Merge tag 'pm+acpi-for-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael Wysocki: - Introduction of device PM QoS flags. - ACPI device power management update allowing subsystems other than PCI to use it more easily. - ACPI device enumeration rework allowing additional kinds of devices to be enumerated via ACPI. From Mika Westerberg, Adrian Hunter, Mathias Nyman, Andy Shevchenko, and Rafael J. Wysocki. - ACPICA update to version 20121018 from Bob Moore and Lv Zheng. - ACPI memory hotplug update from Wen Congyang and Yasuaki Ishimatsu. - Introduction of acpi_handle_<level>() messaging macros and ACPI-based CPU hot-remove support from Toshi Kani. - ACPI EC updates from Feng Tang. - cpufreq updates from Viresh Kumar, Fabio Baltieri and others. - cpuidle changes to quickly notice governor prediction failure from Youquan Song. - Support for using multiple cpuidle drivers at the same time and cpuidle cleanups from Daniel Lezcano. - devfreq updates from Nishanth Menon and others. - cpupower update from Thomas Renninger. - Fixes and small cleanups all over the place. * tag 'pm+acpi-for-3.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (196 commits) mmc: sdhci-acpi: enable runtime-pm for device HID INT33C6 ACPI: add Haswell LPSS devices to acpi_platform_device_ids list ACPI: add documentation about ACPI 5 enumeration pnpacpi: fix incorrect TEST_ALPHA() test ACPI / PM: Fix header of acpi_dev_pm_detach() in acpi.h ACPI / video: ignore BIOS initial backlight value for HP Folio 13-2000 ACPI : do not use Lid and Sleep button for S5 wakeup ACPI / PNP: Do not crash due to stale pointer use during system resume ACPI / video: Add "Asus UL30VT" to ACPI video detect blacklist ACPI: do acpisleep dmi check when CONFIG_ACPI_SLEEP is set spi / ACPI: add ACPI enumeration support gpio / ACPI: add ACPI support PM / devfreq: remove compiler error with module governors (2) cpupower: IvyBridge (0x3a and 0x3e models) support cpupower: Provide -c param for cpupower monitor to schedule process on all cores cpupower tools: Fix warning and a bug with the cpu package count cpupower tools: Fix malloc of cpu_info structure cpupower tools: Fix issues with sysfs_topology_read_file cpupower tools: Fix minor warnings cpupower tools: Update .gitignore for files created in the debug directories ...
This commit is contained in:
@@ -35,6 +35,8 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/acpi.h>
|
||||
|
||||
static void spidev_release(struct device *dev)
|
||||
{
|
||||
@@ -93,6 +95,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
|
||||
if (of_driver_match_device(dev, drv))
|
||||
return 1;
|
||||
|
||||
/* Then try ACPI */
|
||||
if (acpi_driver_match_device(dev, drv))
|
||||
return 1;
|
||||
|
||||
if (sdrv->id_table)
|
||||
return !!spi_match_id(sdrv->id_table, spi);
|
||||
|
||||
@@ -888,6 +894,100 @@ static void of_register_spi_devices(struct spi_master *master)
|
||||
static void of_register_spi_devices(struct spi_master *master) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ACPI
|
||||
static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
|
||||
{
|
||||
struct spi_device *spi = data;
|
||||
|
||||
if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
|
||||
struct acpi_resource_spi_serialbus *sb;
|
||||
|
||||
sb = &ares->data.spi_serial_bus;
|
||||
if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
|
||||
spi->chip_select = sb->device_selection;
|
||||
spi->max_speed_hz = sb->connection_speed;
|
||||
|
||||
if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
|
||||
spi->mode |= SPI_CPHA;
|
||||
if (sb->clock_polarity == ACPI_SPI_START_HIGH)
|
||||
spi->mode |= SPI_CPOL;
|
||||
if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
|
||||
spi->mode |= SPI_CS_HIGH;
|
||||
}
|
||||
} else if (spi->irq < 0) {
|
||||
struct resource r;
|
||||
|
||||
if (acpi_dev_resource_interrupt(ares, 0, &r))
|
||||
spi->irq = r.start;
|
||||
}
|
||||
|
||||
/* Always tell the ACPI core to skip this resource */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
|
||||
void *data, void **return_value)
|
||||
{
|
||||
struct spi_master *master = data;
|
||||
struct list_head resource_list;
|
||||
struct acpi_device *adev;
|
||||
struct spi_device *spi;
|
||||
int ret;
|
||||
|
||||
if (acpi_bus_get_device(handle, &adev))
|
||||
return AE_OK;
|
||||
if (acpi_bus_get_status(adev) || !adev->status.present)
|
||||
return AE_OK;
|
||||
|
||||
spi = spi_alloc_device(master);
|
||||
if (!spi) {
|
||||
dev_err(&master->dev, "failed to allocate SPI device for %s\n",
|
||||
dev_name(&adev->dev));
|
||||
return AE_NO_MEMORY;
|
||||
}
|
||||
|
||||
ACPI_HANDLE_SET(&spi->dev, handle);
|
||||
spi->irq = -1;
|
||||
|
||||
INIT_LIST_HEAD(&resource_list);
|
||||
ret = acpi_dev_get_resources(adev, &resource_list,
|
||||
acpi_spi_add_resource, spi);
|
||||
acpi_dev_free_resource_list(&resource_list);
|
||||
|
||||
if (ret < 0 || !spi->max_speed_hz) {
|
||||
spi_dev_put(spi);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias));
|
||||
if (spi_add_device(spi)) {
|
||||
dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",
|
||||
dev_name(&adev->dev));
|
||||
spi_dev_put(spi);
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static void acpi_register_spi_devices(struct spi_master *master)
|
||||
{
|
||||
acpi_status status;
|
||||
acpi_handle handle;
|
||||
|
||||
handle = ACPI_HANDLE(&master->dev);
|
||||
if (!handle)
|
||||
return;
|
||||
|
||||
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
|
||||
acpi_spi_add_device, NULL,
|
||||
master, NULL);
|
||||
if (ACPI_FAILURE(status))
|
||||
dev_warn(&master->dev, "failed to enumerate SPI slaves\n");
|
||||
}
|
||||
#else
|
||||
static inline void acpi_register_spi_devices(struct spi_master *master) {}
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
static void spi_master_release(struct device *dev)
|
||||
{
|
||||
struct spi_master *master;
|
||||
@@ -1023,8 +1123,9 @@ int spi_register_master(struct spi_master *master)
|
||||
spi_match_master_to_boardinfo(master, &bi->board_info);
|
||||
mutex_unlock(&board_lock);
|
||||
|
||||
/* Register devices from the device tree */
|
||||
/* Register devices from the device tree and ACPI */
|
||||
of_register_spi_devices(master);
|
||||
acpi_register_spi_devices(master);
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
|
Reference in New Issue
Block a user