162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * SPDX-License-Identifier: MIT
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright © 2021 Intel Corporation
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <drm/drm_drv.h>
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include "gem/i915_gem_context.h"
1062306a36Sopenharmony_ci#include "gem/i915_gem_object.h"
1162306a36Sopenharmony_ci#include "i915_active.h"
1262306a36Sopenharmony_ci#include "i915_driver.h"
1362306a36Sopenharmony_ci#include "i915_params.h"
1462306a36Sopenharmony_ci#include "i915_pci.h"
1562306a36Sopenharmony_ci#include "i915_perf.h"
1662306a36Sopenharmony_ci#include "i915_request.h"
1762306a36Sopenharmony_ci#include "i915_scheduler.h"
1862306a36Sopenharmony_ci#include "i915_selftest.h"
1962306a36Sopenharmony_ci#include "i915_vma.h"
2062306a36Sopenharmony_ci#include "i915_vma_resource.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistatic int i915_check_nomodeset(void)
2362306a36Sopenharmony_ci{
2462306a36Sopenharmony_ci	bool use_kms = true;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	/*
2762306a36Sopenharmony_ci	 * Enable KMS by default, unless explicitly overriden by
2862306a36Sopenharmony_ci	 * either the i915.modeset parameter or by the
2962306a36Sopenharmony_ci	 * nomodeset boot option.
3062306a36Sopenharmony_ci	 */
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	if (i915_modparams.modeset == 0)
3362306a36Sopenharmony_ci		use_kms = false;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	if (drm_firmware_drivers_only() && i915_modparams.modeset == -1)
3662306a36Sopenharmony_ci		use_kms = false;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	if (!use_kms) {
3962306a36Sopenharmony_ci		/* Silently fail loading to not upset userspace. */
4062306a36Sopenharmony_ci		DRM_DEBUG_DRIVER("KMS disabled.\n");
4162306a36Sopenharmony_ci		return 1;
4262306a36Sopenharmony_ci	}
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	return 0;
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic const struct {
4862306a36Sopenharmony_ci   int (*init)(void);
4962306a36Sopenharmony_ci   void (*exit)(void);
5062306a36Sopenharmony_ci} init_funcs[] = {
5162306a36Sopenharmony_ci	{ .init = i915_check_nomodeset },
5262306a36Sopenharmony_ci	{ .init = i915_active_module_init,
5362306a36Sopenharmony_ci	  .exit = i915_active_module_exit },
5462306a36Sopenharmony_ci	{ .init = i915_context_module_init,
5562306a36Sopenharmony_ci	  .exit = i915_context_module_exit },
5662306a36Sopenharmony_ci	{ .init = i915_gem_context_module_init,
5762306a36Sopenharmony_ci	  .exit = i915_gem_context_module_exit },
5862306a36Sopenharmony_ci	{ .init = i915_objects_module_init,
5962306a36Sopenharmony_ci	  .exit = i915_objects_module_exit },
6062306a36Sopenharmony_ci	{ .init = i915_request_module_init,
6162306a36Sopenharmony_ci	  .exit = i915_request_module_exit },
6262306a36Sopenharmony_ci	{ .init = i915_scheduler_module_init,
6362306a36Sopenharmony_ci	  .exit = i915_scheduler_module_exit },
6462306a36Sopenharmony_ci	{ .init = i915_vma_module_init,
6562306a36Sopenharmony_ci	  .exit = i915_vma_module_exit },
6662306a36Sopenharmony_ci	{ .init = i915_vma_resource_module_init,
6762306a36Sopenharmony_ci	  .exit = i915_vma_resource_module_exit },
6862306a36Sopenharmony_ci	{ .init = i915_mock_selftests },
6962306a36Sopenharmony_ci	{ .init = i915_pmu_init,
7062306a36Sopenharmony_ci	  .exit = i915_pmu_exit },
7162306a36Sopenharmony_ci	{ .init = i915_pci_register_driver,
7262306a36Sopenharmony_ci	  .exit = i915_pci_unregister_driver },
7362306a36Sopenharmony_ci	{ .init = i915_perf_sysctl_register,
7462306a36Sopenharmony_ci	  .exit = i915_perf_sysctl_unregister },
7562306a36Sopenharmony_ci};
7662306a36Sopenharmony_cistatic int init_progress;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistatic int __init i915_init(void)
7962306a36Sopenharmony_ci{
8062306a36Sopenharmony_ci	int err, i;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(init_funcs); i++) {
8362306a36Sopenharmony_ci		err = init_funcs[i].init();
8462306a36Sopenharmony_ci		if (err < 0) {
8562306a36Sopenharmony_ci			while (i--) {
8662306a36Sopenharmony_ci				if (init_funcs[i].exit)
8762306a36Sopenharmony_ci					init_funcs[i].exit();
8862306a36Sopenharmony_ci			}
8962306a36Sopenharmony_ci			return err;
9062306a36Sopenharmony_ci		} else if (err > 0) {
9162306a36Sopenharmony_ci			/*
9262306a36Sopenharmony_ci			 * Early-exit success is reserved for things which
9362306a36Sopenharmony_ci			 * don't have an exit() function because we have no
9462306a36Sopenharmony_ci			 * idea how far they got or how to partially tear
9562306a36Sopenharmony_ci			 * them down.
9662306a36Sopenharmony_ci			 */
9762306a36Sopenharmony_ci			WARN_ON(init_funcs[i].exit);
9862306a36Sopenharmony_ci			break;
9962306a36Sopenharmony_ci		}
10062306a36Sopenharmony_ci	}
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	init_progress = i;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	return 0;
10562306a36Sopenharmony_ci}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistatic void __exit i915_exit(void)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	int i;
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	for (i = init_progress - 1; i >= 0; i--) {
11262306a36Sopenharmony_ci		GEM_BUG_ON(i >= ARRAY_SIZE(init_funcs));
11362306a36Sopenharmony_ci		if (init_funcs[i].exit)
11462306a36Sopenharmony_ci			init_funcs[i].exit();
11562306a36Sopenharmony_ci	}
11662306a36Sopenharmony_ci}
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_cimodule_init(i915_init);
11962306a36Sopenharmony_cimodule_exit(i915_exit);
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ciMODULE_AUTHOR("Tungsten Graphics, Inc.");
12262306a36Sopenharmony_ciMODULE_AUTHOR("Intel Corporation");
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciMODULE_DESCRIPTION(DRIVER_DESC);
12562306a36Sopenharmony_ciMODULE_LICENSE("GPL and additional rights");
126