From 5b36f1deefa63ef71cd3c3933781318ac61c5469 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sun, 12 Jul 2009 10:03:42 +0000 Subject: hvc_console: Drop unnecessary NULL test The result of container_of should not be NULL. In particular, in this case the argument to the enclosing function has passed though INIT_WORK, which dereferences it, implying that its container cannot be NULL. A simplified version of the semantic patch that makes this change is as follows: (http://www.emn.fr/x-info/coccinelle/) // @@ identifier fn,work,x,fld; type T; expression E1,E2; statement S; @@ static fn(struct work_struct *work) { ... when != work = E1 x = container_of(work,T,fld) ... when != x = E2 - if (x == NULL) S ... } // Signed-off-by: Julia Lawall Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_console.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index d97779ef72c..25ce15bb1c0 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c @@ -516,8 +516,6 @@ static void hvc_set_winsz(struct work_struct *work) struct winsize ws; hp = container_of(work, struct hvc_struct, tty_resize); - if (!hp) - return; spin_lock_irqsave(&hp->lock, hvc_flags); if (!hp->tty) { -- cgit v1.2.3 From 52f072cb084bbb460d3a4ae09f0b6efc3e7e8a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 4 Aug 2009 11:51:03 +0000 Subject: agp/uninorth: Allow larger aperture sizes on pre-U3 bridges. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using the radeon KMS test functionality, I verified that the AGP bridge of the Intrepid2 chipset in my PowerBook supports aperture sizes up to 256M. So allow aperture sizes up to 256M on pre-U3 bridges as well, and bump the default size to 256M. It's possible that older revisions only support smaller sizes, but it'll be easy to verify that with the raden KMS test functionality. Also, there's only a problem on an actual attempt to access the aperture beyond the maximum size supported by the hardware, and non-KMS X still defaults to using only 32M. Also use ARRAY_SIZE for the aperture size arrays. Signed-off-by: Michel Dänzer Signed-off-by: Benjamin Herrenschmidt --- drivers/char/agp/uninorth-agp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index f192c3b9ad4..37ff3bd56d6 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -27,6 +27,8 @@ static int uninorth_rev; static int is_u3; +#define DEFAULT_APERTURE_SIZE 256 +#define DEFAULT_APERTURE_STRING "256" static char *aperture = NULL; static int uninorth_fetch_size(void) @@ -55,7 +57,7 @@ static int uninorth_fetch_size(void) if (!size) { for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) - if (values[i].size == 32) + if (values[i].size == DEFAULT_APERTURE_SIZE) break; } @@ -474,13 +476,11 @@ void null_cache_flush(void) /* Setup function */ -static const struct aper_size_info_32 uninorth_sizes[7] = +static const struct aper_size_info_32 uninorth_sizes[] = { -#if 0 /* Not sure uninorth supports that high aperture sizes */ {256, 65536, 6, 64}, {128, 32768, 5, 32}, {64, 16384, 4, 16}, -#endif {32, 8192, 3, 8}, {16, 4096, 2, 4}, {8, 2048, 1, 2}, @@ -491,7 +491,7 @@ static const struct aper_size_info_32 uninorth_sizes[7] = * Not sure that u3 supports that high aperture sizes but it * would strange if it did not :) */ -static const struct aper_size_info_32 u3_sizes[8] = +static const struct aper_size_info_32 u3_sizes[] = { {512, 131072, 7, 128}, {256, 65536, 6, 64}, @@ -507,7 +507,7 @@ const struct agp_bridge_driver uninorth_agp_driver = { .owner = THIS_MODULE, .aperture_sizes = (void *)uninorth_sizes, .size_type = U32_APER_SIZE, - .num_aperture_sizes = 4, + .num_aperture_sizes = ARRAY_SIZE(uninorth_sizes), .configure = uninorth_configure, .fetch_size = uninorth_fetch_size, .cleanup = uninorth_cleanup, @@ -534,7 +534,7 @@ const struct agp_bridge_driver u3_agp_driver = { .owner = THIS_MODULE, .aperture_sizes = (void *)u3_sizes, .size_type = U32_APER_SIZE, - .num_aperture_sizes = 8, + .num_aperture_sizes = ARRAY_SIZE(u3_sizes), .configure = uninorth_configure, .fetch_size = uninorth_fetch_size, .cleanup = uninorth_cleanup, @@ -717,7 +717,7 @@ module_param(aperture, charp, 0); MODULE_PARM_DESC(aperture, "Aperture size, must be power of two between 4MB and an\n" "\t\tupper limit specific to the UniNorth revision.\n" - "\t\tDefault: 32M"); + "\t\tDefault: " DEFAULT_APERTURE_STRING "M"); MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From e8a5f900148d058bce2d7bdce3d6bcbcb40267ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Tue, 4 Aug 2009 11:51:04 +0000 Subject: agp/uninorth: Simplify cache flushing. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Map the GART table uncached, so we don't always need to flush the CPU caches explicitly after updates. Signed-off-by: Michel Dänzer Signed-off-by: Benjamin Herrenschmidt --- drivers/char/agp/uninorth-agp.c | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 37ff3bd56d6..bba29abe917 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -181,8 +182,6 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, } (void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]); mb(); - flush_dcache_range((unsigned long)&agp_bridge->gatt_table[pg_start], - (unsigned long)&agp_bridge->gatt_table[pg_start + mem->page_count]); uninorth_tlbflush(mem); return 0; @@ -226,7 +225,6 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type) (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000); } mb(); - flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]); uninorth_tlbflush(mem); return 0; @@ -245,7 +243,6 @@ int u3_remove_memory(struct agp_memory *mem, off_t pg_start, int type) for (i = 0; i < mem->page_count; ++i) gp[i] = 0; mb(); - flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]); uninorth_tlbflush(mem); return 0; @@ -398,6 +395,7 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) int i; void *temp; struct page *page; + struct page **pages; /* We can't handle 2 level gatt's */ if (bridge->driver->size_type == LVL2_APER_SIZE) @@ -426,21 +424,39 @@ static int uninorth_create_gatt_table(struct agp_bridge_data *bridge) if (table == NULL) return -ENOMEM; + pages = kmalloc((1 << page_order) * sizeof(struct page*), GFP_KERNEL); + if (pages == NULL) + goto enomem; + table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1); - for (page = virt_to_page(table); page <= virt_to_page(table_end); page++) + for (page = virt_to_page(table), i = 0; page <= virt_to_page(table_end); + page++, i++) { SetPageReserved(page); + pages[i] = page; + } bridge->gatt_table_real = (u32 *) table; - bridge->gatt_table = (u32 *)table; + /* Need to clear out any dirty data still sitting in caches */ + flush_dcache_range((unsigned long)table, + (unsigned long)(table_end + PAGE_SIZE)); + bridge->gatt_table = vmap(pages, (1 << page_order), 0, PAGE_KERNEL_NCG); + + if (bridge->gatt_table == NULL) + goto enomem; + bridge->gatt_bus_addr = virt_to_gart(table); for (i = 0; i < num_entries; i++) bridge->gatt_table[i] = 0; - flush_dcache_range((unsigned long)table, (unsigned long)table_end); - return 0; + +enomem: + kfree(pages); + if (table) + free_pages((unsigned long)table, page_order); + return -ENOMEM; } static int uninorth_free_gatt_table(struct agp_bridge_data *bridge) @@ -458,6 +474,7 @@ static int uninorth_free_gatt_table(struct agp_bridge_data *bridge) * from the table. */ + vunmap(bridge->gatt_table); table = (char *) bridge->gatt_table_real; table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1); -- cgit v1.2.3 From 728656506447b3b349d082a7fb99445f9cb0caaa Mon Sep 17 00:00:00 2001 From: Roel Kluin Date: Thu, 6 Aug 2009 13:00:37 +0000 Subject: powerpc/hvsi: Avoid calculating possibly-invalid address Check whether index is within bounds prior to calculating a possibly-invalid address. Signed-off-by: Roel Kluin Cc: Bernd Petrovitsch Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvsi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/char') diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 2989056a9e3..793b236c926 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c @@ -1230,11 +1230,12 @@ static struct tty_driver *hvsi_console_device(struct console *console, static int __init hvsi_console_setup(struct console *console, char *options) { - struct hvsi_struct *hp = &hvsi_ports[console->index]; + struct hvsi_struct *hp; int ret; if (console->index < 0 || console->index >= hvsi_count) return -1; + hp = &hvsi_ports[console->index]; /* give the FSP a chance to change the baud rate when we re-open */ hvsi_close_protocol(hp); -- cgit v1.2.3 From 948c28fe3001f2c9d852dff2a0b2c69fe7cec91b Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 20 Aug 2009 11:14:06 +0000 Subject: hvc_console: Add __init and __exit to hvc_vio Trivial patch which adds the __init/__exit macros to the module_init/ module_exit functions of char/hvc_vio.c Please have a look at the small patch and either pull it through your tree, or please ack' it so Jiri can pull it through the trivial tree. linux version 2.6.31-rc6 - linus git tree, Do 20. Aug 22:26:06 CEST 2009 Signed-off-by: Peter Huewe Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_vio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index c72b994652a..10be343d6ae 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c @@ -120,7 +120,7 @@ static struct vio_driver hvc_vio_driver = { } }; -static int hvc_vio_init(void) +static int __init hvc_vio_init(void) { int rc; @@ -134,7 +134,7 @@ static int hvc_vio_init(void) } module_init(hvc_vio_init); /* after drivers/char/hvc_console.c */ -static void hvc_vio_exit(void) +static void __exit hvc_vio_exit(void) { vio_unregister_driver(&hvc_vio_driver); } -- cgit v1.2.3 From d331d8305cba713605854aab63a000fb892353a7 Mon Sep 17 00:00:00 2001 From: Martyn Welch Date: Thu, 13 Aug 2009 09:03:02 +0100 Subject: powerpc/nvram: Enable use Generic NVRAM driver for different size chips Remove the reliance on a staticly defined NVRAM size, allowing platforms to support NVRAMs with sizes differing from the standard. A fall back value is provided for platforms not supporting this extension. Signed-off-by: Martyn Welch Signed-off-by: Benjamin Herrenschmidt --- drivers/char/generic_nvram.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'drivers/char') diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index a00869c650d..ef31738c2cb 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c @@ -2,7 +2,7 @@ * Generic /dev/nvram driver for architectures providing some * "generic" hooks, that is : * - * nvram_read_byte, nvram_write_byte, nvram_sync + * nvram_read_byte, nvram_write_byte, nvram_sync, nvram_get_size * * Note that an additional hook is supported for PowerMac only * for getting the nvram "partition" informations @@ -28,6 +28,8 @@ #define NVRAM_SIZE 8192 +static ssize_t nvram_len; + static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) { lock_kernel(); @@ -36,7 +38,7 @@ static loff_t nvram_llseek(struct file *file, loff_t offset, int origin) offset += file->f_pos; break; case 2: - offset += NVRAM_SIZE; + offset += nvram_len; break; } if (offset < 0) { @@ -56,9 +58,9 @@ static ssize_t read_nvram(struct file *file, char __user *buf, if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; - if (*ppos >= NVRAM_SIZE) + if (*ppos >= nvram_len) return 0; - for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) + for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) if (__put_user(nvram_read_byte(i), p)) return -EFAULT; *ppos = i; @@ -74,9 +76,9 @@ static ssize_t write_nvram(struct file *file, const char __user *buf, if (!access_ok(VERIFY_READ, buf, count)) return -EFAULT; - if (*ppos >= NVRAM_SIZE) + if (*ppos >= nvram_len) return 0; - for (i = *ppos; count > 0 && i < NVRAM_SIZE; ++i, ++p, --count) { + for (i = *ppos; count > 0 && i < nvram_len; ++i, ++p, --count) { if (__get_user(c, p)) return -EFAULT; nvram_write_byte(c, i); @@ -133,9 +135,20 @@ static struct miscdevice nvram_dev = { int __init nvram_init(void) { + int ret = 0; + printk(KERN_INFO "Generic non-volatile memory driver v%s\n", NVRAM_VERSION); - return misc_register(&nvram_dev); + ret = misc_register(&nvram_dev); + if (ret != 0) + goto out; + + nvram_len = nvram_get_size(); + if (nvram_len < 0) + nvram_len = NVRAM_SIZE; + +out: + return ret; } void __exit nvram_cleanup(void) -- cgit v1.2.3