diff options
author | Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> | 2013-10-17 18:35:32 -0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2013-10-17 19:40:50 -0400 |
commit | 49c72a0a8ad640fa6026962056eeaf85a4ce79fd (patch) | |
tree | 4c138230a1b6b4b357fb2f99b1e033272decb018 /arch/x86/platform | |
parent | 3fd79ae4275001f293dbd170479e89df6c433226 (diff) |
intel_mid: Added custom handler for ipc devices
Added a custom handler for medfield based ipc devices and
moved devs_id structure defintion to header file.
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Link: http://lkml.kernel.org/r/1382049336-21316-9-git-send-email-david.a.cohen@linux.intel.com
Signed-off-by: David Cohen <david.a.cohen@linux.intel.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/platform')
-rw-r--r-- | arch/x86/platform/intel-mid/intel-mid.c | 82 |
1 files changed, 51 insertions, 31 deletions
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c index 7bfd7847a7a6..40a3ff8e53e5 100644 --- a/arch/x86/platform/intel-mid/intel-mid.c +++ b/arch/x86/platform/intel-mid/intel-mid.c | |||
@@ -78,6 +78,8 @@ int sfi_mtimer_num; | |||
78 | struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX]; | 78 | struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX]; |
79 | EXPORT_SYMBOL_GPL(sfi_mrtc_array); | 79 | EXPORT_SYMBOL_GPL(sfi_mrtc_array); |
80 | int sfi_mrtc_num; | 80 | int sfi_mrtc_num; |
81 | static void __init ipc_device_handler(struct sfi_device_table_entry *pentry, | ||
82 | struct devs_id *dev); | ||
81 | 83 | ||
82 | static void intel_mid_power_off(void) | 84 | static void intel_mid_power_off(void) |
83 | { | 85 | { |
@@ -386,21 +388,6 @@ static int get_gpio_by_name(const char *name) | |||
386 | return -1; | 388 | return -1; |
387 | } | 389 | } |
388 | 390 | ||
389 | /* | ||
390 | * Here defines the array of devices platform data that IAFW would export | ||
391 | * through SFI "DEVS" table, we use name and type to match the device and | ||
392 | * its platform data. | ||
393 | */ | ||
394 | struct devs_id { | ||
395 | char name[SFI_NAME_LEN + 1]; | ||
396 | u8 type; | ||
397 | u8 delay; | ||
398 | void *(*get_platform_data)(void *info); | ||
399 | /* Custom handler for devices */ | ||
400 | void (*device_handler)(struct sfi_device_table_entry *pentry, | ||
401 | struct devs_id *dev); | ||
402 | }; | ||
403 | |||
404 | /* the offset for the mapping of global gpio pin to irq */ | 391 | /* the offset for the mapping of global gpio pin to irq */ |
405 | #define INTEL_MID_IRQ_OFFSET 0x100 | 392 | #define INTEL_MID_IRQ_OFFSET 0x100 |
406 | 393 | ||
@@ -695,24 +682,24 @@ static void *tc35876x_platform_data(void *data) | |||
695 | static const struct devs_id __initconst device_ids[] = { | 682 | static const struct devs_id __initconst device_ids[] = { |
696 | {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data, NULL}, | 683 | {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data, NULL}, |
697 | {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data, NULL}, | 684 | {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data, NULL}, |
698 | {"pmic_gpio", SFI_DEV_TYPE_IPC, 1, &pmic_gpio_platform_data, NULL}, | 685 | {"pmic_gpio", SFI_DEV_TYPE_IPC, 1, &pmic_gpio_platform_data, &ipc_device_handler}, |
699 | {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data, NULL}, | 686 | {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data, NULL}, |
700 | {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data, NULL}, | 687 | {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data, NULL}, |
701 | {"i2c_max7315_2", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data, NULL}, | 688 | {"i2c_max7315_2", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data, NULL}, |
702 | {"tca6416", SFI_DEV_TYPE_I2C, 1, &tca6416_platform_data, NULL}, | 689 | {"tca6416", SFI_DEV_TYPE_I2C, 1, &tca6416_platform_data, NULL}, |
703 | {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data, NULL}, | 690 | {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data, NULL}, |
704 | {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data, NULL}, | 691 | {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data, NULL}, |
705 | {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data, NULL}, | 692 | {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data, &ipc_device_handler}, |
706 | {"mpu3050", SFI_DEV_TYPE_I2C, 1, &mpu3050_platform_data, NULL}, | 693 | {"mpu3050", SFI_DEV_TYPE_I2C, 1, &mpu3050_platform_data, NULL}, |
707 | {"i2c_disp_brig", SFI_DEV_TYPE_I2C, 0, &tc35876x_platform_data, NULL}, | 694 | {"i2c_disp_brig", SFI_DEV_TYPE_I2C, 0, &tc35876x_platform_data, NULL}, |
708 | 695 | ||
709 | /* MSIC subdevices */ | 696 | /* MSIC subdevices */ |
710 | {"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data, NULL}, | 697 | {"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data, &ipc_device_handler}, |
711 | {"msic_gpio", SFI_DEV_TYPE_IPC, 1, &msic_gpio_platform_data, NULL}, | 698 | {"msic_gpio", SFI_DEV_TYPE_IPC, 1, &msic_gpio_platform_data, &ipc_device_handler}, |
712 | {"msic_audio", SFI_DEV_TYPE_IPC, 1, &msic_audio_platform_data, NULL}, | 699 | {"msic_audio", SFI_DEV_TYPE_IPC, 1, &msic_audio_platform_data, &ipc_device_handler}, |
713 | {"msic_power_btn", SFI_DEV_TYPE_IPC, 1, &msic_power_btn_platform_data, NULL}, | 700 | {"msic_power_btn", SFI_DEV_TYPE_IPC, 1, &msic_power_btn_platform_data, &ipc_device_handler}, |
714 | {"msic_ocd", SFI_DEV_TYPE_IPC, 1, &msic_ocd_platform_data, NULL}, | 701 | {"msic_ocd", SFI_DEV_TYPE_IPC, 1, &msic_ocd_platform_data, &ipc_device_handler}, |
715 | {"msic_thermal", SFI_DEV_TYPE_IPC, 1, &msic_thermal_platform_data, NULL}, | 702 | {"msic_thermal", SFI_DEV_TYPE_IPC, 1, &msic_thermal_platform_data, &ipc_device_handler}, |
716 | { 0 } | 703 | { 0 } |
717 | }; | 704 | }; |
718 | 705 | ||
@@ -843,13 +830,6 @@ static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *pentry, | |||
843 | pentry->name, pentry->irq); | 830 | pentry->name, pentry->irq); |
844 | pdata = dev->get_platform_data(pentry); | 831 | pdata = dev->get_platform_data(pentry); |
845 | 832 | ||
846 | /* | ||
847 | * On Medfield the platform device creation is handled by the MSIC | ||
848 | * MFD driver so we don't need to do it here. | ||
849 | */ | ||
850 | if (intel_mid_has_msic()) | ||
851 | return; | ||
852 | |||
853 | pdev = platform_device_alloc(pentry->name, 0); | 833 | pdev = platform_device_alloc(pentry->name, 0); |
854 | if (pdev == NULL) { | 834 | if (pdev == NULL) { |
855 | pr_err("out of memory for SFI platform device '%s'.\n", | 835 | pr_err("out of memory for SFI platform device '%s'.\n", |
@@ -859,7 +839,7 @@ static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *pentry, | |||
859 | install_irq_resource(pdev, pentry->irq); | 839 | install_irq_resource(pdev, pentry->irq); |
860 | 840 | ||
861 | pdev->dev.platform_data = pdata; | 841 | pdev->dev.platform_data = pdata; |
862 | intel_scu_device_register(pdev); | 842 | platform_device_add(pdev); |
863 | } | 843 | } |
864 | 844 | ||
865 | static void __init sfi_handle_spi_dev(struct sfi_device_table_entry *pentry, | 845 | static void __init sfi_handle_spi_dev(struct sfi_device_table_entry *pentry, |
@@ -914,6 +894,46 @@ static void __init sfi_handle_i2c_dev(struct sfi_device_table_entry *pentry, | |||
914 | i2c_register_board_info(pentry->host_num, &i2c_info, 1); | 894 | i2c_register_board_info(pentry->host_num, &i2c_info, 1); |
915 | } | 895 | } |
916 | 896 | ||
897 | static void __init ipc_device_handler(struct sfi_device_table_entry *pentry, | ||
898 | struct devs_id *dev) | ||
899 | { | ||
900 | struct platform_device *pdev; | ||
901 | void *pdata = NULL; | ||
902 | static struct resource res __initdata = { | ||
903 | .name = "IRQ", | ||
904 | .flags = IORESOURCE_IRQ, | ||
905 | }; | ||
906 | |||
907 | pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n", | ||
908 | pentry->name, pentry->irq); | ||
909 | |||
910 | /* | ||
911 | * We need to call platform init of IPC devices to fill misc_pdata | ||
912 | * structure. It will be used in msic_init for initialization. | ||
913 | */ | ||
914 | if (dev != NULL) | ||
915 | pdata = dev->get_platform_data(pentry); | ||
916 | |||
917 | /* | ||
918 | * On Medfield the platform device creation is handled by the MSIC | ||
919 | * MFD driver so we don't need to do it here. | ||
920 | */ | ||
921 | if (intel_mid_has_msic()) | ||
922 | return; | ||
923 | |||
924 | pdev = platform_device_alloc(pentry->name, 0); | ||
925 | if (pdev == NULL) { | ||
926 | pr_err("out of memory for SFI platform device '%s'.\n", | ||
927 | pentry->name); | ||
928 | return; | ||
929 | } | ||
930 | res.start = pentry->irq; | ||
931 | platform_device_add_resources(pdev, &res, 1); | ||
932 | |||
933 | pdev->dev.platform_data = pdata; | ||
934 | intel_scu_device_register(pdev); | ||
935 | } | ||
936 | |||
917 | static struct devs_id __init *get_device_id(u8 type, char *name) | 937 | static struct devs_id __init *get_device_id(u8 type, char *name) |
918 | { | 938 | { |
919 | struct devs_id *dev = device_ids; | 939 | struct devs_id *dev = device_ids; |