summaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 15:45:35 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-11 15:45:35 -0500
commitbad73c5aa069f1f14cc07ce7bbae8d463635560c (patch)
treedb905bb3400e6fe70be95cd20158bed79b2b2c6c /drivers/spi/spi.c
parentb58ed041a360ed051fab17e4d9b0f451c6fedba7 (diff)
parentf316fc56555a5c3bcf6350f3d5ac26dd2c55f4cb (diff)
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 ...
Diffstat (limited to 'drivers/spi/spi.c')
-rw-r--r--drivers/spi/spi.c103
1 files changed, 102 insertions, 1 deletions
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index d3e64080c409..718cc1f49230 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -35,6 +35,8 @@
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/delay.h> 36#include <linux/delay.h>
37#include <linux/kthread.h> 37#include <linux/kthread.h>
38#include <linux/ioport.h>
39#include <linux/acpi.h>
38 40
39static void spidev_release(struct device *dev) 41static void spidev_release(struct device *dev)
40{ 42{
@@ -93,6 +95,10 @@ static int spi_match_device(struct device *dev, struct device_driver *drv)
93 if (of_driver_match_device(dev, drv)) 95 if (of_driver_match_device(dev, drv))
94 return 1; 96 return 1;
95 97
98 /* Then try ACPI */
99 if (acpi_driver_match_device(dev, drv))
100 return 1;
101
96 if (sdrv->id_table) 102 if (sdrv->id_table)
97 return !!spi_match_id(sdrv->id_table, spi); 103 return !!spi_match_id(sdrv->id_table, spi);
98 104
@@ -888,6 +894,100 @@ static void of_register_spi_devices(struct spi_master *master)
888static void of_register_spi_devices(struct spi_master *master) { } 894static void of_register_spi_devices(struct spi_master *master) { }
889#endif 895#endif
890 896
897#ifdef CONFIG_ACPI
898static int acpi_spi_add_resource(struct acpi_resource *ares, void *data)
899{
900 struct spi_device *spi = data;
901
902 if (ares->type == ACPI_RESOURCE_TYPE_SERIAL_BUS) {
903 struct acpi_resource_spi_serialbus *sb;
904
905 sb = &ares->data.spi_serial_bus;
906 if (sb->type == ACPI_RESOURCE_SERIAL_TYPE_SPI) {
907 spi->chip_select = sb->device_selection;
908 spi->max_speed_hz = sb->connection_speed;
909
910 if (sb->clock_phase == ACPI_SPI_SECOND_PHASE)
911 spi->mode |= SPI_CPHA;
912 if (sb->clock_polarity == ACPI_SPI_START_HIGH)
913 spi->mode |= SPI_CPOL;
914 if (sb->device_polarity == ACPI_SPI_ACTIVE_HIGH)
915 spi->mode |= SPI_CS_HIGH;
916 }
917 } else if (spi->irq < 0) {
918 struct resource r;
919
920 if (acpi_dev_resource_interrupt(ares, 0, &r))
921 spi->irq = r.start;
922 }
923
924 /* Always tell the ACPI core to skip this resource */
925 return 1;
926}
927
928static acpi_status acpi_spi_add_device(acpi_handle handle, u32 level,
929 void *data, void **return_value)
930{
931 struct spi_master *master = data;
932 struct list_head resource_list;
933 struct acpi_device *adev;
934 struct spi_device *spi;
935 int ret;
936
937 if (acpi_bus_get_device(handle, &adev))
938 return AE_OK;
939 if (acpi_bus_get_status(adev) || !adev->status.present)
940 return AE_OK;
941
942 spi = spi_alloc_device(master);
943 if (!spi) {
944 dev_err(&master->dev, "failed to allocate SPI device for %s\n",
945 dev_name(&adev->dev));
946 return AE_NO_MEMORY;
947 }
948
949 ACPI_HANDLE_SET(&spi->dev, handle);
950 spi->irq = -1;
951
952 INIT_LIST_HEAD(&resource_list);
953 ret = acpi_dev_get_resources(adev, &resource_list,
954 acpi_spi_add_resource, spi);
955 acpi_dev_free_resource_list(&resource_list);
956
957 if (ret < 0 || !spi->max_speed_hz) {
958 spi_dev_put(spi);
959 return AE_OK;
960 }
961
962 strlcpy(spi->modalias, dev_name(&adev->dev), sizeof(spi->modalias));
963 if (spi_add_device(spi)) {
964 dev_err(&master->dev, "failed to add SPI device %s from ACPI\n",
965 dev_name(&adev->dev));
966 spi_dev_put(spi);
967 }
968
969 return AE_OK;
970}
971
972static void acpi_register_spi_devices(struct spi_master *master)
973{
974 acpi_status status;
975 acpi_handle handle;
976
977 handle = ACPI_HANDLE(&master->dev);
978 if (!handle)
979 return;
980
981 status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1,
982 acpi_spi_add_device, NULL,
983 master, NULL);
984 if (ACPI_FAILURE(status))
985 dev_warn(&master->dev, "failed to enumerate SPI slaves\n");
986}
987#else
988static inline void acpi_register_spi_devices(struct spi_master *master) {}
989#endif /* CONFIG_ACPI */
990
891static void spi_master_release(struct device *dev) 991static void spi_master_release(struct device *dev)
892{ 992{
893 struct spi_master *master; 993 struct spi_master *master;
@@ -1023,8 +1123,9 @@ int spi_register_master(struct spi_master *master)
1023 spi_match_master_to_boardinfo(master, &bi->board_info); 1123 spi_match_master_to_boardinfo(master, &bi->board_info);
1024 mutex_unlock(&board_lock); 1124 mutex_unlock(&board_lock);
1025 1125
1026 /* Register devices from the device tree */ 1126 /* Register devices from the device tree and ACPI */
1027 of_register_spi_devices(master); 1127 of_register_spi_devices(master);
1128 acpi_register_spi_devices(master);
1028done: 1129done:
1029 return status; 1130 return status;
1030} 1131}