aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform/intel-mid/intel-mid.c
diff options
context:
space:
mode:
authorDavid Cohen <david.a.cohen@linux.intel.com>2013-10-17 18:35:36 -0400
committerH. Peter Anvin <hpa@linux.intel.com>2013-10-17 19:41:50 -0400
commit40a96d54ee2232045783e657eb9224cd723dcb40 (patch)
tree917d337e1b724744cee6ca7610187a821e374a8a /arch/x86/platform/intel-mid/intel-mid.c
parent66ac50137049b3d3fab39e5ae245e1562aee5acd (diff)
intel_mid: Move platform device setups to their own platform_<device>.* files
As Intel rolling out more SoC's after Moorestown, we need to re-structure the code in a way that is backward compatible and easy to expand. This patch implements a flexible way to support multiple boards and devices. This patch does not add any new functional support. It just refactors the existing code to increase the modularity and decrease the code duplication for supporting multiple soc's and boards. Currently intel-mid.c has both board and soc related code in one file. This patch moves the board related code to new files and let linker script to create SFI devite table following this: 1. Move the SFI device specific code to arch/x86/platform/intel-mid/device-libs/platform_<device>.* A new device file is added for every supported device. This code will get conditionally compiled by using corresponding device driver CONFIG option. 2. Move the device_ids location to .x86_intel_mid_dev.init section by using new sfi_device() macro. This patch was based on previous code from Sathyanarayanan Kuppuswamy. Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Link: http://lkml.kernel.org/r/1382049336-21316-13-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/intel-mid/intel-mid.c')
-rw-r--r--arch/x86/platform/intel-mid/intel-mid.c419
1 files changed, 0 insertions, 419 deletions
diff --git a/arch/x86/platform/intel-mid/intel-mid.c b/arch/x86/platform/intel-mid/intel-mid.c
index 40915698b9b7..523a1c8f7f07 100644
--- a/arch/x86/platform/intel-mid/intel-mid.c
+++ b/arch/x86/platform/intel-mid/intel-mid.c
@@ -61,8 +61,6 @@ enum intel_mid_timer_options intel_mid_timer_options;
61enum intel_mid_cpu_type __intel_mid_cpu_chip; 61enum intel_mid_cpu_type __intel_mid_cpu_chip;
62EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip); 62EXPORT_SYMBOL_GPL(__intel_mid_cpu_chip);
63 63
64static void __init ipc_device_handler(struct sfi_device_table_entry *pentry,
65 struct devs_id *dev);
66static void intel_mid_power_off(void) 64static void intel_mid_power_off(void)
67{ 65{
68} 66}
@@ -213,420 +211,3 @@ static inline int __init setup_x86_intel_mid_timer(char *arg)
213} 211}
214__setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer); 212__setup("x86_intel_mid_timer=", setup_x86_intel_mid_timer);
215 213
216/* the offset for the mapping of global gpio pin to irq */
217#define INTEL_MID_IRQ_OFFSET 0x100
218
219static void __init *pmic_gpio_platform_data(void *info)
220{
221 static struct intel_pmic_gpio_platform_data pmic_gpio_pdata;
222 int gpio_base = get_gpio_by_name("pmic_gpio_base");
223
224 if (gpio_base == -1)
225 gpio_base = 64;
226 pmic_gpio_pdata.gpio_base = gpio_base;
227 pmic_gpio_pdata.irq_base = gpio_base + INTEL_MID_IRQ_OFFSET;
228 pmic_gpio_pdata.gpiointr = 0xffffeff8;
229
230 return &pmic_gpio_pdata;
231}
232
233static void __init *max3111_platform_data(void *info)
234{
235 struct spi_board_info *spi_info = info;
236 int intr = get_gpio_by_name("max3111_int");
237
238 spi_info->mode = SPI_MODE_0;
239 if (intr == -1)
240 return NULL;
241 spi_info->irq = intr + INTEL_MID_IRQ_OFFSET;
242 return NULL;
243}
244
245/* we have multiple max7315 on the board ... */
246#define MAX7315_NUM 2
247static void __init *max7315_platform_data(void *info)
248{
249 static struct pca953x_platform_data max7315_pdata[MAX7315_NUM];
250 static int nr;
251 struct pca953x_platform_data *max7315 = &max7315_pdata[nr];
252 struct i2c_board_info *i2c_info = info;
253 int gpio_base, intr;
254 char base_pin_name[SFI_NAME_LEN + 1];
255 char intr_pin_name[SFI_NAME_LEN + 1];
256
257 if (nr == MAX7315_NUM) {
258 pr_err("too many max7315s, we only support %d\n",
259 MAX7315_NUM);
260 return NULL;
261 }
262 /* we have several max7315 on the board, we only need load several
263 * instances of the same pca953x driver to cover them
264 */
265 strcpy(i2c_info->type, "max7315");
266 if (nr++) {
267 sprintf(base_pin_name, "max7315_%d_base", nr);
268 sprintf(intr_pin_name, "max7315_%d_int", nr);
269 } else {
270 strcpy(base_pin_name, "max7315_base");
271 strcpy(intr_pin_name, "max7315_int");
272 }
273
274 gpio_base = get_gpio_by_name(base_pin_name);
275 intr = get_gpio_by_name(intr_pin_name);
276
277 if (gpio_base == -1)
278 return NULL;
279 max7315->gpio_base = gpio_base;
280 if (intr != -1) {
281 i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
282 max7315->irq_base = gpio_base + INTEL_MID_IRQ_OFFSET;
283 } else {
284 i2c_info->irq = -1;
285 max7315->irq_base = -1;
286 }
287 return max7315;
288}
289
290static void *tca6416_platform_data(void *info)
291{
292 static struct pca953x_platform_data tca6416;
293 struct i2c_board_info *i2c_info = info;
294 int gpio_base, intr;
295 char base_pin_name[SFI_NAME_LEN + 1];
296 char intr_pin_name[SFI_NAME_LEN + 1];
297
298 strcpy(i2c_info->type, "tca6416");
299 strcpy(base_pin_name, "tca6416_base");
300 strcpy(intr_pin_name, "tca6416_int");
301
302 gpio_base = get_gpio_by_name(base_pin_name);
303 intr = get_gpio_by_name(intr_pin_name);
304
305 if (gpio_base == -1)
306 return NULL;
307 tca6416.gpio_base = gpio_base;
308 if (intr != -1) {
309 i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
310 tca6416.irq_base = gpio_base + INTEL_MID_IRQ_OFFSET;
311 } else {
312 i2c_info->irq = -1;
313 tca6416.irq_base = -1;
314 }
315 return &tca6416;
316}
317
318static void *mpu3050_platform_data(void *info)
319{
320 struct i2c_board_info *i2c_info = info;
321 int intr = get_gpio_by_name("mpu3050_int");
322
323 if (intr == -1)
324 return NULL;
325
326 i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
327 return NULL;
328}
329
330static void __init *emc1403_platform_data(void *info)
331{
332 static short intr2nd_pdata;
333 struct i2c_board_info *i2c_info = info;
334 int intr = get_gpio_by_name("thermal_int");
335 int intr2nd = get_gpio_by_name("thermal_alert");
336
337 if (intr == -1 || intr2nd == -1)
338 return NULL;
339
340 i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
341 intr2nd_pdata = intr2nd + INTEL_MID_IRQ_OFFSET;
342
343 return &intr2nd_pdata;
344}
345
346static void __init *lis331dl_platform_data(void *info)
347{
348 static short intr2nd_pdata;
349 struct i2c_board_info *i2c_info = info;
350 int intr = get_gpio_by_name("accel_int");
351 int intr2nd = get_gpio_by_name("accel_2");
352
353 if (intr == -1 || intr2nd == -1)
354 return NULL;
355
356 i2c_info->irq = intr + INTEL_MID_IRQ_OFFSET;
357 intr2nd_pdata = intr2nd + INTEL_MID_IRQ_OFFSET;
358
359 return &intr2nd_pdata;
360}
361
362static void __init *no_platform_data(void *info)
363{
364 return NULL;
365}
366
367static struct resource msic_resources[] = {
368 {
369 .start = INTEL_MSIC_IRQ_PHYS_BASE,
370 .end = INTEL_MSIC_IRQ_PHYS_BASE + 64 - 1,
371 .flags = IORESOURCE_MEM,
372 },
373};
374
375static struct intel_msic_platform_data msic_pdata;
376
377static struct platform_device msic_device = {
378 .name = "intel_msic",
379 .id = -1,
380 .dev = {
381 .platform_data = &msic_pdata,
382 },
383 .num_resources = ARRAY_SIZE(msic_resources),
384 .resource = msic_resources,
385};
386
387static inline bool intel_mid_has_msic(void)
388{
389 return intel_mid_identify_cpu() == INTEL_MID_CPU_CHIP_PENWELL;
390}
391
392static int msic_scu_status_change(struct notifier_block *nb,
393 unsigned long code, void *data)
394{
395 if (code == SCU_DOWN) {
396 platform_device_unregister(&msic_device);
397 return 0;
398 }
399
400 return platform_device_register(&msic_device);
401}
402
403static int __init msic_init(void)
404{
405 static struct notifier_block msic_scu_notifier = {
406 .notifier_call = msic_scu_status_change,
407 };
408
409 /*
410 * We need to be sure that the SCU IPC is ready before MSIC device
411 * can be registered.
412 */
413 if (intel_mid_has_msic())
414 intel_scu_notifier_add(&msic_scu_notifier);
415
416 return 0;
417}
418arch_initcall(msic_init);
419
420/*
421 * msic_generic_platform_data - sets generic platform data for the block
422 * @info: pointer to the SFI device table entry for this block
423 * @block: MSIC block
424 *
425 * Function sets IRQ number from the SFI table entry for given device to
426 * the MSIC platform data.
427 */
428static void *msic_generic_platform_data(void *info, enum intel_msic_block block)
429{
430 struct sfi_device_table_entry *entry = info;
431
432 BUG_ON(block < 0 || block >= INTEL_MSIC_BLOCK_LAST);
433 msic_pdata.irq[block] = entry->irq;
434
435 return no_platform_data(info);
436}
437
438static void *msic_battery_platform_data(void *info)
439{
440 return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_BATTERY);
441}
442
443static void *msic_gpio_platform_data(void *info)
444{
445 static struct intel_msic_gpio_pdata pdata;
446 int gpio = get_gpio_by_name("msic_gpio_base");
447
448 if (gpio < 0)
449 return NULL;
450
451 pdata.gpio_base = gpio;
452 msic_pdata.gpio = &pdata;
453
454 return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_GPIO);
455}
456
457static void *msic_audio_platform_data(void *info)
458{
459 struct platform_device *pdev;
460
461 pdev = platform_device_register_simple("sst-platform", -1, NULL, 0);
462 if (IS_ERR(pdev)) {
463 pr_err("failed to create audio platform device\n");
464 return NULL;
465 }
466
467 return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_AUDIO);
468}
469
470static void *msic_power_btn_platform_data(void *info)
471{
472 return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_POWER_BTN);
473}
474
475static void *msic_ocd_platform_data(void *info)
476{
477 static struct intel_msic_ocd_pdata pdata;
478 int gpio = get_gpio_by_name("ocd_gpio");
479
480 if (gpio < 0)
481 return NULL;
482
483 pdata.gpio = gpio;
484 msic_pdata.ocd = &pdata;
485
486 return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_OCD);
487}
488
489static void *msic_thermal_platform_data(void *info)
490{
491 return msic_generic_platform_data(info, INTEL_MSIC_BLOCK_THERMAL);
492}
493
494/* tc35876x DSI-LVDS bridge chip and panel platform data */
495static void *tc35876x_platform_data(void *data)
496{
497 static struct tc35876x_platform_data pdata;
498
499 /* gpio pins set to -1 will not be used by the driver */
500 pdata.gpio_bridge_reset = get_gpio_by_name("LCMB_RXEN");
501 pdata.gpio_panel_bl_en = get_gpio_by_name("6S6P_BL_EN");
502 pdata.gpio_panel_vadd = get_gpio_by_name("EN_VREG_LCD_V3P3");
503
504 return &pdata;
505}
506
507static const struct devs_id __initconst device_ids[] = {
508 {"bma023", SFI_DEV_TYPE_I2C, 1, &no_platform_data, NULL},
509 {"pmic_gpio", SFI_DEV_TYPE_SPI, 1, &pmic_gpio_platform_data, NULL},
510 {"pmic_gpio", SFI_DEV_TYPE_IPC, 1, &pmic_gpio_platform_data, &ipc_device_handler},
511 {"spi_max3111", SFI_DEV_TYPE_SPI, 0, &max3111_platform_data, NULL},
512 {"i2c_max7315", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data, NULL},
513 {"i2c_max7315_2", SFI_DEV_TYPE_I2C, 1, &max7315_platform_data, NULL},
514 {"tca6416", SFI_DEV_TYPE_I2C, 1, &tca6416_platform_data, NULL},
515 {"emc1403", SFI_DEV_TYPE_I2C, 1, &emc1403_platform_data, NULL},
516 {"i2c_accel", SFI_DEV_TYPE_I2C, 0, &lis331dl_platform_data, NULL},
517 {"pmic_audio", SFI_DEV_TYPE_IPC, 1, &no_platform_data, &ipc_device_handler},
518 {"mpu3050", SFI_DEV_TYPE_I2C, 1, &mpu3050_platform_data, NULL},
519 {"i2c_disp_brig", SFI_DEV_TYPE_I2C, 0, &tc35876x_platform_data, NULL},
520
521 /* MSIC subdevices */
522 {"msic_battery", SFI_DEV_TYPE_IPC, 1, &msic_battery_platform_data, &ipc_device_handler},
523 {"msic_gpio", SFI_DEV_TYPE_IPC, 1, &msic_gpio_platform_data, &ipc_device_handler},
524 {"msic_audio", SFI_DEV_TYPE_IPC, 1, &msic_audio_platform_data, &ipc_device_handler},
525 {"msic_power_btn", SFI_DEV_TYPE_IPC, 1, &msic_power_btn_platform_data, &ipc_device_handler},
526 {"msic_ocd", SFI_DEV_TYPE_IPC, 1, &msic_ocd_platform_data, &ipc_device_handler},
527 {"msic_thermal", SFI_DEV_TYPE_IPC, 1, &msic_thermal_platform_data, &ipc_device_handler},
528 { 0 }
529};
530
531static void __init ipc_device_handler(struct sfi_device_table_entry *pentry,
532 struct devs_id *dev)
533{
534 struct platform_device *pdev;
535 void *pdata = NULL;
536 static struct resource res __initdata = {
537 .name = "IRQ",
538 .flags = IORESOURCE_IRQ,
539 };
540
541 pr_debug("IPC bus, name = %16.16s, irq = 0x%2x\n",
542 pentry->name, pentry->irq);
543
544 /*
545 * We need to call platform init of IPC devices to fill misc_pdata
546 * structure. It will be used in msic_init for initialization.
547 */
548 if (dev != NULL)
549 pdata = dev->get_platform_data(pentry);
550
551 /*
552 * On Medfield the platform device creation is handled by the MSIC
553 * MFD driver so we don't need to do it here.
554 */
555 if (intel_mid_has_msic())
556 return;
557
558 pdev = platform_device_alloc(pentry->name, 0);
559 if (pdev == NULL) {
560 pr_err("out of memory for SFI platform device '%s'.\n",
561 pentry->name);
562 return;
563 }
564 res.start = pentry->irq;
565 platform_device_add_resources(pdev, &res, 1);
566
567 pdev->dev.platform_data = pdata;
568 intel_scu_device_register(pdev);
569}
570
571
572/*
573 * we will search these buttons in SFI GPIO table (by name)
574 * and register them dynamically. Please add all possible
575 * buttons here, we will shrink them if no GPIO found.
576 */
577static struct gpio_keys_button gpio_button[] = {
578 {KEY_POWER, -1, 1, "power_btn", EV_KEY, 0, 3000},
579 {KEY_PROG1, -1, 1, "prog_btn1", EV_KEY, 0, 20},
580 {KEY_PROG2, -1, 1, "prog_btn2", EV_KEY, 0, 20},
581 {SW_LID, -1, 1, "lid_switch", EV_SW, 0, 20},
582 {KEY_VOLUMEUP, -1, 1, "vol_up", EV_KEY, 0, 20},
583 {KEY_VOLUMEDOWN, -1, 1, "vol_down", EV_KEY, 0, 20},
584 {KEY_CAMERA, -1, 1, "camera_full", EV_KEY, 0, 20},
585 {KEY_CAMERA_FOCUS, -1, 1, "camera_half", EV_KEY, 0, 20},
586 {SW_KEYPAD_SLIDE, -1, 1, "MagSw1", EV_SW, 0, 20},
587 {SW_KEYPAD_SLIDE, -1, 1, "MagSw2", EV_SW, 0, 20},
588};
589
590static struct gpio_keys_platform_data intel_mid_gpio_keys = {
591 .buttons = gpio_button,
592 .rep = 1,
593 .nbuttons = -1, /* will fill it after search */
594};
595
596static struct platform_device pb_device = {
597 .name = "gpio-keys",
598 .id = -1,
599 .dev = {
600 .platform_data = &intel_mid_gpio_keys,
601 },
602};
603
604/*
605 * Shrink the non-existent buttons, register the gpio button
606 * device if there is some
607 */
608static int __init pb_keys_init(void)
609{
610 struct gpio_keys_button *gb = gpio_button;
611 int i, num, good = 0;
612
613 num = sizeof(gpio_button) / sizeof(struct gpio_keys_button);
614 for (i = 0; i < num; i++) {
615 gb[i].gpio = get_gpio_by_name(gb[i].desc);
616 pr_debug("info[%2d]: name = %s, gpio = %d\n", i, gb[i].desc,
617 gb[i].gpio);
618 if (gb[i].gpio == -1)
619 continue;
620
621 if (i != good)
622 gb[good] = gb[i];
623 good++;
624 }
625
626 if (good) {
627 intel_mid_gpio_keys.nbuttons = good;
628 return platform_device_register(&pb_device);
629 }
630 return 0;
631}
632late_initcall(pb_keys_init); \ No newline at end of file