aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform
diff options
context:
space:
mode:
authorKuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>2013-10-17 18:35:33 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2013-10-17 19:40:51 -0400
commitaeedb370e7398fb5b39185b295d36f2da0653215 (patch)
treedefbbded137cd7cddc8669781a0102352f63e79b /arch/x86/platform
parent49c72a0a8ad640fa6026962056eeaf85a4ce79fd (diff)
intel_mid: Moved SFI related code to sfi.c
Moved SFI specific parsing/handling code to sfi.c. This will enable us to reuse our intel-mid code for platforms that supports firmware interfaces other than SFI (like ACPI). Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: http://lkml.kernel.org/r/1382049336-21316-10-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/Makefile2
-rw-r--r--arch/x86/platform/intel-mid/intel-mid.c451
-rw-r--r--arch/x86/platform/intel-mid/sfi.c485
3 files changed, 488 insertions, 450 deletions
diff --git a/arch/x86/platform/intel-mid/Makefile b/arch/x86/platform/intel-mid/Makefile
index de296358111e..b11e5b2de336 100644
--- a/arch/x86/platform/intel-mid/Makefile
+++ b/arch/x86/platform/intel-mid/Makefile
@@ -1,3 +1,5 @@
1obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o 1obj-$(CONFIG_X86_INTEL_MID) += intel-mid.o
2obj-$(CONFIG_X86_INTEL_MID) += intel_mid_vrtc.o 2obj-$(CONFIG_X86_INTEL_MID) += intel_mid_vrtc.o
3obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_intel_mid.o 3obj-$(CONFIG_EARLY_PRINTK_INTEL_MID) += early_printk_intel_mid.o
4# SFI specific code
5obj-$(CONFIG_SFI) += sfi.o
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index 40a3ff8e53e5..40915698b9b7 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -18,19 +18,9 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/scatterlist.h> 19#include <linux/scatterlist.h>
20#include <linux/sfi.h> 20#include <linux/sfi.h>
21#include <linux/intel_pmic_gpio.h>
22#include <linux/spi/spi.h>
23#include <linux/i2c.h>
24#include <linux/platform_data/pca953x.h>
25#include <linux/gpio_keys.h>
26#include <linux/input.h>
27#include <linux/platform_device.h>
28#include <linux/irq.h> 21#include <linux/irq.h>
29#include <linux/module.h> 22#include <linux/module.h>
30#include <linux/notifier.h> 23#include <linux/notifier.h>
31#include <linux/mfd/intel_msic.h>
32#include <linux/gpio.h>
33#include <linux/i2c/tc35876x.h>
34 24
35#include <asm/setup.h> 25#include <asm/setup.h>
36#include <asm/mpspec_def.h> 26#include <asm/mpspec_def.h>
@@ -68,19 +58,11 @@
68 58
69enum intel_mid_timer_options intel_mid_timer_options; 59enum intel_mid_timer_options intel_mid_timer_options;
70 60
71static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
72static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
73enum intel_mid_cpu_type __intel_mid_cpu_chip; 61enum intel_mid_cpu_type __intel_mid_cpu_chip;
74EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip); 62EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip);
75 63
76int sfi_mtimer_num;
77
78struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
79EXPORT_SYMBOL_GPL(sfi_mrtc_array);
80int sfi_mrtc_num;
81static void __init ipc_device_handler(struct sfi_device_table_entry *pentry, 64static void __init ipc_device_handler(struct sfi_device_table_entry *pentry,
82 struct devs_id *dev); 65 struct devs_id *dev);
83
84static void intel_mid_power_off(void) 66static void intel_mid_power_off(void)
85{ 67{
86} 68}
@@ -90,114 +72,6 @@ static void intel_mid_reboot(void)
90 intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0); 72 intel_scu_ipc_simple_command(IPCMSG_COLD_BOOT, 0);
91} 73}
92 74
93/* parse all the mtimer info to a static mtimer array */
94static int __init sfi_parse_mtmr(struct sfi_table_header *table)
95{
96 struct sfi_table_simple *sb;
97 struct sfi_timer_table_entry *pentry;
98 struct mpc_intsrc mp_irq;
99 int totallen;
100
101 sb = (struct sfi_table_simple *)table;
102 if (!sfi_mtimer_num) {
103 sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb,
104 struct sfi_timer_table_entry);
105 pentry = (struct sfi_timer_table_entry *) sb->pentry;
106 totallen = sfi_mtimer_num * sizeof(*pentry);
107 memcpy(sfi_mtimer_array, pentry, totallen);
108 }
109
110 pr_debug("SFI MTIMER info (num = %d):\n", sfi_mtimer_num);
111 pentry = sfi_mtimer_array;
112 for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) {
113 pr_debug("timer[%d]: paddr = 0x%08x, freq = %dHz,"
114 " irq = %d\n", totallen, (u32)pentry->phys_addr,
115 pentry->freq_hz, pentry->irq);
116 if (!pentry->irq)
117 continue;
118 mp_irq.type = MP_INTSRC;
119 mp_irq.irqtype = mp_INT;
120/* triggering mode edge bit 2-3, active high polarity bit 0-1 */
121 mp_irq.irqflag = 5;
122 mp_irq.srcbus = MP_BUS_ISA;
123 mp_irq.srcbusirq = pentry->irq; /* IRQ */
124 mp_irq.dstapic = MP_APIC_ALL;
125 mp_irq.dstirq = pentry->irq;
126 mp_save_irq(&mp_irq);
127 }
128
129 return 0;
130}
131
132struct sfi_timer_table_entry *sfi_get_mtmr(int hint)
133{
134 int i;
135 if (hint < sfi_mtimer_num) {
136 if (!sfi_mtimer_usage[hint]) {
137 pr_debug("hint taken for timer %d irq %d\n",
138 hint, sfi_mtimer_array[hint].irq);
139 sfi_mtimer_usage[hint] = 1;
140 return &sfi_mtimer_array[hint];
141 }
142 }
143 /* take the first timer available */
144 for (i = 0; i < sfi_mtimer_num;) {
145 if (!sfi_mtimer_usage[i]) {
146 sfi_mtimer_usage[i] = 1;
147 return &sfi_mtimer_array[i];
148 }
149 i++;
150 }
151 return NULL;
152}
153
154void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr)
155{
156 int i;
157 for (i = 0; i < sfi_mtimer_num;) {
158 if (mtmr->irq == sfi_mtimer_array[i].irq) {
159 sfi_mtimer_usage[i] = 0;
160 return;
161 }
162 i++;
163 }
164}
165
166/* parse all the mrtc info to a global mrtc array */
167int __init sfi_parse_mrtc(struct sfi_table_header *table)
168{
169 struct sfi_table_simple *sb;
170 struct sfi_rtc_table_entry *pentry;
171 struct mpc_intsrc mp_irq;
172
173 int totallen;
174
175 sb = (struct sfi_table_simple *)table;
176 if (!sfi_mrtc_num) {
177 sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb,
178 struct sfi_rtc_table_entry);
179 pentry = (struct sfi_rtc_table_entry *)sb->pentry;
180 totallen = sfi_mrtc_num * sizeof(*pentry);
181 memcpy(sfi_mrtc_array, pentry, totallen);
182 }
183
184 pr_debug("SFI RTC info (num = %d):\n", sfi_mrtc_num);
185 pentry = sfi_mrtc_array;
186 for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) {
187 pr_debug("RTC[%d]: paddr = 0x%08x, irq = %d\n",
188 totallen, (u32)pentry->phys_addr, pentry->irq);
189 mp_irq.type = MP_INTSRC;
190 mp_irq.irqtype = mp_INT;
191 mp_irq.irqflag = 0xf; /* level trigger and active low */
192 mp_irq.srcbus = MP_BUS_ISA;
193 mp_irq.srcbusirq = pentry->irq; /* IRQ */
194 mp_irq.dstapic = MP_APIC_ALL;
195 mp_irq.dstirq = pentry->irq;
196 mp_save_irq(&mp_irq);
197 }
198 return 0;
199}
200
201static unsigned long __init intel_mid_calibrate_tsc(void) 75static unsigned long __init intel_mid_calibrate_tsc(void)
202{ 76{
203 unsigned long fast_calibrate; 77 unsigned long fast_calibrate;
@@ -339,55 +213,6 @@ static inline int __init setup_x86_intel_mid_timer(char *arg)
339} 213}
340__setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer); 214__setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer);
341 215
342/*
343 * Parsing GPIO table first, since the DEVS table will need this table
344 * to map the pin name to the actual pin.
345 */
346static struct sfi_gpio_table_entry *gpio_table;
347static int gpio_num_entry;
348
349static int __init sfi_parse_gpio(struct sfi_table_header *table)
350{
351 struct sfi_table_simple *sb;
352 struct sfi_gpio_table_entry *pentry;
353 int num, i;
354
355 if (gpio_table)
356 return 0;
357 sb = (struct sfi_table_simple *)table;
358 num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
359 pentry = (struct sfi_gpio_table_entry *)sb->pentry;
360
361 gpio_table = kmalloc(num * sizeof(*pentry), GFP_KERNEL);
362 if (!gpio_table)
363 return -1;
364 memcpy(gpio_table, pentry, num * sizeof(*pentry));
365 gpio_num_entry = num;
366
367 pr_debug("GPIO pin info:\n");
368 for (i = 0; i < num; i++, pentry++)
369 pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s,"
370 " pin = %d\n", i,
371 pentry->controller_name,
372 pentry->pin_name,
373 pentry->pin_no);
374 return 0;
375}
376
377static int get_gpio_by_name(const char *name)
378{
379 struct sfi_gpio_table_entry *pentry = gpio_table;
380 int i;
381
382 if (!pentry)
383 return -1;
384 for (i = 0; i < gpio_num_entry; i++, pentry++) {
385 if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN))
386 return pentry->pin_no;
387 }
388 return -1;
389}
390
391/* the offset for the mapping of global gpio pin to irq */ 216/* the offset for the mapping of global gpio pin to irq */
392#define INTEL_MID_IRQ_OFFSET 0x100 217#define INTEL_MID_IRQ_OFFSET 0x100
393 218
@@ -703,197 +528,6 @@ static const struct devs_id __initconst device_ids[] = {
703 { 0 } 528 { 0 }
704}; 529};
705 530
706#define MAX_IPCDEVS 24
707static struct platform_device *ipc_devs[MAX_IPCDEVS];
708static int ipc_next_dev;
709
710#define MAX_SCU_SPI 24
711static struct spi_board_info *spi_devs[MAX_SCU_SPI];
712static int spi_next_dev;
713
714#define MAX_SCU_I2C 24
715static struct i2c_board_info *i2c_devs[MAX_SCU_I2C];
716static int i2c_bus[MAX_SCU_I2C];
717static int i2c_next_dev;
718
719static void __init intel_scu_device_register(struct platform_device *pdev)
720{
721 if (ipc_next_dev == MAX_IPCDEVS)
722 pr_err("too many SCU IPC devices");
723 else
724 ipc_devs[ipc_next_dev++] = pdev;
725}
726
727static void __init intel_scu_spi_device_register(struct spi_board_info *sdev)
728{
729 struct spi_board_info *new_dev;
730
731 if (spi_next_dev == MAX_SCU_SPI) {
732 pr_err("too many SCU SPI devices");
733 return;
734 }
735
736 new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL);
737 if (!new_dev) {
738 pr_err("failed to alloc mem for delayed spi dev %s\n",
739 sdev->modalias);
740 return;
741 }
742 memcpy(new_dev, sdev, sizeof(*sdev));
743
744 spi_devs[spi_next_dev++] = new_dev;
745}
746
747static void __init intel_scu_i2c_device_register(int bus,
748 struct i2c_board_info *idev)
749{
750 struct i2c_board_info *new_dev;
751
752 if (i2c_next_dev == MAX_SCU_I2C) {
753 pr_err("too many SCU I2C devices");
754 return;
755 }
756
757 new_dev = kzalloc(sizeof(*idev), GFP_KERNEL);
758 if (!new_dev) {
759 pr_err("failed to alloc mem for delayed i2c dev %s\n",
760 idev->type);
761 return;
762 }
763 memcpy(new_dev, idev, sizeof(*idev));
764
765 i2c_bus[i2c_next_dev] = bus;
766 i2c_devs[i2c_next_dev++] = new_dev;
767}
768
769BLOCKING_NOTIFIER_HEAD(intel_scu_notifier);
770EXPORT_SYMBOL_GPL(intel_scu_notifier);
771
772/* Called by IPC driver */
773void intel_scu_devices_create(void)
774{
775 int i;
776
777 for (i = 0; i < ipc_next_dev; i++)
778 platform_device_add(ipc_devs[i]);
779
780 for (i = 0; i < spi_next_dev; i++)
781 spi_register_board_info(spi_devs[i], 1);
782
783 for (i = 0; i < i2c_next_dev; i++) {
784 struct i2c_adapter *adapter;
785 struct i2c_client *client;
786
787 adapter = i2c_get_adapter(i2c_bus[i]);
788 if (adapter) {
789 client = i2c_new_device(adapter, i2c_devs[i]);
790 if (!client)
791 pr_err("can't create i2c device %s\n",
792 i2c_devs[i]->type);
793 } else
794 i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1);
795 }
796 intel_scu_notifier_post(SCU_AVAILABLE, NULL);
797}
798EXPORT_SYMBOL_GPL(intel_scu_devices_create);
799
800/* Called by IPC driver */
801void intel_scu_devices_destroy(void)
802{
803 int i;
804
805 intel_scu_notifier_post(SCU_DOWN, NULL);
806
807 for (i = 0; i < ipc_next_dev; i++)
808 platform_device_del(ipc_devs[i]);
809}
810EXPORT_SYMBOL_GPL(intel_scu_devices_destroy);
811
812static void __init install_irq_resource(struct platform_device *pdev, int irq)
813{
814 /* Single threaded */
815 static struct resource __initdata res = {
816 .name = "IRQ",
817 .flags = IORESOURCE_IRQ,
818 };
819 res.start = irq;
820 platform_device_add_resources(pdev, &res, 1);
821}
822
823static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *pentry,
824 struct devs_id *dev)
825{
826 struct platform_device *pdev;
827 void *pdata = NULL;
828
829 pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n",
830 pentry->name, pentry->irq);
831 pdata = dev->get_platform_data(pentry);
832
833 pdev = platform_device_alloc(pentry->name, 0);
834 if (pdev == NULL) {
835 pr_err("out of memory for SFI platform device '%s'.\n",
836 pentry->name);
837 return;
838 }
839 install_irq_resource(pdev, pentry->irq);
840
841 pdev->dev.platform_data = pdata;
842 platform_device_add(pdev);
843}
844
845static void __init sfi_handle_spi_dev(struct sfi_device_table_entry *pentry,
846 struct devs_id *dev)
847{
848 struct spi_board_info spi_info;
849 void *pdata = NULL;
850
851 memset(&spi_info, 0, sizeof(spi_info));
852 strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN);
853 spi_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq);
854 spi_info.bus_num = pentry->host_num;
855 spi_info.chip_select = pentry->addr;
856 spi_info.max_speed_hz = pentry->max_freq;
857 pr_debug("SPI bus=%d, name=%16.16s, irq=0x%2x, max_freq=%d, cs=%d\n",
858 spi_info.bus_num,
859 spi_info.modalias,
860 spi_info.irq,
861 spi_info.max_speed_hz,
862 spi_info.chip_select);
863
864 pdata = dev->get_platform_data(&spi_info);
865
866 spi_info.platform_data = pdata;
867 if (dev->delay)
868 intel_scu_spi_device_register(&spi_info);
869 else
870 spi_register_board_info(&spi_info, 1);
871}
872
873static void __init sfi_handle_i2c_dev(struct sfi_device_table_entry *pentry,
874 struct devs_id *dev)
875{
876 struct i2c_board_info i2c_info;
877 void *pdata = NULL;
878
879 memset(&i2c_info, 0, sizeof(i2c_info));
880 strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN);
881 i2c_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq);
882 i2c_info.addr = pentry->addr;
883 pr_debug("I2C bus = %d, name = %16.16s, irq = 0x%2x, addr = 0x%x\n",
884 pentry->host_num,
885 i2c_info.type,
886 i2c_info.irq,
887 i2c_info.addr);
888 pdata = dev->get_platform_data(&i2c_info);
889 i2c_info.platform_data = pdata;
890
891 if (dev->delay)
892 intel_scu_i2c_device_register(pentry->host_num, &i2c_info);
893 else
894 i2c_register_board_info(pentry->host_num, &i2c_info, 1);
895}
896
897static void __init ipc_device_handler(struct sfi_device_table_entry *pentry, 531static void __init ipc_device_handler(struct sfi_device_table_entry *pentry,
898 struct devs_id *dev) 532 struct devs_id *dev)
899{ 533{
@@ -934,89 +568,6 @@ static void __init ipc_device_handler(struct sfi_device_table_entry *pentry,
934 intel_scu_device_register(pdev); 568 intel_scu_device_register(pdev);
935} 569}
936 570
937static struct devs_id __init *get_device_id(u8 type, char *name)
938{
939 struct devs_id *dev = device_ids;
940
941 if (device_ids == NULL)
942 return NULL;
943
944 while (dev->name[0]) {
945 if (dev->type == type &&
946 !strncmp(dev->name, name, SFI_NAME_LEN)) {
947 return dev;
948 }
949 dev++;
950 }
951
952 return NULL;
953}
954
955static int __init sfi_parse_devs(struct sfi_table_header *table)
956{
957 struct sfi_table_simple *sb;
958 struct sfi_device_table_entry *pentry;
959 struct devs_id *dev = NULL;
960 int num, i;
961 int ioapic;
962 struct io_apic_irq_attr irq_attr;
963
964 sb = (struct sfi_table_simple *)table;
965 num = SFI_GET_NUM_ENTRIES(sb, struct sfi_device_table_entry);
966 pentry = (struct sfi_device_table_entry *)sb->pentry;
967
968 for (i = 0; i < num; i++, pentry++) {
969 int irq = pentry->irq;
970
971 if (irq != (u8)0xff) { /* native RTE case */
972 /* these SPI2 devices are not exposed to system as PCI
973 * devices, but they have separate RTE entry in IOAPIC
974 * so we have to enable them one by one here
975 */
976 ioapic = mp_find_ioapic(irq);
977 irq_attr.ioapic = ioapic;
978 irq_attr.ioapic_pin = irq;
979 irq_attr.trigger = 1;
980 irq_attr.polarity = 1;
981 io_apic_set_pci_routing(NULL, irq, &irq_attr);
982 } else
983 irq = 0; /* No irq */
984
985 dev = get_device_id(pentry->type, pentry->name);
986
987 if ((dev == NULL) || (dev->get_platform_data == NULL))
988 continue;
989
990 if (dev->device_handler) {
991 dev->device_handler(pentry, dev);
992 } else {
993 switch (pentry->type) {
994 case SFI_DEV_TYPE_IPC:
995 sfi_handle_ipc_dev(pentry, dev);
996 break;
997 case SFI_DEV_TYPE_SPI:
998 sfi_handle_spi_dev(pentry, dev);
999 break;
1000 case SFI_DEV_TYPE_I2C:
1001 sfi_handle_i2c_dev(pentry, dev);
1002 break;
1003 case SFI_DEV_TYPE_UART:
1004 case SFI_DEV_TYPE_HSI:
1005 default:
1006 break;
1007 }
1008 }
1009 }
1010 return 0;
1011}
1012
1013static int __init intel_mid_platform_init(void)
1014{
1015 sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, sfi_parse_gpio);
1016 sfi_table_parse(SFI_SIG_DEVS, NULL, NULL, sfi_parse_devs);
1017 return 0;
1018}
1019arch_initcall(intel_mid_platform_init);
1020 571
1021/* 572/*
1022 * we will search these buttons in SFI GPIO table (by name) 573 * we will search these buttons in SFI GPIO table (by name)
@@ -1078,4 +629,4 @@ static int __init pb_keys_init(void)
1078 } 629 }
1079 return 0; 630 return 0;
1080} 631}
1081late_initcall(pb_keys_init); 632late_initcall(pb_keys_init); \ No newline at end of file
diff --git a/arch/x86/platform/intel-mid/sfi.c b/arch/x86/platform/intel-mid/sfi.c
new file mode 100644
index 000000000000..2f8196d38f53
--- /dev/null
+++ b/arch/x86/platform/intel-mid/sfi.c
@@ -0,0 +1,485 @@
1/*
2 * intel_mid_sfi.c: Intel MID SFI initialization code
3 *
4 * (C) Copyright 2013 Intel Corporation
5 * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; version 2
10 * of the License.
11 */
12
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/interrupt.h>
16#include <linux/scatterlist.h>
17#include <linux/sfi.h>
18#include <linux/intel_pmic_gpio.h>
19#include <linux/spi/spi.h>
20#include <linux/i2c.h>
21#include <linux/skbuff.h>
22#include <linux/gpio.h>
23#include <linux/gpio_keys.h>
24#include <linux/input.h>
25#include <linux/platform_device.h>
26#include <linux/irq.h>
27#include <linux/module.h>
28#include <linux/notifier.h>
29#include <linux/mmc/core.h>
30#include <linux/mmc/card.h>
31#include <linux/blkdev.h>
32
33#include <asm/setup.h>
34#include <asm/mpspec_def.h>
35#include <asm/hw_irq.h>
36#include <asm/apic.h>
37#include <asm/io_apic.h>
38#include <asm/intel-mid.h>
39#include <asm/intel_mid_vrtc.h>
40#include <asm/io.h>
41#include <asm/i8259.h>
42#include <asm/intel_scu_ipc.h>
43#include <asm/apb_timer.h>
44#include <asm/reboot.h>
45#include "intel_mid_weak_decls.h"
46
47#define SFI_SIG_OEM0 "OEM0"
48#define MAX_IPCDEVS 24
49#define MAX_SCU_SPI 24
50#define MAX_SCU_I2C 24
51
52static struct platform_device *ipc_devs[MAX_IPCDEVS];
53static struct spi_board_info *spi_devs[MAX_SCU_SPI];
54static struct i2c_board_info *i2c_devs[MAX_SCU_I2C];
55static struct sfi_gpio_table_entry *gpio_table;
56static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
57static int ipc_next_dev;
58static int spi_next_dev;
59static int i2c_next_dev;
60static int i2c_bus[MAX_SCU_I2C];
61static int gpio_num_entry;
62static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
63int sfi_mrtc_num;
64int sfi_mtimer_num;
65
66struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
67EXPORT_SYMBOL_GPL(sfi_mrtc_array);
68
69struct blocking_notifier_head intel_scu_notifier =
70 BLOCKING_NOTIFIER_INIT(intel_scu_notifier);
71EXPORT_SYMBOL_GPL(intel_scu_notifier);
72
73/* parse all the mtimer info to a static mtimer array */
74int __init sfi_parse_mtmr(struct sfi_table_header *table)
75{
76 struct sfi_table_simple *sb;
77 struct sfi_timer_table_entry *pentry;
78 struct mpc_intsrc mp_irq;
79 int totallen;
80
81 sb = (struct sfi_table_simple *)table;
82 if (!sfi_mtimer_num) {
83 sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb,
84 struct sfi_timer_table_entry);
85 pentry = (struct sfi_timer_table_entry *) sb->pentry;
86 totallen = sfi_mtimer_num * sizeof(*pentry);
87 memcpy(sfi_mtimer_array, pentry, totallen);
88 }
89
90 pr_debug("SFI MTIMER info (num = %d):\n", sfi_mtimer_num);
91 pentry = sfi_mtimer_array;
92 for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) {
93 pr_debug("timer[%d]: paddr = 0x%08x, freq = %dHz, irq = %d\n",
94 totallen, (u32)pentry->phys_addr,
95 pentry->freq_hz, pentry->irq);
96 if (!pentry->irq)
97 continue;
98 mp_irq.type = MP_INTSRC;
99 mp_irq.irqtype = mp_INT;
100/* triggering mode edge bit 2-3, active high polarity bit 0-1 */
101 mp_irq.irqflag = 5;
102 mp_irq.srcbus = MP_BUS_ISA;
103 mp_irq.srcbusirq = pentry->irq; /* IRQ */
104 mp_irq.dstapic = MP_APIC_ALL;
105 mp_irq.dstirq = pentry->irq;
106 mp_save_irq(&mp_irq);
107 }
108
109 return 0;
110}
111
112struct sfi_timer_table_entry *sfi_get_mtmr(int hint)
113{
114 int i;
115 if (hint < sfi_mtimer_num) {
116 if (!sfi_mtimer_usage[hint]) {
117 pr_debug("hint taken for timer %d irq %d\n",
118 hint, sfi_mtimer_array[hint].irq);
119 sfi_mtimer_usage[hint] = 1;
120 return &sfi_mtimer_array[hint];
121 }
122 }
123 /* take the first timer available */
124 for (i = 0; i < sfi_mtimer_num;) {
125 if (!sfi_mtimer_usage[i]) {
126 sfi_mtimer_usage[i] = 1;
127 return &sfi_mtimer_array[i];
128 }
129 i++;
130 }
131 return NULL;
132}
133
134void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr)
135{
136 int i;
137 for (i = 0; i < sfi_mtimer_num;) {
138 if (mtmr->irq == sfi_mtimer_array[i].irq) {
139 sfi_mtimer_usage[i] = 0;
140 return;
141 }
142 i++;
143 }
144}
145
146/* parse all the mrtc info to a global mrtc array */
147int __init sfi_parse_mrtc(struct sfi_table_header *table)
148{
149 struct sfi_table_simple *sb;
150 struct sfi_rtc_table_entry *pentry;
151 struct mpc_intsrc mp_irq;
152
153 int totallen;
154
155 sb = (struct sfi_table_simple *)table;
156 if (!sfi_mrtc_num) {
157 sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb,
158 struct sfi_rtc_table_entry);
159 pentry = (struct sfi_rtc_table_entry *)sb->pentry;
160 totallen = sfi_mrtc_num * sizeof(*pentry);
161 memcpy(sfi_mrtc_array, pentry, totallen);
162 }
163
164 pr_debug("SFI RTC info (num = %d):\n", sfi_mrtc_num);
165 pentry = sfi_mrtc_array;
166 for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) {
167 pr_debug("RTC[%d]: paddr = 0x%08x, irq = %d\n",
168 totallen, (u32)pentry->phys_addr, pentry->irq);
169 mp_irq.type = MP_INTSRC;
170 mp_irq.irqtype = mp_INT;
171 mp_irq.irqflag = 0xf; /* level trigger and active low */
172 mp_irq.srcbus = MP_BUS_ISA;
173 mp_irq.srcbusirq = pentry->irq; /* IRQ */
174 mp_irq.dstapic = MP_APIC_ALL;
175 mp_irq.dstirq = pentry->irq;
176 mp_save_irq(&mp_irq);
177 }
178 return 0;
179}
180
181
182/*
183 * Parsing GPIO table first, since the DEVS table will need this table
184 * to map the pin name to the actual pin.
185 */
186static int __init sfi_parse_gpio(struct sfi_table_header *table)
187{
188 struct sfi_table_simple *sb;
189 struct sfi_gpio_table_entry *pentry;
190 int num, i;
191
192 if (gpio_table)
193 return 0;
194 sb = (struct sfi_table_simple *)table;
195 num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
196 pentry = (struct sfi_gpio_table_entry *)sb->pentry;
197
198 gpio_table = kmalloc(num * sizeof(*pentry), GFP_KERNEL);
199 if (!gpio_table)
200 return -1;
201 memcpy(gpio_table, pentry, num * sizeof(*pentry));
202 gpio_num_entry = num;
203
204 pr_debug("GPIO pin info:\n");
205 for (i = 0; i < num; i++, pentry++)
206 pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s,"
207 " pin = %d\n", i,
208 pentry->controller_name,
209 pentry->pin_name,
210 pentry->pin_no);
211 return 0;
212}
213
214int get_gpio_by_name(const char *name)
215{
216 struct sfi_gpio_table_entry *pentry = gpio_table;
217 int i;
218
219 if (!pentry)
220 return -1;
221 for (i = 0; i < gpio_num_entry; i++, pentry++) {
222 if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN))
223 return pentry->pin_no;
224 }
225 return -1;
226}
227
228void __init intel_scu_device_register(struct platform_device *pdev)
229{
230 if (ipc_next_dev == MAX_IPCDEVS)
231 pr_err("too many SCU IPC devices");
232 else
233 ipc_devs[ipc_next_dev++] = pdev;
234}
235
236static void __init intel_scu_spi_device_register(struct spi_board_info *sdev)
237{
238 struct spi_board_info *new_dev;
239
240 if (spi_next_dev == MAX_SCU_SPI) {
241 pr_err("too many SCU SPI devices");
242 return;
243 }
244
245 new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL);
246 if (!new_dev) {
247 pr_err("failed to alloc mem for delayed spi dev %s\n",
248 sdev->modalias);
249 return;
250 }
251 memcpy(new_dev, sdev, sizeof(*sdev));
252
253 spi_devs[spi_next_dev++] = new_dev;
254}
255
256static void __init intel_scu_i2c_device_register(int bus,
257 struct i2c_board_info *idev)
258{
259 struct i2c_board_info *new_dev;
260
261 if (i2c_next_dev == MAX_SCU_I2C) {
262 pr_err("too many SCU I2C devices");
263 return;
264 }
265
266 new_dev = kzalloc(sizeof(*idev), GFP_KERNEL);
267 if (!new_dev) {
268 pr_err("failed to alloc mem for delayed i2c dev %s\n",
269 idev->type);
270 return;
271 }
272 memcpy(new_dev, idev, sizeof(*idev));
273
274 i2c_bus[i2c_next_dev] = bus;
275 i2c_devs[i2c_next_dev++] = new_dev;
276}
277
278/* Called by IPC driver */
279void intel_scu_devices_create(void)
280{
281 int i;
282
283 for (i = 0; i < ipc_next_dev; i++)
284 platform_device_add(ipc_devs[i]);
285
286 for (i = 0; i < spi_next_dev; i++)
287 spi_register_board_info(spi_devs[i], 1);
288
289 for (i = 0; i < i2c_next_dev; i++) {
290 struct i2c_adapter *adapter;
291 struct i2c_client *client;
292
293 adapter = i2c_get_adapter(i2c_bus[i]);
294 if (adapter) {
295 client = i2c_new_device(adapter, i2c_devs[i]);
296 if (!client)
297 pr_err("can't create i2c device %s\n",
298 i2c_devs[i]->type);
299 } else
300 i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1);
301 }
302 intel_scu_notifier_post(SCU_AVAILABLE, NULL);
303}
304EXPORT_SYMBOL_GPL(intel_scu_devices_create);
305
306/* Called by IPC driver */
307void intel_scu_devices_destroy(void)
308{
309 int i;
310
311 intel_scu_notifier_post(SCU_DOWN, NULL);
312
313 for (i = 0; i < ipc_next_dev; i++)
314 platform_device_del(ipc_devs[i]);
315}
316EXPORT_SYMBOL_GPL(intel_scu_devices_destroy);
317
318static void __init install_irq_resource(struct platform_device *pdev, int irq)
319{
320 /* Single threaded */
321 static struct resource res __initdata = {
322 .name = "IRQ",
323 .flags = IORESOURCE_IRQ,
324 };
325 res.start = irq;
326 platform_device_add_resources(pdev, &res, 1);
327}
328
329static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *pentry,
330 struct devs_id *dev)
331{
332 struct platform_device *pdev;
333 void *pdata = NULL;
334
335 pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n",
336 pentry->name, pentry->irq);
337 pdata = dev->get_platform_data(pentry);
338
339 pdev = platform_device_alloc(pentry->name, 0);
340 if (pdev == NULL) {
341 pr_err("out of memory for SFI platform device '%s'.\n",
342 pentry->name);
343 return;
344 }
345 install_irq_resource(pdev, pentry->irq);
346
347 pdev->dev.platform_data = pdata;
348 platform_device_add(pdev);
349}
350
351static void __init sfi_handle_spi_dev(struct sfi_device_table_entry *pentry,
352 struct devs_id *dev)
353{
354 struct spi_board_info spi_info;
355 void *pdata = NULL;
356
357 memset(&spi_info, 0, sizeof(spi_info));
358 strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN);
359 spi_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq);
360 spi_info.bus_num = pentry->host_num;
361 spi_info.chip_select = pentry->addr;
362 spi_info.max_speed_hz = pentry->max_freq;
363 pr_debug("SPI bus=%d, name=%16.16s, irq=0x%2x, max_freq=%d, cs=%d\n",
364 spi_info.bus_num,
365 spi_info.modalias,
366 spi_info.irq,
367 spi_info.max_speed_hz,
368 spi_info.chip_select);
369
370 pdata = dev->get_platform_data(&spi_info);
371
372 spi_info.platform_data = pdata;
373 if (dev->delay)
374 intel_scu_spi_device_register(&spi_info);
375 else
376 spi_register_board_info(&spi_info, 1);
377}
378
379static void __init sfi_handle_i2c_dev(struct sfi_device_table_entry *pentry,
380 struct devs_id *dev)
381{
382 struct i2c_board_info i2c_info;
383 void *pdata = NULL;
384
385 memset(&i2c_info, 0, sizeof(i2c_info));
386 strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN);
387 i2c_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq);
388 i2c_info.addr = pentry->addr;
389 pr_debug("I2C bus = %d, name = %16.16s, irq = 0x%2x, addr = 0x%x\n",
390 pentry->host_num,
391 i2c_info.type,
392 i2c_info.irq,
393 i2c_info.addr);
394 pdata = dev->get_platform_data(&i2c_info);
395 i2c_info.platform_data = pdata;
396
397 if (dev->delay)
398 intel_scu_i2c_device_register(pentry->host_num, &i2c_info);
399 else
400 i2c_register_board_info(pentry->host_num, &i2c_info, 1);
401}
402
403static struct devs_id __init *get_device_id(u8 type, char *name)
404{
405 struct devs_id *dev = device_ids;
406
407 if (device_ids == NULL)
408 return NULL;
409
410 while (dev->name[0]) {
411 if (dev->type == type &&
412 !strncmp(dev->name, name, SFI_NAME_LEN)) {
413 return dev;
414 }
415 dev++;
416 }
417
418 return NULL;
419}
420
421static int __init sfi_parse_devs(struct sfi_table_header *table)
422{
423 struct sfi_table_simple *sb;
424 struct sfi_device_table_entry *pentry;
425 struct devs_id *dev = NULL;
426 int num, i;
427 int ioapic;
428 struct io_apic_irq_attr irq_attr;
429
430 sb = (struct sfi_table_simple *)table;
431 num = SFI_GET_NUM_ENTRIES(sb, struct sfi_device_table_entry);
432 pentry = (struct sfi_device_table_entry *)sb->pentry;
433
434 for (i = 0; i < num; i++, pentry++) {
435 int irq = pentry->irq;
436
437 if (irq != (u8)0xff) { /* native RTE case */
438 /* these SPI2 devices are not exposed to system as PCI
439 * devices, but they have separate RTE entry in IOAPIC
440 * so we have to enable them one by one here
441 */
442 ioapic = mp_find_ioapic(irq);
443 irq_attr.ioapic = ioapic;
444 irq_attr.ioapic_pin = irq;
445 irq_attr.trigger = 1;
446 irq_attr.polarity = 1;
447 io_apic_set_pci_routing(NULL, irq, &irq_attr);
448 } else
449 irq = 0; /* No irq */
450
451 dev = get_device_id(pentry->type, pentry->name);
452
453 if ((dev == NULL) || (dev->get_platform_data == NULL))
454 continue;
455
456 if (dev->device_handler) {
457 dev->device_handler(pentry, dev);
458 } else {
459 switch (pentry->type) {
460 case SFI_DEV_TYPE_IPC:
461 sfi_handle_ipc_dev(pentry, dev);
462 break;
463 case SFI_DEV_TYPE_SPI:
464 sfi_handle_spi_dev(pentry, dev);
465 break;
466 case SFI_DEV_TYPE_I2C:
467 sfi_handle_i2c_dev(pentry, dev);
468 break;
469 case SFI_DEV_TYPE_UART:
470 case SFI_DEV_TYPE_HSI:
471 default:
472 break;
473 }
474 }
475 }
476 return 0;
477}
478
479static int __init intel_mid_platform_init(void)
480{
481 sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, sfi_parse_gpio);
482 sfi_table_parse(SFI_SIG_DEVS, NULL, NULL, sfi_parse_devs);
483 return 0;
484}
485arch_initcall(intel_mid_platform_init);