@@ -250,11 +250,37 @@ struct opregion_asle_ext {
250250
251251#define MAX_DSLP 1500
252252
253+ #define OPREGION_SIZE (8 * 1024)
254+
255+ struct intel_opregion {
256+ struct drm_i915_private * i915 ;
257+
258+ struct opregion_header * header ;
259+ struct opregion_acpi * acpi ;
260+ struct opregion_swsci * swsci ;
261+ u32 swsci_gbda_sub_functions ;
262+ u32 swsci_sbcb_sub_functions ;
263+ struct opregion_asle * asle ;
264+ struct opregion_asle_ext * asle_ext ;
265+ void * rvda ;
266+ void * vbt_firmware ;
267+ const void * vbt ;
268+ u32 vbt_size ;
269+ u32 * lid_state ;
270+ struct work_struct asle_work ;
271+ struct notifier_block acpi_notifier ;
272+ };
273+
253274static int check_swsci_function (struct drm_i915_private * i915 , u32 function )
254275{
255- struct opregion_swsci * swsci = i915 -> display .opregion .swsci ;
276+ struct intel_opregion * opregion = i915 -> display .opregion ;
277+ struct opregion_swsci * swsci ;
256278 u32 main_function , sub_function ;
257279
280+ if (!opregion )
281+ return - ENODEV ;
282+
283+ swsci = opregion -> swsci ;
258284 if (!swsci )
259285 return - ENODEV ;
260286
@@ -265,11 +291,11 @@ static int check_swsci_function(struct drm_i915_private *i915, u32 function)
265291
266292 /* Check if we can call the function. See swsci_setup for details. */
267293 if (main_function == SWSCI_SBCB ) {
268- if ((i915 -> display . opregion . swsci_sbcb_sub_functions &
294+ if ((opregion -> swsci_sbcb_sub_functions &
269295 (1 << sub_function )) == 0 )
270296 return - EINVAL ;
271297 } else if (main_function == SWSCI_GBDA ) {
272- if ((i915 -> display . opregion . swsci_gbda_sub_functions &
298+ if ((opregion -> swsci_gbda_sub_functions &
273299 (1 << sub_function )) == 0 )
274300 return - EINVAL ;
275301 }
@@ -280,7 +306,7 @@ static int check_swsci_function(struct drm_i915_private *i915, u32 function)
280306static int swsci (struct drm_i915_private * dev_priv ,
281307 u32 function , u32 parm , u32 * parm_out )
282308{
283- struct opregion_swsci * swsci = dev_priv -> display . opregion . swsci ;
309+ struct opregion_swsci * swsci ;
284310 struct pci_dev * pdev = to_pci_dev (dev_priv -> drm .dev );
285311 u32 scic , dslp ;
286312 u16 swsci_val ;
@@ -290,6 +316,8 @@ static int swsci(struct drm_i915_private *dev_priv,
290316 if (ret )
291317 return ret ;
292318
319+ swsci = dev_priv -> display .opregion -> swsci ;
320+
293321 /* Driver sleep timeout in ms. */
294322 dslp = swsci -> dslp ;
295323 if (!dslp ) {
@@ -462,7 +490,7 @@ static u32 asle_set_backlight(struct drm_i915_private *dev_priv, u32 bclp)
462490{
463491 struct intel_connector * connector ;
464492 struct drm_connector_list_iter conn_iter ;
465- struct opregion_asle * asle = dev_priv -> display .opregion . asle ;
493+ struct opregion_asle * asle = dev_priv -> display .opregion -> asle ;
466494
467495 drm_dbg (& dev_priv -> drm , "bclp = 0x%08x\n" , bclp );
468496
@@ -584,9 +612,8 @@ static void asle_work(struct work_struct *work)
584612{
585613 struct intel_opregion * opregion =
586614 container_of (work , struct intel_opregion , asle_work );
587- struct drm_i915_private * dev_priv =
588- container_of (opregion , struct drm_i915_private , display .opregion );
589- struct opregion_asle * asle = dev_priv -> display .opregion .asle ;
615+ struct drm_i915_private * dev_priv = opregion -> i915 ;
616+ struct opregion_asle * asle = opregion -> asle ;
590617 u32 aslc_stat = 0 ;
591618 u32 aslc_req ;
592619
@@ -634,14 +661,15 @@ static void asle_work(struct work_struct *work)
634661
635662bool intel_opregion_asle_present (struct drm_i915_private * i915 )
636663{
637- return i915 -> display .opregion . asle ;
664+ return i915 -> display .opregion && i915 -> display . opregion -> asle ;
638665}
639666
640- void intel_opregion_asle_intr (struct drm_i915_private * dev_priv )
667+ void intel_opregion_asle_intr (struct drm_i915_private * i915 )
641668{
642- if (dev_priv -> display .opregion .asle )
643- queue_work (dev_priv -> unordered_wq ,
644- & dev_priv -> display .opregion .asle_work );
669+ struct intel_opregion * opregion = i915 -> display .opregion ;
670+
671+ if (opregion && opregion -> asle )
672+ queue_work (i915 -> unordered_wq , & opregion -> asle_work );
645673}
646674
647675#define ACPI_EV_DISPLAY_SWITCH (1<<0)
@@ -697,7 +725,7 @@ static void set_did(struct intel_opregion *opregion, int i, u32 val)
697725
698726static void intel_didl_outputs (struct drm_i915_private * dev_priv )
699727{
700- struct intel_opregion * opregion = & dev_priv -> display .opregion ;
728+ struct intel_opregion * opregion = dev_priv -> display .opregion ;
701729 struct intel_connector * connector ;
702730 struct drm_connector_list_iter conn_iter ;
703731 int i = 0 , max_outputs ;
@@ -736,7 +764,7 @@ static void intel_didl_outputs(struct drm_i915_private *dev_priv)
736764
737765static void intel_setup_cadls (struct drm_i915_private * dev_priv )
738766{
739- struct intel_opregion * opregion = & dev_priv -> display .opregion ;
767+ struct intel_opregion * opregion = dev_priv -> display .opregion ;
740768 struct intel_connector * connector ;
741769 struct drm_connector_list_iter conn_iter ;
742770 int i = 0 ;
@@ -766,7 +794,7 @@ static void intel_setup_cadls(struct drm_i915_private *dev_priv)
766794
767795static void swsci_setup (struct drm_i915_private * dev_priv )
768796{
769- struct intel_opregion * opregion = & dev_priv -> display .opregion ;
797+ struct intel_opregion * opregion = dev_priv -> display .opregion ;
770798 bool requested_callbacks = false;
771799 u32 tmp ;
772800
@@ -844,7 +872,7 @@ static const struct dmi_system_id intel_no_opregion_vbt[] = {
844872
845873static int intel_load_vbt_firmware (struct drm_i915_private * dev_priv )
846874{
847- struct intel_opregion * opregion = & dev_priv -> display .opregion ;
875+ struct intel_opregion * opregion = dev_priv -> display .opregion ;
848876 const struct firmware * fw = NULL ;
849877 const char * name = dev_priv -> display .params .vbt_firmware ;
850878 int ret ;
@@ -884,7 +912,7 @@ static int intel_load_vbt_firmware(struct drm_i915_private *dev_priv)
884912
885913int intel_opregion_setup (struct drm_i915_private * dev_priv )
886914{
887- struct intel_opregion * opregion = & dev_priv -> display . opregion ;
915+ struct intel_opregion * opregion ;
888916 struct pci_dev * pdev = to_pci_dev (dev_priv -> drm .dev );
889917 u32 asls , mboxes ;
890918 char buf [sizeof (OPREGION_SIGNATURE )];
@@ -907,11 +935,20 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
907935 return - ENOTSUPP ;
908936 }
909937
938+ opregion = kzalloc (sizeof (* opregion ), GFP_KERNEL );
939+ if (!opregion )
940+ return - ENOMEM ;
941+
942+ opregion -> i915 = dev_priv ;
943+ dev_priv -> display .opregion = opregion ;
944+
910945 INIT_WORK (& opregion -> asle_work , asle_work );
911946
912947 base = memremap (asls , OPREGION_SIZE , MEMREMAP_WB );
913- if (!base )
914- return - ENOMEM ;
948+ if (!base ) {
949+ err = - ENOMEM ;
950+ goto err_memremap ;
951+ }
915952
916953 memcpy (buf , base , sizeof (buf ));
917954
@@ -1039,6 +1076,10 @@ int intel_opregion_setup(struct drm_i915_private *dev_priv)
10391076
10401077err_out :
10411078 memunmap (base );
1079+ err_memremap :
1080+ kfree (opregion );
1081+ dev_priv -> display .opregion = NULL ;
1082+
10421083 return err ;
10431084}
10441085
@@ -1111,12 +1152,12 @@ const struct drm_edid *intel_opregion_get_edid(struct intel_connector *intel_con
11111152{
11121153 struct drm_connector * connector = & intel_connector -> base ;
11131154 struct drm_i915_private * i915 = to_i915 (connector -> dev );
1114- struct intel_opregion * opregion = & i915 -> display .opregion ;
1155+ struct intel_opregion * opregion = i915 -> display .opregion ;
11151156 const struct drm_edid * drm_edid ;
11161157 const void * edid ;
11171158 int len ;
11181159
1119- if (!opregion -> asle_ext )
1160+ if (!opregion || ! opregion -> asle_ext )
11201161 return NULL ;
11211162
11221163 edid = opregion -> asle_ext -> bddc ;
@@ -1139,9 +1180,9 @@ const struct drm_edid *intel_opregion_get_edid(struct intel_connector *intel_con
11391180
11401181const void * intel_opregion_get_vbt (struct drm_i915_private * i915 , size_t * size )
11411182{
1142- struct intel_opregion * opregion = & i915 -> display .opregion ;
1183+ struct intel_opregion * opregion = i915 -> display .opregion ;
11431184
1144- if (!opregion -> vbt )
1185+ if (!opregion || ! opregion -> vbt )
11451186 return NULL ;
11461187
11471188 if (size )
@@ -1152,8 +1193,13 @@ const void *intel_opregion_get_vbt(struct drm_i915_private *i915, size_t *size)
11521193
11531194bool intel_opregion_headless_sku (struct drm_i915_private * i915 )
11541195{
1155- struct intel_opregion * opregion = & i915 -> display .opregion ;
1156- struct opregion_header * header = opregion -> header ;
1196+ struct intel_opregion * opregion = i915 -> display .opregion ;
1197+ struct opregion_header * header ;
1198+
1199+ if (!opregion )
1200+ return false;
1201+
1202+ header = opregion -> header ;
11571203
11581204 if (!header || header -> over .major < 2 ||
11591205 (header -> over .major == 2 && header -> over .minor < 3 ))
@@ -1164,9 +1210,9 @@ bool intel_opregion_headless_sku(struct drm_i915_private *i915)
11641210
11651211void intel_opregion_register (struct drm_i915_private * i915 )
11661212{
1167- struct intel_opregion * opregion = & i915 -> display .opregion ;
1213+ struct intel_opregion * opregion = i915 -> display .opregion ;
11681214
1169- if (!opregion -> header )
1215+ if (!opregion )
11701216 return ;
11711217
11721218 if (opregion -> acpi ) {
@@ -1180,7 +1226,7 @@ void intel_opregion_register(struct drm_i915_private *i915)
11801226
11811227static void intel_opregion_resume_display (struct drm_i915_private * i915 )
11821228{
1183- struct intel_opregion * opregion = & i915 -> display .opregion ;
1229+ struct intel_opregion * opregion = i915 -> display .opregion ;
11841230
11851231 if (opregion -> acpi ) {
11861232 intel_didl_outputs (i915 );
@@ -1206,9 +1252,9 @@ static void intel_opregion_resume_display(struct drm_i915_private *i915)
12061252
12071253void intel_opregion_resume (struct drm_i915_private * i915 )
12081254{
1209- struct intel_opregion * opregion = & i915 -> display .opregion ;
1255+ struct intel_opregion * opregion = i915 -> display .opregion ;
12101256
1211- if (!opregion -> header )
1257+ if (!opregion )
12121258 return ;
12131259
12141260 if (HAS_DISPLAY (i915 ))
@@ -1219,22 +1265,22 @@ void intel_opregion_resume(struct drm_i915_private *i915)
12191265
12201266static void intel_opregion_suspend_display (struct drm_i915_private * i915 )
12211267{
1222- struct intel_opregion * opregion = & i915 -> display .opregion ;
1268+ struct intel_opregion * opregion = i915 -> display .opregion ;
12231269
12241270 if (opregion -> asle )
12251271 opregion -> asle -> ardy = ASLE_ARDY_NOT_READY ;
12261272
1227- cancel_work_sync (& i915 -> display . opregion . asle_work );
1273+ cancel_work_sync (& opregion -> asle_work );
12281274
12291275 if (opregion -> acpi )
12301276 opregion -> acpi -> drdy = 0 ;
12311277}
12321278
12331279void intel_opregion_suspend (struct drm_i915_private * i915 , pci_power_t state )
12341280{
1235- struct intel_opregion * opregion = & i915 -> display .opregion ;
1281+ struct intel_opregion * opregion = i915 -> display .opregion ;
12361282
1237- if (!opregion -> header )
1283+ if (!opregion )
12381284 return ;
12391285
12401286 intel_opregion_notify_adapter (i915 , state );
@@ -1245,11 +1291,11 @@ void intel_opregion_suspend(struct drm_i915_private *i915, pci_power_t state)
12451291
12461292void intel_opregion_unregister (struct drm_i915_private * i915 )
12471293{
1248- struct intel_opregion * opregion = & i915 -> display .opregion ;
1294+ struct intel_opregion * opregion = i915 -> display .opregion ;
12491295
12501296 intel_opregion_suspend (i915 , PCI_D1 );
12511297
1252- if (!opregion -> header )
1298+ if (!opregion )
12531299 return ;
12541300
12551301 if (opregion -> acpi_notifier .notifier_call ) {
@@ -1260,36 +1306,25 @@ void intel_opregion_unregister(struct drm_i915_private *i915)
12601306
12611307void intel_opregion_cleanup (struct drm_i915_private * i915 )
12621308{
1263- struct intel_opregion * opregion = & i915 -> display .opregion ;
1309+ struct intel_opregion * opregion = i915 -> display .opregion ;
12641310
1265- if (!opregion -> header )
1311+ if (!opregion )
12661312 return ;
12671313
1268- /* just clear all opregion memory pointers now */
12691314 memunmap (opregion -> header );
1270- if (opregion -> rvda ) {
1315+ if (opregion -> rvda )
12711316 memunmap (opregion -> rvda );
1272- opregion -> rvda = NULL ;
1273- }
1274- if (opregion -> vbt_firmware ) {
1275- kfree (opregion -> vbt_firmware );
1276- opregion -> vbt_firmware = NULL ;
1277- }
1278- opregion -> header = NULL ;
1279- opregion -> acpi = NULL ;
1280- opregion -> swsci = NULL ;
1281- opregion -> asle = NULL ;
1282- opregion -> asle_ext = NULL ;
1283- opregion -> vbt = NULL ;
1284- opregion -> lid_state = NULL ;
1317+ kfree (opregion -> vbt_firmware );
1318+ kfree (opregion );
1319+ i915 -> display .opregion = NULL ;
12851320}
12861321
12871322static int intel_opregion_show (struct seq_file * m , void * unused )
12881323{
12891324 struct drm_i915_private * i915 = m -> private ;
1290- struct intel_opregion * opregion = & i915 -> display .opregion ;
1325+ struct intel_opregion * opregion = i915 -> display .opregion ;
12911326
1292- if (opregion -> header )
1327+ if (opregion )
12931328 seq_write (m , opregion -> header , OPREGION_SIZE );
12941329
12951330 return 0 ;
0 commit comments