int acpi_pci_bind_root ( struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus) { int result = 0; acpi_status status = AE_OK; struct acpi_pci_data *data = NULL; char *pathname = NULL; struct acpi_buffer buffer = {0, NULL}; ACPI_FUNCTION_TRACE("acpi_pci_bind_root"); pathname = (char *)kmalloc(ACPI_PATHNAME_MAX, GFP_KERNEL); if(!pathname) return_VALUE(-ENOMEM); memset(pathname, 0, ACPI_PATHNAME_MAX); buffer.length = ACPI_PATHNAME_MAX; buffer.pointer = pathname; if (!device || !id || !bus) { kfree(pathname); return_VALUE(-EINVAL); } data = kmalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); if (!data) { kfree(pathname); return_VALUE(-ENOMEM); } memset(data, 0, sizeof(struct acpi_pci_data)); data->id = *id; data->bus = bus; device->ops.bind = acpi_pci_bind; device->ops.unbind = acpi_pci_unbind; acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to " "%02x:%02x\n", pathname, id->segment, id->bus)); status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unable to attach ACPI-PCI context to device %s\n", pathname)); result = -ENODEV; goto end; } end: kfree(pathname); if (result != 0) kfree(data); return_VALUE(result); }
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) { int trips = 0; int result; acpi_status status; int i; if (tz->trips.critical.flags.valid) trips++; if (tz->trips.hot.flags.valid) trips++; if (tz->trips.passive.flags.valid) trips++; for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].flags.valid; i++, trips++); if (tz->trips.passive.flags.valid) tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz, &acpi_thermal_zone_ops, NULL, tz->trips.passive.tsp*100, tz->polling_frequency*100); else tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz, &acpi_thermal_zone_ops, NULL, 0, tz->polling_frequency*100); if (IS_ERR(tz->thermal_zone)) return -ENODEV; result = sysfs_create_link(&tz->device->dev.kobj, &tz->thermal_zone->device.kobj, "thermal_zone"); if (result) return result; result = sysfs_create_link(&tz->thermal_zone->device.kobj, &tz->device->dev.kobj, "device"); if (result) return result; status = acpi_attach_data(tz->device->handle, acpi_bus_private_data_handler, tz->thermal_zone); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "Error attaching device data\n"); return -ENODEV; } tz->tz_enabled = 1; dev_info(&tz->device->dev, "registered as thermal_zone%d\n", tz->thermal_zone->id); return 0; }
int acpi_bus_attach_private_data(acpi_handle handle, void *data) { acpi_status status; status = acpi_attach_data(handle, acpi_bus_private_data_handler, data); if (ACPI_FAILURE(status)) { acpi_handle_debug(handle, "Error attaching device data\n"); return -ENODEV; } return 0; }
int acpi_pci_bind_root(struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus) { int result = 0; acpi_status status; struct acpi_pci_data *data = NULL; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; if (!device || !id || !bus) { return -EINVAL; } data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); if (!data) return -ENOMEM; data->id = *id; data->bus = bus; device->ops.bind = acpi_pci_bind; device->ops.unbind = acpi_pci_unbind; status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); if (ACPI_FAILURE(status)) { kfree (data); return -ENODEV; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI root bridge [%s] to " "%04x:%02x\n", (char *)buffer.pointer, id->segment, id->bus)); status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to attach ACPI-PCI context to device %s", (char *)buffer.pointer)); result = -ENODEV; goto end; } end: kfree(buffer.pointer); if (result != 0) kfree(data); return result; }
int acpi_pci_bind(struct acpi_device *device) { int result = 0; acpi_status status; struct acpi_pci_data *data; struct acpi_pci_data *pdata; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_handle handle; if (!device || !device->parent) return -EINVAL; data = kzalloc(sizeof(struct acpi_pci_data), GFP_KERNEL); if (!data) return -ENOMEM; status = acpi_get_name(device->handle, ACPI_FULL_PATHNAME, &buffer); if (ACPI_FAILURE(status)) { kfree(data); return -ENODEV; } ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Binding PCI device [%s]...\n", (char *)buffer.pointer)); /* * Segment & Bus * ------------- * These are obtained via the parent device's ACPI-PCI context. */ status = acpi_get_data(device->parent->handle, acpi_pci_data_handler, (void **)&pdata); if (ACPI_FAILURE(status) || !pdata || !pdata->bus) { ACPI_EXCEPTION((AE_INFO, status, "Invalid ACPI-PCI context for parent device %s", acpi_device_bid(device->parent))); result = -ENODEV; goto end; } data->id.segment = pdata->id.segment; data->id.bus = pdata->bus->number; /* * Device & Function * ----------------- * These are simply obtained from the device's _ADR method. Note * that a value of zero is valid. */ data->id.device = device->pnp.bus_address >> 16; data->id.function = device->pnp.bus_address & 0xFFFF; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "...to %04x:%02x:%02x.%d\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); /* * TBD: Support slot devices (e.g. function=0xFFFF). */ /* * Locate PCI Device * ----------------- * Locate matching device in PCI namespace. If it doesn't exist * this typically means that the device isn't currently inserted * (e.g. docking station, port replicator, etc.). */ data->dev = pci_get_slot(pdata->bus, PCI_DEVFN(data->id.device, data->id.function)); if (!data->dev) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %04x:%02x:%02x.%d not present in PCI namespace\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); result = -ENODEV; goto end; } if (!data->dev->bus) { printk(KERN_ERR PREFIX "Device %04x:%02x:%02x.%d has invalid 'bus' field\n", data->id.segment, data->id.bus, data->id.device, data->id.function); result = -ENODEV; goto end; } /* * PCI Bridge? * ----------- * If so, set the 'bus' field and install the 'bind' function to * facilitate callbacks for all of its children. */ if (data->dev->subordinate) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %04x:%02x:%02x.%d is a PCI bridge\n", data->id.segment, data->id.bus, data->id.device, data->id.function)); data->bus = data->dev->subordinate; device->ops.bind = acpi_pci_bind; device->ops.unbind = acpi_pci_unbind; } /* * Attach ACPI-PCI Context * ----------------------- * Thus binding the ACPI and PCI devices. */ status = acpi_attach_data(device->handle, acpi_pci_data_handler, data); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to attach ACPI-PCI context to device %s", acpi_device_bid(device))); result = -ENODEV; goto end; } /* * PCI Routing Table * ----------------- * Evaluate and parse _PRT, if exists. This code is independent of * PCI bridges (above) to allow parsing of _PRT objects within the * scope of non-bridge devices. Note that _PRTs within the scope of * a PCI bridge assume the bridge's subordinate bus number. * * TBD: Can _PRTs exist within the scope of non-bridge PCI devices? */ status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle); if (ACPI_SUCCESS(status)) { if (data->bus) /* PCI-PCI bridge */ acpi_pci_irq_add_prt(device->handle, data->id.segment, data->bus->number); else /* non-bridge PCI device */ acpi_pci_irq_add_prt(device->handle, data->id.segment, data->id.bus); } end: kfree(buffer.pointer); if (result) { pci_dev_put(data->dev); kfree(data); } return result; }
/** * acpi_gpiochip_request_interrupts() - Register isr for gpio chip ACPI events * @chip: gpio chip * * ACPI5 platforms can use GPIO signaled ACPI events. These GPIO interrupts are * handled by ACPI event methods which need to be called from the GPIO * chip's interrupt handler. acpi_gpiochip_request_interrupts finds out which * gpio pins have acpi event methods and assigns interrupt handlers that calls * the acpi event methods for those pins. */ void acpi_gpiochip_request_interrupts(struct gpio_chip *chip) { struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; struct acpi_resource *res; acpi_handle handle, evt_handle; struct list_head *evt_pins = NULL; acpi_status status; unsigned int pin; int irq, ret; char ev_name[5]; if (!chip->dev || !chip->to_irq) return; handle = ACPI_HANDLE(chip->dev); if (!handle) return; status = acpi_get_event_resources(handle, &buf); if (ACPI_FAILURE(status)) return; status = acpi_get_handle(handle, "_EVT", &evt_handle); if (ACPI_SUCCESS(status)) { evt_pins = kzalloc(sizeof(*evt_pins), GFP_KERNEL); if (evt_pins) { INIT_LIST_HEAD(evt_pins); status = acpi_attach_data(handle, acpi_gpio_evt_dh, evt_pins); if (ACPI_FAILURE(status)) { kfree(evt_pins); evt_pins = NULL; } } } /* * If a GPIO interrupt has an ACPI event handler method, or _EVT is * present, set up an interrupt handler that calls the ACPI event * handler. */ for (res = buf.pointer; res && (res->type != ACPI_RESOURCE_TYPE_END_TAG); res = ACPI_NEXT_RESOURCE(res)) { irq_handler_t handler = NULL; void *data; if (res->type != ACPI_RESOURCE_TYPE_GPIO || res->data.gpio.connection_type != ACPI_RESOURCE_GPIO_TYPE_INT) continue; pin = res->data.gpio.pin_table[0]; if (pin > chip->ngpio) continue; irq = chip->to_irq(chip, pin); if (irq < 0) continue; if (pin <= 255) { acpi_handle ev_handle; sprintf(ev_name, "_%c%02X", res->data.gpio.triggering ? 'E' : 'L', pin); status = acpi_get_handle(handle, ev_name, &ev_handle); if (ACPI_SUCCESS(status)) { handler = acpi_gpio_irq_handler; data = ev_handle; } } if (!handler && evt_pins) { struct acpi_gpio_evt_pin *evt_pin; evt_pin = kzalloc(sizeof(*evt_pin), GFP_KERNEL); if (!evt_pin) continue; list_add_tail(&evt_pin->node, evt_pins); evt_pin->evt_handle = evt_handle; evt_pin->pin = pin; evt_pin->irq = irq; handler = acpi_gpio_irq_handler_evt; data = evt_pin; } if (!handler) continue; /* Assume BIOS sets the triggering, so no flags */ ret = devm_request_threaded_irq(chip->dev, irq, NULL, handler, 0, "GPIO-signaled-ACPI-event", data); if (ret) dev_err(chip->dev, "Failed to request IRQ %d ACPI event handler\n", irq); } }