Loading drivers/misc/sony-laptop.c +148 −56 Original line number Original line Diff line number Diff line Loading @@ -1173,7 +1173,8 @@ static struct acpi_driver sony_nc_driver = { #define SONYPI_TYPE3_OFFSET 0x12 #define SONYPI_TYPE3_OFFSET 0x12 struct sony_pic_ioport { struct sony_pic_ioport { struct acpi_resource_io io; struct acpi_resource_io io1; struct acpi_resource_io io2; struct list_head list; struct list_head list; }; }; Loading Loading @@ -1443,11 +1444,11 @@ static u8 sony_pic_call1(u8 dev) { { u8 v1, v2; u8 v1, v2; wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); ITERATIONS_LONG); outb(dev, spic_dev.cur_ioport->io.minimum + 4); outb(dev, spic_dev.cur_ioport->io1.minimum + 4); v1 = inb_p(spic_dev.cur_ioport->io.minimum + 4); v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4); v2 = inb_p(spic_dev.cur_ioport->io.minimum); v2 = inb_p(spic_dev.cur_ioport->io1.minimum); dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1); dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1); return v2; return v2; } } Loading @@ -1456,13 +1457,13 @@ static u8 sony_pic_call2(u8 dev, u8 fn) { { u8 v1; u8 v1; wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); ITERATIONS_LONG); outb(dev, spic_dev.cur_ioport->io.minimum + 4); outb(dev, spic_dev.cur_ioport->io1.minimum + 4); wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); ITERATIONS_LONG); outb(fn, spic_dev.cur_ioport->io.minimum); outb(fn, spic_dev.cur_ioport->io1.minimum); v1 = inb_p(spic_dev.cur_ioport->io.minimum); v1 = inb_p(spic_dev.cur_ioport->io1.minimum); dprintk("sony_pic_call2: 0x%.4x\n", v1); dprintk("sony_pic_call2: 0x%.4x\n", v1); return v1; return v1; } } Loading @@ -1471,13 +1472,13 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v) { { u8 v1; u8 v1; wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); outb(dev, spic_dev.cur_ioport->io.minimum + 4); outb(dev, spic_dev.cur_ioport->io1.minimum + 4); wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); outb(fn, spic_dev.cur_ioport->io.minimum); outb(fn, spic_dev.cur_ioport->io1.minimum); wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); outb(v, spic_dev.cur_ioport->io.minimum); outb(v, spic_dev.cur_ioport->io1.minimum); v1 = inb_p(spic_dev.cur_ioport->io.minimum); v1 = inb_p(spic_dev.cur_ioport->io1.minimum); dprintk("sony_pic_call3: 0x%.4x\n", v1); dprintk("sony_pic_call3: 0x%.4x\n", v1); return v1; return v1; } } Loading Loading @@ -2074,7 +2075,18 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) switch (resource->type) { switch (resource->type) { case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_START_DEPENDENT: { /* start IO enumeration */ struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); if (!ioport) return AE_ERROR; list_add(&ioport->list, &dev->ioports); return AE_OK; } case ACPI_RESOURCE_TYPE_END_DEPENDENT: case ACPI_RESOURCE_TYPE_END_DEPENDENT: /* end IO enumeration */ return AE_OK; return AE_OK; case ACPI_RESOURCE_TYPE_IRQ: case ACPI_RESOURCE_TYPE_IRQ: Loading @@ -2101,7 +2113,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) if (!interrupt) if (!interrupt) return AE_ERROR; return AE_ERROR; list_add_tail(&interrupt->list, &dev->interrupts); list_add(&interrupt->list, &dev->interrupts); interrupt->irq.triggering = p->triggering; interrupt->irq.triggering = p->triggering; interrupt->irq.polarity = p->polarity; interrupt->irq.polarity = p->polarity; interrupt->irq.sharable = p->sharable; interrupt->irq.sharable = p->sharable; Loading @@ -2113,18 +2125,27 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) case ACPI_RESOURCE_TYPE_IO: case ACPI_RESOURCE_TYPE_IO: { { struct acpi_resource_io *io = &resource->data.io; struct acpi_resource_io *io = &resource->data.io; struct sony_pic_ioport *ioport = NULL; struct sony_pic_ioport *ioport = list_first_entry(&dev->ioports, struct sony_pic_ioport, list); if (!io) { if (!io) { dprintk("Blank IO resource\n"); dprintk("Blank IO resource\n"); return AE_OK; return AE_OK; } } ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); if (!ioport->io1.minimum) { if (!ioport) memcpy(&ioport->io1, io, sizeof(*io)); dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum, ioport->io1.address_length); } else if (!ioport->io2.minimum) { memcpy(&ioport->io2, io, sizeof(*io)); dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum, ioport->io2.address_length); } else { printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); return AE_ERROR; return AE_ERROR; } list_add_tail(&ioport->list, &dev->ioports); memcpy(&ioport->io, io, sizeof(*io)); return AE_OK; return AE_OK; } } default: default: Loading Loading @@ -2199,10 +2220,22 @@ static int sony_pic_enable(struct acpi_device *device, { { acpi_status status; acpi_status status; int result = 0; int result = 0; /* Type 1 resource layout is: * IO * IO * IRQNoFlags * End * * Type 2 and 3 resource layout is: * IO * IRQNoFlags * End */ struct { struct { struct acpi_resource io_res; struct acpi_resource res1; struct acpi_resource irq_res; struct acpi_resource res2; struct acpi_resource end; struct acpi_resource res3; struct acpi_resource res4; } *resource; } *resource; struct acpi_buffer buffer = { 0, NULL }; struct acpi_buffer buffer = { 0, NULL }; Loading @@ -2217,21 +2250,49 @@ static int sony_pic_enable(struct acpi_device *device, buffer.length = sizeof(*resource) + 1; buffer.length = sizeof(*resource) + 1; buffer.pointer = resource; buffer.pointer = resource; /* setup Type 1 resources */ if (spic_dev.model == SONYPI_DEVICE_TYPE1) { /* setup io resources */ resource->res1.type = ACPI_RESOURCE_TYPE_IO; resource->res1.length = sizeof(struct acpi_resource); memcpy(&resource->res1.data.io, &ioport->io1, sizeof(struct acpi_resource_io)); resource->res2.type = ACPI_RESOURCE_TYPE_IO; resource->res2.length = sizeof(struct acpi_resource); memcpy(&resource->res2.data.io, &ioport->io2, sizeof(struct acpi_resource_io)); /* setup irq resource */ resource->res3.type = ACPI_RESOURCE_TYPE_IRQ; resource->res3.length = sizeof(struct acpi_resource); memcpy(&resource->res3.data.irq, &irq->irq, sizeof(struct acpi_resource_irq)); /* we requested a shared irq */ resource->res3.data.irq.sharable = ACPI_SHARED; resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG; } /* setup Type 2/3 resources */ else { /* setup io resource */ /* setup io resource */ resource->io_res.type = ACPI_RESOURCE_TYPE_IO; resource->res1.type = ACPI_RESOURCE_TYPE_IO; resource->io_res.length = sizeof(struct acpi_resource); resource->res1.length = sizeof(struct acpi_resource); memcpy(&resource->io_res.data.io, &ioport->io, memcpy(&resource->res1.data.io, &ioport->io1, sizeof(struct acpi_resource_io)); sizeof(struct acpi_resource_io)); /* setup irq resource */ /* setup irq resource */ resource->irq_res.type = ACPI_RESOURCE_TYPE_IRQ; resource->res2.type = ACPI_RESOURCE_TYPE_IRQ; resource->irq_res.length = sizeof(struct acpi_resource); resource->res2.length = sizeof(struct acpi_resource); memcpy(&resource->irq_res.data.irq, &irq->irq, memcpy(&resource->res2.data.irq, &irq->irq, sizeof(struct acpi_resource_irq)); sizeof(struct acpi_resource_irq)); /* we requested a shared irq */ /* we requested a shared irq */ resource->irq_res.data.irq.sharable = ACPI_SHARED; resource->res2.data.irq.sharable = ACPI_SHARED; resource->end.type = ACPI_RESOURCE_TYPE_END_TAG; resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG; } /* Attempt to set the resource */ /* Attempt to set the resource */ dprintk("Evaluating _SRS\n"); dprintk("Evaluating _SRS\n"); Loading @@ -2239,7 +2300,7 @@ static int sony_pic_enable(struct acpi_device *device, /* check for total failure */ /* check for total failure */ if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) { printk(KERN_ERR DRV_PFX "Error evaluating _SRS"); printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n"); result = -ENODEV; result = -ENODEV; goto end; goto end; } } Loading Loading @@ -2268,11 +2329,14 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; ev = inb_p(dev->cur_ioport->io.minimum); ev = inb_p(dev->cur_ioport->io1.minimum); data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset); if (dev->cur_ioport->io2.minimum) data_mask = inb_p(dev->cur_ioport->io2.minimum); else data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset); dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset); ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset); if (ev == 0x00 || ev == 0xff) if (ev == 0x00 || ev == 0xff) return IRQ_HANDLED; return IRQ_HANDLED; Loading Loading @@ -2323,8 +2387,11 @@ static int sony_pic_remove(struct acpi_device *device, int type) } } free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); release_region(spic_dev.cur_ioport->io.minimum, release_region(spic_dev.cur_ioport->io1.minimum, spic_dev.cur_ioport->io.address_length); spic_dev.cur_ioport->io1.address_length); if (spic_dev.cur_ioport->io2.minimum) release_region(spic_dev.cur_ioport->io2.minimum, spic_dev.cur_ioport->io2.address_length); sonypi_compat_exit(); sonypi_compat_exit(); Loading Loading @@ -2397,16 +2464,38 @@ static int sony_pic_add(struct acpi_device *device) goto err_remove_input; goto err_remove_input; /* request io port */ /* request io port */ list_for_each_entry(io, &spic_dev.ioports, list) { list_for_each_entry_reverse(io, &spic_dev.ioports, list) { if (request_region(io->io.minimum, io->io.address_length, if (request_region(io->io1.minimum, io->io1.address_length, "Sony Programable I/O Device")) { dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n", io->io1.minimum, io->io1.maximum, io->io1.address_length); /* Type 1 have 2 ioports */ if (io->io2.minimum) { if (request_region(io->io2.minimum, io->io2.address_length, "Sony Programable I/O Device")) { "Sony Programable I/O Device")) { dprintk("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n", dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n", io->io.minimum, io->io.maximum, io->io2.minimum, io->io2.maximum, io->io.address_length); io->io2.address_length); spic_dev.cur_ioport = io; break; } else { dprintk("Unable to get I/O port2: " "0x%.4x (0x%.4x) + 0x%.2x\n", io->io2.minimum, io->io2.maximum, io->io2.address_length); release_region(io->io1.minimum, io->io1.address_length); } } else { spic_dev.cur_ioport = io; spic_dev.cur_ioport = io; break; break; } } } } } if (!spic_dev.cur_ioport) { if (!spic_dev.cur_ioport) { printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); result = -ENODEV; result = -ENODEV; Loading @@ -2414,7 +2503,7 @@ static int sony_pic_add(struct acpi_device *device) } } /* request IRQ */ /* request IRQ */ list_for_each_entry(irq, &spic_dev.interrupts, list) { list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, IRQF_SHARED, "sony-laptop", &spic_dev)) { IRQF_SHARED, "sony-laptop", &spic_dev)) { dprintk("IRQ: %d - triggering: %d - " dprintk("IRQ: %d - triggering: %d - " Loading Loading @@ -2462,8 +2551,11 @@ static int sony_pic_add(struct acpi_device *device) free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); err_release_region: err_release_region: release_region(spic_dev.cur_ioport->io.minimum, release_region(spic_dev.cur_ioport->io1.minimum, spic_dev.cur_ioport->io.address_length); spic_dev.cur_ioport->io1.address_length); if (spic_dev.cur_ioport->io2.minimum) release_region(spic_dev.cur_ioport->io2.minimum, spic_dev.cur_ioport->io2.address_length); err_remove_compat: err_remove_compat: sonypi_compat_exit(); sonypi_compat_exit(); Loading Loading
drivers/misc/sony-laptop.c +148 −56 Original line number Original line Diff line number Diff line Loading @@ -1173,7 +1173,8 @@ static struct acpi_driver sony_nc_driver = { #define SONYPI_TYPE3_OFFSET 0x12 #define SONYPI_TYPE3_OFFSET 0x12 struct sony_pic_ioport { struct sony_pic_ioport { struct acpi_resource_io io; struct acpi_resource_io io1; struct acpi_resource_io io2; struct list_head list; struct list_head list; }; }; Loading Loading @@ -1443,11 +1444,11 @@ static u8 sony_pic_call1(u8 dev) { { u8 v1, v2; u8 v1, v2; wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); ITERATIONS_LONG); outb(dev, spic_dev.cur_ioport->io.minimum + 4); outb(dev, spic_dev.cur_ioport->io1.minimum + 4); v1 = inb_p(spic_dev.cur_ioport->io.minimum + 4); v1 = inb_p(spic_dev.cur_ioport->io1.minimum + 4); v2 = inb_p(spic_dev.cur_ioport->io.minimum); v2 = inb_p(spic_dev.cur_ioport->io1.minimum); dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1); dprintk("sony_pic_call1: 0x%.4x\n", (v2 << 8) | v1); return v2; return v2; } } Loading @@ -1456,13 +1457,13 @@ static u8 sony_pic_call2(u8 dev, u8 fn) { { u8 v1; u8 v1; wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); ITERATIONS_LONG); outb(dev, spic_dev.cur_ioport->io.minimum + 4); outb(dev, spic_dev.cur_ioport->io1.minimum + 4); wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); ITERATIONS_LONG); outb(fn, spic_dev.cur_ioport->io.minimum); outb(fn, spic_dev.cur_ioport->io1.minimum); v1 = inb_p(spic_dev.cur_ioport->io.minimum); v1 = inb_p(spic_dev.cur_ioport->io1.minimum); dprintk("sony_pic_call2: 0x%.4x\n", v1); dprintk("sony_pic_call2: 0x%.4x\n", v1); return v1; return v1; } } Loading @@ -1471,13 +1472,13 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v) { { u8 v1; u8 v1; wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); outb(dev, spic_dev.cur_ioport->io.minimum + 4); outb(dev, spic_dev.cur_ioport->io1.minimum + 4); wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); outb(fn, spic_dev.cur_ioport->io.minimum); outb(fn, spic_dev.cur_ioport->io1.minimum); wait_on_command(inb_p(spic_dev.cur_ioport->io.minimum + 4) & 2, ITERATIONS_LONG); wait_on_command(inb_p(spic_dev.cur_ioport->io1.minimum + 4) & 2, ITERATIONS_LONG); outb(v, spic_dev.cur_ioport->io.minimum); outb(v, spic_dev.cur_ioport->io1.minimum); v1 = inb_p(spic_dev.cur_ioport->io.minimum); v1 = inb_p(spic_dev.cur_ioport->io1.minimum); dprintk("sony_pic_call3: 0x%.4x\n", v1); dprintk("sony_pic_call3: 0x%.4x\n", v1); return v1; return v1; } } Loading Loading @@ -2074,7 +2075,18 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) switch (resource->type) { switch (resource->type) { case ACPI_RESOURCE_TYPE_START_DEPENDENT: case ACPI_RESOURCE_TYPE_START_DEPENDENT: { /* start IO enumeration */ struct sony_pic_ioport *ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); if (!ioport) return AE_ERROR; list_add(&ioport->list, &dev->ioports); return AE_OK; } case ACPI_RESOURCE_TYPE_END_DEPENDENT: case ACPI_RESOURCE_TYPE_END_DEPENDENT: /* end IO enumeration */ return AE_OK; return AE_OK; case ACPI_RESOURCE_TYPE_IRQ: case ACPI_RESOURCE_TYPE_IRQ: Loading @@ -2101,7 +2113,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) if (!interrupt) if (!interrupt) return AE_ERROR; return AE_ERROR; list_add_tail(&interrupt->list, &dev->interrupts); list_add(&interrupt->list, &dev->interrupts); interrupt->irq.triggering = p->triggering; interrupt->irq.triggering = p->triggering; interrupt->irq.polarity = p->polarity; interrupt->irq.polarity = p->polarity; interrupt->irq.sharable = p->sharable; interrupt->irq.sharable = p->sharable; Loading @@ -2113,18 +2125,27 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context) case ACPI_RESOURCE_TYPE_IO: case ACPI_RESOURCE_TYPE_IO: { { struct acpi_resource_io *io = &resource->data.io; struct acpi_resource_io *io = &resource->data.io; struct sony_pic_ioport *ioport = NULL; struct sony_pic_ioport *ioport = list_first_entry(&dev->ioports, struct sony_pic_ioport, list); if (!io) { if (!io) { dprintk("Blank IO resource\n"); dprintk("Blank IO resource\n"); return AE_OK; return AE_OK; } } ioport = kzalloc(sizeof(*ioport), GFP_KERNEL); if (!ioport->io1.minimum) { if (!ioport) memcpy(&ioport->io1, io, sizeof(*io)); dprintk("IO1 at 0x%.4x (0x%.2x)\n", ioport->io1.minimum, ioport->io1.address_length); } else if (!ioport->io2.minimum) { memcpy(&ioport->io2, io, sizeof(*io)); dprintk("IO2 at 0x%.4x (0x%.2x)\n", ioport->io2.minimum, ioport->io2.address_length); } else { printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n"); return AE_ERROR; return AE_ERROR; } list_add_tail(&ioport->list, &dev->ioports); memcpy(&ioport->io, io, sizeof(*io)); return AE_OK; return AE_OK; } } default: default: Loading Loading @@ -2199,10 +2220,22 @@ static int sony_pic_enable(struct acpi_device *device, { { acpi_status status; acpi_status status; int result = 0; int result = 0; /* Type 1 resource layout is: * IO * IO * IRQNoFlags * End * * Type 2 and 3 resource layout is: * IO * IRQNoFlags * End */ struct { struct { struct acpi_resource io_res; struct acpi_resource res1; struct acpi_resource irq_res; struct acpi_resource res2; struct acpi_resource end; struct acpi_resource res3; struct acpi_resource res4; } *resource; } *resource; struct acpi_buffer buffer = { 0, NULL }; struct acpi_buffer buffer = { 0, NULL }; Loading @@ -2217,21 +2250,49 @@ static int sony_pic_enable(struct acpi_device *device, buffer.length = sizeof(*resource) + 1; buffer.length = sizeof(*resource) + 1; buffer.pointer = resource; buffer.pointer = resource; /* setup Type 1 resources */ if (spic_dev.model == SONYPI_DEVICE_TYPE1) { /* setup io resources */ resource->res1.type = ACPI_RESOURCE_TYPE_IO; resource->res1.length = sizeof(struct acpi_resource); memcpy(&resource->res1.data.io, &ioport->io1, sizeof(struct acpi_resource_io)); resource->res2.type = ACPI_RESOURCE_TYPE_IO; resource->res2.length = sizeof(struct acpi_resource); memcpy(&resource->res2.data.io, &ioport->io2, sizeof(struct acpi_resource_io)); /* setup irq resource */ resource->res3.type = ACPI_RESOURCE_TYPE_IRQ; resource->res3.length = sizeof(struct acpi_resource); memcpy(&resource->res3.data.irq, &irq->irq, sizeof(struct acpi_resource_irq)); /* we requested a shared irq */ resource->res3.data.irq.sharable = ACPI_SHARED; resource->res4.type = ACPI_RESOURCE_TYPE_END_TAG; } /* setup Type 2/3 resources */ else { /* setup io resource */ /* setup io resource */ resource->io_res.type = ACPI_RESOURCE_TYPE_IO; resource->res1.type = ACPI_RESOURCE_TYPE_IO; resource->io_res.length = sizeof(struct acpi_resource); resource->res1.length = sizeof(struct acpi_resource); memcpy(&resource->io_res.data.io, &ioport->io, memcpy(&resource->res1.data.io, &ioport->io1, sizeof(struct acpi_resource_io)); sizeof(struct acpi_resource_io)); /* setup irq resource */ /* setup irq resource */ resource->irq_res.type = ACPI_RESOURCE_TYPE_IRQ; resource->res2.type = ACPI_RESOURCE_TYPE_IRQ; resource->irq_res.length = sizeof(struct acpi_resource); resource->res2.length = sizeof(struct acpi_resource); memcpy(&resource->irq_res.data.irq, &irq->irq, memcpy(&resource->res2.data.irq, &irq->irq, sizeof(struct acpi_resource_irq)); sizeof(struct acpi_resource_irq)); /* we requested a shared irq */ /* we requested a shared irq */ resource->irq_res.data.irq.sharable = ACPI_SHARED; resource->res2.data.irq.sharable = ACPI_SHARED; resource->end.type = ACPI_RESOURCE_TYPE_END_TAG; resource->res3.type = ACPI_RESOURCE_TYPE_END_TAG; } /* Attempt to set the resource */ /* Attempt to set the resource */ dprintk("Evaluating _SRS\n"); dprintk("Evaluating _SRS\n"); Loading @@ -2239,7 +2300,7 @@ static int sony_pic_enable(struct acpi_device *device, /* check for total failure */ /* check for total failure */ if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) { printk(KERN_ERR DRV_PFX "Error evaluating _SRS"); printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n"); result = -ENODEV; result = -ENODEV; goto end; goto end; } } Loading Loading @@ -2268,11 +2329,14 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; ev = inb_p(dev->cur_ioport->io.minimum); ev = inb_p(dev->cur_ioport->io1.minimum); data_mask = inb_p(dev->cur_ioport->io.minimum + dev->evport_offset); if (dev->cur_ioport->io2.minimum) data_mask = inb_p(dev->cur_ioport->io2.minimum); else data_mask = inb_p(dev->cur_ioport->io1.minimum + dev->evport_offset); dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", dprintk("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n", ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset); ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset); if (ev == 0x00 || ev == 0xff) if (ev == 0x00 || ev == 0xff) return IRQ_HANDLED; return IRQ_HANDLED; Loading Loading @@ -2323,8 +2387,11 @@ static int sony_pic_remove(struct acpi_device *device, int type) } } free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); release_region(spic_dev.cur_ioport->io.minimum, release_region(spic_dev.cur_ioport->io1.minimum, spic_dev.cur_ioport->io.address_length); spic_dev.cur_ioport->io1.address_length); if (spic_dev.cur_ioport->io2.minimum) release_region(spic_dev.cur_ioport->io2.minimum, spic_dev.cur_ioport->io2.address_length); sonypi_compat_exit(); sonypi_compat_exit(); Loading Loading @@ -2397,16 +2464,38 @@ static int sony_pic_add(struct acpi_device *device) goto err_remove_input; goto err_remove_input; /* request io port */ /* request io port */ list_for_each_entry(io, &spic_dev.ioports, list) { list_for_each_entry_reverse(io, &spic_dev.ioports, list) { if (request_region(io->io.minimum, io->io.address_length, if (request_region(io->io1.minimum, io->io1.address_length, "Sony Programable I/O Device")) { dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n", io->io1.minimum, io->io1.maximum, io->io1.address_length); /* Type 1 have 2 ioports */ if (io->io2.minimum) { if (request_region(io->io2.minimum, io->io2.address_length, "Sony Programable I/O Device")) { "Sony Programable I/O Device")) { dprintk("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n", dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n", io->io.minimum, io->io.maximum, io->io2.minimum, io->io2.maximum, io->io.address_length); io->io2.address_length); spic_dev.cur_ioport = io; break; } else { dprintk("Unable to get I/O port2: " "0x%.4x (0x%.4x) + 0x%.2x\n", io->io2.minimum, io->io2.maximum, io->io2.address_length); release_region(io->io1.minimum, io->io1.address_length); } } else { spic_dev.cur_ioport = io; spic_dev.cur_ioport = io; break; break; } } } } } if (!spic_dev.cur_ioport) { if (!spic_dev.cur_ioport) { printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); result = -ENODEV; result = -ENODEV; Loading @@ -2414,7 +2503,7 @@ static int sony_pic_add(struct acpi_device *device) } } /* request IRQ */ /* request IRQ */ list_for_each_entry(irq, &spic_dev.interrupts, list) { list_for_each_entry_reverse(irq, &spic_dev.interrupts, list) { if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, if (!request_irq(irq->irq.interrupts[0], sony_pic_irq, IRQF_SHARED, "sony-laptop", &spic_dev)) { IRQF_SHARED, "sony-laptop", &spic_dev)) { dprintk("IRQ: %d - triggering: %d - " dprintk("IRQ: %d - triggering: %d - " Loading Loading @@ -2462,8 +2551,11 @@ static int sony_pic_add(struct acpi_device *device) free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); free_irq(spic_dev.cur_irq->irq.interrupts[0], &spic_dev); err_release_region: err_release_region: release_region(spic_dev.cur_ioport->io.minimum, release_region(spic_dev.cur_ioport->io1.minimum, spic_dev.cur_ioport->io.address_length); spic_dev.cur_ioport->io1.address_length); if (spic_dev.cur_ioport->io2.minimum) release_region(spic_dev.cur_ioport->io2.minimum, spic_dev.cur_ioport->io2.address_length); err_remove_compat: err_remove_compat: sonypi_compat_exit(); sonypi_compat_exit(); Loading