127dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss/* 227dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss * devoard misc stuff. 327dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss */ 427dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 527dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss#include <linux/init.h> 6206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss#include <linux/mtd/mtd.h> 7206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss#include <linux/mtd/map.h> 8206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss#include <linux/mtd/physmap.h> 927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss#include <linux/slab.h> 1027dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss#include <linux/platform_device.h> 1132fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss#include <linux/pm.h> 1232fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss 1332fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss#include <asm/reboot.h> 1432fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss#include <asm/mach-db1x00/bcsr.h> 1532fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss 161c043f16a01c144305e952025e883b55706f2450Manuel Lauss 171c043f16a01c144305e952025e883b55706f2450Manuel Laussstatic struct platform_device db1x00_rtc_dev = { 181c043f16a01c144305e952025e883b55706f2450Manuel Lauss .name = "rtc-au1xxx", 191c043f16a01c144305e952025e883b55706f2450Manuel Lauss .id = -1, 201c043f16a01c144305e952025e883b55706f2450Manuel Lauss}; 211c043f16a01c144305e952025e883b55706f2450Manuel Lauss 221c043f16a01c144305e952025e883b55706f2450Manuel Lauss 2332fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Laussstatic void db1x_power_off(void) 2432fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss{ 2532fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss bcsr_write(BCSR_RESETS, 0); 2632fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss bcsr_write(BCSR_SYSTEM, BCSR_SYSTEM_PWROFF | BCSR_SYSTEM_RESET); 2732fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss} 2832fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss 2932fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Laussstatic void db1x_reset(char *c) 3032fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss{ 3132fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss bcsr_write(BCSR_RESETS, 0); 3232fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss bcsr_write(BCSR_SYSTEM, 0); 3332fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss} 3432fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss 351c043f16a01c144305e952025e883b55706f2450Manuel Laussstatic int __init db1x_late_setup(void) 3632fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss{ 3732fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss if (!pm_power_off) 3832fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss pm_power_off = db1x_power_off; 3932fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss if (!_machine_halt) 4032fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss _machine_halt = db1x_power_off; 4132fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss if (!_machine_restart) 4232fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss _machine_restart = db1x_reset; 4332fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss 441c043f16a01c144305e952025e883b55706f2450Manuel Lauss platform_device_register(&db1x00_rtc_dev); 451c043f16a01c144305e952025e883b55706f2450Manuel Lauss 4632fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss return 0; 4732fd6901a6d8d19f94e4de6be4e4b552ab078620Manuel Lauss} 481c043f16a01c144305e952025e883b55706f2450Manuel Laussdevice_initcall(db1x_late_setup); 4927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 5027dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss/* register a pcmcia socket */ 5111b897cf84c37e6522db914793677e933ef311fbManuel Laussint __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start, 5211b897cf84c37e6522db914793677e933ef311fbManuel Lauss phys_addr_t pcmcia_attr_end, 5311b897cf84c37e6522db914793677e933ef311fbManuel Lauss phys_addr_t pcmcia_mem_start, 5411b897cf84c37e6522db914793677e933ef311fbManuel Lauss phys_addr_t pcmcia_mem_end, 5511b897cf84c37e6522db914793677e933ef311fbManuel Lauss phys_addr_t pcmcia_io_start, 5611b897cf84c37e6522db914793677e933ef311fbManuel Lauss phys_addr_t pcmcia_io_end, 5727dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss int card_irq, 5827dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss int cd_irq, 5927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss int stschg_irq, 6027dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss int eject_irq, 6127dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss int id) 6227dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss{ 6327dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss int cnt, i, ret; 6427dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss struct resource *sr; 6527dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss struct platform_device *pd; 6627dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 6727dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss cnt = 5; 6827dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss if (eject_irq) 6927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss cnt++; 7027dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss if (stschg_irq) 7127dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss cnt++; 7227dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 7327dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr = kzalloc(sizeof(struct resource) * cnt, GFP_KERNEL); 7427dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss if (!sr) 7527dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss return -ENOMEM; 7627dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 7727dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss pd = platform_device_alloc("db1xxx_pcmcia", id); 7827dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss if (!pd) { 7927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss ret = -ENOMEM; 8027dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss goto out; 8127dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss } 8227dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 8311b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[0].name = "pcmcia-attr"; 8427dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[0].flags = IORESOURCE_MEM; 8511b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[0].start = pcmcia_attr_start; 8611b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[0].end = pcmcia_attr_end; 8727dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 8811b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[1].name = "pcmcia-mem"; 8927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[1].flags = IORESOURCE_MEM; 9011b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[1].start = pcmcia_mem_start; 9111b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[1].end = pcmcia_mem_end; 9227dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 9311b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[2].name = "pcmcia-io"; 9427dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[2].flags = IORESOURCE_MEM; 9511b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[2].start = pcmcia_io_start; 9611b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[2].end = pcmcia_io_end; 9727dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 9827dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[3].name = "insert"; 9927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[3].flags = IORESOURCE_IRQ; 10027dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[3].start = sr[3].end = cd_irq; 10127dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 10227dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[4].name = "card"; 10327dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[4].flags = IORESOURCE_IRQ; 10427dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[4].start = sr[4].end = card_irq; 10527dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 10627dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss i = 5; 10727dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss if (stschg_irq) { 10811b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[i].name = "stschg"; 10927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[i].flags = IORESOURCE_IRQ; 11011b897cf84c37e6522db914793677e933ef311fbManuel Lauss sr[i].start = sr[i].end = stschg_irq; 11127dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss i++; 11227dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss } 11327dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss if (eject_irq) { 11427dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[i].name = "eject"; 11527dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[i].flags = IORESOURCE_IRQ; 11627dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss sr[i].start = sr[i].end = eject_irq; 11727dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss } 11827dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 11927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss pd->resource = sr; 12027dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss pd->num_resources = cnt; 12127dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 12227dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss ret = platform_device_add(pd); 12327dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss if (!ret) 12427dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss return 0; 12527dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss 12627dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss platform_device_put(pd); 12727dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Laussout: 12827dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss kfree(sr); 12927dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss return ret; 13027dd65ac9afabc8e67ab73f7c2f575eddbb47167Manuel Lauss} 131206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 132206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss#define YAMON_SIZE 0x00100000 133206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss#define YAMON_ENV_SIZE 0x00040000 134206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 135206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Laussint __init db1x_register_norflash(unsigned long size, int width, 136206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss int swapped) 137206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss{ 138206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss struct physmap_flash_data *pfd; 139206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss struct platform_device *pd; 140206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss struct mtd_partition *parts; 141206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss struct resource *res; 142206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss int ret, i; 143206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 144206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss if (size < (8 * 1024 * 1024)) 145206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss return -EINVAL; 146206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 147206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss ret = -ENOMEM; 148206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts = kzalloc(sizeof(struct mtd_partition) * 5, GFP_KERNEL); 149206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss if (!parts) 150206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss goto out; 151206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 152206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss res = kzalloc(sizeof(struct resource), GFP_KERNEL); 153206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss if (!res) 154206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss goto out1; 155206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 156206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss pfd = kzalloc(sizeof(struct physmap_flash_data), GFP_KERNEL); 157206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss if (!pfd) 158206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss goto out2; 159206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 160206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss pd = platform_device_alloc("physmap-flash", 0); 161206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss if (!pd) 162206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss goto out3; 163206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 164206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss /* NOR flash ends at 0x20000000, regardless of size */ 165206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss res->start = 0x20000000 - size; 166206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss res->end = 0x20000000 - 1; 167206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss res->flags = IORESOURCE_MEM; 168206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 169206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss /* partition setup. Most Develboards have a switch which allows 170206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss * to swap the physical locations of the 2 NOR flash banks. 171206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss */ 172206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss i = 0; 173206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss if (!swapped) { 174206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss /* first NOR chip */ 175206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].offset = 0; 176206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].name = "User FS"; 177206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].size = size / 2; 178206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss i++; 179206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss } 180206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 181206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].offset = MTDPART_OFS_APPEND; 182206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].name = "User FS 2"; 183206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].size = (size / 2) - (0x20000000 - 0x1fc00000); 184206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss i++; 185206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 186206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].offset = MTDPART_OFS_APPEND; 187206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].name = "YAMON"; 188206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].size = YAMON_SIZE; 189206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].mask_flags = MTD_WRITEABLE; 190206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss i++; 191206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 192206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].offset = MTDPART_OFS_APPEND; 193206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].name = "raw kernel"; 194206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].size = 0x00400000 - YAMON_SIZE - YAMON_ENV_SIZE; 195206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss i++; 196206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 197206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].offset = MTDPART_OFS_APPEND; 198206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].name = "YAMON Env"; 199206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].size = YAMON_ENV_SIZE; 200206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].mask_flags = MTD_WRITEABLE; 201206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss i++; 202206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 203206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss if (swapped) { 204206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].offset = MTDPART_OFS_APPEND; 205206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].name = "User FS"; 206206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss parts[i].size = size / 2; 207206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss i++; 208206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss } 209206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 210206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss pfd->width = width; 211206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss pfd->parts = parts; 212206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss pfd->nr_parts = 5; 213206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 214206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss pd->dev.platform_data = pfd; 215206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss pd->resource = res; 216206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss pd->num_resources = 1; 217206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 218206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss ret = platform_device_add(pd); 219206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss if (!ret) 220206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss return ret; 221206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss 222206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss platform_device_put(pd); 223206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Laussout3: 224206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss kfree(pfd); 225206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Laussout2: 226206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss kfree(res); 227206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Laussout1: 228206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss kfree(parts); 229206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Laussout: 230206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss return ret; 231206aa6cdadad8bbedee5649f1346fe47e922a039Manuel Lauss} 232