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