Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-v5.15/omap-gpmc' into for-next

+118 -81
-5
arch/arm/mach-omap2/pm34xx.c
··· 26 26 #include <linux/delay.h> 27 27 #include <linux/slab.h> 28 28 #include <linux/of.h> 29 - #include <linux/omap-gpmc.h> 30 29 31 30 #include <trace/events/power.h> 32 31 ··· 80 81 81 82 /* Save the Interrupt controller context */ 82 83 omap_intc_save_context(); 83 - /* Save the GPMC context */ 84 - omap3_gpmc_save_context(); 85 84 /* Save the system control module context, padconf already save above*/ 86 85 omap3_control_save_context(); 87 86 } ··· 88 91 { 89 92 /* Restore the control module context, padconf restored by h/w */ 90 93 omap3_control_restore_context(); 91 - /* Restore the GPMC context */ 92 - omap3_gpmc_restore_context(); 93 94 /* Restore the interrupt controller context */ 94 95 omap_intc_restore_context(); 95 96 }
+118 -73
drivers/memory/omap-gpmc.c
··· 9 9 * Copyright (C) 2009 Texas Instruments 10 10 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com> 11 11 */ 12 + #include <linux/cpu_pm.h> 12 13 #include <linux/irq.h> 13 14 #include <linux/kernel.h> 14 15 #include <linux/init.h> ··· 233 232 int irq; 234 233 struct irq_chip irq_chip; 235 234 struct gpio_chip gpio_chip; 235 + struct notifier_block nb; 236 + struct omap3_gpmc_regs context; 236 237 int nirqs; 238 + unsigned int is_suspended:1; 237 239 }; 238 240 239 241 static struct irq_domain *gpmc_irq_domain; ··· 2388 2384 return 0; 2389 2385 } 2390 2386 2387 + static void omap3_gpmc_save_context(struct gpmc_device *gpmc) 2388 + { 2389 + struct omap3_gpmc_regs *gpmc_context; 2390 + int i; 2391 + 2392 + if (!gpmc || !gpmc_base) 2393 + return; 2394 + 2395 + gpmc_context = &gpmc->context; 2396 + 2397 + gpmc_context->sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); 2398 + gpmc_context->irqenable = gpmc_read_reg(GPMC_IRQENABLE); 2399 + gpmc_context->timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); 2400 + gpmc_context->config = gpmc_read_reg(GPMC_CONFIG); 2401 + gpmc_context->prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); 2402 + gpmc_context->prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); 2403 + gpmc_context->prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); 2404 + for (i = 0; i < gpmc_cs_num; i++) { 2405 + gpmc_context->cs_context[i].is_valid = gpmc_cs_mem_enabled(i); 2406 + if (gpmc_context->cs_context[i].is_valid) { 2407 + gpmc_context->cs_context[i].config1 = 2408 + gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); 2409 + gpmc_context->cs_context[i].config2 = 2410 + gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); 2411 + gpmc_context->cs_context[i].config3 = 2412 + gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); 2413 + gpmc_context->cs_context[i].config4 = 2414 + gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); 2415 + gpmc_context->cs_context[i].config5 = 2416 + gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); 2417 + gpmc_context->cs_context[i].config6 = 2418 + gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); 2419 + gpmc_context->cs_context[i].config7 = 2420 + gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); 2421 + } 2422 + } 2423 + } 2424 + 2425 + static void omap3_gpmc_restore_context(struct gpmc_device *gpmc) 2426 + { 2427 + struct omap3_gpmc_regs *gpmc_context; 2428 + int i; 2429 + 2430 + if (!gpmc || !gpmc_base) 2431 + return; 2432 + 2433 + gpmc_context = &gpmc->context; 2434 + 2435 + gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context->sysconfig); 2436 + gpmc_write_reg(GPMC_IRQENABLE, gpmc_context->irqenable); 2437 + gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context->timeout_ctrl); 2438 + gpmc_write_reg(GPMC_CONFIG, gpmc_context->config); 2439 + gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context->prefetch_config1); 2440 + gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context->prefetch_config2); 2441 + gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context->prefetch_control); 2442 + for (i = 0; i < gpmc_cs_num; i++) { 2443 + if (gpmc_context->cs_context[i].is_valid) { 2444 + gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, 2445 + gpmc_context->cs_context[i].config1); 2446 + gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, 2447 + gpmc_context->cs_context[i].config2); 2448 + gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, 2449 + gpmc_context->cs_context[i].config3); 2450 + gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, 2451 + gpmc_context->cs_context[i].config4); 2452 + gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, 2453 + gpmc_context->cs_context[i].config5); 2454 + gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, 2455 + gpmc_context->cs_context[i].config6); 2456 + gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, 2457 + gpmc_context->cs_context[i].config7); 2458 + } else { 2459 + gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, 0); 2460 + } 2461 + } 2462 + } 2463 + 2464 + static int omap_gpmc_context_notifier(struct notifier_block *nb, 2465 + unsigned long cmd, void *v) 2466 + { 2467 + struct gpmc_device *gpmc; 2468 + 2469 + gpmc = container_of(nb, struct gpmc_device, nb); 2470 + if (gpmc->is_suspended || pm_runtime_suspended(gpmc->dev)) 2471 + return NOTIFY_OK; 2472 + 2473 + switch (cmd) { 2474 + case CPU_CLUSTER_PM_ENTER: 2475 + omap3_gpmc_save_context(gpmc); 2476 + break; 2477 + case CPU_CLUSTER_PM_ENTER_FAILED: /* No need to restore context */ 2478 + break; 2479 + case CPU_CLUSTER_PM_EXIT: 2480 + omap3_gpmc_restore_context(gpmc); 2481 + break; 2482 + } 2483 + 2484 + return NOTIFY_OK; 2485 + } 2486 + 2391 2487 static int gpmc_probe(struct platform_device *pdev) 2392 2488 { 2393 2489 int rc; ··· 2576 2472 2577 2473 gpmc_probe_dt_children(pdev); 2578 2474 2475 + gpmc->nb.notifier_call = omap_gpmc_context_notifier; 2476 + cpu_pm_register_notifier(&gpmc->nb); 2477 + 2579 2478 return 0; 2580 2479 2581 2480 gpio_init_failed: ··· 2593 2486 { 2594 2487 struct gpmc_device *gpmc = platform_get_drvdata(pdev); 2595 2488 2489 + cpu_pm_unregister_notifier(&gpmc->nb); 2596 2490 gpmc_free_irq(gpmc); 2597 2491 gpmc_mem_exit(); 2598 2492 pm_runtime_put_sync(&pdev->dev); ··· 2605 2497 #ifdef CONFIG_PM_SLEEP 2606 2498 static int gpmc_suspend(struct device *dev) 2607 2499 { 2608 - omap3_gpmc_save_context(); 2500 + struct gpmc_device *gpmc = dev_get_drvdata(dev); 2501 + 2502 + omap3_gpmc_save_context(gpmc); 2609 2503 pm_runtime_put_sync(dev); 2504 + gpmc->is_suspended = 1; 2505 + 2610 2506 return 0; 2611 2507 } 2612 2508 2613 2509 static int gpmc_resume(struct device *dev) 2614 2510 { 2511 + struct gpmc_device *gpmc = dev_get_drvdata(dev); 2512 + 2615 2513 pm_runtime_get_sync(dev); 2616 - omap3_gpmc_restore_context(); 2514 + omap3_gpmc_restore_context(gpmc); 2515 + gpmc->is_suspended = 0; 2516 + 2617 2517 return 0; 2618 2518 } 2619 2519 #endif ··· 2643 2527 return platform_driver_register(&gpmc_driver); 2644 2528 } 2645 2529 postcore_initcall(gpmc_init); 2646 - 2647 - static struct omap3_gpmc_regs gpmc_context; 2648 - 2649 - void omap3_gpmc_save_context(void) 2650 - { 2651 - int i; 2652 - 2653 - if (!gpmc_base) 2654 - return; 2655 - 2656 - gpmc_context.sysconfig = gpmc_read_reg(GPMC_SYSCONFIG); 2657 - gpmc_context.irqenable = gpmc_read_reg(GPMC_IRQENABLE); 2658 - gpmc_context.timeout_ctrl = gpmc_read_reg(GPMC_TIMEOUT_CONTROL); 2659 - gpmc_context.config = gpmc_read_reg(GPMC_CONFIG); 2660 - gpmc_context.prefetch_config1 = gpmc_read_reg(GPMC_PREFETCH_CONFIG1); 2661 - gpmc_context.prefetch_config2 = gpmc_read_reg(GPMC_PREFETCH_CONFIG2); 2662 - gpmc_context.prefetch_control = gpmc_read_reg(GPMC_PREFETCH_CONTROL); 2663 - for (i = 0; i < gpmc_cs_num; i++) { 2664 - gpmc_context.cs_context[i].is_valid = gpmc_cs_mem_enabled(i); 2665 - if (gpmc_context.cs_context[i].is_valid) { 2666 - gpmc_context.cs_context[i].config1 = 2667 - gpmc_cs_read_reg(i, GPMC_CS_CONFIG1); 2668 - gpmc_context.cs_context[i].config2 = 2669 - gpmc_cs_read_reg(i, GPMC_CS_CONFIG2); 2670 - gpmc_context.cs_context[i].config3 = 2671 - gpmc_cs_read_reg(i, GPMC_CS_CONFIG3); 2672 - gpmc_context.cs_context[i].config4 = 2673 - gpmc_cs_read_reg(i, GPMC_CS_CONFIG4); 2674 - gpmc_context.cs_context[i].config5 = 2675 - gpmc_cs_read_reg(i, GPMC_CS_CONFIG5); 2676 - gpmc_context.cs_context[i].config6 = 2677 - gpmc_cs_read_reg(i, GPMC_CS_CONFIG6); 2678 - gpmc_context.cs_context[i].config7 = 2679 - gpmc_cs_read_reg(i, GPMC_CS_CONFIG7); 2680 - } 2681 - } 2682 - } 2683 - 2684 - void omap3_gpmc_restore_context(void) 2685 - { 2686 - int i; 2687 - 2688 - if (!gpmc_base) 2689 - return; 2690 - 2691 - gpmc_write_reg(GPMC_SYSCONFIG, gpmc_context.sysconfig); 2692 - gpmc_write_reg(GPMC_IRQENABLE, gpmc_context.irqenable); 2693 - gpmc_write_reg(GPMC_TIMEOUT_CONTROL, gpmc_context.timeout_ctrl); 2694 - gpmc_write_reg(GPMC_CONFIG, gpmc_context.config); 2695 - gpmc_write_reg(GPMC_PREFETCH_CONFIG1, gpmc_context.prefetch_config1); 2696 - gpmc_write_reg(GPMC_PREFETCH_CONFIG2, gpmc_context.prefetch_config2); 2697 - gpmc_write_reg(GPMC_PREFETCH_CONTROL, gpmc_context.prefetch_control); 2698 - for (i = 0; i < gpmc_cs_num; i++) { 2699 - if (gpmc_context.cs_context[i].is_valid) { 2700 - gpmc_cs_write_reg(i, GPMC_CS_CONFIG1, 2701 - gpmc_context.cs_context[i].config1); 2702 - gpmc_cs_write_reg(i, GPMC_CS_CONFIG2, 2703 - gpmc_context.cs_context[i].config2); 2704 - gpmc_cs_write_reg(i, GPMC_CS_CONFIG3, 2705 - gpmc_context.cs_context[i].config3); 2706 - gpmc_cs_write_reg(i, GPMC_CS_CONFIG4, 2707 - gpmc_context.cs_context[i].config4); 2708 - gpmc_cs_write_reg(i, GPMC_CS_CONFIG5, 2709 - gpmc_context.cs_context[i].config5); 2710 - gpmc_cs_write_reg(i, GPMC_CS_CONFIG6, 2711 - gpmc_context.cs_context[i].config6); 2712 - gpmc_cs_write_reg(i, GPMC_CS_CONFIG7, 2713 - gpmc_context.cs_context[i].config7); 2714 - } 2715 - } 2716 - }
-3
include/linux/omap-gpmc.h
··· 81 81 extern void gpmc_read_settings_dt(struct device_node *np, 82 82 struct gpmc_settings *p); 83 83 84 - extern void omap3_gpmc_save_context(void); 85 - extern void omap3_gpmc_restore_context(void); 86 - 87 84 struct gpmc_timings; 88 85 struct omap_nand_platform_data; 89 86 struct omap_onenand_platform_data;