xref: /OK3568_Linux_fs/kernel/arch/x86/platform/intel-mid/sfi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * intel_mid_sfi.c: Intel MID SFI initialization code
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * (C) Copyright 2013 Intel Corporation
6*4882a593Smuzhiyun  * Author: Sathyanarayanan Kuppuswamy <sathyanarayanan.kuppuswamy@intel.com>
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/init.h>
10*4882a593Smuzhiyun #include <linux/kernel.h>
11*4882a593Smuzhiyun #include <linux/interrupt.h>
12*4882a593Smuzhiyun #include <linux/scatterlist.h>
13*4882a593Smuzhiyun #include <linux/sfi.h>
14*4882a593Smuzhiyun #include <linux/spi/spi.h>
15*4882a593Smuzhiyun #include <linux/i2c.h>
16*4882a593Smuzhiyun #include <linux/skbuff.h>
17*4882a593Smuzhiyun #include <linux/gpio.h>
18*4882a593Smuzhiyun #include <linux/gpio_keys.h>
19*4882a593Smuzhiyun #include <linux/input.h>
20*4882a593Smuzhiyun #include <linux/platform_device.h>
21*4882a593Smuzhiyun #include <linux/irq.h>
22*4882a593Smuzhiyun #include <linux/export.h>
23*4882a593Smuzhiyun #include <linux/notifier.h>
24*4882a593Smuzhiyun #include <linux/mmc/core.h>
25*4882a593Smuzhiyun #include <linux/mmc/card.h>
26*4882a593Smuzhiyun #include <linux/blkdev.h>
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #include <asm/setup.h>
29*4882a593Smuzhiyun #include <asm/mpspec_def.h>
30*4882a593Smuzhiyun #include <asm/hw_irq.h>
31*4882a593Smuzhiyun #include <asm/apic.h>
32*4882a593Smuzhiyun #include <asm/io_apic.h>
33*4882a593Smuzhiyun #include <asm/intel-mid.h>
34*4882a593Smuzhiyun #include <asm/intel_mid_vrtc.h>
35*4882a593Smuzhiyun #include <asm/io.h>
36*4882a593Smuzhiyun #include <asm/i8259.h>
37*4882a593Smuzhiyun #include <asm/intel_scu_ipc.h>
38*4882a593Smuzhiyun #include <asm/apb_timer.h>
39*4882a593Smuzhiyun #include <asm/reboot.h>
40*4882a593Smuzhiyun 
41*4882a593Smuzhiyun #define	SFI_SIG_OEM0	"OEM0"
42*4882a593Smuzhiyun #define MAX_IPCDEVS	24
43*4882a593Smuzhiyun #define MAX_SCU_SPI	24
44*4882a593Smuzhiyun #define MAX_SCU_I2C	24
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun static struct platform_device *ipc_devs[MAX_IPCDEVS];
47*4882a593Smuzhiyun static struct spi_board_info *spi_devs[MAX_SCU_SPI];
48*4882a593Smuzhiyun static struct i2c_board_info *i2c_devs[MAX_SCU_I2C];
49*4882a593Smuzhiyun static struct sfi_gpio_table_entry *gpio_table;
50*4882a593Smuzhiyun static struct sfi_timer_table_entry sfi_mtimer_array[SFI_MTMR_MAX_NUM];
51*4882a593Smuzhiyun static int ipc_next_dev;
52*4882a593Smuzhiyun static int spi_next_dev;
53*4882a593Smuzhiyun static int i2c_next_dev;
54*4882a593Smuzhiyun static int i2c_bus[MAX_SCU_I2C];
55*4882a593Smuzhiyun static int gpio_num_entry;
56*4882a593Smuzhiyun static u32 sfi_mtimer_usage[SFI_MTMR_MAX_NUM];
57*4882a593Smuzhiyun int sfi_mrtc_num;
58*4882a593Smuzhiyun int sfi_mtimer_num;
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun struct sfi_rtc_table_entry sfi_mrtc_array[SFI_MRTC_MAX];
61*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(sfi_mrtc_array);
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun struct blocking_notifier_head intel_scu_notifier =
64*4882a593Smuzhiyun 			BLOCKING_NOTIFIER_INIT(intel_scu_notifier);
65*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(intel_scu_notifier);
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun #define intel_mid_sfi_get_pdata(dev, priv)	\
68*4882a593Smuzhiyun 	((dev)->get_platform_data ? (dev)->get_platform_data(priv) : NULL)
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /* parse all the mtimer info to a static mtimer array */
sfi_parse_mtmr(struct sfi_table_header * table)71*4882a593Smuzhiyun int __init sfi_parse_mtmr(struct sfi_table_header *table)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	struct sfi_table_simple *sb;
74*4882a593Smuzhiyun 	struct sfi_timer_table_entry *pentry;
75*4882a593Smuzhiyun 	struct mpc_intsrc mp_irq;
76*4882a593Smuzhiyun 	int totallen;
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun 	sb = (struct sfi_table_simple *)table;
79*4882a593Smuzhiyun 	if (!sfi_mtimer_num) {
80*4882a593Smuzhiyun 		sfi_mtimer_num = SFI_GET_NUM_ENTRIES(sb,
81*4882a593Smuzhiyun 					struct sfi_timer_table_entry);
82*4882a593Smuzhiyun 		pentry = (struct sfi_timer_table_entry *) sb->pentry;
83*4882a593Smuzhiyun 		totallen = sfi_mtimer_num * sizeof(*pentry);
84*4882a593Smuzhiyun 		memcpy(sfi_mtimer_array, pentry, totallen);
85*4882a593Smuzhiyun 	}
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 	pr_debug("SFI MTIMER info (num = %d):\n", sfi_mtimer_num);
88*4882a593Smuzhiyun 	pentry = sfi_mtimer_array;
89*4882a593Smuzhiyun 	for (totallen = 0; totallen < sfi_mtimer_num; totallen++, pentry++) {
90*4882a593Smuzhiyun 		pr_debug("timer[%d]: paddr = 0x%08x, freq = %dHz, irq = %d\n",
91*4882a593Smuzhiyun 			totallen, (u32)pentry->phys_addr,
92*4882a593Smuzhiyun 			pentry->freq_hz, pentry->irq);
93*4882a593Smuzhiyun 		mp_irq.type = MP_INTSRC;
94*4882a593Smuzhiyun 		mp_irq.irqtype = mp_INT;
95*4882a593Smuzhiyun 		mp_irq.irqflag = MP_IRQTRIG_EDGE | MP_IRQPOL_ACTIVE_HIGH;
96*4882a593Smuzhiyun 		mp_irq.srcbus = MP_BUS_ISA;
97*4882a593Smuzhiyun 		mp_irq.srcbusirq = pentry->irq;	/* IRQ */
98*4882a593Smuzhiyun 		mp_irq.dstapic = MP_APIC_ALL;
99*4882a593Smuzhiyun 		mp_irq.dstirq = pentry->irq;
100*4882a593Smuzhiyun 		mp_save_irq(&mp_irq);
101*4882a593Smuzhiyun 		mp_map_gsi_to_irq(pentry->irq, IOAPIC_MAP_ALLOC, NULL);
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	return 0;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun 
sfi_get_mtmr(int hint)107*4882a593Smuzhiyun struct sfi_timer_table_entry *sfi_get_mtmr(int hint)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	int i;
110*4882a593Smuzhiyun 	if (hint < sfi_mtimer_num) {
111*4882a593Smuzhiyun 		if (!sfi_mtimer_usage[hint]) {
112*4882a593Smuzhiyun 			pr_debug("hint taken for timer %d irq %d\n",
113*4882a593Smuzhiyun 				hint, sfi_mtimer_array[hint].irq);
114*4882a593Smuzhiyun 			sfi_mtimer_usage[hint] = 1;
115*4882a593Smuzhiyun 			return &sfi_mtimer_array[hint];
116*4882a593Smuzhiyun 		}
117*4882a593Smuzhiyun 	}
118*4882a593Smuzhiyun 	/* take the first timer available */
119*4882a593Smuzhiyun 	for (i = 0; i < sfi_mtimer_num;) {
120*4882a593Smuzhiyun 		if (!sfi_mtimer_usage[i]) {
121*4882a593Smuzhiyun 			sfi_mtimer_usage[i] = 1;
122*4882a593Smuzhiyun 			return &sfi_mtimer_array[i];
123*4882a593Smuzhiyun 		}
124*4882a593Smuzhiyun 		i++;
125*4882a593Smuzhiyun 	}
126*4882a593Smuzhiyun 	return NULL;
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun 
sfi_free_mtmr(struct sfi_timer_table_entry * mtmr)129*4882a593Smuzhiyun void sfi_free_mtmr(struct sfi_timer_table_entry *mtmr)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun 	int i;
132*4882a593Smuzhiyun 	for (i = 0; i < sfi_mtimer_num;) {
133*4882a593Smuzhiyun 		if (mtmr->irq == sfi_mtimer_array[i].irq) {
134*4882a593Smuzhiyun 			sfi_mtimer_usage[i] = 0;
135*4882a593Smuzhiyun 			return;
136*4882a593Smuzhiyun 		}
137*4882a593Smuzhiyun 		i++;
138*4882a593Smuzhiyun 	}
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun /* parse all the mrtc info to a global mrtc array */
sfi_parse_mrtc(struct sfi_table_header * table)142*4882a593Smuzhiyun int __init sfi_parse_mrtc(struct sfi_table_header *table)
143*4882a593Smuzhiyun {
144*4882a593Smuzhiyun 	struct sfi_table_simple *sb;
145*4882a593Smuzhiyun 	struct sfi_rtc_table_entry *pentry;
146*4882a593Smuzhiyun 	struct mpc_intsrc mp_irq;
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 	int totallen;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	sb = (struct sfi_table_simple *)table;
151*4882a593Smuzhiyun 	if (!sfi_mrtc_num) {
152*4882a593Smuzhiyun 		sfi_mrtc_num = SFI_GET_NUM_ENTRIES(sb,
153*4882a593Smuzhiyun 						struct sfi_rtc_table_entry);
154*4882a593Smuzhiyun 		pentry = (struct sfi_rtc_table_entry *)sb->pentry;
155*4882a593Smuzhiyun 		totallen = sfi_mrtc_num * sizeof(*pentry);
156*4882a593Smuzhiyun 		memcpy(sfi_mrtc_array, pentry, totallen);
157*4882a593Smuzhiyun 	}
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun 	pr_debug("SFI RTC info (num = %d):\n", sfi_mrtc_num);
160*4882a593Smuzhiyun 	pentry = sfi_mrtc_array;
161*4882a593Smuzhiyun 	for (totallen = 0; totallen < sfi_mrtc_num; totallen++, pentry++) {
162*4882a593Smuzhiyun 		pr_debug("RTC[%d]: paddr = 0x%08x, irq = %d\n",
163*4882a593Smuzhiyun 			totallen, (u32)pentry->phys_addr, pentry->irq);
164*4882a593Smuzhiyun 		mp_irq.type = MP_INTSRC;
165*4882a593Smuzhiyun 		mp_irq.irqtype = mp_INT;
166*4882a593Smuzhiyun 		mp_irq.irqflag = MP_IRQTRIG_LEVEL | MP_IRQPOL_ACTIVE_LOW;
167*4882a593Smuzhiyun 		mp_irq.srcbus = MP_BUS_ISA;
168*4882a593Smuzhiyun 		mp_irq.srcbusirq = pentry->irq;	/* IRQ */
169*4882a593Smuzhiyun 		mp_irq.dstapic = MP_APIC_ALL;
170*4882a593Smuzhiyun 		mp_irq.dstirq = pentry->irq;
171*4882a593Smuzhiyun 		mp_save_irq(&mp_irq);
172*4882a593Smuzhiyun 		mp_map_gsi_to_irq(pentry->irq, IOAPIC_MAP_ALLOC, NULL);
173*4882a593Smuzhiyun 	}
174*4882a593Smuzhiyun 	return 0;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun /*
179*4882a593Smuzhiyun  * Parsing GPIO table first, since the DEVS table will need this table
180*4882a593Smuzhiyun  * to map the pin name to the actual pin.
181*4882a593Smuzhiyun  */
sfi_parse_gpio(struct sfi_table_header * table)182*4882a593Smuzhiyun static int __init sfi_parse_gpio(struct sfi_table_header *table)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	struct sfi_table_simple *sb;
185*4882a593Smuzhiyun 	struct sfi_gpio_table_entry *pentry;
186*4882a593Smuzhiyun 	int num, i;
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	if (gpio_table)
189*4882a593Smuzhiyun 		return 0;
190*4882a593Smuzhiyun 	sb = (struct sfi_table_simple *)table;
191*4882a593Smuzhiyun 	num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
192*4882a593Smuzhiyun 	pentry = (struct sfi_gpio_table_entry *)sb->pentry;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	gpio_table = kmemdup(pentry, num * sizeof(*pentry), GFP_KERNEL);
195*4882a593Smuzhiyun 	if (!gpio_table)
196*4882a593Smuzhiyun 		return -1;
197*4882a593Smuzhiyun 	gpio_num_entry = num;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun 	pr_debug("GPIO pin info:\n");
200*4882a593Smuzhiyun 	for (i = 0; i < num; i++, pentry++)
201*4882a593Smuzhiyun 		pr_debug("info[%2d]: controller = %16.16s, pin_name = %16.16s,"
202*4882a593Smuzhiyun 		" pin = %d\n", i,
203*4882a593Smuzhiyun 			pentry->controller_name,
204*4882a593Smuzhiyun 			pentry->pin_name,
205*4882a593Smuzhiyun 			pentry->pin_no);
206*4882a593Smuzhiyun 	return 0;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun 
get_gpio_by_name(const char * name)209*4882a593Smuzhiyun int get_gpio_by_name(const char *name)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun 	struct sfi_gpio_table_entry *pentry = gpio_table;
212*4882a593Smuzhiyun 	int i;
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun 	if (!pentry)
215*4882a593Smuzhiyun 		return -1;
216*4882a593Smuzhiyun 	for (i = 0; i < gpio_num_entry; i++, pentry++) {
217*4882a593Smuzhiyun 		if (!strncmp(name, pentry->pin_name, SFI_NAME_LEN))
218*4882a593Smuzhiyun 			return pentry->pin_no;
219*4882a593Smuzhiyun 	}
220*4882a593Smuzhiyun 	return -EINVAL;
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun 
intel_scu_ipc_device_register(struct platform_device * pdev)223*4882a593Smuzhiyun static void __init intel_scu_ipc_device_register(struct platform_device *pdev)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	if (ipc_next_dev == MAX_IPCDEVS)
226*4882a593Smuzhiyun 		pr_err("too many SCU IPC devices");
227*4882a593Smuzhiyun 	else
228*4882a593Smuzhiyun 		ipc_devs[ipc_next_dev++] = pdev;
229*4882a593Smuzhiyun }
230*4882a593Smuzhiyun 
intel_scu_spi_device_register(struct spi_board_info * sdev)231*4882a593Smuzhiyun static void __init intel_scu_spi_device_register(struct spi_board_info *sdev)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun 	struct spi_board_info *new_dev;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	if (spi_next_dev == MAX_SCU_SPI) {
236*4882a593Smuzhiyun 		pr_err("too many SCU SPI devices");
237*4882a593Smuzhiyun 		return;
238*4882a593Smuzhiyun 	}
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	new_dev = kzalloc(sizeof(*sdev), GFP_KERNEL);
241*4882a593Smuzhiyun 	if (!new_dev) {
242*4882a593Smuzhiyun 		pr_err("failed to alloc mem for delayed spi dev %s\n",
243*4882a593Smuzhiyun 			sdev->modalias);
244*4882a593Smuzhiyun 		return;
245*4882a593Smuzhiyun 	}
246*4882a593Smuzhiyun 	*new_dev = *sdev;
247*4882a593Smuzhiyun 
248*4882a593Smuzhiyun 	spi_devs[spi_next_dev++] = new_dev;
249*4882a593Smuzhiyun }
250*4882a593Smuzhiyun 
intel_scu_i2c_device_register(int bus,struct i2c_board_info * idev)251*4882a593Smuzhiyun static void __init intel_scu_i2c_device_register(int bus,
252*4882a593Smuzhiyun 						struct i2c_board_info *idev)
253*4882a593Smuzhiyun {
254*4882a593Smuzhiyun 	struct i2c_board_info *new_dev;
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	if (i2c_next_dev == MAX_SCU_I2C) {
257*4882a593Smuzhiyun 		pr_err("too many SCU I2C devices");
258*4882a593Smuzhiyun 		return;
259*4882a593Smuzhiyun 	}
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun 	new_dev = kzalloc(sizeof(*idev), GFP_KERNEL);
262*4882a593Smuzhiyun 	if (!new_dev) {
263*4882a593Smuzhiyun 		pr_err("failed to alloc mem for delayed i2c dev %s\n",
264*4882a593Smuzhiyun 			idev->type);
265*4882a593Smuzhiyun 		return;
266*4882a593Smuzhiyun 	}
267*4882a593Smuzhiyun 	*new_dev = *idev;
268*4882a593Smuzhiyun 
269*4882a593Smuzhiyun 	i2c_bus[i2c_next_dev] = bus;
270*4882a593Smuzhiyun 	i2c_devs[i2c_next_dev++] = new_dev;
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun /* Called by IPC driver */
intel_scu_devices_create(void)274*4882a593Smuzhiyun void intel_scu_devices_create(void)
275*4882a593Smuzhiyun {
276*4882a593Smuzhiyun 	int i;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	for (i = 0; i < ipc_next_dev; i++)
279*4882a593Smuzhiyun 		platform_device_add(ipc_devs[i]);
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	for (i = 0; i < spi_next_dev; i++)
282*4882a593Smuzhiyun 		spi_register_board_info(spi_devs[i], 1);
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	for (i = 0; i < i2c_next_dev; i++) {
285*4882a593Smuzhiyun 		struct i2c_adapter *adapter;
286*4882a593Smuzhiyun 		struct i2c_client *client;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 		adapter = i2c_get_adapter(i2c_bus[i]);
289*4882a593Smuzhiyun 		if (adapter) {
290*4882a593Smuzhiyun 			client = i2c_new_client_device(adapter, i2c_devs[i]);
291*4882a593Smuzhiyun 			if (IS_ERR(client))
292*4882a593Smuzhiyun 				pr_err("can't create i2c device %s\n",
293*4882a593Smuzhiyun 					i2c_devs[i]->type);
294*4882a593Smuzhiyun 		} else
295*4882a593Smuzhiyun 			i2c_register_board_info(i2c_bus[i], i2c_devs[i], 1);
296*4882a593Smuzhiyun 	}
297*4882a593Smuzhiyun 	intel_scu_notifier_post(SCU_AVAILABLE, NULL);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(intel_scu_devices_create);
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun /* Called by IPC driver */
intel_scu_devices_destroy(void)302*4882a593Smuzhiyun void intel_scu_devices_destroy(void)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	int i;
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	intel_scu_notifier_post(SCU_DOWN, NULL);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun 	for (i = 0; i < ipc_next_dev; i++)
309*4882a593Smuzhiyun 		platform_device_del(ipc_devs[i]);
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(intel_scu_devices_destroy);
312*4882a593Smuzhiyun 
install_irq_resource(struct platform_device * pdev,int irq)313*4882a593Smuzhiyun static void __init install_irq_resource(struct platform_device *pdev, int irq)
314*4882a593Smuzhiyun {
315*4882a593Smuzhiyun 	/* Single threaded */
316*4882a593Smuzhiyun 	static struct resource res __initdata = {
317*4882a593Smuzhiyun 		.name = "IRQ",
318*4882a593Smuzhiyun 		.flags = IORESOURCE_IRQ,
319*4882a593Smuzhiyun 	};
320*4882a593Smuzhiyun 	res.start = irq;
321*4882a593Smuzhiyun 	platform_device_add_resources(pdev, &res, 1);
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun 
sfi_handle_ipc_dev(struct sfi_device_table_entry * pentry,struct devs_id * dev)324*4882a593Smuzhiyun static void __init sfi_handle_ipc_dev(struct sfi_device_table_entry *pentry,
325*4882a593Smuzhiyun 					struct devs_id *dev)
326*4882a593Smuzhiyun {
327*4882a593Smuzhiyun 	struct platform_device *pdev;
328*4882a593Smuzhiyun 	void *pdata = NULL;
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 	pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n",
331*4882a593Smuzhiyun 		pentry->name, pentry->irq);
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun 	/*
334*4882a593Smuzhiyun 	 * We need to call platform init of IPC devices to fill misc_pdata
335*4882a593Smuzhiyun 	 * structure. It will be used in msic_init for initialization.
336*4882a593Smuzhiyun 	 */
337*4882a593Smuzhiyun 	pdata = intel_mid_sfi_get_pdata(dev, pentry);
338*4882a593Smuzhiyun 	if (IS_ERR(pdata))
339*4882a593Smuzhiyun 		return;
340*4882a593Smuzhiyun 
341*4882a593Smuzhiyun 	/*
342*4882a593Smuzhiyun 	 * On Medfield the platform device creation is handled by the MSIC
343*4882a593Smuzhiyun 	 * MFD driver so we don't need to do it here.
344*4882a593Smuzhiyun 	 */
345*4882a593Smuzhiyun 	if (dev->msic && intel_mid_has_msic())
346*4882a593Smuzhiyun 		return;
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	pdev = platform_device_alloc(pentry->name, 0);
349*4882a593Smuzhiyun 	if (pdev == NULL) {
350*4882a593Smuzhiyun 		pr_err("out of memory for SFI platform device '%s'.\n",
351*4882a593Smuzhiyun 			pentry->name);
352*4882a593Smuzhiyun 		return;
353*4882a593Smuzhiyun 	}
354*4882a593Smuzhiyun 	install_irq_resource(pdev, pentry->irq);
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun 	pdev->dev.platform_data = pdata;
357*4882a593Smuzhiyun 	if (dev->delay)
358*4882a593Smuzhiyun 		intel_scu_ipc_device_register(pdev);
359*4882a593Smuzhiyun 	else
360*4882a593Smuzhiyun 		platform_device_add(pdev);
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun 
sfi_handle_spi_dev(struct sfi_device_table_entry * pentry,struct devs_id * dev)363*4882a593Smuzhiyun static void __init sfi_handle_spi_dev(struct sfi_device_table_entry *pentry,
364*4882a593Smuzhiyun 					struct devs_id *dev)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun 	struct spi_board_info spi_info;
367*4882a593Smuzhiyun 	void *pdata = NULL;
368*4882a593Smuzhiyun 
369*4882a593Smuzhiyun 	memset(&spi_info, 0, sizeof(spi_info));
370*4882a593Smuzhiyun 	strncpy(spi_info.modalias, pentry->name, SFI_NAME_LEN);
371*4882a593Smuzhiyun 	spi_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq);
372*4882a593Smuzhiyun 	spi_info.bus_num = pentry->host_num;
373*4882a593Smuzhiyun 	spi_info.chip_select = pentry->addr;
374*4882a593Smuzhiyun 	spi_info.max_speed_hz = pentry->max_freq;
375*4882a593Smuzhiyun 	pr_debug("SPI bus=%d, name=%16.16s, irq=0x%2x, max_freq=%d, cs=%d\n",
376*4882a593Smuzhiyun 		spi_info.bus_num,
377*4882a593Smuzhiyun 		spi_info.modalias,
378*4882a593Smuzhiyun 		spi_info.irq,
379*4882a593Smuzhiyun 		spi_info.max_speed_hz,
380*4882a593Smuzhiyun 		spi_info.chip_select);
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	pdata = intel_mid_sfi_get_pdata(dev, &spi_info);
383*4882a593Smuzhiyun 	if (IS_ERR(pdata))
384*4882a593Smuzhiyun 		return;
385*4882a593Smuzhiyun 
386*4882a593Smuzhiyun 	spi_info.platform_data = pdata;
387*4882a593Smuzhiyun 	if (dev->delay)
388*4882a593Smuzhiyun 		intel_scu_spi_device_register(&spi_info);
389*4882a593Smuzhiyun 	else
390*4882a593Smuzhiyun 		spi_register_board_info(&spi_info, 1);
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun 
sfi_handle_i2c_dev(struct sfi_device_table_entry * pentry,struct devs_id * dev)393*4882a593Smuzhiyun static void __init sfi_handle_i2c_dev(struct sfi_device_table_entry *pentry,
394*4882a593Smuzhiyun 					struct devs_id *dev)
395*4882a593Smuzhiyun {
396*4882a593Smuzhiyun 	struct i2c_board_info i2c_info;
397*4882a593Smuzhiyun 	void *pdata = NULL;
398*4882a593Smuzhiyun 
399*4882a593Smuzhiyun 	memset(&i2c_info, 0, sizeof(i2c_info));
400*4882a593Smuzhiyun 	strncpy(i2c_info.type, pentry->name, SFI_NAME_LEN);
401*4882a593Smuzhiyun 	i2c_info.irq = ((pentry->irq == (u8)0xff) ? 0 : pentry->irq);
402*4882a593Smuzhiyun 	i2c_info.addr = pentry->addr;
403*4882a593Smuzhiyun 	pr_debug("I2C bus = %d, name = %16.16s, irq = 0x%2x, addr = 0x%x\n",
404*4882a593Smuzhiyun 		pentry->host_num,
405*4882a593Smuzhiyun 		i2c_info.type,
406*4882a593Smuzhiyun 		i2c_info.irq,
407*4882a593Smuzhiyun 		i2c_info.addr);
408*4882a593Smuzhiyun 	pdata = intel_mid_sfi_get_pdata(dev, &i2c_info);
409*4882a593Smuzhiyun 	i2c_info.platform_data = pdata;
410*4882a593Smuzhiyun 	if (IS_ERR(pdata))
411*4882a593Smuzhiyun 		return;
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	if (dev->delay)
414*4882a593Smuzhiyun 		intel_scu_i2c_device_register(pentry->host_num, &i2c_info);
415*4882a593Smuzhiyun 	else
416*4882a593Smuzhiyun 		i2c_register_board_info(pentry->host_num, &i2c_info, 1);
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
sfi_handle_sd_dev(struct sfi_device_table_entry * pentry,struct devs_id * dev)419*4882a593Smuzhiyun static void __init sfi_handle_sd_dev(struct sfi_device_table_entry *pentry,
420*4882a593Smuzhiyun 					struct devs_id *dev)
421*4882a593Smuzhiyun {
422*4882a593Smuzhiyun 	struct mid_sd_board_info sd_info;
423*4882a593Smuzhiyun 	void *pdata;
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	memset(&sd_info, 0, sizeof(sd_info));
426*4882a593Smuzhiyun 	strncpy(sd_info.name, pentry->name, SFI_NAME_LEN);
427*4882a593Smuzhiyun 	sd_info.bus_num = pentry->host_num;
428*4882a593Smuzhiyun 	sd_info.max_clk = pentry->max_freq;
429*4882a593Smuzhiyun 	sd_info.addr = pentry->addr;
430*4882a593Smuzhiyun 	pr_debug("SD bus = %d, name = %16.16s, max_clk = %d, addr = 0x%x\n",
431*4882a593Smuzhiyun 		 sd_info.bus_num,
432*4882a593Smuzhiyun 		 sd_info.name,
433*4882a593Smuzhiyun 		 sd_info.max_clk,
434*4882a593Smuzhiyun 		 sd_info.addr);
435*4882a593Smuzhiyun 	pdata = intel_mid_sfi_get_pdata(dev, &sd_info);
436*4882a593Smuzhiyun 	if (IS_ERR(pdata))
437*4882a593Smuzhiyun 		return;
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 	/* Nothing we can do with this for now */
440*4882a593Smuzhiyun 	sd_info.platform_data = pdata;
441*4882a593Smuzhiyun 
442*4882a593Smuzhiyun 	pr_debug("Successfully registered %16.16s", sd_info.name);
443*4882a593Smuzhiyun }
444*4882a593Smuzhiyun 
445*4882a593Smuzhiyun extern struct devs_id *const __x86_intel_mid_dev_start[],
446*4882a593Smuzhiyun 		      *const __x86_intel_mid_dev_end[];
447*4882a593Smuzhiyun 
get_device_id(u8 type,char * name)448*4882a593Smuzhiyun static struct devs_id __init *get_device_id(u8 type, char *name)
449*4882a593Smuzhiyun {
450*4882a593Smuzhiyun 	struct devs_id *const *dev_table;
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	for (dev_table = __x86_intel_mid_dev_start;
453*4882a593Smuzhiyun 			dev_table < __x86_intel_mid_dev_end; dev_table++) {
454*4882a593Smuzhiyun 		struct devs_id *dev = *dev_table;
455*4882a593Smuzhiyun 		if (dev->type == type &&
456*4882a593Smuzhiyun 			!strncmp(dev->name, name, SFI_NAME_LEN)) {
457*4882a593Smuzhiyun 			return dev;
458*4882a593Smuzhiyun 		}
459*4882a593Smuzhiyun 	}
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun 	return NULL;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun 
sfi_parse_devs(struct sfi_table_header * table)464*4882a593Smuzhiyun static int __init sfi_parse_devs(struct sfi_table_header *table)
465*4882a593Smuzhiyun {
466*4882a593Smuzhiyun 	struct sfi_table_simple *sb;
467*4882a593Smuzhiyun 	struct sfi_device_table_entry *pentry;
468*4882a593Smuzhiyun 	struct devs_id *dev = NULL;
469*4882a593Smuzhiyun 	int num, i, ret;
470*4882a593Smuzhiyun 	int polarity;
471*4882a593Smuzhiyun 	struct irq_alloc_info info;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	sb = (struct sfi_table_simple *)table;
474*4882a593Smuzhiyun 	num = SFI_GET_NUM_ENTRIES(sb, struct sfi_device_table_entry);
475*4882a593Smuzhiyun 	pentry = (struct sfi_device_table_entry *)sb->pentry;
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun 	for (i = 0; i < num; i++, pentry++) {
478*4882a593Smuzhiyun 		int irq = pentry->irq;
479*4882a593Smuzhiyun 
480*4882a593Smuzhiyun 		if (irq != (u8)0xff) { /* native RTE case */
481*4882a593Smuzhiyun 			/* these SPI2 devices are not exposed to system as PCI
482*4882a593Smuzhiyun 			 * devices, but they have separate RTE entry in IOAPIC
483*4882a593Smuzhiyun 			 * so we have to enable them one by one here
484*4882a593Smuzhiyun 			 */
485*4882a593Smuzhiyun 			if (intel_mid_identify_cpu() ==
486*4882a593Smuzhiyun 					INTEL_MID_CPU_CHIP_TANGIER) {
487*4882a593Smuzhiyun 				if (!strncmp(pentry->name, "r69001-ts-i2c", 13))
488*4882a593Smuzhiyun 					/* active low */
489*4882a593Smuzhiyun 					polarity = 1;
490*4882a593Smuzhiyun 				else if (!strncmp(pentry->name,
491*4882a593Smuzhiyun 						"synaptics_3202", 14))
492*4882a593Smuzhiyun 					/* active low */
493*4882a593Smuzhiyun 					polarity = 1;
494*4882a593Smuzhiyun 				else if (irq == 41)
495*4882a593Smuzhiyun 					/* fast_int_1 */
496*4882a593Smuzhiyun 					polarity = 1;
497*4882a593Smuzhiyun 				else
498*4882a593Smuzhiyun 					/* active high */
499*4882a593Smuzhiyun 					polarity = 0;
500*4882a593Smuzhiyun 			} else {
501*4882a593Smuzhiyun 				/* PNW and CLV go with active low */
502*4882a593Smuzhiyun 				polarity = 1;
503*4882a593Smuzhiyun 			}
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 			ioapic_set_alloc_attr(&info, NUMA_NO_NODE, 1, polarity);
506*4882a593Smuzhiyun 			ret = mp_map_gsi_to_irq(irq, IOAPIC_MAP_ALLOC, &info);
507*4882a593Smuzhiyun 			WARN_ON(ret < 0);
508*4882a593Smuzhiyun 		}
509*4882a593Smuzhiyun 
510*4882a593Smuzhiyun 		dev = get_device_id(pentry->type, pentry->name);
511*4882a593Smuzhiyun 
512*4882a593Smuzhiyun 		if (!dev)
513*4882a593Smuzhiyun 			continue;
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 		switch (pentry->type) {
516*4882a593Smuzhiyun 		case SFI_DEV_TYPE_IPC:
517*4882a593Smuzhiyun 			sfi_handle_ipc_dev(pentry, dev);
518*4882a593Smuzhiyun 			break;
519*4882a593Smuzhiyun 		case SFI_DEV_TYPE_SPI:
520*4882a593Smuzhiyun 			sfi_handle_spi_dev(pentry, dev);
521*4882a593Smuzhiyun 			break;
522*4882a593Smuzhiyun 		case SFI_DEV_TYPE_I2C:
523*4882a593Smuzhiyun 			sfi_handle_i2c_dev(pentry, dev);
524*4882a593Smuzhiyun 			break;
525*4882a593Smuzhiyun 		case SFI_DEV_TYPE_SD:
526*4882a593Smuzhiyun 			sfi_handle_sd_dev(pentry, dev);
527*4882a593Smuzhiyun 			break;
528*4882a593Smuzhiyun 		case SFI_DEV_TYPE_UART:
529*4882a593Smuzhiyun 		case SFI_DEV_TYPE_HSI:
530*4882a593Smuzhiyun 		default:
531*4882a593Smuzhiyun 			break;
532*4882a593Smuzhiyun 		}
533*4882a593Smuzhiyun 	}
534*4882a593Smuzhiyun 	return 0;
535*4882a593Smuzhiyun }
536*4882a593Smuzhiyun 
intel_mid_platform_init(void)537*4882a593Smuzhiyun static int __init intel_mid_platform_init(void)
538*4882a593Smuzhiyun {
539*4882a593Smuzhiyun 	sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, sfi_parse_gpio);
540*4882a593Smuzhiyun 	sfi_table_parse(SFI_SIG_DEVS, NULL, NULL, sfi_parse_devs);
541*4882a593Smuzhiyun 	return 0;
542*4882a593Smuzhiyun }
543*4882a593Smuzhiyun arch_initcall(intel_mid_platform_init);
544