From 301d9cb80b4f64ba24d4b141ad3ca58165a29afb Mon Sep 17 00:00:00 2001 From: Ishizaki Kou Date: Thu, 26 Jul 2007 20:06:08 +1000 Subject: [POWERPC] Init markings for hvc_beat Fix warnings about section mismatch. Signed-off-by: Kou Ishizaki Signed-off-by: Paul Mackerras --- drivers/char/hvc_beat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hvc_beat.c b/drivers/char/hvc_beat.c index 6f019f19be71..e74bb949c289 100644 --- a/drivers/char/hvc_beat.c +++ b/drivers/char/hvc_beat.c @@ -97,7 +97,7 @@ static int hvc_beat_config(char *p) return 0; } -static int hvc_beat_console_init(void) +static int __init hvc_beat_console_init(void) { if (hvc_beat_useit && machine_is_compatible("Beat")) { hvc_instantiate(0, 0, &hvc_beat_get_put_ops); @@ -106,7 +106,7 @@ static int hvc_beat_console_init(void) } /* temp */ -static int hvc_beat_init(void) +static int __init hvc_beat_init(void) { struct hvc_struct *hp; -- cgit v1.2.3 From 0d279d47612d1b63155a1d9637a6fc5143dad594 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Mon, 30 Jul 2007 15:55:02 +1000 Subject: [POWERPC] Fixes to allow use of Ebony's flash chips through physmap_of This patch contains a handful of small fixes to allow the Ebony's flash to be exposed as MTD devices via the physmap_of driver. Specifically it: - Makes a small addition to the device tree and zImage wrapper to record the correct address for the flash in the device tree based on the board switches as reported via an FPGA register. - Prohibits building the old hard-coded "Ebony" flash map on arch/powerpc kernels, in favour of using physmap_of's device tree based approach. - Enables MTD and physmap_of in the Ebony defconfig. Signed-off-by: David Gibson Signed-off-by: Paul Mackerras --- drivers/mtd/maps/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index cc6c73442435..6cd132c75187 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig @@ -362,7 +362,7 @@ config MTD_WALNUT config MTD_EBONY tristate "Flash devices mapped on IBM 440GP Ebony" - depends on MTD_JEDECPROBE && EBONY + depends on MTD_JEDECPROBE && EBONY && !PPC_MERGE help This enables access routines for the flash chips on the IBM 440GP Ebony board. If you have one of these boards and would like to -- cgit v1.2.3 From cc61f957f486871536cc5531e83337fff4fe48f3 Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Wed, 1 Aug 2007 08:10:03 +1000 Subject: [POWERPC] drivers/macintosh/therm_adt746x.c: kmalloc + memset conversion to kzalloc Signed-off-by: Mariusz Kozlowski Signed-off-by: Paul Mackerras --- drivers/macintosh/therm_adt746x.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index f25685b9b7cf..276945d51513 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c @@ -379,13 +379,10 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, if (thermostat) return 0; - th = (struct thermostat *) - kmalloc(sizeof(struct thermostat), GFP_KERNEL); - + th = kzalloc(sizeof(struct thermostat), GFP_KERNEL); if (!th) return -ENOMEM; - memset(th, 0, sizeof(*th)); th->clt.addr = addr; th->clt.adapter = adapter; th->clt.driver = &thermostat_driver; -- cgit v1.2.3 From 7b52b440d37d669ec93297cf589984a110518d43 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 13 Aug 2007 06:38:34 +1000 Subject: [POWERPC] via-pmu: Fix typo in printk This fixes a typo in a printk message. Signed-off-by: Michael Buesch Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- drivers/macintosh/via-pmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 157080b3b468..5eee480245f3 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -410,7 +410,7 @@ static int __init via_pmu_start(void) irq = irq_of_parse_and_map(vias, 0); if (irq == NO_IRQ) { - printk(KERN_ERR "via-pmu: can't map interruptn"); + printk(KERN_ERR "via-pmu: can't map interrupt\n"); return -ENODEV; } if (request_irq(irq, via_pmu_interrupt, 0, "VIA-PMU", (void *)0)) { -- cgit v1.2.3 From 9c25099db74b384e16345622071552f9f10dd045 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 15 Aug 2007 16:42:12 +1000 Subject: [POWERPC] Use of_get_property in ipmi code get_property has been renamed to of_get_property. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- drivers/char/ipmi/ipmi_si_intf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 96d2f9ee42d6..d57083a9e4e0 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2251,19 +2251,19 @@ static int __devinit ipmi_of_probe(struct of_device *dev, return ret; } - regsize = get_property(np, "reg-size", &proplen); + regsize = of_get_property(np, "reg-size", &proplen); if (regsize && proplen != 4) { dev_warn(&dev->dev, PFX "invalid regsize from OF\n"); return -EINVAL; } - regspacing = get_property(np, "reg-spacing", &proplen); + regspacing = of_get_property(np, "reg-spacing", &proplen); if (regspacing && proplen != 4) { dev_warn(&dev->dev, PFX "invalid regspacing from OF\n"); return -EINVAL; } - regshift = get_property(np, "reg-shift", &proplen); + regshift = of_get_property(np, "reg-shift", &proplen); if (regshift && proplen != 4) { dev_warn(&dev->dev, PFX "invalid regshift from OF\n"); return -EINVAL; -- cgit v1.2.3 From a05afe9146f7611d40a58be34ee8442727a6af1f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 15 Aug 2007 16:54:04 +1000 Subject: [POWERPC] Comment out a currently unused function Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- drivers/macintosh/windfarm_smu_sat.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c index 351982bcec1b..f449d775cdf4 100644 --- a/drivers/macintosh/windfarm_smu_sat.c +++ b/drivers/macintosh/windfarm_smu_sat.c @@ -380,10 +380,12 @@ static int __init sat_sensors_init(void) return i2c_add_driver(&wf_sat_driver); } +#if 0 /* uncomment when module_exit() below is uncommented */ static void __exit sat_sensors_exit(void) { i2c_del_driver(&wf_sat_driver); } +#endif module_init(sat_sensors_init); /*module_exit(sat_sensors_exit); Uncomment when cleanup is implemented */ -- cgit v1.2.3 From ed16c20da6f500bc2dfad933078d2987636a7b60 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 17 Aug 2007 01:47:39 -0500 Subject: [POWERPC] Remove old includes from arch/ppc Remove includes of files that existed in arch/ppc that we dont need in arch/powerpc anymore. The following includes were removed: This also caused platforms/embedded6xx/mpc7448_hpc2.h to no longer be needed and thus removed. Signed-off-by: Kumar Gala --- drivers/macintosh/adb-iop.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/macintosh/adb-iop.c b/drivers/macintosh/adb-iop.c index 17ef5d3c01b4..444696625171 100644 --- a/drivers/macintosh/adb-iop.c +++ b/drivers/macintosh/adb-iop.c @@ -19,7 +19,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3 From 33d71d26ba982f99b8cb76b86b2e1e0a0964a8ac Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 20 Aug 2007 08:50:28 -0500 Subject: [POWERPC] Copy over headers from arch/ppc to arch/powerpc that we need To build arch/powerpc without including asm-ppc/ we need these files in asm-powerpc/ Moved some headers under arch/powerpc/platforms if they were only used by platform or driver files and fixed up the source file includes to match the new locations Signed-off-by: Kumar Gala --- drivers/macintosh/ans-lcd.c | 3 ++- drivers/macintosh/ans-lcd.h | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 drivers/macintosh/ans-lcd.h (limited to 'drivers') diff --git a/drivers/macintosh/ans-lcd.c b/drivers/macintosh/ans-lcd.c index e54c4d9f6365..73c50bc02095 100644 --- a/drivers/macintosh/ans-lcd.c +++ b/drivers/macintosh/ans-lcd.c @@ -14,9 +14,10 @@ #include #include #include -#include #include +#include "ans-lcd.h" + #define ANSLCD_ADDR 0xf301c000 #define ANSLCD_CTRL_IX 0x00 #define ANSLCD_DATA_IX 0x10 diff --git a/drivers/macintosh/ans-lcd.h b/drivers/macintosh/ans-lcd.h new file mode 100644 index 000000000000..d795b9fd2db6 --- /dev/null +++ b/drivers/macintosh/ans-lcd.h @@ -0,0 +1,11 @@ +#ifndef _PPC_ANS_LCD_H +#define _PPC_ANS_LCD_H + +#define ANSLCD_MINOR 156 + +#define ANSLCD_CLEAR 0x01 +#define ANSLCD_SENDCTRL 0x02 +#define ANSLCD_SETSHORTDELAY 0x03 +#define ANSLCD_SETLONGDELAY 0x04 + +#endif -- cgit v1.2.3 From 2099172d61abda1b793b499bb8edcaac4de2cdae Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 7 Sep 2007 13:23:53 +1000 Subject: [POWERPC] Document and implement an improved flash device binding for powerpc This replaces the binding for flash chips in booting-without-of.txt with an clarified and improved version. It also makes drivers/mtd/maps/physmap_of.c recognize this new binding. Finally it revises the Ebony device tree source to use the new binding as an example. Signed-off-by: David Gibson Acked-by: Segher Boessenkool Signed-off-by: Paul Mackerras --- drivers/mtd/maps/physmap_of.c | 239 ++++++++++++++++++++++++++++++------------ 1 file changed, 174 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index bbb42c35b69b..3df001bfee36 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -4,6 +4,9 @@ * Copyright (C) 2006 MontaVista Software Inc. * Author: Vitaly Wool * + * Revised to handle newer style flash binding by: + * Copyright (C) 2007 David Gibson, IBM Corporation. + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your @@ -30,56 +33,135 @@ struct physmap_flash_info { struct map_info map; struct resource *res; #ifdef CONFIG_MTD_PARTITIONS - int nr_parts; struct mtd_partition *parts; #endif }; -static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL }; -#ifdef CONFIG_MTD_PARTITIONS -static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -#endif - #ifdef CONFIG_MTD_PARTITIONS -static int parse_flash_partitions(struct device_node *node, - struct mtd_partition **parts) +static int parse_obsolete_partitions(struct of_device *dev, + struct physmap_flash_info *info, + struct device_node *dp) { - int i, plen, retval = -ENOMEM; - const u32 *part; - const char *name; + int i, plen, nr_parts; + const struct { + u32 offset, len; + } *part; + const char *names; - part = of_get_property(node, "partitions", &plen); - if (part == NULL) - goto err; + part = of_get_property(dp, "partitions", &plen); + if (!part) + return -ENOENT; - retval = plen / (2 * sizeof(u32)); - *parts = kzalloc(retval * sizeof(struct mtd_partition), GFP_KERNEL); - if (*parts == NULL) { + dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n"); + + nr_parts = plen / sizeof(part[0]); + + info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL); + if (!info->parts) { printk(KERN_ERR "Can't allocate the flash partition data!\n"); - goto err; + return -ENOMEM; } - name = of_get_property(node, "partition-names", &plen); + names = of_get_property(dp, "partition-names", &plen); - for (i = 0; i < retval; i++) { - (*parts)[i].offset = *part++; - (*parts)[i].size = *part & ~1; - if (*part++ & 1) /* bit 0 set signifies read only partition */ - (*parts)[i].mask_flags = MTD_WRITEABLE; + for (i = 0; i < nr_parts; i++) { + info->parts[i].offset = part->offset; + info->parts[i].size = part->len & ~1; + if (part->len & 1) /* bit 0 set signifies read only partition */ + info->parts[i].mask_flags = MTD_WRITEABLE; - if (name != NULL && plen > 0) { - int len = strlen(name) + 1; + if (names && (plen > 0)) { + int len = strlen(names) + 1; - (*parts)[i].name = (char *)name; + info->parts[i].name = (char *)names; plen -= len; - name += len; - } else - (*parts)[i].name = "unnamed"; + names += len; + } else { + info->parts[i].name = "unnamed"; + } + + part++; } -err: - return retval; + + return nr_parts; } -#endif + +static int __devinit process_partitions(struct physmap_flash_info *info, + struct of_device *dev) +{ + const char *partname; + static const char *part_probe_types[] + = { "cmdlinepart", "RedBoot", NULL }; + struct device_node *dp = dev->node, *pp; + int nr_parts, i; + + /* First look for RedBoot table or partitions on the command + * line, these take precedence over device tree information */ + nr_parts = parse_mtd_partitions(info->mtd, part_probe_types, + &info->parts, 0); + if (nr_parts > 0) { + add_mtd_partitions(info->mtd, info->parts, nr_parts); + return 0; + } + + /* First count the subnodes */ + nr_parts = 0; + for (pp = dp->child; pp; pp = pp->sibling) + nr_parts++; + + if (nr_parts) { + info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition), + GFP_KERNEL); + if (!info->parts) { + printk(KERN_ERR "Can't allocate the flash partition data!\n"); + return -ENOMEM; + } + + for (pp = dp->child, i = 0 ; pp; pp = pp->sibling, i++) { + const u32 *reg; + int len; + + reg = of_get_property(pp, "reg", &len); + if (!reg || (len != 2*sizeof(u32))) { + dev_err(&dev->dev, "Invalid 'reg' on %s\n", + dp->full_name); + kfree(info->parts); + info->parts = NULL; + return -EINVAL; + } + info->parts[i].offset = reg[0]; + info->parts[i].size = reg[1]; + + partname = of_get_property(pp, "label", &len); + if (!partname) + partname = of_get_property(pp, "name", &len); + info->parts[i].name = (char *)partname; + + if (of_get_property(pp, "read-only", &len)) + info->parts[i].mask_flags = MTD_WRITEABLE; + } + } else { + nr_parts = parse_obsolete_partitions(dev, info, dp); + } + + if (nr_parts < 0) + return nr_parts; + + if (nr_parts > 0) + add_mtd_partitions(info->mtd, info->parts, nr_parts); + else + add_mtd_device(info->mtd); + + return 0; +} +#else /* MTD_PARTITIONS */ +static int __devinit process_partitions(struct physmap_flash_info *info, + struct device_node *dev) +{ + add_mtd_device(info->mtd); + return 0; +} +#endif /* MTD_PARTITIONS */ static int of_physmap_remove(struct of_device *dev) { @@ -92,7 +174,7 @@ static int of_physmap_remove(struct of_device *dev) if (info->mtd != NULL) { #ifdef CONFIG_MTD_PARTITIONS - if (info->nr_parts) { + if (info->parts) { del_mtd_partitions(info->mtd); kfree(info->parts); } else { @@ -115,17 +197,51 @@ static int of_physmap_remove(struct of_device *dev) return 0; } +/* Helper function to handle probing of the obsolete "direct-mapped" + * compatible binding, which has an extra "probe-type" property + * describing the type of flash probe necessary. */ +static struct mtd_info * __devinit obsolete_probe(struct of_device *dev, + struct map_info *map) +{ + struct device_node *dp = dev->node; + const char *of_probe; + struct mtd_info *mtd; + static const char *rom_probe_types[] + = { "cfi_probe", "jedec_probe", "map_rom"}; + int i; + + dev_warn(&dev->dev, "Device tree uses obsolete \"direct-mapped\" " + "flash binding\n"); + + of_probe = of_get_property(dp, "probe-type", NULL); + if (!of_probe) { + for (i = 0; i < ARRAY_SIZE(rom_probe_types); i++) { + mtd = do_map_probe(rom_probe_types[i], map); + if (mtd) + return mtd; + } + return NULL; + } else if (strcmp(of_probe, "CFI") == 0) { + return do_map_probe("cfi_probe", map); + } else if (strcmp(of_probe, "JEDEC") == 0) { + return do_map_probe("jedec_probe", map); + } else { + if (strcmp(of_probe, "ROM") != 0) + dev_dbg(&dev->dev, "obsolete_probe: don't know probe type " + "'%s', mapping as rom\n", of_probe); + return do_map_probe("mtd_rom", map); + } +} + static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match) { struct device_node *dp = dev->node; struct resource res; struct physmap_flash_info *info; - const char **probe_type; - const char *of_probe; + const char *probe_type = (const char *)match->data; const u32 *width; int err; - if (of_address_to_resource(dp, 0, &res)) { dev_err(&dev->dev, "Can't get the flash mapping!\n"); err = -EINVAL; @@ -174,21 +290,11 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev simple_map_init(&info->map); - of_probe = of_get_property(dp, "probe-type", NULL); - if (of_probe == NULL) { - probe_type = rom_probe_types; - for (; info->mtd == NULL && *probe_type != NULL; probe_type++) - info->mtd = do_map_probe(*probe_type, &info->map); - } else if (!strcmp(of_probe, "CFI")) - info->mtd = do_map_probe("cfi_probe", &info->map); - else if (!strcmp(of_probe, "JEDEC")) - info->mtd = do_map_probe("jedec_probe", &info->map); - else { - if (strcmp(of_probe, "ROM")) - dev_dbg(&dev->dev, "map_probe: don't know probe type " - "'%s', mapping as rom\n", of_probe); - info->mtd = do_map_probe("mtd_rom", &info->map); - } + if (probe_type) + info->mtd = do_map_probe(probe_type, &info->map); + else + info->mtd = obsolete_probe(dev, &info->map); + if (info->mtd == NULL) { dev_err(&dev->dev, "map_probe failed\n"); err = -ENXIO; @@ -196,19 +302,7 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev } info->mtd->owner = THIS_MODULE; -#ifdef CONFIG_MTD_PARTITIONS - err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0); - if (err > 0) { - add_mtd_partitions(info->mtd, info->parts, err); - } else if ((err = parse_flash_partitions(dp, &info->parts)) > 0) { - dev_info(&dev->dev, "Using OF partition information\n"); - add_mtd_partitions(info->mtd, info->parts, err); - info->nr_parts = err; - } else -#endif - - add_mtd_device(info->mtd); - return 0; + return process_partitions(info, dev); err_out: of_physmap_remove(dev); @@ -220,6 +314,21 @@ err_out: } static struct of_device_id of_physmap_match[] = { + { + .compatible = "cfi-flash", + .data = (void *)"cfi_probe", + }, + { + /* FIXME: JEDEC chips can't be safely and reliably + * probed, although the mtd code gets it right in + * practice most of the time. We should use the + * vendor and device ids specified by the binding to + * bypass the heuristic probe code, but the mtd layer + * provides, at present, no interface for doing so + * :(. */ + .compatible = "jedec-flash", + .data = (void *)"jedec_probe", + }, { .type = "rom", .compatible = "direct-mapped" -- cgit v1.2.3 From 89a300e85b646dd08343264f025f4f412d552bfd Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Wed, 22 Aug 2007 21:49:01 -0500 Subject: ucc_geth: kill unused include The ucc_geth_mii code is based on the gianfar_mii code that use to include ocp.h. ucc never need this and it causes issues when we want to kill arch/ppc includes from arch/powerpc. Signed-off-by: Kumar Gala --- drivers/net/ucc_geth_mii.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c index 6c257b88ce51..df884f0ad8e5 100644 --- a/drivers/net/ucc_geth_mii.c +++ b/drivers/net/ucc_geth_mii.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include -- cgit v1.2.3 From af6a9aabc106b70ab03d6665c713bca3dd3cb195 Mon Sep 17 00:00:00 2001 From: John Rigby Date: Wed, 23 May 2007 11:30:55 -0600 Subject: [POWERPC] 52xx: Fix mpc52xx_uart_of_assign to use correct index Use idx as index into mpc52xx_uart_nodes instead of i Signed-off-by: John Rigby Signed-off-by: Kumar Gala --- drivers/serial/mpc52xx_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c index 35f8b86cc78f..035cca028199 100644 --- a/drivers/serial/mpc52xx_uart.c +++ b/drivers/serial/mpc52xx_uart.c @@ -1051,7 +1051,7 @@ mpc52xx_uart_of_assign(struct device_node *np, int idx) /* If the slot is already occupied, then swap slots */ if (mpc52xx_uart_nodes[idx] && (free_idx != -1)) mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx]; - mpc52xx_uart_nodes[i] = np; + mpc52xx_uart_nodes[idx] = np; } static void -- cgit v1.2.3 From aa0154290fc05948560ac43afcccf8259e10bcd0 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Sun, 26 Aug 2007 19:10:59 +1000 Subject: [POWERPC] Fix pmac_zilog debug arg drivers/serial/pmac_zilog.c:1590: warning: format '%d' expects type 'int', but argument 3 has type 'pm_message_t' Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- drivers/serial/pmac_zilog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 0fa9f6761763..f793ac212672 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -1587,7 +1587,7 @@ static int pmz_suspend(struct macio_dev *mdev, pm_message_t pm_state) if (pm_state.event == mdev->ofdev.dev.power.power_state.event) return 0; - pmz_debug("suspend, switching to state %d\n", pm_state); + pmz_debug("suspend, switching to state %d\n", pm_state.event); state = pmz_uart_reg.state + uap->port.line; -- cgit v1.2.3 From 8d9ae994d8fce807fc90fb8e3b6ac8df1cc7dce6 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Sat, 15 Sep 2007 04:54:12 +1000 Subject: [POWERPC] Make partitions optional in physmap_of The latest physmap_of driver has a small error where it will fail the probe with: physmap-flash: probe of fff00000.small-flas failed with error -2 if there are no partition subnodes in the device tree and the old style binding is not used. Since partition definitions are optional, the probe should still succeed. Signed-off-by: Josh Boyer Acked-by: David Gibson --- drivers/mtd/maps/physmap_of.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 3df001bfee36..096dd47b5d5d 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -142,6 +142,8 @@ static int __devinit process_partitions(struct physmap_flash_info *info, } } else { nr_parts = parse_obsolete_partitions(dev, info, dp); + if (nr_parts == -ENOENT) + nr_parts = 0; } if (nr_parts < 0) -- cgit v1.2.3 From c4d5e375470862fd741f93bf0686d7ac2f7fdce4 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Thu, 20 Sep 2007 11:22:25 +1000 Subject: [POWERPC] Cleanups for physmap_of.c (v2) This patch includes a whole batch of smallish cleanups for drivers/mtd/physmap_of.c. - A bunch of uneeded #includes are removed - We switch to the modern linux/of.h etc. in place of asm/prom.h - Use some helper macros to avoid some ugly inline #ifdefs - A few lines of unreachable code are removed - A number of indentation / line-wrapping fixes - More consistent use of kernel idioms such as if (!p) instead of if (p == NULL) - Clarify some printk()s and other informative strings. - parse_obsolete_partitions() now returns 0 if no partition information is found, instead of returning -ENOENT which the caller had to handle specially. - (the big one) Despite the name, this driver really has nothing to do with drivers/mtd/physmap.c. The fact that the flash chips must be physically direct mapped is a constrant, but doesn't really say anything about the actual purpose of this driver, which is to instantiate MTD devices based on information from the device tree. Therefore the physmap name is replaced everywhere within the file with "of_flash". The file itself and the Kconfig option is not renamed for now (so that the diff is actually a diff). That can come later. Signed-off-by: David Gibson Signed-off-by: Josh Boyer --- drivers/mtd/maps/physmap_of.c | 224 +++++++++++++++++++----------------------- 1 file changed, 99 insertions(+), 125 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 096dd47b5d5d..cf75a566442e 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -1,5 +1,5 @@ /* - * Normal mappings of chips in physical memory for OF devices + * Flash mappings described by the OF (or flattened) device tree * * Copyright (C) 2006 MontaVista Software Inc. * Author: Vitaly Wool @@ -15,20 +15,15 @@ #include #include -#include #include -#include #include #include #include #include -#include -#include -#include -#include -#include +#include +#include -struct physmap_flash_info { +struct of_flash { struct mtd_info *mtd; struct map_info map; struct resource *res; @@ -38,8 +33,10 @@ struct physmap_flash_info { }; #ifdef CONFIG_MTD_PARTITIONS +#define OF_FLASH_PARTS(info) ((info)->parts) + static int parse_obsolete_partitions(struct of_device *dev, - struct physmap_flash_info *info, + struct of_flash *info, struct device_node *dp) { int i, plen, nr_parts; @@ -50,17 +47,15 @@ static int parse_obsolete_partitions(struct of_device *dev, part = of_get_property(dp, "partitions", &plen); if (!part) - return -ENOENT; + return 0; /* No partitions found */ dev_warn(&dev->dev, "Device tree uses obsolete partition map binding\n"); nr_parts = plen / sizeof(part[0]); - info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition), GFP_KERNEL); - if (!info->parts) { - printk(KERN_ERR "Can't allocate the flash partition data!\n"); + info->parts = kzalloc(nr_parts * sizeof(*info->parts), GFP_KERNEL); + if (!info->parts) return -ENOMEM; - } names = of_get_property(dp, "partition-names", &plen); @@ -86,8 +81,8 @@ static int parse_obsolete_partitions(struct of_device *dev, return nr_parts; } -static int __devinit process_partitions(struct physmap_flash_info *info, - struct of_device *dev) +static int __devinit parse_partitions(struct of_flash *info, + struct of_device *dev) { const char *partname; static const char *part_probe_types[] @@ -109,89 +104,68 @@ static int __devinit process_partitions(struct physmap_flash_info *info, for (pp = dp->child; pp; pp = pp->sibling) nr_parts++; - if (nr_parts) { - info->parts = kzalloc(nr_parts * sizeof(struct mtd_partition), - GFP_KERNEL); - if (!info->parts) { - printk(KERN_ERR "Can't allocate the flash partition data!\n"); - return -ENOMEM; - } + if (nr_parts == 0) + return parse_obsolete_partitions(dev, info, dp); + + info->parts = kzalloc(nr_parts * sizeof(*info->parts), + GFP_KERNEL); + if (!info->parts) + return -ENOMEM; - for (pp = dp->child, i = 0 ; pp; pp = pp->sibling, i++) { - const u32 *reg; - int len; - - reg = of_get_property(pp, "reg", &len); - if (!reg || (len != 2*sizeof(u32))) { - dev_err(&dev->dev, "Invalid 'reg' on %s\n", - dp->full_name); - kfree(info->parts); - info->parts = NULL; - return -EINVAL; - } - info->parts[i].offset = reg[0]; - info->parts[i].size = reg[1]; - - partname = of_get_property(pp, "label", &len); - if (!partname) - partname = of_get_property(pp, "name", &len); - info->parts[i].name = (char *)partname; - - if (of_get_property(pp, "read-only", &len)) - info->parts[i].mask_flags = MTD_WRITEABLE; + for (pp = dp->child, i = 0; pp; pp = pp->sibling, i++) { + const u32 *reg; + int len; + + reg = of_get_property(pp, "reg", &len); + if (!reg || (len != 2*sizeof(u32))) { + dev_err(&dev->dev, "Invalid 'reg' on %s\n", + dp->full_name); + kfree(info->parts); + info->parts = NULL; + return -EINVAL; } - } else { - nr_parts = parse_obsolete_partitions(dev, info, dp); - if (nr_parts == -ENOENT) - nr_parts = 0; - } + info->parts[i].offset = reg[0]; + info->parts[i].size = reg[1]; - if (nr_parts < 0) - return nr_parts; + partname = of_get_property(pp, "label", &len); + if (!partname) + partname = of_get_property(pp, "name", &len); + info->parts[i].name = (char *)partname; - if (nr_parts > 0) - add_mtd_partitions(info->mtd, info->parts, nr_parts); - else - add_mtd_device(info->mtd); + if (of_get_property(pp, "read-only", &len)) + info->parts[i].mask_flags = MTD_WRITEABLE; + } - return 0; + return nr_parts; } #else /* MTD_PARTITIONS */ -static int __devinit process_partitions(struct physmap_flash_info *info, - struct device_node *dev) -{ - add_mtd_device(info->mtd); - return 0; -} +#define OF_FLASH_PARTS(info) (0) +#define parse_partitions(info, dev) (0) #endif /* MTD_PARTITIONS */ -static int of_physmap_remove(struct of_device *dev) +static int of_flash_remove(struct of_device *dev) { - struct physmap_flash_info *info; + struct of_flash *info; info = dev_get_drvdata(&dev->dev); - if (info == NULL) + if (!info) return 0; dev_set_drvdata(&dev->dev, NULL); - if (info->mtd != NULL) { -#ifdef CONFIG_MTD_PARTITIONS - if (info->parts) { + if (info->mtd) { + if (OF_FLASH_PARTS(info)) { del_mtd_partitions(info->mtd); - kfree(info->parts); + kfree(OF_FLASH_PARTS(info)); } else { del_mtd_device(info->mtd); } -#else - del_mtd_device(info->mtd); -#endif map_destroy(info->mtd); } - if (info->map.virt != NULL) + if (info->map.virt) iounmap(info->map.virt); - if (info->res != NULL) { + if (info->res) { release_resource(info->res); kfree(info->res); } @@ -229,52 +203,49 @@ static struct mtd_info * __devinit obsolete_probe(struct of_device *dev, return do_map_probe("jedec_probe", map); } else { if (strcmp(of_probe, "ROM") != 0) - dev_dbg(&dev->dev, "obsolete_probe: don't know probe type " - "'%s', mapping as rom\n", of_probe); + dev_warn(&dev->dev, "obsolete_probe: don't know probe " + "type '%s', mapping as rom\n", of_probe); return do_map_probe("mtd_rom", map); } } -static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match) +static int __devinit of_flash_probe(struct of_device *dev, + const struct of_device_id *match) { struct device_node *dp = dev->node; struct resource res; - struct physmap_flash_info *info; - const char *probe_type = (const char *)match->data; + struct of_flash *info; + const char *probe_type = match->data; const u32 *width; int err; + err = -ENXIO; if (of_address_to_resource(dp, 0, &res)) { - dev_err(&dev->dev, "Can't get the flash mapping!\n"); - err = -EINVAL; + dev_err(&dev->dev, "Can't get IO address from device tree\n"); goto err_out; } - dev_dbg(&dev->dev, "physmap flash device: %.8llx at %.8llx\n", - (unsigned long long)res.end - res.start + 1, - (unsigned long long)res.start); + dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n", + (unsigned long long)res.start, (unsigned long long)res.end); - info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL); - if (info == NULL) { - err = -ENOMEM; + err = -ENOMEM; + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) goto err_out; - } memset(info, 0, sizeof(*info)); dev_set_drvdata(&dev->dev, info); + err = -EBUSY; info->res = request_mem_region(res.start, res.end - res.start + 1, - dev->dev.bus_id); - if (info->res == NULL) { - dev_err(&dev->dev, "Could not reserve memory region\n"); - err = -ENOMEM; + dev->dev.bus_id); + if (!info->res) goto err_out; - } + err = -ENXIO; width = of_get_property(dp, "bank-width", NULL); - if (width == NULL) { - dev_err(&dev->dev, "Can't get the flash bank width!\n"); - err = -EINVAL; + if (!width) { + dev_err(&dev->dev, "Can't get bank width from device tree\n"); goto err_out; } @@ -283,10 +254,10 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev info->map.size = res.end - res.start + 1; info->map.bankwidth = *width; + err = -ENOMEM; info->map.virt = ioremap(info->map.phys, info->map.size); - if (info->map.virt == NULL) { - dev_err(&dev->dev, "Failed to ioremap flash region\n"); - err = EIO; + if (!info->map.virt) { + dev_err(&dev->dev, "Failed to ioremap() flash region\n"); goto err_out; } @@ -297,25 +268,30 @@ static int __devinit of_physmap_probe(struct of_device *dev, const struct of_dev else info->mtd = obsolete_probe(dev, &info->map); - if (info->mtd == NULL) { - dev_err(&dev->dev, "map_probe failed\n"); - err = -ENXIO; + err = -ENXIO; + if (!info->mtd) { + dev_err(&dev->dev, "do_map_probe() failed\n"); goto err_out; } info->mtd->owner = THIS_MODULE; - return process_partitions(info, dev); + err = parse_partitions(info, dev); + if (err < 0) + goto err_out; -err_out: - of_physmap_remove(dev); - return err; + if (err > 0) + add_mtd_partitions(info->mtd, OF_FLASH_PARTS(info), err); + else + add_mtd_device(info->mtd); return 0; - +err_out: + of_flash_remove(dev); + return err; } -static struct of_device_id of_physmap_match[] = { +static struct of_device_id of_flash_match[] = { { .compatible = "cfi-flash", .data = (void *)"cfi_probe", @@ -337,30 +313,28 @@ static struct of_device_id of_physmap_match[] = { }, { }, }; +MODULE_DEVICE_TABLE(of, of_flash_match); -MODULE_DEVICE_TABLE(of, of_physmap_match); - - -static struct of_platform_driver of_physmap_flash_driver = { - .name = "physmap-flash", - .match_table = of_physmap_match, - .probe = of_physmap_probe, - .remove = of_physmap_remove, +static struct of_platform_driver of_flash_driver = { + .name = "of-flash", + .match_table = of_flash_match, + .probe = of_flash_probe, + .remove = of_flash_remove, }; -static int __init of_physmap_init(void) +static int __init of_flash_init(void) { - return of_register_platform_driver(&of_physmap_flash_driver); + return of_register_platform_driver(&of_flash_driver); } -static void __exit of_physmap_exit(void) +static void __exit of_flash_exit(void) { - of_unregister_platform_driver(&of_physmap_flash_driver); + of_unregister_platform_driver(&of_flash_driver); } -module_init(of_physmap_init); -module_exit(of_physmap_exit); +module_init(of_flash_init); +module_exit(of_flash_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Vitaly Wool "); -MODULE_DESCRIPTION("Configurable MTD map driver for OF"); +MODULE_DESCRIPTION("Device tree based MTD map driver"); -- cgit v1.2.3 From e4533b243e5e0c3a26287a902a1ed0f8f5b1cec0 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 5 Apr 2007 00:19:43 +1000 Subject: [POWERPC] Optionally use new device number for pmac_zilog This adds the option for the pmac_zilog driver to use the major/minor numbers recently allocated specifically for it (/dev/ttyPZn) instead of the /dev/ttySn numbers. The advantage of doing this is that it allows the pmac_zilog and 8250 drivers to coexist. The disadvantage of doing this is that it is a user-visible ABI change and it will break existing working setups on powermacs, and could be confusing to users. Signed-off-by: David Woodhouse Signed-off-by: Paul Mackerras --- drivers/serial/Kconfig | 25 +++++++++++++++++++++++++ drivers/serial/pmac_zilog.c | 20 +++++++++++++++----- 2 files changed, 40 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 81b52b7cca21..d6ae38e55d01 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -986,6 +986,31 @@ config SERIAL_PMACZILOG PowerMac machines. Say Y or M if you want to be able to these serial ports. +config SERIAL_PMACZILOG_TTYS + bool "Use ttySn device nodes for Zilog z85c30" + depends on SERIAL_PMACZILOG + help + The pmac_zilog driver for the z85C30 chip on many powermacs + historically used the device numbers for /dev/ttySn. The + 8250 serial port driver also uses these numbers, which means + the two drivers being unable to coexist; you could not use + both z85C30 and 8250 type ports at the same time. + + If this option is not selected, the pmac_zilog driver will + use the device numbers allocated for /dev/ttyPZn. This allows + the pmac_zilog and 8250 drivers to co-exist, but may cause + existing userspace setups to break. Programs that need to + access the built-in serial ports on powermacs will need to + be reconfigured to use /dev/ttyPZn instead of /dev/ttySn. + + If you enable this option, any z85c30 ports in the system will + be registered as ttyS0 onwards as in the past, and you will be + unable to use the 8250 module for PCMCIA or other 16C550-style + UARTs. + + Say N unless you need the z85c30 ports on your powermac + to appear as /dev/ttySn. + config SERIAL_PMACZILOG_CONSOLE bool "Console on PowerMac z85c30 serial port" depends on SERIAL_PMACZILOG=y diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index f793ac212672..794bd0f50d73 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -88,6 +88,16 @@ MODULE_LICENSE("GPL"); #define PWRDBG(fmt, arg...) printk(KERN_DEBUG fmt , ## arg) +#ifdef CONFIG_SERIAL_PMACZILOG_TTYS +#define PMACZILOG_MAJOR TTY_MAJOR +#define PMACZILOG_MINOR 64 +#define PMACZILOG_NAME "ttyS" +#else +#define PMACZILOG_MAJOR 204 +#define PMACZILOG_MINOR 192 +#define PMACZILOG_NAME "ttyPZ" +#endif + /* * For the sake of early serial console, we can do a pre-probe @@ -99,9 +109,10 @@ static DEFINE_MUTEX(pmz_irq_mutex); static struct uart_driver pmz_uart_reg = { .owner = THIS_MODULE, - .driver_name = "ttyS", - .dev_name = "ttyS", - .major = TTY_MAJOR, + .driver_name = PMACZILOG_NAME, + .dev_name = PMACZILOG_NAME, + .major = PMACZILOG_MAJOR, + .minor = PMACZILOG_MINOR, }; @@ -1778,7 +1789,7 @@ static void pmz_console_write(struct console *con, const char *s, unsigned int c static int __init pmz_console_setup(struct console *co, char *options); static struct console pmz_console = { - .name = "ttyS", + .name = PMACZILOG_NAME, .write = pmz_console_write, .device = uart_console_device, .setup = pmz_console_setup, @@ -1802,7 +1813,6 @@ static int __init pmz_register(void) pmz_uart_reg.nr = pmz_ports_count; pmz_uart_reg.cons = PMACZILOG_CONSOLE; - pmz_uart_reg.minor = 64; /* * Register this driver with the serial core -- cgit v1.2.3 From 555ddbb4e2191c8823df2d61525218ac39481385 Mon Sep 17 00:00:00 2001 From: Aristeu Rozanski Date: Tue, 17 Jul 2007 06:53:09 +1000 Subject: [POWERPC] adbhid: Enable KEY_FN key reporting When a Fn key is used in combination with another key in ADB keyboards it will generate a Fn event and then a second event that can be a different key than pressed (Fn + F1 for instance can generate Fn + brightness down if it's configured like that). This enables the reporting of the Fn key to the input system. As Fn is a dead key for most purposes, it's useful to report it so applications can make use of it. One example is apple_mouse (https://jake.ruivo.org/uinputd/trunk/apple_mouse/) that emulates the second and third keys using a combination of keyboard keys and the mouse button. Other applications may use the KEY_FN as a modifier as well. I've been updating and using this patch for months without problems. Signed-off-by: Aristeu Rozanski Acked-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- drivers/macintosh/adbhid.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index b46817f699f1..48d17bf6c927 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -70,7 +70,7 @@ static struct notifier_block adbhid_adb_notifier = { #define ADB_KEY_POWER_OLD 0x7e #define ADB_KEY_POWER 0x7f -u8 adb_to_linux_keycodes[128] = { +u16 adb_to_linux_keycodes[128] = { /* 0x00 */ KEY_A, /* 30 */ /* 0x01 */ KEY_S, /* 31 */ /* 0x02 */ KEY_D, /* 32 */ @@ -134,7 +134,7 @@ u8 adb_to_linux_keycodes[128] = { /* 0x3c */ KEY_RIGHT, /* 106 */ /* 0x3d */ KEY_DOWN, /* 108 */ /* 0x3e */ KEY_UP, /* 103 */ - /* 0x3f */ 0, + /* 0x3f */ KEY_FN, /* 0x1d0 */ /* 0x40 */ 0, /* 0x41 */ KEY_KPDOT, /* 83 */ /* 0x42 */ 0, @@ -208,7 +208,7 @@ struct adbhid { int original_handler_id; int current_handler_id; int mouse_kind; - unsigned char *keycode; + u16 *keycode; char name[64]; char phys[32]; int flags; @@ -275,7 +275,7 @@ static void adbhid_input_keycode(int id, int keycode, int repeat) { struct adbhid *ahid = adbhid[id]; - int up_flag; + int up_flag, key; up_flag = (keycode & 0x80); keycode &= 0x7f; @@ -321,8 +321,7 @@ adbhid_input_keycode(int id, int keycode, int repeat) } } else ahid->flags |= FLAG_FN_KEY_PRESSED; - /* Swallow the key press */ - return; + break; case ADB_KEY_DEL: /* Emulate Fn+delete = forward delete */ if (ahid->flags & FLAG_FN_KEY_PRESSED) { @@ -336,9 +335,9 @@ adbhid_input_keycode(int id, int keycode, int repeat) #endif /* CONFIG_PPC_PMAC */ } - if (adbhid[id]->keycode[keycode]) { - input_report_key(adbhid[id]->input, - adbhid[id]->keycode[keycode], !up_flag); + key = adbhid[id]->keycode[keycode]; + if (key) { + input_report_key(adbhid[id]->input, key, !up_flag); input_sync(adbhid[id]->input); } else printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode, @@ -757,8 +756,8 @@ adbhid_input_register(int id, int default_id, int original_handler_id, input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP); input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML); input_dev->event = adbhid_kbd_event; - input_dev->keycodemax = 127; - input_dev->keycodesize = 1; + input_dev->keycodemax = KEY_FN; + input_dev->keycodesize = sizeof(hid->keycode[0]); break; case ADB_MOUSE: -- cgit v1.2.3 From 4c2a54b09ba35a409afc34bd331a57a994921664 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 19 Sep 2007 14:50:22 +1000 Subject: [POWERPC] Fix platinumfb framebuffer Current kernels have a non-working platinumfb due to some resource management issues. This fixes it. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- drivers/video/platinumfb.c | 48 +++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 8503e733a172..cbe71a5338d0 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -17,6 +17,8 @@ * more details. */ +#undef DEBUG + #include #include #include @@ -535,33 +537,35 @@ static int __devinit platinumfb_probe(struct of_device* odev, volatile __u8 *fbuffer; int bank0, bank1, bank2, bank3, rc; - printk(KERN_INFO "platinumfb: Found Apple Platinum video hardware\n"); + dev_info(&odev->dev, "Found Apple Platinum video hardware\n"); info = framebuffer_alloc(sizeof(*pinfo), &odev->dev); - if (info == NULL) + if (info == NULL) { + dev_err(&odev->dev, "Failed to allocate fbdev !\n"); return -ENOMEM; + } pinfo = info->par; if (of_address_to_resource(dp, 0, &pinfo->rsrc_reg) || of_address_to_resource(dp, 1, &pinfo->rsrc_fb)) { - printk(KERN_ERR "platinumfb: Can't get resources\n"); - framebuffer_release(info); - return -ENXIO; - } - if (!request_mem_region(pinfo->rsrc_reg.start, - pinfo->rsrc_reg.start - - pinfo->rsrc_reg.end + 1, - "platinumfb registers")) { + dev_err(&odev->dev, "Can't get resources\n"); framebuffer_release(info); return -ENXIO; } + dev_dbg(&odev->dev, " registers : 0x%llx...0x%llx\n", + (unsigned long long)pinfo->rsrc_reg.start, + (unsigned long long)pinfo->rsrc_reg.end); + dev_dbg(&odev->dev, " framebuffer: 0x%llx...0x%llx\n", + (unsigned long long)pinfo->rsrc_fb.start, + (unsigned long long)pinfo->rsrc_fb.end); + + /* Do not try to request register space, they overlap with the + * northbridge and that can fail. Only request framebuffer + */ if (!request_mem_region(pinfo->rsrc_fb.start, - pinfo->rsrc_fb.start - - pinfo->rsrc_fb.end + 1, + pinfo->rsrc_fb.end - pinfo->rsrc_fb.start + 1, "platinumfb framebuffer")) { - release_mem_region(pinfo->rsrc_reg.start, - pinfo->rsrc_reg.end - - pinfo->rsrc_reg.start + 1); + printk(KERN_ERR "platinumfb: Can't request framebuffer !\n"); framebuffer_release(info); return -ENXIO; } @@ -600,7 +604,8 @@ static int __devinit platinumfb_probe(struct of_device* odev, bank2 = fbuffer[0x200000] == 0x56; bank3 = fbuffer[0x300000] == 0x78; pinfo->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000; - printk(KERN_INFO "platinumfb: Total VRAM = %dMB (%d%d%d%d)\n", (int) (pinfo->total_vram / 1024 / 1024), + printk(KERN_INFO "platinumfb: Total VRAM = %dMB (%d%d%d%d)\n", + (unsigned int) (pinfo->total_vram / 1024 / 1024), bank3, bank2, bank1, bank0); /* @@ -644,16 +649,15 @@ static int __devexit platinumfb_remove(struct of_device* odev) unregister_framebuffer (info); /* Unmap frame buffer and registers */ + iounmap(pinfo->frame_buffer); + iounmap(pinfo->platinum_regs); + iounmap(pinfo->cmap_regs); + release_mem_region(pinfo->rsrc_fb.start, pinfo->rsrc_fb.end - pinfo->rsrc_fb.start + 1); - release_mem_region(pinfo->rsrc_reg.start, - pinfo->rsrc_reg.end - - pinfo->rsrc_reg.start + 1); - iounmap(pinfo->frame_buffer); - iounmap(pinfo->platinum_regs); + release_mem_region(pinfo->cmap_regs_phys, 0x1000); - iounmap(pinfo->cmap_regs); framebuffer_release(info); -- cgit v1.2.3 From a4e32b5f0ac60e6bca7c6896f47e1c624ae45df1 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 2 Oct 2007 13:30:05 -0700 Subject: [POWERPC] Sky Cpu and Nexus: code style improvement Remove useless spaces and adds some empty lines to make code more readable. Also marker for printk is added. Signed-off-by: Cyrill Gorcunov Cc: Benjamin Herrenschmidt Cc: Kumar Gala Cc: Brian Waite Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/misc/hdpuftrs/hdpu_cpustate.c | 38 ++++++++++++++++------------------- drivers/misc/hdpuftrs/hdpu_nexus.c | 24 +++++++++++++--------- 2 files changed, 31 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index 276ba3c5143f..1874b0740f2b 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -169,22 +169,21 @@ static struct platform_driver hdpu_cpustate_driver = { * The various file operations we support. */ static const struct file_operations cpustate_fops = { - owner:THIS_MODULE, - open:cpustate_open, - release:cpustate_release, - read:cpustate_read, - write:cpustate_write, - fasync:NULL, - poll:NULL, - ioctl:NULL, - llseek:no_llseek, - + owner: THIS_MODULE, + open: cpustate_open, + release: cpustate_release, + read: cpustate_read, + write: cpustate_write, + fasync: NULL, + poll: NULL, + ioctl: NULL, + llseek: no_llseek, }; static struct miscdevice cpustate_dev = { MISC_DYNAMIC_MINOR, "sky_cpustate", - &cpustate_fops + &cpustate_fops, }; static int hdpu_cpustate_probe(struct platform_device *pdev) @@ -199,18 +198,18 @@ static int hdpu_cpustate_probe(struct platform_device *pdev) ret = misc_register(&cpustate_dev); if (ret) { - printk(KERN_WARNING "sky_cpustate: Unable to register misc " - "device.\n"); + printk(KERN_WARNING "sky_cpustate: " + "Unable to register misc device.\n"); cpustate.set_addr = NULL; cpustate.clr_addr = NULL; return ret; } proc_de = create_proc_read_entry("sky_cpustate", 0, 0, - cpustate_read_proc, NULL); + cpustate_read_proc, NULL); if (proc_de == NULL) - printk(KERN_WARNING "sky_cpustate: Unable to create proc " - "dir entry\n"); + printk(KERN_WARNING "sky_cpustate: " + "Unable to create proc dir entry\n"); printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n"); return 0; @@ -218,21 +217,18 @@ static int hdpu_cpustate_probe(struct platform_device *pdev) static int hdpu_cpustate_remove(struct platform_device *pdev) { - cpustate.set_addr = NULL; cpustate.clr_addr = NULL; remove_proc_entry("sky_cpustate", NULL); misc_deregister(&cpustate_dev); - return 0; + return 0; } static int __init cpustate_init(void) { - int rc; - rc = platform_driver_register(&hdpu_cpustate_driver); - return rc; + return platform_driver_register(&hdpu_cpustate_driver); } static void __exit cpustate_exit(void) diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index 60c8b26f0678..fd3f3c22115f 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -40,40 +40,43 @@ static struct platform_driver hdpu_nexus_driver = { int hdpu_slot_id_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *zero, void *ptr) { - if (offset > 0) return 0; + return sprintf(buffer, "%d\n", slot_id); } int hdpu_chassis_id_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *zero, void *ptr) { - if (offset > 0) return 0; + return sprintf(buffer, "%d\n", chassis_id); } static int hdpu_nexus_probe(struct platform_device *pdev) { struct resource *res; + int *nexus_id_addr; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - int *nexus_id_addr; - nexus_id_addr = - ioremap(res->start, (unsigned long)(res->end - res->start)); + nexus_id_addr = ioremap(res->start, + (unsigned long)(res->end - res->start)); if (nexus_id_addr) { slot_id = (*nexus_id_addr >> 8) & 0x1f; chassis_id = *nexus_id_addr & 0xff; iounmap(nexus_id_addr); - } else - printk("Could not map slot id\n"); + } else { + printk(KERN_ERR "Could not map slot id\n"); + } + hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root); hdpu_slot_id->read_proc = hdpu_slot_id_read; hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root); hdpu_chassis_id->read_proc = hdpu_chassis_id_read; + return 0; } @@ -81,18 +84,19 @@ static int hdpu_nexus_remove(struct platform_device *pdev) { slot_id = -1; chassis_id = -1; + remove_proc_entry("sky_slot_id", &proc_root); remove_proc_entry("sky_chassis_id", &proc_root); + hdpu_slot_id = 0; hdpu_chassis_id = 0; + return 0; } static int __init nexus_init(void) { - int rc; - rc = platform_driver_register(&hdpu_nexus_driver); - return rc; + return platform_driver_register(&hdpu_nexus_driver); } static void __exit nexus_exit(void) -- cgit v1.2.3 From d2ceb47a7cbcc50b45832c6b24c47515838d169a Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 2 Oct 2007 13:30:06 -0700 Subject: [POWERPC] Sky Cpu and Nexus: include io.h Add #include directive to properly declare ioremap() and writel(). Signed-off-by: Cyrill Gorcunov Cc: Benjamin Herrenschmidt Cc: Kumar Gala Cc: Brian Waite Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/misc/hdpuftrs/hdpu_cpustate.c | 1 + drivers/misc/hdpuftrs/hdpu_nexus.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index 1874b0740f2b..b5c6f21dcb69 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -22,6 +22,7 @@ #include #include #include +#include #define SKY_CPUSTATE_VERSION "1.1" diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index fd3f3c22115f..fda9998f45ca 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -20,6 +20,7 @@ #include #include +#include static int hdpu_nexus_probe(struct platform_device *pdev); static int hdpu_nexus_remove(struct platform_device *pdev); -- cgit v1.2.3 From 7472fd36a87e84c2819066543224285a6ab79ffc Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 2 Oct 2007 13:30:06 -0700 Subject: [POWERPC] Sky Cpu and Nexus: check for platform_get_resource retcode Add adds checking for platform_get_resource() return code to prevent possible NULL pointer usage. Signed-off-by: Cyrill Gorcunov Cc: Benjamin Herrenschmidt Cc: Kumar Gala Cc: Brian Waite Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/misc/hdpuftrs/hdpu_cpustate.c | 5 +++++ drivers/misc/hdpuftrs/hdpu_nexus.c | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index b5c6f21dcb69..b16742c7c69d 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -194,6 +194,11 @@ static int hdpu_cpustate_probe(struct platform_device *pdev) int ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + printk(KERN_ERR "sky_cpustate: " + "Invalid memory resource.\n"); + return -EINVAL; + } cpustate.set_addr = (unsigned long *)res->start; cpustate.clr_addr = (unsigned long *)res->end - 1; diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index fda9998f45ca..01bc9179603b 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -62,6 +62,11 @@ static int hdpu_nexus_probe(struct platform_device *pdev) int *nexus_id_addr; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + printk(KERN_ERR "sky_nexus: " + "Invalid memory resource.\n"); + return -EINVAL; + } nexus_id_addr = ioremap(res->start, (unsigned long)(res->end - res->start)); if (nexus_id_addr) { @@ -69,7 +74,7 @@ static int hdpu_nexus_probe(struct platform_device *pdev) chassis_id = *nexus_id_addr & 0xff; iounmap(nexus_id_addr); } else { - printk(KERN_ERR "Could not map slot id\n"); + printk(KERN_ERR "sky_nexus: Could not map slot id\n"); } hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root); -- cgit v1.2.3 From 5f725fe92cc2e75892b237e863d5f695fb634bb2 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 2 Oct 2007 13:30:07 -0700 Subject: [POWERPC] Sky Cpu and Nexus: check for create_proc_entry ret code Adds checking of create_proc_entry call to prevent possible NULL pointer usage. Signed-off-by: Cyrill Gorcunov Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Kumar Gala Cc: Brian Waite Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/misc/hdpuftrs/hdpu_nexus.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index 01bc9179603b..cc818532c7ec 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -78,10 +78,20 @@ static int hdpu_nexus_probe(struct platform_device *pdev) } hdpu_slot_id = create_proc_entry("sky_slot_id", 0666, &proc_root); - hdpu_slot_id->read_proc = hdpu_slot_id_read; + if (!hdpu_slot_id) { + printk(KERN_WARNING "sky_nexus: " + "Unable to create proc dir entry: sky_slot_id\n"); + } else { + hdpu_slot_id->read_proc = hdpu_slot_id_read; + } hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root); - hdpu_chassis_id->read_proc = hdpu_chassis_id_read; + if (!hdpu_chassis_id) { + printk(KERN_WARNING "sky_nexus: " + "Unable to create proc dir entry: sky_chassis_id\n"); + } else { + hdpu_chassis_id->read_proc = hdpu_chassis_id_read; + } return 0; } -- cgit v1.2.3 From 8b70da1a094fb781d49a811fd2368907adc92b8d Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 2 Oct 2007 13:30:08 -0700 Subject: [POWERPC] Sky Cpu: use C99 style for struct init This changes structure item init format to C99, and removes useless structure items init. Signed-off-by: Cyrill Gorcunov Cc: Benjamin Herrenschmidt Cc: Kumar Gala Cc: Brian Waite Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/misc/hdpuftrs/hdpu_cpustate.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index b16742c7c69d..32f65a3e07ce 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -170,21 +170,18 @@ static struct platform_driver hdpu_cpustate_driver = { * The various file operations we support. */ static const struct file_operations cpustate_fops = { - owner: THIS_MODULE, - open: cpustate_open, - release: cpustate_release, - read: cpustate_read, - write: cpustate_write, - fasync: NULL, - poll: NULL, - ioctl: NULL, - llseek: no_llseek, + .owner = THIS_MODULE, + .open = cpustate_open, + .release = cpustate_release, + .read = cpustate_read, + .write = cpustate_write, + .llseek = no_llseek, }; static struct miscdevice cpustate_dev = { - MISC_DYNAMIC_MINOR, - "sky_cpustate", - &cpustate_fops, + .minor = MISC_DYNAMIC_MINOR, + .name = "sky_cpustate", + .fops = &cpustate_fops, }; static int hdpu_cpustate_probe(struct platform_device *pdev) -- cgit v1.2.3 From 3049ea7e04408abf35dc295014cb6f1eabcf9b8c Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Tue, 2 Oct 2007 13:30:09 -0700 Subject: [POWERPC] Sky Cpu and Nexus: use seq_file/single_open on proc interface This patch changes proc interface to be used with single_file/seq_open calls. Signed-off-by: Cyrill Gorcunov Signed-off-by: Andrew Morton Signed-off-by: Paul Mackerras --- drivers/misc/hdpuftrs/hdpu_cpustate.c | 66 +++++++++++++++++++---------------- drivers/misc/hdpuftrs/hdpu_nexus.c | 52 ++++++++++++++++++++------- 2 files changed, 74 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index 32f65a3e07ce..aa8ce7abe922 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -19,9 +19,10 @@ #include #include #include +#include #include #include -#include +#include #include #define SKY_CPUSTATE_VERSION "1.1" @@ -29,7 +30,30 @@ static int hdpu_cpustate_probe(struct platform_device *pdev); static int hdpu_cpustate_remove(struct platform_device *pdev); -struct cpustate_t cpustate; +static unsigned char cpustate_get_state(void); +static int cpustate_proc_open(struct inode *inode, struct file *file); +static int cpustate_proc_read(struct seq_file *seq, void *offset); + +static struct cpustate_t cpustate; + +static const struct file_operations proc_cpustate = { + .open = cpustate_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int cpustate_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, cpustate_proc_read, NULL); +} + +static int cpustate_proc_read(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "CPU State: %04x\n", cpustate_get_state()); + return 0; +} static int cpustate_get_ref(int excl) { @@ -67,13 +91,13 @@ static int cpustate_free_ref(void) return 0; } -unsigned char cpustate_get_state(void) +static unsigned char cpustate_get_state(void) { return cpustate.cached_val; } -void cpustate_set_state(unsigned char new_state) +static void cpustate_set_state(unsigned char new_state) { unsigned int state = (new_state << 21); @@ -135,29 +159,6 @@ static int cpustate_release(struct inode *inode, struct file *file) return cpustate_free_ref(); } -/* - * Info exported via "/proc/sky_cpustate". - */ -static int cpustate_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - int len = 0; - - p += sprintf(p, "CPU State: %04x\n", cpustate_get_state()); - len = p - page; - - if (len <= off + count) - *eof = 1; - *start = page + off; - len -= off; - if (len > count) - len = count; - if (len < 0) - len = 0; - return len; -} - static struct platform_driver hdpu_cpustate_driver = { .probe = hdpu_cpustate_probe, .remove = hdpu_cpustate_remove, @@ -208,11 +209,14 @@ static int hdpu_cpustate_probe(struct platform_device *pdev) return ret; } - proc_de = create_proc_read_entry("sky_cpustate", 0, 0, - cpustate_read_proc, NULL); - if (proc_de == NULL) + proc_de = create_proc_entry("sky_cpustate", 0666, &proc_root); + if (!proc_de) { printk(KERN_WARNING "sky_cpustate: " - "Unable to create proc dir entry\n"); + "Unable to create proc entry\n"); + } else { + proc_de->proc_fops = &proc_cpustate; + proc_de->owner = THIS_MODULE; + } printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n"); return 0; diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index cc818532c7ec..2887b2147980 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -18,18 +18,38 @@ #include #include #include - #include +#include #include static int hdpu_nexus_probe(struct platform_device *pdev); static int hdpu_nexus_remove(struct platform_device *pdev); +static int hdpu_slot_id_open(struct inode *inode, struct file *file); +static int hdpu_slot_id_read(struct seq_file *seq, void *offset); +static int hdpu_chassis_id_open(struct inode *inode, struct file *file); +static int hdpu_chassis_id_read(struct seq_file *seq, void *offset); static struct proc_dir_entry *hdpu_slot_id; static struct proc_dir_entry *hdpu_chassis_id; static int slot_id = -1; static int chassis_id = -1; +static const struct file_operations proc_slot_id = { + .open = hdpu_slot_id_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static const struct file_operations proc_chassis_id = { + .open = hdpu_chassis_id_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + static struct platform_driver hdpu_nexus_driver = { .probe = hdpu_nexus_probe, .remove = hdpu_nexus_remove, @@ -38,22 +58,26 @@ static struct platform_driver hdpu_nexus_driver = { }, }; -int hdpu_slot_id_read(char *buffer, char **buffer_location, off_t offset, - int buffer_length, int *zero, void *ptr) +static int hdpu_slot_id_open(struct inode *inode, struct file *file) { - if (offset > 0) - return 0; + return single_open(file, hdpu_slot_id_read, NULL); +} - return sprintf(buffer, "%d\n", slot_id); +static int hdpu_slot_id_read(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n", slot_id); + return 0; } -int hdpu_chassis_id_read(char *buffer, char **buffer_location, off_t offset, - int buffer_length, int *zero, void *ptr) +static int hdpu_chassis_id_open(struct inode *inode, struct file *file) { - if (offset > 0) - return 0; + return single_open(file, hdpu_chassis_id_read, NULL); +} - return sprintf(buffer, "%d\n", chassis_id); +static int hdpu_chassis_id_read(struct seq_file *seq, void *offset) +{ + seq_printf(seq, "%d\n", chassis_id); + return 0; } static int hdpu_nexus_probe(struct platform_device *pdev) @@ -82,7 +106,8 @@ static int hdpu_nexus_probe(struct platform_device *pdev) printk(KERN_WARNING "sky_nexus: " "Unable to create proc dir entry: sky_slot_id\n"); } else { - hdpu_slot_id->read_proc = hdpu_slot_id_read; + hdpu_slot_id->proc_fops = &proc_slot_id; + hdpu_slot_id->owner = THIS_MODULE; } hdpu_chassis_id = create_proc_entry("sky_chassis_id", 0666, &proc_root); @@ -90,7 +115,8 @@ static int hdpu_nexus_probe(struct platform_device *pdev) printk(KERN_WARNING "sky_nexus: " "Unable to create proc dir entry: sky_chassis_id\n"); } else { - hdpu_chassis_id->read_proc = hdpu_chassis_id_read; + hdpu_chassis_id->proc_fops = &proc_chassis_id; + hdpu_chassis_id->owner = THIS_MODULE; } return 0; -- cgit v1.2.3 From a15da8eff3627b8368db7f5dd260e5643213d918 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 2 Oct 2007 12:15:39 +1000 Subject: [POWERPC] Uartlite: Fix reg io to access documented register size The Uartlite data sheet defines the registers as 32 bit wide. This patch changes the register access to use 32 bit transfers and eliminates the magic +3 offset which is currently required to make the device work. Signed-off-by: Grant Likely Acked-by: John Williams Signed-off-by: Josh Boyer --- drivers/serial/uartlite.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index f5051cf1a0c8..59b674aa2c01 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -61,7 +61,7 @@ static int ulite_receive(struct uart_port *port, int stat) /* stats */ if (stat & ULITE_STATUS_RXVALID) { port->icount.rx++; - ch = readb(port->membase + ULITE_RX); + ch = in_be32((void*)port->membase + ULITE_RX); if (stat & ULITE_STATUS_PARITY) port->icount.parity++; @@ -106,7 +106,7 @@ static int ulite_transmit(struct uart_port *port, int stat) return 0; if (port->x_char) { - writeb(port->x_char, port->membase + ULITE_TX); + out_be32((void*)port->membase + ULITE_TX, port->x_char); port->x_char = 0; port->icount.tx++; return 1; @@ -115,7 +115,7 @@ static int ulite_transmit(struct uart_port *port, int stat) if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return 0; - writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX); + out_be32((void*)port->membase + ULITE_TX, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); port->icount.tx++; @@ -132,7 +132,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) int busy; do { - int stat = readb(port->membase + ULITE_STATUS); + int stat = in_be32((void*)port->membase + ULITE_STATUS); busy = ulite_receive(port, stat); busy |= ulite_transmit(port, stat); } while (busy); @@ -148,7 +148,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port) unsigned int ret; spin_lock_irqsave(&port->lock, flags); - ret = readb(port->membase + ULITE_STATUS); + ret = in_be32((void*)port->membase + ULITE_STATUS); spin_unlock_irqrestore(&port->lock, flags); return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; @@ -171,7 +171,7 @@ static void ulite_stop_tx(struct uart_port *port) static void ulite_start_tx(struct uart_port *port) { - ulite_transmit(port, readb(port->membase + ULITE_STATUS)); + ulite_transmit(port, in_be32((void*)port->membase + ULITE_STATUS)); } static void ulite_stop_rx(struct uart_port *port) @@ -200,17 +200,17 @@ static int ulite_startup(struct uart_port *port) if (ret) return ret; - writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, - port->membase + ULITE_CONTROL); - writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); + out_be32((void*)port->membase + ULITE_CONTROL, + ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); + out_be32((void*)port->membase + ULITE_CONTROL, ULITE_CONTROL_IE); return 0; } static void ulite_shutdown(struct uart_port *port) { - writeb(0, port->membase + ULITE_CONTROL); - readb(port->membase + ULITE_CONTROL); /* dummy */ + out_be32((void*)port->membase + ULITE_CONTROL, 0); + in_be32((void*)port->membase + ULITE_CONTROL); /* dummy */ free_irq(port->irq, port); } @@ -314,7 +314,7 @@ static void ulite_console_wait_tx(struct uart_port *port) /* wait up to 10ms for the character(s) to be sent */ for (i = 0; i < 10000; i++) { - if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY) + if (in_be32((void*)port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY) break; udelay(1); } @@ -323,7 +323,7 @@ static void ulite_console_wait_tx(struct uart_port *port) static void ulite_console_putchar(struct uart_port *port, int ch) { ulite_console_wait_tx(port); - writeb(ch, port->membase + ULITE_TX); + out_be32((void*)port->membase + ULITE_TX, ch); } static void ulite_console_write(struct console *co, const char *s, @@ -340,8 +340,8 @@ static void ulite_console_write(struct console *co, const char *s, spin_lock_irqsave(&port->lock, flags); /* save and disable interrupt */ - ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; - writeb(0, port->membase + ULITE_CONTROL); + ier = in_be32((void*)port->membase + ULITE_STATUS) & ULITE_STATUS_IE; + out_be32((void*)port->membase + ULITE_CONTROL, 0); uart_console_write(port, s, count, ulite_console_putchar); @@ -349,7 +349,7 @@ static void ulite_console_write(struct console *co, const char *s, /* restore interrupt state */ if (ier) - writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); + out_be32((void*)port->membase + ULITE_CONTROL, ULITE_CONTROL_IE); if (locked) spin_unlock_irqrestore(&port->lock, flags); -- cgit v1.2.3 From 483c79db95b56a9650bd6f0638e7366eb20ffc01 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 2 Oct 2007 12:15:44 +1000 Subject: [POWERPC] Uartlite: change name of ports to ulite_ports Changed to match naming convention used in the rest of the module Signed-off-by: Grant Likely Signed-off-by: Josh Boyer --- drivers/serial/uartlite.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 59b674aa2c01..ae05a67d9dbe 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -46,7 +46,7 @@ #define ULITE_CONTROL_IE 0x10 -static struct uart_port ports[ULITE_NR_UARTS]; +static struct uart_port ulite_ports[ULITE_NR_UARTS]; static int ulite_receive(struct uart_port *port, int stat) { @@ -329,7 +329,7 @@ static void ulite_console_putchar(struct uart_port *port, int ch) static void ulite_console_write(struct console *co, const char *s, unsigned int count) { - struct uart_port *port = &ports[co->index]; + struct uart_port *port = &ulite_ports[co->index]; unsigned long flags; unsigned int ier; int locked = 1; @@ -366,7 +366,7 @@ static int __init ulite_console_setup(struct console *co, char *options) if (co->index < 0 || co->index >= ULITE_NR_UARTS) return -EINVAL; - port = &ports[co->index]; + port = &ulite_ports[co->index]; /* not initialized yet? */ if (!port->membase) @@ -420,7 +420,7 @@ static int __devinit ulite_probe(struct platform_device *pdev) if (pdev->id < 0 || pdev->id >= ULITE_NR_UARTS) return -EINVAL; - if (ports[pdev->id].membase) + if (ulite_ports[pdev->id].membase) return -EBUSY; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -431,7 +431,7 @@ static int __devinit ulite_probe(struct platform_device *pdev) if (!res2) return -ENODEV; - port = &ports[pdev->id]; + port = &ulite_ports[pdev->id]; port->fifosize = 16; port->regshift = 2; -- cgit v1.2.3 From 00775828e66124b4af54fafc393e5e89248802c9 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 2 Oct 2007 12:15:49 +1000 Subject: [POWERPC] Uartlite: Add macro for uartlite device name Changed to make the following OF_platform bus binding patch a wee bit cleaner Signed-off-by: Grant Likely Signed-off-by: Josh Boyer --- drivers/serial/uartlite.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index ae05a67d9dbe..10e0da97811e 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -18,6 +18,7 @@ #include #include +#define ULITE_NAME "ttyUL" #define ULITE_MAJOR 204 #define ULITE_MINOR 187 #define ULITE_NR_UARTS 4 @@ -381,7 +382,7 @@ static int __init ulite_console_setup(struct console *co, char *options) static struct uart_driver ulite_uart_driver; static struct console ulite_console = { - .name = "ttyUL", + .name = ULITE_NAME, .write = ulite_console_write, .device = uart_console_device, .setup = ulite_console_setup, @@ -403,7 +404,7 @@ console_initcall(ulite_console_init); static struct uart_driver ulite_uart_driver = { .owner = THIS_MODULE, .driver_name = "uartlite", - .dev_name = "ttyUL", + .dev_name = ULITE_NAME, .major = ULITE_MAJOR, .minor = ULITE_MINOR, .nr = ULITE_NR_UARTS, -- cgit v1.2.3 From 8fa7b6100693e0b648ffd34564f6f41226502a19 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 2 Oct 2007 12:15:54 +1000 Subject: [POWERPC] Uartlite: Separate the bus binding from the driver proper Separate the bus binding code from the driver structure allocation code in preparation for adding the of_platform_bus bindings needed by arch/powerpc Signed-off-by: Grant Likely Signed-off-by: Josh Boyer --- drivers/serial/uartlite.c | 99 +++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 10e0da97811e..c00a627ef89e 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -413,59 +413,90 @@ static struct uart_driver ulite_uart_driver = { #endif }; -static int __devinit ulite_probe(struct platform_device *pdev) +static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq) { - struct resource *res, *res2; struct uart_port *port; + int rc; - if (pdev->id < 0 || pdev->id >= ULITE_NR_UARTS) + /* if id = -1; then scan for a free id and use that */ + if (id < 0) { + for (id = 0; id < ULITE_NR_UARTS; id++) + if (ulite_ports[id].mapbase == 0) + break; + } + if (id < 0 || id >= ULITE_NR_UARTS) { + dev_err(dev, "%s%i too large\n", ULITE_NAME, id); return -EINVAL; + } - if (ulite_ports[pdev->id].membase) + if (ulite_ports[id].mapbase) { + dev_err(dev, "cannot assign to %s%i; it is already in use\n", + ULITE_NAME, id); return -EBUSY; + } - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; + port = &ulite_ports[id]; - res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res2) - return -ENODEV; + spin_lock_init(&port->lock); + port->fifosize = 16; + port->regshift = 2; + port->iotype = UPIO_MEM; + port->iobase = 1; /* mark port in use */ + port->mapbase = base; + port->membase = NULL; + port->ops = &ulite_ops; + port->irq = irq; + port->flags = UPF_BOOT_AUTOCONF; + port->dev = dev; + port->type = PORT_UNKNOWN; + port->line = id; + + dev_set_drvdata(dev, port); + + /* Register the port */ + rc = uart_add_one_port(&ulite_uart_driver, port); + if (rc) { + dev_err(dev, "uart_add_one_port() failed; err=%i\n", rc); + port->mapbase = 0; + dev_set_drvdata(dev, NULL); + return rc; + } - port = &ulite_ports[pdev->id]; + return 0; +} - port->fifosize = 16; - port->regshift = 2; - port->iotype = UPIO_MEM; - port->iobase = 1; /* mark port in use */ - port->mapbase = res->start; - port->membase = NULL; - port->ops = &ulite_ops; - port->irq = res2->start; - port->flags = UPF_BOOT_AUTOCONF; - port->dev = &pdev->dev; - port->type = PORT_UNKNOWN; - port->line = pdev->id; +static int __devinit ulite_release(struct device *dev) +{ + struct uart_port *port = dev_get_drvdata(dev); + int rc = 0; - uart_add_one_port(&ulite_uart_driver, port); - platform_set_drvdata(pdev, port); + if (port) { + rc = uart_remove_one_port(&ulite_uart_driver, port); + dev_set_drvdata(dev, NULL); + port->mapbase = 0; + } - return 0; + return rc; } -static int ulite_remove(struct platform_device *pdev) +static int __devinit ulite_probe(struct platform_device *pdev) { - struct uart_port *port = platform_get_drvdata(pdev); + struct resource *res, *res2; - platform_set_drvdata(pdev, NULL); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; - if (port) - uart_remove_one_port(&ulite_uart_driver, port); + res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res2) + return -ENODEV; - /* mark port as free */ - port->membase = NULL; + return ulite_assign(&pdev->dev, pdev->id, res->start, res2->start); +} - return 0; +static int ulite_remove(struct platform_device *pdev) +{ + return ulite_release(&pdev->dev); } static struct platform_driver ulite_platform_driver = { -- cgit v1.2.3 From 435706b385d1f5422e44ee86b5dec0a2150eca02 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 2 Oct 2007 12:15:59 +1000 Subject: [POWERPC] Uartlite: Comment block tidy Tidy the comments to split the driver into logical section; the main driver, the console driver, the platform bus binding, and module initialization and teardown. Signed-off-by: Grant Likely Signed-off-by: Josh Boyer --- drivers/serial/uartlite.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index c00a627ef89e..ed13b9fac1af 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -23,9 +23,13 @@ #define ULITE_MINOR 187 #define ULITE_NR_UARTS 4 -/* For register details see datasheet: - http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf -*/ +/* --------------------------------------------------------------------- + * Register definitions + * + * For register details see datasheet: + * http://www.xilinx.com/bvdocs/ipcenter/data_sheet/opb_uartlite.pdf + */ + #define ULITE_RX 0x00 #define ULITE_TX 0x04 #define ULITE_STATUS 0x08 @@ -49,6 +53,10 @@ static struct uart_port ulite_ports[ULITE_NR_UARTS]; +/* --------------------------------------------------------------------- + * Core UART driver operations + */ + static int ulite_receive(struct uart_port *port, int stat) { struct tty_struct *tty = port->info->tty; @@ -308,6 +316,10 @@ static struct uart_ops ulite_ops = { .verify_port = ulite_verify_port }; +/* --------------------------------------------------------------------- + * Console driver operations + */ + #ifdef CONFIG_SERIAL_UARTLITE_CONSOLE static void ulite_console_wait_tx(struct uart_port *port) { @@ -413,6 +425,19 @@ static struct uart_driver ulite_uart_driver = { #endif }; +/* --------------------------------------------------------------------- + * Port assignment functions (mapping devices to uart_port structures) + */ + +/** ulite_assign: register a uartlite device with the driver + * + * @dev: pointer to device structure + * @id: requested id number. Pass -1 for automatic port assignment + * @base: base address of uartlite registers + * @irq: irq number for uartlite + * + * Returns: 0 on success, <0 otherwise + */ static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq) { struct uart_port *port; @@ -465,6 +490,10 @@ static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq) return 0; } +/** ulite_release: register a uartlite device with the driver + * + * @dev: pointer to device structure + */ static int __devinit ulite_release(struct device *dev) { struct uart_port *port = dev_get_drvdata(dev); @@ -479,6 +508,10 @@ static int __devinit ulite_release(struct device *dev) return rc; } +/* --------------------------------------------------------------------- + * Platform bus binding + */ + static int __devinit ulite_probe(struct platform_device *pdev) { struct resource *res, *res2; @@ -508,6 +541,10 @@ static struct platform_driver ulite_platform_driver = { }, }; +/* --------------------------------------------------------------------- + * Module setup/teardown + */ + int __init ulite_init(void) { int ret; -- cgit v1.2.3 From 852e1ea748e83eba7fdb1cc198f271837b16137b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 2 Oct 2007 12:16:04 +1000 Subject: [POWERPC] Uartlite: Add of-platform-bus binding Add of_platform bus binding so this driver can be used with arch/powerpc Signed-off-by: Grant Likely Signed-off-by: Josh Boyer --- drivers/serial/uartlite.c | 96 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index ed13b9fac1af..0904c2a62fc4 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -1,7 +1,8 @@ /* * uartlite.c: Serial driver for Xilinx uartlite serial controller * - * Peter Korsgaard + * Copyright (C) 2006 Peter Korsgaard + * Copyright (C) 2007 Secret Lab Technologies Ltd. * * This file is licensed under the terms of the GNU General Public License * version 2. This program is licensed "as is" without any warranty of any @@ -17,6 +18,10 @@ #include #include #include +#if defined(CONFIG_OF) +#include +#include +#endif #define ULITE_NAME "ttyUL" #define ULITE_MAJOR 204 @@ -382,8 +387,10 @@ static int __init ulite_console_setup(struct console *co, char *options) port = &ulite_ports[co->index]; /* not initialized yet? */ - if (!port->membase) + if (!port->membase) { + pr_debug("console on ttyUL%i not initialized\n", co->index); return -ENODEV; + } if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); @@ -541,6 +548,72 @@ static struct platform_driver ulite_platform_driver = { }, }; +/* --------------------------------------------------------------------- + * OF bus bindings + */ +#if defined(CONFIG_OF) +static int __devinit +ulite_of_probe(struct of_device *op, const struct of_device_id *match) +{ + struct resource res; + const unsigned int *id; + int irq, rc; + + dev_dbg(&op->dev, "%s(%p, %p)\n", __FUNCTION__, op, match); + + rc = of_address_to_resource(op->node, 0, &res); + if (rc) { + dev_err(&op->dev, "invalide address\n"); + return rc; + } + + irq = irq_of_parse_and_map(op->node, 0); + + id = of_get_property(op->node, "port-number", NULL); + + return ulite_assign(&op->dev, id ? *id : -1, res.start, irq); +} + +static int __devexit ulite_of_remove(struct of_device *op) +{ + return ulite_release(&op->dev); +} + +/* Match table for of_platform binding */ +static struct of_device_id __devinit ulite_of_match[] = { + { .type = "serial", .compatible = "xilinx,uartlite", }, + {}, +}; +MODULE_DEVICE_TABLE(of, ulite_of_match); + +static struct of_platform_driver ulite_of_driver = { + .owner = THIS_MODULE, + .name = "uartlite", + .match_table = ulite_of_match, + .probe = ulite_of_probe, + .remove = __devexit_p(ulite_of_remove), + .driver = { + .name = "uartlite", + }, +}; + +/* Registration helpers to keep the number of #ifdefs to a minimum */ +static inline int __init ulite_of_register(void) +{ + pr_debug("uartlite: calling of_register_platform_driver()\n"); + return of_register_platform_driver(&ulite_of_driver); +} + +static inline void __exit ulite_of_unregister(void) +{ + of_unregister_platform_driver(&ulite_of_driver); +} +#else /* CONFIG_OF */ +/* CONFIG_OF not enabled; do nothing helpers */ +static inline int __init ulite_of_register(void) { return 0; } +static inline void __exit ulite_of_unregister(void) { } +#endif /* CONFIG_OF */ + /* --------------------------------------------------------------------- * Module setup/teardown */ @@ -549,20 +622,35 @@ int __init ulite_init(void) { int ret; + pr_debug("uartlite: calling uart_register_driver()\n"); ret = uart_register_driver(&ulite_uart_driver); if (ret) - return ret; + goto err_uart; + + ret = ulite_of_register(); + if (ret) + goto err_of; + pr_debug("uartlite: calling platform_driver_register()\n"); ret = platform_driver_register(&ulite_platform_driver); if (ret) - uart_unregister_driver(&ulite_uart_driver); + goto err_plat; + + return 0; +err_plat: + ulite_of_unregister(); +err_of: + uart_unregister_driver(&ulite_uart_driver); +err_uart: + printk(KERN_ERR "registering uartlite driver failed: err=%i", ret); return ret; } void __exit ulite_exit(void) { platform_driver_unregister(&ulite_platform_driver); + ulite_of_unregister(); uart_unregister_driver(&ulite_uart_driver); } -- cgit v1.2.3 From fb4e6e663b404ecdfac2e3f6e643d204488b28e9 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Tue, 2 Oct 2007 12:16:09 +1000 Subject: [POWERPC] Uartlite: Let the console be initialized earlier By configuring it earlier we get console output sooner which is helpful for debugging when the kernel crashes before the serial drivers are initialized. Signed-off-by: Grant Likely Signed-off-by: Josh Boyer --- drivers/serial/uartlite.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 0904c2a62fc4..2b8404c81164 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -373,6 +373,31 @@ static void ulite_console_write(struct console *co, const char *s, spin_unlock_irqrestore(&port->lock, flags); } +#if defined(CONFIG_OF) +static inline void __init ulite_console_of_find_device(int id) +{ + struct device_node *np; + struct resource res; + const unsigned int *of_id; + int rc; + + for_each_compatible_node(np, NULL, "xilinx,uartlite") { + of_id = of_get_property(np, "port-number", NULL); + if ((!of_id) || (*of_id != id)) + continue; + + rc = of_address_to_resource(np, 0, &res); + if (rc) + continue; + + ulite_ports[id].mapbase = res.start; + return; + } +} +#else /* CONFIG_OF */ +static inline void __init ulite_console_of_find_device(int id) { /* do nothing */ } +#endif /* CONFIG_OF */ + static int __init ulite_console_setup(struct console *co, char *options) { struct uart_port *port; @@ -386,10 +411,20 @@ static int __init ulite_console_setup(struct console *co, char *options) port = &ulite_ports[co->index]; + /* Check if it is an OF device */ + if (!port->mapbase) + ulite_console_of_find_device(co->index); + + /* Do we have a device now? */ + if (!port->mapbase) { + pr_debug("console on ttyUL%i not present\n", co->index); + return -ENODEV; + } + /* not initialized yet? */ if (!port->membase) { - pr_debug("console on ttyUL%i not initialized\n", co->index); - return -ENODEV; + if (ulite_request_port(port)) + return -ENODEV; } if (options) @@ -461,7 +496,7 @@ static int __devinit ulite_assign(struct device *dev, int id, u32 base, int irq) return -EINVAL; } - if (ulite_ports[id].mapbase) { + if ((ulite_ports[id].mapbase) && (ulite_ports[id].mapbase != base)) { dev_err(dev, "cannot assign to %s%i; it is already in use\n", ULITE_NAME, id); return -EBUSY; -- cgit v1.2.3 From dc8afdc7ada82562231cbae867fe6dcdb7b677f5 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 1 Oct 2007 07:47:00 +1000 Subject: [POWERPC] XilinxFB: Move xilinxfb_platform_data definition to a shared header file XilnixFB can be used by more than just arch/ppc. Move the data structure definition into include/linux/xilinxfb.h so it can be used by microblaze and arch/powerpc Signed-off-by: Grant Likely Signed-off-by: Josh Boyer --- drivers/video/xilinxfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 6ef9733a18d4..4bc67ab56afa 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -30,7 +30,7 @@ #include #include -#include +#include #define DRIVER_NAME "xilinxfb" #define DRIVER_DESCRIPTION "Xilinx TFT LCD frame buffer driver" -- cgit v1.2.3 From e077b50c29a7e8be5812d1156934ea837b712ca6 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 3 Oct 2007 02:47:02 +1000 Subject: [POWERPC] Uartlite: Revert register io access changes Reverts commit a15da8eff3627b8368db7f5dd260e5643213d918 This driver is used by devices other than the xilinx opb-uartlite which depend on bytewise access to the registers. The change to 32 bit access does not work on these devices. Signed-off-by: Grant Likely Acked-by: Peter Korsgaard Signed-off-by: Josh Boyer --- drivers/serial/uartlite.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 2b8404c81164..dfef83f14960 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c @@ -75,7 +75,7 @@ static int ulite_receive(struct uart_port *port, int stat) /* stats */ if (stat & ULITE_STATUS_RXVALID) { port->icount.rx++; - ch = in_be32((void*)port->membase + ULITE_RX); + ch = readb(port->membase + ULITE_RX); if (stat & ULITE_STATUS_PARITY) port->icount.parity++; @@ -120,7 +120,7 @@ static int ulite_transmit(struct uart_port *port, int stat) return 0; if (port->x_char) { - out_be32((void*)port->membase + ULITE_TX, port->x_char); + writeb(port->x_char, port->membase + ULITE_TX); port->x_char = 0; port->icount.tx++; return 1; @@ -129,7 +129,7 @@ static int ulite_transmit(struct uart_port *port, int stat) if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return 0; - out_be32((void*)port->membase + ULITE_TX, xmit->buf[xmit->tail]); + writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); port->icount.tx++; @@ -146,7 +146,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id) int busy; do { - int stat = in_be32((void*)port->membase + ULITE_STATUS); + int stat = readb(port->membase + ULITE_STATUS); busy = ulite_receive(port, stat); busy |= ulite_transmit(port, stat); } while (busy); @@ -162,7 +162,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port) unsigned int ret; spin_lock_irqsave(&port->lock, flags); - ret = in_be32((void*)port->membase + ULITE_STATUS); + ret = readb(port->membase + ULITE_STATUS); spin_unlock_irqrestore(&port->lock, flags); return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0; @@ -185,7 +185,7 @@ static void ulite_stop_tx(struct uart_port *port) static void ulite_start_tx(struct uart_port *port) { - ulite_transmit(port, in_be32((void*)port->membase + ULITE_STATUS)); + ulite_transmit(port, readb(port->membase + ULITE_STATUS)); } static void ulite_stop_rx(struct uart_port *port) @@ -214,17 +214,17 @@ static int ulite_startup(struct uart_port *port) if (ret) return ret; - out_be32((void*)port->membase + ULITE_CONTROL, - ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); - out_be32((void*)port->membase + ULITE_CONTROL, ULITE_CONTROL_IE); + writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, + port->membase + ULITE_CONTROL); + writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); return 0; } static void ulite_shutdown(struct uart_port *port) { - out_be32((void*)port->membase + ULITE_CONTROL, 0); - in_be32((void*)port->membase + ULITE_CONTROL); /* dummy */ + writeb(0, port->membase + ULITE_CONTROL); + readb(port->membase + ULITE_CONTROL); /* dummy */ free_irq(port->irq, port); } @@ -332,7 +332,7 @@ static void ulite_console_wait_tx(struct uart_port *port) /* wait up to 10ms for the character(s) to be sent */ for (i = 0; i < 10000; i++) { - if (in_be32((void*)port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY) + if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY) break; udelay(1); } @@ -341,7 +341,7 @@ static void ulite_console_wait_tx(struct uart_port *port) static void ulite_console_putchar(struct uart_port *port, int ch) { ulite_console_wait_tx(port); - out_be32((void*)port->membase + ULITE_TX, ch); + writeb(ch, port->membase + ULITE_TX); } static void ulite_console_write(struct console *co, const char *s, @@ -358,8 +358,8 @@ static void ulite_console_write(struct console *co, const char *s, spin_lock_irqsave(&port->lock, flags); /* save and disable interrupt */ - ier = in_be32((void*)port->membase + ULITE_STATUS) & ULITE_STATUS_IE; - out_be32((void*)port->membase + ULITE_CONTROL, 0); + ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE; + writeb(0, port->membase + ULITE_CONTROL); uart_console_write(port, s, count, ulite_console_putchar); @@ -367,7 +367,7 @@ static void ulite_console_write(struct console *co, const char *s, /* restore interrupt state */ if (ier) - out_be32((void*)port->membase + ULITE_CONTROL, ULITE_CONTROL_IE); + writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL); if (locked) spin_unlock_irqrestore(&port->lock, flags); @@ -598,7 +598,7 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match) rc = of_address_to_resource(op->node, 0, &res); if (rc) { - dev_err(&op->dev, "invalide address\n"); + dev_err(&op->dev, "invalid address\n"); return rc; } @@ -606,7 +606,7 @@ ulite_of_probe(struct of_device *op, const struct of_device_id *match) id = of_get_property(op->node, "port-number", NULL); - return ulite_assign(&op->dev, id ? *id : -1, res.start, irq); + return ulite_assign(&op->dev, id ? *id : -1, res.start+3, irq); } static int __devexit ulite_of_remove(struct of_device *op) -- cgit v1.2.3 From 7ae870368d198affa249ed3382a8a288167ce885 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 17 Jul 2007 17:59:06 -0500 Subject: [POWERPC] cpm_uart: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set. The existing OF glue code was crufty and broken. Rather than fix it, it has been removed, and the serial driver now talks to the device tree directly. The non-CONFIG_PPC_CPM_NEW_BINDING code can go away once CPM platforms are dropped from arch/ppc (which will hopefully be soon), and existing arch/powerpc boards that I wasn't able to test on for this patchset get converted (which should be even sooner). Signed-off-by: Scott Wood Signed-off-by: Kumar Gala --- drivers/serial/cpm_uart/cpm_uart.h | 6 +- drivers/serial/cpm_uart/cpm_uart_core.c | 241 +++++++++++++++++++++++++++++--- drivers/serial/cpm_uart/cpm_uart_cpm1.c | 16 ++- drivers/serial/cpm_uart/cpm_uart_cpm1.h | 2 + drivers/serial/cpm_uart/cpm_uart_cpm2.c | 18 ++- drivers/serial/cpm_uart/cpm_uart_cpm2.h | 2 + 6 files changed, 260 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index a8f894c78194..4e1987adc23b 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h @@ -80,14 +80,18 @@ struct uart_cpm_port { int is_portb; /* wait on close if needed */ int wait_closing; + /* value to combine with opcode to form cpm command */ + u32 command; }; +#ifndef CONFIG_PPC_CPM_NEW_BINDING extern int cpm_uart_port_map[UART_NR]; +#endif extern int cpm_uart_nr; extern struct uart_cpm_port cpm_uart_ports[UART_NR]; /* these are located in their respective files */ -void cpm_line_cr_cmd(int line, int cmd); +void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd); int cpm_uart_init_portdesc(void); int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con); void cpm_uart_freebuf(struct uart_cpm_port *pinfo); diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index cefde58dbad2..8564ba2f3ec2 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -10,7 +10,7 @@ * Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2) * Pantelis Antoniou (panto@intracom.gr) (CPM1) * - * Copyright (C) 2004 Freescale Semiconductor, Inc. + * Copyright (C) 2004, 2007 Freescale Semiconductor, Inc. * (C) 2004 Intracom, S.A. * (C) 2005-2006 MontaVista Software, Inc. * Vitaly Bordug @@ -47,6 +47,11 @@ #include #include #include +#include + +#ifdef CONFIG_PPC_CPM_NEW_BINDING +#include +#endif #if defined(CONFIG_SERIAL_CPM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) #define SUPPORT_SYSRQ @@ -57,12 +62,6 @@ #include "cpm_uart.h" -/***********************************************************************/ - -/* Track which ports are configured as uarts */ -int cpm_uart_port_map[UART_NR]; -/* How many ports did we config as uarts */ -int cpm_uart_nr = 0; /**************************************************************/ @@ -73,6 +72,11 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); /**************************************************************/ +#ifndef CONFIG_PPC_CPM_NEW_BINDING +/* Track which ports are configured as uarts */ +int cpm_uart_port_map[UART_NR]; +/* How many ports did we config as uarts */ +int cpm_uart_nr; /* Place-holder for board-specific stuff */ struct platform_device* __attribute__ ((weak)) __init @@ -119,6 +123,7 @@ static int cpm_uart_id2nr(int id) /* not found or invalid argument */ return -1; } +#endif /* * Check, if transmit buffers are processed @@ -232,15 +237,14 @@ static void cpm_uart_enable_ms(struct uart_port *port) static void cpm_uart_break_ctl(struct uart_port *port, int break_state) { struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - int line = pinfo - cpm_uart_ports; pr_debug("CPM uart[%d]:break ctrl, break_state: %d\n", port->line, break_state); if (break_state) - cpm_line_cr_cmd(line, CPM_CR_STOP_TX); + cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); else - cpm_line_cr_cmd(line, CPM_CR_RESTART_TX); + cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); } /* @@ -407,7 +411,6 @@ static int cpm_uart_startup(struct uart_port *port) { int retval; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - int line = pinfo - cpm_uart_ports; pr_debug("CPM uart[%d]:startup\n", port->line); @@ -426,7 +429,7 @@ static int cpm_uart_startup(struct uart_port *port) } if (!(pinfo->flags & FLAG_CONSOLE)) - cpm_line_cr_cmd(line,CPM_CR_INIT_TRX); + cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); return 0; } @@ -442,7 +445,6 @@ inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo) static void cpm_uart_shutdown(struct uart_port *port) { struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - int line = pinfo - cpm_uart_ports; pr_debug("CPM uart[%d]:shutdown\n", port->line); @@ -473,9 +475,9 @@ static void cpm_uart_shutdown(struct uart_port *port) /* Shut them really down and reinit buffer descriptors */ if (IS_SMC(pinfo)) - cpm_line_cr_cmd(line, CPM_CR_STOP_TX); + cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); else - cpm_line_cr_cmd(line, CPM_CR_GRA_STOP_TX); + cpm_line_cr_cmd(pinfo, CPM_CR_GRA_STOP_TX); cpm_uart_initbd(pinfo); } @@ -595,7 +597,6 @@ static void cpm_uart_set_termios(struct uart_port *port, cpm_set_brg(pinfo->brg - 1, baud); spin_unlock_irqrestore(&port->lock, flags); - } static const char *cpm_uart_type(struct uart_port *port) @@ -742,7 +743,6 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) { - int line = pinfo - cpm_uart_ports; volatile scc_t *scp; volatile scc_uart_t *sup; @@ -783,7 +783,7 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) /* Send the CPM an initialize command. */ - cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); + cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. @@ -803,7 +803,6 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) { - int line = pinfo - cpm_uart_ports; volatile smc_t *sp; volatile smc_uart_t *up; @@ -840,7 +839,7 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) up->smc_brkec = 0; up->smc_brkcr = 1; - cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); + cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. @@ -929,6 +928,85 @@ static struct uart_ops cpm_uart_pops = { .verify_port = cpm_uart_verify_port, }; +#ifdef CONFIG_PPC_CPM_NEW_BINDING +struct uart_cpm_port cpm_uart_ports[UART_NR]; + +int cpm_uart_init_port(struct device_node *np, struct uart_cpm_port *pinfo) +{ + const u32 *data; + void __iomem *mem, __iomem *pram; + int len; + int ret; + + data = of_get_property(np, "fsl,cpm-brg", &len); + if (!data || len != 4) { + printk(KERN_ERR "CPM UART %s has no/invalid " + "fsl,cpm-brg property.\n", np->name); + return -EINVAL; + } + pinfo->brg = *data; + + data = of_get_property(np, "fsl,cpm-command", &len); + if (!data || len != 4) { + printk(KERN_ERR "CPM UART %s has no/invalid " + "fsl,cpm-command property.\n", np->name); + return -EINVAL; + } + pinfo->command = *data; + + mem = of_iomap(np, 0); + if (!mem) + return -ENOMEM; + + pram = of_iomap(np, 1); + if (!pram) { + ret = -ENOMEM; + goto out_mem; + } + + if (of_device_is_compatible(np, "fsl,cpm1-scc-uart") || + of_device_is_compatible(np, "fsl,cpm2-scc-uart")) { + pinfo->sccp = mem; + pinfo->sccup = pram; + } else if (of_device_is_compatible(np, "fsl,cpm1-smc-uart") || + of_device_is_compatible(np, "fsl,cpm2-smc-uart")) { + pinfo->flags |= FLAG_SMC; + pinfo->smcp = mem; + pinfo->smcup = pram; + } else { + ret = -ENODEV; + goto out_pram; + } + + pinfo->tx_nrfifos = TX_NUM_FIFO; + pinfo->tx_fifosize = TX_BUF_SIZE; + pinfo->rx_nrfifos = RX_NUM_FIFO; + pinfo->rx_fifosize = RX_BUF_SIZE; + + pinfo->port.uartclk = ppc_proc_freq; + pinfo->port.mapbase = (unsigned long)mem; + pinfo->port.type = PORT_CPM; + pinfo->port.ops = &cpm_uart_pops, + pinfo->port.iotype = UPIO_MEM; + spin_lock_init(&pinfo->port.lock); + + pinfo->port.irq = of_irq_to_resource(np, 0, NULL); + if (pinfo->port.irq == NO_IRQ) { + ret = -EINVAL; + goto out_pram; + } + + return cpm_uart_request_port(&pinfo->port); + +out_pram: + iounmap(pram); +out_mem: + iounmap(mem); + return ret; +} + +#else + struct uart_cpm_port cpm_uart_ports[UART_NR] = { [UART_SMC1] = { .port = { @@ -1072,6 +1150,7 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) return 0; } +#endif #ifdef CONFIG_SERIAL_CPM_CONSOLE /* @@ -1083,8 +1162,12 @@ int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con) static void cpm_uart_console_write(struct console *co, const char *s, u_int count) { +#ifdef CONFIG_PPC_CPM_NEW_BINDING + struct uart_cpm_port *pinfo = &cpm_uart_ports[co->index]; +#else struct uart_cpm_port *pinfo = &cpm_uart_ports[cpm_uart_port_map[co->index]]; +#endif unsigned int i; volatile cbd_t *bdp, *bdbase; volatile unsigned char *cp; @@ -1155,13 +1238,47 @@ static void cpm_uart_console_write(struct console *co, const char *s, static int __init cpm_uart_console_setup(struct console *co, char *options) { - struct uart_port *port; - struct uart_cpm_port *pinfo; int baud = 38400; int bits = 8; int parity = 'n'; int flow = 'n'; int ret; + struct uart_cpm_port *pinfo; + struct uart_port *port; + +#ifdef CONFIG_PPC_CPM_NEW_BINDING + struct device_node *np = NULL; + int i = 0; + + if (co->index >= UART_NR) { + printk(KERN_ERR "cpm_uart: console index %d too high\n", + co->index); + return -ENODEV; + } + + do { + np = of_find_node_by_type(np, "serial"); + if (!np) + return -ENODEV; + + if (!of_device_is_compatible(np, "fsl,cpm1-smc-uart") && + !of_device_is_compatible(np, "fsl,cpm1-scc-uart") && + !of_device_is_compatible(np, "fsl,cpm2-smc-uart") && + !of_device_is_compatible(np, "fsl,cpm2-scc-uart")) + i--; + } while (i++ != co->index); + + pinfo = &cpm_uart_ports[co->index]; + + pinfo->flags |= FLAG_CONSOLE; + port = &pinfo->port; + + ret = cpm_uart_init_port(np, pinfo); + of_node_put(np); + if (ret) + return ret; + +#else struct fs_uart_platform_info *pdata; struct platform_device* pdev = early_uart_get_pdev(co->index); @@ -1188,6 +1305,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) } pinfo->flags |= FLAG_CONSOLE; +#endif if (options) { uart_parse_options(options, &baud, &parity, &bits, &flow); @@ -1196,6 +1314,10 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) baud = 9600; } +#ifdef CONFIG_PPC_EARLY_DEBUG_CPM + udbg_putc = NULL; +#endif + if (IS_SMC(pinfo)) { pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); @@ -1252,7 +1374,81 @@ static struct uart_driver cpm_reg = { .major = SERIAL_CPM_MAJOR, .minor = SERIAL_CPM_MINOR, .cons = CPM_UART_CONSOLE, + .nr = UART_NR, +}; + +#ifdef CONFIG_PPC_CPM_NEW_BINDING +static int probe_index; + +static int __devinit cpm_uart_probe(struct of_device *ofdev, + const struct of_device_id *match) +{ + int index = probe_index++; + struct uart_cpm_port *pinfo = &cpm_uart_ports[index]; + int ret; + + pinfo->port.line = index; + + if (index >= UART_NR) + return -ENODEV; + + dev_set_drvdata(&ofdev->dev, pinfo); + + ret = cpm_uart_init_port(ofdev->node, pinfo); + if (ret) + return ret; + + return uart_add_one_port(&cpm_reg, &pinfo->port); +} + +static int __devexit cpm_uart_remove(struct of_device *ofdev) +{ + struct uart_cpm_port *pinfo = dev_get_drvdata(&ofdev->dev); + return uart_remove_one_port(&cpm_reg, &pinfo->port); +} + +static struct of_device_id cpm_uart_match[] = { + { + .compatible = "fsl,cpm1-smc-uart", + }, + { + .compatible = "fsl,cpm1-scc-uart", + }, + { + .compatible = "fsl,cpm2-smc-uart", + }, + { + .compatible = "fsl,cpm2-scc-uart", + }, + {} }; + +static struct of_platform_driver cpm_uart_driver = { + .name = "cpm_uart", + .match_table = cpm_uart_match, + .probe = cpm_uart_probe, + .remove = cpm_uart_remove, + }; + +static int __init cpm_uart_init(void) +{ + int ret = uart_register_driver(&cpm_reg); + if (ret) + return ret; + + ret = of_register_platform_driver(&cpm_uart_driver); + if (ret) + uart_unregister_driver(&cpm_reg); + + return ret; +} + +static void __exit cpm_uart_exit(void) +{ + of_unregister_platform_driver(&cpm_uart_driver); + uart_unregister_driver(&cpm_reg); +} +#else static int cpm_uart_drv_probe(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -1380,6 +1576,7 @@ static void __exit cpm_uart_exit(void) driver_unregister(&cpm_smc_uart_driver); uart_unregister_driver(&cpm_reg); } +#endif module_init(cpm_uart_init); module_exit(cpm_uart_exit); diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 8c6324ed0202..4647f55e19f1 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -49,9 +49,20 @@ /**************************************************************/ -void cpm_line_cr_cmd(int line, int cmd) +#ifdef CONFIG_PPC_CPM_NEW_BINDING +void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) +{ + u16 __iomem *cpcr = &cpmp->cp_cpcr; + + out_be16(cpcr, port->command | (cmd << 8) | CPM_CR_FLG); + while (in_be16(cpcr) & CPM_CR_FLG) + ; +} +#else +void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) { ushort val; + int line = port - cpm_uart_ports; volatile cpm8xx_t *cp = cpmp; switch (line) { @@ -114,6 +125,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) /* XXX SCC4: insert port configuration here */ pinfo->brg = 4; } +#endif /* * Allocate DP-Ram and memory buffers. We need to allocate a transmit and @@ -184,6 +196,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) cpm_dpfree(pinfo->dp_addr); } +#ifndef CONFIG_PPC_CPM_NEW_BINDING /* Setup any dynamic params in the uart desc */ int cpm_uart_init_portdesc(void) { @@ -279,3 +292,4 @@ int cpm_uart_init_portdesc(void) #endif return 0; } +#endif diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h index 2a6477834c3e..69f523a442e0 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h @@ -13,12 +13,14 @@ #include /* defines for IRQs */ +#ifndef CONFIG_PPC_CPM_NEW_BINDING #define SMC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC1) #define SMC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SMC2) #define SCC1_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC1) #define SCC2_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC2) #define SCC3_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC3) #define SCC4_IRQ (CPM_IRQ_OFFSET + CPMVEC_SCC4) +#endif static inline void cpm_set_brg(int brg, int baud) { diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 7b61d805ebe9..7ebce263ad40 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -49,9 +49,22 @@ /**************************************************************/ -void cpm_line_cr_cmd(int line, int cmd) +#ifdef CONFIG_PPC_CPM_NEW_BINDING +void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) +{ + cpm_cpm2_t __iomem *cp = cpm2_map(im_cpm); + + out_be32(&cp->cp_cpcr, port->command | cmd | CPM_CR_FLG); + while (in_be32(&cp->cp_cpcr) & CPM_CR_FLG) + ; + + cpm2_unmap(cp); +} +#else +void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) { ulong val; + int line = port - cpm_uart_ports; volatile cpm_cpm2_t *cp = cpm2_map(im_cpm); @@ -211,6 +224,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) cpm2_unmap(cpmux); cpm2_unmap(io); } +#endif /* * Allocate DP-Ram and memory buffers. We need to allocate a transmit and @@ -281,6 +295,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) cpm_dpfree(pinfo->dp_addr); } +#ifndef CONFIG_PPC_CPM_NEW_BINDING /* Setup any dynamic params in the uart desc */ int cpm_uart_init_portdesc(void) { @@ -386,3 +401,4 @@ int cpm_uart_init_portdesc(void) return 0; } +#endif diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h index 1b3219f56c81..e7717ece0831 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h @@ -13,12 +13,14 @@ #include /* defines for IRQs */ +#ifndef CONFIG_PPC_CPM_NEW_BINDING #define SMC1_IRQ SIU_INT_SMC1 #define SMC2_IRQ SIU_INT_SMC2 #define SCC1_IRQ SIU_INT_SCC1 #define SCC2_IRQ SIU_INT_SCC2 #define SCC3_IRQ SIU_INT_SCC3 #define SCC4_IRQ SIU_INT_SCC4 +#endif static inline void cpm_set_brg(int brg, int baud) { -- cgit v1.2.3 From c1dcfd9d199043ff0e8805484a736ad36d9dd04a Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 24 Jul 2007 15:53:07 -0500 Subject: [POWERPC] cpm_uart: sparse fixes Mostly a bunch of direct access to in/out conversions, plus a few cast removals, __iomem annotations, and miscellaneous cleanup. Signed-off-by: Scott Wood Signed-off-by: Kumar Gala --- drivers/serial/cpm_uart/cpm_uart.h | 42 ++--- drivers/serial/cpm_uart/cpm_uart_core.c | 299 ++++++++++++++++---------------- drivers/serial/cpm_uart/cpm_uart_cpm1.c | 2 +- drivers/serial/cpm_uart/cpm_uart_cpm1.h | 14 +- drivers/serial/cpm_uart/cpm_uart_cpm2.c | 4 +- drivers/serial/cpm_uart/cpm_uart_cpm2.h | 14 +- 6 files changed, 192 insertions(+), 183 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 4e1987adc23b..32b9737759c4 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h @@ -56,21 +56,21 @@ struct uart_cpm_port { u16 rx_fifosize; u16 tx_nrfifos; u16 tx_fifosize; - smc_t *smcp; - smc_uart_t *smcup; - scc_t *sccp; - scc_uart_t *sccup; - volatile cbd_t *rx_bd_base; - volatile cbd_t *rx_cur; - volatile cbd_t *tx_bd_base; - volatile cbd_t *tx_cur; + smc_t __iomem *smcp; + smc_uart_t __iomem *smcup; + scc_t __iomem *sccp; + scc_uart_t __iomem *sccup; + cbd_t __iomem *rx_bd_base; + cbd_t __iomem *rx_cur; + cbd_t __iomem *tx_bd_base; + cbd_t __iomem *tx_cur; unsigned char *tx_buf; unsigned char *rx_buf; u32 flags; void (*set_lineif)(struct uart_cpm_port *); u8 brg; uint dp_addr; - void *mem_addr; + void *mem_addr; dma_addr_t dma_addr; u32 mem_size; /* helpers */ @@ -106,34 +106,36 @@ void scc4_lineif(struct uart_cpm_port *pinfo); /* virtual to phys transtalion */ -static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo) +static inline unsigned long cpu2cpm_addr(void *addr, + struct uart_cpm_port *pinfo) { int offset; u32 val = (u32)addr; + u32 mem = (u32)pinfo->mem_addr; /* sane check */ - if (likely((val >= (u32)pinfo->mem_addr)) && - (val<((u32)pinfo->mem_addr + pinfo->mem_size))) { - offset = val - (u32)pinfo->mem_addr; - return pinfo->dma_addr+offset; + if (likely(val >= mem && val < mem + pinfo->mem_size)) { + offset = val - mem; + return pinfo->dma_addr + offset; } /* something nasty happened */ BUG(); return 0; } -static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo) +static inline void *cpm2cpu_addr(unsigned long addr, + struct uart_cpm_port *pinfo) { int offset; u32 val = addr; + u32 dma = (u32)pinfo->dma_addr; /* sane check */ - if (likely((val >= pinfo->dma_addr) && - (val<(pinfo->dma_addr + pinfo->mem_size)))) { - offset = val - (u32)pinfo->dma_addr; - return (void*)(pinfo->mem_addr+offset); + if (likely(val >= dma && val < dma + pinfo->mem_size)) { + offset = val - dma; + return pinfo->mem_addr + offset; } /* something nasty happened */ BUG(); - return 0; + return NULL; } diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 8564ba2f3ec2..afaf195b6e04 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -131,14 +131,14 @@ static int cpm_uart_id2nr(int id) static unsigned int cpm_uart_tx_empty(struct uart_port *port) { struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - volatile cbd_t *bdp = pinfo->tx_bd_base; + cbd_t __iomem *bdp = pinfo->tx_bd_base; int ret = 0; while (1) { - if (bdp->cbd_sc & BD_SC_READY) + if (in_be16(&bdp->cbd_sc) & BD_SC_READY) break; - if (bdp->cbd_sc & BD_SC_WRAP) { + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) { ret = TIOCSER_TEMT; break; } @@ -167,15 +167,15 @@ static unsigned int cpm_uart_get_mctrl(struct uart_port *port) static void cpm_uart_stop_tx(struct uart_port *port) { struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - volatile smc_t *smcp = pinfo->smcp; - volatile scc_t *sccp = pinfo->sccp; + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; pr_debug("CPM uart[%d]:stop tx\n", port->line); if (IS_SMC(pinfo)) - smcp->smc_smcm &= ~SMCM_TX; + clrbits8(&smcp->smc_smcm, SMCM_TX); else - sccp->scc_sccm &= ~UART_SCCM_TX; + clrbits16(&sccp->scc_sccm, UART_SCCM_TX); } /* @@ -184,24 +184,24 @@ static void cpm_uart_stop_tx(struct uart_port *port) static void cpm_uart_start_tx(struct uart_port *port) { struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - volatile smc_t *smcp = pinfo->smcp; - volatile scc_t *sccp = pinfo->sccp; + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; pr_debug("CPM uart[%d]:start tx\n", port->line); if (IS_SMC(pinfo)) { - if (smcp->smc_smcm & SMCM_TX) + if (in_8(&smcp->smc_smcm) & SMCM_TX) return; } else { - if (sccp->scc_sccm & UART_SCCM_TX) + if (in_be16(&sccp->scc_sccm) & UART_SCCM_TX) return; } if (cpm_uart_tx_pump(port) != 0) { if (IS_SMC(pinfo)) { - smcp->smc_smcm |= SMCM_TX; + setbits8(&smcp->smc_smcm, SMCM_TX); } else { - sccp->scc_sccm |= UART_SCCM_TX; + setbits16(&sccp->scc_sccm, UART_SCCM_TX); } } } @@ -212,15 +212,15 @@ static void cpm_uart_start_tx(struct uart_port *port) static void cpm_uart_stop_rx(struct uart_port *port) { struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - volatile smc_t *smcp = pinfo->smcp; - volatile scc_t *sccp = pinfo->sccp; + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; pr_debug("CPM uart[%d]:stop rx\n", port->line); if (IS_SMC(pinfo)) - smcp->smc_smcm &= ~SMCM_RX; + clrbits8(&smcp->smc_smcm, SMCM_RX); else - sccp->scc_sccm &= ~UART_SCCM_RX; + clrbits16(&sccp->scc_sccm, UART_SCCM_RX); } /* @@ -263,10 +263,11 @@ static void cpm_uart_int_tx(struct uart_port *port) static void cpm_uart_int_rx(struct uart_port *port) { int i; - unsigned char ch, *cp; + unsigned char ch; + u8 *cp; struct tty_struct *tty = port->info->tty; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - volatile cbd_t *bdp; + cbd_t __iomem *bdp; u16 status; unsigned int flg; @@ -278,13 +279,13 @@ static void cpm_uart_int_rx(struct uart_port *port) bdp = pinfo->rx_cur; for (;;) { /* get status */ - status = bdp->cbd_sc; + status = in_be16(&bdp->cbd_sc); /* If this one is empty, return happy */ if (status & BD_SC_EMPTY) break; /* get number of characters, and check spce in flip-buffer */ - i = bdp->cbd_datlen; + i = in_be16(&bdp->cbd_datlen); /* If we have not enough room in tty flip buffer, then we try * later, which will be the next rx-interrupt or a timeout @@ -295,7 +296,7 @@ static void cpm_uart_int_rx(struct uart_port *port) } /* get pointer */ - cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); /* loop through the buffer */ while (i-- > 0) { @@ -315,10 +316,11 @@ static void cpm_uart_int_rx(struct uart_port *port) } /* End while (i--) */ /* This BD is ready to be used again. Clear status. get next */ - bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID); - bdp->cbd_sc |= BD_SC_EMPTY; + clrbits16(&bdp->cbd_sc, BD_SC_BR | BD_SC_FR | BD_SC_PR | + BD_SC_OV | BD_SC_ID); + setbits16(&bdp->cbd_sc, BD_SC_EMPTY); - if (bdp->cbd_sc & BD_SC_WRAP) + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = pinfo->rx_bd_base; else bdp++; @@ -326,7 +328,7 @@ static void cpm_uart_int_rx(struct uart_port *port) } /* End for (;;) */ /* Write back buffer pointer */ - pinfo->rx_cur = (volatile cbd_t *) bdp; + pinfo->rx_cur = bdp; /* activate BH processing */ tty_flip_buffer_push(tty); @@ -380,14 +382,14 @@ static irqreturn_t cpm_uart_int(int irq, void *data) u8 events; struct uart_port *port = (struct uart_port *)data; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - volatile smc_t *smcp = pinfo->smcp; - volatile scc_t *sccp = pinfo->sccp; + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; pr_debug("CPM uart[%d]:IRQ\n", port->line); if (IS_SMC(pinfo)) { - events = smcp->smc_smce; - smcp->smc_smce = events; + events = in_8(&smcp->smc_smce); + out_8(&smcp->smc_smce, events); if (events & SMCM_BRKE) uart_handle_break(port); if (events & SMCM_RX) @@ -395,8 +397,8 @@ static irqreturn_t cpm_uart_int(int irq, void *data) if (events & SMCM_TX) cpm_uart_int_tx(port); } else { - events = sccp->scc_scce; - sccp->scc_scce = events; + events = in_be16(&sccp->scc_scce); + out_be16(&sccp->scc_scce, events); if (events & UART_SCCM_BRKE) uart_handle_break(port); if (events & UART_SCCM_RX) @@ -421,11 +423,11 @@ static int cpm_uart_startup(struct uart_port *port) /* Startup rx-int */ if (IS_SMC(pinfo)) { - pinfo->smcp->smc_smcm |= SMCM_RX; - pinfo->smcp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); + setbits8(&pinfo->smcp->smc_smcm, SMCM_RX); + setbits16(&pinfo->smcp->smc_smcmr, (SMCMR_REN | SMCMR_TEN)); } else { - pinfo->sccp->scc_sccm |= UART_SCCM_RX; - pinfo->sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); + setbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX); + setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT)); } if (!(pinfo->flags & FLAG_CONSOLE)) @@ -464,13 +466,13 @@ static void cpm_uart_shutdown(struct uart_port *port) /* Stop uarts */ if (IS_SMC(pinfo)) { - volatile smc_t *smcp = pinfo->smcp; - smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); + smc_t __iomem *smcp = pinfo->smcp; + clrbits16(&smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); + clrbits8(&smcp->smc_smcm, SMCM_RX | SMCM_TX); } else { - volatile scc_t *sccp = pinfo->sccp; - sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); + scc_t __iomem *sccp = pinfo->sccp; + clrbits32(&sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); + clrbits16(&sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); } /* Shut them really down and reinit buffer descriptors */ @@ -492,8 +494,8 @@ static void cpm_uart_set_termios(struct uart_port *port, u16 cval, scval, prev_mode; int bits, sbits; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; - volatile smc_t *smcp = pinfo->smcp; - volatile scc_t *sccp = pinfo->sccp; + smc_t __iomem *smcp = pinfo->smcp; + scc_t __iomem *sccp = pinfo->sccp; pr_debug("CPM uart[%d]:set_termios\n", port->line); @@ -588,11 +590,11 @@ static void cpm_uart_set_termios(struct uart_port *port, * enables, because we want to put them back if they were * present. */ - prev_mode = smcp->smc_smcmr; - smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART; - smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN)); + prev_mode = in_be16(&smcp->smc_smcmr); + out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART); + setbits16(&smcp->smc_smcmr, (prev_mode & (SMCMR_REN | SMCMR_TEN))); } else { - sccp->scc_psmr = (sbits << 12) | scval; + out_be16(&sccp->scc_psmr, (sbits << 12) | scval); } cpm_set_brg(pinfo->brg - 1, baud); @@ -630,8 +632,8 @@ static int cpm_uart_verify_port(struct uart_port *port, */ static int cpm_uart_tx_pump(struct uart_port *port) { - volatile cbd_t *bdp; - unsigned char *p; + cbd_t __iomem *bdp; + u8 *p; int count; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; struct circ_buf *xmit = &port->info->xmit; @@ -641,13 +643,14 @@ static int cpm_uart_tx_pump(struct uart_port *port) /* Pick next descriptor and fill from buffer */ bdp = pinfo->tx_cur; - p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); *p++ = port->x_char; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; + + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); /* Get next BD. */ - if (bdp->cbd_sc & BD_SC_WRAP) + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = pinfo->tx_bd_base; else bdp++; @@ -666,9 +669,10 @@ static int cpm_uart_tx_pump(struct uart_port *port) /* Pick next descriptor and fill from buffer */ bdp = pinfo->tx_cur; - while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { + while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) && + xmit->tail != xmit->head) { count = 0; - p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); + p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); while (count < pinfo->tx_fifosize) { *p++ = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); @@ -677,11 +681,10 @@ static int cpm_uart_tx_pump(struct uart_port *port) if (xmit->head == xmit->tail) break; } - bdp->cbd_datlen = count; - bdp->cbd_sc |= BD_SC_READY; - eieio(); + out_be16(&bdp->cbd_datlen, count); + setbits16(&bdp->cbd_sc, BD_SC_READY); /* Get next BD. */ - if (bdp->cbd_sc & BD_SC_WRAP) + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = pinfo->tx_bd_base; else bdp++; @@ -706,7 +709,7 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) { int i; u8 *mem_addr; - volatile cbd_t *bdp; + cbd_t __iomem *bdp; pr_debug("CPM uart[%d]:initbd\n", pinfo->port.line); @@ -717,13 +720,13 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) mem_addr = pinfo->mem_addr; bdp = pinfo->rx_cur = pinfo->rx_bd_base; for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { - bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); - bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; + out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); + out_be16(&bdp->cbd_sc, BD_SC_EMPTY | BD_SC_INTRPT); mem_addr += pinfo->rx_fifosize; } - bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); - bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; + out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); + out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT); /* Set the physical address of the host memory * buffers in the buffer descriptors, and the @@ -732,19 +735,19 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); bdp = pinfo->tx_cur = pinfo->tx_bd_base; for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { - bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); - bdp->cbd_sc = BD_SC_INTRPT; + out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); + out_be16(&bdp->cbd_sc, BD_SC_INTRPT); mem_addr += pinfo->tx_fifosize; } - bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo); - bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; + out_be32(&bdp->cbd_bufaddr, cpu2cpm_addr(mem_addr, pinfo)); + out_be16(&bdp->cbd_sc, BD_SC_WRAP | BD_SC_INTRPT); } static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) { - volatile scc_t *scp; - volatile scc_uart_t *sup; + scc_t __iomem *scp; + scc_uart_t __iomem *sup; pr_debug("CPM uart[%d]:init_scc\n", pinfo->port.line); @@ -752,8 +755,10 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) sup = pinfo->sccup; /* Store address */ - pinfo->sccup->scc_genscc.scc_rbase = (unsigned char *)pinfo->rx_bd_base - DPRAM_BASE; - pinfo->sccup->scc_genscc.scc_tbase = (unsigned char *)pinfo->tx_bd_base - DPRAM_BASE; + out_be16(&pinfo->sccup->scc_genscc.scc_rbase, + (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); + out_be16(&pinfo->sccup->scc_genscc.scc_tbase, + (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); /* Set up the uart parameters in the * parameter ram. @@ -761,25 +766,25 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) cpm_set_scc_fcr(sup); - sup->scc_genscc.scc_mrblr = pinfo->rx_fifosize; - sup->scc_maxidl = pinfo->rx_fifosize; - sup->scc_brkcr = 1; - sup->scc_parec = 0; - sup->scc_frmec = 0; - sup->scc_nosec = 0; - sup->scc_brkec = 0; - sup->scc_uaddr1 = 0; - sup->scc_uaddr2 = 0; - sup->scc_toseq = 0; - sup->scc_char1 = 0x8000; - sup->scc_char2 = 0x8000; - sup->scc_char3 = 0x8000; - sup->scc_char4 = 0x8000; - sup->scc_char5 = 0x8000; - sup->scc_char6 = 0x8000; - sup->scc_char7 = 0x8000; - sup->scc_char8 = 0x8000; - sup->scc_rccm = 0xc0ff; + out_be16(&sup->scc_genscc.scc_mrblr, pinfo->rx_fifosize); + out_be16(&sup->scc_maxidl, pinfo->rx_fifosize); + out_be16(&sup->scc_brkcr, 1); + out_be16(&sup->scc_parec, 0); + out_be16(&sup->scc_frmec, 0); + out_be16(&sup->scc_nosec, 0); + out_be16(&sup->scc_brkec, 0); + out_be16(&sup->scc_uaddr1, 0); + out_be16(&sup->scc_uaddr2, 0); + out_be16(&sup->scc_toseq, 0); + out_be16(&sup->scc_char1, 0x8000); + out_be16(&sup->scc_char2, 0x8000); + out_be16(&sup->scc_char3, 0x8000); + out_be16(&sup->scc_char4, 0x8000); + out_be16(&sup->scc_char5, 0x8000); + out_be16(&sup->scc_char6, 0x8000); + out_be16(&sup->scc_char7, 0x8000); + out_be16(&sup->scc_char8, 0x8000); + out_be16(&sup->scc_rccm, 0xc0ff); /* Send the CPM an initialize command. */ @@ -788,23 +793,23 @@ static void cpm_uart_init_scc(struct uart_cpm_port *pinfo) /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ - scp->scc_gsmrh = 0; - scp->scc_gsmrl = - (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); + out_be32(&scp->scc_gsmrh, 0); + out_be32(&scp->scc_gsmrl, + SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); /* Enable rx interrupts and clear all pending events. */ - scp->scc_sccm = 0; - scp->scc_scce = 0xffff; - scp->scc_dsr = 0x7e7e; - scp->scc_psmr = 0x3000; + out_be16(&scp->scc_sccm, 0); + out_be16(&scp->scc_scce, 0xffff); + out_be16(&scp->scc_dsr, 0x7e7e); + out_be16(&scp->scc_psmr, 0x3000); - scp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); + setbits32(&scp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); } static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) { - volatile smc_t *sp; - volatile smc_uart_t *up; + smc_t __iomem *sp; + smc_uart_t __iomem *up; pr_debug("CPM uart[%d]:init_smc\n", pinfo->port.line); @@ -812,19 +817,21 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) up = pinfo->smcup; /* Store address */ - pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE; - pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE; + out_be16(&pinfo->smcup->smc_rbase, + (u8 __iomem *)pinfo->rx_bd_base - DPRAM_BASE); + out_be16(&pinfo->smcup->smc_tbase, + (u8 __iomem *)pinfo->tx_bd_base - DPRAM_BASE); /* * In case SMC1 is being relocated... */ #if defined (CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - up->smc_rbptr = pinfo->smcup->smc_rbase; - up->smc_tbptr = pinfo->smcup->smc_tbase; - up->smc_rstate = 0; - up->smc_tstate = 0; - up->smc_brkcr = 1; /* number of break chars */ - up->smc_brkec = 0; + out_be16(&up->smc_rbptr, in_be16(&pinfo->smcup->smc_rbase)); + out_be16(&up->smc_tbptr, in_be16(&pinfo->smcup->smc_tbase)); + out_be32(&up->smc_rstate, 0); + out_be32(&up->smc_tstate, 0); + out_be16(&up->smc_brkcr, 1); /* number of break chars */ + out_be16(&up->smc_brkec, 0); #endif /* Set up the uart parameters in the @@ -833,24 +840,24 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) cpm_set_smc_fcr(up); /* Using idle charater time requires some additional tuning. */ - up->smc_mrblr = pinfo->rx_fifosize; - up->smc_maxidl = pinfo->rx_fifosize; - up->smc_brklen = 0; - up->smc_brkec = 0; - up->smc_brkcr = 1; + out_be16(&up->smc_mrblr, pinfo->rx_fifosize); + out_be16(&up->smc_maxidl, pinfo->rx_fifosize); + out_be16(&up->smc_brklen, 0); + out_be16(&up->smc_brkec, 0); + out_be16(&up->smc_brkcr, 1); cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX); /* Set UART mode, 8 bit, no parity, one stop. * Enable receive and transmit. */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; + out_be16(&sp->smc_smcmr, smcr_mk_clen(9) | SMCMR_SM_UART); /* Enable only rx interrupts clear all pending events. */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; + out_8(&sp->smc_smcm, 0); + out_8(&sp->smc_smce, 0xff); - sp->smc_smcmr |= (SMCMR_REN | SMCMR_TEN); + setbits16(&sp->smc_smcmr, SMCMR_REN | SMCMR_TEN); } /* @@ -868,11 +875,11 @@ static int cpm_uart_request_port(struct uart_port *port) return 0; if (IS_SMC(pinfo)) { - pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); - pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); + clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); } else { - pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); - pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); + clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); } ret = cpm_uart_allocbuf(pinfo, 0); @@ -931,10 +938,11 @@ static struct uart_ops cpm_uart_pops = { #ifdef CONFIG_PPC_CPM_NEW_BINDING struct uart_cpm_port cpm_uart_ports[UART_NR]; -int cpm_uart_init_port(struct device_node *np, struct uart_cpm_port *pinfo) +static int cpm_uart_init_port(struct device_node *np, + struct uart_cpm_port *pinfo) { const u32 *data; - void __iomem *mem, __iomem *pram; + void __iomem *mem, *pram; int len; int ret; @@ -1169,8 +1177,8 @@ static void cpm_uart_console_write(struct console *co, const char *s, &cpm_uart_ports[cpm_uart_port_map[co->index]]; #endif unsigned int i; - volatile cbd_t *bdp, *bdbase; - volatile unsigned char *cp; + cbd_t __iomem *bdp, *bdbase; + unsigned char *cp; /* Get the address of the host memory buffer. */ @@ -1188,37 +1196,36 @@ static void cpm_uart_console_write(struct console *co, const char *s, * Ready indicates output is ready, and xmt is doing * that, not that it is ready for us to send. */ - while ((bdp->cbd_sc & BD_SC_READY) != 0) + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; /* Send the character out. * If the buffer address is in the CPM DPRAM, don't * convert it. */ - cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); - + cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); *cp = *s; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); - if (bdp->cbd_sc & BD_SC_WRAP) + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = bdbase; else bdp++; /* if a LF, also do CR... */ if (*s == 10) { - while ((bdp->cbd_sc & BD_SC_READY) != 0) + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; - cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo); - + cp = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo); *cp = 13; - bdp->cbd_datlen = 1; - bdp->cbd_sc |= BD_SC_READY; - if (bdp->cbd_sc & BD_SC_WRAP) + out_be16(&bdp->cbd_datlen, 1); + setbits16(&bdp->cbd_sc, BD_SC_READY); + + if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP) bdp = bdbase; else bdp++; @@ -1229,10 +1236,10 @@ static void cpm_uart_console_write(struct console *co, const char *s, * Finally, Wait for transmitter & holding register to empty * and restore the IER */ - while ((bdp->cbd_sc & BD_SC_READY) != 0) + while ((in_be16(&bdp->cbd_sc) & BD_SC_READY) != 0) ; - pinfo->tx_cur = (volatile cbd_t *) bdp; + pinfo->tx_cur = bdp; } @@ -1319,11 +1326,11 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) #endif if (IS_SMC(pinfo)) { - pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX); - pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); + clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); } else { - pinfo->sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); - pinfo->sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_TX | UART_SCCM_RX); + clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT); } ret = cpm_uart_allocbuf(pinfo, 1); @@ -1354,7 +1361,7 @@ static struct console cpm_scc_uart_console = { .data = &cpm_reg, }; -int __init cpm_uart_console_init(void) +static int __init cpm_uart_console_init(void) { register_console(&cpm_scc_uart_console); return 0; diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 4647f55e19f1..52fb044bb79a 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -179,7 +179,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); - pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; + pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem; pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; return 0; diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.h b/drivers/serial/cpm_uart/cpm_uart_cpm1.h index 69f523a442e0..9b5465fb0bbb 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.h @@ -27,18 +27,18 @@ static inline void cpm_set_brg(int brg, int baud) cpm_setbrg(brg, baud); } -static inline void cpm_set_scc_fcr(volatile scc_uart_t * sup) +static inline void cpm_set_scc_fcr(scc_uart_t __iomem * sup) { - sup->scc_genscc.scc_rfcr = SMC_EB; - sup->scc_genscc.scc_tfcr = SMC_EB; + out_8(&sup->scc_genscc.scc_rfcr, SMC_EB); + out_8(&sup->scc_genscc.scc_tfcr, SMC_EB); } -static inline void cpm_set_smc_fcr(volatile smc_uart_t * up) +static inline void cpm_set_smc_fcr(smc_uart_t __iomem * up) { - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; + out_8(&up->smc_rfcr, SMC_EB); + out_8(&up->smc_tfcr, SMC_EB); } -#define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0)) +#define DPRAM_BASE ((u8 __iomem __force *)cpm_dpram_addr(0)) #endif diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 7ebce263ad40..5bd4508ce3c1 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -278,7 +278,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); - pinfo->rx_bd_base = (volatile cbd_t *)dp_mem; + pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem; pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; return 0; @@ -289,7 +289,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo) dma_free_coherent(NULL, L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + L1_CACHE_ALIGN(pinfo->tx_nrfifos * - pinfo->tx_fifosize), pinfo->mem_addr, + pinfo->tx_fifosize), (void __force *)pinfo->mem_addr, pinfo->dma_addr); cpm_dpfree(pinfo->dp_addr); diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.h b/drivers/serial/cpm_uart/cpm_uart_cpm2.h index e7717ece0831..40006a7dce46 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.h +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.h @@ -27,18 +27,18 @@ static inline void cpm_set_brg(int brg, int baud) cpm_setbrg(brg, baud); } -static inline void cpm_set_scc_fcr(volatile scc_uart_t * sup) +static inline void cpm_set_scc_fcr(scc_uart_t __iomem *sup) { - sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; - sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; + out_8(&sup->scc_genscc.scc_rfcr, CPMFCR_GBL | CPMFCR_EB); + out_8(&sup->scc_genscc.scc_tfcr, CPMFCR_GBL | CPMFCR_EB); } -static inline void cpm_set_smc_fcr(volatile smc_uart_t * up) +static inline void cpm_set_smc_fcr(smc_uart_t __iomem *up) { - up->smc_rfcr = CPMFCR_GBL | CPMFCR_EB; - up->smc_tfcr = CPMFCR_GBL | CPMFCR_EB; + out_8(&up->smc_rfcr, CPMFCR_GBL | CPMFCR_EB); + out_8(&up->smc_tfcr, CPMFCR_GBL | CPMFCR_EB); } -#define DPRAM_BASE ((unsigned char *)cpm_dpram_addr(0)) +#define DPRAM_BASE ((u8 __iomem __force *)cpm_dpram_addr(0)) #endif -- cgit v1.2.3 From d948a29ea7a9514f588dafb61d5a6da68131c3ba Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 17 Jul 2007 18:09:33 -0500 Subject: [POWERPC] cpm_uart: Issue STOP_TX command before initializing console. This prevents some bootloader/bootwrapper characters from being lost. Signed-off-by: Scott Wood Signed-off-by: Kumar Gala --- drivers/serial/cpm_uart/cpm_uart_core.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index afaf195b6e04..b5e4478de0e3 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c @@ -1325,6 +1325,8 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) udbg_putc = NULL; #endif + cpm_line_cr_cmd(pinfo, CPM_CR_STOP_TX); + if (IS_SMC(pinfo)) { clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX | SMCM_TX); clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN | SMCMR_TEN); @@ -1346,6 +1348,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) cpm_uart_init_scc(pinfo); uart_set_options(port, co, baud, parity, bits, flow); + cpm_line_cr_cmd(pinfo, CPM_CR_RESTART_TX); return 0; } -- cgit v1.2.3 From 15f8c604a79c4840ed76eecf3af5d88b7c1dee9e Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 28 Sep 2007 14:06:16 -0500 Subject: [POWERPC] cpm: Describe multi-user ram in its own device node. The way the current CPM binding describes available multi-user (a.k.a. dual-ported) RAM doesn't work well when there are multiple free regions, and it doesn't work at all if the region doesn't begin at the start of the muram area (as the hardware needs to be programmed with offsets into this area). The latter situation can happen with SMC UARTs on CPM2, as its parameter RAM is relocatable, u-boot puts it at zero, and the kernel doesn't support moving it. It is now described with a muram node, similar to QE. The current CPM binding is sufficiently recent (i.e. never appeared in an official release) that compatibility with existing device trees is not an issue. The code supporting the new binding is shared between cpm1 and cpm2, rather than remain separated. QE should be able to use this code as well, once minor fixes are made to its device trees. Signed-off-by: Scott Wood Signed-off-by: Kumar Gala --- drivers/serial/cpm_uart/cpm_uart_cpm2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c index 5bd4508ce3c1..882dbc17d590 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c @@ -235,7 +235,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) { int dpmemsz, memsz; - u8 *dp_mem; + u8 __iomem *dp_mem; unsigned long dp_offset; u8 *mem_addr; dma_addr_t dma_addr = 0; @@ -278,7 +278,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); - pinfo->rx_bd_base = (cbd_t __iomem __force *)dp_mem; + pinfo->rx_bd_base = (cbd_t __iomem *)dp_mem; pinfo->tx_bd_base = pinfo->rx_bd_base + pinfo->rx_nrfifos; return 0; -- cgit v1.2.3 From 6b0b594bb81f86dbc7b0829ee5102abaab242913 Mon Sep 17 00:00:00 2001 From: Timur Tabi Date: Wed, 3 Oct 2007 11:34:59 -0500 Subject: [POWERPC] qe: miscellaneous code improvements and fixes to the QE library This patch makes numerous miscellaneous code improvements to the QE library. 1. Remove struct ucc_common and merge ucc_init_guemr() into ucc_set_type() (every caller of ucc_init_guemr() also calls ucc_set_type()). Modify all callers of ucc_set_type() accordingly. 2. Remove the unused enum ucc_pram_initial_offset. 3. Refactor qe_setbrg(), also implement work-around for errata QE_General4. 4. Several printk() calls were missing the terminating \n. 5. Add __iomem where needed, and change u16 to __be16 and u32 to __be32 where appropriate. 6. In ucc_slow_init() the RBASE and TBASE registers in the PRAM were programmed with the wrong value. 7. Add the protocol type to struct us_info and updated ucc_slow_init() to use it, instead of always programming QE_CR_PROTOCOL_UNSPECIFIED. 8. Rename ucc_slow_restart_x() to ucc_slow_restart_tx() 9. Add several macros in qe.h (mostly for slow UCC support, but also to standardize some naming convention) and remove several unused macros. 10. Update ucc_geth.c to use the new macros. 11. Add ucc_slow_info.protocol to specify which QE_CR_PROTOCOL_xxx protcol to use when initializing the UCC in ucc_slow_init(). 12. Rename ucc_slow_pram.rfcr to rbmr and ucc_slow_pram.tfcr to tbmr, since these are the real names of the registers. 13. Use the setbits, clrbits, and clrsetbits where appropriate. 14. Refactor ucc_set_qe_mux_rxtx(). 15. Remove all instances of 'volatile'. 16. Simplify get_cmxucr_reg(); 17. Replace qe_mux.cmxucrX with qe_mux.cmxucr[]. 18. Updated struct ucc_geth because struct ucc_fast is not padded any more. Signed-off-by: Timur Tabi Signed-off-by: Kumar Gala --- drivers/net/ucc_geth.c | 2 +- drivers/net/ucc_geth.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 9a38dfe45f8f..7dedc9609603 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -2919,7 +2919,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) test = in_be16(&ugeth->p_tx_glbl_pram->temoder); /* Function code register value to be used later */ - function_code = QE_BMR_BYTE_ORDER_BO_MOT | UCC_FAST_FUNCTION_CODE_GBL; + function_code = UCC_BMR_BO_BE | UCC_BMR_GBL; /* Required for QE */ /* function code register */ diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h index bb4dac8c0c65..1aa69023cde1 100644 --- a/drivers/net/ucc_geth.h +++ b/drivers/net/ucc_geth.h @@ -44,6 +44,7 @@ struct ucc_geth { struct ucc_fast uccf; + u8 res0[0x100 - sizeof(struct ucc_fast)]; u32 maccfg1; /* mac configuration reg. 1 */ u32 maccfg2; /* mac configuration reg. 2 */ -- cgit v1.2.3 From 258de4badd5b7b5d168307638f755bd4df16c18e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 4 Oct 2007 10:48:36 -0600 Subject: [POWERPC] XilinxFB: add banner output to probe routine when DEBUG is defined Debug support: when DEBUG is defined, output relevant details to the log about the framebuffer registration. Signed-off-by: Grant Likely Acked-by: Andrei Konovalov --- drivers/video/xilinxfb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 4bc67ab56afa..1a5f1e429c4d 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -287,6 +287,11 @@ xilinxfb_drv_probe(struct device *dev) goto failed4; } + /* Put a banner in the log (for DEBUG) */ + dev_dbg(dev, "regs: phys=%x, virt=%p\n", + drvdata->regs_phys, drvdata->regs); + dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", + (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE); return 0; /* success */ failed4: -- cgit v1.2.3 From 3cb3ec2c26473d8123a468abfaca1e926344b1c2 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 4 Oct 2007 10:48:36 -0600 Subject: [POWERPC] XilinxFB: Replace calls to printk with dev_dbg, dev_err, etc. The dev_dbg, dev_err, etc functions provide more context that plain vanilla printk which is useful for debugging. Where appropriate, change printk calls to the appropriate dev_*() call. Signed-off-by: Grant Likely Acked-by: Andrei Konovalov --- drivers/video/xilinxfb.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 1a5f1e429c4d..e63cbd1acfd2 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -18,6 +18,7 @@ * Geert Uytterhoeven. */ +#include #include #include #include @@ -214,7 +215,7 @@ xilinxfb_drv_probe(struct device *dev) drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { - printk(KERN_ERR "Couldn't allocate device private record\n"); + dev_err(dev, "Couldn't allocate device private record\n"); return -ENOMEM; } dev_set_drvdata(dev, drvdata); @@ -222,14 +223,13 @@ xilinxfb_drv_probe(struct device *dev) /* Map the control registers in */ regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) { - printk(KERN_ERR "Couldn't get registers resource\n"); + dev_err(dev, "Couldn't get registers resource\n"); retval = -EFAULT; goto failed1; } if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) { - printk(KERN_ERR - "Couldn't lock memory region at 0x%08X\n", + dev_err(dev, "Couldn't lock memory region at 0x%08X\n", regs_res->start); retval = -EBUSY; goto failed1; @@ -241,7 +241,7 @@ xilinxfb_drv_probe(struct device *dev) drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE), &drvdata->fb_phys, GFP_KERNEL); if (!drvdata->fb_virt) { - printk(KERN_ERR "Could not allocate frame buffer memory\n"); + dev_err(dev, "Could not allocate frame buffer memory\n"); retval = -ENOMEM; goto failed2; } @@ -267,7 +267,7 @@ xilinxfb_drv_probe(struct device *dev) drvdata->info.pseudo_palette = drvdata->pseudo_palette; if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) { - printk(KERN_ERR "Fail to allocate colormap (%d entries)\n", + dev_err(dev, "Fail to allocate colormap (%d entries)\n", PALETTE_ENTRIES_NO); retval = -EFAULT; goto failed3; @@ -282,7 +282,7 @@ xilinxfb_drv_probe(struct device *dev) /* Register new frame buffer */ if (register_framebuffer(&drvdata->info) < 0) { - printk(KERN_ERR "Could not register frame buffer\n"); + dev_err(dev, "Could not register frame buffer\n"); retval = -EINVAL; goto failed4; } -- cgit v1.2.3 From 3fb99ce4e2748dafe3f10dba2932f0d13f577623 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 4 Oct 2007 10:48:37 -0600 Subject: [POWERPC] XilinxFB: rename failout labels to reflect failure Labels and gotos are used in xilinxfb_assign to unwind allocations on device registration failures. Rename the labels to reflect the error which occured. This change is being made to make it easier to add new failout paths (which occurs in a subsuquent patch) and to make reviewing the failout path easier. Signed-off-by: Grant Likely Acked-by: Andrei Konovalov --- drivers/video/xilinxfb.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index e63cbd1acfd2..9aa754a25218 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -225,14 +225,14 @@ xilinxfb_drv_probe(struct device *dev) if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) { dev_err(dev, "Couldn't get registers resource\n"); retval = -EFAULT; - goto failed1; + goto err_region; } if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) { dev_err(dev, "Couldn't lock memory region at 0x%08X\n", regs_res->start); retval = -EBUSY; - goto failed1; + goto err_region; } drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8); drvdata->regs_phys = regs_res->start; @@ -243,7 +243,7 @@ xilinxfb_drv_probe(struct device *dev) if (!drvdata->fb_virt) { dev_err(dev, "Could not allocate frame buffer memory\n"); retval = -ENOMEM; - goto failed2; + goto err_fbmem; } /* Clear (turn to black) the framebuffer */ @@ -270,7 +270,7 @@ xilinxfb_drv_probe(struct device *dev) dev_err(dev, "Fail to allocate colormap (%d entries)\n", PALETTE_ENTRIES_NO); retval = -EFAULT; - goto failed3; + goto err_cmap; } drvdata->info.flags = FBINFO_DEFAULT; @@ -284,7 +284,7 @@ xilinxfb_drv_probe(struct device *dev) if (register_framebuffer(&drvdata->info) < 0) { dev_err(dev, "Could not register frame buffer\n"); retval = -EINVAL; - goto failed4; + goto err_regfb; } /* Put a banner in the log (for DEBUG) */ @@ -294,10 +294,10 @@ xilinxfb_drv_probe(struct device *dev) (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE); return 0; /* success */ -failed4: +err_regfb: fb_dealloc_cmap(&drvdata->info.cmap); -failed3: +err_cmap: dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, drvdata->fb_phys); @@ -305,10 +305,10 @@ failed3: xilinx_fb_out_be32(drvdata, REG_CTRL, 0); iounmap(drvdata->regs); -failed2: +err_fbmem: release_mem_region(regs_res->start, 8); -failed1: +err_region: kfree(drvdata); dev_set_drvdata(dev, NULL); -- cgit v1.2.3 From 264776224d3bb0cd80bc0ec11a769e05a58f8c6b Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 4 Oct 2007 10:48:37 -0600 Subject: [POWERPC] XilinxFB: Split device setup from bus binding Split the device setup code away from the platform bus binding. This is in preparation for adding the of_platform bus binding to this driver and most of the setup code is common between the two busses. Signed-off-by: Grant Likely Acked-by: Andrei Konovalov --- drivers/video/xilinxfb.c | 133 ++++++++++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 9aa754a25218..12d91279996d 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -196,23 +196,17 @@ static struct fb_ops xilinxfb_ops = .fb_imageblit = cfb_imageblit, }; -/* === The device driver === */ +/* --------------------------------------------------------------------- + * Bus independent setup/teardown + */ -static int -xilinxfb_drv_probe(struct device *dev) +static int xilinxfb_assign(struct device *dev, unsigned long physaddr, + int width_mm, int height_mm, int rotate) { - struct platform_device *pdev; - struct xilinxfb_platform_data *pdata; struct xilinxfb_drvdata *drvdata; - struct resource *regs_res; - int retval; - - if (!dev) - return -EINVAL; - - pdev = to_platform_device(dev); - pdata = pdev->dev.platform_data; + int rc; + /* Allocate the driver data region */ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); if (!drvdata) { dev_err(dev, "Couldn't allocate device private record\n"); @@ -221,40 +215,39 @@ xilinxfb_drv_probe(struct device *dev) dev_set_drvdata(dev, drvdata); /* Map the control registers in */ - regs_res = platform_get_resource(pdev, IORESOURCE_IO, 0); - if (!regs_res || (regs_res->end - regs_res->start + 1 < 8)) { - dev_err(dev, "Couldn't get registers resource\n"); - retval = -EFAULT; + if (!request_mem_region(physaddr, 8, DRIVER_NAME)) { + dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", + physaddr); + rc = -ENODEV; goto err_region; } - - if (!request_mem_region(regs_res->start, 8, DRIVER_NAME)) { - dev_err(dev, "Couldn't lock memory region at 0x%08X\n", - regs_res->start); - retval = -EBUSY; - goto err_region; + drvdata->regs_phys = physaddr; + drvdata->regs = ioremap(physaddr, 8); + if (!drvdata->regs) { + dev_err(dev, "Couldn't lock memory region at 0x%08lX\n", + physaddr); + rc = -ENODEV; + goto err_map; } - drvdata->regs = (u32 __iomem*) ioremap(regs_res->start, 8); - drvdata->regs_phys = regs_res->start; /* Allocate the framebuffer memory */ drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE), &drvdata->fb_phys, GFP_KERNEL); if (!drvdata->fb_virt) { dev_err(dev, "Could not allocate frame buffer memory\n"); - retval = -ENOMEM; + rc = -ENOMEM; goto err_fbmem; } /* Clear (turn to black) the framebuffer */ - memset_io((void *) drvdata->fb_virt, 0, FB_SIZE); + memset_io(drvdata->fb_virt, 0, FB_SIZE); /* Tell the hardware where the frame buffer is */ xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); /* Turn on the display */ drvdata->reg_ctrl_default = REG_CTRL_ENABLE; - if (pdata && pdata->rotate_screen) + if (rotate) drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); @@ -265,31 +258,29 @@ xilinxfb_drv_probe(struct device *dev) drvdata->info.fix = xilinx_fb_fix; drvdata->info.fix.smem_start = drvdata->fb_phys; drvdata->info.pseudo_palette = drvdata->pseudo_palette; + drvdata->info.flags = FBINFO_DEFAULT; + drvdata->info.var = xilinx_fb_var; + + xilinx_fb_var.height = height_mm; + xilinx_fb_var.width = width_mm; - if (fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0) < 0) { + /* Allocate a colour map */ + rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0); + if (rc) { dev_err(dev, "Fail to allocate colormap (%d entries)\n", PALETTE_ENTRIES_NO); - retval = -EFAULT; goto err_cmap; } - drvdata->info.flags = FBINFO_DEFAULT; - if (pdata) { - xilinx_fb_var.height = pdata->screen_height_mm; - xilinx_fb_var.width = pdata->screen_width_mm; - } - drvdata->info.var = xilinx_fb_var; - /* Register new frame buffer */ - if (register_framebuffer(&drvdata->info) < 0) { + rc = register_framebuffer(&drvdata->info); + if (rc) { dev_err(dev, "Could not register frame buffer\n"); - retval = -EINVAL; goto err_regfb; } /* Put a banner in the log (for DEBUG) */ - dev_dbg(dev, "regs: phys=%x, virt=%p\n", - drvdata->regs_phys, drvdata->regs); + dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE); return 0; /* success */ @@ -300,30 +291,25 @@ err_regfb: err_cmap: dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, drvdata->fb_phys); - /* Turn off the display */ xilinx_fb_out_be32(drvdata, REG_CTRL, 0); - iounmap(drvdata->regs); err_fbmem: - release_mem_region(regs_res->start, 8); + iounmap(drvdata->regs); + +err_map: + release_mem_region(physaddr, 8); err_region: kfree(drvdata); dev_set_drvdata(dev, NULL); - return retval; + return rc; } -static int -xilinxfb_drv_remove(struct device *dev) +static int xilinxfb_release(struct device *dev) { - struct xilinxfb_drvdata *drvdata; - - if (!dev) - return -ENODEV; - - drvdata = (struct xilinxfb_drvdata *) dev_get_drvdata(dev); + struct xilinxfb_drvdata *drvdata = dev_get_drvdata(dev); #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) xilinx_fb_blank(VESA_POWERDOWN, &drvdata->info); @@ -348,6 +334,47 @@ xilinxfb_drv_remove(struct device *dev) return 0; } +/* --------------------------------------------------------------------- + * Platform bus binding + */ + +static int +xilinxfb_drv_probe(struct device *dev) +{ + struct platform_device *pdev; + struct xilinxfb_platform_data *pdata; + struct resource *res; + int width_mm; + int height_mm; + int rotate; + + pdev = to_platform_device(dev); + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(dev, "Missing pdata structure\n"); + return -ENODEV; + } + + /* Find the registers address */ + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (!res) { + dev_err(dev, "Couldn't get registers resource\n"); + return -ENODEV; + } + + height_mm = pdata->screen_height_mm; + width_mm = pdata->screen_width_mm; + rotate = pdata->rotate_screen ? 1 : 0; + + return xilinxfb_assign(dev, res->start, width_mm, height_mm, rotate); +} + +static int +xilinxfb_drv_remove(struct device *dev) +{ + return xilinxfb_release(dev); +} + static struct device_driver xilinxfb_driver = { .name = DRIVER_NAME, -- cgit v1.2.3 From 47473e31585032e5c048eeec50e0f9165890230a Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 4 Oct 2007 10:48:37 -0600 Subject: [POWERPC] XilinxFB: cleanup platform_bus binding to use platform bus API. Change the platform bus binding to make use of the established platform_bus API. Signed-off-by: Grant Likely Acked-by: Andrei Konovalov --- drivers/video/xilinxfb.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index 12d91279996d..e482bb519635 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -339,26 +339,24 @@ static int xilinxfb_release(struct device *dev) */ static int -xilinxfb_drv_probe(struct device *dev) +xilinxfb_platform_probe(struct platform_device *pdev) { - struct platform_device *pdev; struct xilinxfb_platform_data *pdata; struct resource *res; int width_mm; int height_mm; int rotate; - pdev = to_platform_device(dev); pdata = pdev->dev.platform_data; if (!pdata) { - dev_err(dev, "Missing pdata structure\n"); + dev_err(&pdev->dev, "Missing pdata structure\n"); return -ENODEV; } /* Find the registers address */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (!res) { - dev_err(dev, "Couldn't get registers resource\n"); + dev_err(&pdev->dev, "Couldn't get registers resource\n"); return -ENODEV; } @@ -366,22 +364,24 @@ xilinxfb_drv_probe(struct device *dev) width_mm = pdata->screen_width_mm; rotate = pdata->rotate_screen ? 1 : 0; - return xilinxfb_assign(dev, res->start, width_mm, height_mm, rotate); + return xilinxfb_assign(&pdev->dev, res->start, width_mm, height_mm, + rotate); } static int -xilinxfb_drv_remove(struct device *dev) +xilinxfb_platform_remove(struct platform_device *pdev) { - return xilinxfb_release(dev); + return xilinxfb_release(&pdev->dev); } -static struct device_driver xilinxfb_driver = { - .name = DRIVER_NAME, - .bus = &platform_bus_type, - - .probe = xilinxfb_drv_probe, - .remove = xilinxfb_drv_remove +static struct platform_driver xilinxfb_platform_driver = { + .probe = xilinxfb_platform_probe, + .remove = xilinxfb_platform_remove, + .driver = { + .owner = THIS_MODULE, + .name = DRIVER_NAME, + }, }; static int __init @@ -391,13 +391,13 @@ xilinxfb_init(void) * No kernel boot options used, * so we just need to register the driver */ - return driver_register(&xilinxfb_driver); + return platform_driver_register(&xilinxfb_platform_driver); } static void __exit xilinxfb_cleanup(void) { - driver_unregister(&xilinxfb_driver); + platform_driver_unregister(&xilinxfb_platform_driver); } module_init(xilinxfb_init); -- cgit v1.2.3 From 31e8d4603ecaeb02424c9669e252ab835354a36e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 4 Oct 2007 10:48:37 -0600 Subject: [POWERPC] XilinxFB: add of_platform bus binding Adds the of_platform bus binding to the xilinxfb driver. Needed to use framebuffer devices described in the OF device tree (used by arch/powerpc). Signed-off-by: Grant Likely Acked-by: Andrei Konovalov --- drivers/video/xilinxfb.c | 107 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 98 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index e482bb519635..dbb23a9fef7b 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -6,9 +6,12 @@ * Author: MontaVista Software, Inc. * source@mvista.com * - * 2002-2007 (c) MontaVista Software, Inc. This file is licensed under the - * terms of the GNU General Public License version 2. This program is licensed - * "as is" without any warranty of any kind, whether express or implied. + * 2002-2007 (c) MontaVista Software, Inc. + * 2007 (c) Secret Lab Technologies, Ltd. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. */ /* @@ -29,7 +32,10 @@ #include #include #include - +#if defined(CONFIG_OF) +#include +#include +#endif #include #include @@ -384,20 +390,103 @@ static struct platform_driver xilinxfb_platform_driver = { }, }; +/* --------------------------------------------------------------------- + * OF bus binding + */ + +#if defined(CONFIG_OF) +static int __devinit +xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) +{ + struct resource res; + const u32 *prop; + int width = 0, height = 0, rotate = 0; + int size, rc; + + dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); + + rc = of_address_to_resource(op->node, 0, &res); + if (rc) { + dev_err(&op->dev, "invalid address\n"); + return rc; + } + + prop = of_get_property(op->node, "display-number", &size); + if ((prop) && (size >= sizeof(u32)*2)) { + width = prop[0]; + height = prop[1]; + } + + if (of_find_property(op->node, "rotate-display", NULL)) + rotate = 1; + + return xilinxfb_assign(&op->dev, res.start, width, height, rotate); +} + +static int __devexit xilinxfb_of_remove(struct of_device *op) +{ + return xilinxfb_release(&op->dev); +} + +/* Match table for of_platform binding */ +static struct of_device_id __devinit xilinxfb_of_match[] = { + { .compatible = "xilinx,ml300-fb", }, + {}, +}; +MODULE_DEVICE_TABLE(of, xilinxfb_of_match); + +static struct of_platform_driver xilinxfb_of_driver = { + .owner = THIS_MODULE, + .name = DRIVER_NAME, + .match_table = xilinxfb_of_match, + .probe = xilinxfb_of_probe, + .remove = __devexit_p(xilinxfb_of_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +/* Registration helpers to keep the number of #ifdefs to a minimum */ +static inline int __init xilinxfb_of_register(void) +{ + pr_debug("xilinxfb: calling of_register_platform_driver()\n"); + return of_register_platform_driver(&xilinxfb_of_driver); +} + +static inline void __exit xilinxfb_of_unregister(void) +{ + of_unregister_platform_driver(&xilinxfb_of_driver); +} +#else /* CONFIG_OF */ +/* CONFIG_OF not enabled; do nothing helpers */ +static inline int __init xilinxfb_of_register(void) { return 0; } +static inline void __exit xilinxfb_of_unregister(void) { } +#endif /* CONFIG_OF */ + +/* --------------------------------------------------------------------- + * Module setup and teardown + */ + static int __init xilinxfb_init(void) { - /* - * No kernel boot options used, - * so we just need to register the driver - */ - return platform_driver_register(&xilinxfb_platform_driver); + int rc; + rc = xilinxfb_of_register(); + if (rc) + return rc; + + rc = platform_driver_register(&xilinxfb_platform_driver); + if (rc) + xilinxfb_of_unregister(); + + return rc; } static void __exit xilinxfb_cleanup(void) { platform_driver_unregister(&xilinxfb_platform_driver); + xilinxfb_of_unregister(); } module_init(xilinxfb_init); -- cgit v1.2.3 From e3cec00366e9d60ff65c6f6f8fffdfcadea01056 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 4 Oct 2007 15:44:52 -0600 Subject: [POWERPC] XilinxFB: Make missing pdata structure non-fatal Missing pdata structure is not a fatal error. The device can still be initialized without it. Signed-off-by: Grant Likely --- drivers/video/xilinxfb.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index dbb23a9fef7b..e6e12be845a9 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -349,15 +349,9 @@ xilinxfb_platform_probe(struct platform_device *pdev) { struct xilinxfb_platform_data *pdata; struct resource *res; - int width_mm; - int height_mm; - int rotate; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "Missing pdata structure\n"); - return -ENODEV; - } + int width_mm = 0; + int height_mm = 0; + int rotate = 0; /* Find the registers address */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -366,9 +360,13 @@ xilinxfb_platform_probe(struct platform_device *pdev) return -ENODEV; } - height_mm = pdata->screen_height_mm; - width_mm = pdata->screen_width_mm; - rotate = pdata->rotate_screen ? 1 : 0; + /* If a pdata structure is provided, then extract the parameters */ + pdata = pdev->dev.platform_data; + if (pdata) { + height_mm = pdata->screen_height_mm; + width_mm = pdata->screen_width_mm; + rotate = pdata->rotate_screen ? 1 : 0; + } return xilinxfb_assign(&pdev->dev, res->start, width_mm, height_mm, rotate); -- cgit v1.2.3 From b9a22794f2c186b5722eac94b6735e797d976027 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 4 Oct 2007 10:48:37 -0600 Subject: [POWERPC] XilinxFB: sparse fixes Signed-off-by: Grant Likely --- drivers/video/xilinxfb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index e6e12be845a9..dec602c23075 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -118,7 +118,7 @@ struct xilinxfb_drvdata { u32 regs_phys; /* phys. address of the control registers */ u32 __iomem *regs; /* virt. address of the control registers */ - unsigned char __iomem *fb_virt; /* virt. address of the frame buffer */ + void *fb_virt; /* virt. address of the frame buffer */ dma_addr_t fb_phys; /* phys. address of the frame buffer */ u32 reg_ctrl_default; @@ -246,7 +246,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, } /* Clear (turn to black) the framebuffer */ - memset_io(drvdata->fb_virt, 0, FB_SIZE); + memset_io((void __iomem *)drvdata->fb_virt, 0, FB_SIZE); /* Tell the hardware where the frame buffer is */ xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); @@ -259,7 +259,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, /* Fill struct fb_info */ drvdata->info.device = dev; - drvdata->info.screen_base = drvdata->fb_virt; + drvdata->info.screen_base = (void __iomem *)drvdata->fb_virt; drvdata->info.fbops = &xilinxfb_ops; drvdata->info.fix = xilinx_fb_fix; drvdata->info.fix.smem_start = drvdata->fb_phys; -- cgit v1.2.3 From 73be7d5267774b8fef1d83ebffc070cd090c4398 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 11 Oct 2007 14:50:55 +1000 Subject: [POWERPC] iSeries: Simplify viocd initialisation We don't need to keep a lump of dma coherent memory around for the life of the module. Signed-off-by: Stephen Rothwell Acked-by: Jens Axboe Signed-off-by: Paul Mackerras --- drivers/cdrom/viocd.c | 37 +++++++++++++------------------------ 1 file changed, 13 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index e51550db1575..b88fdebe77f6 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -136,17 +136,12 @@ struct cdrom_info { char type[4]; char model[3]; }; -/* - * This needs to be allocated since it is passed to the - * Hypervisor and we may be a module. - */ -static struct cdrom_info *viocd_unitinfo; -static dma_addr_t unitinfo_dmaaddr; struct disk_info { struct gendisk *viocd_disk; struct cdrom_device_info viocd_info; struct device *dev; + struct cdrom_info unitinfo; }; static struct disk_info viocd_diskinfo[VIOCD_MAX_CD]; @@ -164,9 +159,9 @@ static int proc_viocd_show(struct seq_file *m, void *v) for (i = 0; i < viocd_numdev; i++) { seq_printf(m, "viocd device %d is iSeries resource %10.10s" "type %4.4s, model %3.3s\n", - i, viocd_unitinfo[i].rsrcname, - viocd_unitinfo[i].type, - viocd_unitinfo[i].model); + i, viocd_diskinfo[i].unitinfo.rsrcname, + viocd_diskinfo[i].unitinfo.type, + viocd_diskinfo[i].unitinfo.model); } return 0; } @@ -222,6 +217,8 @@ static void __init get_viocd_info(void) HvLpEvent_Rc hvrc; int i; struct viocd_waitevent we; + struct cdrom_info *viocd_unitinfo; + dma_addr_t unitinfo_dmaaddr; viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, @@ -259,16 +256,15 @@ static void __init get_viocd_info(void) goto error_ret; } - for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) + for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) { + viocd_diskinfo[viocd_numdev].unitinfo = viocd_unitinfo[i]; viocd_numdev++; + } error_ret: - if (viocd_numdev == 0) { - dma_free_coherent(iSeries_vio_dev, - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, - viocd_unitinfo, unitinfo_dmaaddr); - viocd_unitinfo = NULL; - } + dma_free_coherent(iSeries_vio_dev, + sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, + viocd_unitinfo, unitinfo_dmaaddr); } static int viocd_open(struct cdrom_device_info *cdi, int purpose) @@ -674,7 +670,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) d = &viocd_diskinfo[deviceno]; c = &d->viocd_info; - ci = &viocd_unitinfo[deviceno]; + ci = &d->unitinfo; c->ops = &viocd_dops; c->speed = 4; @@ -816,9 +812,6 @@ static int __init viocd_init(void) return 0; out_free_info: - dma_free_coherent(iSeries_vio_dev, - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, - viocd_unitinfo, unitinfo_dmaaddr); vio_clearHandler(viomajorsubtype_cdio); viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); out_unregister: @@ -830,10 +823,6 @@ static void __exit viocd_exit(void) { remove_proc_entry("iSeries/viocd", NULL); vio_unregister_driver(&viocd_driver); - if (viocd_unitinfo != NULL) - dma_free_coherent(iSeries_vio_dev, - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, - viocd_unitinfo, unitinfo_dmaaddr); viopath_close(viopath_hostLp, viomajorsubtype_cdio, MAX_CD_REQ + 2); vio_clearHandler(viomajorsubtype_cdio); unregister_blkdev(VIOCD_MAJOR, VIOCD_DEVICE); -- cgit v1.2.3 From 1670b2b2716b98541765da94be1332ad5c314b7a Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 11 Oct 2007 14:53:32 +1000 Subject: [POWERPC] Remove iSeries_vio_dev It was only being used to carry around dma_iommu_ops and vio_iommu_table which we can use directly instead. This also means that vio_bus_device doesn't need to refer to them either. Signed-off-by: Stephen Rothwell Acked-by: Jens Axboe Signed-off-by: Paul Mackerras --- drivers/cdrom/viocd.c | 5 ++--- drivers/char/viotape.c | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index b88fdebe77f6..c081e5400ce0 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -220,7 +220,7 @@ static void __init get_viocd_info(void) struct cdrom_info *viocd_unitinfo; dma_addr_t unitinfo_dmaaddr; - viocd_unitinfo = dma_alloc_coherent(iSeries_vio_dev, + viocd_unitinfo = iseries_hv_alloc( sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, &unitinfo_dmaaddr, GFP_ATOMIC); if (viocd_unitinfo == NULL) { @@ -262,8 +262,7 @@ static void __init get_viocd_info(void) } error_ret: - dma_free_coherent(iSeries_vio_dev, - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, + iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, viocd_unitinfo, unitinfo_dmaaddr); } diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index e12275df6ea2..064c09195215 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -392,8 +392,8 @@ static int get_viotape_info(void) if (op == NULL) return -ENOMEM; - viotape_unitinfo = dma_alloc_coherent(iSeries_vio_dev, len, - &viotape_unitinfo_token, GFP_ATOMIC); + viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token, + GFP_ATOMIC); if (viotape_unitinfo == NULL) { free_op_struct(op); return -ENOMEM; @@ -1103,8 +1103,7 @@ static void __exit viotap_exit(void) class_destroy(tape_class); unregister_chrdev(VIOTAPE_MAJOR, "viotape"); if (viotape_unitinfo) - dma_free_coherent(iSeries_vio_dev, - sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE, + iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE, viotape_unitinfo, viotape_unitinfo_token); viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); vio_clearHandler(viomajorsubtype_tape); -- cgit v1.2.3 From b833b481c10cf591b15cc674948cc514e55d3b94 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 11 Oct 2007 14:57:26 +1000 Subject: [POWERPC] iSeries: Move detection of virtual cdroms Now we will only have entries in the device tree for the actual existing devices (including their OS/400 properties). This way viocd.c gets all the information about the devices from the device tree. Signed-off-by: Stephen Rothwell Acked-by: Jens Axboe Signed-off-by: Paul Mackerras --- drivers/cdrom/viocd.c | 116 +++++++++----------------------------------------- 1 file changed, 19 insertions(+), 97 deletions(-) (limited to 'drivers') diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index c081e5400ce0..880b5dce3a62 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c @@ -56,30 +56,6 @@ #define VIOCD_KERN_WARNING KERN_WARNING "viocd: " #define VIOCD_KERN_INFO KERN_INFO "viocd: " -struct viocdlpevent { - struct HvLpEvent event; - u32 reserved; - u16 version; - u16 sub_result; - u16 disk; - u16 flags; - u32 token; - u64 offset; /* On open, max number of disks */ - u64 len; /* On open, size of the disk */ - u32 block_size; /* Only set on open */ - u32 media_size; /* Only set on open */ -}; - -enum viocdsubtype { - viocdopen = 0x0001, - viocdclose = 0x0002, - viocdread = 0x0003, - viocdwrite = 0x0004, - viocdlockdoor = 0x0005, - viocdgetinfo = 0x0006, - viocdcheck = 0x0007 -}; - /* * Should probably make this a module parameter....sigh */ @@ -131,17 +107,13 @@ static struct capability_entry capability_table[] __initdata = { /* These are our internal structures for keeping track of devices */ static int viocd_numdev; -struct cdrom_info { - char rsrcname[10]; - char type[4]; - char model[3]; -}; - struct disk_info { struct gendisk *viocd_disk; struct cdrom_device_info viocd_info; struct device *dev; - struct cdrom_info unitinfo; + const char *rsrcname; + const char *type; + const char *model; }; static struct disk_info viocd_diskinfo[VIOCD_MAX_CD]; @@ -159,9 +131,9 @@ static int proc_viocd_show(struct seq_file *m, void *v) for (i = 0; i < viocd_numdev; i++) { seq_printf(m, "viocd device %d is iSeries resource %10.10s" "type %4.4s, model %3.3s\n", - i, viocd_diskinfo[i].unitinfo.rsrcname, - viocd_diskinfo[i].unitinfo.type, - viocd_diskinfo[i].unitinfo.model); + i, viocd_diskinfo[i].rsrcname, + viocd_diskinfo[i].type, + viocd_diskinfo[i].model); } return 0; } @@ -211,61 +183,6 @@ struct block_device_operations viocd_fops = { .media_changed = viocd_blk_media_changed, }; -/* Get info on CD devices from OS/400 */ -static void __init get_viocd_info(void) -{ - HvLpEvent_Rc hvrc; - int i; - struct viocd_waitevent we; - struct cdrom_info *viocd_unitinfo; - dma_addr_t unitinfo_dmaaddr; - - viocd_unitinfo = iseries_hv_alloc( - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, - &unitinfo_dmaaddr, GFP_ATOMIC); - if (viocd_unitinfo == NULL) { - printk(VIOCD_KERN_WARNING "error allocating unitinfo\n"); - return; - } - - memset(viocd_unitinfo, 0, sizeof(*viocd_unitinfo) * VIOCD_MAX_CD); - - init_completion(&we.com); - - hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, - HvLpEvent_Type_VirtualIo, - viomajorsubtype_cdio | viocdgetinfo, - HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, - viopath_sourceinst(viopath_hostLp), - viopath_targetinst(viopath_hostLp), - (u64)&we, VIOVERSION << 16, unitinfo_dmaaddr, 0, - sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, 0); - if (hvrc != HvLpEvent_Rc_Good) { - printk(VIOCD_KERN_WARNING "cdrom error sending event. rc %d\n", - (int)hvrc); - goto error_ret; - } - - wait_for_completion(&we.com); - - if (we.rc) { - const struct vio_error_entry *err = - vio_lookup_rc(viocd_err_table, we.sub_result); - printk(VIOCD_KERN_WARNING "bad rc %d:0x%04X on getinfo: %s\n", - we.rc, we.sub_result, err->msg); - goto error_ret; - } - - for (i = 0; (i < VIOCD_MAX_CD) && viocd_unitinfo[i].rsrcname[0]; i++) { - viocd_diskinfo[viocd_numdev].unitinfo = viocd_unitinfo[i]; - viocd_numdev++; - } - -error_ret: - iseries_hv_free(sizeof(*viocd_unitinfo) * VIOCD_MAX_CD, - viocd_unitinfo, unitinfo_dmaaddr); -} - static int viocd_open(struct cdrom_device_info *cdi, int purpose) { struct disk_info *diskinfo = cdi->handle; @@ -576,7 +493,6 @@ static void vio_handle_cd_event(struct HvLpEvent *event) bevent->block_size / 512); } /* FALLTHROUGH !! */ - case viocdgetinfo: case viocdlockdoor: pwe = (struct viocd_waitevent *)event->xCorrelationToken; return_complete: @@ -660,22 +576,30 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) int deviceno; struct disk_info *d; struct cdrom_device_info *c; - struct cdrom_info *ci; struct request_queue *q; + struct device_node *node = vdev->dev.archdata.of_node; deviceno = vdev->unit_address; - if (deviceno >= viocd_numdev) + if (deviceno > VIOCD_MAX_CD) return -ENODEV; + if (!node) + return -ENODEV; + + if (deviceno >= viocd_numdev) + viocd_numdev = deviceno + 1; d = &viocd_diskinfo[deviceno]; + d->rsrcname = of_get_property(node, "linux,vio_rsrcname", NULL); + d->type = of_get_property(node, "linux,vio_type", NULL); + d->model = of_get_property(node, "linux,vio_model", NULL); + c = &d->viocd_info; - ci = &d->unitinfo; c->ops = &viocd_dops; c->speed = 4; c->capacity = 1; c->handle = d; - c->mask = ~find_capability(ci->type); + c->mask = ~find_capability(d->type); sprintf(c->name, VIOCD_DEVICE "%c", 'a' + deviceno); if (register_cdrom(c) != 0) { @@ -685,7 +609,7 @@ static int viocd_probe(struct vio_dev *vdev, const struct vio_device_id *id) } printk(VIOCD_KERN_INFO "cd %s is iSeries resource %10.10s " "type %4.4s, model %3.3s\n", - c->name, ci->rsrcname, ci->type, ci->model); + c->name, d->rsrcname, d->type, d->model); q = blk_init_queue(do_viocd_request, &viocd_reqlock); if (q == NULL) { printk(VIOCD_KERN_WARNING "Cannot allocate queue for %s!\n", @@ -794,8 +718,6 @@ static int __init viocd_init(void) /* Initialize our request handler */ vio_setHandler(viomajorsubtype_cdio, vio_handle_cd_event); - get_viocd_info(); - spin_lock_init(&viocd_reqlock); ret = vio_register_driver(&viocd_driver); -- cgit v1.2.3 From 7465ce0db310d2fa29f721da7e3aacd1dad7090f Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 11 Oct 2007 14:58:31 +1000 Subject: [POWERPC] iSeries: Move detection of virtual tapes Now we will only have entries in the device tree for the actual existing devices (including their OS/400 properties). This way viotape.c gets all the information about the devices from the device tree. Signed-off-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- drivers/char/viotape.c | 124 +++++++------------------------------------------ 1 file changed, 18 insertions(+), 106 deletions(-) (limited to 'drivers') diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c index 064c09195215..f1d60f0cef8f 100644 --- a/drivers/char/viotape.c +++ b/drivers/char/viotape.c @@ -92,47 +92,6 @@ struct viot_devinfo_struct { #define VIOTAPOP_SETPART 14 #define VIOTAPOP_UNLOAD 15 -struct viotapelpevent { - struct HvLpEvent event; - u32 reserved; - u16 version; - u16 sub_type_result; - u16 tape; - u16 flags; - u32 token; - u64 len; - union { - struct { - u32 tape_op; - u32 count; - } op; - struct { - u32 type; - u32 resid; - u32 dsreg; - u32 gstat; - u32 erreg; - u32 file_no; - u32 block_no; - } get_status; - struct { - u32 block_no; - } get_pos; - } u; -}; - -enum viotapesubtype { - viotapeopen = 0x0001, - viotapeclose = 0x0002, - viotaperead = 0x0003, - viotapewrite = 0x0004, - viotapegetinfo = 0x0005, - viotapeop = 0x0006, - viotapegetpos = 0x0007, - viotapesetpos = 0x0008, - viotapegetstatus = 0x0009 -}; - enum viotaperc { viotape_InvalidRange = 0x0601, viotape_InvalidToken = 0x0602, @@ -223,14 +182,11 @@ static const struct vio_error_entry viotape_err_table[] = { #define VIOT_WRITING 2 /* Our info on the tapes */ -struct tape_descr { - char rsrcname[10]; - char type[4]; - char model[3]; -}; - -static struct tape_descr *viotape_unitinfo; -static dma_addr_t viotape_unitinfo_token; +static struct { + const char *rsrcname; + const char *type; + const char *model; +} viotape_unitinfo[VIOTAPE_MAX_TAPE]; static struct mtget viomtget[VIOTAPE_MAX_TAPE]; @@ -381,53 +337,6 @@ int tape_rc_to_errno(int tape_rc, char *operation, int tapeno) return -err->errno; } -/* Get info on all tapes from OS/400 */ -static int get_viotape_info(void) -{ - HvLpEvent_Rc hvrc; - int i; - size_t len = sizeof(*viotape_unitinfo) * VIOTAPE_MAX_TAPE; - struct op_struct *op = get_op_struct(); - - if (op == NULL) - return -ENOMEM; - - viotape_unitinfo = iseries_hv_alloc(len, &viotape_unitinfo_token, - GFP_ATOMIC); - if (viotape_unitinfo == NULL) { - free_op_struct(op); - return -ENOMEM; - } - - memset(viotape_unitinfo, 0, len); - - hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, - HvLpEvent_Type_VirtualIo, - viomajorsubtype_tape | viotapegetinfo, - HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck, - viopath_sourceinst(viopath_hostLp), - viopath_targetinst(viopath_hostLp), - (u64) (unsigned long) op, VIOVERSION << 16, - viotape_unitinfo_token, len, 0, 0); - if (hvrc != HvLpEvent_Rc_Good) { - printk(VIOTAPE_KERN_WARN "hv error on op %d\n", - (int)hvrc); - free_op_struct(op); - return -EIO; - } - - wait_for_completion(&op->com); - - free_op_struct(op); - - for (i = 0; - ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0])); - i++) - viotape_numdev++; - return 0; -} - - /* Write */ static ssize_t viotap_write(struct file *file, const char *buf, size_t count, loff_t * ppos) @@ -899,7 +808,6 @@ static void vioHandleTapeEvent(struct HvLpEvent *event) tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK; op = (struct op_struct *)event->xCorrelationToken; switch (tapeminor) { - case viotapegetinfo: case viotapeopen: case viotapeclose: op->rc = tevent->sub_type_result; @@ -942,11 +850,23 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id) { int i = vdev->unit_address; int j; + struct device_node *node = vdev->dev.archdata.of_node; - if (i >= viotape_numdev) + if (i > VIOTAPE_MAX_TAPE) + return -ENODEV; + if (!node) return -ENODEV; + if (i >= viotape_numdev) + viotape_numdev = i + 1; + tape_device[i] = &vdev->dev; + viotape_unitinfo[i].rsrcname = of_get_property(node, + "linux,vio_rsrcname", NULL); + viotape_unitinfo[i].type = of_get_property(node, "linux,vio_type", + NULL); + viotape_unitinfo[i].model = of_get_property(node, "linux,vio_model", + NULL); state[i].cur_part = 0; for (j = 0; j < MAX_PARTITIONS; ++j) @@ -1044,11 +964,6 @@ int __init viotap_init(void) goto unreg_chrdev; } - if ((ret = get_viotape_info()) < 0) { - printk(VIOTAPE_KERN_WARN "Unable to obtain virtual device information"); - goto unreg_class; - } - ret = vio_register_driver(&viotape_driver); if (ret) goto unreg_class; @@ -1102,9 +1017,6 @@ static void __exit viotap_exit(void) vio_unregister_driver(&viotape_driver); class_destroy(tape_class); unregister_chrdev(VIOTAPE_MAJOR, "viotape"); - if (viotape_unitinfo) - iseries_hv_free(sizeof(viotape_unitinfo[0]) * VIOTAPE_MAX_TAPE, - viotape_unitinfo, viotape_unitinfo_token); viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2); vio_clearHandler(viomajorsubtype_tape); clear_op_struct_pool(); -- cgit v1.2.3 From 8251b4c481bca72568e9c1042ea11189838e5f6d Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 11 Oct 2007 14:59:54 +1000 Subject: [POWERPC] iSeries: Move viodasd probing This way we only have entries in the device tree for disks that actually exist. A slight complication is that disks may be attached to LPARs at runtime. Signed-off-by: Stephen Rothwell Acked-by: Jens Axboe Signed-off-by: Paul Mackerras --- drivers/block/viodasd.c | 77 ++++++++++++++++--------------------------------- 1 file changed, 25 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c index af3969a9c963..e824b672e05a 100644 --- a/drivers/block/viodasd.c +++ b/drivers/block/viodasd.c @@ -74,53 +74,9 @@ enum { static DEFINE_SPINLOCK(viodasd_spinlock); #define VIOMAXREQ 16 -#define VIOMAXBLOCKDMA 12 #define DEVICE_NO(cell) ((struct viodasd_device *)(cell) - &viodasd_devices[0]) -struct open_data { - u64 disk_size; - u16 max_disk; - u16 cylinders; - u16 tracks; - u16 sectors; - u16 bytes_per_sector; -}; - -struct rw_data { - u64 offset; - struct { - u32 token; - u32 reserved; - u64 len; - } dma_info[VIOMAXBLOCKDMA]; -}; - -struct vioblocklpevent { - struct HvLpEvent event; - u32 reserved; - u16 version; - u16 sub_result; - u16 disk; - u16 flags; - union { - struct open_data open_data; - struct rw_data rw_data; - u64 changed; - } u; -}; - -#define vioblockflags_ro 0x0001 - -enum vioblocksubtype { - vioblockopen = 0x0001, - vioblockclose = 0x0002, - vioblockread = 0x0003, - vioblockwrite = 0x0004, - vioblockflush = 0x0005, - vioblockcheck = 0x0007 -}; - struct viodasd_waitevent { struct completion com; int rc; @@ -429,7 +385,7 @@ static void do_viodasd_request(struct request_queue *q) * Probe a single disk and fill in the viodasd_device structure * for it. */ -static void probe_disk(struct viodasd_device *d) +static int probe_disk(struct viodasd_device *d) { HvLpEvent_Rc hvrc; struct viodasd_waitevent we; @@ -453,14 +409,14 @@ retry: 0, 0, 0); if (hvrc != 0) { printk(VIOD_KERN_WARNING "bad rc on HV open %d\n", (int)hvrc); - return; + return 0; } wait_for_completion(&we.com); if (we.rc != 0) { if (flags != 0) - return; + return 0; /* try again with read only flag set */ flags = vioblockflags_ro; goto retry; @@ -490,15 +446,32 @@ retry: if (hvrc != 0) { printk(VIOD_KERN_WARNING "bad rc sending event to OS/400 %d\n", (int)hvrc); - return; + return 0; } + + if (d->dev == NULL) { + /* this is when we reprobe for new disks */ + if (vio_create_viodasd(dev_no) == NULL) { + printk(VIOD_KERN_WARNING + "cannot allocate virtual device for disk %d\n", + dev_no); + return 0; + } + /* + * The vio_create_viodasd will have recursed into this + * routine with d->dev set to the new vio device and + * will finish the setup of the disk below. + */ + return 1; + } + /* create the request queue for the disk */ spin_lock_init(&d->q_lock); q = blk_init_queue(do_viodasd_request, &d->q_lock); if (q == NULL) { printk(VIOD_KERN_WARNING "cannot allocate queue for disk %d\n", dev_no); - return; + return 0; } g = alloc_disk(1 << PARTITION_SHIFT); if (g == NULL) { @@ -506,7 +479,7 @@ retry: "cannot allocate disk structure for disk %d\n", dev_no); blk_cleanup_queue(q); - return; + return 0; } d->disk = g; @@ -538,6 +511,7 @@ retry: /* register us in the global list */ add_disk(g); + return 1; } /* returns the total number of scatterlist elements converted */ @@ -718,8 +692,7 @@ static int viodasd_probe(struct vio_dev *vdev, const struct vio_device_id *id) struct viodasd_device *d = &viodasd_devices[vdev->unit_address]; d->dev = &vdev->dev; - probe_disk(d); - if (d->disk == NULL) + if (!probe_disk(d)) return -ENODEV; return 0; } -- cgit v1.2.3 From 01ba1e9d26fcd29f3ad4f3a5bcf40c0fbc40ee81 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 11 Oct 2007 04:31:46 +1000 Subject: [POWERPC] XilinxFB: Use pdata to pass around framebuffer parameters The call to xilinxfb_assign is getting unwieldy when adding features to the Xilinx framebuffer driver. Change xilinxfb_assign() to accept a pointer to a xilinxfb_platform_data structure to prepare for adding additition configuration options. Signed-off-by: Grant Likely Signed-off-by: Paul Mackerras --- drivers/video/xilinxfb.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index dec602c23075..b3b57f4a35a2 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -83,6 +83,12 @@ #define PALETTE_ENTRIES_NO 16 /* passed to fb_alloc_cmap() */ +/* + * Default xilinxfb configuration + */ +static struct xilinxfb_platform_data xilinx_fb_default_pdata = { +}; + /* * Here are the default fb_fix_screeninfo and fb_var_screeninfo structures */ @@ -207,7 +213,7 @@ static struct fb_ops xilinxfb_ops = */ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, - int width_mm, int height_mm, int rotate) + struct xilinxfb_platform_data *pdata) { struct xilinxfb_drvdata *drvdata; int rc; @@ -253,7 +259,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, /* Turn on the display */ drvdata->reg_ctrl_default = REG_CTRL_ENABLE; - if (rotate) + if (pdata->rotate_screen) drvdata->reg_ctrl_default |= REG_CTRL_ROTATE; xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); @@ -267,8 +273,8 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, drvdata->info.flags = FBINFO_DEFAULT; drvdata->info.var = xilinx_fb_var; - xilinx_fb_var.height = height_mm; - xilinx_fb_var.width = width_mm; + xilinx_fb_var.height = pdata->screen_height_mm; + xilinx_fb_var.width = pdata->screen_width_mm; /* Allocate a colour map */ rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0); @@ -349,9 +355,6 @@ xilinxfb_platform_probe(struct platform_device *pdev) { struct xilinxfb_platform_data *pdata; struct resource *res; - int width_mm = 0; - int height_mm = 0; - int rotate = 0; /* Find the registers address */ res = platform_get_resource(pdev, IORESOURCE_IO, 0); @@ -361,15 +364,12 @@ xilinxfb_platform_probe(struct platform_device *pdev) } /* If a pdata structure is provided, then extract the parameters */ - pdata = pdev->dev.platform_data; - if (pdata) { - height_mm = pdata->screen_height_mm; - width_mm = pdata->screen_width_mm; - rotate = pdata->rotate_screen ? 1 : 0; - } + if (pdev->dev.platform_data) + pdata = pdev->dev.platform_data; + else + pdata = &xilinx_fb_default_pdata; - return xilinxfb_assign(&pdev->dev, res->start, width_mm, height_mm, - rotate); + return xilinxfb_assign(&pdev->dev, res->start, pdata); } static int @@ -398,9 +398,12 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) { struct resource res; const u32 *prop; - int width = 0, height = 0, rotate = 0; + struct xilinxfb_platform_data pdata; int size, rc; + /* Copy with the default pdata (not a ptr reference!) */ + pdata = xilinx_fb_default_pdata; + dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match); rc = of_address_to_resource(op->node, 0, &res); @@ -411,14 +414,14 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) prop = of_get_property(op->node, "display-number", &size); if ((prop) && (size >= sizeof(u32)*2)) { - width = prop[0]; - height = prop[1]; + pdata.screen_width_mm = prop[0]; + pdata.screen_height_mm = prop[1]; } if (of_find_property(op->node, "rotate-display", NULL)) - rotate = 1; + pdata.rotate_screen = 1; - return xilinxfb_assign(&op->dev, res.start, width, height, rotate); + return xilinxfb_assign(&op->dev, res.start, &pdata); } static int __devexit xilinxfb_of_remove(struct of_device *op) -- cgit v1.2.3 From b4d6a7268fc754eefb196cabc0ccfa2e97022af2 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 11 Oct 2007 04:31:51 +1000 Subject: [POWERPC] XilinxFB: Add support for custom screen resolution Some custom implementations of the xilinx fb can use resolutions other than 640x480. This patch allows the resolution to be specified in the device tree or the xilinx_platform_data structure. Signed-off-by: Grant Likely Signed-off-by: Paul Mackerras --- drivers/video/xilinxfb.c | 71 ++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index b3b57f4a35a2..c6174125f52b 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -70,12 +70,6 @@ */ #define BYTES_PER_PIXEL 4 #define BITS_PER_PIXEL (BYTES_PER_PIXEL * 8) -#define XRES 640 -#define YRES 480 -#define XRES_VIRTUAL 1024 -#define YRES_VIRTUAL YRES -#define LINE_LENGTH (XRES_VIRTUAL * BYTES_PER_PIXEL) -#define FB_SIZE (YRES_VIRTUAL * LINE_LENGTH) #define RED_SHIFT 16 #define GREEN_SHIFT 8 @@ -87,6 +81,10 @@ * Default xilinxfb configuration */ static struct xilinxfb_platform_data xilinx_fb_default_pdata = { + .xres = 640, + .yres = 480, + .xvirt = 1024, + .yvirt = 480; }; /* @@ -96,17 +94,10 @@ static struct fb_fix_screeninfo xilinx_fb_fix = { .id = "Xilinx", .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, - .smem_len = FB_SIZE, - .line_length = LINE_LENGTH, .accel = FB_ACCEL_NONE }; static struct fb_var_screeninfo xilinx_fb_var = { - .xres = XRES, - .yres = YRES, - .xres_virtual = XRES_VIRTUAL, - .yres_virtual = YRES_VIRTUAL, - .bits_per_pixel = BITS_PER_PIXEL, .red = { RED_SHIFT, 8, 0 }, @@ -217,6 +208,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, { struct xilinxfb_drvdata *drvdata; int rc; + int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL; /* Allocate the driver data region */ drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); @@ -243,7 +235,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, } /* Allocate the framebuffer memory */ - drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(FB_SIZE), + drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize), &drvdata->fb_phys, GFP_KERNEL); if (!drvdata->fb_virt) { dev_err(dev, "Could not allocate frame buffer memory\n"); @@ -252,7 +244,7 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, } /* Clear (turn to black) the framebuffer */ - memset_io((void __iomem *)drvdata->fb_virt, 0, FB_SIZE); + memset_io((void __iomem *)drvdata->fb_virt, 0, fbsize); /* Tell the hardware where the frame buffer is */ xilinx_fb_out_be32(drvdata, REG_FB_ADDR, drvdata->fb_phys); @@ -269,12 +261,18 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, drvdata->info.fbops = &xilinxfb_ops; drvdata->info.fix = xilinx_fb_fix; drvdata->info.fix.smem_start = drvdata->fb_phys; + drvdata->info.fix.smem_len = fbsize; + drvdata->info.fix.line_length = pdata->xvirt * BYTES_PER_PIXEL; + drvdata->info.pseudo_palette = drvdata->pseudo_palette; drvdata->info.flags = FBINFO_DEFAULT; drvdata->info.var = xilinx_fb_var; - - xilinx_fb_var.height = pdata->screen_height_mm; - xilinx_fb_var.width = pdata->screen_width_mm; + drvdata->info.var.height = pdata->screen_height_mm; + drvdata->info.var.width = pdata->screen_width_mm; + drvdata->info.var.xres = pdata->xres; + drvdata->info.var.yres = pdata->yres; + drvdata->info.var.xres_virtual = pdata->xvirt; + drvdata->info.var.yres_virtual = pdata->yvirt; /* Allocate a colour map */ rc = fb_alloc_cmap(&drvdata->info.cmap, PALETTE_ENTRIES_NO, 0); @@ -294,14 +292,15 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, /* Put a banner in the log (for DEBUG) */ dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs); dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n", - (void*)drvdata->fb_phys, drvdata->fb_virt, FB_SIZE); + (void*)drvdata->fb_phys, drvdata->fb_virt, fbsize); + return 0; /* success */ err_regfb: fb_dealloc_cmap(&drvdata->info.cmap); err_cmap: - dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, + dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, drvdata->fb_phys); /* Turn off the display */ xilinx_fb_out_be32(drvdata, REG_CTRL, 0); @@ -331,8 +330,8 @@ static int xilinxfb_release(struct device *dev) fb_dealloc_cmap(&drvdata->info.cmap); - dma_free_coherent(dev, PAGE_ALIGN(FB_SIZE), drvdata->fb_virt, - drvdata->fb_phys); + dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), + drvdata->fb_virt, drvdata->fb_phys); /* Turn off the display */ xilinx_fb_out_be32(drvdata, REG_CTRL, 0); @@ -364,10 +363,18 @@ xilinxfb_platform_probe(struct platform_device *pdev) } /* If a pdata structure is provided, then extract the parameters */ - if (pdev->dev.platform_data) + pdata = &xilinx_fb_default_pdata; + if (pdev->dev.platform_data) { pdata = pdev->dev.platform_data; - else - pdata = &xilinx_fb_default_pdata; + if (!pdata->xres) + pdata->xres = xilinx_fb_default_pdata.xres; + if (!pdata->yres) + pdata->yres = xilinx_fb_default_pdata.yres; + if (!pdata->xvirt) + pdata->xvirt = xilinx_fb_default_pdata.xvirt; + if (!pdata->yvirt) + pdata->yvirt = xilinx_fb_default_pdata.yvirt; + } return xilinxfb_assign(&pdev->dev, res->start, pdata); } @@ -412,12 +419,24 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match) return rc; } - prop = of_get_property(op->node, "display-number", &size); + prop = of_get_property(op->node, "phys-size", &size); if ((prop) && (size >= sizeof(u32)*2)) { pdata.screen_width_mm = prop[0]; pdata.screen_height_mm = prop[1]; } + prop = of_get_property(op->node, "resolution", &size); + if ((prop) && (size >= sizeof(u32)*2)) { + pdata.xres = prop[0]; + pdata.yres = prop[1]; + } + + prop = of_get_property(op->node, "virtual-resolution", &size); + if ((prop) && (size >= sizeof(u32)*2)) { + pdata.xvirt = prop[0]; + pdata.yvirt = prop[1]; + } + if (of_find_property(op->node, "rotate-display", NULL)) pdata.rotate_screen = 1; -- cgit v1.2.3 From 287e5d6fcccfa38b953cebe307e1ddfd32363355 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 11 Oct 2007 04:31:56 +1000 Subject: [POWERPC] XilinxFB: Allow fixed framebuffer base address Allow a fixed framebuffer address to be assigned to the framebuffer device instead of allocating the framebuffer from the consistent memory pool. Signed-off-by: Grant Likely Signed-off-by: Paul Mackerras --- drivers/video/xilinxfb.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c index c6174125f52b..6ef99b2d13ca 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/xilinxfb.c @@ -117,6 +117,7 @@ struct xilinxfb_drvdata { void *fb_virt; /* virt. address of the frame buffer */ dma_addr_t fb_phys; /* phys. address of the frame buffer */ + int fb_alloced; /* Flag, was the fb memory alloced? */ u32 reg_ctrl_default; @@ -235,8 +236,15 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr, } /* Allocate the framebuffer memory */ - drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize), - &drvdata->fb_phys, GFP_KERNEL); + if (pdata->fb_phys) { + drvdata->fb_phys = pdata->fb_phys; + drvdata->fb_virt = ioremap(pdata->fb_phys, fbsize); + } else { + drvdata->fb_alloced = 1; + drvdata->fb_virt = dma_alloc_coherent(dev, PAGE_ALIGN(fbsize), + &drvdata->fb_phys, GFP_KERNEL); + } + if (!drvdata->fb_virt) { dev_err(dev, "Could not allocate frame buffer memory\n"); rc = -ENOMEM; @@ -300,8 +308,9 @@ err_regfb: fb_dealloc_cmap(&drvdata->info.cmap); err_cmap: - dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, - drvdata->fb_phys); + if (drvdata->fb_alloced) + dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt, + drvdata->fb_phys); /* Turn off the display */ xilinx_fb_out_be32(drvdata, REG_CTRL, 0); @@ -330,8 +339,9 @@ static int xilinxfb_release(struct device *dev) fb_dealloc_cmap(&drvdata->info.cmap); - dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), - drvdata->fb_virt, drvdata->fb_phys); + if (drvdata->fb_alloced) + dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len), + drvdata->fb_virt, drvdata->fb_phys); /* Turn off the display */ xilinx_fb_out_be32(drvdata, REG_CTRL, 0); -- cgit v1.2.3