aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpica/acevents.h2
-rw-r--r--drivers/acpi/acpica/acglobal.h3
-rw-r--r--drivers/acpi/acpica/aclocal.h12
-rw-r--r--drivers/acpi/acpica/acnamesp.h13
-rw-r--r--drivers/acpi/acpica/amlcode.h2
-rw-r--r--drivers/acpi/acpica/dsobject.c5
-rw-r--r--drivers/acpi/acpica/dsopcode.c17
-rw-r--r--drivers/acpi/acpica/dswstate.c4
-rw-r--r--drivers/acpi/acpica/evregion.c12
-rw-r--r--drivers/acpi/acpica/evxfevnt.c4
-rw-r--r--drivers/acpi/acpica/exconfig.c125
-rw-r--r--drivers/acpi/acpica/excreate.c2
-rw-r--r--drivers/acpi/acpica/exdump.c6
-rw-r--r--drivers/acpi/acpica/exfldio.c20
-rw-r--r--drivers/acpi/acpica/exmutex.c45
-rw-r--r--drivers/acpi/acpica/exstore.c4
-rw-r--r--drivers/acpi/acpica/hwregs.c4
-rw-r--r--drivers/acpi/acpica/nsalloc.c14
-rw-r--r--drivers/acpi/acpica/nsnames.c2
-rw-r--r--drivers/acpi/acpica/nsobject.c9
-rw-r--r--drivers/acpi/acpica/nspredef.c7
-rw-r--r--drivers/acpi/acpica/nssearch.c4
-rw-r--r--drivers/acpi/acpica/nswalk.c69
-rw-r--r--drivers/acpi/acpica/nsxfname.c150
-rw-r--r--drivers/acpi/acpica/nsxfobj.c9
-rw-r--r--drivers/acpi/acpica/rscalc.c5
-rw-r--r--drivers/acpi/acpica/rsxface.c8
-rw-r--r--drivers/acpi/acpica/tbfadt.c16
-rw-r--r--drivers/acpi/acpica/tbinstal.c2
-rw-r--r--drivers/acpi/acpica/utcopy.c23
-rw-r--r--drivers/acpi/acpica/utdebug.c8
-rw-r--r--drivers/acpi/acpica/utdelete.c21
-rw-r--r--drivers/acpi/acpica/utmisc.c20
-rw-r--r--drivers/acpi/acpica/utmutex.c26
-rw-r--r--drivers/block/cciss.c1
-rw-r--r--drivers/block/mg_disk.c28
-rw-r--r--drivers/block/ps3disk.c18
-rw-r--r--drivers/block/ps3vram.c168
-rw-r--r--drivers/char/hvc_iucv.c204
-rw-r--r--drivers/char/ps3flash.c296
-rw-r--r--drivers/hwmon/Kconfig16
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/f71882fg.c250
-rw-r--r--drivers/hwmon/hwmon.c29
-rw-r--r--drivers/hwmon/ibmaem.c1
-rw-r--r--drivers/hwmon/max6650.c86
-rw-r--r--drivers/hwmon/sht15.c10
-rw-r--r--drivers/hwmon/tmp401.c690
-rw-r--r--drivers/hwmon/w83627ehf.c10
-rw-r--r--drivers/i2c/busses/Kconfig6
-rw-r--r--drivers/i2c/busses/i2c-viapro.c4
-rw-r--r--drivers/i2c/busses/i2c-voodoo3.c1
-rw-r--r--drivers/i2c/chips/Kconfig15
-rw-r--r--drivers/i2c/chips/Makefile1
-rw-r--r--drivers/i2c/i2c-core.c43
-rw-r--r--drivers/macintosh/therm_adt746x.c84
-rw-r--r--drivers/macintosh/therm_pm72.c95
-rw-r--r--drivers/macintosh/therm_windtunnel.c126
-rw-r--r--drivers/macintosh/windfarm_lm75_sensor.c129
-rw-r--r--drivers/macintosh/windfarm_max6690_sensor.c103
-rw-r--r--drivers/macintosh/windfarm_smu_sat.c109
-rw-r--r--drivers/md/dm.c1
-rw-r--r--drivers/misc/eeprom/Kconfig14
-rw-r--r--drivers/misc/eeprom/Makefile1
-rw-r--r--drivers/misc/eeprom/max6875.c (renamed from drivers/i2c/chips/max6875.c)2
-rw-r--r--drivers/net/ps3_gelic_net.c8
-rw-r--r--drivers/ps3/ps3-sys-manager.c2
-rw-r--r--drivers/ps3/ps3av.c8
-rw-r--r--drivers/ps3/ps3av_cmd.c3
-rw-r--r--drivers/s390/block/dasd.c109
-rw-r--r--drivers/s390/block/dasd_devmap.c1
-rw-r--r--drivers/s390/block/dasd_eckd.c108
-rw-r--r--drivers/s390/block/dasd_fba.c6
-rw-r--r--drivers/s390/block/dasd_int.h13
-rw-r--r--drivers/s390/block/dcssblk.c132
-rw-r--r--drivers/s390/block/xpram.c129
-rw-r--r--drivers/s390/char/con3215.c205
-rw-r--r--drivers/s390/char/con3270.c12
-rw-r--r--drivers/s390/char/fs3270.c16
-rw-r--r--drivers/s390/char/monreader.c140
-rw-r--r--drivers/s390/char/monwriter.c98
-rw-r--r--drivers/s390/char/raw3270.c84
-rw-r--r--drivers/s390/char/raw3270.h12
-rw-r--r--drivers/s390/char/sclp.c248
-rw-r--r--drivers/s390/char/sclp.h23
-rw-r--r--drivers/s390/char/sclp_cmd.c42
-rw-r--r--drivers/s390/char/sclp_con.c139
-rw-r--r--drivers/s390/char/sclp_rw.c20
-rw-r--r--drivers/s390/char/sclp_rw.h12
-rw-r--r--drivers/s390/char/sclp_vt220.c118
-rw-r--r--drivers/s390/char/tape.h3
-rw-r--r--drivers/s390/char/tape_34xx.c3
-rw-r--r--drivers/s390/char/tape_3590.c3
-rw-r--r--drivers/s390/char/tape_core.c52
-rw-r--r--drivers/s390/char/vmlogrdr.c27
-rw-r--r--drivers/s390/char/vmur.c26
-rw-r--r--drivers/s390/char/vmwatchdog.c81
-rw-r--r--drivers/s390/cio/ccwgroup.c78
-rw-r--r--drivers/s390/cio/chsc.c3
-rw-r--r--drivers/s390/cio/chsc.h1
-rw-r--r--drivers/s390/cio/chsc_sch.c32
-rw-r--r--drivers/s390/cio/cmf.c5
-rw-r--r--drivers/s390/cio/css.c157
-rw-r--r--drivers/s390/cio/css.h10
-rw-r--r--drivers/s390/cio/device.c260
-rw-r--r--drivers/s390/cio/device.h3
-rw-r--r--drivers/s390/cio/device_fsm.c96
-rw-r--r--drivers/s390/cio/device_ops.c26
-rw-r--r--drivers/s390/cio/io_sch.h1
-rw-r--r--drivers/s390/net/claw.c14
-rw-r--r--drivers/s390/net/ctcm_main.c37
-rw-r--r--drivers/s390/net/lcs.c74
-rw-r--r--drivers/s390/net/netiucv.c115
-rw-r--r--drivers/s390/net/qeth_core_main.c51
-rw-r--r--drivers/s390/net/qeth_l2_main.c52
-rw-r--r--drivers/s390/net/qeth_l3_main.c52
-rw-r--r--drivers/s390/net/smsgiucv.c63
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c33
-rw-r--r--drivers/sbus/char/openprom.c2
-rw-r--r--drivers/spi/spi_bfin5xx.c4
-rw-r--r--drivers/usb/host/ehci-ps3.c7
-rw-r--r--drivers/usb/host/ohci-ps3.c7
-rw-r--r--drivers/video/bw2.c20
-rw-r--r--drivers/video/cg14.c19
-rw-r--r--drivers/video/cg3.c20
-rw-r--r--drivers/video/cg6.c25
-rw-r--r--drivers/video/leo.c14
-rw-r--r--drivers/video/p9100.c20
-rw-r--r--drivers/video/ps3fb.c272
-rw-r--r--drivers/video/tdfxfb.c1
130 files changed, 5155 insertions, 1517 deletions
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index 07e20135f01b..0bba148a2c61 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -139,7 +139,7 @@ acpi_status acpi_ev_initialize_op_regions(void);
139acpi_status 139acpi_status
140acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, 140acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
141 u32 function, 141 u32 function,
142 acpi_physical_address address, 142 u32 region_offset,
143 u32 bit_width, acpi_integer * value); 143 u32 bit_width, acpi_integer * value);
144 144
145acpi_status 145acpi_status
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 16e5210ae936..3d87362d17ed 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -362,9 +362,6 @@ extern u8 acpi_gbl_method_executing;
362extern u8 acpi_gbl_abort_method; 362extern u8 acpi_gbl_abort_method;
363extern u8 acpi_gbl_db_terminate_threads; 363extern u8 acpi_gbl_db_terminate_threads;
364 364
365ACPI_EXTERN int optind;
366ACPI_EXTERN char *optarg;
367
368ACPI_EXTERN u8 acpi_gbl_db_opt_tables; 365ACPI_EXTERN u8 acpi_gbl_db_opt_tables;
369ACPI_EXTERN u8 acpi_gbl_db_opt_stats; 366ACPI_EXTERN u8 acpi_gbl_db_opt_stats;
370ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods; 367ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods;
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 2ec394a328e9..ee986edfa0da 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -205,6 +205,7 @@ struct acpi_namespace_node {
205#define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */ 205#define ANOBJ_METHOD_LOCAL 0x08 /* Node is a method local */
206#define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */ 206#define ANOBJ_SUBTREE_HAS_INI 0x10 /* Used to optimize device initialization */
207#define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ 207#define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */
208#define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (install_method) */
208 209
209#define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */ 210#define ANOBJ_IS_EXTERNAL 0x08 /* i_aSL only: This object created via External() */
210#define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */ 211#define ANOBJ_METHOD_NO_RETVAL 0x10 /* i_aSL only: Method has no return value */
@@ -788,11 +789,14 @@ struct acpi_bit_register_info {
788/* For control registers, both ignored and reserved bits must be preserved */ 789/* For control registers, both ignored and reserved bits must be preserved */
789 790
790/* 791/*
791 * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0) 792 * For PM1 control, the SCI enable bit (bit 0, SCI_EN) is defined by the
792 * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly 793 * ACPI specification to be a "preserved" bit - "OSPM always preserves this
793 * as a BIOS workaround on some machines. 794 * bit position", section 4.7.3.2.1. However, on some machines the OS must
795 * write a one to this bit after resume for the machine to work properly.
796 * To enable this, we no longer attempt to preserve this bit. No machines
797 * are known to fail if the bit is not preserved. (May 2009)
794 */ 798 */
795#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bits 9 */ 799#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0200 /* Bit 9 */
796#define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */ 800#define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */
797#define ACPI_PM1_CONTROL_PRESERVED_BITS \ 801#define ACPI_PM1_CONTROL_PRESERVED_BITS \
798 (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS) 802 (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h
index 46cb5b46d280..94cdc2b8cb93 100644
--- a/drivers/acpi/acpica/acnamesp.h
+++ b/drivers/acpi/acpica/acnamesp.h
@@ -99,10 +99,19 @@ acpi_ns_walk_namespace(acpi_object_type type,
99 acpi_walk_callback user_function, 99 acpi_walk_callback user_function,
100 void *context, void **return_value); 100 void *context, void **return_value);
101 101
102struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node 102struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
103 *parent, struct acpi_namespace_node 103 *parent,
104 struct acpi_namespace_node
104 *child); 105 *child);
105 106
107struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
108 struct
109 acpi_namespace_node
110 *parent,
111 struct
112 acpi_namespace_node
113 *child);
114
106/* 115/*
107 * nsparse - table parsing 116 * nsparse - table parsing
108 */ 117 */
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h
index ff851c5df698..067f967eb389 100644
--- a/drivers/acpi/acpica/amlcode.h
+++ b/drivers/acpi/acpica/amlcode.h
@@ -483,7 +483,7 @@ typedef enum {
483 483
484#define AML_METHOD_ARG_COUNT 0x07 484#define AML_METHOD_ARG_COUNT 0x07
485#define AML_METHOD_SERIALIZED 0x08 485#define AML_METHOD_SERIALIZED 0x08
486#define AML_METHOD_SYNCH_LEVEL 0xF0 486#define AML_METHOD_SYNC_LEVEL 0xF0
487 487
488/* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */ 488/* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */
489 489
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index dab3f48f0b42..02e6caad4a76 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -734,7 +734,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
734 734
735 /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */ 735 /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
736 736
737 obj_desc->reference.value = opcode - AML_LOCAL_OP; 737 obj_desc->reference.value =
738 ((u32)opcode) - AML_LOCAL_OP;
738 obj_desc->reference.class = ACPI_REFCLASS_LOCAL; 739 obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
739 740
740#ifndef ACPI_NO_METHOD_EXECUTION 741#ifndef ACPI_NO_METHOD_EXECUTION
@@ -754,7 +755,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
754 755
755 /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */ 756 /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
756 757
757 obj_desc->reference.value = opcode - AML_ARG_OP; 758 obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP;
758 obj_desc->reference.class = ACPI_REFCLASS_ARG; 759 obj_desc->reference.class = ACPI_REFCLASS_ARG;
759 760
760#ifndef ACPI_NO_METHOD_EXECUTION 761#ifndef ACPI_NO_METHOD_EXECUTION
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index b4c87b5053e6..584d766e6f12 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -1386,14 +1386,19 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
1386 1386
1387 case AML_BREAK_POINT_OP: 1387 case AML_BREAK_POINT_OP:
1388 1388
1389 /* Call up to the OS service layer to handle this */ 1389 /*
1390 1390 * Set the single-step flag. This will cause the debugger (if present)
1391 status = 1391 * to break to the console within the AML debugger at the start of the
1392 acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, 1392 * next AML instruction.
1393 "Executed AML Breakpoint opcode"); 1393 */
1394 ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
1395 ACPI_DEBUGGER_EXEC(acpi_os_printf
1396 ("**break** Executed AML BreakPoint opcode\n"));
1394 1397
1395 /* If and when it returns, all done. */ 1398 /* Call to the OSL in case OS wants a piece of the action */
1396 1399
1400 status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
1401 "Executed AML Breakpoint opcode");
1397 break; 1402 break;
1398 1403
1399 case AML_BREAK_OP: 1404 case AML_BREAK_OP:
diff --git a/drivers/acpi/acpica/dswstate.c b/drivers/acpi/acpica/dswstate.c
index 40f92bf7dce5..e46c821cf572 100644
--- a/drivers/acpi/acpica/dswstate.c
+++ b/drivers/acpi/acpica/dswstate.c
@@ -102,7 +102,7 @@ acpi_ds_result_pop(union acpi_operand_object **object,
102 /* Return object of the top element and clean that top element result stack */ 102 /* Return object of the top element and clean that top element result stack */
103 103
104 walk_state->result_count--; 104 walk_state->result_count--;
105 index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; 105 index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
106 106
107 *object = state->results.obj_desc[index]; 107 *object = state->results.obj_desc[index];
108 if (!*object) { 108 if (!*object) {
@@ -186,7 +186,7 @@ acpi_ds_result_push(union acpi_operand_object * object,
186 186
187 /* Assign the address of object to the top free element of result stack */ 187 /* Assign the address of object to the top free element of result stack */
188 188
189 index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM; 189 index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
190 state->results.obj_desc[index] = object; 190 state->results.obj_desc[index] = object;
191 walk_state->result_count++; 191 walk_state->result_count++;
192 192
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 538d63264555..98c7f9c62653 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -275,7 +275,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
275 * 275 *
276 * PARAMETERS: region_obj - Internal region object 276 * PARAMETERS: region_obj - Internal region object
277 * Function - Read or Write operation 277 * Function - Read or Write operation
278 * Address - Where in the space to read or write 278 * region_offset - Where in the region to read or write
279 * bit_width - Field width in bits (8, 16, 32, or 64) 279 * bit_width - Field width in bits (8, 16, 32, or 64)
280 * Value - Pointer to in or out value, must be 280 * Value - Pointer to in or out value, must be
281 * full 64-bit acpi_integer 281 * full 64-bit acpi_integer
@@ -290,7 +290,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
290acpi_status 290acpi_status
291acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, 291acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
292 u32 function, 292 u32 function,
293 acpi_physical_address address, 293 u32 region_offset,
294 u32 bit_width, acpi_integer * value) 294 u32 bit_width, acpi_integer * value)
295{ 295{
296 acpi_status status; 296 acpi_status status;
@@ -396,7 +396,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
396 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION, 396 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
397 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", 397 "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
398 &region_obj->region.handler->address_space, handler, 398 &region_obj->region.handler->address_space, handler,
399 ACPI_FORMAT_NATIVE_UINT(address), 399 ACPI_FORMAT_NATIVE_UINT(region_obj->region.address +
400 region_offset),
400 acpi_ut_get_region_name(region_obj->region. 401 acpi_ut_get_region_name(region_obj->region.
401 space_id))); 402 space_id)));
402 403
@@ -412,8 +413,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
412 413
413 /* Call the handler */ 414 /* Call the handler */
414 415
415 status = handler(function, address, bit_width, value, 416 status = handler(function,
416 handler_desc->address_space.context, 417 (region_obj->region.address + region_offset),
418 bit_width, value, handler_desc->address_space.context,
417 region_obj2->extra.region_context); 419 region_obj2->extra.region_context);
418 420
419 if (ACPI_FAILURE(status)) { 421 if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index d0a080747ec3..4721f58fe42c 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -51,7 +51,7 @@
51ACPI_MODULE_NAME("evxfevnt") 51ACPI_MODULE_NAME("evxfevnt")
52 52
53/* Local prototypes */ 53/* Local prototypes */
54acpi_status 54static acpi_status
55acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 55acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
56 struct acpi_gpe_block_info *gpe_block, void *context); 56 struct acpi_gpe_block_info *gpe_block, void *context);
57 57
@@ -785,7 +785,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
785 * block device. NULL if the GPE is one of the FADT-defined GPEs. 785 * block device. NULL if the GPE is one of the FADT-defined GPEs.
786 * 786 *
787 ******************************************************************************/ 787 ******************************************************************************/
788acpi_status 788static acpi_status
789acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, 789acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
790 struct acpi_gpe_block_info *gpe_block, void *context) 790 struct acpi_gpe_block_info *gpe_block, void *context)
791{ 791{
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 3deb20a126b2..277fd609611a 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -47,6 +47,7 @@
47#include "acnamesp.h" 47#include "acnamesp.h"
48#include "actables.h" 48#include "actables.h"
49#include "acdispat.h" 49#include "acdispat.h"
50#include "acevents.h"
50 51
51#define _COMPONENT ACPI_EXECUTER 52#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exconfig") 53ACPI_MODULE_NAME("exconfig")
@@ -57,6 +58,10 @@ acpi_ex_add_table(u32 table_index,
57 struct acpi_namespace_node *parent_node, 58 struct acpi_namespace_node *parent_node,
58 union acpi_operand_object **ddb_handle); 59 union acpi_operand_object **ddb_handle);
59 60
61static acpi_status
62acpi_ex_region_read(union acpi_operand_object *obj_desc,
63 u32 length, u8 *buffer);
64
60/******************************************************************************* 65/*******************************************************************************
61 * 66 *
62 * FUNCTION: acpi_ex_add_table 67 * FUNCTION: acpi_ex_add_table
@@ -91,6 +96,7 @@ acpi_ex_add_table(u32 table_index,
91 96
92 /* Init the table handle */ 97 /* Init the table handle */
93 98
99 obj_desc->common.flags |= AOPOBJ_DATA_VALID;
94 obj_desc->reference.class = ACPI_REFCLASS_TABLE; 100 obj_desc->reference.class = ACPI_REFCLASS_TABLE;
95 *ddb_handle = obj_desc; 101 *ddb_handle = obj_desc;
96 102
@@ -229,6 +235,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
229 walk_state); 235 walk_state);
230 if (ACPI_FAILURE(status)) { 236 if (ACPI_FAILURE(status)) {
231 (void)acpi_ex_unload_table(ddb_handle); 237 (void)acpi_ex_unload_table(ddb_handle);
238
239 acpi_ut_remove_reference(ddb_handle);
232 return_ACPI_STATUS(status); 240 return_ACPI_STATUS(status);
233 } 241 }
234 } 242 }
@@ -254,6 +262,47 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
254 262
255/******************************************************************************* 263/*******************************************************************************
256 * 264 *
265 * FUNCTION: acpi_ex_region_read
266 *
267 * PARAMETERS: obj_desc - Region descriptor
268 * Length - Number of bytes to read
269 * Buffer - Pointer to where to put the data
270 *
271 * RETURN: Status
272 *
273 * DESCRIPTION: Read data from an operation region. The read starts from the
274 * beginning of the region.
275 *
276 ******************************************************************************/
277
278static acpi_status
279acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
280{
281 acpi_status status;
282 acpi_integer value;
283 u32 region_offset = 0;
284 u32 i;
285
286 /* Bytewise reads */
287
288 for (i = 0; i < length; i++) {
289 status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
290 region_offset, 8,
291 &value);
292 if (ACPI_FAILURE(status)) {
293 return status;
294 }
295
296 *buffer = (u8)value;
297 buffer++;
298 region_offset++;
299 }
300
301 return AE_OK;
302}
303
304/*******************************************************************************
305 *
257 * FUNCTION: acpi_ex_load_op 306 * FUNCTION: acpi_ex_load_op
258 * 307 *
259 * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be 308 * PARAMETERS: obj_desc - Region or Buffer/Field where the table will be
@@ -314,18 +363,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
314 } 363 }
315 } 364 }
316 365
317 /* 366 /* Get the table header first so we can get the table length */
318 * Map the table header and get the actual table length. The region 367
319 * length is not guaranteed to be the same as the table length. 368 table = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
320 */
321 table = acpi_os_map_memory(obj_desc->region.address,
322 sizeof(struct acpi_table_header));
323 if (!table) { 369 if (!table) {
324 return_ACPI_STATUS(AE_NO_MEMORY); 370 return_ACPI_STATUS(AE_NO_MEMORY);
325 } 371 }
326 372
373 status =
374 acpi_ex_region_read(obj_desc,
375 sizeof(struct acpi_table_header),
376 ACPI_CAST_PTR(u8, table));
327 length = table->length; 377 length = table->length;
328 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); 378 ACPI_FREE(table);
379
380 if (ACPI_FAILURE(status)) {
381 return_ACPI_STATUS(status);
382 }
329 383
330 /* Must have at least an ACPI table header */ 384 /* Must have at least an ACPI table header */
331 385
@@ -334,10 +388,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
334 } 388 }
335 389
336 /* 390 /*
337 * The memory region is not guaranteed to remain stable and we must 391 * The original implementation simply mapped the table, with no copy.
338 * copy the table to a local buffer. For example, the memory region 392 * However, the memory region is not guaranteed to remain stable and
339 * is corrupted after suspend on some machines. Dynamically loaded 393 * we must copy the table to a local buffer. For example, the memory
340 * tables are usually small, so this overhead is minimal. 394 * region is corrupted after suspend on some machines. Dynamically
395 * loaded tables are usually small, so this overhead is minimal.
396 *
397 * The latest implementation (5/2009) does not use a mapping at all.
398 * We use the low-level operation region interface to read the table
399 * instead of the obvious optimization of using a direct mapping.
400 * This maintains a consistent use of operation regions across the
401 * entire subsystem. This is important if additional processing must
402 * be performed in the (possibly user-installed) operation region
403 * handler. For example, acpi_exec and ASLTS depend on this.
341 */ 404 */
342 405
343 /* Allocate a buffer for the table */ 406 /* Allocate a buffer for the table */
@@ -347,17 +410,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
347 return_ACPI_STATUS(AE_NO_MEMORY); 410 return_ACPI_STATUS(AE_NO_MEMORY);
348 } 411 }
349 412
350 /* Map the entire table and copy it */ 413 /* Read the entire table */
351 414
352 table = acpi_os_map_memory(obj_desc->region.address, length); 415 status = acpi_ex_region_read(obj_desc, length,
353 if (!table) { 416 ACPI_CAST_PTR(u8,
417 table_desc.pointer));
418 if (ACPI_FAILURE(status)) {
354 ACPI_FREE(table_desc.pointer); 419 ACPI_FREE(table_desc.pointer);
355 return_ACPI_STATUS(AE_NO_MEMORY); 420 return_ACPI_STATUS(status);
356 } 421 }
357 422
358 ACPI_MEMCPY(table_desc.pointer, table, length);
359 acpi_os_unmap_memory(table, length);
360
361 table_desc.address = obj_desc->region.address; 423 table_desc.address = obj_desc->region.address;
362 break; 424 break;
363 425
@@ -454,6 +516,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
454 return_ACPI_STATUS(status); 516 return_ACPI_STATUS(status);
455 } 517 }
456 518
519 /* Remove the reference by added by acpi_ex_store above */
520
521 acpi_ut_remove_reference(ddb_handle);
522
457 /* Invoke table handler if present */ 523 /* Invoke table handler if present */
458 524
459 if (acpi_gbl_table_handler) { 525 if (acpi_gbl_table_handler) {
@@ -495,13 +561,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
495 561
496 /* 562 /*
497 * Validate the handle 563 * Validate the handle
498 * Although the handle is partially validated in acpi_ex_reconfiguration(), 564 * Although the handle is partially validated in acpi_ex_reconfiguration()
499 * when it calls acpi_ex_resolve_operands(), the handle is more completely 565 * when it calls acpi_ex_resolve_operands(), the handle is more completely
500 * validated here. 566 * validated here.
567 *
568 * Handle must be a valid operand object of type reference. Also, the
569 * ddb_handle must still be marked valid (table has not been previously
570 * unloaded)
501 */ 571 */
502 if ((!ddb_handle) || 572 if ((!ddb_handle) ||
503 (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) || 573 (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
504 (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) { 574 (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) ||
575 (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) {
505 return_ACPI_STATUS(AE_BAD_PARAMETER); 576 return_ACPI_STATUS(AE_BAD_PARAMETER);
506 } 577 }
507 578
@@ -509,6 +580,12 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
509 580
510 table_index = table_desc->reference.value; 581 table_index = table_desc->reference.value;
511 582
583 /* Ensure the table is still loaded */
584
585 if (!acpi_tb_is_table_loaded(table_index)) {
586 return_ACPI_STATUS(AE_NOT_EXIST);
587 }
588
512 /* Invoke table handler if present */ 589 /* Invoke table handler if present */
513 590
514 if (acpi_gbl_table_handler) { 591 if (acpi_gbl_table_handler) {
@@ -530,8 +607,10 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
530 (void)acpi_tb_release_owner_id(table_index); 607 (void)acpi_tb_release_owner_id(table_index);
531 acpi_tb_set_table_loaded_flag(table_index, FALSE); 608 acpi_tb_set_table_loaded_flag(table_index, FALSE);
532 609
533 /* Table unloaded, remove a reference to the ddb_handle object */ 610 /*
534 611 * Invalidate the handle. We do this because the handle may be stored
535 acpi_ut_remove_reference(ddb_handle); 612 * in a named object and may not be actually deleted until much later.
613 */
614 ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID;
536 return_ACPI_STATUS(AE_OK); 615 return_ACPI_STATUS(AE_OK);
537} 616}
diff --git a/drivers/acpi/acpica/excreate.c b/drivers/acpi/acpica/excreate.c
index a57ad2564ab0..02b25d233d99 100644
--- a/drivers/acpi/acpica/excreate.c
+++ b/drivers/acpi/acpica/excreate.c
@@ -502,7 +502,7 @@ acpi_ex_create_method(u8 * aml_start,
502 * ACPI 2.0: sync_level = sync_level in method declaration 502 * ACPI 2.0: sync_level = sync_level in method declaration
503 */ 503 */
504 obj_desc->method.sync_level = (u8) 504 obj_desc->method.sync_level = (u8)
505 ((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4); 505 ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
506 } 506 }
507 507
508 /* Attach the new object to the method Node */ 508 /* Attach the new object to the method Node */
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index 89d141fdae0b..ec524614e708 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -120,9 +120,11 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = {
120 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"} 120 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"}
121}; 121};
122 122
123static struct acpi_exdump_info acpi_ex_dump_method[8] = { 123static struct acpi_exdump_info acpi_ex_dump_method[9] = {
124 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL}, 124 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL},
125 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "ParamCount"}, 125 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"},
126 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count),
127 "Parameter Count"},
126 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"}, 128 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"},
127 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"}, 129 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"},
128 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"}, 130 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"},
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index 99cee61e655d..d4075b821021 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -222,7 +222,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
222{ 222{
223 acpi_status status; 223 acpi_status status;
224 union acpi_operand_object *rgn_desc; 224 union acpi_operand_object *rgn_desc;
225 acpi_physical_address address; 225 u32 region_offset;
226 226
227 ACPI_FUNCTION_TRACE(ex_access_region); 227 ACPI_FUNCTION_TRACE(ex_access_region);
228 228
@@ -243,7 +243,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
243 * 3) The current offset into the field 243 * 3) The current offset into the field
244 */ 244 */
245 rgn_desc = obj_desc->common_field.region_obj; 245 rgn_desc = obj_desc->common_field.region_obj;
246 address = rgn_desc->region.address + 246 region_offset =
247 obj_desc->common_field.base_byte_offset + field_datum_byte_offset; 247 obj_desc->common_field.base_byte_offset + field_datum_byte_offset;
248 248
249 if ((function & ACPI_IO_MASK) == ACPI_READ) { 249 if ((function & ACPI_IO_MASK) == ACPI_READ) {
@@ -260,16 +260,18 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
260 obj_desc->common_field.access_byte_width, 260 obj_desc->common_field.access_byte_width,
261 obj_desc->common_field.base_byte_offset, 261 obj_desc->common_field.base_byte_offset,
262 field_datum_byte_offset, ACPI_CAST_PTR(void, 262 field_datum_byte_offset, ACPI_CAST_PTR(void,
263 address))); 263 (rgn_desc->
264 region.
265 address +
266 region_offset))));
264 267
265 /* Invoke the appropriate address_space/op_region handler */ 268 /* Invoke the appropriate address_space/op_region handler */
266 269
267 status = acpi_ev_address_space_dispatch(rgn_desc, function, 270 status =
268 address, 271 acpi_ev_address_space_dispatch(rgn_desc, function, region_offset,
269 ACPI_MUL_8(obj_desc-> 272 ACPI_MUL_8(obj_desc->common_field.
270 common_field. 273 access_byte_width),
271 access_byte_width), 274 value);
272 value);
273 275
274 if (ACPI_FAILURE(status)) { 276 if (ACPI_FAILURE(status)) {
275 if (status == AE_NOT_IMPLEMENTED) { 277 if (status == AE_NOT_IMPLEMENTED) {
diff --git a/drivers/acpi/acpica/exmutex.c b/drivers/acpi/acpica/exmutex.c
index d301c1f363ef..2f0114202b05 100644
--- a/drivers/acpi/acpica/exmutex.c
+++ b/drivers/acpi/acpica/exmutex.c
@@ -83,6 +83,15 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)
83 83
84 if (obj_desc->mutex.prev) { 84 if (obj_desc->mutex.prev) {
85 (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next; 85 (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next;
86
87 /*
88 * Migrate the previous sync level associated with this mutex to the
89 * previous mutex on the list so that it may be preserved. This handles
90 * the case where several mutexes have been acquired at the same level,
91 * but are not released in opposite order.
92 */
93 (obj_desc->mutex.prev)->mutex.original_sync_level =
94 obj_desc->mutex.original_sync_level;
86 } else { 95 } else {
87 thread->acquired_mutex_list = obj_desc->mutex.next; 96 thread->acquired_mutex_list = obj_desc->mutex.next;
88 } 97 }
@@ -349,6 +358,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
349 struct acpi_walk_state *walk_state) 358 struct acpi_walk_state *walk_state)
350{ 359{
351 acpi_status status = AE_OK; 360 acpi_status status = AE_OK;
361 u8 previous_sync_level;
352 362
353 ACPI_FUNCTION_TRACE(ex_release_mutex); 363 ACPI_FUNCTION_TRACE(ex_release_mutex);
354 364
@@ -373,11 +383,12 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
373 walk_state->thread->thread_id) 383 walk_state->thread->thread_id)
374 && (obj_desc != acpi_gbl_global_lock_mutex)) { 384 && (obj_desc != acpi_gbl_global_lock_mutex)) {
375 ACPI_ERROR((AE_INFO, 385 ACPI_ERROR((AE_INFO,
376 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", 386 "Thread %p cannot release Mutex [%4.4s] acquired by thread %p",
377 (unsigned long)walk_state->thread->thread_id, 387 ACPI_CAST_PTR(void, walk_state->thread->thread_id),
378 acpi_ut_get_node_name(obj_desc->mutex.node), 388 acpi_ut_get_node_name(obj_desc->mutex.node),
379 (unsigned long)obj_desc->mutex.owner_thread-> 389 ACPI_CAST_PTR(void,
380 thread_id)); 390 obj_desc->mutex.owner_thread->
391 thread_id)));
381 return_ACPI_STATUS(AE_AML_NOT_OWNER); 392 return_ACPI_STATUS(AE_AML_NOT_OWNER);
382 } 393 }
383 394
@@ -391,10 +402,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
391 } 402 }
392 403
393 /* 404 /*
394 * The sync level of the mutex must be less than or equal to the current 405 * The sync level of the mutex must be equal to the current sync level. In
395 * sync level 406 * other words, the current level means that at least one mutex at that
407 * level is currently being held. Attempting to release a mutex of a
408 * different level can only mean that the mutex ordering rule is being
409 * violated. This behavior is clarified in ACPI 4.0 specification.
396 */ 410 */
397 if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) { 411 if (obj_desc->mutex.sync_level !=
412 walk_state->thread->current_sync_level) {
398 ACPI_ERROR((AE_INFO, 413 ACPI_ERROR((AE_INFO,
399 "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d", 414 "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
400 acpi_ut_get_node_name(obj_desc->mutex.node), 415 acpi_ut_get_node_name(obj_desc->mutex.node),
@@ -403,14 +418,24 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
403 return_ACPI_STATUS(AE_AML_MUTEX_ORDER); 418 return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
404 } 419 }
405 420
421 /*
422 * Get the previous sync_level from the head of the acquired mutex list.
423 * This handles the case where several mutexes at the same level have been
424 * acquired, but are not released in reverse order.
425 */
426 previous_sync_level =
427 walk_state->thread->acquired_mutex_list->mutex.original_sync_level;
428
406 status = acpi_ex_release_mutex_object(obj_desc); 429 status = acpi_ex_release_mutex_object(obj_desc);
430 if (ACPI_FAILURE(status)) {
431 return_ACPI_STATUS(status);
432 }
407 433
408 if (obj_desc->mutex.acquisition_depth == 0) { 434 if (obj_desc->mutex.acquisition_depth == 0) {
409 435
410 /* Restore the original sync_level */ 436 /* Restore the previous sync_level */
411 437
412 walk_state->thread->current_sync_level = 438 walk_state->thread->current_sync_level = previous_sync_level;
413 obj_desc->mutex.original_sync_level;
414 } 439 }
415 return_ACPI_STATUS(status); 440 return_ACPI_STATUS(status);
416} 441}
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index 90d606196c99..6efd07a4f779 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -193,10 +193,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
193 193
194 case ACPI_REFCLASS_TABLE: 194 case ACPI_REFCLASS_TABLE:
195 195
196 /* Case for ddb_handle */
197
196 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT, 198 ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
197 "Table Index 0x%X\n", 199 "Table Index 0x%X\n",
198 source_desc->reference.value)); 200 source_desc->reference.value));
199 break; 201 return;
200 202
201 default: 203 default:
202 break; 204 break;
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 7b2fb602b5cb..23d5505cb1f7 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -81,9 +81,9 @@ acpi_status acpi_hw_clear_acpi_status(void)
81 81
82 ACPI_FUNCTION_TRACE(hw_clear_acpi_status); 82 ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
83 83
84 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n", 84 ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
85 ACPI_BITMASK_ALL_FIXED_STATUS, 85 ACPI_BITMASK_ALL_FIXED_STATUS,
86 acpi_gbl_xpm1a_status.address)); 86 ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address)));
87 87
88 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock); 88 lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
89 89
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index aceb93111967..efc971ab7d65 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -334,9 +334,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
334 334
335 /* Get the next node in this scope (NULL if none) */ 335 /* Get the next node in this scope (NULL if none) */
336 336
337 child_node = 337 child_node = acpi_ns_get_next_node(parent_node, child_node);
338 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
339 child_node);
340 if (child_node) { 338 if (child_node) {
341 339
342 /* Found a child node - detach any attached object */ 340 /* Found a child node - detach any attached object */
@@ -345,8 +343,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
345 343
346 /* Check if this node has any children */ 344 /* Check if this node has any children */
347 345
348 if (acpi_ns_get_next_node 346 if (child_node->child) {
349 (ACPI_TYPE_ANY, child_node, NULL)) {
350 /* 347 /*
351 * There is at least one child of this node, 348 * There is at least one child of this node,
352 * visit the node 349 * visit the node
@@ -432,9 +429,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
432 * Get the next child of this parent node. When child_node is NULL, 429 * Get the next child of this parent node. When child_node is NULL,
433 * the first child of the parent is returned 430 * the first child of the parent is returned
434 */ 431 */
435 child_node = 432 child_node = acpi_ns_get_next_node(parent_node, child_node);
436 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
437 child_node);
438 433
439 if (deletion_node) { 434 if (deletion_node) {
440 acpi_ns_delete_children(deletion_node); 435 acpi_ns_delete_children(deletion_node);
@@ -452,8 +447,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
452 447
453 /* Check if this node has any children */ 448 /* Check if this node has any children */
454 449
455 if (acpi_ns_get_next_node 450 if (child_node->child) {
456 (ACPI_TYPE_ANY, child_node, NULL)) {
457 /* 451 /*
458 * There is at least one child of this node, 452 * There is at least one child of this node,
459 * visit the node 453 * visit the node
diff --git a/drivers/acpi/acpica/nsnames.c b/drivers/acpi/acpica/nsnames.c
index ae3dc10a7e81..af8e6bcee07e 100644
--- a/drivers/acpi/acpica/nsnames.c
+++ b/drivers/acpi/acpica/nsnames.c
@@ -149,7 +149,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
149 149
150 name_buffer = ACPI_ALLOCATE_ZEROED(size); 150 name_buffer = ACPI_ALLOCATE_ZEROED(size);
151 if (!name_buffer) { 151 if (!name_buffer) {
152 ACPI_ERROR((AE_INFO, "Allocation failure")); 152 ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size));
153 return_PTR(NULL); 153 return_PTR(NULL);
154 } 154 }
155 155
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index 3eb20bfda9d8..60f3af08d28c 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -213,6 +213,15 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
213 return_VOID; 213 return_VOID;
214 } 214 }
215 215
216 if (node->flags & ANOBJ_ALLOCATED_BUFFER) {
217
218 /* Free the dynamic aml buffer */
219
220 if (obj_desc->common.type == ACPI_TYPE_METHOD) {
221 ACPI_FREE(obj_desc->method.aml_start);
222 }
223 }
224
216 /* Clear the entry in all cases */ 225 /* Clear the entry in all cases */
217 226
218 node->object = NULL; 227 node->object = NULL;
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index d9e8cbc6e679..7f8e066b12a3 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -144,7 +144,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
144 144
145 pathname = acpi_ns_get_external_pathname(node); 145 pathname = acpi_ns_get_external_pathname(node);
146 if (!pathname) { 146 if (!pathname) {
147 pathname = ACPI_CAST_PTR(char, predefined->info.name); 147 return AE_OK; /* Could not get pathname, ignore */
148 } 148 }
149 149
150 /* 150 /*
@@ -230,10 +230,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
230 } 230 }
231 231
232 exit: 232 exit:
233 if (pathname != predefined->info.name) { 233 ACPI_FREE(pathname);
234 ACPI_FREE(pathname);
235 }
236
237 return (status); 234 return (status);
238} 235}
239 236
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index f9b4f51bf8f2..7e865639a928 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -45,6 +45,10 @@
45#include "accommon.h" 45#include "accommon.h"
46#include "acnamesp.h" 46#include "acnamesp.h"
47 47
48#ifdef ACPI_ASL_COMPILER
49#include "amlcode.h"
50#endif
51
48#define _COMPONENT ACPI_NAMESPACE 52#define _COMPONENT ACPI_NAMESPACE
49ACPI_MODULE_NAME("nssearch") 53ACPI_MODULE_NAME("nssearch")
50 54
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 83e3aa6d4b9b..35539df5c75d 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -52,8 +52,7 @@ ACPI_MODULE_NAME("nswalk")
52 * 52 *
53 * FUNCTION: acpi_ns_get_next_node 53 * FUNCTION: acpi_ns_get_next_node
54 * 54 *
55 * PARAMETERS: Type - Type of node to be searched for 55 * PARAMETERS: parent_node - Parent node whose children we are
56 * parent_node - Parent node whose children we are
57 * getting 56 * getting
58 * child_node - Previous child that was found. 57 * child_node - Previous child that was found.
59 * The NEXT child will be returned 58 * The NEXT child will be returned
@@ -66,27 +65,68 @@ ACPI_MODULE_NAME("nswalk")
66 * within Scope is returned. 65 * within Scope is returned.
67 * 66 *
68 ******************************************************************************/ 67 ******************************************************************************/
69struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node 68struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
70 *parent_node, struct acpi_namespace_node 69 *parent_node,
70 struct acpi_namespace_node
71 *child_node) 71 *child_node)
72{ 72{
73 struct acpi_namespace_node *next_node = NULL;
74
75 ACPI_FUNCTION_ENTRY(); 73 ACPI_FUNCTION_ENTRY();
76 74
77 if (!child_node) { 75 if (!child_node) {
78 76
79 /* It's really the parent's _scope_ that we want */ 77 /* It's really the parent's _scope_ that we want */
80 78
81 next_node = parent_node->child; 79 return parent_node->child;
82 } 80 }
83 81
84 else { 82 /*
85 /* Start search at the NEXT node */ 83 * Get the next node.
86 84 *
87 next_node = acpi_ns_get_next_valid_node(child_node); 85 * If we are at the end of this peer list, return NULL
86 */
87 if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
88 return NULL;
88 } 89 }
89 90
91 /* Otherwise just return the next peer */
92
93 return child_node->peer;
94}
95
96/*******************************************************************************
97 *
98 * FUNCTION: acpi_ns_get_next_node_typed
99 *
100 * PARAMETERS: Type - Type of node to be searched for
101 * parent_node - Parent node whose children we are
102 * getting
103 * child_node - Previous child that was found.
104 * The NEXT child will be returned
105 *
106 * RETURN: struct acpi_namespace_node - Pointer to the NEXT child or NULL if
107 * none is found.
108 *
109 * DESCRIPTION: Return the next peer node within the namespace. If Handle
110 * is valid, Scope is ignored. Otherwise, the first node
111 * within Scope is returned.
112 *
113 ******************************************************************************/
114
115struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
116 struct
117 acpi_namespace_node
118 *parent_node,
119 struct
120 acpi_namespace_node
121 *child_node)
122{
123 struct acpi_namespace_node *next_node = NULL;
124
125 ACPI_FUNCTION_ENTRY();
126
127 next_node = acpi_ns_get_next_node(parent_node, child_node);
128
129
90 /* If any type is OK, we are done */ 130 /* If any type is OK, we are done */
91 131
92 if (type == ACPI_TYPE_ANY) { 132 if (type == ACPI_TYPE_ANY) {
@@ -186,9 +226,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
186 /* Get the next node in this scope. Null if not found */ 226 /* Get the next node in this scope. Null if not found */
187 227
188 status = AE_OK; 228 status = AE_OK;
189 child_node = 229 child_node = acpi_ns_get_next_node(parent_node, child_node);
190 acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
191 child_node);
192 if (child_node) { 230 if (child_node) {
193 231
194 /* Found next child, get the type if we are not searching for ANY */ 232 /* Found next child, get the type if we are not searching for ANY */
@@ -269,8 +307,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
269 * function has specified that the maximum depth has been reached. 307 * function has specified that the maximum depth has been reached.
270 */ 308 */
271 if ((level < max_depth) && (status != AE_CTRL_DEPTH)) { 309 if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
272 if (acpi_ns_get_next_node 310 if (child_node->child) {
273 (ACPI_TYPE_ANY, child_node, NULL)) {
274 311
275 /* There is at least one child of this node, visit it */ 312 /* There is at least one child of this node, visit it */
276 313
diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c
index 9589fea24997..f23593d6add4 100644
--- a/drivers/acpi/acpica/nsxfname.c
+++ b/drivers/acpi/acpica/nsxfname.c
@@ -45,6 +45,8 @@
45#include <acpi/acpi.h> 45#include <acpi/acpi.h>
46#include "accommon.h" 46#include "accommon.h"
47#include "acnamesp.h" 47#include "acnamesp.h"
48#include "acparser.h"
49#include "amlcode.h"
48 50
49#define _COMPONENT ACPI_NAMESPACE 51#define _COMPONENT ACPI_NAMESPACE
50ACPI_MODULE_NAME("nsxfname") 52ACPI_MODULE_NAME("nsxfname")
@@ -358,3 +360,151 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
358} 360}
359 361
360ACPI_EXPORT_SYMBOL(acpi_get_object_info) 362ACPI_EXPORT_SYMBOL(acpi_get_object_info)
363
364/******************************************************************************
365 *
366 * FUNCTION: acpi_install_method
367 *
368 * PARAMETERS: Buffer - An ACPI table containing one control method
369 *
370 * RETURN: Status
371 *
372 * DESCRIPTION: Install a control method into the namespace. If the method
373 * name already exists in the namespace, it is overwritten. The
374 * input buffer must contain a valid DSDT or SSDT containing a
375 * single control method.
376 *
377 ******************************************************************************/
378acpi_status acpi_install_method(u8 *buffer)
379{
380 struct acpi_table_header *table =
381 ACPI_CAST_PTR(struct acpi_table_header, buffer);
382 u8 *aml_buffer;
383 u8 *aml_start;
384 char *path;
385 struct acpi_namespace_node *node;
386 union acpi_operand_object *method_obj;
387 struct acpi_parse_state parser_state;
388 u32 aml_length;
389 u16 opcode;
390 u8 method_flags;
391 acpi_status status;
392
393 /* Parameter validation */
394
395 if (!buffer) {
396 return AE_BAD_PARAMETER;
397 }
398
399 /* Table must be a DSDT or SSDT */
400
401 if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) &&
402 !ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
403 return AE_BAD_HEADER;
404 }
405
406 /* First AML opcode in the table must be a control method */
407
408 parser_state.aml = buffer + sizeof(struct acpi_table_header);
409 opcode = acpi_ps_peek_opcode(&parser_state);
410 if (opcode != AML_METHOD_OP) {
411 return AE_BAD_PARAMETER;
412 }
413
414 /* Extract method information from the raw AML */
415
416 parser_state.aml += acpi_ps_get_opcode_size(opcode);
417 parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state);
418 path = acpi_ps_get_next_namestring(&parser_state);
419 method_flags = *parser_state.aml++;
420 aml_start = parser_state.aml;
421 aml_length = ACPI_PTR_DIFF(parser_state.pkg_end, aml_start);
422
423 /*
424 * Allocate resources up-front. We don't want to have to delete a new
425 * node from the namespace if we cannot allocate memory.
426 */
427 aml_buffer = ACPI_ALLOCATE(aml_length);
428 if (!aml_buffer) {
429 return AE_NO_MEMORY;
430 }
431
432 method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
433 if (!method_obj) {
434 ACPI_FREE(aml_buffer);
435 return AE_NO_MEMORY;
436 }
437
438 /* Lock namespace for acpi_ns_lookup, we may be creating a new node */
439
440 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
441 if (ACPI_FAILURE(status)) {
442 goto error_exit;
443 }
444
445 /* The lookup either returns an existing node or creates a new one */
446
447 status =
448 acpi_ns_lookup(NULL, path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
449 ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND,
450 NULL, &node);
451
452 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
453
454 if (ACPI_FAILURE(status)) { /* ns_lookup */
455 if (status != AE_ALREADY_EXISTS) {
456 goto error_exit;
457 }
458
459 /* Node existed previously, make sure it is a method node */
460
461 if (node->type != ACPI_TYPE_METHOD) {
462 status = AE_TYPE;
463 goto error_exit;
464 }
465 }
466
467 /* Copy the method AML to the local buffer */
468
469 ACPI_MEMCPY(aml_buffer, aml_start, aml_length);
470
471 /* Initialize the method object with the new method's information */
472
473 method_obj->method.aml_start = aml_buffer;
474 method_obj->method.aml_length = aml_length;
475
476 method_obj->method.param_count = (u8)
477 (method_flags & AML_METHOD_ARG_COUNT);
478
479 method_obj->method.method_flags = (u8)
480 (method_flags & ~AML_METHOD_ARG_COUNT);
481
482 if (method_flags & AML_METHOD_SERIALIZED) {
483 method_obj->method.sync_level = (u8)
484 ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
485 }
486
487 /*
488 * Now that it is complete, we can attach the new method object to
489 * the method Node (detaches/deletes any existing object)
490 */
491 status = acpi_ns_attach_object(node, method_obj, ACPI_TYPE_METHOD);
492
493 /*
494 * Flag indicates AML buffer is dynamic, must be deleted later.
495 * Must be set only after attach above.
496 */
497 node->flags |= ANOBJ_ALLOCATED_BUFFER;
498
499 /* Remove local reference to the method object */
500
501 acpi_ut_remove_reference(method_obj);
502 return status;
503
504error_exit:
505
506 ACPI_FREE(aml_buffer);
507 ACPI_FREE(method_obj);
508 return status;
509}
510ACPI_EXPORT_SYMBOL(acpi_install_method)
diff --git a/drivers/acpi/acpica/nsxfobj.c b/drivers/acpi/acpica/nsxfobj.c
index 1c7efc15225f..4071bad4458e 100644
--- a/drivers/acpi/acpica/nsxfobj.c
+++ b/drivers/acpi/acpica/nsxfobj.c
@@ -162,6 +162,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_type)
162acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle) 162acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle)
163{ 163{
164 struct acpi_namespace_node *node; 164 struct acpi_namespace_node *node;
165 struct acpi_namespace_node *parent_node;
165 acpi_status status; 166 acpi_status status;
166 167
167 if (!ret_handle) { 168 if (!ret_handle) {
@@ -189,12 +190,12 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle)
189 190
190 /* Get the parent entry */ 191 /* Get the parent entry */
191 192
192 *ret_handle = 193 parent_node = acpi_ns_get_parent_node(node);
193 acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node)); 194 *ret_handle = acpi_ns_convert_entry_to_handle(parent_node);
194 195
195 /* Return exception if parent is null */ 196 /* Return exception if parent is null */
196 197
197 if (!acpi_ns_get_parent_node(node)) { 198 if (!parent_node) {
198 status = AE_NULL_ENTRY; 199 status = AE_NULL_ENTRY;
199 } 200 }
200 201
@@ -268,7 +269,7 @@ acpi_get_next_object(acpi_object_type type,
268 269
269 /* Internal function does the real work */ 270 /* Internal function does the real work */
270 271
271 node = acpi_ns_get_next_node(type, parent_node, child_node); 272 node = acpi_ns_get_next_node_typed(type, parent_node, child_node);
272 if (!node) { 273 if (!node) {
273 status = AE_NOT_FOUND; 274 status = AE_NOT_FOUND;
274 goto unlock_and_exit; 275 goto unlock_and_exit;
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index 88b5a2c4814d..3c4dcc3d1069 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -547,7 +547,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
547 547
548 if (!package_element || 548 if (!package_element ||
549 (package_element->common.type != ACPI_TYPE_PACKAGE)) { 549 (package_element->common.type != ACPI_TYPE_PACKAGE)) {
550 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 550 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
551 } 551 }
552 552
553 /* 553 /*
@@ -593,9 +593,6 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
593 } else { 593 } else {
594 temp_size_needed += 594 temp_size_needed +=
595 acpi_ns_get_pathname_length((*sub_object_list)->reference.node); 595 acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
596 if (!temp_size_needed) {
597 return_ACPI_STATUS(AE_BAD_PARAMETER);
598 }
599 } 596 }
600 } else { 597 } else {
601 /* 598 /*
diff --git a/drivers/acpi/acpica/rsxface.c b/drivers/acpi/acpica/rsxface.c
index 69a2aa5b5d83..395212bcd19b 100644
--- a/drivers/acpi/acpica/rsxface.c
+++ b/drivers/acpi/acpica/rsxface.c
@@ -338,13 +338,17 @@ acpi_resource_to_address64(struct acpi_resource *resource,
338 switch (resource->type) { 338 switch (resource->type) {
339 case ACPI_RESOURCE_TYPE_ADDRESS16: 339 case ACPI_RESOURCE_TYPE_ADDRESS16:
340 340
341 address16 = (struct acpi_resource_address16 *)&resource->data; 341 address16 =
342 ACPI_CAST_PTR(struct acpi_resource_address16,
343 &resource->data);
342 ACPI_COPY_ADDRESS(out, address16); 344 ACPI_COPY_ADDRESS(out, address16);
343 break; 345 break;
344 346
345 case ACPI_RESOURCE_TYPE_ADDRESS32: 347 case ACPI_RESOURCE_TYPE_ADDRESS32:
346 348
347 address32 = (struct acpi_resource_address32 *)&resource->data; 349 address32 =
350 ACPI_CAST_PTR(struct acpi_resource_address32,
351 &resource->data);
348 ACPI_COPY_ADDRESS(out, address32); 352 ACPI_COPY_ADDRESS(out, address32);
349 break; 353 break;
350 354
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 71e655d14cb0..82b02dcb942e 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -284,9 +284,9 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
284 if (length > sizeof(struct acpi_table_fadt)) { 284 if (length > sizeof(struct acpi_table_fadt)) {
285 ACPI_WARNING((AE_INFO, 285 ACPI_WARNING((AE_INFO,
286 "FADT (revision %u) is longer than ACPI 2.0 version, " 286 "FADT (revision %u) is longer than ACPI 2.0 version, "
287 "truncating length 0x%X to 0x%zX", 287 "truncating length 0x%X to 0x%X",
288 table->revision, (unsigned)length, 288 table->revision, length,
289 sizeof(struct acpi_table_fadt))); 289 (u32)sizeof(struct acpi_table_fadt)));
290 } 290 }
291 291
292 /* Clear the entire local FADT */ 292 /* Clear the entire local FADT */
@@ -441,7 +441,7 @@ static void acpi_tb_convert_fadt(void)
441 &acpi_gbl_FADT, 441 &acpi_gbl_FADT,
442 fadt_info_table 442 fadt_info_table
443 [i].length), 443 [i].length),
444 address32); 444 (u64) address32);
445 } 445 }
446 } 446 }
447} 447}
@@ -469,7 +469,6 @@ static void acpi_tb_convert_fadt(void)
469static void acpi_tb_validate_fadt(void) 469static void acpi_tb_validate_fadt(void)
470{ 470{
471 char *name; 471 char *name;
472 u32 *address32;
473 struct acpi_generic_address *address64; 472 struct acpi_generic_address *address64;
474 u8 length; 473 u8 length;
475 u32 i; 474 u32 i;
@@ -505,15 +504,12 @@ static void acpi_tb_validate_fadt(void)
505 504
506 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) { 505 for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
507 /* 506 /*
508 * Generate pointers to the 32-bit and 64-bit addresses, get the 507 * Generate pointer to the 64-bit address, get the register
509 * register length (width), and the register name 508 * length (width) and the register name
510 */ 509 */
511 address64 = ACPI_ADD_PTR(struct acpi_generic_address, 510 address64 = ACPI_ADD_PTR(struct acpi_generic_address,
512 &acpi_gbl_FADT, 511 &acpi_gbl_FADT,
513 fadt_info_table[i].address64); 512 fadt_info_table[i].address64);
514 address32 =
515 ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
516 fadt_info_table[i].address32);
517 length = 513 length =
518 *ACPI_ADD_PTR(u8, &acpi_gbl_FADT, 514 *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
519 fadt_info_table[i].length); 515 fadt_info_table[i].length);
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index f865d5a096de..63e82329a9e8 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -472,7 +472,7 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
472 * lock may block, and also since the execution of a namespace walk 472 * lock may block, and also since the execution of a namespace walk
473 * must be allowed to use the interpreter. 473 * must be allowed to use the interpreter.
474 */ 474 */
475 acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 475 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
476 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); 476 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
477 477
478 acpi_ns_delete_namespace_by_owner(owner_id); 478 acpi_ns_delete_namespace_by_owner(owner_id);
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index 919624f123d5..0f0c64bf8ac9 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -676,6 +676,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
676{ 676{
677 u16 reference_count; 677 u16 reference_count;
678 union acpi_operand_object *next_object; 678 union acpi_operand_object *next_object;
679 acpi_status status;
679 680
680 /* Save fields from destination that we don't want to overwrite */ 681 /* Save fields from destination that we don't want to overwrite */
681 682
@@ -768,6 +769,28 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
768 } 769 }
769 break; 770 break;
770 771
772 /*
773 * For Mutex and Event objects, we cannot simply copy the underlying
774 * OS object. We must create a new one.
775 */
776 case ACPI_TYPE_MUTEX:
777
778 status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
779 if (ACPI_FAILURE(status)) {
780 return status;
781 }
782 break;
783
784 case ACPI_TYPE_EVENT:
785
786 status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
787 &dest_desc->event.
788 os_semaphore);
789 if (ACPI_FAILURE(status)) {
790 return status;
791 }
792 break;
793
771 default: 794 default:
772 /* Nothing to do for other simple objects */ 795 /* Nothing to do for other simple objects */
773 break; 796 break;
diff --git a/drivers/acpi/acpica/utdebug.c b/drivers/acpi/acpica/utdebug.c
index 38821f53042c..527d729f6815 100644
--- a/drivers/acpi/acpica/utdebug.c
+++ b/drivers/acpi/acpica/utdebug.c
@@ -179,9 +179,9 @@ acpi_debug_print(u32 requested_debug_level,
179 if (thread_id != acpi_gbl_prev_thread_id) { 179 if (thread_id != acpi_gbl_prev_thread_id) {
180 if (ACPI_LV_THREADS & acpi_dbg_level) { 180 if (ACPI_LV_THREADS & acpi_dbg_level) {
181 acpi_os_printf 181 acpi_os_printf
182 ("\n**** Context Switch from TID %lX to TID %lX ****\n\n", 182 ("\n**** Context Switch from TID %p to TID %p ****\n\n",
183 (unsigned long)acpi_gbl_prev_thread_id, 183 ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id),
184 (unsigned long)thread_id); 184 ACPI_CAST_PTR(void, thread_id));
185 } 185 }
186 186
187 acpi_gbl_prev_thread_id = thread_id; 187 acpi_gbl_prev_thread_id = thread_id;
@@ -194,7 +194,7 @@ acpi_debug_print(u32 requested_debug_level,
194 acpi_os_printf("%8s-%04ld ", module_name, line_number); 194 acpi_os_printf("%8s-%04ld ", module_name, line_number);
195 195
196 if (ACPI_LV_THREADS & acpi_dbg_level) { 196 if (ACPI_LV_THREADS & acpi_dbg_level) {
197 acpi_os_printf("[%04lX] ", (unsigned long)thread_id); 197 acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id));
198 } 198 }
199 199
200 acpi_os_printf("[%02ld] %-22.22s: ", 200 acpi_os_printf("[%02ld] %-22.22s: ",
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
index a5ee23bc4f55..bc1710315088 100644
--- a/drivers/acpi/acpica/utdelete.c
+++ b/drivers/acpi/acpica/utdelete.c
@@ -75,6 +75,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
75 union acpi_operand_object *handler_desc; 75 union acpi_operand_object *handler_desc;
76 union acpi_operand_object *second_desc; 76 union acpi_operand_object *second_desc;
77 union acpi_operand_object *next_desc; 77 union acpi_operand_object *next_desc;
78 union acpi_operand_object **last_obj_ptr;
78 79
79 ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object); 80 ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object);
80 81
@@ -223,6 +224,26 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
223 */ 224 */
224 handler_desc = object->region.handler; 225 handler_desc = object->region.handler;
225 if (handler_desc) { 226 if (handler_desc) {
227 next_desc =
228 handler_desc->address_space.region_list;
229 last_obj_ptr =
230 &handler_desc->address_space.region_list;
231
232 /* Remove the region object from the handler's list */
233
234 while (next_desc) {
235 if (next_desc == object) {
236 *last_obj_ptr =
237 next_desc->region.next;
238 break;
239 }
240
241 /* Walk the linked list of handler */
242
243 last_obj_ptr = &next_desc->region.next;
244 next_desc = next_desc->region.next;
245 }
246
226 if (handler_desc->address_space.handler_flags & 247 if (handler_desc->address_space.handler_flags &
227 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { 248 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
228 249
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index 1c9e250caefb..fbe782348b0b 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -1033,11 +1033,12 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...)
1033{ 1033{
1034 va_list args; 1034 va_list args;
1035 1035
1036 acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number); 1036 acpi_os_printf("ACPI Error: ");
1037 1037
1038 va_start(args, format); 1038 va_start(args, format);
1039 acpi_os_vprintf(format, args); 1039 acpi_os_vprintf(format, args);
1040 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); 1040 acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
1041 line_number);
1041 va_end(args); 1042 va_end(args);
1042} 1043}
1043 1044
@@ -1047,12 +1048,12 @@ acpi_exception(const char *module_name,
1047{ 1048{
1048 va_list args; 1049 va_list args;
1049 1050
1050 acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name, 1051 acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status));
1051 line_number, acpi_format_exception(status));
1052 1052
1053 va_start(args, format); 1053 va_start(args, format);
1054 acpi_os_vprintf(format, args); 1054 acpi_os_vprintf(format, args);
1055 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); 1055 acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
1056 line_number);
1056 va_end(args); 1057 va_end(args);
1057} 1058}
1058 1059
@@ -1061,11 +1062,12 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...)
1061{ 1062{
1062 va_list args; 1063 va_list args;
1063 1064
1064 acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number); 1065 acpi_os_printf("ACPI Warning: ");
1065 1066
1066 va_start(args, format); 1067 va_start(args, format);
1067 acpi_os_vprintf(format, args); 1068 acpi_os_vprintf(format, args);
1068 acpi_os_printf(" [%X]\n", ACPI_CA_VERSION); 1069 acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
1070 line_number);
1069 va_end(args); 1071 va_end(args);
1070} 1072}
1071 1073
@@ -1074,10 +1076,6 @@ acpi_info(const char *module_name, u32 line_number, const char *format, ...)
1074{ 1076{
1075 va_list args; 1077 va_list args;
1076 1078
1077 /*
1078 * Removed module_name, line_number, and acpica version, not needed
1079 * for info output
1080 */
1081 acpi_os_printf("ACPI: "); 1079 acpi_os_printf("ACPI: ");
1082 1080
1083 va_start(args, format); 1081 va_start(args, format);
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 26c93a748e64..80bb65154117 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -230,17 +230,18 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
230 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { 230 if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
231 if (i == mutex_id) { 231 if (i == mutex_id) {
232 ACPI_ERROR((AE_INFO, 232 ACPI_ERROR((AE_INFO,
233 "Mutex [%s] already acquired by this thread [%X]", 233 "Mutex [%s] already acquired by this thread [%p]",
234 acpi_ut_get_mutex_name 234 acpi_ut_get_mutex_name
235 (mutex_id), 235 (mutex_id),
236 this_thread_id)); 236 ACPI_CAST_PTR(void,
237 this_thread_id)));
237 238
238 return (AE_ALREADY_ACQUIRED); 239 return (AE_ALREADY_ACQUIRED);
239 } 240 }
240 241
241 ACPI_ERROR((AE_INFO, 242 ACPI_ERROR((AE_INFO,
242 "Invalid acquire order: Thread %X owns [%s], wants [%s]", 243 "Invalid acquire order: Thread %p owns [%s], wants [%s]",
243 this_thread_id, 244 ACPI_CAST_PTR(void, this_thread_id),
244 acpi_ut_get_mutex_name(i), 245 acpi_ut_get_mutex_name(i),
245 acpi_ut_get_mutex_name(mutex_id))); 246 acpi_ut_get_mutex_name(mutex_id)));
246 247
@@ -251,24 +252,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
251#endif 252#endif
252 253
253 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 254 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
254 "Thread %lX attempting to acquire Mutex [%s]\n", 255 "Thread %p attempting to acquire Mutex [%s]\n",
255 (unsigned long)this_thread_id, 256 ACPI_CAST_PTR(void, this_thread_id),
256 acpi_ut_get_mutex_name(mutex_id))); 257 acpi_ut_get_mutex_name(mutex_id)));
257 258
258 status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, 259 status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
259 ACPI_WAIT_FOREVER); 260 ACPI_WAIT_FOREVER);
260 if (ACPI_SUCCESS(status)) { 261 if (ACPI_SUCCESS(status)) {
261 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 262 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
262 "Thread %lX acquired Mutex [%s]\n", 263 "Thread %p acquired Mutex [%s]\n",
263 (unsigned long)this_thread_id, 264 ACPI_CAST_PTR(void, this_thread_id),
264 acpi_ut_get_mutex_name(mutex_id))); 265 acpi_ut_get_mutex_name(mutex_id)));
265 266
266 acpi_gbl_mutex_info[mutex_id].use_count++; 267 acpi_gbl_mutex_info[mutex_id].use_count++;
267 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; 268 acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
268 } else { 269 } else {
269 ACPI_EXCEPTION((AE_INFO, status, 270 ACPI_EXCEPTION((AE_INFO, status,
270 "Thread %lX could not acquire Mutex [%X]", 271 "Thread %p could not acquire Mutex [%X]",
271 (unsigned long)this_thread_id, mutex_id)); 272 ACPI_CAST_PTR(void, this_thread_id), mutex_id));
272 } 273 }
273 274
274 return (status); 275 return (status);
@@ -293,9 +294,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
293 ACPI_FUNCTION_NAME(ut_release_mutex); 294 ACPI_FUNCTION_NAME(ut_release_mutex);
294 295
295 this_thread_id = acpi_os_get_thread_id(); 296 this_thread_id = acpi_os_get_thread_id();
296 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 297 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n",
297 "Thread %lX releasing Mutex [%s]\n", 298 ACPI_CAST_PTR(void, this_thread_id),
298 (unsigned long)this_thread_id,
299 acpi_ut_get_mutex_name(mutex_id))); 299 acpi_ut_get_mutex_name(mutex_id)));
300 300
301 if (mutex_id > ACPI_MAX_MUTEX) { 301 if (mutex_id > ACPI_MAX_MUTEX) {
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index b22cec97ea19..c7a527c08a09 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -38,7 +38,6 @@
38#include <linux/hdreg.h> 38#include <linux/hdreg.h>
39#include <linux/spinlock.h> 39#include <linux/spinlock.h>
40#include <linux/compat.h> 40#include <linux/compat.h>
41#include <linux/blktrace_api.h>
42#include <asm/uaccess.h> 41#include <asm/uaccess.h>
43#include <asm/io.h> 42#include <asm/io.h>
44 43
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
index 60de5a01e71e..f703f5478246 100644
--- a/drivers/block/mg_disk.c
+++ b/drivers/block/mg_disk.c
@@ -22,13 +22,12 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/mg_disk.h>
25 26
26#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1) 27#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
27 28
28/* name for block device */ 29/* name for block device */
29#define MG_DISK_NAME "mgd" 30#define MG_DISK_NAME "mgd"
30/* name for platform device */
31#define MG_DEV_NAME "mg_disk"
32 31
33#define MG_DISK_MAJ 0 32#define MG_DISK_MAJ 0
34#define MG_DISK_MAX_PART 16 33#define MG_DISK_MAX_PART 16
@@ -103,33 +102,8 @@
103#define MG_TMAX_SWRST_TO_RDY 500 102#define MG_TMAX_SWRST_TO_RDY 500
104#define MG_TMAX_RSTOUT 3000 103#define MG_TMAX_RSTOUT 3000
105 104
106/* device attribution */
107/* use mflash as boot device */
108#define MG_BOOT_DEV (1 << 0)
109/* use mflash as storage device */
110#define MG_STORAGE_DEV (1 << 1)
111/* same as MG_STORAGE_DEV, but bootloader already done reset sequence */
112#define MG_STORAGE_DEV_SKIP_RST (1 << 2)
113
114#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST) 105#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST)
115 106
116/* names of GPIO resource */
117#define MG_RST_PIN "mg_rst"
118/* except MG_BOOT_DEV, reset-out pin should be assigned */
119#define MG_RSTOUT_PIN "mg_rstout"
120
121/* private driver data */
122struct mg_drv_data {
123 /* disk resource */
124 u32 use_polling;
125
126 /* device attribution */
127 u32 dev_attr;
128
129 /* internally used */
130 struct mg_host *host;
131};
132
133/* main structure for mflash driver */ 107/* main structure for mflash driver */
134struct mg_host { 108struct mg_host {
135 struct device *dev; 109 struct device *dev;
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index aaeeb544228a..34cbb7f3efa8 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -120,7 +120,7 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev,
120static int ps3disk_submit_request_sg(struct ps3_storage_device *dev, 120static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
121 struct request *req) 121 struct request *req)
122{ 122{
123 struct ps3disk_private *priv = dev->sbd.core.driver_data; 123 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
124 int write = rq_data_dir(req), res; 124 int write = rq_data_dir(req), res;
125 const char *op = write ? "write" : "read"; 125 const char *op = write ? "write" : "read";
126 u64 start_sector, sectors; 126 u64 start_sector, sectors;
@@ -168,7 +168,7 @@ static int ps3disk_submit_request_sg(struct ps3_storage_device *dev,
168static int ps3disk_submit_flush_request(struct ps3_storage_device *dev, 168static int ps3disk_submit_flush_request(struct ps3_storage_device *dev,
169 struct request *req) 169 struct request *req)
170{ 170{
171 struct ps3disk_private *priv = dev->sbd.core.driver_data; 171 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
172 u64 res; 172 u64 res;
173 173
174 dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__); 174 dev_dbg(&dev->sbd.core, "%s:%u: flush request\n", __func__, __LINE__);
@@ -213,7 +213,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev,
213static void ps3disk_request(struct request_queue *q) 213static void ps3disk_request(struct request_queue *q)
214{ 214{
215 struct ps3_storage_device *dev = q->queuedata; 215 struct ps3_storage_device *dev = q->queuedata;
216 struct ps3disk_private *priv = dev->sbd.core.driver_data; 216 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
217 217
218 if (priv->req) { 218 if (priv->req) {
219 dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__); 219 dev_dbg(&dev->sbd.core, "%s:%u busy\n", __func__, __LINE__);
@@ -245,7 +245,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
245 return IRQ_HANDLED; 245 return IRQ_HANDLED;
246 } 246 }
247 247
248 priv = dev->sbd.core.driver_data; 248 priv = ps3_system_bus_get_drvdata(&dev->sbd);
249 req = priv->req; 249 req = priv->req;
250 if (!req) { 250 if (!req) {
251 dev_dbg(&dev->sbd.core, 251 dev_dbg(&dev->sbd.core,
@@ -364,7 +364,7 @@ static void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs,
364 364
365static int ps3disk_identify(struct ps3_storage_device *dev) 365static int ps3disk_identify(struct ps3_storage_device *dev)
366{ 366{
367 struct ps3disk_private *priv = dev->sbd.core.driver_data; 367 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
368 struct lv1_ata_cmnd_block ata_cmnd; 368 struct lv1_ata_cmnd_block ata_cmnd;
369 u16 *id = dev->bounce_buf; 369 u16 *id = dev->bounce_buf;
370 u64 res; 370 u64 res;
@@ -445,7 +445,7 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
445 goto fail; 445 goto fail;
446 } 446 }
447 447
448 dev->sbd.core.driver_data = priv; 448 ps3_system_bus_set_drvdata(_dev, priv);
449 spin_lock_init(&priv->lock); 449 spin_lock_init(&priv->lock);
450 450
451 dev->bounce_size = BOUNCE_SIZE; 451 dev->bounce_size = BOUNCE_SIZE;
@@ -523,7 +523,7 @@ fail_free_bounce:
523 kfree(dev->bounce_buf); 523 kfree(dev->bounce_buf);
524fail_free_priv: 524fail_free_priv:
525 kfree(priv); 525 kfree(priv);
526 dev->sbd.core.driver_data = NULL; 526 ps3_system_bus_set_drvdata(_dev, NULL);
527fail: 527fail:
528 mutex_lock(&ps3disk_mask_mutex); 528 mutex_lock(&ps3disk_mask_mutex);
529 __clear_bit(devidx, &ps3disk_mask); 529 __clear_bit(devidx, &ps3disk_mask);
@@ -534,7 +534,7 @@ fail:
534static int ps3disk_remove(struct ps3_system_bus_device *_dev) 534static int ps3disk_remove(struct ps3_system_bus_device *_dev)
535{ 535{
536 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); 536 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
537 struct ps3disk_private *priv = dev->sbd.core.driver_data; 537 struct ps3disk_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
538 538
539 mutex_lock(&ps3disk_mask_mutex); 539 mutex_lock(&ps3disk_mask_mutex);
540 __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS, 540 __clear_bit(MINOR(disk_devt(priv->gendisk)) / PS3DISK_MINORS,
@@ -548,7 +548,7 @@ static int ps3disk_remove(struct ps3_system_bus_device *_dev)
548 ps3stor_teardown(dev); 548 ps3stor_teardown(dev);
549 kfree(dev->bounce_buf); 549 kfree(dev->bounce_buf);
550 kfree(priv); 550 kfree(priv);
551 dev->sbd.core.driver_data = NULL; 551 ps3_system_bus_set_drvdata(_dev, NULL);
552 return 0; 552 return 0;
553} 553}
554 554
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 8eddef373a91..095f97e60665 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -14,8 +14,10 @@
14#include <linux/seq_file.h> 14#include <linux/seq_file.h>
15 15
16#include <asm/firmware.h> 16#include <asm/firmware.h>
17#include <asm/iommu.h>
17#include <asm/lv1call.h> 18#include <asm/lv1call.h>
18#include <asm/ps3.h> 19#include <asm/ps3.h>
20#include <asm/ps3gpu.h>
19 21
20 22
21#define DEVICE_NAME "ps3vram" 23#define DEVICE_NAME "ps3vram"
@@ -45,8 +47,6 @@
45#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c 47#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c
46#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 48#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104
47 49
48#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
49
50#define CACHE_PAGE_PRESENT 1 50#define CACHE_PAGE_PRESENT 1
51#define CACHE_PAGE_DIRTY 2 51#define CACHE_PAGE_DIRTY 2
52 52
@@ -72,8 +72,7 @@ struct ps3vram_priv {
72 u64 memory_handle; 72 u64 memory_handle;
73 u64 context_handle; 73 u64 context_handle;
74 u32 *ctrl; 74 u32 *ctrl;
75 u32 *reports; 75 void *reports;
76 u8 __iomem *ddr_base;
77 u8 *xdr_buf; 76 u8 *xdr_buf;
78 77
79 u32 *fifo_base; 78 u32 *fifo_base;
@@ -81,8 +80,8 @@ struct ps3vram_priv {
81 80
82 struct ps3vram_cache cache; 81 struct ps3vram_cache cache;
83 82
84 /* Used to serialize cache/DMA operations */ 83 spinlock_t lock; /* protecting list of bios */
85 struct mutex lock; 84 struct bio_list list;
86}; 85};
87 86
88 87
@@ -103,15 +102,15 @@ static char *size = "256M";
103module_param(size, charp, 0); 102module_param(size, charp, 0);
104MODULE_PARM_DESC(size, "memory size"); 103MODULE_PARM_DESC(size, "memory size");
105 104
106static u32 *ps3vram_get_notifier(u32 *reports, int notifier) 105static u32 *ps3vram_get_notifier(void *reports, int notifier)
107{ 106{
108 return (void *)reports + DMA_NOTIFIER_OFFSET_BASE + 107 return reports + DMA_NOTIFIER_OFFSET_BASE +
109 DMA_NOTIFIER_SIZE * notifier; 108 DMA_NOTIFIER_SIZE * notifier;
110} 109}
111 110
112static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) 111static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
113{ 112{
114 struct ps3vram_priv *priv = dev->core.driver_data; 113 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
115 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); 114 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
116 int i; 115 int i;
117 116
@@ -122,7 +121,7 @@ static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev)
122static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, 121static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
123 unsigned int timeout_ms) 122 unsigned int timeout_ms)
124{ 123{
125 struct ps3vram_priv *priv = dev->core.driver_data; 124 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
126 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); 125 u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER);
127 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); 126 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
128 127
@@ -137,7 +136,7 @@ static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev,
137 136
138static void ps3vram_init_ring(struct ps3_system_bus_device *dev) 137static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
139{ 138{
140 struct ps3vram_priv *priv = dev->core.driver_data; 139 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
141 140
142 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; 141 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
143 priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; 142 priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET;
@@ -146,7 +145,7 @@ static void ps3vram_init_ring(struct ps3_system_bus_device *dev)
146static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, 145static int ps3vram_wait_ring(struct ps3_system_bus_device *dev,
147 unsigned int timeout_ms) 146 unsigned int timeout_ms)
148{ 147{
149 struct ps3vram_priv *priv = dev->core.driver_data; 148 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
150 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); 149 unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms);
151 150
152 do { 151 do {
@@ -175,7 +174,7 @@ static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag,
175 174
176static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) 175static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
177{ 176{
178 struct ps3vram_priv *priv = dev->core.driver_data; 177 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
179 int status; 178 int status;
180 179
181 ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); 180 ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET));
@@ -183,20 +182,17 @@ static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev)
183 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; 182 priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET;
184 183
185 /* asking the HV for a blit will kick the FIFO */ 184 /* asking the HV for a blit will kick the FIFO */
186 status = lv1_gpu_context_attribute(priv->context_handle, 185 status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0);
187 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
188 0, 0, 0);
189 if (status) 186 if (status)
190 dev_err(&dev->core, 187 dev_err(&dev->core, "%s: lv1_gpu_fb_blit failed %d\n",
191 "%s: lv1_gpu_context_attribute failed %d\n", __func__, 188 __func__, status);
192 status);
193 189
194 priv->fifo_ptr = priv->fifo_base; 190 priv->fifo_ptr = priv->fifo_base;
195} 191}
196 192
197static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) 193static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
198{ 194{
199 struct ps3vram_priv *priv = dev->core.driver_data; 195 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
200 int status; 196 int status;
201 197
202 mutex_lock(&ps3_gpu_mutex); 198 mutex_lock(&ps3_gpu_mutex);
@@ -205,13 +201,10 @@ static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
205 (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); 201 (priv->fifo_ptr - priv->fifo_base) * sizeof(u32);
206 202
207 /* asking the HV for a blit will kick the FIFO */ 203 /* asking the HV for a blit will kick the FIFO */
208 status = lv1_gpu_context_attribute(priv->context_handle, 204 status = lv1_gpu_fb_blit(priv->context_handle, 0, 0, 0, 0);
209 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0,
210 0, 0, 0);
211 if (status) 205 if (status)
212 dev_err(&dev->core, 206 dev_err(&dev->core, "%s: lv1_gpu_fb_blit failed %d\n",
213 "%s: lv1_gpu_context_attribute failed %d\n", __func__, 207 __func__, status);
214 status);
215 208
216 if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > 209 if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) >
217 FIFO_SIZE - 1024) { 210 FIFO_SIZE - 1024) {
@@ -225,7 +218,7 @@ static void ps3vram_fire_ring(struct ps3_system_bus_device *dev)
225 218
226static void ps3vram_bind(struct ps3_system_bus_device *dev) 219static void ps3vram_bind(struct ps3_system_bus_device *dev)
227{ 220{
228 struct ps3vram_priv *priv = dev->core.driver_data; 221 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
229 222
230 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); 223 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1);
231 ps3vram_out_ring(priv, 0x31337303); 224 ps3vram_out_ring(priv, 0x31337303);
@@ -248,7 +241,7 @@ static int ps3vram_upload(struct ps3_system_bus_device *dev,
248 unsigned int src_offset, unsigned int dst_offset, 241 unsigned int src_offset, unsigned int dst_offset,
249 int len, int count) 242 int len, int count)
250{ 243{
251 struct ps3vram_priv *priv = dev->core.driver_data; 244 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
252 245
253 ps3vram_begin_ring(priv, UPLOAD_SUBCH, 246 ps3vram_begin_ring(priv, UPLOAD_SUBCH,
254 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); 247 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
@@ -280,7 +273,7 @@ static int ps3vram_download(struct ps3_system_bus_device *dev,
280 unsigned int src_offset, unsigned int dst_offset, 273 unsigned int src_offset, unsigned int dst_offset,
281 int len, int count) 274 int len, int count)
282{ 275{
283 struct ps3vram_priv *priv = dev->core.driver_data; 276 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
284 277
285 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 278 ps3vram_begin_ring(priv, DOWNLOAD_SUBCH,
286 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); 279 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
@@ -310,7 +303,7 @@ static int ps3vram_download(struct ps3_system_bus_device *dev,
310 303
311static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry) 304static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry)
312{ 305{
313 struct ps3vram_priv *priv = dev->core.driver_data; 306 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
314 struct ps3vram_cache *cache = &priv->cache; 307 struct ps3vram_cache *cache = &priv->cache;
315 308
316 if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY)) 309 if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY))
@@ -332,7 +325,7 @@ static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry)
332static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry, 325static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry,
333 unsigned int address) 326 unsigned int address)
334{ 327{
335 struct ps3vram_priv *priv = dev->core.driver_data; 328 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
336 struct ps3vram_cache *cache = &priv->cache; 329 struct ps3vram_cache *cache = &priv->cache;
337 330
338 dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address); 331 dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address);
@@ -352,7 +345,7 @@ static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry,
352 345
353static void ps3vram_cache_flush(struct ps3_system_bus_device *dev) 346static void ps3vram_cache_flush(struct ps3_system_bus_device *dev)
354{ 347{
355 struct ps3vram_priv *priv = dev->core.driver_data; 348 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
356 struct ps3vram_cache *cache = &priv->cache; 349 struct ps3vram_cache *cache = &priv->cache;
357 int i; 350 int i;
358 351
@@ -366,7 +359,7 @@ static void ps3vram_cache_flush(struct ps3_system_bus_device *dev)
366static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev, 359static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev,
367 loff_t address) 360 loff_t address)
368{ 361{
369 struct ps3vram_priv *priv = dev->core.driver_data; 362 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
370 struct ps3vram_cache *cache = &priv->cache; 363 struct ps3vram_cache *cache = &priv->cache;
371 unsigned int base; 364 unsigned int base;
372 unsigned int offset; 365 unsigned int offset;
@@ -400,7 +393,7 @@ static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev,
400 393
401static int ps3vram_cache_init(struct ps3_system_bus_device *dev) 394static int ps3vram_cache_init(struct ps3_system_bus_device *dev)
402{ 395{
403 struct ps3vram_priv *priv = dev->core.driver_data; 396 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
404 397
405 priv->cache.page_count = CACHE_PAGE_COUNT; 398 priv->cache.page_count = CACHE_PAGE_COUNT;
406 priv->cache.page_size = CACHE_PAGE_SIZE; 399 priv->cache.page_size = CACHE_PAGE_SIZE;
@@ -419,7 +412,7 @@ static int ps3vram_cache_init(struct ps3_system_bus_device *dev)
419 412
420static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev) 413static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev)
421{ 414{
422 struct ps3vram_priv *priv = dev->core.driver_data; 415 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
423 416
424 ps3vram_cache_flush(dev); 417 ps3vram_cache_flush(dev);
425 kfree(priv->cache.tags); 418 kfree(priv->cache.tags);
@@ -428,7 +421,7 @@ static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev)
428static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, 421static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
429 size_t len, size_t *retlen, u_char *buf) 422 size_t len, size_t *retlen, u_char *buf)
430{ 423{
431 struct ps3vram_priv *priv = dev->core.driver_data; 424 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
432 unsigned int cached, count; 425 unsigned int cached, count;
433 426
434 dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__, 427 dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__,
@@ -449,8 +442,6 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
449 offset = (unsigned int) (from & (priv->cache.page_size - 1)); 442 offset = (unsigned int) (from & (priv->cache.page_size - 1));
450 avail = priv->cache.page_size - offset; 443 avail = priv->cache.page_size - offset;
451 444
452 mutex_lock(&priv->lock);
453
454 entry = ps3vram_cache_match(dev, from); 445 entry = ps3vram_cache_match(dev, from);
455 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; 446 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
456 447
@@ -462,8 +453,6 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
462 avail = count; 453 avail = count;
463 memcpy(buf, priv->xdr_buf + cached, avail); 454 memcpy(buf, priv->xdr_buf + cached, avail);
464 455
465 mutex_unlock(&priv->lock);
466
467 buf += avail; 456 buf += avail;
468 count -= avail; 457 count -= avail;
469 from += avail; 458 from += avail;
@@ -476,7 +465,7 @@ static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from,
476static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, 465static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
477 size_t len, size_t *retlen, const u_char *buf) 466 size_t len, size_t *retlen, const u_char *buf)
478{ 467{
479 struct ps3vram_priv *priv = dev->core.driver_data; 468 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
480 unsigned int cached, count; 469 unsigned int cached, count;
481 470
482 if (to >= priv->size) 471 if (to >= priv->size)
@@ -494,8 +483,6 @@ static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
494 offset = (unsigned int) (to & (priv->cache.page_size - 1)); 483 offset = (unsigned int) (to & (priv->cache.page_size - 1));
495 avail = priv->cache.page_size - offset; 484 avail = priv->cache.page_size - offset;
496 485
497 mutex_lock(&priv->lock);
498
499 entry = ps3vram_cache_match(dev, to); 486 entry = ps3vram_cache_match(dev, to);
500 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; 487 cached = CACHE_OFFSET + entry * priv->cache.page_size + offset;
501 488
@@ -509,8 +496,6 @@ static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to,
509 496
510 priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; 497 priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY;
511 498
512 mutex_unlock(&priv->lock);
513
514 buf += avail; 499 buf += avail;
515 count -= avail; 500 count -= avail;
516 to += avail; 501 to += avail;
@@ -543,28 +528,26 @@ static const struct file_operations ps3vram_proc_fops = {
543 528
544static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) 529static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
545{ 530{
546 struct ps3vram_priv *priv = dev->core.driver_data; 531 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
547 struct proc_dir_entry *pde; 532 struct proc_dir_entry *pde;
548 533
549 pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops); 534 pde = proc_create_data(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops,
550 if (!pde) { 535 priv);
536 if (!pde)
551 dev_warn(&dev->core, "failed to create /proc entry\n"); 537 dev_warn(&dev->core, "failed to create /proc entry\n");
552 return;
553 }
554 pde->data = priv;
555} 538}
556 539
557static int ps3vram_make_request(struct request_queue *q, struct bio *bio) 540static struct bio *ps3vram_do_bio(struct ps3_system_bus_device *dev,
541 struct bio *bio)
558{ 542{
559 struct ps3_system_bus_device *dev = q->queuedata; 543 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
560 int write = bio_data_dir(bio) == WRITE; 544 int write = bio_data_dir(bio) == WRITE;
561 const char *op = write ? "write" : "read"; 545 const char *op = write ? "write" : "read";
562 loff_t offset = bio->bi_sector << 9; 546 loff_t offset = bio->bi_sector << 9;
563 int error = 0; 547 int error = 0;
564 struct bio_vec *bvec; 548 struct bio_vec *bvec;
565 unsigned int i; 549 unsigned int i;
566 550 struct bio *next;
567 dev_dbg(&dev->core, "%s\n", __func__);
568 551
569 bio_for_each_segment(bvec, bio, i) { 552 bio_for_each_segment(bvec, bio, i) {
570 /* PS3 is ppc64, so we don't handle highmem */ 553 /* PS3 is ppc64, so we don't handle highmem */
@@ -585,6 +568,7 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
585 568
586 if (retlen != len) { 569 if (retlen != len) {
587 dev_err(&dev->core, "Short %s\n", op); 570 dev_err(&dev->core, "Short %s\n", op);
571 error = -EIO;
588 goto out; 572 goto out;
589 } 573 }
590 574
@@ -594,7 +578,35 @@ static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
594 dev_dbg(&dev->core, "%s completed\n", op); 578 dev_dbg(&dev->core, "%s completed\n", op);
595 579
596out: 580out:
581 spin_lock_irq(&priv->lock);
582 bio_list_pop(&priv->list);
583 next = bio_list_peek(&priv->list);
584 spin_unlock_irq(&priv->lock);
585
597 bio_endio(bio, error); 586 bio_endio(bio, error);
587 return next;
588}
589
590static int ps3vram_make_request(struct request_queue *q, struct bio *bio)
591{
592 struct ps3_system_bus_device *dev = q->queuedata;
593 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
594 int busy;
595
596 dev_dbg(&dev->core, "%s\n", __func__);
597
598 spin_lock_irq(&priv->lock);
599 busy = !bio_list_empty(&priv->list);
600 bio_list_add(&priv->list, bio);
601 spin_unlock_irq(&priv->lock);
602
603 if (busy)
604 return 0;
605
606 do {
607 bio = ps3vram_do_bio(dev, bio);
608 } while (bio);
609
598 return 0; 610 return 0;
599} 611}
600 612
@@ -604,8 +616,8 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
604 int error, status; 616 int error, status;
605 struct request_queue *queue; 617 struct request_queue *queue;
606 struct gendisk *gendisk; 618 struct gendisk *gendisk;
607 u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size, 619 u64 ddr_size, ddr_lpar, ctrl_lpar, info_lpar, reports_lpar,
608 reports_size; 620 reports_size, xdr_lpar;
609 char *rest; 621 char *rest;
610 622
611 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 623 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
@@ -614,10 +626,9 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
614 goto fail; 626 goto fail;
615 } 627 }
616 628
617 mutex_init(&priv->lock); 629 spin_lock_init(&priv->lock);
618 dev->core.driver_data = priv; 630 bio_list_init(&priv->list);
619 631 ps3_system_bus_set_drvdata(dev, priv);
620 priv = dev->core.driver_data;
621 632
622 /* Allocate XDR buffer (1MiB aligned) */ 633 /* Allocate XDR buffer (1MiB aligned) */
623 priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, 634 priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL,
@@ -636,7 +647,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
636 if (ps3_open_hv_device(dev)) { 647 if (ps3_open_hv_device(dev)) {
637 dev_err(&dev->core, "ps3_open_hv_device failed\n"); 648 dev_err(&dev->core, "ps3_open_hv_device failed\n");
638 error = -EAGAIN; 649 error = -EAGAIN;
639 goto out_close_gpu; 650 goto out_free_xdr_buf;
640 } 651 }
641 652
642 /* Request memory */ 653 /* Request memory */
@@ -660,7 +671,7 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
660 dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n", 671 dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n",
661 status); 672 status);
662 error = -ENOMEM; 673 error = -ENOMEM;
663 goto out_free_xdr_buf; 674 goto out_close_gpu;
664 } 675 }
665 676
666 /* Request context */ 677 /* Request context */
@@ -676,9 +687,11 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
676 } 687 }
677 688
678 /* Map XDR buffer to RSX */ 689 /* Map XDR buffer to RSX */
690 xdr_lpar = ps3_mm_phys_to_lpar(__pa(priv->xdr_buf));
679 status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, 691 status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
680 ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), 692 xdr_lpar, XDR_BUF_SIZE,
681 XDR_BUF_SIZE, 0); 693 CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
694 CBE_IOPTE_M);
682 if (status) { 695 if (status) {
683 dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n", 696 dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n",
684 status); 697 status);
@@ -686,19 +699,11 @@ static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev)
686 goto out_free_context; 699 goto out_free_context;
687 } 700 }
688 701
689 priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE);
690
691 if (!priv->ddr_base) {
692 dev_err(&dev->core, "ioremap DDR failed\n");
693 error = -ENOMEM;
694 goto out_free_context;
695 }
696
697 priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); 702 priv->ctrl = ioremap(ctrl_lpar, 64 * 1024);
698 if (!priv->ctrl) { 703 if (!priv->ctrl) {
699 dev_err(&dev->core, "ioremap CTRL failed\n"); 704 dev_err(&dev->core, "ioremap CTRL failed\n");
700 error = -ENOMEM; 705 error = -ENOMEM;
701 goto out_unmap_vram; 706 goto out_unmap_context;
702 } 707 }
703 708
704 priv->reports = ioremap(reports_lpar, reports_size); 709 priv->reports = ioremap(reports_lpar, reports_size);
@@ -775,8 +780,9 @@ out_unmap_reports:
775 iounmap(priv->reports); 780 iounmap(priv->reports);
776out_unmap_ctrl: 781out_unmap_ctrl:
777 iounmap(priv->ctrl); 782 iounmap(priv->ctrl);
778out_unmap_vram: 783out_unmap_context:
779 iounmap(priv->ddr_base); 784 lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, xdr_lpar,
785 XDR_BUF_SIZE, CBE_IOPTE_M);
780out_free_context: 786out_free_context:
781 lv1_gpu_context_free(priv->context_handle); 787 lv1_gpu_context_free(priv->context_handle);
782out_free_memory: 788out_free_memory:
@@ -787,14 +793,14 @@ out_free_xdr_buf:
787 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); 793 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
788fail_free_priv: 794fail_free_priv:
789 kfree(priv); 795 kfree(priv);
790 dev->core.driver_data = NULL; 796 ps3_system_bus_set_drvdata(dev, NULL);
791fail: 797fail:
792 return error; 798 return error;
793} 799}
794 800
795static int ps3vram_remove(struct ps3_system_bus_device *dev) 801static int ps3vram_remove(struct ps3_system_bus_device *dev)
796{ 802{
797 struct ps3vram_priv *priv = dev->core.driver_data; 803 struct ps3vram_priv *priv = ps3_system_bus_get_drvdata(dev);
798 804
799 del_gendisk(priv->gendisk); 805 del_gendisk(priv->gendisk);
800 put_disk(priv->gendisk); 806 put_disk(priv->gendisk);
@@ -803,13 +809,15 @@ static int ps3vram_remove(struct ps3_system_bus_device *dev)
803 ps3vram_cache_cleanup(dev); 809 ps3vram_cache_cleanup(dev);
804 iounmap(priv->reports); 810 iounmap(priv->reports);
805 iounmap(priv->ctrl); 811 iounmap(priv->ctrl);
806 iounmap(priv->ddr_base); 812 lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF,
813 ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)),
814 XDR_BUF_SIZE, CBE_IOPTE_M);
807 lv1_gpu_context_free(priv->context_handle); 815 lv1_gpu_context_free(priv->context_handle);
808 lv1_gpu_memory_free(priv->memory_handle); 816 lv1_gpu_memory_free(priv->memory_handle);
809 ps3_close_hv_device(dev); 817 ps3_close_hv_device(dev);
810 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); 818 free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE));
811 kfree(priv); 819 kfree(priv);
812 dev->core.driver_data = NULL; 820 ps3_system_bus_set_drvdata(dev, NULL);
813 return 0; 821 return 0;
814} 822}
815 823
diff --git a/drivers/char/hvc_iucv.c b/drivers/char/hvc_iucv.c
index 54481a887769..86105efb4eb6 100644
--- a/drivers/char/hvc_iucv.c
+++ b/drivers/char/hvc_iucv.c
@@ -4,7 +4,7 @@
4 * This HVC device driver provides terminal access using 4 * This HVC device driver provides terminal access using
5 * z/VM IUCV communication paths. 5 * z/VM IUCV communication paths.
6 * 6 *
7 * Copyright IBM Corp. 2008 7 * Copyright IBM Corp. 2008, 2009
8 * 8 *
9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com> 9 * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
10 */ 10 */
@@ -15,6 +15,7 @@
15#include <asm/ebcdic.h> 15#include <asm/ebcdic.h>
16#include <linux/ctype.h> 16#include <linux/ctype.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/device.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/mempool.h> 20#include <linux/mempool.h>
20#include <linux/moduleparam.h> 21#include <linux/moduleparam.h>
@@ -74,6 +75,7 @@ struct hvc_iucv_private {
74 wait_queue_head_t sndbuf_waitq; /* wait for send completion */ 75 wait_queue_head_t sndbuf_waitq; /* wait for send completion */
75 struct list_head tty_outqueue; /* outgoing IUCV messages */ 76 struct list_head tty_outqueue; /* outgoing IUCV messages */
76 struct list_head tty_inqueue; /* incoming IUCV messages */ 77 struct list_head tty_inqueue; /* incoming IUCV messages */
78 struct device *dev; /* device structure */
77}; 79};
78 80
79struct iucv_tty_buffer { 81struct iucv_tty_buffer {
@@ -542,7 +544,68 @@ static void flush_sndbuf_sync(struct hvc_iucv_private *priv)
542 544
543 if (sync_wait) 545 if (sync_wait)
544 wait_event_timeout(priv->sndbuf_waitq, 546 wait_event_timeout(priv->sndbuf_waitq,
545 tty_outqueue_empty(priv), HZ); 547 tty_outqueue_empty(priv), HZ/10);
548}
549
550/**
551 * hvc_iucv_hangup() - Sever IUCV path and schedule hvc tty hang up
552 * @priv: Pointer to hvc_iucv_private structure
553 *
554 * This routine severs an existing IUCV communication path and hangs
555 * up the underlying HVC terminal device.
556 * The hang-up occurs only if an IUCV communication path is established;
557 * otherwise there is no need to hang up the terminal device.
558 *
559 * The IUCV HVC hang-up is separated into two steps:
560 * 1. After the IUCV path has been severed, the iucv_state is set to
561 * IUCV_SEVERED.
562 * 2. Later, when the HVC thread calls hvc_iucv_get_chars(), the
563 * IUCV_SEVERED state causes the tty hang-up in the HVC layer.
564 *
565 * If the tty has not yet been opened, clean up the hvc_iucv_private
566 * structure to allow re-connects.
567 * If the tty has been opened, let get_chars() return -EPIPE to signal
568 * the HVC layer to hang up the tty and, if so, wake up the HVC thread
569 * to call get_chars()...
570 *
571 * Special notes on hanging up a HVC terminal instantiated as console:
572 * Hang-up: 1. do_tty_hangup() replaces file ops (= hung_up_tty_fops)
573 * 2. do_tty_hangup() calls tty->ops->close() for console_filp
574 * => no hangup notifier is called by HVC (default)
575 * 2. hvc_close() returns because of tty_hung_up_p(filp)
576 * => no delete notifier is called!
577 * Finally, the back-end is not being notified, thus, the tty session is
578 * kept active (TTY_OPEN) to be ready for re-connects.
579 *
580 * Locking: spin_lock(&priv->lock) w/o disabling bh
581 */
582static void hvc_iucv_hangup(struct hvc_iucv_private *priv)
583{
584 struct iucv_path *path;
585
586 path = NULL;
587 spin_lock(&priv->lock);
588 if (priv->iucv_state == IUCV_CONNECTED) {
589 path = priv->path;
590 priv->path = NULL;
591 priv->iucv_state = IUCV_SEVERED;
592 if (priv->tty_state == TTY_CLOSED)
593 hvc_iucv_cleanup(priv);
594 else
595 /* console is special (see above) */
596 if (priv->is_console) {
597 hvc_iucv_cleanup(priv);
598 priv->tty_state = TTY_OPENED;
599 } else
600 hvc_kick();
601 }
602 spin_unlock(&priv->lock);
603
604 /* finally sever path (outside of priv->lock due to lock ordering) */
605 if (path) {
606 iucv_path_sever(path, NULL);
607 iucv_path_free(path);
608 }
546} 609}
547 610
548/** 611/**
@@ -735,11 +798,8 @@ out_path_handled:
735 * @ipuser: User specified data for this path 798 * @ipuser: User specified data for this path
736 * (AF_IUCV: port/service name and originator port) 799 * (AF_IUCV: port/service name and originator port)
737 * 800 *
738 * The function also severs the path (as required by the IUCV protocol) and 801 * This function calls the hvc_iucv_hangup() function for the
739 * sets the iucv state to IUCV_SEVERED for the associated struct 802 * respective IUCV HVC terminal.
740 * hvc_iucv_private instance. Later, the IUCV_SEVERED state triggers a tty
741 * hangup (hvc_iucv_get_chars() / hvc_iucv_write()).
742 * If tty portion of the HVC is closed, clean up the outqueue.
743 * 803 *
744 * Locking: struct hvc_iucv_private->lock 804 * Locking: struct hvc_iucv_private->lock
745 */ 805 */
@@ -747,33 +807,7 @@ static void hvc_iucv_path_severed(struct iucv_path *path, u8 ipuser[16])
747{ 807{
748 struct hvc_iucv_private *priv = path->private; 808 struct hvc_iucv_private *priv = path->private;
749 809
750 spin_lock(&priv->lock); 810 hvc_iucv_hangup(priv);
751 priv->iucv_state = IUCV_SEVERED;
752
753 /* If the tty has not yet been opened, clean up the hvc_iucv_private
754 * structure to allow re-connects.
755 * This is also done for our console device because console hangups
756 * are handled specially and no notifier is called by HVC.
757 * The tty session is active (TTY_OPEN) and ready for re-connects...
758 *
759 * If it has been opened, let get_chars() return -EPIPE to signal the
760 * HVC layer to hang up the tty.
761 * If so, we need to wake up the HVC thread to call get_chars()...
762 */
763 priv->path = NULL;
764 if (priv->tty_state == TTY_CLOSED)
765 hvc_iucv_cleanup(priv);
766 else
767 if (priv->is_console) {
768 hvc_iucv_cleanup(priv);
769 priv->tty_state = TTY_OPENED;
770 } else
771 hvc_kick();
772 spin_unlock(&priv->lock);
773
774 /* finally sever path (outside of priv->lock due to lock ordering) */
775 iucv_path_sever(path, ipuser);
776 iucv_path_free(path);
777} 811}
778 812
779/** 813/**
@@ -853,6 +887,37 @@ static void hvc_iucv_msg_complete(struct iucv_path *path,
853 destroy_tty_buffer_list(&list_remove); 887 destroy_tty_buffer_list(&list_remove);
854} 888}
855 889
890/**
891 * hvc_iucv_pm_freeze() - Freeze PM callback
892 * @dev: IUVC HVC terminal device
893 *
894 * Sever an established IUCV communication path and
895 * trigger a hang-up of the underlying HVC terminal.
896 */
897static int hvc_iucv_pm_freeze(struct device *dev)
898{
899 struct hvc_iucv_private *priv = dev_get_drvdata(dev);
900
901 local_bh_disable();
902 hvc_iucv_hangup(priv);
903 local_bh_enable();
904
905 return 0;
906}
907
908/**
909 * hvc_iucv_pm_restore_thaw() - Thaw and restore PM callback
910 * @dev: IUVC HVC terminal device
911 *
912 * Wake up the HVC thread to trigger hang-up and respective
913 * HVC back-end notifier invocations.
914 */
915static int hvc_iucv_pm_restore_thaw(struct device *dev)
916{
917 hvc_kick();
918 return 0;
919}
920
856 921
857/* HVC operations */ 922/* HVC operations */
858static struct hv_ops hvc_iucv_ops = { 923static struct hv_ops hvc_iucv_ops = {
@@ -863,6 +928,20 @@ static struct hv_ops hvc_iucv_ops = {
863 .notifier_hangup = hvc_iucv_notifier_hangup, 928 .notifier_hangup = hvc_iucv_notifier_hangup,
864}; 929};
865 930
931/* Suspend / resume device operations */
932static struct dev_pm_ops hvc_iucv_pm_ops = {
933 .freeze = hvc_iucv_pm_freeze,
934 .thaw = hvc_iucv_pm_restore_thaw,
935 .restore = hvc_iucv_pm_restore_thaw,
936};
937
938/* IUCV HVC device driver */
939static struct device_driver hvc_iucv_driver = {
940 .name = KMSG_COMPONENT,
941 .bus = &iucv_bus,
942 .pm = &hvc_iucv_pm_ops,
943};
944
866/** 945/**
867 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance 946 * hvc_iucv_alloc() - Allocates a new struct hvc_iucv_private instance
868 * @id: hvc_iucv_table index 947 * @id: hvc_iucv_table index
@@ -897,14 +976,12 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
897 /* set console flag */ 976 /* set console flag */
898 priv->is_console = is_console; 977 priv->is_console = is_console;
899 978
900 /* finally allocate hvc */ 979 /* allocate hvc device */
901 priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id, /* PAGE_SIZE */ 980 priv->hvc = hvc_alloc(HVC_IUCV_MAGIC + id, /* PAGE_SIZE */
902 HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256); 981 HVC_IUCV_MAGIC + id, &hvc_iucv_ops, 256);
903 if (IS_ERR(priv->hvc)) { 982 if (IS_ERR(priv->hvc)) {
904 rc = PTR_ERR(priv->hvc); 983 rc = PTR_ERR(priv->hvc);
905 free_page((unsigned long) priv->sndbuf); 984 goto out_error_hvc;
906 kfree(priv);
907 return rc;
908 } 985 }
909 986
910 /* notify HVC thread instead of using polling */ 987 /* notify HVC thread instead of using polling */
@@ -915,8 +992,45 @@ static int __init hvc_iucv_alloc(int id, unsigned int is_console)
915 memcpy(priv->srv_name, name, 8); 992 memcpy(priv->srv_name, name, 8);
916 ASCEBC(priv->srv_name, 8); 993 ASCEBC(priv->srv_name, 8);
917 994
995 /* create and setup device */
996 priv->dev = kzalloc(sizeof(*priv->dev), GFP_KERNEL);
997 if (!priv->dev) {
998 rc = -ENOMEM;
999 goto out_error_dev;
1000 }
1001 dev_set_name(priv->dev, "hvc_iucv%d", id);
1002 dev_set_drvdata(priv->dev, priv);
1003 priv->dev->bus = &iucv_bus;
1004 priv->dev->parent = iucv_root;
1005 priv->dev->driver = &hvc_iucv_driver;
1006 priv->dev->release = (void (*)(struct device *)) kfree;
1007 rc = device_register(priv->dev);
1008 if (rc) {
1009 kfree(priv->dev);
1010 goto out_error_dev;
1011 }
1012
918 hvc_iucv_table[id] = priv; 1013 hvc_iucv_table[id] = priv;
919 return 0; 1014 return 0;
1015
1016out_error_dev:
1017 hvc_remove(priv->hvc);
1018out_error_hvc:
1019 free_page((unsigned long) priv->sndbuf);
1020 kfree(priv);
1021
1022 return rc;
1023}
1024
1025/**
1026 * hvc_iucv_destroy() - Destroy and free hvc_iucv_private instances
1027 */
1028static void __init hvc_iucv_destroy(struct hvc_iucv_private *priv)
1029{
1030 hvc_remove(priv->hvc);
1031 device_unregister(priv->dev);
1032 free_page((unsigned long) priv->sndbuf);
1033 kfree(priv);
920} 1034}
921 1035
922/** 1036/**
@@ -1109,6 +1223,11 @@ static int __init hvc_iucv_init(void)
1109 goto out_error; 1223 goto out_error;
1110 } 1224 }
1111 1225
1226 /* register IUCV HVC device driver */
1227 rc = driver_register(&hvc_iucv_driver);
1228 if (rc)
1229 goto out_error;
1230
1112 /* parse hvc_iucv_allow string and create z/VM user ID filter list */ 1231 /* parse hvc_iucv_allow string and create z/VM user ID filter list */
1113 if (hvc_iucv_filter_string) { 1232 if (hvc_iucv_filter_string) {
1114 rc = hvc_iucv_setup_filter(hvc_iucv_filter_string); 1233 rc = hvc_iucv_setup_filter(hvc_iucv_filter_string);
@@ -1183,15 +1302,14 @@ out_error_iucv:
1183 iucv_unregister(&hvc_iucv_handler, 0); 1302 iucv_unregister(&hvc_iucv_handler, 0);
1184out_error_hvc: 1303out_error_hvc:
1185 for (i = 0; i < hvc_iucv_devices; i++) 1304 for (i = 0; i < hvc_iucv_devices; i++)
1186 if (hvc_iucv_table[i]) { 1305 if (hvc_iucv_table[i])
1187 if (hvc_iucv_table[i]->hvc) 1306 hvc_iucv_destroy(hvc_iucv_table[i]);
1188 hvc_remove(hvc_iucv_table[i]->hvc);
1189 kfree(hvc_iucv_table[i]);
1190 }
1191out_error_memory: 1307out_error_memory:
1192 mempool_destroy(hvc_iucv_mempool); 1308 mempool_destroy(hvc_iucv_mempool);
1193 kmem_cache_destroy(hvc_iucv_buffer_cache); 1309 kmem_cache_destroy(hvc_iucv_buffer_cache);
1194out_error: 1310out_error:
1311 if (hvc_iucv_filter)
1312 kfree(hvc_iucv_filter);
1195 hvc_iucv_devices = 0; /* ensure that we do not provide any device */ 1313 hvc_iucv_devices = 0; /* ensure that we do not provide any device */
1196 return rc; 1314 return rc;
1197} 1315}
diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c
index afbe45676d71..f424d394a286 100644
--- a/drivers/char/ps3flash.c
+++ b/drivers/char/ps3flash.c
@@ -33,48 +33,64 @@
33 33
34struct ps3flash_private { 34struct ps3flash_private {
35 struct mutex mutex; /* Bounce buffer mutex */ 35 struct mutex mutex; /* Bounce buffer mutex */
36 u64 chunk_sectors;
37 int tag; /* Start sector of buffer, -1 if invalid */
38 bool dirty;
36}; 39};
37 40
38static struct ps3_storage_device *ps3flash_dev; 41static struct ps3_storage_device *ps3flash_dev;
39 42
40static ssize_t ps3flash_read_write_sectors(struct ps3_storage_device *dev, 43static int ps3flash_read_write_sectors(struct ps3_storage_device *dev,
41 u64 lpar, u64 start_sector, 44 u64 start_sector, int write)
42 u64 sectors, int write)
43{ 45{
44 u64 res = ps3stor_read_write_sectors(dev, lpar, start_sector, sectors, 46 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
47 u64 res = ps3stor_read_write_sectors(dev, dev->bounce_lpar,
48 start_sector, priv->chunk_sectors,
45 write); 49 write);
46 if (res) { 50 if (res) {
47 dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__, 51 dev_err(&dev->sbd.core, "%s:%u: %s failed 0x%llx\n", __func__,
48 __LINE__, write ? "write" : "read", res); 52 __LINE__, write ? "write" : "read", res);
49 return -EIO; 53 return -EIO;
50 } 54 }
51 return sectors; 55 return 0;
52} 56}
53 57
54static ssize_t ps3flash_read_sectors(struct ps3_storage_device *dev, 58static int ps3flash_writeback(struct ps3_storage_device *dev)
55 u64 start_sector, u64 sectors,
56 unsigned int sector_offset)
57{ 59{
58 u64 max_sectors, lpar; 60 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
61 int res;
59 62
60 max_sectors = dev->bounce_size / dev->blk_size; 63 if (!priv->dirty || priv->tag < 0)
61 if (sectors > max_sectors) { 64 return 0;
62 dev_dbg(&dev->sbd.core, "%s:%u Limiting sectors to %llu\n",
63 __func__, __LINE__, max_sectors);
64 sectors = max_sectors;
65 }
66 65
67 lpar = dev->bounce_lpar + sector_offset * dev->blk_size; 66 res = ps3flash_read_write_sectors(dev, priv->tag, 1);
68 return ps3flash_read_write_sectors(dev, lpar, start_sector, sectors, 67 if (res)
69 0); 68 return res;
69
70 priv->dirty = false;
71 return 0;
70} 72}
71 73
72static ssize_t ps3flash_write_chunk(struct ps3_storage_device *dev, 74static int ps3flash_fetch(struct ps3_storage_device *dev, u64 start_sector)
73 u64 start_sector)
74{ 75{
75 u64 sectors = dev->bounce_size / dev->blk_size; 76 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
76 return ps3flash_read_write_sectors(dev, dev->bounce_lpar, start_sector, 77 int res;
77 sectors, 1); 78
79 if (start_sector == priv->tag)
80 return 0;
81
82 res = ps3flash_writeback(dev);
83 if (res)
84 return res;
85
86 priv->tag = -1;
87
88 res = ps3flash_read_write_sectors(dev, start_sector, 0);
89 if (res)
90 return res;
91
92 priv->tag = start_sector;
93 return 0;
78} 94}
79 95
80static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin) 96static loff_t ps3flash_llseek(struct file *file, loff_t offset, int origin)
@@ -104,18 +120,19 @@ out:
104 return res; 120 return res;
105} 121}
106 122
107static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count, 123static ssize_t ps3flash_read(char __user *userbuf, void *kernelbuf,
108 loff_t *pos) 124 size_t count, loff_t *pos)
109{ 125{
110 struct ps3_storage_device *dev = ps3flash_dev; 126 struct ps3_storage_device *dev = ps3flash_dev;
111 struct ps3flash_private *priv = dev->sbd.core.driver_data; 127 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
112 u64 size, start_sector, end_sector, offset; 128 u64 size, sector, offset;
113 ssize_t sectors_read; 129 int res;
114 size_t remaining, n; 130 size_t remaining, n;
131 const void *src;
115 132
116 dev_dbg(&dev->sbd.core, 133 dev_dbg(&dev->sbd.core,
117 "%s:%u: Reading %zu bytes at position %lld to user 0x%p\n", 134 "%s:%u: Reading %zu bytes at position %lld to U0x%p/K0x%p\n",
118 __func__, __LINE__, count, *pos, buf); 135 __func__, __LINE__, count, *pos, userbuf, kernelbuf);
119 136
120 size = dev->regions[dev->region_idx].size*dev->blk_size; 137 size = dev->regions[dev->region_idx].size*dev->blk_size;
121 if (*pos >= size || !count) 138 if (*pos >= size || !count)
@@ -128,61 +145,63 @@ static ssize_t ps3flash_read(struct file *file, char __user *buf, size_t count,
128 count = size - *pos; 145 count = size - *pos;
129 } 146 }
130 147
131 start_sector = *pos / dev->blk_size; 148 sector = *pos / dev->bounce_size * priv->chunk_sectors;
132 offset = *pos % dev->blk_size; 149 offset = *pos % dev->bounce_size;
133 end_sector = DIV_ROUND_UP(*pos + count, dev->blk_size);
134 150
135 remaining = count; 151 remaining = count;
136 do { 152 do {
153 n = min_t(u64, remaining, dev->bounce_size - offset);
154 src = dev->bounce_buf + offset;
155
137 mutex_lock(&priv->mutex); 156 mutex_lock(&priv->mutex);
138 157
139 sectors_read = ps3flash_read_sectors(dev, start_sector, 158 res = ps3flash_fetch(dev, sector);
140 end_sector-start_sector, 159 if (res)
141 0);
142 if (sectors_read < 0) {
143 mutex_unlock(&priv->mutex);
144 goto fail; 160 goto fail;
145 }
146 161
147 n = min_t(u64, remaining, sectors_read*dev->blk_size-offset);
148 dev_dbg(&dev->sbd.core, 162 dev_dbg(&dev->sbd.core,
149 "%s:%u: copy %lu bytes from 0x%p to user 0x%p\n", 163 "%s:%u: copy %lu bytes from 0x%p to U0x%p/K0x%p\n",
150 __func__, __LINE__, n, dev->bounce_buf+offset, buf); 164 __func__, __LINE__, n, src, userbuf, kernelbuf);
151 if (copy_to_user(buf, dev->bounce_buf+offset, n)) { 165 if (userbuf) {
152 mutex_unlock(&priv->mutex); 166 if (copy_to_user(userbuf, src, n)) {
153 sectors_read = -EFAULT; 167 res = -EFAULT;
154 goto fail; 168 goto fail;
169 }
170 userbuf += n;
171 }
172 if (kernelbuf) {
173 memcpy(kernelbuf, src, n);
174 kernelbuf += n;
155 } 175 }
156 176
157 mutex_unlock(&priv->mutex); 177 mutex_unlock(&priv->mutex);
158 178
159 *pos += n; 179 *pos += n;
160 buf += n;
161 remaining -= n; 180 remaining -= n;
162 start_sector += sectors_read; 181 sector += priv->chunk_sectors;
163 offset = 0; 182 offset = 0;
164 } while (remaining > 0); 183 } while (remaining > 0);
165 184
166 return count; 185 return count;
167 186
168fail: 187fail:
169 return sectors_read; 188 mutex_unlock(&priv->mutex);
189 return res;
170} 190}
171 191
172static ssize_t ps3flash_write(struct file *file, const char __user *buf, 192static ssize_t ps3flash_write(const char __user *userbuf,
173 size_t count, loff_t *pos) 193 const void *kernelbuf, size_t count, loff_t *pos)
174{ 194{
175 struct ps3_storage_device *dev = ps3flash_dev; 195 struct ps3_storage_device *dev = ps3flash_dev;
176 struct ps3flash_private *priv = dev->sbd.core.driver_data; 196 struct ps3flash_private *priv = ps3_system_bus_get_drvdata(&dev->sbd);
177 u64 size, chunk_sectors, start_write_sector, end_write_sector, 197 u64 size, sector, offset;
178 end_read_sector, start_read_sector, head, tail, offset; 198 int res = 0;
179 ssize_t res;
180 size_t remaining, n; 199 size_t remaining, n;
181 unsigned int sec_off; 200 void *dst;
182 201
183 dev_dbg(&dev->sbd.core, 202 dev_dbg(&dev->sbd.core,
184 "%s:%u: Writing %zu bytes at position %lld from user 0x%p\n", 203 "%s:%u: Writing %zu bytes at position %lld from U0x%p/K0x%p\n",
185 __func__, __LINE__, count, *pos, buf); 204 __func__, __LINE__, count, *pos, userbuf, kernelbuf);
186 205
187 size = dev->regions[dev->region_idx].size*dev->blk_size; 206 size = dev->regions[dev->region_idx].size*dev->blk_size;
188 if (*pos >= size || !count) 207 if (*pos >= size || !count)
@@ -195,89 +214,46 @@ static ssize_t ps3flash_write(struct file *file, const char __user *buf,
195 count = size - *pos; 214 count = size - *pos;
196 } 215 }
197 216
198 chunk_sectors = dev->bounce_size / dev->blk_size; 217 sector = *pos / dev->bounce_size * priv->chunk_sectors;
199
200 start_write_sector = *pos / dev->bounce_size * chunk_sectors;
201 offset = *pos % dev->bounce_size; 218 offset = *pos % dev->bounce_size;
202 end_write_sector = DIV_ROUND_UP(*pos + count, dev->bounce_size) *
203 chunk_sectors;
204
205 end_read_sector = DIV_ROUND_UP(*pos, dev->blk_size);
206 start_read_sector = (*pos + count) / dev->blk_size;
207
208 /*
209 * As we have to write in 256 KiB chunks, while we can read in blk_size
210 * (usually 512 bytes) chunks, we perform the following steps:
211 * 1. Read from start_write_sector to end_read_sector ("head")
212 * 2. Read from start_read_sector to end_write_sector ("tail")
213 * 3. Copy data to buffer
214 * 4. Write from start_write_sector to end_write_sector
215 * All of this is complicated by using only one 256 KiB bounce buffer.
216 */
217
218 head = end_read_sector - start_write_sector;
219 tail = end_write_sector - start_read_sector;
220 219
221 remaining = count; 220 remaining = count;
222 do { 221 do {
222 n = min_t(u64, remaining, dev->bounce_size - offset);
223 dst = dev->bounce_buf + offset;
224
223 mutex_lock(&priv->mutex); 225 mutex_lock(&priv->mutex);
224 226
225 if (end_read_sector >= start_read_sector) { 227 if (n != dev->bounce_size)
226 /* Merge head and tail */ 228 res = ps3flash_fetch(dev, sector);
227 dev_dbg(&dev->sbd.core, 229 else if (sector != priv->tag)
228 "Merged head and tail: %llu sectors at %llu\n", 230 res = ps3flash_writeback(dev);
229 chunk_sectors, start_write_sector); 231 if (res)
230 res = ps3flash_read_sectors(dev, start_write_sector, 232 goto fail;
231 chunk_sectors, 0); 233
232 if (res < 0) 234 dev_dbg(&dev->sbd.core,
235 "%s:%u: copy %lu bytes from U0x%p/K0x%p to 0x%p\n",
236 __func__, __LINE__, n, userbuf, kernelbuf, dst);
237 if (userbuf) {
238 if (copy_from_user(dst, userbuf, n)) {
239 res = -EFAULT;
233 goto fail; 240 goto fail;
234 } else {
235 if (head) {
236 /* Read head */
237 dev_dbg(&dev->sbd.core,
238 "head: %llu sectors at %llu\n", head,
239 start_write_sector);
240 res = ps3flash_read_sectors(dev,
241 start_write_sector,
242 head, 0);
243 if (res < 0)
244 goto fail;
245 }
246 if (start_read_sector <
247 start_write_sector+chunk_sectors) {
248 /* Read tail */
249 dev_dbg(&dev->sbd.core,
250 "tail: %llu sectors at %llu\n", tail,
251 start_read_sector);
252 sec_off = start_read_sector-start_write_sector;
253 res = ps3flash_read_sectors(dev,
254 start_read_sector,
255 tail, sec_off);
256 if (res < 0)
257 goto fail;
258 } 241 }
242 userbuf += n;
259 } 243 }
260 244 if (kernelbuf) {
261 n = min_t(u64, remaining, dev->bounce_size-offset); 245 memcpy(dst, kernelbuf, n);
262 dev_dbg(&dev->sbd.core, 246 kernelbuf += n;
263 "%s:%u: copy %lu bytes from user 0x%p to 0x%p\n",
264 __func__, __LINE__, n, buf, dev->bounce_buf+offset);
265 if (copy_from_user(dev->bounce_buf+offset, buf, n)) {
266 res = -EFAULT;
267 goto fail;
268 } 247 }
269 248
270 res = ps3flash_write_chunk(dev, start_write_sector); 249 priv->tag = sector;
271 if (res < 0) 250 priv->dirty = true;
272 goto fail;
273 251
274 mutex_unlock(&priv->mutex); 252 mutex_unlock(&priv->mutex);
275 253
276 *pos += n; 254 *pos += n;
277 buf += n;
278 remaining -= n; 255 remaining -= n;
279 start_write_sector += chunk_sectors; 256 sector += priv->chunk_sectors;
280 head = 0;
281 offset = 0; 257 offset = 0;
282 } while (remaining > 0); 258 } while (remaining > 0);
283 259
@@ -288,6 +264,51 @@ fail:
288 return res; 264 return res;
289} 265}
290 266
267static ssize_t ps3flash_user_read(struct file *file, char __user *buf,
268 size_t count, loff_t *pos)
269{
270 return ps3flash_read(buf, NULL, count, pos);
271}
272
273static ssize_t ps3flash_user_write(struct file *file, const char __user *buf,
274 size_t count, loff_t *pos)
275{
276 return ps3flash_write(buf, NULL, count, pos);
277}
278
279static ssize_t ps3flash_kernel_read(void *buf, size_t count, loff_t pos)
280{
281 return ps3flash_read(NULL, buf, count, &pos);
282}
283
284static ssize_t ps3flash_kernel_write(const void *buf, size_t count,
285 loff_t pos)
286{
287 ssize_t res;
288 int wb;
289
290 res = ps3flash_write(NULL, buf, count, &pos);
291 if (res < 0)
292 return res;
293
294 /* Make kernel writes synchronous */
295 wb = ps3flash_writeback(ps3flash_dev);
296 if (wb)
297 return wb;
298
299 return res;
300}
301
302static int ps3flash_flush(struct file *file, fl_owner_t id)
303{
304 return ps3flash_writeback(ps3flash_dev);
305}
306
307static int ps3flash_fsync(struct file *file, struct dentry *dentry,
308 int datasync)
309{
310 return ps3flash_writeback(ps3flash_dev);
311}
291 312
292static irqreturn_t ps3flash_interrupt(int irq, void *data) 313static irqreturn_t ps3flash_interrupt(int irq, void *data)
293{ 314{
@@ -312,12 +333,18 @@ static irqreturn_t ps3flash_interrupt(int irq, void *data)
312 return IRQ_HANDLED; 333 return IRQ_HANDLED;
313} 334}
314 335
315
316static const struct file_operations ps3flash_fops = { 336static const struct file_operations ps3flash_fops = {
317 .owner = THIS_MODULE, 337 .owner = THIS_MODULE,
318 .llseek = ps3flash_llseek, 338 .llseek = ps3flash_llseek,
319 .read = ps3flash_read, 339 .read = ps3flash_user_read,
320 .write = ps3flash_write, 340 .write = ps3flash_user_write,
341 .flush = ps3flash_flush,
342 .fsync = ps3flash_fsync,
343};
344
345static const struct ps3_os_area_flash_ops ps3flash_kernel_ops = {
346 .read = ps3flash_kernel_read,
347 .write = ps3flash_kernel_write,
321}; 348};
322 349
323static struct miscdevice ps3flash_misc = { 350static struct miscdevice ps3flash_misc = {
@@ -366,11 +393,13 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
366 goto fail; 393 goto fail;
367 } 394 }
368 395
369 dev->sbd.core.driver_data = priv; 396 ps3_system_bus_set_drvdata(&dev->sbd, priv);
370 mutex_init(&priv->mutex); 397 mutex_init(&priv->mutex);
398 priv->tag = -1;
371 399
372 dev->bounce_size = ps3flash_bounce_buffer.size; 400 dev->bounce_size = ps3flash_bounce_buffer.size;
373 dev->bounce_buf = ps3flash_bounce_buffer.address; 401 dev->bounce_buf = ps3flash_bounce_buffer.address;
402 priv->chunk_sectors = dev->bounce_size / dev->blk_size;
374 403
375 error = ps3stor_setup(dev, ps3flash_interrupt); 404 error = ps3stor_setup(dev, ps3flash_interrupt);
376 if (error) 405 if (error)
@@ -386,13 +415,15 @@ static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev)
386 415
387 dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n", 416 dev_info(&dev->sbd.core, "%s:%u: registered misc device %d\n",
388 __func__, __LINE__, ps3flash_misc.minor); 417 __func__, __LINE__, ps3flash_misc.minor);
418
419 ps3_os_area_flash_register(&ps3flash_kernel_ops);
389 return 0; 420 return 0;
390 421
391fail_teardown: 422fail_teardown:
392 ps3stor_teardown(dev); 423 ps3stor_teardown(dev);
393fail_free_priv: 424fail_free_priv:
394 kfree(priv); 425 kfree(priv);
395 dev->sbd.core.driver_data = NULL; 426 ps3_system_bus_set_drvdata(&dev->sbd, NULL);
396fail: 427fail:
397 ps3flash_dev = NULL; 428 ps3flash_dev = NULL;
398 return error; 429 return error;
@@ -402,10 +433,11 @@ static int ps3flash_remove(struct ps3_system_bus_device *_dev)
402{ 433{
403 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); 434 struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core);
404 435
436 ps3_os_area_flash_register(NULL);
405 misc_deregister(&ps3flash_misc); 437 misc_deregister(&ps3flash_misc);
406 ps3stor_teardown(dev); 438 ps3stor_teardown(dev);
407 kfree(dev->sbd.core.driver_data); 439 kfree(ps3_system_bus_get_drvdata(&dev->sbd));
408 dev->sbd.core.driver_data = NULL; 440 ps3_system_bus_set_drvdata(&dev->sbd, NULL);
409 ps3flash_dev = NULL; 441 ps3flash_dev = NULL;
410 return 0; 442 return 0;
411} 443}
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index d73f5f473e38..f8090e137fef 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -306,11 +306,11 @@ config SENSORS_F71805F
306 will be called f71805f. 306 will be called f71805f.
307 307
308config SENSORS_F71882FG 308config SENSORS_F71882FG
309 tristate "Fintek F71862FG, F71882FG and F8000" 309 tristate "Fintek F71858FG, F71862FG, F71882FG and F8000"
310 depends on EXPERIMENTAL 310 depends on EXPERIMENTAL
311 help 311 help
312 If you say yes here you get support for hardware monitoring 312 If you say yes here you get support for hardware monitoring
313 features of the Fintek F71882FG/F71883FG, F71862FG/71863FG 313 features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG
314 and F8000 Super-I/O chips. 314 and F8000 Super-I/O chips.
315 315
316 This driver can also be built as a module. If so, the module 316 This driver can also be built as a module. If so, the module
@@ -418,7 +418,7 @@ config SENSORS_IBMAEM
418 power sensors and capping hardware in various IBM System X 418 power sensors and capping hardware in various IBM System X
419 servers that support Active Energy Manager. This includes 419 servers that support Active Energy Manager. This includes
420 the x3350, x3550, x3650, x3655, x3755, x3850 M2, x3950 M2, 420 the x3350, x3550, x3650, x3655, x3755, x3850 M2, x3950 M2,
421 and certain HS2x/LS2x/QS2x blades. 421 and certain HC10/HS2x/LS2x/QS2x blades.
422 422
423 This driver can also be built as a module. If so, the module 423 This driver can also be built as a module. If so, the module
424 will be called ibmaem. 424 will be called ibmaem.
@@ -787,6 +787,16 @@ config SENSORS_THMC50
787 This driver can also be built as a module. If so, the module 787 This driver can also be built as a module. If so, the module
788 will be called thmc50. 788 will be called thmc50.
789 789
790config SENSORS_TMP401
791 tristate "Texas Instruments TMP401 and compatibles"
792 depends on I2C && EXPERIMENTAL
793 help
794 If you say yes here you get support for Texas Instruments TMP401 and
795 TMP411 temperature sensor chips.
796
797 This driver can also be built as a module. If so, the module
798 will be called tmp401.
799
790config SENSORS_VIA686A 800config SENSORS_VIA686A
791 tristate "VIA686A" 801 tristate "VIA686A"
792 depends on PCI 802 depends on PCI
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 0ae26984ba45..b793dce6bed5 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -82,6 +82,7 @@ obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
82obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o 82obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
83obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o 83obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
84obj-$(CONFIG_SENSORS_THMC50) += thmc50.o 84obj-$(CONFIG_SENSORS_THMC50) += thmc50.o
85obj-$(CONFIG_SENSORS_TMP401) += tmp401.o
85obj-$(CONFIG_SENSORS_VIA686A) += via686a.o 86obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
86obj-$(CONFIG_SENSORS_VT1211) += vt1211.o 87obj-$(CONFIG_SENSORS_VT1211) += vt1211.o
87obj-$(CONFIG_SENSORS_VT8231) += vt8231.o 88obj-$(CONFIG_SENSORS_VT8231) += vt8231.o
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index 5f81ddf71508..4146105f1a57 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -1,6 +1,6 @@
1/*************************************************************************** 1/***************************************************************************
2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> * 2 * Copyright (C) 2006 by Hans Edgington <hans@edgington.nl> *
3 * Copyright (C) 2007,2008 by Hans de Goede <hdegoede@redhat.com> * 3 * Copyright (C) 2007-2009 Hans de Goede <hdegoede@redhat.com> *
4 * * 4 * *
5 * This program is free software; you can redistribute it and/or modify * 5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by * 6 * it under the terms of the GNU General Public License as published by *
@@ -32,6 +32,7 @@
32 32
33#define DRVNAME "f71882fg" 33#define DRVNAME "f71882fg"
34 34
35#define SIO_F71858FG_LD_HWM 0x02 /* Hardware monitor logical device */
35#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */ 36#define SIO_F71882FG_LD_HWM 0x04 /* Hardware monitor logical device */
36#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */ 37#define SIO_UNLOCK_KEY 0x87 /* Key to enable Super-I/O */
37#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */ 38#define SIO_LOCK_KEY 0xAA /* Key to diasble Super-I/O */
@@ -44,6 +45,7 @@
44#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ 45#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
45 46
46#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ 47#define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */
48#define SIO_F71858_ID 0x0507 /* Chipset ID */
47#define SIO_F71862_ID 0x0601 /* Chipset ID */ 49#define SIO_F71862_ID 0x0601 /* Chipset ID */
48#define SIO_F71882_ID 0x0541 /* Chipset ID */ 50#define SIO_F71882_ID 0x0541 /* Chipset ID */
49#define SIO_F8000_ID 0x0581 /* Chipset ID */ 51#define SIO_F8000_ID 0x0581 /* Chipset ID */
@@ -70,6 +72,7 @@
70#define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr)) 72#define F71882FG_REG_TEMP_HIGH(nr) (0x81 + 2 * (nr))
71#define F71882FG_REG_TEMP_STATUS 0x62 73#define F71882FG_REG_TEMP_STATUS 0x62
72#define F71882FG_REG_TEMP_BEEP 0x63 74#define F71882FG_REG_TEMP_BEEP 0x63
75#define F71882FG_REG_TEMP_CONFIG 0x69
73#define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr)) 76#define F71882FG_REG_TEMP_HYST(nr) (0x6C + (nr))
74#define F71882FG_REG_TEMP_TYPE 0x6B 77#define F71882FG_REG_TEMP_TYPE 0x6B
75#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F 78#define F71882FG_REG_TEMP_DIODE_OPEN 0x6F
@@ -92,9 +95,10 @@ static unsigned short force_id;
92module_param(force_id, ushort, 0); 95module_param(force_id, ushort, 0);
93MODULE_PARM_DESC(force_id, "Override the detected device ID"); 96MODULE_PARM_DESC(force_id, "Override the detected device ID");
94 97
95enum chips { f71862fg, f71882fg, f8000 }; 98enum chips { f71858fg, f71862fg, f71882fg, f8000 };
96 99
97static const char *f71882fg_names[] = { 100static const char *f71882fg_names[] = {
101 "f71858fg",
98 "f71862fg", 102 "f71862fg",
99 "f71882fg", 103 "f71882fg",
100 "f8000", 104 "f8000",
@@ -119,6 +123,7 @@ struct f71882fg_data {
119 struct device *hwmon_dev; 123 struct device *hwmon_dev;
120 124
121 struct mutex update_lock; 125 struct mutex update_lock;
126 int temp_start; /* temp numbering start (0 or 1) */
122 char valid; /* !=0 if following fields are valid */ 127 char valid; /* !=0 if following fields are valid */
123 unsigned long last_updated; /* In jiffies */ 128 unsigned long last_updated; /* In jiffies */
124 unsigned long last_limits; /* In jiffies */ 129 unsigned long last_limits; /* In jiffies */
@@ -136,7 +141,7 @@ struct f71882fg_data {
136 /* Note: all models have only 3 temperature channels, but on some 141 /* Note: all models have only 3 temperature channels, but on some
137 they are addressed as 0-2 and on others as 1-3, so for coding 142 they are addressed as 0-2 and on others as 1-3, so for coding
138 convenience we reserve space for 4 channels */ 143 convenience we reserve space for 4 channels */
139 u8 temp[4]; 144 u16 temp[4];
140 u8 temp_ovt[4]; 145 u8 temp_ovt[4];
141 u8 temp_high[4]; 146 u8 temp_high[4];
142 u8 temp_hyst[2]; /* 2 hysts stored per reg */ 147 u8 temp_hyst[2]; /* 2 hysts stored per reg */
@@ -144,6 +149,7 @@ struct f71882fg_data {
144 u8 temp_status; 149 u8 temp_status;
145 u8 temp_beep; 150 u8 temp_beep;
146 u8 temp_diode_open; 151 u8 temp_diode_open;
152 u8 temp_config;
147 u8 pwm[4]; 153 u8 pwm[4];
148 u8 pwm_enable; 154 u8 pwm_enable;
149 u8 pwm_auto_point_hyst[2]; 155 u8 pwm_auto_point_hyst[2];
@@ -247,11 +253,55 @@ static struct platform_driver f71882fg_driver = {
247 .name = DRVNAME, 253 .name = DRVNAME,
248 }, 254 },
249 .probe = f71882fg_probe, 255 .probe = f71882fg_probe,
250 .remove = __devexit_p(f71882fg_remove), 256 .remove = f71882fg_remove,
251}; 257};
252 258
253static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); 259static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
254 260
261/* Temp and in attr for the f71858fg */
262static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = {
263 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
264 SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1),
265 SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2),
266 SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0),
267 SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max,
268 store_temp_max, 0, 0),
269 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
270 store_temp_max_hyst, 0, 0),
271 SENSOR_ATTR_2(temp1_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 0),
272 SENSOR_ATTR_2(temp1_crit, S_IRUGO|S_IWUSR, show_temp_crit,
273 store_temp_crit, 0, 0),
274 SENSOR_ATTR_2(temp1_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
275 0, 0),
276 SENSOR_ATTR_2(temp1_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
277 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
278 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
279 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_max,
280 store_temp_max, 0, 1),
281 SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
282 store_temp_max_hyst, 0, 1),
283 SENSOR_ATTR_2(temp2_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 1),
284 SENSOR_ATTR_2(temp2_crit, S_IRUGO|S_IWUSR, show_temp_crit,
285 store_temp_crit, 0, 1),
286 SENSOR_ATTR_2(temp2_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
287 0, 1),
288 SENSOR_ATTR_2(temp2_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
289 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
290 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
291 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
292 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max,
293 store_temp_max, 0, 2),
294 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max_hyst,
295 store_temp_max_hyst, 0, 2),
296 SENSOR_ATTR_2(temp3_max_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 2),
297 SENSOR_ATTR_2(temp3_crit, S_IRUGO|S_IWUSR, show_temp_crit,
298 store_temp_crit, 0, 2),
299 SENSOR_ATTR_2(temp3_crit_hyst, S_IRUGO, show_temp_crit_hyst, NULL,
300 0, 2),
301 SENSOR_ATTR_2(temp3_crit_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
302 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
303};
304
255/* Temp and in attr common to both the f71862fg and f71882fg */ 305/* Temp and in attr common to both the f71862fg and f71882fg */
256static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = { 306static struct sensor_device_attribute_2 f718x2fg_in_temp_attr[] = {
257 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), 307 SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0),
@@ -344,6 +394,7 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
344 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 394 SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
345 store_temp_max, 0, 0), 395 store_temp_max, 0, 0),
346 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4), 396 SENSOR_ATTR_2(temp1_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 4),
397 SENSOR_ATTR_2(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0, 0),
347 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1), 398 SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1),
348 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit, 399 SENSOR_ATTR_2(temp2_max, S_IRUGO|S_IWUSR, show_temp_crit,
349 store_temp_crit, 0, 1), 400 store_temp_crit, 0, 1),
@@ -351,12 +402,14 @@ static struct sensor_device_attribute_2 f8000_in_temp_attr[] = {
351 store_temp_max, 0, 1), 402 store_temp_max, 0, 1),
352 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5), 403 SENSOR_ATTR_2(temp2_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 5),
353 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1), 404 SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 1),
405 SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 1),
354 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2), 406 SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 2),
355 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit, 407 SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_crit,
356 store_temp_crit, 0, 2), 408 store_temp_crit, 0, 2),
357 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max, 409 SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO|S_IWUSR, show_temp_max,
358 store_temp_max, 0, 2), 410 store_temp_max, 0, 2),
359 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6), 411 SENSOR_ATTR_2(temp3_alarm, S_IRUGO, show_temp_alarm, NULL, 0, 6),
412 SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2),
360}; 413};
361 414
362/* Fan / PWM attr common to all models */ 415/* Fan / PWM attr common to all models */
@@ -395,6 +448,9 @@ static struct sensor_device_attribute_2 fxxxx_fan_attr[] = {
395 show_pwm_auto_point_channel, 448 show_pwm_auto_point_channel,
396 store_pwm_auto_point_channel, 0, 1), 449 store_pwm_auto_point_channel, 0, 1),
397 450
451 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
452 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
453 store_pwm_enable, 0, 2),
398 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR, 454 SENSOR_ATTR_2(pwm3_interpolate, S_IRUGO|S_IWUSR,
399 show_pwm_interpolate, store_pwm_interpolate, 0, 2), 455 show_pwm_interpolate, store_pwm_interpolate, 0, 2),
400 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR, 456 SENSOR_ATTR_2(pwm3_auto_channels_temp, S_IRUGO|S_IWUSR,
@@ -450,9 +506,6 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
450 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO, 506 SENSOR_ATTR_2(pwm2_auto_point2_temp_hyst, S_IRUGO,
451 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 507 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
452 508
453 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
454 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
455 store_pwm_enable, 0, 2),
456 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 509 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
457 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 510 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
458 1, 2), 511 1, 2),
@@ -473,22 +526,8 @@ static struct sensor_device_attribute_2 f71862fg_fan_attr[] = {
473 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 526 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
474}; 527};
475 528
476/* Fan / PWM attr for the f71882fg */ 529/* Fan / PWM attr common to both the f71882fg and f71858fg */
477static struct sensor_device_attribute_2 f71882fg_fan_attr[] = { 530static struct sensor_device_attribute_2 f71882fg_f71858fg_fan_attr[] = {
478 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
479 store_fan_beep, 0, 0),
480 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
481 store_fan_beep, 0, 1),
482 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
483 store_fan_beep, 0, 2),
484 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
485 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
486 show_fan_full_speed,
487 store_fan_full_speed, 0, 3),
488 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
489 store_fan_beep, 0, 3),
490 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
491
492 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR, 531 SENSOR_ATTR_2(pwm1_auto_point1_pwm, S_IRUGO|S_IWUSR,
493 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 532 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
494 0, 0), 533 0, 0),
@@ -565,9 +604,6 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
565 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO, 604 SENSOR_ATTR_2(pwm2_auto_point4_temp_hyst, S_IRUGO,
566 show_pwm_auto_point_temp_hyst, NULL, 3, 1), 605 show_pwm_auto_point_temp_hyst, NULL, 3, 1),
567 606
568 SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 2),
569 SENSOR_ATTR_2(pwm3_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
570 store_pwm_enable, 0, 2),
571 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR, 607 SENSOR_ATTR_2(pwm3_auto_point1_pwm, S_IRUGO|S_IWUSR,
572 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 608 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
573 0, 2), 609 0, 2),
@@ -605,6 +641,24 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
605 show_pwm_auto_point_temp_hyst, NULL, 2, 2), 641 show_pwm_auto_point_temp_hyst, NULL, 2, 2),
606 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO, 642 SENSOR_ATTR_2(pwm3_auto_point4_temp_hyst, S_IRUGO,
607 show_pwm_auto_point_temp_hyst, NULL, 3, 2), 643 show_pwm_auto_point_temp_hyst, NULL, 3, 2),
644};
645
646/* Fan / PWM attr found on the f71882fg but not on the f71858fg */
647static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
648 SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
649 store_fan_beep, 0, 0),
650 SENSOR_ATTR_2(fan2_beep, S_IRUGO|S_IWUSR, show_fan_beep,
651 store_fan_beep, 0, 1),
652 SENSOR_ATTR_2(fan3_beep, S_IRUGO|S_IWUSR, show_fan_beep,
653 store_fan_beep, 0, 2),
654
655 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
656 SENSOR_ATTR_2(fan4_full_speed, S_IRUGO|S_IWUSR,
657 show_fan_full_speed,
658 store_fan_full_speed, 0, 3),
659 SENSOR_ATTR_2(fan4_beep, S_IRUGO|S_IWUSR, show_fan_beep,
660 store_fan_beep, 0, 3),
661 SENSOR_ATTR_2(fan4_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 3),
608 662
609 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3), 663 SENSOR_ATTR_2(pwm4, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0, 3),
610 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable, 664 SENSOR_ATTR_2(pwm4_enable, S_IRUGO|S_IWUSR, show_pwm_enable,
@@ -659,8 +713,6 @@ static struct sensor_device_attribute_2 f71882fg_fan_attr[] = {
659static struct sensor_device_attribute_2 f8000_fan_attr[] = { 713static struct sensor_device_attribute_2 f8000_fan_attr[] = {
660 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3), 714 SENSOR_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 0, 3),
661 715
662 SENSOR_ATTR_2(pwm3, S_IRUGO, show_pwm, NULL, 0, 2),
663
664 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR, 716 SENSOR_ATTR_2(temp1_auto_point1_pwm, S_IRUGO|S_IWUSR,
665 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm, 717 show_pwm_auto_point_pwm, store_pwm_auto_point_pwm,
666 0, 2), 718 0, 2),
@@ -857,13 +909,20 @@ static void f71882fg_write16(struct f71882fg_data *data, u8 reg, u16 val)
857 outb(val & 255, data->addr + DATA_REG_OFFSET); 909 outb(val & 255, data->addr + DATA_REG_OFFSET);
858} 910}
859 911
912static u16 f71882fg_read_temp(struct f71882fg_data *data, int nr)
913{
914 if (data->type == f71858fg)
915 return f71882fg_read16(data, F71882FG_REG_TEMP(nr));
916 else
917 return f71882fg_read8(data, F71882FG_REG_TEMP(nr));
918}
919
860static struct f71882fg_data *f71882fg_update_device(struct device *dev) 920static struct f71882fg_data *f71882fg_update_device(struct device *dev)
861{ 921{
862 struct f71882fg_data *data = dev_get_drvdata(dev); 922 struct f71882fg_data *data = dev_get_drvdata(dev);
863 int nr, reg = 0, reg2; 923 int nr, reg = 0, reg2;
864 int nr_fans = (data->type == f71882fg) ? 4 : 3; 924 int nr_fans = (data->type == f71882fg) ? 4 : 3;
865 int nr_ins = (data->type == f8000) ? 3 : 9; 925 int nr_ins = (data->type == f71858fg || data->type == f8000) ? 3 : 9;
866 int temp_start = (data->type == f8000) ? 0 : 1;
867 926
868 mutex_lock(&data->update_lock); 927 mutex_lock(&data->update_lock);
869 928
@@ -878,7 +937,7 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
878 } 937 }
879 938
880 /* Get High & boundary temps*/ 939 /* Get High & boundary temps*/
881 for (nr = temp_start; nr < 3 + temp_start; nr++) { 940 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++) {
882 data->temp_ovt[nr] = f71882fg_read8(data, 941 data->temp_ovt[nr] = f71882fg_read8(data,
883 F71882FG_REG_TEMP_OVT(nr)); 942 F71882FG_REG_TEMP_OVT(nr));
884 data->temp_high[nr] = f71882fg_read8(data, 943 data->temp_high[nr] = f71882fg_read8(data,
@@ -886,14 +945,17 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
886 } 945 }
887 946
888 if (data->type != f8000) { 947 if (data->type != f8000) {
889 data->fan_beep = f71882fg_read8(data,
890 F71882FG_REG_FAN_BEEP);
891 data->temp_beep = f71882fg_read8(data,
892 F71882FG_REG_TEMP_BEEP);
893 data->temp_hyst[0] = f71882fg_read8(data, 948 data->temp_hyst[0] = f71882fg_read8(data,
894 F71882FG_REG_TEMP_HYST(0)); 949 F71882FG_REG_TEMP_HYST(0));
895 data->temp_hyst[1] = f71882fg_read8(data, 950 data->temp_hyst[1] = f71882fg_read8(data,
896 F71882FG_REG_TEMP_HYST(1)); 951 F71882FG_REG_TEMP_HYST(1));
952 }
953
954 if (data->type == f71862fg || data->type == f71882fg) {
955 data->fan_beep = f71882fg_read8(data,
956 F71882FG_REG_FAN_BEEP);
957 data->temp_beep = f71882fg_read8(data,
958 F71882FG_REG_TEMP_BEEP);
897 /* Have to hardcode type, because temp1 is special */ 959 /* Have to hardcode type, because temp1 is special */
898 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); 960 reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE);
899 data->temp_type[2] = (reg & 0x04) ? 2 : 4; 961 data->temp_type[2] = (reg & 0x04) ? 2 : 4;
@@ -904,10 +966,10 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
904 data->temp_type[1] = 6 /* PECI */; 966 data->temp_type[1] = 6 /* PECI */;
905 else if ((reg2 & 0x03) == 0x02) 967 else if ((reg2 & 0x03) == 0x02)
906 data->temp_type[1] = 5 /* AMDSI */; 968 data->temp_type[1] = 5 /* AMDSI */;
907 else if (data->type != f8000) 969 else if (data->type == f71862fg || data->type == f71882fg)
908 data->temp_type[1] = (reg & 0x02) ? 2 : 4; 970 data->temp_type[1] = (reg & 0x02) ? 2 : 4;
909 else 971 else
910 data->temp_type[1] = 2; /* F8000 only supports BJT */ 972 data->temp_type[1] = 2; /* Only supports BJT */
911 973
912 data->pwm_enable = f71882fg_read8(data, 974 data->pwm_enable = f71882fg_read8(data,
913 F71882FG_REG_PWM_ENABLE); 975 F71882FG_REG_PWM_ENABLE);
@@ -963,9 +1025,8 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev)
963 F71882FG_REG_TEMP_STATUS); 1025 F71882FG_REG_TEMP_STATUS);
964 data->temp_diode_open = f71882fg_read8(data, 1026 data->temp_diode_open = f71882fg_read8(data,
965 F71882FG_REG_TEMP_DIODE_OPEN); 1027 F71882FG_REG_TEMP_DIODE_OPEN);
966 for (nr = temp_start; nr < 3 + temp_start; nr++) 1028 for (nr = data->temp_start; nr < 3 + data->temp_start; nr++)
967 data->temp[nr] = f71882fg_read8(data, 1029 data->temp[nr] = f71882fg_read_temp(data, nr);
968 F71882FG_REG_TEMP(nr));
969 1030
970 data->fan_status = f71882fg_read8(data, 1031 data->fan_status = f71882fg_read8(data,
971 F71882FG_REG_FAN_STATUS); 1032 F71882FG_REG_FAN_STATUS);
@@ -1168,8 +1229,24 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
1168{ 1229{
1169 struct f71882fg_data *data = f71882fg_update_device(dev); 1230 struct f71882fg_data *data = f71882fg_update_device(dev);
1170 int nr = to_sensor_dev_attr_2(devattr)->index; 1231 int nr = to_sensor_dev_attr_2(devattr)->index;
1232 int sign, temp;
1233
1234 if (data->type == f71858fg) {
1235 /* TEMP_TABLE_SEL 1 or 3 ? */
1236 if (data->temp_config & 1) {
1237 sign = data->temp[nr] & 0x0001;
1238 temp = (data->temp[nr] >> 5) & 0x7ff;
1239 } else {
1240 sign = data->temp[nr] & 0x8000;
1241 temp = (data->temp[nr] >> 5) & 0x3ff;
1242 }
1243 temp *= 125;
1244 if (sign)
1245 temp -= 128000;
1246 } else
1247 temp = data->temp[nr] * 1000;
1171 1248
1172 return sprintf(buf, "%d\n", data->temp[nr] * 1000); 1249 return sprintf(buf, "%d\n", temp);
1173} 1250}
1174 1251
1175static ssize_t show_temp_max(struct device *dev, struct device_attribute 1252static ssize_t show_temp_max(struct device *dev, struct device_attribute
@@ -1440,6 +1517,10 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1440 int nr = to_sensor_dev_attr_2(devattr)->index; 1517 int nr = to_sensor_dev_attr_2(devattr)->index;
1441 long val = simple_strtol(buf, NULL, 10); 1518 long val = simple_strtol(buf, NULL, 10);
1442 1519
1520 /* Special case for F8000 pwm channel 3 which only does auto mode */
1521 if (data->type == f8000 && nr == 2 && val != 2)
1522 return -EINVAL;
1523
1443 mutex_lock(&data->update_lock); 1524 mutex_lock(&data->update_lock);
1444 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE); 1525 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1445 /* Special case for F8000 auto PWM mode / Thermostat mode */ 1526 /* Special case for F8000 auto PWM mode / Thermostat mode */
@@ -1458,6 +1539,12 @@ static ssize_t store_pwm_enable(struct device *dev, struct device_attribute
1458 } else { 1539 } else {
1459 switch (val) { 1540 switch (val) {
1460 case 1: 1541 case 1:
1542 /* The f71858fg does not support manual RPM mode */
1543 if (data->type == f71858fg &&
1544 ((data->pwm_enable >> (2 * nr)) & 1)) {
1545 count = -EINVAL;
1546 goto leave;
1547 }
1461 data->pwm_enable |= 2 << (2 * nr); 1548 data->pwm_enable |= 2 << (2 * nr);
1462 break; /* Manual */ 1549 break; /* Manual */
1463 case 2: 1550 case 2:
@@ -1616,9 +1703,9 @@ static ssize_t show_pwm_auto_point_channel(struct device *dev,
1616 int result; 1703 int result;
1617 struct f71882fg_data *data = f71882fg_update_device(dev); 1704 struct f71882fg_data *data = f71882fg_update_device(dev);
1618 int nr = to_sensor_dev_attr_2(devattr)->index; 1705 int nr = to_sensor_dev_attr_2(devattr)->index;
1619 int temp_start = (data->type == f8000) ? 0 : 1;
1620 1706
1621 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) - temp_start); 1707 result = 1 << ((data->pwm_auto_point_mapping[nr] & 3) -
1708 data->temp_start);
1622 1709
1623 return sprintf(buf, "%d\n", result); 1710 return sprintf(buf, "%d\n", result);
1624} 1711}
@@ -1629,7 +1716,6 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev,
1629{ 1716{
1630 struct f71882fg_data *data = dev_get_drvdata(dev); 1717 struct f71882fg_data *data = dev_get_drvdata(dev);
1631 int nr = to_sensor_dev_attr_2(devattr)->index; 1718 int nr = to_sensor_dev_attr_2(devattr)->index;
1632 int temp_start = (data->type == f8000) ? 0 : 1;
1633 long val = simple_strtol(buf, NULL, 10); 1719 long val = simple_strtol(buf, NULL, 10);
1634 1720
1635 switch (val) { 1721 switch (val) {
@@ -1645,7 +1731,7 @@ static ssize_t store_pwm_auto_point_channel(struct device *dev,
1645 default: 1731 default:
1646 return -EINVAL; 1732 return -EINVAL;
1647 } 1733 }
1648 val += temp_start; 1734 val += data->temp_start;
1649 mutex_lock(&data->update_lock); 1735 mutex_lock(&data->update_lock);
1650 data->pwm_auto_point_mapping[nr] = 1736 data->pwm_auto_point_mapping[nr] =
1651 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr)); 1737 f71882fg_read8(data, F71882FG_REG_POINT_MAPPING(nr));
@@ -1721,6 +1807,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1721 1807
1722 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start; 1808 data->addr = platform_get_resource(pdev, IORESOURCE_IO, 0)->start;
1723 data->type = sio_data->type; 1809 data->type = sio_data->type;
1810 data->temp_start =
1811 (data->type == f71858fg || data->type == f8000) ? 0 : 1;
1724 mutex_init(&data->update_lock); 1812 mutex_init(&data->update_lock);
1725 platform_set_drvdata(pdev, data); 1813 platform_set_drvdata(pdev, data);
1726 1814
@@ -1736,19 +1824,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1736 goto exit_free; 1824 goto exit_free;
1737 } 1825 }
1738 1826
1739 data->pwm_enable = f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1740 /* If it is a 71862 and the fan / pwm part is enabled sanity check
1741 the pwm settings */
1742 if (data->type == f71862fg && (start_reg & 0x02)) {
1743 if ((data->pwm_enable & 0x15) != 0x15) {
1744 dev_err(&pdev->dev,
1745 "Invalid (reserved) pwm settings: 0x%02x\n",
1746 (unsigned int)data->pwm_enable);
1747 err = -ENODEV;
1748 goto exit_free;
1749 }
1750 }
1751
1752 /* Register sysfs interface files */ 1827 /* Register sysfs interface files */
1753 err = device_create_file(&pdev->dev, &dev_attr_name); 1828 err = device_create_file(&pdev->dev, &dev_attr_name);
1754 if (err) 1829 if (err)
@@ -1756,6 +1831,20 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1756 1831
1757 if (start_reg & 0x01) { 1832 if (start_reg & 0x01) {
1758 switch (data->type) { 1833 switch (data->type) {
1834 case f71858fg:
1835 data->temp_config =
1836 f71882fg_read8(data, F71882FG_REG_TEMP_CONFIG);
1837 if (data->temp_config & 0x10)
1838 /* The f71858fg temperature alarms behave as
1839 the f8000 alarms in this mode */
1840 err = f71882fg_create_sysfs_files(pdev,
1841 f8000_in_temp_attr,
1842 ARRAY_SIZE(f8000_in_temp_attr));
1843 else
1844 err = f71882fg_create_sysfs_files(pdev,
1845 f71858fg_in_temp_attr,
1846 ARRAY_SIZE(f71858fg_in_temp_attr));
1847 break;
1759 case f71882fg: 1848 case f71882fg:
1760 err = f71882fg_create_sysfs_files(pdev, 1849 err = f71882fg_create_sysfs_files(pdev,
1761 f71882fg_in_temp_attr, 1850 f71882fg_in_temp_attr,
@@ -1779,6 +1868,35 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1779 } 1868 }
1780 1869
1781 if (start_reg & 0x02) { 1870 if (start_reg & 0x02) {
1871 data->pwm_enable =
1872 f71882fg_read8(data, F71882FG_REG_PWM_ENABLE);
1873
1874 /* Sanity check the pwm settings */
1875 switch (data->type) {
1876 case f71858fg:
1877 err = 0;
1878 for (i = 0; i < nr_fans; i++)
1879 if (((data->pwm_enable >> (i * 2)) & 3) == 3)
1880 err = 1;
1881 break;
1882 case f71862fg:
1883 err = (data->pwm_enable & 0x15) != 0x15;
1884 break;
1885 case f71882fg:
1886 err = 0;
1887 break;
1888 case f8000:
1889 err = data->pwm_enable & 0x20;
1890 break;
1891 }
1892 if (err) {
1893 dev_err(&pdev->dev,
1894 "Invalid (reserved) pwm settings: 0x%02x\n",
1895 (unsigned int)data->pwm_enable);
1896 err = -ENODEV;
1897 goto exit_unregister_sysfs;
1898 }
1899
1782 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr, 1900 err = f71882fg_create_sysfs_files(pdev, fxxxx_fan_attr,
1783 ARRAY_SIZE(fxxxx_fan_attr)); 1901 ARRAY_SIZE(fxxxx_fan_attr));
1784 if (err) 1902 if (err)
@@ -1794,6 +1912,13 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
1794 err = f71882fg_create_sysfs_files(pdev, 1912 err = f71882fg_create_sysfs_files(pdev,
1795 f71882fg_fan_attr, 1913 f71882fg_fan_attr,
1796 ARRAY_SIZE(f71882fg_fan_attr)); 1914 ARRAY_SIZE(f71882fg_fan_attr));
1915 if (err)
1916 goto exit_unregister_sysfs;
1917 /* fall through! */
1918 case f71858fg:
1919 err = f71882fg_create_sysfs_files(pdev,
1920 f71882fg_f71858fg_fan_attr,
1921 ARRAY_SIZE(f71882fg_f71858fg_fan_attr));
1797 break; 1922 break;
1798 case f8000: 1923 case f8000:
1799 err = f71882fg_create_sysfs_files(pdev, 1924 err = f71882fg_create_sysfs_files(pdev,
@@ -1878,6 +2003,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
1878 2003
1879 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); 2004 devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID);
1880 switch (devid) { 2005 switch (devid) {
2006 case SIO_F71858_ID:
2007 sio_data->type = f71858fg;
2008 break;
1881 case SIO_F71862_ID: 2009 case SIO_F71862_ID:
1882 sio_data->type = f71862fg; 2010 sio_data->type = f71862fg;
1883 break; 2011 break;
@@ -1892,7 +2020,11 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
1892 goto exit; 2020 goto exit;
1893 } 2021 }
1894 2022
1895 superio_select(sioaddr, SIO_F71882FG_LD_HWM); 2023 if (sio_data->type == f71858fg)
2024 superio_select(sioaddr, SIO_F71858FG_LD_HWM);
2025 else
2026 superio_select(sioaddr, SIO_F71882FG_LD_HWM);
2027
1896 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) { 2028 if (!(superio_inb(sioaddr, SIO_REG_ENABLE) & 0x01)) {
1897 printk(KERN_WARNING DRVNAME ": Device not activated\n"); 2029 printk(KERN_WARNING DRVNAME ": Device not activated\n");
1898 goto exit; 2030 goto exit;
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index e15c3e7b07e9..29ea6753f3bb 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -18,6 +18,7 @@
18#include <linux/hwmon.h> 18#include <linux/hwmon.h>
19#include <linux/gfp.h> 19#include <linux/gfp.h>
20#include <linux/spinlock.h> 20#include <linux/spinlock.h>
21#include <linux/pci.h>
21 22
22#define HWMON_ID_PREFIX "hwmon" 23#define HWMON_ID_PREFIX "hwmon"
23#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" 24#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
@@ -86,8 +87,36 @@ void hwmon_device_unregister(struct device *dev)
86 "hwmon_device_unregister() failed: bad class ID!\n"); 87 "hwmon_device_unregister() failed: bad class ID!\n");
87} 88}
88 89
90static void __init hwmon_pci_quirks(void)
91{
92#if defined CONFIG_X86 && defined CONFIG_PCI
93 struct pci_dev *sb;
94 u16 base;
95 u8 enable;
96
97 /* Open access to 0x295-0x296 on MSI MS-7031 */
98 sb = pci_get_device(PCI_VENDOR_ID_ATI, 0x436c, NULL);
99 if (sb &&
100 (sb->subsystem_vendor == 0x1462 && /* MSI */
101 sb->subsystem_device == 0x0031)) { /* MS-7031 */
102
103 pci_read_config_byte(sb, 0x48, &enable);
104 pci_read_config_word(sb, 0x64, &base);
105
106 if (base == 0 && !(enable & BIT(2))) {
107 dev_info(&sb->dev,
108 "Opening wide generic port at 0x295\n");
109 pci_write_config_word(sb, 0x64, 0x295);
110 pci_write_config_byte(sb, 0x48, enable | BIT(2));
111 }
112 }
113#endif
114}
115
89static int __init hwmon_init(void) 116static int __init hwmon_init(void)
90{ 117{
118 hwmon_pci_quirks();
119
91 hwmon_class = class_create(THIS_MODULE, "hwmon"); 120 hwmon_class = class_create(THIS_MODULE, "hwmon");
92 if (IS_ERR(hwmon_class)) { 121 if (IS_ERR(hwmon_class)) {
93 printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n"); 122 printk(KERN_ERR "hwmon.c: couldn't create sysfs class\n");
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index fe74609a7feb..405d3fb5d76f 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -1127,3 +1127,4 @@ MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3650-*");
1127MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*"); 1127MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3655-*");
1128MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*"); 1128MODULE_ALIAS("dmi:bvnIBM:*:pnIBMSystemx3755-*");
1129MODULE_ALIAS("dmi:bvnIBM:*:pnIBM3850M2/x3950M2-*"); 1129MODULE_ALIAS("dmi:bvnIBM:*:pnIBM3850M2/x3950M2-*");
1130MODULE_ALIAS("dmi:bvnIBM:*:pnIBMBladeHC10-*");
diff --git a/drivers/hwmon/max6650.c b/drivers/hwmon/max6650.c
index f27af6a9da41..86142a858238 100644
--- a/drivers/hwmon/max6650.c
+++ b/drivers/hwmon/max6650.c
@@ -12,7 +12,7 @@
12 * also work with the MAX6651. It does not distinguish max6650 and max6651 12 * also work with the MAX6651. It does not distinguish max6650 and max6651
13 * chips. 13 * chips.
14 * 14 *
15 * Tha datasheet was last seen at: 15 * The datasheet was last seen at:
16 * 16 *
17 * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf 17 * http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
18 * 18 *
@@ -98,6 +98,16 @@ I2C_CLIENT_INSMOD_1(max6650);
98#define MAX6650_CFG_MODE_OPEN_LOOP 0x30 98#define MAX6650_CFG_MODE_OPEN_LOOP 0x30
99#define MAX6650_COUNT_MASK 0x03 99#define MAX6650_COUNT_MASK 0x03
100 100
101/*
102 * Alarm status register bits
103 */
104
105#define MAX6650_ALRM_MAX 0x01
106#define MAX6650_ALRM_MIN 0x02
107#define MAX6650_ALRM_TACH 0x04
108#define MAX6650_ALRM_GPIO1 0x08
109#define MAX6650_ALRM_GPIO2 0x10
110
101/* Minimum and maximum values of the FAN-RPM */ 111/* Minimum and maximum values of the FAN-RPM */
102#define FAN_RPM_MIN 240 112#define FAN_RPM_MIN 240
103#define FAN_RPM_MAX 30000 113#define FAN_RPM_MAX 30000
@@ -151,6 +161,7 @@ struct max6650_data
151 u8 tach[4]; 161 u8 tach[4];
152 u8 count; 162 u8 count;
153 u8 dac; 163 u8 dac;
164 u8 alarm;
154}; 165};
155 166
156static ssize_t get_fan(struct device *dev, struct device_attribute *devattr, 167static ssize_t get_fan(struct device *dev, struct device_attribute *devattr,
@@ -418,6 +429,33 @@ static ssize_t set_div(struct device *dev, struct device_attribute *devattr,
418 return count; 429 return count;
419} 430}
420 431
432/*
433 * Get alarm stati:
434 * Possible values:
435 * 0 = no alarm
436 * 1 = alarm
437 */
438
439static ssize_t get_alarm(struct device *dev, struct device_attribute *devattr,
440 char *buf)
441{
442 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
443 struct max6650_data *data = max6650_update_device(dev);
444 struct i2c_client *client = to_i2c_client(dev);
445 int alarm = 0;
446
447 if (data->alarm & attr->index) {
448 mutex_lock(&data->update_lock);
449 alarm = 1;
450 data->alarm &= ~attr->index;
451 data->alarm |= i2c_smbus_read_byte_data(client,
452 MAX6650_REG_ALARM);
453 mutex_unlock(&data->update_lock);
454 }
455
456 return sprintf(buf, "%d\n", alarm);
457}
458
421static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0); 459static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, get_fan, NULL, 0);
422static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1); 460static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, get_fan, NULL, 1);
423static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2); 461static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, get_fan, NULL, 2);
@@ -426,7 +464,41 @@ static DEVICE_ATTR(fan1_target, S_IWUSR | S_IRUGO, get_target, set_target);
426static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div); 464static DEVICE_ATTR(fan1_div, S_IWUSR | S_IRUGO, get_div, set_div);
427static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable); 465static DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, get_enable, set_enable);
428static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm); 466static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
467static SENSOR_DEVICE_ATTR(fan1_max_alarm, S_IRUGO, get_alarm, NULL,
468 MAX6650_ALRM_MAX);
469static SENSOR_DEVICE_ATTR(fan1_min_alarm, S_IRUGO, get_alarm, NULL,
470 MAX6650_ALRM_MIN);
471static SENSOR_DEVICE_ATTR(fan1_fault, S_IRUGO, get_alarm, NULL,
472 MAX6650_ALRM_TACH);
473static SENSOR_DEVICE_ATTR(gpio1_alarm, S_IRUGO, get_alarm, NULL,
474 MAX6650_ALRM_GPIO1);
475static SENSOR_DEVICE_ATTR(gpio2_alarm, S_IRUGO, get_alarm, NULL,
476 MAX6650_ALRM_GPIO2);
477
478static mode_t max6650_attrs_visible(struct kobject *kobj, struct attribute *a,
479 int n)
480{
481 struct device *dev = container_of(kobj, struct device, kobj);
482 struct i2c_client *client = to_i2c_client(dev);
483 u8 alarm_en = i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN);
484 struct device_attribute *devattr;
429 485
486 /*
487 * Hide the alarms that have not been enabled by the firmware
488 */
489
490 devattr = container_of(a, struct device_attribute, attr);
491 if (devattr == &sensor_dev_attr_fan1_max_alarm.dev_attr
492 || devattr == &sensor_dev_attr_fan1_min_alarm.dev_attr
493 || devattr == &sensor_dev_attr_fan1_fault.dev_attr
494 || devattr == &sensor_dev_attr_gpio1_alarm.dev_attr
495 || devattr == &sensor_dev_attr_gpio2_alarm.dev_attr) {
496 if (!(alarm_en & to_sensor_dev_attr(devattr)->index))
497 return 0;
498 }
499
500 return a->mode;
501}
430 502
431static struct attribute *max6650_attrs[] = { 503static struct attribute *max6650_attrs[] = {
432 &sensor_dev_attr_fan1_input.dev_attr.attr, 504 &sensor_dev_attr_fan1_input.dev_attr.attr,
@@ -437,11 +509,17 @@ static struct attribute *max6650_attrs[] = {
437 &dev_attr_fan1_div.attr, 509 &dev_attr_fan1_div.attr,
438 &dev_attr_pwm1_enable.attr, 510 &dev_attr_pwm1_enable.attr,
439 &dev_attr_pwm1.attr, 511 &dev_attr_pwm1.attr,
512 &sensor_dev_attr_fan1_max_alarm.dev_attr.attr,
513 &sensor_dev_attr_fan1_min_alarm.dev_attr.attr,
514 &sensor_dev_attr_fan1_fault.dev_attr.attr,
515 &sensor_dev_attr_gpio1_alarm.dev_attr.attr,
516 &sensor_dev_attr_gpio2_alarm.dev_attr.attr,
440 NULL 517 NULL
441}; 518};
442 519
443static struct attribute_group max6650_attr_grp = { 520static struct attribute_group max6650_attr_grp = {
444 .attrs = max6650_attrs, 521 .attrs = max6650_attrs,
522 .is_visible = max6650_attrs_visible,
445}; 523};
446 524
447/* 525/*
@@ -659,6 +737,12 @@ static struct max6650_data *max6650_update_device(struct device *dev)
659 MAX6650_REG_COUNT); 737 MAX6650_REG_COUNT);
660 data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC); 738 data->dac = i2c_smbus_read_byte_data(client, MAX6650_REG_DAC);
661 739
740 /* Alarms are cleared on read in case the condition that
741 * caused the alarm is removed. Keep the value latched here
742 * for providing the register through different alarm files. */
743 data->alarm |= i2c_smbus_read_byte_data(client,
744 MAX6650_REG_ALARM);
745
662 data->last_updated = jiffies; 746 data->last_updated = jiffies;
663 data->valid = 1; 747 data->valid = 1;
664 } 748 }
diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c
index 6cbdc2fea734..56cd6004da36 100644
--- a/drivers/hwmon/sht15.c
+++ b/drivers/hwmon/sht15.c
@@ -627,35 +627,35 @@ static struct platform_driver sht_drivers[] = {
627 .owner = THIS_MODULE, 627 .owner = THIS_MODULE,
628 }, 628 },
629 .probe = sht15_probe, 629 .probe = sht15_probe,
630 .remove = sht15_remove, 630 .remove = __devexit_p(sht15_remove),
631 }, { 631 }, {
632 .driver = { 632 .driver = {
633 .name = "sht11", 633 .name = "sht11",
634 .owner = THIS_MODULE, 634 .owner = THIS_MODULE,
635 }, 635 },
636 .probe = sht15_probe, 636 .probe = sht15_probe,
637 .remove = sht15_remove, 637 .remove = __devexit_p(sht15_remove),
638 }, { 638 }, {
639 .driver = { 639 .driver = {
640 .name = "sht15", 640 .name = "sht15",
641 .owner = THIS_MODULE, 641 .owner = THIS_MODULE,
642 }, 642 },
643 .probe = sht15_probe, 643 .probe = sht15_probe,
644 .remove = sht15_remove, 644 .remove = __devexit_p(sht15_remove),
645 }, { 645 }, {
646 .driver = { 646 .driver = {
647 .name = "sht71", 647 .name = "sht71",
648 .owner = THIS_MODULE, 648 .owner = THIS_MODULE,
649 }, 649 },
650 .probe = sht15_probe, 650 .probe = sht15_probe,
651 .remove = sht15_remove, 651 .remove = __devexit_p(sht15_remove),
652 }, { 652 }, {
653 .driver = { 653 .driver = {
654 .name = "sht75", 654 .name = "sht75",
655 .owner = THIS_MODULE, 655 .owner = THIS_MODULE,
656 }, 656 },
657 .probe = sht15_probe, 657 .probe = sht15_probe,
658 .remove = sht15_remove, 658 .remove = __devexit_p(sht15_remove),
659 }, 659 },
660}; 660};
661 661
diff --git a/drivers/hwmon/tmp401.c b/drivers/hwmon/tmp401.c
new file mode 100644
index 000000000000..7b34f2cd08bb
--- /dev/null
+++ b/drivers/hwmon/tmp401.c
@@ -0,0 +1,690 @@
1/* tmp401.c
2 *
3 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
4 * Preliminary tmp411 support by:
5 * Gabriel Konat, Sander Leget, Wouter Willems
6 * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23/*
24 * Driver for the Texas Instruments TMP401 SMBUS temperature sensor IC.
25 *
26 * Note this IC is in some aspect similar to the LM90, but it has quite a
27 * few differences too, for example the local temp has a higher resolution
28 * and thus has 16 bits registers for its value and limit instead of 8 bits.
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/slab.h>
34#include <linux/jiffies.h>
35#include <linux/i2c.h>
36#include <linux/hwmon.h>
37#include <linux/hwmon-sysfs.h>
38#include <linux/err.h>
39#include <linux/mutex.h>
40#include <linux/sysfs.h>
41
42/* Addresses to scan */
43static const unsigned short normal_i2c[] = { 0x4c, I2C_CLIENT_END };
44
45/* Insmod parameters */
46I2C_CLIENT_INSMOD_2(tmp401, tmp411);
47
48/*
49 * The TMP401 registers, note some registers have different addresses for
50 * reading and writing
51 */
52#define TMP401_STATUS 0x02
53#define TMP401_CONFIG_READ 0x03
54#define TMP401_CONFIG_WRITE 0x09
55#define TMP401_CONVERSION_RATE_READ 0x04
56#define TMP401_CONVERSION_RATE_WRITE 0x0A
57#define TMP401_TEMP_CRIT_HYST 0x21
58#define TMP401_CONSECUTIVE_ALERT 0x22
59#define TMP401_MANUFACTURER_ID_REG 0xFE
60#define TMP401_DEVICE_ID_REG 0xFF
61#define TMP411_N_FACTOR_REG 0x18
62
63static const u8 TMP401_TEMP_MSB[2] = { 0x00, 0x01 };
64static const u8 TMP401_TEMP_LSB[2] = { 0x15, 0x10 };
65static const u8 TMP401_TEMP_LOW_LIMIT_MSB_READ[2] = { 0x06, 0x08 };
66static const u8 TMP401_TEMP_LOW_LIMIT_MSB_WRITE[2] = { 0x0C, 0x0E };
67static const u8 TMP401_TEMP_LOW_LIMIT_LSB[2] = { 0x17, 0x14 };
68static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_READ[2] = { 0x05, 0x07 };
69static const u8 TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[2] = { 0x0B, 0x0D };
70static const u8 TMP401_TEMP_HIGH_LIMIT_LSB[2] = { 0x16, 0x13 };
71/* These are called the THERM limit / hysteresis / mask in the datasheet */
72static const u8 TMP401_TEMP_CRIT_LIMIT[2] = { 0x20, 0x19 };
73
74static const u8 TMP411_TEMP_LOWEST_MSB[2] = { 0x30, 0x34 };
75static const u8 TMP411_TEMP_LOWEST_LSB[2] = { 0x31, 0x35 };
76static const u8 TMP411_TEMP_HIGHEST_MSB[2] = { 0x32, 0x36 };
77static const u8 TMP411_TEMP_HIGHEST_LSB[2] = { 0x33, 0x37 };
78
79/* Flags */
80#define TMP401_CONFIG_RANGE 0x04
81#define TMP401_CONFIG_SHUTDOWN 0x40
82#define TMP401_STATUS_LOCAL_CRIT 0x01
83#define TMP401_STATUS_REMOTE_CRIT 0x02
84#define TMP401_STATUS_REMOTE_OPEN 0x04
85#define TMP401_STATUS_REMOTE_LOW 0x08
86#define TMP401_STATUS_REMOTE_HIGH 0x10
87#define TMP401_STATUS_LOCAL_LOW 0x20
88#define TMP401_STATUS_LOCAL_HIGH 0x40
89
90/* Manufacturer / Device ID's */
91#define TMP401_MANUFACTURER_ID 0x55
92#define TMP401_DEVICE_ID 0x11
93#define TMP411_DEVICE_ID 0x12
94
95/*
96 * Functions declarations
97 */
98
99static int tmp401_probe(struct i2c_client *client,
100 const struct i2c_device_id *id);
101static int tmp401_detect(struct i2c_client *client, int kind,
102 struct i2c_board_info *info);
103static int tmp401_remove(struct i2c_client *client);
104static struct tmp401_data *tmp401_update_device(struct device *dev);
105
106/*
107 * Driver data (common to all clients)
108 */
109
110static const struct i2c_device_id tmp401_id[] = {
111 { "tmp401", tmp401 },
112 { "tmp411", tmp411 },
113 { }
114};
115MODULE_DEVICE_TABLE(i2c, tmp401_id);
116
117static struct i2c_driver tmp401_driver = {
118 .class = I2C_CLASS_HWMON,
119 .driver = {
120 .name = "tmp401",
121 },
122 .probe = tmp401_probe,
123 .remove = tmp401_remove,
124 .id_table = tmp401_id,
125 .detect = tmp401_detect,
126 .address_data = &addr_data,
127};
128
129/*
130 * Client data (each client gets its own)
131 */
132
133struct tmp401_data {
134 struct device *hwmon_dev;
135 struct mutex update_lock;
136 char valid; /* zero until following fields are valid */
137 unsigned long last_updated; /* in jiffies */
138 int kind;
139
140 /* register values */
141 u8 status;
142 u8 config;
143 u16 temp[2];
144 u16 temp_low[2];
145 u16 temp_high[2];
146 u8 temp_crit[2];
147 u8 temp_crit_hyst;
148 u16 temp_lowest[2];
149 u16 temp_highest[2];
150};
151
152/*
153 * Sysfs attr show / store functions
154 */
155
156static int tmp401_register_to_temp(u16 reg, u8 config)
157{
158 int temp = reg;
159
160 if (config & TMP401_CONFIG_RANGE)
161 temp -= 64 * 256;
162
163 return (temp * 625 + 80) / 160;
164}
165
166static u16 tmp401_temp_to_register(long temp, u8 config)
167{
168 if (config & TMP401_CONFIG_RANGE) {
169 temp = SENSORS_LIMIT(temp, -64000, 191000);
170 temp += 64000;
171 } else
172 temp = SENSORS_LIMIT(temp, 0, 127000);
173
174 return (temp * 160 + 312) / 625;
175}
176
177static int tmp401_crit_register_to_temp(u8 reg, u8 config)
178{
179 int temp = reg;
180
181 if (config & TMP401_CONFIG_RANGE)
182 temp -= 64;
183
184 return temp * 1000;
185}
186
187static u8 tmp401_crit_temp_to_register(long temp, u8 config)
188{
189 if (config & TMP401_CONFIG_RANGE) {
190 temp = SENSORS_LIMIT(temp, -64000, 191000);
191 temp += 64000;
192 } else
193 temp = SENSORS_LIMIT(temp, 0, 127000);
194
195 return (temp + 500) / 1000;
196}
197
198static ssize_t show_temp_value(struct device *dev,
199 struct device_attribute *devattr, char *buf)
200{
201 int index = to_sensor_dev_attr(devattr)->index;
202 struct tmp401_data *data = tmp401_update_device(dev);
203
204 return sprintf(buf, "%d\n",
205 tmp401_register_to_temp(data->temp[index], data->config));
206}
207
208static ssize_t show_temp_min(struct device *dev,
209 struct device_attribute *devattr, char *buf)
210{
211 int index = to_sensor_dev_attr(devattr)->index;
212 struct tmp401_data *data = tmp401_update_device(dev);
213
214 return sprintf(buf, "%d\n",
215 tmp401_register_to_temp(data->temp_low[index], data->config));
216}
217
218static ssize_t show_temp_max(struct device *dev,
219 struct device_attribute *devattr, char *buf)
220{
221 int index = to_sensor_dev_attr(devattr)->index;
222 struct tmp401_data *data = tmp401_update_device(dev);
223
224 return sprintf(buf, "%d\n",
225 tmp401_register_to_temp(data->temp_high[index], data->config));
226}
227
228static ssize_t show_temp_crit(struct device *dev,
229 struct device_attribute *devattr, char *buf)
230{
231 int index = to_sensor_dev_attr(devattr)->index;
232 struct tmp401_data *data = tmp401_update_device(dev);
233
234 return sprintf(buf, "%d\n",
235 tmp401_crit_register_to_temp(data->temp_crit[index],
236 data->config));
237}
238
239static ssize_t show_temp_crit_hyst(struct device *dev,
240 struct device_attribute *devattr, char *buf)
241{
242 int temp, index = to_sensor_dev_attr(devattr)->index;
243 struct tmp401_data *data = tmp401_update_device(dev);
244
245 mutex_lock(&data->update_lock);
246 temp = tmp401_crit_register_to_temp(data->temp_crit[index],
247 data->config);
248 temp -= data->temp_crit_hyst * 1000;
249 mutex_unlock(&data->update_lock);
250
251 return sprintf(buf, "%d\n", temp);
252}
253
254static ssize_t show_temp_lowest(struct device *dev,
255 struct device_attribute *devattr, char *buf)
256{
257 int index = to_sensor_dev_attr(devattr)->index;
258 struct tmp401_data *data = tmp401_update_device(dev);
259
260 return sprintf(buf, "%d\n",
261 tmp401_register_to_temp(data->temp_lowest[index],
262 data->config));
263}
264
265static ssize_t show_temp_highest(struct device *dev,
266 struct device_attribute *devattr, char *buf)
267{
268 int index = to_sensor_dev_attr(devattr)->index;
269 struct tmp401_data *data = tmp401_update_device(dev);
270
271 return sprintf(buf, "%d\n",
272 tmp401_register_to_temp(data->temp_highest[index],
273 data->config));
274}
275
276static ssize_t show_status(struct device *dev,
277 struct device_attribute *devattr, char *buf)
278{
279 int mask = to_sensor_dev_attr(devattr)->index;
280 struct tmp401_data *data = tmp401_update_device(dev);
281
282 if (data->status & mask)
283 return sprintf(buf, "1\n");
284 else
285 return sprintf(buf, "0\n");
286}
287
288static ssize_t store_temp_min(struct device *dev, struct device_attribute
289 *devattr, const char *buf, size_t count)
290{
291 int index = to_sensor_dev_attr(devattr)->index;
292 struct tmp401_data *data = tmp401_update_device(dev);
293 long val;
294 u16 reg;
295
296 if (strict_strtol(buf, 10, &val))
297 return -EINVAL;
298
299 reg = tmp401_temp_to_register(val, data->config);
300
301 mutex_lock(&data->update_lock);
302
303 i2c_smbus_write_byte_data(to_i2c_client(dev),
304 TMP401_TEMP_LOW_LIMIT_MSB_WRITE[index], reg >> 8);
305 i2c_smbus_write_byte_data(to_i2c_client(dev),
306 TMP401_TEMP_LOW_LIMIT_LSB[index], reg & 0xFF);
307
308 data->temp_low[index] = reg;
309
310 mutex_unlock(&data->update_lock);
311
312 return count;
313}
314
315static ssize_t store_temp_max(struct device *dev, struct device_attribute
316 *devattr, const char *buf, size_t count)
317{
318 int index = to_sensor_dev_attr(devattr)->index;
319 struct tmp401_data *data = tmp401_update_device(dev);
320 long val;
321 u16 reg;
322
323 if (strict_strtol(buf, 10, &val))
324 return -EINVAL;
325
326 reg = tmp401_temp_to_register(val, data->config);
327
328 mutex_lock(&data->update_lock);
329
330 i2c_smbus_write_byte_data(to_i2c_client(dev),
331 TMP401_TEMP_HIGH_LIMIT_MSB_WRITE[index], reg >> 8);
332 i2c_smbus_write_byte_data(to_i2c_client(dev),
333 TMP401_TEMP_HIGH_LIMIT_LSB[index], reg & 0xFF);
334
335 data->temp_high[index] = reg;
336
337 mutex_unlock(&data->update_lock);
338
339 return count;
340}
341
342static ssize_t store_temp_crit(struct device *dev, struct device_attribute
343 *devattr, const char *buf, size_t count)
344{
345 int index = to_sensor_dev_attr(devattr)->index;
346 struct tmp401_data *data = tmp401_update_device(dev);
347 long val;
348 u8 reg;
349
350 if (strict_strtol(buf, 10, &val))
351 return -EINVAL;
352
353 reg = tmp401_crit_temp_to_register(val, data->config);
354
355 mutex_lock(&data->update_lock);
356
357 i2c_smbus_write_byte_data(to_i2c_client(dev),
358 TMP401_TEMP_CRIT_LIMIT[index], reg);
359
360 data->temp_crit[index] = reg;
361
362 mutex_unlock(&data->update_lock);
363
364 return count;
365}
366
367static ssize_t store_temp_crit_hyst(struct device *dev, struct device_attribute
368 *devattr, const char *buf, size_t count)
369{
370 int temp, index = to_sensor_dev_attr(devattr)->index;
371 struct tmp401_data *data = tmp401_update_device(dev);
372 long val;
373 u8 reg;
374
375 if (strict_strtol(buf, 10, &val))
376 return -EINVAL;
377
378 if (data->config & TMP401_CONFIG_RANGE)
379 val = SENSORS_LIMIT(val, -64000, 191000);
380 else
381 val = SENSORS_LIMIT(val, 0, 127000);
382
383 mutex_lock(&data->update_lock);
384 temp = tmp401_crit_register_to_temp(data->temp_crit[index],
385 data->config);
386 val = SENSORS_LIMIT(val, temp - 255000, temp);
387 reg = ((temp - val) + 500) / 1000;
388
389 i2c_smbus_write_byte_data(to_i2c_client(dev),
390 TMP401_TEMP_CRIT_HYST, reg);
391
392 data->temp_crit_hyst = reg;
393
394 mutex_unlock(&data->update_lock);
395
396 return count;
397}
398
399/*
400 * Resets the historical measurements of minimum and maximum temperatures.
401 * This is done by writing any value to any of the minimum/maximum registers
402 * (0x30-0x37).
403 */
404static ssize_t reset_temp_history(struct device *dev,
405 struct device_attribute *devattr, const char *buf, size_t count)
406{
407 long val;
408
409 if (strict_strtol(buf, 10, &val))
410 return -EINVAL;
411
412 if (val != 1) {
413 dev_err(dev, "temp_reset_history value %ld not"
414 " supported. Use 1 to reset the history!\n", val);
415 return -EINVAL;
416 }
417 i2c_smbus_write_byte_data(to_i2c_client(dev),
418 TMP411_TEMP_LOWEST_MSB[0], val);
419
420 return count;
421}
422
423static struct sensor_device_attribute tmp401_attr[] = {
424 SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0),
425 SENSOR_ATTR(temp1_min, 0644, show_temp_min, store_temp_min, 0),
426 SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0),
427 SENSOR_ATTR(temp1_crit, 0644, show_temp_crit, store_temp_crit, 0),
428 SENSOR_ATTR(temp1_crit_hyst, 0644, show_temp_crit_hyst,
429 store_temp_crit_hyst, 0),
430 SENSOR_ATTR(temp1_min_alarm, 0444, show_status, NULL,
431 TMP401_STATUS_LOCAL_LOW),
432 SENSOR_ATTR(temp1_max_alarm, 0444, show_status, NULL,
433 TMP401_STATUS_LOCAL_HIGH),
434 SENSOR_ATTR(temp1_crit_alarm, 0444, show_status, NULL,
435 TMP401_STATUS_LOCAL_CRIT),
436 SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1),
437 SENSOR_ATTR(temp2_min, 0644, show_temp_min, store_temp_min, 1),
438 SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1),
439 SENSOR_ATTR(temp2_crit, 0644, show_temp_crit, store_temp_crit, 1),
440 SENSOR_ATTR(temp2_crit_hyst, 0444, show_temp_crit_hyst, NULL, 1),
441 SENSOR_ATTR(temp2_fault, 0444, show_status, NULL,
442 TMP401_STATUS_REMOTE_OPEN),
443 SENSOR_ATTR(temp2_min_alarm, 0444, show_status, NULL,
444 TMP401_STATUS_REMOTE_LOW),
445 SENSOR_ATTR(temp2_max_alarm, 0444, show_status, NULL,
446 TMP401_STATUS_REMOTE_HIGH),
447 SENSOR_ATTR(temp2_crit_alarm, 0444, show_status, NULL,
448 TMP401_STATUS_REMOTE_CRIT),
449};
450
451/*
452 * Additional features of the TMP411 chip.
453 * The TMP411 stores the minimum and maximum
454 * temperature measured since power-on, chip-reset, or
455 * minimum and maximum register reset for both the local
456 * and remote channels.
457 */
458static struct sensor_device_attribute tmp411_attr[] = {
459 SENSOR_ATTR(temp1_highest, 0444, show_temp_highest, NULL, 0),
460 SENSOR_ATTR(temp1_lowest, 0444, show_temp_lowest, NULL, 0),
461 SENSOR_ATTR(temp2_highest, 0444, show_temp_highest, NULL, 1),
462 SENSOR_ATTR(temp2_lowest, 0444, show_temp_lowest, NULL, 1),
463 SENSOR_ATTR(temp_reset_history, 0200, NULL, reset_temp_history, 0),
464};
465
466/*
467 * Begin non sysfs callback code (aka Real code)
468 */
469
470static void tmp401_init_client(struct i2c_client *client)
471{
472 int config, config_orig;
473
474 /* Set the conversion rate to 2 Hz */
475 i2c_smbus_write_byte_data(client, TMP401_CONVERSION_RATE_WRITE, 5);
476
477 /* Start conversions (disable shutdown if necessary) */
478 config = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
479 if (config < 0) {
480 dev_warn(&client->dev, "Initialization failed!\n");
481 return;
482 }
483
484 config_orig = config;
485 config &= ~TMP401_CONFIG_SHUTDOWN;
486
487 if (config != config_orig)
488 i2c_smbus_write_byte_data(client, TMP401_CONFIG_WRITE, config);
489}
490
491static int tmp401_detect(struct i2c_client *client, int kind,
492 struct i2c_board_info *info)
493{
494 struct i2c_adapter *adapter = client->adapter;
495
496 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
497 return -ENODEV;
498
499 /* Detect and identify the chip */
500 if (kind <= 0) {
501 u8 reg;
502
503 reg = i2c_smbus_read_byte_data(client,
504 TMP401_MANUFACTURER_ID_REG);
505 if (reg != TMP401_MANUFACTURER_ID)
506 return -ENODEV;
507
508 reg = i2c_smbus_read_byte_data(client, TMP401_DEVICE_ID_REG);
509
510 switch (reg) {
511 case TMP401_DEVICE_ID:
512 kind = tmp401;
513 break;
514 case TMP411_DEVICE_ID:
515 kind = tmp411;
516 break;
517 default:
518 return -ENODEV;
519 }
520
521 reg = i2c_smbus_read_byte_data(client, TMP401_CONFIG_READ);
522 if (reg & 0x1b)
523 return -ENODEV;
524
525 reg = i2c_smbus_read_byte_data(client,
526 TMP401_CONVERSION_RATE_READ);
527 /* Datasheet says: 0x1-0x6 */
528 if (reg > 15)
529 return -ENODEV;
530 }
531 strlcpy(info->type, tmp401_id[kind - 1].name, I2C_NAME_SIZE);
532
533 return 0;
534}
535
536static int tmp401_probe(struct i2c_client *client,
537 const struct i2c_device_id *id)
538{
539 int i, err = 0;
540 struct tmp401_data *data;
541 const char *names[] = { "TMP401", "TMP411" };
542
543 data = kzalloc(sizeof(struct tmp401_data), GFP_KERNEL);
544 if (!data)
545 return -ENOMEM;
546
547 i2c_set_clientdata(client, data);
548 mutex_init(&data->update_lock);
549 data->kind = id->driver_data;
550
551 /* Initialize the TMP401 chip */
552 tmp401_init_client(client);
553
554 /* Register sysfs hooks */
555 for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++) {
556 err = device_create_file(&client->dev,
557 &tmp401_attr[i].dev_attr);
558 if (err)
559 goto exit_remove;
560 }
561
562 /* Register aditional tmp411 sysfs hooks */
563 if (data->kind == tmp411) {
564 for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++) {
565 err = device_create_file(&client->dev,
566 &tmp411_attr[i].dev_attr);
567 if (err)
568 goto exit_remove;
569 }
570 }
571
572 data->hwmon_dev = hwmon_device_register(&client->dev);
573 if (IS_ERR(data->hwmon_dev)) {
574 err = PTR_ERR(data->hwmon_dev);
575 data->hwmon_dev = NULL;
576 goto exit_remove;
577 }
578
579 dev_info(&client->dev, "Detected TI %s chip\n",
580 names[data->kind - 1]);
581
582 return 0;
583
584exit_remove:
585 tmp401_remove(client); /* will also free data for us */
586 return err;
587}
588
589static int tmp401_remove(struct i2c_client *client)
590{
591 struct tmp401_data *data = i2c_get_clientdata(client);
592 int i;
593
594 if (data->hwmon_dev)
595 hwmon_device_unregister(data->hwmon_dev);
596
597 for (i = 0; i < ARRAY_SIZE(tmp401_attr); i++)
598 device_remove_file(&client->dev, &tmp401_attr[i].dev_attr);
599
600 if (data->kind == tmp411) {
601 for (i = 0; i < ARRAY_SIZE(tmp411_attr); i++)
602 device_remove_file(&client->dev,
603 &tmp411_attr[i].dev_attr);
604 }
605
606 kfree(data);
607 return 0;
608}
609
610static struct tmp401_data *tmp401_update_device_reg16(
611 struct i2c_client *client, struct tmp401_data *data)
612{
613 int i;
614
615 for (i = 0; i < 2; i++) {
616 /*
617 * High byte must be read first immediately followed
618 * by the low byte
619 */
620 data->temp[i] = i2c_smbus_read_byte_data(client,
621 TMP401_TEMP_MSB[i]) << 8;
622 data->temp[i] |= i2c_smbus_read_byte_data(client,
623 TMP401_TEMP_LSB[i]);
624 data->temp_low[i] = i2c_smbus_read_byte_data(client,
625 TMP401_TEMP_LOW_LIMIT_MSB_READ[i]) << 8;
626 data->temp_low[i] |= i2c_smbus_read_byte_data(client,
627 TMP401_TEMP_LOW_LIMIT_LSB[i]);
628 data->temp_high[i] = i2c_smbus_read_byte_data(client,
629 TMP401_TEMP_HIGH_LIMIT_MSB_READ[i]) << 8;
630 data->temp_high[i] |= i2c_smbus_read_byte_data(client,
631 TMP401_TEMP_HIGH_LIMIT_LSB[i]);
632 data->temp_crit[i] = i2c_smbus_read_byte_data(client,
633 TMP401_TEMP_CRIT_LIMIT[i]);
634
635 if (data->kind == tmp411) {
636 data->temp_lowest[i] = i2c_smbus_read_byte_data(client,
637 TMP411_TEMP_LOWEST_MSB[i]) << 8;
638 data->temp_lowest[i] |= i2c_smbus_read_byte_data(
639 client, TMP411_TEMP_LOWEST_LSB[i]);
640
641 data->temp_highest[i] = i2c_smbus_read_byte_data(
642 client, TMP411_TEMP_HIGHEST_MSB[i]) << 8;
643 data->temp_highest[i] |= i2c_smbus_read_byte_data(
644 client, TMP411_TEMP_HIGHEST_LSB[i]);
645 }
646 }
647 return data;
648}
649
650static struct tmp401_data *tmp401_update_device(struct device *dev)
651{
652 struct i2c_client *client = to_i2c_client(dev);
653 struct tmp401_data *data = i2c_get_clientdata(client);
654
655 mutex_lock(&data->update_lock);
656
657 if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
658 data->status = i2c_smbus_read_byte_data(client, TMP401_STATUS);
659 data->config = i2c_smbus_read_byte_data(client,
660 TMP401_CONFIG_READ);
661 tmp401_update_device_reg16(client, data);
662
663 data->temp_crit_hyst = i2c_smbus_read_byte_data(client,
664 TMP401_TEMP_CRIT_HYST);
665
666 data->last_updated = jiffies;
667 data->valid = 1;
668 }
669
670 mutex_unlock(&data->update_lock);
671
672 return data;
673}
674
675static int __init tmp401_init(void)
676{
677 return i2c_add_driver(&tmp401_driver);
678}
679
680static void __exit tmp401_exit(void)
681{
682 i2c_del_driver(&tmp401_driver);
683}
684
685MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
686MODULE_DESCRIPTION("Texas Instruments TMP401 temperature sensor driver");
687MODULE_LICENSE("GPL");
688
689module_init(tmp401_init);
690module_exit(tmp401_exit);
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index e64b42058b21..0e9746913d2b 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -36,6 +36,7 @@
36 w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 36 w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3
37 0x8860 0xa1 37 0x8860 0xa1
38 w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 38 w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3
39 w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3
39 w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 40 w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3
40*/ 41*/
41 42
@@ -53,12 +54,13 @@
53#include <asm/io.h> 54#include <asm/io.h>
54#include "lm75.h" 55#include "lm75.h"
55 56
56enum kinds { w83627ehf, w83627dhg, w83667hg }; 57enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg };
57 58
58/* used to set data->name = w83627ehf_device_names[data->sio_kind] */ 59/* used to set data->name = w83627ehf_device_names[data->sio_kind] */
59static const char * w83627ehf_device_names[] = { 60static const char * w83627ehf_device_names[] = {
60 "w83627ehf", 61 "w83627ehf",
61 "w83627dhg", 62 "w83627dhg",
63 "w83627dhg",
62 "w83667hg", 64 "w83667hg",
63}; 65};
64 66
@@ -86,6 +88,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
86#define SIO_W83627EHF_ID 0x8850 88#define SIO_W83627EHF_ID 0x8850
87#define SIO_W83627EHG_ID 0x8860 89#define SIO_W83627EHG_ID 0x8860
88#define SIO_W83627DHG_ID 0xa020 90#define SIO_W83627DHG_ID 0xa020
91#define SIO_W83627DHG_P_ID 0xb070
89#define SIO_W83667HG_ID 0xa510 92#define SIO_W83667HG_ID 0xa510
90#define SIO_ID_MASK 0xFFF0 93#define SIO_ID_MASK 0xFFF0
91 94
@@ -1517,6 +1520,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
1517 static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; 1520 static const char __initdata sio_name_W83627EHF[] = "W83627EHF";
1518 static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; 1521 static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
1519 static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; 1522 static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
1523 static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P";
1520 static const char __initdata sio_name_W83667HG[] = "W83667HG"; 1524 static const char __initdata sio_name_W83667HG[] = "W83667HG";
1521 1525
1522 u16 val; 1526 u16 val;
@@ -1542,6 +1546,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
1542 sio_data->kind = w83627dhg; 1546 sio_data->kind = w83627dhg;
1543 sio_name = sio_name_W83627DHG; 1547 sio_name = sio_name_W83627DHG;
1544 break; 1548 break;
1549 case SIO_W83627DHG_P_ID:
1550 sio_data->kind = w83627dhg_p;
1551 sio_name = sio_name_W83627DHG_P;
1552 break;
1545 case SIO_W83667HG_ID: 1553 case SIO_W83667HG_ID:
1546 sio_data->kind = w83667hg; 1554 sio_data->kind = w83667hg;
1547 sio_name = sio_name_W83667HG; 1555 sio_name = sio_name_W83667HG;
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index c8460fa9cfac..0d04d3ebfc2d 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -211,7 +211,7 @@ config I2C_VIA
211 will be called i2c-via. 211 will be called i2c-via.
212 212
213config I2C_VIAPRO 213config I2C_VIAPRO
214 tristate "VIA VT82C596/82C686/82xx and CX700/VX800/VX820" 214 tristate "VIA VT82C596/82C686/82xx and CX700/VX8xx"
215 depends on PCI 215 depends on PCI
216 help 216 help
217 If you say yes to this option, support will be included for the VIA 217 If you say yes to this option, support will be included for the VIA
@@ -225,8 +225,8 @@ config I2C_VIAPRO
225 VT8237R/A/S 225 VT8237R/A/S
226 VT8251 226 VT8251
227 CX700 227 CX700
228 VX800 228 VX800/VX820
229 VX820 229 VX855/VX875
230 230
231 This driver can also be built as a module. If so, the module 231 This driver can also be built as a module. If so, the module
232 will be called i2c-viapro. 232 will be called i2c-viapro.
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 02e6f724b05f..54d810a4d00f 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -37,6 +37,7 @@
37 VT8251 0x3287 yes 37 VT8251 0x3287 yes
38 CX700 0x8324 yes 38 CX700 0x8324 yes
39 VX800/VX820 0x8353 yes 39 VX800/VX820 0x8353 yes
40 VX855/VX875 0x8409 yes
40 41
41 Note: we assume there can only be one device, with one SMBus interface. 42 Note: we assume there can only be one device, with one SMBus interface.
42*/ 43*/
@@ -404,6 +405,7 @@ found:
404 switch (pdev->device) { 405 switch (pdev->device) {
405 case PCI_DEVICE_ID_VIA_CX700: 406 case PCI_DEVICE_ID_VIA_CX700:
406 case PCI_DEVICE_ID_VIA_VX800: 407 case PCI_DEVICE_ID_VIA_VX800:
408 case PCI_DEVICE_ID_VIA_VX855:
407 case PCI_DEVICE_ID_VIA_8251: 409 case PCI_DEVICE_ID_VIA_8251:
408 case PCI_DEVICE_ID_VIA_8237: 410 case PCI_DEVICE_ID_VIA_8237:
409 case PCI_DEVICE_ID_VIA_8237A: 411 case PCI_DEVICE_ID_VIA_8237A:
@@ -469,6 +471,8 @@ static struct pci_device_id vt596_ids[] = {
469 .driver_data = SMBBA3 }, 471 .driver_data = SMBBA3 },
470 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800), 472 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX800),
471 .driver_data = SMBBA3 }, 473 .driver_data = SMBBA3 },
474 { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855),
475 .driver_data = SMBBA3 },
472 { 0, } 476 { 0, }
473}; 477};
474 478
diff --git a/drivers/i2c/busses/i2c-voodoo3.c b/drivers/i2c/busses/i2c-voodoo3.c
index 1a474acc0ddd..7663d57833a0 100644
--- a/drivers/i2c/busses/i2c-voodoo3.c
+++ b/drivers/i2c/busses/i2c-voodoo3.c
@@ -163,7 +163,6 @@ static struct i2c_algo_bit_data voo_i2c_bit_data = {
163 163
164static struct i2c_adapter voodoo3_i2c_adapter = { 164static struct i2c_adapter voodoo3_i2c_adapter = {
165 .owner = THIS_MODULE, 165 .owner = THIS_MODULE,
166 .class = I2C_CLASS_TV_ANALOG,
167 .name = "I2C Voodoo3/Banshee adapter", 166 .name = "I2C Voodoo3/Banshee adapter",
168 .algo_data = &voo_i2c_bit_data, 167 .algo_data = &voo_i2c_bit_data,
169}; 168};
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index 8f8c81eb0aee..02d746c9c474 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -64,21 +64,6 @@ config SENSORS_PCA9539
64 This driver is deprecated and will be dropped soon. Use 64 This driver is deprecated and will be dropped soon. Use
65 drivers/gpio/pca953x.c instead. 65 drivers/gpio/pca953x.c instead.
66 66
67config SENSORS_MAX6875
68 tristate "Maxim MAX6875 Power supply supervisor"
69 depends on EXPERIMENTAL
70 help
71 If you say yes here you get support for the Maxim MAX6875
72 EEPROM-programmable, quad power-supply sequencer/supervisor.
73
74 This provides an interface to program the EEPROM and reset the chip.
75
76 This driver also supports the Maxim MAX6874 hex power-supply
77 sequencer/supervisor if found at a compatible address.
78
79 This driver can also be built as a module. If so, the module
80 will be called max6875.
81
82config SENSORS_TSL2550 67config SENSORS_TSL2550
83 tristate "Taos TSL2550 ambient light sensor" 68 tristate "Taos TSL2550 ambient light sensor"
84 depends on EXPERIMENTAL 69 depends on EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index 55a376037183..f4680d16ee34 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -11,7 +11,6 @@
11# 11#
12 12
13obj-$(CONFIG_DS1682) += ds1682.o 13obj-$(CONFIG_DS1682) += ds1682.o
14obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
15obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o 14obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
16obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o 15obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
17obj-$(CONFIG_PCF8575) += pcf8575.o 16obj-$(CONFIG_PCF8575) += pcf8575.o
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 85e2e919d1cd..5ed622ee65c3 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -29,7 +29,6 @@
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/idr.h> 31#include <linux/idr.h>
32#include <linux/platform_device.h>
33#include <linux/mutex.h> 32#include <linux/mutex.h>
34#include <linux/completion.h> 33#include <linux/completion.h>
35#include <linux/hardirq.h> 34#include <linux/hardirq.h>
@@ -451,16 +450,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
451 450
452 mutex_lock(&core_lock); 451 mutex_lock(&core_lock);
453 452
454 /* Add the adapter to the driver core.
455 * If the parent pointer is not set up,
456 * we add this adapter to the host bus.
457 */
458 if (adap->dev.parent == NULL) {
459 adap->dev.parent = &platform_bus;
460 pr_debug("I2C adapter driver [%s] forgot to specify "
461 "physical device\n", adap->name);
462 }
463
464 /* Set default timeout to 1 second if not already set */ 453 /* Set default timeout to 1 second if not already set */
465 if (adap->timeout == 0) 454 if (adap->timeout == 0)
466 adap->timeout = HZ; 455 adap->timeout = HZ;
@@ -1022,7 +1011,8 @@ module_exit(i2c_exit);
1022 */ 1011 */
1023int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) 1012int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
1024{ 1013{
1025 int ret; 1014 unsigned long orig_jiffies;
1015 int ret, try;
1026 1016
1027 /* REVISIT the fault reporting model here is weak: 1017 /* REVISIT the fault reporting model here is weak:
1028 * 1018 *
@@ -1060,7 +1050,15 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
1060 mutex_lock_nested(&adap->bus_lock, adap->level); 1050 mutex_lock_nested(&adap->bus_lock, adap->level);
1061 } 1051 }
1062 1052
1063 ret = adap->algo->master_xfer(adap,msgs,num); 1053 /* Retry automatically on arbitration loss */
1054 orig_jiffies = jiffies;
1055 for (ret = 0, try = 0; try <= adap->retries; try++) {
1056 ret = adap->algo->master_xfer(adap, msgs, num);
1057 if (ret != -EAGAIN)
1058 break;
1059 if (time_after(jiffies, orig_jiffies + adap->timeout))
1060 break;
1061 }
1064 mutex_unlock(&adap->bus_lock); 1062 mutex_unlock(&adap->bus_lock);
1065 1063
1066 return ret; 1064 return ret;
@@ -1509,7 +1507,7 @@ struct i2c_adapter* i2c_get_adapter(int id)
1509 struct i2c_adapter *adapter; 1507 struct i2c_adapter *adapter;
1510 1508
1511 mutex_lock(&core_lock); 1509 mutex_lock(&core_lock);
1512 adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id); 1510 adapter = idr_find(&i2c_adapter_idr, id);
1513 if (adapter && !try_module_get(adapter->owner)) 1511 if (adapter && !try_module_get(adapter->owner))
1514 adapter = NULL; 1512 adapter = NULL;
1515 1513
@@ -1995,14 +1993,27 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
1995 char read_write, u8 command, int protocol, 1993 char read_write, u8 command, int protocol,
1996 union i2c_smbus_data *data) 1994 union i2c_smbus_data *data)
1997{ 1995{
1996 unsigned long orig_jiffies;
1997 int try;
1998 s32 res; 1998 s32 res;
1999 1999
2000 flags &= I2C_M_TEN | I2C_CLIENT_PEC; 2000 flags &= I2C_M_TEN | I2C_CLIENT_PEC;
2001 2001
2002 if (adapter->algo->smbus_xfer) { 2002 if (adapter->algo->smbus_xfer) {
2003 mutex_lock(&adapter->bus_lock); 2003 mutex_lock(&adapter->bus_lock);
2004 res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write, 2004
2005 command, protocol, data); 2005 /* Retry automatically on arbitration loss */
2006 orig_jiffies = jiffies;
2007 for (res = 0, try = 0; try <= adapter->retries; try++) {
2008 res = adapter->algo->smbus_xfer(adapter, addr, flags,
2009 read_write, command,
2010 protocol, data);
2011 if (res != -EAGAIN)
2012 break;
2013 if (time_after(jiffies,
2014 orig_jiffies + adapter->timeout))
2015 break;
2016 }
2006 mutex_unlock(&adapter->bus_lock); 2017 mutex_unlock(&adapter->bus_lock);
2007 } else 2018 } else
2008 res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write, 2019 res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 0ddf9044948a..fde377c60cca 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -72,7 +72,7 @@ MODULE_PARM_DESC(verbose,"Verbose log operations "
72 "(default 0)"); 72 "(default 0)");
73 73
74struct thermostat { 74struct thermostat {
75 struct i2c_client clt; 75 struct i2c_client *clt;
76 u8 temps[3]; 76 u8 temps[3];
77 u8 cached_temp[3]; 77 u8 cached_temp[3];
78 u8 initial_limits[3]; 78 u8 initial_limits[3];
@@ -87,9 +87,6 @@ static struct of_device * of_dev;
87static struct thermostat* thermostat; 87static struct thermostat* thermostat;
88static struct task_struct *thread_therm = NULL; 88static struct task_struct *thread_therm = NULL;
89 89
90static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
91 int busno);
92
93static void write_both_fan_speed(struct thermostat *th, int speed); 90static void write_both_fan_speed(struct thermostat *th, int speed);
94static void write_fan_speed(struct thermostat *th, int speed, int fan); 91static void write_fan_speed(struct thermostat *th, int speed, int fan);
95 92
@@ -101,7 +98,7 @@ write_reg(struct thermostat* th, int reg, u8 data)
101 98
102 tmp[0] = reg; 99 tmp[0] = reg;
103 tmp[1] = data; 100 tmp[1] = data;
104 rc = i2c_master_send(&th->clt, (const char *)tmp, 2); 101 rc = i2c_master_send(th->clt, (const char *)tmp, 2);
105 if (rc < 0) 102 if (rc < 0)
106 return rc; 103 return rc;
107 if (rc != 2) 104 if (rc != 2)
@@ -116,12 +113,12 @@ read_reg(struct thermostat* th, int reg)
116 int rc; 113 int rc;
117 114
118 reg_addr = (u8)reg; 115 reg_addr = (u8)reg;
119 rc = i2c_master_send(&th->clt, &reg_addr, 1); 116 rc = i2c_master_send(th->clt, &reg_addr, 1);
120 if (rc < 0) 117 if (rc < 0)
121 return rc; 118 return rc;
122 if (rc != 1) 119 if (rc != 1)
123 return -ENODEV; 120 return -ENODEV;
124 rc = i2c_master_recv(&th->clt, (char *)&data, 1); 121 rc = i2c_master_recv(th->clt, (char *)&data, 1);
125 if (rc < 0) 122 if (rc < 0)
126 return rc; 123 return rc;
127 return data; 124 return data;
@@ -131,26 +128,36 @@ static int
131attach_thermostat(struct i2c_adapter *adapter) 128attach_thermostat(struct i2c_adapter *adapter)
132{ 129{
133 unsigned long bus_no; 130 unsigned long bus_no;
131 struct i2c_board_info info;
132 struct i2c_client *client;
134 133
135 if (strncmp(adapter->name, "uni-n", 5)) 134 if (strncmp(adapter->name, "uni-n", 5))
136 return -ENODEV; 135 return -ENODEV;
137 bus_no = simple_strtoul(adapter->name + 6, NULL, 10); 136 bus_no = simple_strtoul(adapter->name + 6, NULL, 10);
138 if (bus_no != therm_bus) 137 if (bus_no != therm_bus)
139 return -ENODEV; 138 return -ENODEV;
140 return attach_one_thermostat(adapter, therm_address, bus_no); 139
140 memset(&info, 0, sizeof(struct i2c_board_info));
141 strlcpy(info.type, "therm_adt746x", I2C_NAME_SIZE);
142 info.addr = therm_address;
143 client = i2c_new_device(adapter, &info);
144 if (!client)
145 return -ENODEV;
146
147 /*
148 * Let i2c-core delete that device on driver removal.
149 * This is safe because i2c-core holds the core_lock mutex for us.
150 */
151 list_add_tail(&client->detected, &client->driver->clients);
152 return 0;
141} 153}
142 154
143static int 155static int
144detach_thermostat(struct i2c_adapter *adapter) 156remove_thermostat(struct i2c_client *client)
145{ 157{
146 struct thermostat* th; 158 struct thermostat *th = i2c_get_clientdata(client);
147 int i; 159 int i;
148 160
149 if (thermostat == NULL)
150 return 0;
151
152 th = thermostat;
153
154 if (thread_therm != NULL) { 161 if (thread_therm != NULL) {
155 kthread_stop(thread_therm); 162 kthread_stop(thread_therm);
156 } 163 }
@@ -166,8 +173,6 @@ detach_thermostat(struct i2c_adapter *adapter)
166 173
167 write_both_fan_speed(th, -1); 174 write_both_fan_speed(th, -1);
168 175
169 i2c_detach_client(&th->clt);
170
171 thermostat = NULL; 176 thermostat = NULL;
172 177
173 kfree(th); 178 kfree(th);
@@ -175,14 +180,6 @@ detach_thermostat(struct i2c_adapter *adapter)
175 return 0; 180 return 0;
176} 181}
177 182
178static struct i2c_driver thermostat_driver = {
179 .driver = {
180 .name = "therm_adt746x",
181 },
182 .attach_adapter = attach_thermostat,
183 .detach_adapter = detach_thermostat,
184};
185
186static int read_fan_speed(struct thermostat *th, u8 addr) 183static int read_fan_speed(struct thermostat *th, u8 addr)
187{ 184{
188 u8 tmp[2]; 185 u8 tmp[2];
@@ -371,8 +368,8 @@ static void set_limit(struct thermostat *th, int i)
371 th->limits[i] = default_limits_local[i] + limit_adjust; 368 th->limits[i] = default_limits_local[i] + limit_adjust;
372} 369}
373 370
374static int attach_one_thermostat(struct i2c_adapter *adapter, int addr, 371static int probe_thermostat(struct i2c_client *client,
375 int busno) 372 const struct i2c_device_id *id)
376{ 373{
377 struct thermostat* th; 374 struct thermostat* th;
378 int rc; 375 int rc;
@@ -385,16 +382,12 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
385 if (!th) 382 if (!th)
386 return -ENOMEM; 383 return -ENOMEM;
387 384
388 th->clt.addr = addr; 385 i2c_set_clientdata(client, th);
389 th->clt.adapter = adapter; 386 th->clt = client;
390 th->clt.driver = &thermostat_driver;
391 strcpy(th->clt.name, "thermostat");
392 387
393 rc = read_reg(th, 0); 388 rc = read_reg(th, 0);
394 if (rc < 0) { 389 if (rc < 0) {
395 printk(KERN_ERR "adt746x: Thermostat failed to read config " 390 dev_err(&client->dev, "Thermostat failed to read config!\n");
396 "from bus %d !\n",
397 busno);
398 kfree(th); 391 kfree(th);
399 return -ENODEV; 392 return -ENODEV;
400 } 393 }
@@ -423,14 +416,6 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
423 416
424 thermostat = th; 417 thermostat = th;
425 418
426 if (i2c_attach_client(&th->clt)) {
427 printk(KERN_INFO "adt746x: Thermostat failed to attach "
428 "client !\n");
429 thermostat = NULL;
430 kfree(th);
431 return -ENODEV;
432 }
433
434 /* be sure to really write fan speed the first time */ 419 /* be sure to really write fan speed the first time */
435 th->last_speed[0] = -2; 420 th->last_speed[0] = -2;
436 th->last_speed[1] = -2; 421 th->last_speed[1] = -2;
@@ -456,6 +441,21 @@ static int attach_one_thermostat(struct i2c_adapter *adapter, int addr,
456 return 0; 441 return 0;
457} 442}
458 443
444static const struct i2c_device_id therm_adt746x_id[] = {
445 { "therm_adt746x", 0 },
446 { }
447};
448
449static struct i2c_driver thermostat_driver = {
450 .driver = {
451 .name = "therm_adt746x",
452 },
453 .attach_adapter = attach_thermostat,
454 .probe = probe_thermostat,
455 .remove = remove_thermostat,
456 .id_table = therm_adt746x_id,
457};
458
459/* 459/*
460 * Now, unfortunately, sysfs doesn't give us a nice void * we could 460 * Now, unfortunately, sysfs doesn't give us a nice void * we could
461 * pass around to the attribute functions, so we don't really have 461 * pass around to the attribute functions, so we don't really have
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index 817607e2af6a..a028598af2d3 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -287,22 +287,6 @@ struct fcu_fan_table fcu_fans[] = {
287}; 287};
288 288
289/* 289/*
290 * i2c_driver structure to attach to the host i2c controller
291 */
292
293static int therm_pm72_attach(struct i2c_adapter *adapter);
294static int therm_pm72_detach(struct i2c_adapter *adapter);
295
296static struct i2c_driver therm_pm72_driver =
297{
298 .driver = {
299 .name = "therm_pm72",
300 },
301 .attach_adapter = therm_pm72_attach,
302 .detach_adapter = therm_pm72_detach,
303};
304
305/*
306 * Utility function to create an i2c_client structure and 290 * Utility function to create an i2c_client structure and
307 * attach it to one of u3 adapters 291 * attach it to one of u3 adapters
308 */ 292 */
@@ -310,6 +294,7 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
310{ 294{
311 struct i2c_client *clt; 295 struct i2c_client *clt;
312 struct i2c_adapter *adap; 296 struct i2c_adapter *adap;
297 struct i2c_board_info info;
313 298
314 if (id & 0x200) 299 if (id & 0x200)
315 adap = k2; 300 adap = k2;
@@ -320,31 +305,21 @@ static struct i2c_client *attach_i2c_chip(int id, const char *name)
320 if (adap == NULL) 305 if (adap == NULL)
321 return NULL; 306 return NULL;
322 307
323 clt = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); 308 memset(&info, 0, sizeof(struct i2c_board_info));
324 if (clt == NULL) 309 info.addr = (id >> 1) & 0x7f;
325 return NULL; 310 strlcpy(info.type, "therm_pm72", I2C_NAME_SIZE);
326 311 clt = i2c_new_device(adap, &info);
327 clt->addr = (id >> 1) & 0x7f; 312 if (!clt) {
328 clt->adapter = adap;
329 clt->driver = &therm_pm72_driver;
330 strncpy(clt->name, name, I2C_NAME_SIZE-1);
331
332 if (i2c_attach_client(clt)) {
333 printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id); 313 printk(KERN_ERR "therm_pm72: Failed to attach to i2c ID 0x%x\n", id);
334 kfree(clt);
335 return NULL; 314 return NULL;
336 } 315 }
337 return clt;
338}
339 316
340/* 317 /*
341 * Utility function to get rid of the i2c_client structure 318 * Let i2c-core delete that device on driver removal.
342 * (will also detach from the adapter hopepfully) 319 * This is safe because i2c-core holds the core_lock mutex for us.
343 */ 320 */
344static void detach_i2c_chip(struct i2c_client *clt) 321 list_add_tail(&clt->detected, &clt->driver->clients);
345{ 322 return clt;
346 i2c_detach_client(clt);
347 kfree(clt);
348} 323}
349 324
350/* 325/*
@@ -1203,8 +1178,6 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
1203 1178
1204 return 0; 1179 return 0;
1205 fail: 1180 fail:
1206 if (state->monitor)
1207 detach_i2c_chip(state->monitor);
1208 state->monitor = NULL; 1181 state->monitor = NULL;
1209 1182
1210 return -ENODEV; 1183 return -ENODEV;
@@ -1232,7 +1205,6 @@ static void dispose_cpu_state(struct cpu_pid_state *state)
1232 device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm); 1205 device_remove_file(&of_dev->dev, &dev_attr_cpu1_intake_fan_rpm);
1233 } 1206 }
1234 1207
1235 detach_i2c_chip(state->monitor);
1236 state->monitor = NULL; 1208 state->monitor = NULL;
1237} 1209}
1238 1210
@@ -1407,7 +1379,6 @@ static void dispose_backside_state(struct backside_pid_state *state)
1407 device_remove_file(&of_dev->dev, &dev_attr_backside_temperature); 1379 device_remove_file(&of_dev->dev, &dev_attr_backside_temperature);
1408 device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm); 1380 device_remove_file(&of_dev->dev, &dev_attr_backside_fan_pwm);
1409 1381
1410 detach_i2c_chip(state->monitor);
1411 state->monitor = NULL; 1382 state->monitor = NULL;
1412} 1383}
1413 1384
@@ -1532,7 +1503,6 @@ static void dispose_drives_state(struct drives_pid_state *state)
1532 device_remove_file(&of_dev->dev, &dev_attr_drives_temperature); 1503 device_remove_file(&of_dev->dev, &dev_attr_drives_temperature);
1533 device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm); 1504 device_remove_file(&of_dev->dev, &dev_attr_drives_fan_rpm);
1534 1505
1535 detach_i2c_chip(state->monitor);
1536 state->monitor = NULL; 1506 state->monitor = NULL;
1537} 1507}
1538 1508
@@ -1654,7 +1624,6 @@ static void dispose_dimms_state(struct dimm_pid_state *state)
1654 1624
1655 device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature); 1625 device_remove_file(&of_dev->dev, &dev_attr_dimms_temperature);
1656 1626
1657 detach_i2c_chip(state->monitor);
1658 state->monitor = NULL; 1627 state->monitor = NULL;
1659} 1628}
1660 1629
@@ -1779,7 +1748,6 @@ static void dispose_slots_state(struct slots_pid_state *state)
1779 device_remove_file(&of_dev->dev, &dev_attr_slots_temperature); 1748 device_remove_file(&of_dev->dev, &dev_attr_slots_temperature);
1780 device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm); 1749 device_remove_file(&of_dev->dev, &dev_attr_slots_fan_pwm);
1781 1750
1782 detach_i2c_chip(state->monitor);
1783 state->monitor = NULL; 1751 state->monitor = NULL;
1784} 1752}
1785 1753
@@ -2008,8 +1976,6 @@ static int attach_fcu(void)
2008 */ 1976 */
2009static void detach_fcu(void) 1977static void detach_fcu(void)
2010{ 1978{
2011 if (fcu)
2012 detach_i2c_chip(fcu);
2013 fcu = NULL; 1979 fcu = NULL;
2014} 1980}
2015 1981
@@ -2060,12 +2026,21 @@ static int therm_pm72_attach(struct i2c_adapter *adapter)
2060 return 0; 2026 return 0;
2061} 2027}
2062 2028
2029static int therm_pm72_probe(struct i2c_client *client,
2030 const struct i2c_device_id *id)
2031{
2032 /* Always succeed, the real work was done in therm_pm72_attach() */
2033 return 0;
2034}
2035
2063/* 2036/*
2064 * Called on every adapter when the driver or the i2c controller 2037 * Called when any of the devices which participates into thermal management
2065 * is going away. 2038 * is going away.
2066 */ 2039 */
2067static int therm_pm72_detach(struct i2c_adapter *adapter) 2040static int therm_pm72_remove(struct i2c_client *client)
2068{ 2041{
2042 struct i2c_adapter *adapter = client->adapter;
2043
2069 mutex_lock(&driver_lock); 2044 mutex_lock(&driver_lock);
2070 2045
2071 if (state != state_detached) 2046 if (state != state_detached)
@@ -2096,6 +2071,30 @@ static int therm_pm72_detach(struct i2c_adapter *adapter)
2096 return 0; 2071 return 0;
2097} 2072}
2098 2073
2074/*
2075 * i2c_driver structure to attach to the host i2c controller
2076 */
2077
2078static const struct i2c_device_id therm_pm72_id[] = {
2079 /*
2080 * Fake device name, thermal management is done by several
2081 * chips but we don't need to differentiate between them at
2082 * this point.
2083 */
2084 { "therm_pm72", 0 },
2085 { }
2086};
2087
2088static struct i2c_driver therm_pm72_driver = {
2089 .driver = {
2090 .name = "therm_pm72",
2091 },
2092 .attach_adapter = therm_pm72_attach,
2093 .probe = therm_pm72_probe,
2094 .remove = therm_pm72_remove,
2095 .id_table = therm_pm72_id,
2096};
2097
2099static int fan_check_loc_match(const char *loc, int fan) 2098static int fan_check_loc_match(const char *loc, int fan)
2100{ 2099{
2101 char tmp[64]; 2100 char tmp[64];
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 3da0a02efd76..40023313a760 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -48,16 +48,6 @@
48 48
49#define LOG_TEMP 0 /* continously log temperature */ 49#define LOG_TEMP 0 /* continously log temperature */
50 50
51static int do_probe( struct i2c_adapter *adapter, int addr, int kind);
52
53/* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
54static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
55 0x4c, 0x4d, 0x4e, 0x4f,
56 0x2c, 0x2d, 0x2e, 0x2f,
57 I2C_CLIENT_END };
58
59I2C_CLIENT_INSMOD;
60
61static struct { 51static struct {
62 volatile int running; 52 volatile int running;
63 struct task_struct *poll_task; 53 struct task_struct *poll_task;
@@ -315,53 +305,54 @@ static int control_loop(void *dummy)
315static int 305static int
316do_attach( struct i2c_adapter *adapter ) 306do_attach( struct i2c_adapter *adapter )
317{ 307{
318 int ret = 0; 308 /* scan 0x48-0x4f (DS1775) and 0x2c-2x2f (ADM1030) */
309 static const unsigned short scan_ds1775[] = {
310 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
311 I2C_CLIENT_END
312 };
313 static const unsigned short scan_adm1030[] = {
314 0x2c, 0x2d, 0x2e, 0x2f,
315 I2C_CLIENT_END
316 };
319 317
320 if( strncmp(adapter->name, "uni-n", 5) ) 318 if( strncmp(adapter->name, "uni-n", 5) )
321 return 0; 319 return 0;
322 320
323 if( !x.running ) { 321 if( !x.running ) {
324 ret = i2c_probe( adapter, &addr_data, &do_probe ); 322 struct i2c_board_info info;
323
324 memset(&info, 0, sizeof(struct i2c_board_info));
325 strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE);
326 i2c_new_probed_device(adapter, &info, scan_ds1775);
327
328 strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE);
329 i2c_new_probed_device(adapter, &info, scan_adm1030);
330
325 if( x.thermostat && x.fan ) { 331 if( x.thermostat && x.fan ) {
326 x.running = 1; 332 x.running = 1;
327 x.poll_task = kthread_run(control_loop, NULL, "g4fand"); 333 x.poll_task = kthread_run(control_loop, NULL, "g4fand");
328 } 334 }
329 } 335 }
330 return ret; 336 return 0;
331} 337}
332 338
333static int 339static int
334do_detach( struct i2c_client *client ) 340do_remove(struct i2c_client *client)
335{ 341{
336 int err; 342 if (x.running) {
337 343 x.running = 0;
338 if( (err=i2c_detach_client(client)) ) 344 kthread_stop(x.poll_task);
339 printk(KERN_ERR "failed to detach thermostat client\n"); 345 x.poll_task = NULL;
340 else {
341 if( x.running ) {
342 x.running = 0;
343 kthread_stop(x.poll_task);
344 x.poll_task = NULL;
345 }
346 if( client == x.thermostat )
347 x.thermostat = NULL;
348 else if( client == x.fan )
349 x.fan = NULL;
350 else {
351 printk(KERN_ERR "g4fan: bad client\n");
352 }
353 kfree( client );
354 } 346 }
355 return err; 347 if (client == x.thermostat)
356} 348 x.thermostat = NULL;
349 else if (client == x.fan)
350 x.fan = NULL;
351 else
352 printk(KERN_ERR "g4fan: bad client\n");
357 353
358static struct i2c_driver g4fan_driver = { 354 return 0;
359 .driver = { 355}
360 .name = "therm_windtunnel",
361 },
362 .attach_adapter = do_attach,
363 .detach_client = do_detach,
364};
365 356
366static int 357static int
367attach_fan( struct i2c_client *cl ) 358attach_fan( struct i2c_client *cl )
@@ -374,13 +365,8 @@ attach_fan( struct i2c_client *cl )
374 goto out; 365 goto out;
375 printk("ADM1030 fan controller [@%02x]\n", cl->addr ); 366 printk("ADM1030 fan controller [@%02x]\n", cl->addr );
376 367
377 strlcpy( cl->name, "ADM1030 fan controller", sizeof(cl->name) ); 368 x.fan = cl;
378
379 if( !i2c_attach_client(cl) )
380 x.fan = cl;
381 out: 369 out:
382 if( cl != x.fan )
383 kfree( cl );
384 return 0; 370 return 0;
385} 371}
386 372
@@ -412,39 +398,47 @@ attach_thermostat( struct i2c_client *cl )
412 x.temp = temp; 398 x.temp = temp;
413 x.overheat_temp = os_temp; 399 x.overheat_temp = os_temp;
414 x.overheat_hyst = hyst_temp; 400 x.overheat_hyst = hyst_temp;
415 401 x.thermostat = cl;
416 strlcpy( cl->name, "DS1775 thermostat", sizeof(cl->name) );
417
418 if( !i2c_attach_client(cl) )
419 x.thermostat = cl;
420out: 402out:
421 if( cl != x.thermostat )
422 kfree( cl );
423 return 0; 403 return 0;
424} 404}
425 405
406enum chip { ds1775, adm1030 };
407
408static const struct i2c_device_id therm_windtunnel_id[] = {
409 { "therm_ds1775", ds1775 },
410 { "therm_adm1030", adm1030 },
411 { }
412};
413
426static int 414static int
427do_probe( struct i2c_adapter *adapter, int addr, int kind ) 415do_probe(struct i2c_client *cl, const struct i2c_device_id *id)
428{ 416{
429 struct i2c_client *cl; 417 struct i2c_adapter *adapter = cl->adapter;
430 418
431 if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA 419 if( !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA
432 | I2C_FUNC_SMBUS_WRITE_BYTE) ) 420 | I2C_FUNC_SMBUS_WRITE_BYTE) )
433 return 0; 421 return 0;
434 422
435 if( !(cl=kzalloc(sizeof(*cl), GFP_KERNEL)) ) 423 switch (id->driver_data) {
436 return -ENOMEM; 424 case adm1030:
437
438 cl->addr = addr;
439 cl->adapter = adapter;
440 cl->driver = &g4fan_driver;
441 cl->flags = 0;
442
443 if( addr < 0x48 )
444 return attach_fan( cl ); 425 return attach_fan( cl );
445 return attach_thermostat( cl ); 426 case ds1775:
427 return attach_thermostat(cl);
428 }
429 return 0;
446} 430}
447 431
432static struct i2c_driver g4fan_driver = {
433 .driver = {
434 .name = "therm_windtunnel",
435 },
436 .attach_adapter = do_attach,
437 .probe = do_probe,
438 .remove = do_remove,
439 .id_table = therm_windtunnel_id,
440};
441
448 442
449/************************************************************************/ 443/************************************************************************/
450/* initialization / cleanup */ 444/* initialization / cleanup */
diff --git a/drivers/macintosh/windfarm_lm75_sensor.c b/drivers/macintosh/windfarm_lm75_sensor.c
index b92b959fe16e..529886c7a826 100644
--- a/drivers/macintosh/windfarm_lm75_sensor.c
+++ b/drivers/macintosh/windfarm_lm75_sensor.c
@@ -37,34 +37,22 @@
37struct wf_lm75_sensor { 37struct wf_lm75_sensor {
38 int ds1775 : 1; 38 int ds1775 : 1;
39 int inited : 1; 39 int inited : 1;
40 struct i2c_client i2c; 40 struct i2c_client *i2c;
41 struct wf_sensor sens; 41 struct wf_sensor sens;
42}; 42};
43#define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens) 43#define wf_to_lm75(c) container_of(c, struct wf_lm75_sensor, sens)
44#define i2c_to_lm75(c) container_of(c, struct wf_lm75_sensor, i2c)
45
46static int wf_lm75_attach(struct i2c_adapter *adapter);
47static int wf_lm75_detach(struct i2c_client *client);
48
49static struct i2c_driver wf_lm75_driver = {
50 .driver = {
51 .name = "wf_lm75",
52 },
53 .attach_adapter = wf_lm75_attach,
54 .detach_client = wf_lm75_detach,
55};
56 44
57static int wf_lm75_get(struct wf_sensor *sr, s32 *value) 45static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
58{ 46{
59 struct wf_lm75_sensor *lm = wf_to_lm75(sr); 47 struct wf_lm75_sensor *lm = wf_to_lm75(sr);
60 s32 data; 48 s32 data;
61 49
62 if (lm->i2c.adapter == NULL) 50 if (lm->i2c == NULL)
63 return -ENODEV; 51 return -ENODEV;
64 52
65 /* Init chip if necessary */ 53 /* Init chip if necessary */
66 if (!lm->inited) { 54 if (!lm->inited) {
67 u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(&lm->i2c, 1); 55 u8 cfg_new, cfg = (u8)i2c_smbus_read_byte_data(lm->i2c, 1);
68 56
69 DBG("wf_lm75: Initializing %s, cfg was: %02x\n", 57 DBG("wf_lm75: Initializing %s, cfg was: %02x\n",
70 sr->name, cfg); 58 sr->name, cfg);
@@ -73,7 +61,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
73 * the firmware for now 61 * the firmware for now
74 */ 62 */
75 cfg_new = cfg & ~0x01; 63 cfg_new = cfg & ~0x01;
76 i2c_smbus_write_byte_data(&lm->i2c, 1, cfg_new); 64 i2c_smbus_write_byte_data(lm->i2c, 1, cfg_new);
77 lm->inited = 1; 65 lm->inited = 1;
78 66
79 /* If we just powered it up, let's wait 200 ms */ 67 /* If we just powered it up, let's wait 200 ms */
@@ -81,7 +69,7 @@ static int wf_lm75_get(struct wf_sensor *sr, s32 *value)
81 } 69 }
82 70
83 /* Read temperature register */ 71 /* Read temperature register */
84 data = (s32)le16_to_cpu(i2c_smbus_read_word_data(&lm->i2c, 0)); 72 data = (s32)le16_to_cpu(i2c_smbus_read_word_data(lm->i2c, 0));
85 data <<= 8; 73 data <<= 8;
86 *value = data; 74 *value = data;
87 75
@@ -92,12 +80,6 @@ static void wf_lm75_release(struct wf_sensor *sr)
92{ 80{
93 struct wf_lm75_sensor *lm = wf_to_lm75(sr); 81 struct wf_lm75_sensor *lm = wf_to_lm75(sr);
94 82
95 /* check if client is registered and detach from i2c */
96 if (lm->i2c.adapter) {
97 i2c_detach_client(&lm->i2c);
98 lm->i2c.adapter = NULL;
99 }
100
101 kfree(lm); 83 kfree(lm);
102} 84}
103 85
@@ -107,59 +89,77 @@ static struct wf_sensor_ops wf_lm75_ops = {
107 .owner = THIS_MODULE, 89 .owner = THIS_MODULE,
108}; 90};
109 91
110static struct wf_lm75_sensor *wf_lm75_create(struct i2c_adapter *adapter, 92static int wf_lm75_probe(struct i2c_client *client,
111 u8 addr, int ds1775, 93 const struct i2c_device_id *id)
112 const char *loc)
113{ 94{
114 struct wf_lm75_sensor *lm; 95 struct wf_lm75_sensor *lm;
115 int rc; 96 int rc;
116 97
117 DBG("wf_lm75: creating %s device at address 0x%02x\n",
118 ds1775 ? "ds1775" : "lm75", addr);
119
120 lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL); 98 lm = kzalloc(sizeof(struct wf_lm75_sensor), GFP_KERNEL);
121 if (lm == NULL) 99 if (lm == NULL)
122 return NULL; 100 return -ENODEV;
101
102 lm->inited = 0;
103 lm->ds1775 = id->driver_data;
104 lm->i2c = client;
105 lm->sens.name = client->dev.platform_data;
106 lm->sens.ops = &wf_lm75_ops;
107 i2c_set_clientdata(client, lm);
108
109 rc = wf_register_sensor(&lm->sens);
110 if (rc) {
111 i2c_set_clientdata(client, NULL);
112 kfree(lm);
113 }
114
115 return rc;
116}
117
118static struct i2c_client *wf_lm75_create(struct i2c_adapter *adapter,
119 u8 addr, int ds1775,
120 const char *loc)
121{
122 struct i2c_board_info info;
123 struct i2c_client *client;
124 char *name;
125
126 DBG("wf_lm75: creating %s device at address 0x%02x\n",
127 ds1775 ? "ds1775" : "lm75", addr);
123 128
124 /* Usual rant about sensor names not beeing very consistent in 129 /* Usual rant about sensor names not beeing very consistent in
125 * the device-tree, oh well ... 130 * the device-tree, oh well ...
126 * Add more entries below as you deal with more setups 131 * Add more entries below as you deal with more setups
127 */ 132 */
128 if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY")) 133 if (!strcmp(loc, "Hard drive") || !strcmp(loc, "DRIVE BAY"))
129 lm->sens.name = "hd-temp"; 134 name = "hd-temp";
130 else if (!strcmp(loc, "Incoming Air Temp")) 135 else if (!strcmp(loc, "Incoming Air Temp"))
131 lm->sens.name = "incoming-air-temp"; 136 name = "incoming-air-temp";
132 else if (!strcmp(loc, "ODD Temp")) 137 else if (!strcmp(loc, "ODD Temp"))
133 lm->sens.name = "optical-drive-temp"; 138 name = "optical-drive-temp";
134 else if (!strcmp(loc, "HD Temp")) 139 else if (!strcmp(loc, "HD Temp"))
135 lm->sens.name = "hard-drive-temp"; 140 name = "hard-drive-temp";
136 else 141 else
137 goto fail; 142 goto fail;
138 143
139 lm->inited = 0; 144 memset(&info, 0, sizeof(struct i2c_board_info));
140 lm->sens.ops = &wf_lm75_ops; 145 info.addr = (addr >> 1) & 0x7f;
141 lm->ds1775 = ds1775; 146 info.platform_data = name;
142 lm->i2c.addr = (addr >> 1) & 0x7f; 147 strlcpy(info.type, ds1775 ? "wf_ds1775" : "wf_lm75", I2C_NAME_SIZE);
143 lm->i2c.adapter = adapter;
144 lm->i2c.driver = &wf_lm75_driver;
145 strncpy(lm->i2c.name, lm->sens.name, I2C_NAME_SIZE-1);
146
147 rc = i2c_attach_client(&lm->i2c);
148 if (rc) {
149 printk(KERN_ERR "windfarm: failed to attach %s %s to i2c,"
150 " err %d\n", ds1775 ? "ds1775" : "lm75",
151 lm->i2c.name, rc);
152 goto fail;
153 }
154 148
155 if (wf_register_sensor(&lm->sens)) { 149 client = i2c_new_device(adapter, &info);
156 i2c_detach_client(&lm->i2c); 150 if (client == NULL) {
151 printk(KERN_ERR "windfarm: failed to attach %s %s to i2c\n",
152 ds1775 ? "ds1775" : "lm75", name);
157 goto fail; 153 goto fail;
158 } 154 }
159 155
160 return lm; 156 /*
157 * Let i2c-core delete that device on driver removal.
158 * This is safe because i2c-core holds the core_lock mutex for us.
159 */
160 list_add_tail(&client->detected, &client->driver->clients);
161 return client;
161 fail: 162 fail:
162 kfree(lm);
163 return NULL; 163 return NULL;
164} 164}
165 165
@@ -202,21 +202,38 @@ static int wf_lm75_attach(struct i2c_adapter *adapter)
202 return 0; 202 return 0;
203} 203}
204 204
205static int wf_lm75_detach(struct i2c_client *client) 205static int wf_lm75_remove(struct i2c_client *client)
206{ 206{
207 struct wf_lm75_sensor *lm = i2c_to_lm75(client); 207 struct wf_lm75_sensor *lm = i2c_get_clientdata(client);
208 208
209 DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name); 209 DBG("wf_lm75: i2c detatch called for %s\n", lm->sens.name);
210 210
211 /* Mark client detached */ 211 /* Mark client detached */
212 lm->i2c.adapter = NULL; 212 lm->i2c = NULL;
213 213
214 /* release sensor */ 214 /* release sensor */
215 wf_unregister_sensor(&lm->sens); 215 wf_unregister_sensor(&lm->sens);
216 216
217 i2c_set_clientdata(client, NULL);
217 return 0; 218 return 0;
218} 219}
219 220
221static const struct i2c_device_id wf_lm75_id[] = {
222 { "wf_lm75", 0 },
223 { "wf_ds1775", 1 },
224 { }
225};
226
227static struct i2c_driver wf_lm75_driver = {
228 .driver = {
229 .name = "wf_lm75",
230 },
231 .attach_adapter = wf_lm75_attach,
232 .probe = wf_lm75_probe,
233 .remove = wf_lm75_remove,
234 .id_table = wf_lm75_id,
235};
236
220static int __init wf_lm75_sensor_init(void) 237static int __init wf_lm75_sensor_init(void)
221{ 238{
222 /* Don't register on old machines that use therm_pm72 for now */ 239 /* Don't register on old machines that use therm_pm72 for now */
diff --git a/drivers/macintosh/windfarm_max6690_sensor.c b/drivers/macintosh/windfarm_max6690_sensor.c
index e207a90d6b27..e2a55ecda2b2 100644
--- a/drivers/macintosh/windfarm_max6690_sensor.c
+++ b/drivers/macintosh/windfarm_max6690_sensor.c
@@ -26,34 +26,22 @@
26#define MAX6690_EXTERNAL_TEMP 1 26#define MAX6690_EXTERNAL_TEMP 1
27 27
28struct wf_6690_sensor { 28struct wf_6690_sensor {
29 struct i2c_client i2c; 29 struct i2c_client *i2c;
30 struct wf_sensor sens; 30 struct wf_sensor sens;
31}; 31};
32 32
33#define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens) 33#define wf_to_6690(x) container_of((x), struct wf_6690_sensor, sens)
34#define i2c_to_6690(x) container_of((x), struct wf_6690_sensor, i2c)
35
36static int wf_max6690_attach(struct i2c_adapter *adapter);
37static int wf_max6690_detach(struct i2c_client *client);
38
39static struct i2c_driver wf_max6690_driver = {
40 .driver = {
41 .name = "wf_max6690",
42 },
43 .attach_adapter = wf_max6690_attach,
44 .detach_client = wf_max6690_detach,
45};
46 34
47static int wf_max6690_get(struct wf_sensor *sr, s32 *value) 35static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
48{ 36{
49 struct wf_6690_sensor *max = wf_to_6690(sr); 37 struct wf_6690_sensor *max = wf_to_6690(sr);
50 s32 data; 38 s32 data;
51 39
52 if (max->i2c.adapter == NULL) 40 if (max->i2c == NULL)
53 return -ENODEV; 41 return -ENODEV;
54 42
55 /* chip gets initialized by firmware */ 43 /* chip gets initialized by firmware */
56 data = i2c_smbus_read_byte_data(&max->i2c, MAX6690_EXTERNAL_TEMP); 44 data = i2c_smbus_read_byte_data(max->i2c, MAX6690_EXTERNAL_TEMP);
57 if (data < 0) 45 if (data < 0)
58 return data; 46 return data;
59 *value = data << 16; 47 *value = data << 16;
@@ -64,10 +52,6 @@ static void wf_max6690_release(struct wf_sensor *sr)
64{ 52{
65 struct wf_6690_sensor *max = wf_to_6690(sr); 53 struct wf_6690_sensor *max = wf_to_6690(sr);
66 54
67 if (max->i2c.adapter) {
68 i2c_detach_client(&max->i2c);
69 max->i2c.adapter = NULL;
70 }
71 kfree(max); 55 kfree(max);
72} 56}
73 57
@@ -77,19 +61,40 @@ static struct wf_sensor_ops wf_max6690_ops = {
77 .owner = THIS_MODULE, 61 .owner = THIS_MODULE,
78}; 62};
79 63
80static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr, 64static int wf_max6690_probe(struct i2c_client *client,
81 const char *loc) 65 const struct i2c_device_id *id)
82{ 66{
83 struct wf_6690_sensor *max; 67 struct wf_6690_sensor *max;
84 char *name; 68 int rc;
85 69
86 max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL); 70 max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
87 if (max == NULL) { 71 if (max == NULL) {
88 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor %s: " 72 printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: "
89 "no memory\n", loc); 73 "no memory\n");
90 return; 74 return -ENOMEM;
75 }
76
77 max->i2c = client;
78 max->sens.name = client->dev.platform_data;
79 max->sens.ops = &wf_max6690_ops;
80 i2c_set_clientdata(client, max);
81
82 rc = wf_register_sensor(&max->sens);
83 if (rc) {
84 i2c_set_clientdata(client, NULL);
85 kfree(max);
91 } 86 }
92 87
88 return rc;
89}
90
91static struct i2c_client *wf_max6690_create(struct i2c_adapter *adapter,
92 u8 addr, const char *loc)
93{
94 struct i2c_board_info info;
95 struct i2c_client *client;
96 char *name;
97
93 if (!strcmp(loc, "BACKSIDE")) 98 if (!strcmp(loc, "BACKSIDE"))
94 name = "backside-temp"; 99 name = "backside-temp";
95 else if (!strcmp(loc, "NB Ambient")) 100 else if (!strcmp(loc, "NB Ambient"))
@@ -99,27 +104,26 @@ static void wf_max6690_create(struct i2c_adapter *adapter, u8 addr,
99 else 104 else
100 goto fail; 105 goto fail;
101 106
102 max->sens.ops = &wf_max6690_ops; 107 memset(&info, 0, sizeof(struct i2c_board_info));
103 max->sens.name = name; 108 info.addr = addr >> 1;
104 max->i2c.addr = addr >> 1; 109 info.platform_data = name;
105 max->i2c.adapter = adapter; 110 strlcpy(info.type, "wf_max6690", I2C_NAME_SIZE);
106 max->i2c.driver = &wf_max6690_driver;
107 strncpy(max->i2c.name, name, I2C_NAME_SIZE-1);
108 111
109 if (i2c_attach_client(&max->i2c)) { 112 client = i2c_new_device(adapter, &info);
113 if (client == NULL) {
110 printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n"); 114 printk(KERN_ERR "windfarm: failed to attach MAX6690 sensor\n");
111 goto fail; 115 goto fail;
112 } 116 }
113 117
114 if (wf_register_sensor(&max->sens)) { 118 /*
115 i2c_detach_client(&max->i2c); 119 * Let i2c-core delete that device on driver removal.
116 goto fail; 120 * This is safe because i2c-core holds the core_lock mutex for us.
117 } 121 */
118 122 list_add_tail(&client->detected, &client->driver->clients);
119 return; 123 return client;
120 124
121 fail: 125 fail:
122 kfree(max); 126 return NULL;
123} 127}
124 128
125static int wf_max6690_attach(struct i2c_adapter *adapter) 129static int wf_max6690_attach(struct i2c_adapter *adapter)
@@ -154,16 +158,31 @@ static int wf_max6690_attach(struct i2c_adapter *adapter)
154 return 0; 158 return 0;
155} 159}
156 160
157static int wf_max6690_detach(struct i2c_client *client) 161static int wf_max6690_remove(struct i2c_client *client)
158{ 162{
159 struct wf_6690_sensor *max = i2c_to_6690(client); 163 struct wf_6690_sensor *max = i2c_get_clientdata(client);
160 164
161 max->i2c.adapter = NULL; 165 max->i2c = NULL;
162 wf_unregister_sensor(&max->sens); 166 wf_unregister_sensor(&max->sens);
163 167
164 return 0; 168 return 0;
165} 169}
166 170
171static const struct i2c_device_id wf_max6690_id[] = {
172 { "wf_max6690", 0 },
173 { }
174};
175
176static struct i2c_driver wf_max6690_driver = {
177 .driver = {
178 .name = "wf_max6690",
179 },
180 .attach_adapter = wf_max6690_attach,
181 .probe = wf_max6690_probe,
182 .remove = wf_max6690_remove,
183 .id_table = wf_max6690_id,
184};
185
167static int __init wf_max6690_sensor_init(void) 186static int __init wf_max6690_sensor_init(void)
168{ 187{
169 /* Don't register on old machines that use therm_pm72 for now */ 188 /* Don't register on old machines that use therm_pm72 for now */
diff --git a/drivers/macintosh/windfarm_smu_sat.c b/drivers/macintosh/windfarm_smu_sat.c
index 7847e981ac33..5da729e58f99 100644
--- a/drivers/macintosh/windfarm_smu_sat.c
+++ b/drivers/macintosh/windfarm_smu_sat.c
@@ -39,7 +39,7 @@ struct wf_sat {
39 struct mutex mutex; 39 struct mutex mutex;
40 unsigned long last_read; /* jiffies when cache last updated */ 40 unsigned long last_read; /* jiffies when cache last updated */
41 u8 cache[16]; 41 u8 cache[16];
42 struct i2c_client i2c; 42 struct i2c_client *i2c;
43 struct device_node *node; 43 struct device_node *node;
44}; 44};
45 45
@@ -54,18 +54,6 @@ struct wf_sat_sensor {
54}; 54};
55 55
56#define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens) 56#define wf_to_sat(c) container_of(c, struct wf_sat_sensor, sens)
57#define i2c_to_sat(c) container_of(c, struct wf_sat, i2c)
58
59static int wf_sat_attach(struct i2c_adapter *adapter);
60static int wf_sat_detach(struct i2c_client *client);
61
62static struct i2c_driver wf_sat_driver = {
63 .driver = {
64 .name = "wf_smu_sat",
65 },
66 .attach_adapter = wf_sat_attach,
67 .detach_client = wf_sat_detach,
68};
69 57
70struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id, 58struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
71 unsigned int *size) 59 unsigned int *size)
@@ -81,13 +69,13 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
81 if (sat_id > 1 || (sat = sats[sat_id]) == NULL) 69 if (sat_id > 1 || (sat = sats[sat_id]) == NULL)
82 return NULL; 70 return NULL;
83 71
84 err = i2c_smbus_write_word_data(&sat->i2c, 8, id << 8); 72 err = i2c_smbus_write_word_data(sat->i2c, 8, id << 8);
85 if (err) { 73 if (err) {
86 printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err); 74 printk(KERN_ERR "smu_sat_get_sdb_part wr error %d\n", err);
87 return NULL; 75 return NULL;
88 } 76 }
89 77
90 err = i2c_smbus_read_word_data(&sat->i2c, 9); 78 err = i2c_smbus_read_word_data(sat->i2c, 9);
91 if (err < 0) { 79 if (err < 0) {
92 printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n"); 80 printk(KERN_ERR "smu_sat_get_sdb_part rd len error\n");
93 return NULL; 81 return NULL;
@@ -105,7 +93,7 @@ struct smu_sdbp_header *smu_sat_get_sdb_partition(unsigned int sat_id, int id,
105 return NULL; 93 return NULL;
106 94
107 for (i = 0; i < len; i += 4) { 95 for (i = 0; i < len; i += 4) {
108 err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0xa, 4, data); 96 err = i2c_smbus_read_i2c_block_data(sat->i2c, 0xa, 4, data);
109 if (err < 0) { 97 if (err < 0) {
110 printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n", 98 printk(KERN_ERR "smu_sat_get_sdb_part rd err %d\n",
111 err); 99 err);
@@ -138,7 +126,7 @@ static int wf_sat_read_cache(struct wf_sat *sat)
138{ 126{
139 int err; 127 int err;
140 128
141 err = i2c_smbus_read_i2c_block_data(&sat->i2c, 0x3f, 16, sat->cache); 129 err = i2c_smbus_read_i2c_block_data(sat->i2c, 0x3f, 16, sat->cache);
142 if (err < 0) 130 if (err < 0)
143 return err; 131 return err;
144 sat->last_read = jiffies; 132 sat->last_read = jiffies;
@@ -161,7 +149,7 @@ static int wf_sat_get(struct wf_sensor *sr, s32 *value)
161 int i, err; 149 int i, err;
162 s32 val; 150 s32 val;
163 151
164 if (sat->i2c.adapter == NULL) 152 if (sat->i2c == NULL)
165 return -ENODEV; 153 return -ENODEV;
166 154
167 mutex_lock(&sat->mutex); 155 mutex_lock(&sat->mutex);
@@ -193,10 +181,6 @@ static void wf_sat_release(struct wf_sensor *sr)
193 struct wf_sat *sat = sens->sat; 181 struct wf_sat *sat = sens->sat;
194 182
195 if (atomic_dec_and_test(&sat->refcnt)) { 183 if (atomic_dec_and_test(&sat->refcnt)) {
196 if (sat->i2c.adapter) {
197 i2c_detach_client(&sat->i2c);
198 sat->i2c.adapter = NULL;
199 }
200 if (sat->nr >= 0) 184 if (sat->nr >= 0)
201 sats[sat->nr] = NULL; 185 sats[sat->nr] = NULL;
202 kfree(sat); 186 kfree(sat);
@@ -212,38 +196,58 @@ static struct wf_sensor_ops wf_sat_ops = {
212 196
213static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev) 197static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
214{ 198{
199 struct i2c_board_info info;
200 struct i2c_client *client;
201 const u32 *reg;
202 u8 addr;
203
204 reg = of_get_property(dev, "reg", NULL);
205 if (reg == NULL)
206 return;
207 addr = *reg;
208 DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
209
210 memset(&info, 0, sizeof(struct i2c_board_info));
211 info.addr = (addr >> 1) & 0x7f;
212 info.platform_data = dev;
213 strlcpy(info.type, "wf_sat", I2C_NAME_SIZE);
214
215 client = i2c_new_device(adapter, &info);
216 if (client == NULL) {
217 printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
218 return;
219 }
220
221 /*
222 * Let i2c-core delete that device on driver removal.
223 * This is safe because i2c-core holds the core_lock mutex for us.
224 */
225 list_add_tail(&client->detected, &client->driver->clients);
226}
227
228static int wf_sat_probe(struct i2c_client *client,
229 const struct i2c_device_id *id)
230{
231 struct device_node *dev = client->dev.platform_data;
215 struct wf_sat *sat; 232 struct wf_sat *sat;
216 struct wf_sat_sensor *sens; 233 struct wf_sat_sensor *sens;
217 const u32 *reg; 234 const u32 *reg;
218 const char *loc, *type; 235 const char *loc, *type;
219 u8 addr, chip, core; 236 u8 chip, core;
220 struct device_node *child; 237 struct device_node *child;
221 int shift, cpu, index; 238 int shift, cpu, index;
222 char *name; 239 char *name;
223 int vsens[2], isens[2]; 240 int vsens[2], isens[2];
224 241
225 reg = of_get_property(dev, "reg", NULL);
226 if (reg == NULL)
227 return;
228 addr = *reg;
229 DBG(KERN_DEBUG "wf_sat: creating sat at address %x\n", addr);
230
231 sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL); 242 sat = kzalloc(sizeof(struct wf_sat), GFP_KERNEL);
232 if (sat == NULL) 243 if (sat == NULL)
233 return; 244 return -ENOMEM;
234 sat->nr = -1; 245 sat->nr = -1;
235 sat->node = of_node_get(dev); 246 sat->node = of_node_get(dev);
236 atomic_set(&sat->refcnt, 0); 247 atomic_set(&sat->refcnt, 0);
237 mutex_init(&sat->mutex); 248 mutex_init(&sat->mutex);
238 sat->i2c.addr = (addr >> 1) & 0x7f; 249 sat->i2c = client;
239 sat->i2c.adapter = adapter; 250 i2c_set_clientdata(client, sat);
240 sat->i2c.driver = &wf_sat_driver;
241 strncpy(sat->i2c.name, "smu-sat", I2C_NAME_SIZE-1);
242
243 if (i2c_attach_client(&sat->i2c)) {
244 printk(KERN_ERR "windfarm: failed to attach smu-sat to i2c\n");
245 goto fail;
246 }
247 251
248 vsens[0] = vsens[1] = -1; 252 vsens[0] = vsens[1] = -1;
249 isens[0] = isens[1] = -1; 253 isens[0] = isens[1] = -1;
@@ -344,10 +348,7 @@ static void wf_sat_create(struct i2c_adapter *adapter, struct device_node *dev)
344 if (sat->nr >= 0) 348 if (sat->nr >= 0)
345 sats[sat->nr] = sat; 349 sats[sat->nr] = sat;
346 350
347 return; 351 return 0;
348
349 fail:
350 kfree(sat);
351} 352}
352 353
353static int wf_sat_attach(struct i2c_adapter *adapter) 354static int wf_sat_attach(struct i2c_adapter *adapter)
@@ -366,16 +367,32 @@ static int wf_sat_attach(struct i2c_adapter *adapter)
366 return 0; 367 return 0;
367} 368}
368 369
369static int wf_sat_detach(struct i2c_client *client) 370static int wf_sat_remove(struct i2c_client *client)
370{ 371{
371 struct wf_sat *sat = i2c_to_sat(client); 372 struct wf_sat *sat = i2c_get_clientdata(client);
372 373
373 /* XXX TODO */ 374 /* XXX TODO */
374 375
375 sat->i2c.adapter = NULL; 376 sat->i2c = NULL;
377 i2c_set_clientdata(client, NULL);
376 return 0; 378 return 0;
377} 379}
378 380
381static const struct i2c_device_id wf_sat_id[] = {
382 { "wf_sat", 0 },
383 { }
384};
385
386static struct i2c_driver wf_sat_driver = {
387 .driver = {
388 .name = "wf_smu_sat",
389 },
390 .attach_adapter = wf_sat_attach,
391 .probe = wf_sat_probe,
392 .remove = wf_sat_remove,
393 .id_table = wf_sat_id,
394};
395
379static int __init sat_sensors_init(void) 396static int __init sat_sensors_init(void)
380{ 397{
381 return i2c_add_driver(&wf_sat_driver); 398 return i2c_add_driver(&wf_sat_driver);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 3fd8b1e65483..48db308fae67 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -19,7 +19,6 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/idr.h> 20#include <linux/idr.h>
21#include <linux/hdreg.h> 21#include <linux/hdreg.h>
22#include <linux/blktrace_api.h>
23 22
24#include <trace/events/block.h> 23#include <trace/events/block.h>
25 24
diff --git a/drivers/misc/eeprom/Kconfig b/drivers/misc/eeprom/Kconfig
index 89fec052f3b4..9118613af321 100644
--- a/drivers/misc/eeprom/Kconfig
+++ b/drivers/misc/eeprom/Kconfig
@@ -48,6 +48,20 @@ config EEPROM_LEGACY
48 This driver can also be built as a module. If so, the module 48 This driver can also be built as a module. If so, the module
49 will be called eeprom. 49 will be called eeprom.
50 50
51config EEPROM_MAX6875
52 tristate "Maxim MAX6874/5 power supply supervisor"
53 depends on I2C && EXPERIMENTAL
54 help
55 If you say yes here you get read-only support for the user EEPROM of
56 the Maxim MAX6874/5 EEPROM-programmable, quad power-supply
57 sequencer/supervisor.
58
59 All other features of this chip should be accessed via i2c-dev.
60
61 This driver can also be built as a module. If so, the module
62 will be called max6875.
63
64
51config EEPROM_93CX6 65config EEPROM_93CX6
52 tristate "EEPROM 93CX6 support" 66 tristate "EEPROM 93CX6 support"
53 help 67 help
diff --git a/drivers/misc/eeprom/Makefile b/drivers/misc/eeprom/Makefile
index 539dd8f88128..df3d68ffa9d1 100644
--- a/drivers/misc/eeprom/Makefile
+++ b/drivers/misc/eeprom/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_EEPROM_AT24) += at24.o 1obj-$(CONFIG_EEPROM_AT24) += at24.o
2obj-$(CONFIG_EEPROM_AT25) += at25.o 2obj-$(CONFIG_EEPROM_AT25) += at25.o
3obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o 3obj-$(CONFIG_EEPROM_LEGACY) += eeprom.o
4obj-$(CONFIG_EEPROM_MAX6875) += max6875.o
4obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o 5obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
diff --git a/drivers/i2c/chips/max6875.c b/drivers/misc/eeprom/max6875.c
index 033d9d81ec8a..3c0c58eed347 100644
--- a/drivers/i2c/chips/max6875.c
+++ b/drivers/misc/eeprom/max6875.c
@@ -3,7 +3,7 @@
3 3
4 Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> 4 Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com>
5 5
6 Based on i2c/chips/eeprom.c 6 Based on eeprom.c
7 7
8 The MAX6875 has a bank of registers and two banks of EEPROM. 8 The MAX6875 has a bank of registers and two banks of EEPROM.
9 Address ranges are defined as follows: 9 Address ranges are defined as follows:
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 30900b30d532..2b38f39924a6 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -1648,7 +1648,7 @@ static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
1648 result = -ENOMEM; 1648 result = -ENOMEM;
1649 goto fail_alloc_card; 1649 goto fail_alloc_card;
1650 } 1650 }
1651 ps3_system_bus_set_driver_data(dev, card); 1651 ps3_system_bus_set_drvdata(dev, card);
1652 card->dev = dev; 1652 card->dev = dev;
1653 1653
1654 /* get internal vlan info */ 1654 /* get internal vlan info */
@@ -1749,7 +1749,7 @@ fail_alloc_irq:
1749 bus_id(card), 1749 bus_id(card),
1750 0, 0); 1750 0, 0);
1751fail_status_indicator: 1751fail_status_indicator:
1752 ps3_system_bus_set_driver_data(dev, NULL); 1752 ps3_system_bus_set_drvdata(dev, NULL);
1753 kfree(netdev_card(netdev)->unalign); 1753 kfree(netdev_card(netdev)->unalign);
1754 free_netdev(netdev); 1754 free_netdev(netdev);
1755fail_alloc_card: 1755fail_alloc_card:
@@ -1766,7 +1766,7 @@ fail_open:
1766 1766
1767static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev) 1767static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev)
1768{ 1768{
1769 struct gelic_card *card = ps3_system_bus_get_driver_data(dev); 1769 struct gelic_card *card = ps3_system_bus_get_drvdata(dev);
1770 struct net_device *netdev0; 1770 struct net_device *netdev0;
1771 pr_debug("%s: called\n", __func__); 1771 pr_debug("%s: called\n", __func__);
1772 1772
@@ -1803,7 +1803,7 @@ static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev)
1803 kfree(netdev_card(netdev0)->unalign); 1803 kfree(netdev_card(netdev0)->unalign);
1804 free_netdev(netdev0); 1804 free_netdev(netdev0);
1805 1805
1806 ps3_system_bus_set_driver_data(dev, NULL); 1806 ps3_system_bus_set_drvdata(dev, NULL);
1807 1807
1808 ps3_dma_region_free(dev->d_region); 1808 ps3_dma_region_free(dev->d_region);
1809 1809
diff --git a/drivers/ps3/ps3-sys-manager.c b/drivers/ps3/ps3-sys-manager.c
index f17513dd9d4b..88cb74088611 100644
--- a/drivers/ps3/ps3-sys-manager.c
+++ b/drivers/ps3/ps3-sys-manager.c
@@ -706,7 +706,7 @@ static void ps3_sys_manager_work(struct ps3_system_bus_device *dev)
706 ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN); 706 ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN);
707} 707}
708 708
709static int ps3_sys_manager_probe(struct ps3_system_bus_device *dev) 709static int __devinit ps3_sys_manager_probe(struct ps3_system_bus_device *dev)
710{ 710{
711 int result; 711 int result;
712 struct ps3_sys_manager_ops ops; 712 struct ps3_sys_manager_ops ops;
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 235e87fcb49f..e82d8c9c6cda 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -80,12 +80,12 @@ static const struct avset_video_mode {
80 { 0, }, /* auto */ 80 { 0, }, /* auto */
81 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480}, 81 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480},
82 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480}, 82 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480},
83 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720}, 83 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_W, 1280, 720},
84 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080}, 84 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080},
85 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080}, 85 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080},
86 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576}, 86 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576},
87 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576}, 87 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576},
88 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720}, 88 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_W, 1280, 720},
89 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080}, 89 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080},
90 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080}, 90 {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080},
91 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768}, 91 { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768},
@@ -937,7 +937,7 @@ int ps3av_audio_mute(int mute)
937 937
938EXPORT_SYMBOL_GPL(ps3av_audio_mute); 938EXPORT_SYMBOL_GPL(ps3av_audio_mute);
939 939
940static int ps3av_probe(struct ps3_system_bus_device *dev) 940static int __devinit ps3av_probe(struct ps3_system_bus_device *dev)
941{ 941{
942 int res; 942 int res;
943 int id; 943 int id;
@@ -1048,7 +1048,7 @@ static struct ps3_vuart_port_driver ps3av_driver = {
1048 .shutdown = ps3av_shutdown, 1048 .shutdown = ps3av_shutdown,
1049}; 1049};
1050 1050
1051static int ps3av_module_init(void) 1051static int __init ps3av_module_init(void)
1052{ 1052{
1053 int error; 1053 int error;
1054 1054
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index 716596e8e5b0..f555fedd5073 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -21,9 +21,10 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24
24#include <asm/ps3av.h> 25#include <asm/ps3av.h>
25#include <asm/ps3fb.h>
26#include <asm/ps3.h> 26#include <asm/ps3.h>
27#include <asm/ps3gpu.h>
27 28
28#include "vuart.h" 29#include "vuart.h"
29 30
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 442bb98a2821..e5b84db0aa03 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -5,8 +5,7 @@
5 * Carsten Otte <Cotte@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Bugreports.to..: <Linux390@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com>
8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 8 * Copyright IBM Corp. 1999, 2009
9 *
10 */ 9 */
11 10
12#define KMSG_COMPONENT "dasd" 11#define KMSG_COMPONENT "dasd"
@@ -61,6 +60,7 @@ static int dasd_flush_block_queue(struct dasd_block *);
61static void dasd_device_tasklet(struct dasd_device *); 60static void dasd_device_tasklet(struct dasd_device *);
62static void dasd_block_tasklet(struct dasd_block *); 61static void dasd_block_tasklet(struct dasd_block *);
63static void do_kick_device(struct work_struct *); 62static void do_kick_device(struct work_struct *);
63static void do_restore_device(struct work_struct *);
64static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *); 64static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *);
65static void dasd_device_timeout(unsigned long); 65static void dasd_device_timeout(unsigned long);
66static void dasd_block_timeout(unsigned long); 66static void dasd_block_timeout(unsigned long);
@@ -109,6 +109,7 @@ struct dasd_device *dasd_alloc_device(void)
109 device->timer.function = dasd_device_timeout; 109 device->timer.function = dasd_device_timeout;
110 device->timer.data = (unsigned long) device; 110 device->timer.data = (unsigned long) device;
111 INIT_WORK(&device->kick_work, do_kick_device); 111 INIT_WORK(&device->kick_work, do_kick_device);
112 INIT_WORK(&device->restore_device, do_restore_device);
112 device->state = DASD_STATE_NEW; 113 device->state = DASD_STATE_NEW;
113 device->target = DASD_STATE_NEW; 114 device->target = DASD_STATE_NEW;
114 115
@@ -512,6 +513,25 @@ void dasd_kick_device(struct dasd_device *device)
512} 513}
513 514
514/* 515/*
516 * dasd_restore_device will schedule a call do do_restore_device to the kernel
517 * event daemon.
518 */
519static void do_restore_device(struct work_struct *work)
520{
521 struct dasd_device *device = container_of(work, struct dasd_device,
522 restore_device);
523 device->cdev->drv->restore(device->cdev);
524 dasd_put_device(device);
525}
526
527void dasd_restore_device(struct dasd_device *device)
528{
529 dasd_get_device(device);
530 /* queue call to dasd_restore_device to the kernel event daemon. */
531 schedule_work(&device->restore_device);
532}
533
534/*
515 * Set the target state for a device and starts the state change. 535 * Set the target state for a device and starts the state change.
516 */ 536 */
517void dasd_set_target_state(struct dasd_device *device, int target) 537void dasd_set_target_state(struct dasd_device *device, int target)
@@ -908,6 +928,12 @@ int dasd_start_IO(struct dasd_ccw_req *cqr)
908 DBF_DEV_EVENT(DBF_DEBUG, device, "%s", 928 DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
909 "start_IO: -EIO device gone, retry"); 929 "start_IO: -EIO device gone, retry");
910 break; 930 break;
931 case -EINVAL:
932 /* most likely caused in power management context */
933 DBF_DEV_EVENT(DBF_DEBUG, device, "%s",
934 "start_IO: -EINVAL device currently "
935 "not accessible");
936 break;
911 default: 937 default:
912 /* internal error 11 - unknown rc */ 938 /* internal error 11 - unknown rc */
913 snprintf(errorstring, ERRORLENGTH, "11 %d", rc); 939 snprintf(errorstring, ERRORLENGTH, "11 %d", rc);
@@ -2400,6 +2426,12 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
2400 case CIO_OPER: 2426 case CIO_OPER:
2401 /* FIXME: add a sanity check. */ 2427 /* FIXME: add a sanity check. */
2402 device->stopped &= ~DASD_STOPPED_DC_WAIT; 2428 device->stopped &= ~DASD_STOPPED_DC_WAIT;
2429 if (device->stopped & DASD_UNRESUMED_PM) {
2430 device->stopped &= ~DASD_UNRESUMED_PM;
2431 dasd_restore_device(device);
2432 ret = 1;
2433 break;
2434 }
2403 dasd_schedule_device_bh(device); 2435 dasd_schedule_device_bh(device);
2404 if (device->block) 2436 if (device->block)
2405 dasd_schedule_block_bh(device->block); 2437 dasd_schedule_block_bh(device->block);
@@ -2410,6 +2442,79 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
2410 return ret; 2442 return ret;
2411} 2443}
2412 2444
2445int dasd_generic_pm_freeze(struct ccw_device *cdev)
2446{
2447 struct dasd_ccw_req *cqr, *n;
2448 int rc;
2449 struct list_head freeze_queue;
2450 struct dasd_device *device = dasd_device_from_cdev(cdev);
2451
2452 if (IS_ERR(device))
2453 return PTR_ERR(device);
2454 /* disallow new I/O */
2455 device->stopped |= DASD_STOPPED_PM;
2456 /* clear active requests */
2457 INIT_LIST_HEAD(&freeze_queue);
2458 spin_lock_irq(get_ccwdev_lock(cdev));
2459 rc = 0;
2460 list_for_each_entry_safe(cqr, n, &device->ccw_queue, devlist) {
2461 /* Check status and move request to flush_queue */
2462 if (cqr->status == DASD_CQR_IN_IO) {
2463 rc = device->discipline->term_IO(cqr);
2464 if (rc) {
2465 /* unable to terminate requeust */
2466 dev_err(&device->cdev->dev,
2467 "Unable to terminate request %p "
2468 "on suspend\n", cqr);
2469 spin_unlock_irq(get_ccwdev_lock(cdev));
2470 dasd_put_device(device);
2471 return rc;
2472 }
2473 }
2474 list_move_tail(&cqr->devlist, &freeze_queue);
2475 }
2476
2477 spin_unlock_irq(get_ccwdev_lock(cdev));
2478
2479 list_for_each_entry_safe(cqr, n, &freeze_queue, devlist) {
2480 wait_event(dasd_flush_wq,
2481 (cqr->status != DASD_CQR_CLEAR_PENDING));
2482 if (cqr->status == DASD_CQR_CLEARED)
2483 cqr->status = DASD_CQR_QUEUED;
2484 }
2485 /* move freeze_queue to start of the ccw_queue */
2486 spin_lock_irq(get_ccwdev_lock(cdev));
2487 list_splice_tail(&freeze_queue, &device->ccw_queue);
2488 spin_unlock_irq(get_ccwdev_lock(cdev));
2489
2490 if (device->discipline->freeze)
2491 rc = device->discipline->freeze(device);
2492
2493 dasd_put_device(device);
2494 return rc;
2495}
2496EXPORT_SYMBOL_GPL(dasd_generic_pm_freeze);
2497
2498int dasd_generic_restore_device(struct ccw_device *cdev)
2499{
2500 struct dasd_device *device = dasd_device_from_cdev(cdev);
2501 int rc = 0;
2502
2503 if (IS_ERR(device))
2504 return PTR_ERR(device);
2505
2506 dasd_schedule_device_bh(device);
2507 if (device->block)
2508 dasd_schedule_block_bh(device->block);
2509
2510 if (device->discipline->restore)
2511 rc = device->discipline->restore(device);
2512
2513 dasd_put_device(device);
2514 return rc;
2515}
2516EXPORT_SYMBOL_GPL(dasd_generic_restore_device);
2517
2413static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device, 2518static struct dasd_ccw_req *dasd_generic_build_rdc(struct dasd_device *device,
2414 void *rdc_buffer, 2519 void *rdc_buffer,
2415 int rdc_buffer_size, 2520 int rdc_buffer_size,
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index e77666c8e6c0..4cac5b54f26a 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -1098,6 +1098,7 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid)
1098 spin_unlock(&dasd_devmap_lock); 1098 spin_unlock(&dasd_devmap_lock);
1099 return 0; 1099 return 0;
1100} 1100}
1101EXPORT_SYMBOL_GPL(dasd_get_uid);
1101 1102
1102/* 1103/*
1103 * Register the given device unique identifier into devmap struct. 1104 * Register the given device unique identifier into devmap struct.
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index cf0cfdba1244..1c28ec3e4ccb 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -5,10 +5,9 @@
5 * Carsten Otte <Cotte@de.ibm.com> 5 * Carsten Otte <Cotte@de.ibm.com>
6 * Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Bugreports.to..: <Linux390@de.ibm.com> 7 * Bugreports.to..: <Linux390@de.ibm.com>
8 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 8 * Copyright IBM Corp. 1999, 2009
9 * EMC Symmetrix ioctl Copyright EMC Corporation, 2008 9 * EMC Symmetrix ioctl Copyright EMC Corporation, 2008
10 * Author.........: Nigel Hislop <hislop_nigel@emc.com> 10 * Author.........: Nigel Hislop <hislop_nigel@emc.com>
11 *
12 */ 11 */
13 12
14#define KMSG_COMPONENT "dasd" 13#define KMSG_COMPONENT "dasd"
@@ -104,17 +103,6 @@ dasd_eckd_set_online(struct ccw_device *cdev)
104 return dasd_generic_set_online(cdev, &dasd_eckd_discipline); 103 return dasd_generic_set_online(cdev, &dasd_eckd_discipline);
105} 104}
106 105
107static struct ccw_driver dasd_eckd_driver = {
108 .name = "dasd-eckd",
109 .owner = THIS_MODULE,
110 .ids = dasd_eckd_ids,
111 .probe = dasd_eckd_probe,
112 .remove = dasd_generic_remove,
113 .set_offline = dasd_generic_set_offline,
114 .set_online = dasd_eckd_set_online,
115 .notify = dasd_generic_notify,
116};
117
118static const int sizes_trk0[] = { 28, 148, 84 }; 106static const int sizes_trk0[] = { 28, 148, 84 };
119#define LABEL_SIZE 140 107#define LABEL_SIZE 140
120 108
@@ -3236,6 +3224,98 @@ static void dasd_eckd_dump_sense(struct dasd_device *device,
3236 dasd_eckd_dump_sense_ccw(device, req, irb); 3224 dasd_eckd_dump_sense_ccw(device, req, irb);
3237} 3225}
3238 3226
3227int dasd_eckd_pm_freeze(struct dasd_device *device)
3228{
3229 /*
3230 * the device should be disconnected from our LCU structure
3231 * on restore we will reconnect it and reread LCU specific
3232 * information like PAV support that might have changed
3233 */
3234 dasd_alias_remove_device(device);
3235 dasd_alias_disconnect_device_from_lcu(device);
3236
3237 return 0;
3238}
3239
3240int dasd_eckd_restore_device(struct dasd_device *device)
3241{
3242 struct dasd_eckd_private *private;
3243 int is_known, rc;
3244 struct dasd_uid temp_uid;
3245
3246 /* allow new IO again */
3247 device->stopped &= ~DASD_STOPPED_PM;
3248
3249 private = (struct dasd_eckd_private *) device->private;
3250
3251 /* Read Configuration Data */
3252 rc = dasd_eckd_read_conf(device);
3253 if (rc)
3254 goto out_err;
3255
3256 /* Generate device unique id and register in devmap */
3257 rc = dasd_eckd_generate_uid(device, &private->uid);
3258 dasd_get_uid(device->cdev, &temp_uid);
3259 if (memcmp(&private->uid, &temp_uid, sizeof(struct dasd_uid)) != 0)
3260 dev_err(&device->cdev->dev, "The UID of the DASD has changed\n");
3261 if (rc)
3262 goto out_err;
3263 dasd_set_uid(device->cdev, &private->uid);
3264
3265 /* register lcu with alias handling, enable PAV if this is a new lcu */
3266 is_known = dasd_alias_make_device_known_to_lcu(device);
3267 if (is_known < 0)
3268 return is_known;
3269 if (!is_known) {
3270 /* new lcu found */
3271 rc = dasd_eckd_validate_server(device); /* will switch pav on */
3272 if (rc)
3273 goto out_err;
3274 }
3275
3276 /* Read Feature Codes */
3277 rc = dasd_eckd_read_features(device);
3278 if (rc)
3279 goto out_err;
3280
3281 /* Read Device Characteristics */
3282 memset(&private->rdc_data, 0, sizeof(private->rdc_data));
3283 rc = dasd_generic_read_dev_chars(device, "ECKD",
3284 &private->rdc_data, 64);
3285 if (rc) {
3286 DBF_EVENT(DBF_WARNING,
3287 "Read device characteristics failed, rc=%d for "
3288 "device: %s", rc, dev_name(&device->cdev->dev));
3289 goto out_err;
3290 }
3291
3292 /* add device to alias management */
3293 dasd_alias_add_device(device);
3294
3295 return 0;
3296
3297out_err:
3298 /*
3299 * if the resume failed for the DASD we put it in
3300 * an UNRESUMED stop state
3301 */
3302 device->stopped |= DASD_UNRESUMED_PM;
3303 return 0;
3304}
3305
3306static struct ccw_driver dasd_eckd_driver = {
3307 .name = "dasd-eckd",
3308 .owner = THIS_MODULE,
3309 .ids = dasd_eckd_ids,
3310 .probe = dasd_eckd_probe,
3311 .remove = dasd_generic_remove,
3312 .set_offline = dasd_generic_set_offline,
3313 .set_online = dasd_eckd_set_online,
3314 .notify = dasd_generic_notify,
3315 .freeze = dasd_generic_pm_freeze,
3316 .thaw = dasd_generic_restore_device,
3317 .restore = dasd_generic_restore_device,
3318};
3239 3319
3240/* 3320/*
3241 * max_blocks is dependent on the amount of storage that is available 3321 * max_blocks is dependent on the amount of storage that is available
@@ -3274,6 +3354,8 @@ static struct dasd_discipline dasd_eckd_discipline = {
3274 .dump_sense_dbf = dasd_eckd_dump_sense_dbf, 3354 .dump_sense_dbf = dasd_eckd_dump_sense_dbf,
3275 .fill_info = dasd_eckd_fill_info, 3355 .fill_info = dasd_eckd_fill_info,
3276 .ioctl = dasd_eckd_ioctl, 3356 .ioctl = dasd_eckd_ioctl,
3357 .freeze = dasd_eckd_pm_freeze,
3358 .restore = dasd_eckd_restore_device,
3277}; 3359};
3278 3360
3279static int __init 3361static int __init
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index 597c6ffdb9f2..e21ee735f926 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -2,8 +2,7 @@
2 * File...........: linux/drivers/s390/block/dasd_fba.c 2 * File...........: linux/drivers/s390/block/dasd_fba.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 * Bugreports.to..: <Linux390@de.ibm.com> 4 * Bugreports.to..: <Linux390@de.ibm.com>
5 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 5 * Copyright IBM Corp. 1999, 2009
6 *
7 */ 6 */
8 7
9#define KMSG_COMPONENT "dasd" 8#define KMSG_COMPONENT "dasd"
@@ -75,6 +74,9 @@ static struct ccw_driver dasd_fba_driver = {
75 .set_offline = dasd_generic_set_offline, 74 .set_offline = dasd_generic_set_offline,
76 .set_online = dasd_fba_set_online, 75 .set_online = dasd_fba_set_online,
77 .notify = dasd_generic_notify, 76 .notify = dasd_generic_notify,
77 .freeze = dasd_generic_pm_freeze,
78 .thaw = dasd_generic_restore_device,
79 .restore = dasd_generic_restore_device,
78}; 80};
79 81
80static void 82static void
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index f97ceb795078..fd63b2f2bda9 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -4,8 +4,7 @@
4 * Horst Hummel <Horst.Hummel@de.ibm.com> 4 * Horst Hummel <Horst.Hummel@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com> 5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Bugreports.to..: <Linux390@de.ibm.com> 6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 7 * Copyright IBM Corp. 1999, 2009
8 *
9 */ 8 */
10 9
11#ifndef DASD_INT_H 10#ifndef DASD_INT_H
@@ -295,6 +294,10 @@ struct dasd_discipline {
295 int (*fill_geometry) (struct dasd_block *, struct hd_geometry *); 294 int (*fill_geometry) (struct dasd_block *, struct hd_geometry *);
296 int (*fill_info) (struct dasd_device *, struct dasd_information2_t *); 295 int (*fill_info) (struct dasd_device *, struct dasd_information2_t *);
297 int (*ioctl) (struct dasd_block *, unsigned int, void __user *); 296 int (*ioctl) (struct dasd_block *, unsigned int, void __user *);
297
298 /* suspend/resume functions */
299 int (*freeze) (struct dasd_device *);
300 int (*restore) (struct dasd_device *);
298}; 301};
299 302
300extern struct dasd_discipline *dasd_diag_discipline_pointer; 303extern struct dasd_discipline *dasd_diag_discipline_pointer;
@@ -367,6 +370,7 @@ struct dasd_device {
367 atomic_t tasklet_scheduled; 370 atomic_t tasklet_scheduled;
368 struct tasklet_struct tasklet; 371 struct tasklet_struct tasklet;
369 struct work_struct kick_work; 372 struct work_struct kick_work;
373 struct work_struct restore_device;
370 struct timer_list timer; 374 struct timer_list timer;
371 375
372 debug_info_t *debug_area; 376 debug_info_t *debug_area;
@@ -410,6 +414,8 @@ struct dasd_block {
410#define DASD_STOPPED_PENDING 4 /* long busy */ 414#define DASD_STOPPED_PENDING 4 /* long busy */
411#define DASD_STOPPED_DC_WAIT 8 /* disconnected, wait */ 415#define DASD_STOPPED_DC_WAIT 8 /* disconnected, wait */
412#define DASD_STOPPED_SU 16 /* summary unit check handling */ 416#define DASD_STOPPED_SU 16 /* summary unit check handling */
417#define DASD_STOPPED_PM 32 /* pm state transition */
418#define DASD_UNRESUMED_PM 64 /* pm resume failed state */
413 419
414/* per device flags */ 420/* per device flags */
415#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */ 421#define DASD_FLAG_OFFLINE 3 /* device is in offline processing */
@@ -556,6 +562,7 @@ void dasd_free_block(struct dasd_block *);
556void dasd_enable_device(struct dasd_device *); 562void dasd_enable_device(struct dasd_device *);
557void dasd_set_target_state(struct dasd_device *, int); 563void dasd_set_target_state(struct dasd_device *, int);
558void dasd_kick_device(struct dasd_device *); 564void dasd_kick_device(struct dasd_device *);
565void dasd_restore_device(struct dasd_device *);
559 566
560void dasd_add_request_head(struct dasd_ccw_req *); 567void dasd_add_request_head(struct dasd_ccw_req *);
561void dasd_add_request_tail(struct dasd_ccw_req *); 568void dasd_add_request_tail(struct dasd_ccw_req *);
@@ -578,6 +585,8 @@ int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *);
578int dasd_generic_set_offline (struct ccw_device *cdev); 585int dasd_generic_set_offline (struct ccw_device *cdev);
579int dasd_generic_notify(struct ccw_device *, int); 586int dasd_generic_notify(struct ccw_device *, int);
580void dasd_generic_handle_state_change(struct dasd_device *); 587void dasd_generic_handle_state_change(struct dasd_device *);
588int dasd_generic_pm_freeze(struct ccw_device *);
589int dasd_generic_restore_device(struct ccw_device *);
581 590
582int dasd_generic_read_dev_chars(struct dasd_device *, char *, void *, int); 591int dasd_generic_read_dev_chars(struct dasd_device *, char *, void *, int);
583char *dasd_get_sense(struct irb *); 592char *dasd_get_sense(struct irb *);
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index b21caf177e37..016f9e9d2591 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -14,10 +14,11 @@
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/blkdev.h> 16#include <linux/blkdev.h>
17#include <asm/extmem.h>
18#include <asm/io.h>
19#include <linux/completion.h> 17#include <linux/completion.h>
20#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/platform_device.h>
20#include <asm/extmem.h>
21#include <asm/io.h>
21 22
22#define DCSSBLK_NAME "dcssblk" 23#define DCSSBLK_NAME "dcssblk"
23#define DCSSBLK_MINORS_PER_DISK 1 24#define DCSSBLK_MINORS_PER_DISK 1
@@ -940,11 +941,94 @@ dcssblk_check_params(void)
940} 941}
941 942
942/* 943/*
944 * Suspend / Resume
945 */
946static int dcssblk_freeze(struct device *dev)
947{
948 struct dcssblk_dev_info *dev_info;
949 int rc = 0;
950
951 list_for_each_entry(dev_info, &dcssblk_devices, lh) {
952 switch (dev_info->segment_type) {
953 case SEG_TYPE_SR:
954 case SEG_TYPE_ER:
955 case SEG_TYPE_SC:
956 if (!dev_info->is_shared)
957 rc = -EINVAL;
958 break;
959 default:
960 rc = -EINVAL;
961 break;
962 }
963 if (rc)
964 break;
965 }
966 if (rc)
967 pr_err("Suspend failed because device %s is writeable.\n",
968 dev_info->segment_name);
969 return rc;
970}
971
972static int dcssblk_restore(struct device *dev)
973{
974 struct dcssblk_dev_info *dev_info;
975 struct segment_info *entry;
976 unsigned long start, end;
977 int rc = 0;
978
979 list_for_each_entry(dev_info, &dcssblk_devices, lh) {
980 list_for_each_entry(entry, &dev_info->seg_list, lh) {
981 segment_unload(entry->segment_name);
982 rc = segment_load(entry->segment_name, SEGMENT_SHARED,
983 &start, &end);
984 if (rc < 0) {
985// TODO in_use check ?
986 segment_warning(rc, entry->segment_name);
987 goto out_panic;
988 }
989 if (start != entry->start || end != entry->end) {
990 pr_err("Mismatch of start / end address after "
991 "resuming device %s\n",
992 entry->segment_name);
993 goto out_panic;
994 }
995 }
996 }
997 return 0;
998out_panic:
999 panic("fatal dcssblk resume error\n");
1000}
1001
1002static int dcssblk_thaw(struct device *dev)
1003{
1004 return 0;
1005}
1006
1007static struct dev_pm_ops dcssblk_pm_ops = {
1008 .freeze = dcssblk_freeze,
1009 .thaw = dcssblk_thaw,
1010 .restore = dcssblk_restore,
1011};
1012
1013static struct platform_driver dcssblk_pdrv = {
1014 .driver = {
1015 .name = "dcssblk",
1016 .owner = THIS_MODULE,
1017 .pm = &dcssblk_pm_ops,
1018 },
1019};
1020
1021static struct platform_device *dcssblk_pdev;
1022
1023
1024/*
943 * The init/exit functions. 1025 * The init/exit functions.
944 */ 1026 */
945static void __exit 1027static void __exit
946dcssblk_exit(void) 1028dcssblk_exit(void)
947{ 1029{
1030 platform_device_unregister(dcssblk_pdev);
1031 platform_driver_unregister(&dcssblk_pdrv);
948 root_device_unregister(dcssblk_root_dev); 1032 root_device_unregister(dcssblk_root_dev);
949 unregister_blkdev(dcssblk_major, DCSSBLK_NAME); 1033 unregister_blkdev(dcssblk_major, DCSSBLK_NAME);
950} 1034}
@@ -954,30 +1038,44 @@ dcssblk_init(void)
954{ 1038{
955 int rc; 1039 int rc;
956 1040
957 dcssblk_root_dev = root_device_register("dcssblk"); 1041 rc = platform_driver_register(&dcssblk_pdrv);
958 if (IS_ERR(dcssblk_root_dev)) 1042 if (rc)
959 return PTR_ERR(dcssblk_root_dev);
960 rc = device_create_file(dcssblk_root_dev, &dev_attr_add);
961 if (rc) {
962 root_device_unregister(dcssblk_root_dev);
963 return rc; 1043 return rc;
1044
1045 dcssblk_pdev = platform_device_register_simple("dcssblk", -1, NULL,
1046 0);
1047 if (IS_ERR(dcssblk_pdev)) {
1048 rc = PTR_ERR(dcssblk_pdev);
1049 goto out_pdrv;
964 } 1050 }
965 rc = device_create_file(dcssblk_root_dev, &dev_attr_remove); 1051
966 if (rc) { 1052 dcssblk_root_dev = root_device_register("dcssblk");
967 root_device_unregister(dcssblk_root_dev); 1053 if (IS_ERR(dcssblk_root_dev)) {
968 return rc; 1054 rc = PTR_ERR(dcssblk_root_dev);
1055 goto out_pdev;
969 } 1056 }
1057 rc = device_create_file(dcssblk_root_dev, &dev_attr_add);
1058 if (rc)
1059 goto out_root;
1060 rc = device_create_file(dcssblk_root_dev, &dev_attr_remove);
1061 if (rc)
1062 goto out_root;
970 rc = register_blkdev(0, DCSSBLK_NAME); 1063 rc = register_blkdev(0, DCSSBLK_NAME);
971 if (rc < 0) { 1064 if (rc < 0)
972 root_device_unregister(dcssblk_root_dev); 1065 goto out_root;
973 return rc;
974 }
975 dcssblk_major = rc; 1066 dcssblk_major = rc;
976 init_rwsem(&dcssblk_devices_sem); 1067 init_rwsem(&dcssblk_devices_sem);
977 1068
978 dcssblk_check_params(); 1069 dcssblk_check_params();
979
980 return 0; 1070 return 0;
1071
1072out_root:
1073 root_device_unregister(dcssblk_root_dev);
1074out_pdev:
1075 platform_device_unregister(dcssblk_pdev);
1076out_pdrv:
1077 platform_driver_unregister(&dcssblk_pdrv);
1078 return rc;
981} 1079}
982 1080
983module_init(dcssblk_init); 1081module_init(dcssblk_init);
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
index 0ae0c83ef879..2e9e1ecd6d82 100644
--- a/drivers/s390/block/xpram.c
+++ b/drivers/s390/block/xpram.c
@@ -39,7 +39,10 @@
39#include <linux/hdreg.h> /* HDIO_GETGEO */ 39#include <linux/hdreg.h> /* HDIO_GETGEO */
40#include <linux/sysdev.h> 40#include <linux/sysdev.h>
41#include <linux/bio.h> 41#include <linux/bio.h>
42#include <linux/suspend.h>
43#include <linux/platform_device.h>
42#include <asm/uaccess.h> 44#include <asm/uaccess.h>
45#include <asm/checksum.h>
43 46
44#define XPRAM_NAME "xpram" 47#define XPRAM_NAME "xpram"
45#define XPRAM_DEVS 1 /* one partition */ 48#define XPRAM_DEVS 1 /* one partition */
@@ -48,6 +51,7 @@
48typedef struct { 51typedef struct {
49 unsigned int size; /* size of xpram segment in pages */ 52 unsigned int size; /* size of xpram segment in pages */
50 unsigned int offset; /* start page of xpram segment */ 53 unsigned int offset; /* start page of xpram segment */
54 unsigned int csum; /* partition checksum for suspend */
51} xpram_device_t; 55} xpram_device_t;
52 56
53static xpram_device_t xpram_devices[XPRAM_MAX_DEVS]; 57static xpram_device_t xpram_devices[XPRAM_MAX_DEVS];
@@ -138,7 +142,7 @@ static long xpram_page_out (unsigned long page_addr, unsigned int xpage_index)
138/* 142/*
139 * Check if xpram is available. 143 * Check if xpram is available.
140 */ 144 */
141static int __init xpram_present(void) 145static int xpram_present(void)
142{ 146{
143 unsigned long mem_page; 147 unsigned long mem_page;
144 int rc; 148 int rc;
@@ -154,7 +158,7 @@ static int __init xpram_present(void)
154/* 158/*
155 * Return index of the last available xpram page. 159 * Return index of the last available xpram page.
156 */ 160 */
157static unsigned long __init xpram_highest_page_index(void) 161static unsigned long xpram_highest_page_index(void)
158{ 162{
159 unsigned int page_index, add_bit; 163 unsigned int page_index, add_bit;
160 unsigned long mem_page; 164 unsigned long mem_page;
@@ -383,6 +387,106 @@ out:
383} 387}
384 388
385/* 389/*
390 * Save checksums for all partitions.
391 */
392static int xpram_save_checksums(void)
393{
394 unsigned long mem_page;
395 int rc, i;
396
397 rc = 0;
398 mem_page = (unsigned long) __get_free_page(GFP_KERNEL);
399 if (!mem_page)
400 return -ENOMEM;
401 for (i = 0; i < xpram_devs; i++) {
402 rc = xpram_page_in(mem_page, xpram_devices[i].offset);
403 if (rc)
404 goto fail;
405 xpram_devices[i].csum = csum_partial((const void *) mem_page,
406 PAGE_SIZE, 0);
407 }
408fail:
409 free_page(mem_page);
410 return rc ? -ENXIO : 0;
411}
412
413/*
414 * Verify checksums for all partitions.
415 */
416static int xpram_validate_checksums(void)
417{
418 unsigned long mem_page;
419 unsigned int csum;
420 int rc, i;
421
422 rc = 0;
423 mem_page = (unsigned long) __get_free_page(GFP_KERNEL);
424 if (!mem_page)
425 return -ENOMEM;
426 for (i = 0; i < xpram_devs; i++) {
427 rc = xpram_page_in(mem_page, xpram_devices[i].offset);
428 if (rc)
429 goto fail;
430 csum = csum_partial((const void *) mem_page, PAGE_SIZE, 0);
431 if (xpram_devices[i].csum != csum) {
432 rc = -EINVAL;
433 goto fail;
434 }
435 }
436fail:
437 free_page(mem_page);
438 return rc ? -ENXIO : 0;
439}
440
441/*
442 * Resume failed: Print error message and call panic.
443 */
444static void xpram_resume_error(const char *message)
445{
446 pr_err("Resume error: %s\n", message);
447 panic("xpram resume error\n");
448}
449
450/*
451 * Check if xpram setup changed between suspend and resume.
452 */
453static int xpram_restore(struct device *dev)
454{
455 if (!xpram_pages)
456 return 0;
457 if (xpram_present() != 0)
458 xpram_resume_error("xpram disappeared");
459 if (xpram_pages != xpram_highest_page_index() + 1)
460 xpram_resume_error("Size of xpram changed");
461 if (xpram_validate_checksums())
462 xpram_resume_error("Data of xpram changed");
463 return 0;
464}
465
466/*
467 * Save necessary state in suspend.
468 */
469static int xpram_freeze(struct device *dev)
470{
471 return xpram_save_checksums();
472}
473
474static struct dev_pm_ops xpram_pm_ops = {
475 .freeze = xpram_freeze,
476 .restore = xpram_restore,
477};
478
479static struct platform_driver xpram_pdrv = {
480 .driver = {
481 .name = XPRAM_NAME,
482 .owner = THIS_MODULE,
483 .pm = &xpram_pm_ops,
484 },
485};
486
487static struct platform_device *xpram_pdev;
488
489/*
386 * Finally, the init/exit functions. 490 * Finally, the init/exit functions.
387 */ 491 */
388static void __exit xpram_exit(void) 492static void __exit xpram_exit(void)
@@ -394,6 +498,8 @@ static void __exit xpram_exit(void)
394 put_disk(xpram_disks[i]); 498 put_disk(xpram_disks[i]);
395 } 499 }
396 unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME); 500 unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
501 platform_device_unregister(xpram_pdev);
502 platform_driver_unregister(&xpram_pdrv);
397} 503}
398 504
399static int __init xpram_init(void) 505static int __init xpram_init(void)
@@ -411,7 +517,24 @@ static int __init xpram_init(void)
411 rc = xpram_setup_sizes(xpram_pages); 517 rc = xpram_setup_sizes(xpram_pages);
412 if (rc) 518 if (rc)
413 return rc; 519 return rc;
414 return xpram_setup_blkdev(); 520 rc = platform_driver_register(&xpram_pdrv);
521 if (rc)
522 return rc;
523 xpram_pdev = platform_device_register_simple(XPRAM_NAME, -1, NULL, 0);
524 if (IS_ERR(xpram_pdev)) {
525 rc = PTR_ERR(xpram_pdev);
526 goto fail_platform_driver_unregister;
527 }
528 rc = xpram_setup_blkdev();
529 if (rc)
530 goto fail_platform_device_unregister;
531 return 0;
532
533fail_platform_device_unregister:
534 platform_device_unregister(xpram_pdev);
535fail_platform_driver_unregister:
536 platform_driver_unregister(&xpram_pdrv);
537 return rc;
415} 538}
416 539
417module_init(xpram_init); 540module_init(xpram_init);
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 9ab06e0dad40..b79f31add39c 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -1,14 +1,12 @@
1/* 1/*
2 * drivers/s390/char/con3215.c 2 * 3215 line mode terminal driver.
3 * 3215 line mode terminal driver.
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 1999, 2009
6 * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
8 * 6 *
9 * Updated: 7 * Updated:
10 * Aug-2000: Added tab support 8 * Aug-2000: Added tab support
11 * Dan Morrison, IBM Corporation (dmorriso@cse.buffalo.edu) 9 * Dan Morrison, IBM Corporation <dmorriso@cse.buffalo.edu>
12 */ 10 */
13 11
14#include <linux/module.h> 12#include <linux/module.h>
@@ -56,6 +54,7 @@
56#define RAW3215_CLOSING 32 /* set while in close process */ 54#define RAW3215_CLOSING 32 /* set while in close process */
57#define RAW3215_TIMER_RUNS 64 /* set if the output delay timer is on */ 55#define RAW3215_TIMER_RUNS 64 /* set if the output delay timer is on */
58#define RAW3215_FLUSHING 128 /* set to flush buffer (no delay) */ 56#define RAW3215_FLUSHING 128 /* set to flush buffer (no delay) */
57#define RAW3215_FROZEN 256 /* set if 3215 is frozen for suspend */
59 58
60#define TAB_STOP_SIZE 8 /* tab stop size */ 59#define TAB_STOP_SIZE 8 /* tab stop size */
61 60
@@ -111,8 +110,8 @@ static struct tty_driver *tty3215_driver;
111/* 110/*
112 * Get a request structure from the free list 111 * Get a request structure from the free list
113 */ 112 */
114static inline struct raw3215_req * 113static inline struct raw3215_req *raw3215_alloc_req(void)
115raw3215_alloc_req(void) { 114{
116 struct raw3215_req *req; 115 struct raw3215_req *req;
117 unsigned long flags; 116 unsigned long flags;
118 117
@@ -126,8 +125,8 @@ raw3215_alloc_req(void) {
126/* 125/*
127 * Put a request structure back to the free list 126 * Put a request structure back to the free list
128 */ 127 */
129static inline void 128static inline void raw3215_free_req(struct raw3215_req *req)
130raw3215_free_req(struct raw3215_req *req) { 129{
131 unsigned long flags; 130 unsigned long flags;
132 131
133 if (req->type == RAW3215_FREE) 132 if (req->type == RAW3215_FREE)
@@ -145,8 +144,7 @@ raw3215_free_req(struct raw3215_req *req) {
145 * because a 3215 terminal won't accept a new read before the old one is 144 * because a 3215 terminal won't accept a new read before the old one is
146 * completed. 145 * completed.
147 */ 146 */
148static void 147static void raw3215_mk_read_req(struct raw3215_info *raw)
149raw3215_mk_read_req(struct raw3215_info *raw)
150{ 148{
151 struct raw3215_req *req; 149 struct raw3215_req *req;
152 struct ccw1 *ccw; 150 struct ccw1 *ccw;
@@ -174,8 +172,7 @@ raw3215_mk_read_req(struct raw3215_info *raw)
174 * buffer to the 3215 device. If a queued write exists it is replaced by 172 * buffer to the 3215 device. If a queued write exists it is replaced by
175 * the new, probably lengthened request. 173 * the new, probably lengthened request.
176 */ 174 */
177static void 175static void raw3215_mk_write_req(struct raw3215_info *raw)
178raw3215_mk_write_req(struct raw3215_info *raw)
179{ 176{
180 struct raw3215_req *req; 177 struct raw3215_req *req;
181 struct ccw1 *ccw; 178 struct ccw1 *ccw;
@@ -251,8 +248,7 @@ raw3215_mk_write_req(struct raw3215_info *raw)
251/* 248/*
252 * Start a read or a write request 249 * Start a read or a write request
253 */ 250 */
254static void 251static void raw3215_start_io(struct raw3215_info *raw)
255raw3215_start_io(struct raw3215_info *raw)
256{ 252{
257 struct raw3215_req *req; 253 struct raw3215_req *req;
258 int res; 254 int res;
@@ -290,8 +286,7 @@ raw3215_start_io(struct raw3215_info *raw)
290/* 286/*
291 * Function to start a delayed output after RAW3215_TIMEOUT seconds 287 * Function to start a delayed output after RAW3215_TIMEOUT seconds
292 */ 288 */
293static void 289static void raw3215_timeout(unsigned long __data)
294raw3215_timeout(unsigned long __data)
295{ 290{
296 struct raw3215_info *raw = (struct raw3215_info *) __data; 291 struct raw3215_info *raw = (struct raw3215_info *) __data;
297 unsigned long flags; 292 unsigned long flags;
@@ -300,8 +295,10 @@ raw3215_timeout(unsigned long __data)
300 if (raw->flags & RAW3215_TIMER_RUNS) { 295 if (raw->flags & RAW3215_TIMER_RUNS) {
301 del_timer(&raw->timer); 296 del_timer(&raw->timer);
302 raw->flags &= ~RAW3215_TIMER_RUNS; 297 raw->flags &= ~RAW3215_TIMER_RUNS;
303 raw3215_mk_write_req(raw); 298 if (!(raw->flags & RAW3215_FROZEN)) {
304 raw3215_start_io(raw); 299 raw3215_mk_write_req(raw);
300 raw3215_start_io(raw);
301 }
305 } 302 }
306 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 303 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
307} 304}
@@ -312,10 +309,9 @@ raw3215_timeout(unsigned long __data)
312 * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not 309 * amount of data is bigger than RAW3215_MIN_WRITE. If a write is not
313 * done immediately a timer is started with a delay of RAW3215_TIMEOUT. 310 * done immediately a timer is started with a delay of RAW3215_TIMEOUT.
314 */ 311 */
315static inline void 312static inline void raw3215_try_io(struct raw3215_info *raw)
316raw3215_try_io(struct raw3215_info *raw)
317{ 313{
318 if (!(raw->flags & RAW3215_ACTIVE)) 314 if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FROZEN))
319 return; 315 return;
320 if (raw->queued_read != NULL) 316 if (raw->queued_read != NULL)
321 raw3215_start_io(raw); 317 raw3215_start_io(raw);
@@ -359,8 +355,8 @@ static void raw3215_next_io(struct raw3215_info *raw)
359/* 355/*
360 * Interrupt routine, called from common io layer 356 * Interrupt routine, called from common io layer
361 */ 357 */
362static void 358static void raw3215_irq(struct ccw_device *cdev, unsigned long intparm,
363raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb) 359 struct irb *irb)
364{ 360{
365 struct raw3215_info *raw; 361 struct raw3215_info *raw;
366 struct raw3215_req *req; 362 struct raw3215_req *req;
@@ -459,14 +455,40 @@ raw3215_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
459} 455}
460 456
461/* 457/*
458 * Drop the oldest line from the output buffer.
459 */
460static void raw3215_drop_line(struct raw3215_info *raw)
461{
462 int ix;
463 char ch;
464
465 BUG_ON(raw->written != 0);
466 ix = (raw->head - raw->count) & (RAW3215_BUFFER_SIZE - 1);
467 while (raw->count > 0) {
468 ch = raw->buffer[ix];
469 ix = (ix + 1) & (RAW3215_BUFFER_SIZE - 1);
470 raw->count--;
471 if (ch == 0x15)
472 break;
473 }
474 raw->head = ix;
475}
476
477/*
462 * Wait until length bytes are available int the output buffer. 478 * Wait until length bytes are available int the output buffer.
463 * Has to be called with the s390irq lock held. Can be called 479 * Has to be called with the s390irq lock held. Can be called
464 * disabled. 480 * disabled.
465 */ 481 */
466static void 482static void raw3215_make_room(struct raw3215_info *raw, unsigned int length)
467raw3215_make_room(struct raw3215_info *raw, unsigned int length)
468{ 483{
469 while (RAW3215_BUFFER_SIZE - raw->count < length) { 484 while (RAW3215_BUFFER_SIZE - raw->count < length) {
485 /* While console is frozen for suspend we have no other
486 * choice but to drop message from the buffer to make
487 * room for even more messages. */
488 if (raw->flags & RAW3215_FROZEN) {
489 raw3215_drop_line(raw);
490 continue;
491 }
470 /* there might be a request pending */ 492 /* there might be a request pending */
471 raw->flags |= RAW3215_FLUSHING; 493 raw->flags |= RAW3215_FLUSHING;
472 raw3215_mk_write_req(raw); 494 raw3215_mk_write_req(raw);
@@ -488,8 +510,8 @@ raw3215_make_room(struct raw3215_info *raw, unsigned int length)
488/* 510/*
489 * String write routine for 3215 devices 511 * String write routine for 3215 devices
490 */ 512 */
491static void 513static void raw3215_write(struct raw3215_info *raw, const char *str,
492raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length) 514 unsigned int length)
493{ 515{
494 unsigned long flags; 516 unsigned long flags;
495 int c, count; 517 int c, count;
@@ -529,8 +551,7 @@ raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length)
529/* 551/*
530 * Put character routine for 3215 devices 552 * Put character routine for 3215 devices
531 */ 553 */
532static void 554static void raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
533raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
534{ 555{
535 unsigned long flags; 556 unsigned long flags;
536 unsigned int length, i; 557 unsigned int length, i;
@@ -566,8 +587,7 @@ raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
566 * Flush routine, it simply sets the flush flag and tries to start 587 * Flush routine, it simply sets the flush flag and tries to start
567 * pending IO. 588 * pending IO.
568 */ 589 */
569static void 590static void raw3215_flush_buffer(struct raw3215_info *raw)
570raw3215_flush_buffer(struct raw3215_info *raw)
571{ 591{
572 unsigned long flags; 592 unsigned long flags;
573 593
@@ -583,8 +603,7 @@ raw3215_flush_buffer(struct raw3215_info *raw)
583/* 603/*
584 * Fire up a 3215 device. 604 * Fire up a 3215 device.
585 */ 605 */
586static int 606static int raw3215_startup(struct raw3215_info *raw)
587raw3215_startup(struct raw3215_info *raw)
588{ 607{
589 unsigned long flags; 608 unsigned long flags;
590 609
@@ -602,8 +621,7 @@ raw3215_startup(struct raw3215_info *raw)
602/* 621/*
603 * Shutdown a 3215 device. 622 * Shutdown a 3215 device.
604 */ 623 */
605static void 624static void raw3215_shutdown(struct raw3215_info *raw)
606raw3215_shutdown(struct raw3215_info *raw)
607{ 625{
608 DECLARE_WAITQUEUE(wait, current); 626 DECLARE_WAITQUEUE(wait, current);
609 unsigned long flags; 627 unsigned long flags;
@@ -628,8 +646,7 @@ raw3215_shutdown(struct raw3215_info *raw)
628 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 646 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
629} 647}
630 648
631static int 649static int raw3215_probe (struct ccw_device *cdev)
632raw3215_probe (struct ccw_device *cdev)
633{ 650{
634 struct raw3215_info *raw; 651 struct raw3215_info *raw;
635 int line; 652 int line;
@@ -675,8 +692,7 @@ raw3215_probe (struct ccw_device *cdev)
675 return 0; 692 return 0;
676} 693}
677 694
678static void 695static void raw3215_remove (struct ccw_device *cdev)
679raw3215_remove (struct ccw_device *cdev)
680{ 696{
681 struct raw3215_info *raw; 697 struct raw3215_info *raw;
682 698
@@ -689,8 +705,7 @@ raw3215_remove (struct ccw_device *cdev)
689 } 705 }
690} 706}
691 707
692static int 708static int raw3215_set_online (struct ccw_device *cdev)
693raw3215_set_online (struct ccw_device *cdev)
694{ 709{
695 struct raw3215_info *raw; 710 struct raw3215_info *raw;
696 711
@@ -701,8 +716,7 @@ raw3215_set_online (struct ccw_device *cdev)
701 return raw3215_startup(raw); 716 return raw3215_startup(raw);
702} 717}
703 718
704static int 719static int raw3215_set_offline (struct ccw_device *cdev)
705raw3215_set_offline (struct ccw_device *cdev)
706{ 720{
707 struct raw3215_info *raw; 721 struct raw3215_info *raw;
708 722
@@ -715,6 +729,36 @@ raw3215_set_offline (struct ccw_device *cdev)
715 return 0; 729 return 0;
716} 730}
717 731
732static int raw3215_pm_stop(struct ccw_device *cdev)
733{
734 struct raw3215_info *raw;
735 unsigned long flags;
736
737 /* Empty the output buffer, then prevent new I/O. */
738 raw = cdev->dev.driver_data;
739 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
740 raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
741 raw->flags |= RAW3215_FROZEN;
742 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
743 return 0;
744}
745
746static int raw3215_pm_start(struct ccw_device *cdev)
747{
748 struct raw3215_info *raw;
749 unsigned long flags;
750
751 /* Allow I/O again and flush output buffer. */
752 raw = cdev->dev.driver_data;
753 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
754 raw->flags &= ~RAW3215_FROZEN;
755 raw->flags |= RAW3215_FLUSHING;
756 raw3215_try_io(raw);
757 raw->flags &= ~RAW3215_FLUSHING;
758 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
759 return 0;
760}
761
718static struct ccw_device_id raw3215_id[] = { 762static struct ccw_device_id raw3215_id[] = {
719 { CCW_DEVICE(0x3215, 0) }, 763 { CCW_DEVICE(0x3215, 0) },
720 { /* end of list */ }, 764 { /* end of list */ },
@@ -728,14 +772,17 @@ static struct ccw_driver raw3215_ccw_driver = {
728 .remove = &raw3215_remove, 772 .remove = &raw3215_remove,
729 .set_online = &raw3215_set_online, 773 .set_online = &raw3215_set_online,
730 .set_offline = &raw3215_set_offline, 774 .set_offline = &raw3215_set_offline,
775 .freeze = &raw3215_pm_stop,
776 .thaw = &raw3215_pm_start,
777 .restore = &raw3215_pm_start,
731}; 778};
732 779
733#ifdef CONFIG_TN3215_CONSOLE 780#ifdef CONFIG_TN3215_CONSOLE
734/* 781/*
735 * Write a string to the 3215 console 782 * Write a string to the 3215 console
736 */ 783 */
737static void 784static void con3215_write(struct console *co, const char *str,
738con3215_write(struct console *co, const char *str, unsigned int count) 785 unsigned int count)
739{ 786{
740 struct raw3215_info *raw; 787 struct raw3215_info *raw;
741 int i; 788 int i;
@@ -768,13 +815,17 @@ static struct tty_driver *con3215_device(struct console *c, int *index)
768 * panic() calls con3215_flush through a panic_notifier 815 * panic() calls con3215_flush through a panic_notifier
769 * before the system enters a disabled, endless loop. 816 * before the system enters a disabled, endless loop.
770 */ 817 */
771static void 818static void con3215_flush(void)
772con3215_flush(void)
773{ 819{
774 struct raw3215_info *raw; 820 struct raw3215_info *raw;
775 unsigned long flags; 821 unsigned long flags;
776 822
777 raw = raw3215[0]; /* console 3215 is the first one */ 823 raw = raw3215[0]; /* console 3215 is the first one */
824 if (raw->flags & RAW3215_FROZEN)
825 /* The console is still frozen for suspend. */
826 if (ccw_device_force_console())
827 /* Forcing didn't work, no panic message .. */
828 return;
778 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); 829 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
779 raw3215_make_room(raw, RAW3215_BUFFER_SIZE); 830 raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
780 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); 831 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
@@ -811,8 +862,7 @@ static struct console con3215 = {
811 * 3215 console initialization code called from console_init(). 862 * 3215 console initialization code called from console_init().
812 * NOTE: This is called before kmalloc is available. 863 * NOTE: This is called before kmalloc is available.
813 */ 864 */
814static int __init 865static int __init con3215_init(void)
815con3215_init(void)
816{ 866{
817 struct ccw_device *cdev; 867 struct ccw_device *cdev;
818 struct raw3215_info *raw; 868 struct raw3215_info *raw;
@@ -875,8 +925,7 @@ console_initcall(con3215_init);
875 * 925 *
876 * This routine is called whenever a 3215 tty is opened. 926 * This routine is called whenever a 3215 tty is opened.
877 */ 927 */
878static int 928static int tty3215_open(struct tty_struct *tty, struct file * filp)
879tty3215_open(struct tty_struct *tty, struct file * filp)
880{ 929{
881 struct raw3215_info *raw; 930 struct raw3215_info *raw;
882 int retval, line; 931 int retval, line;
@@ -909,8 +958,7 @@ tty3215_open(struct tty_struct *tty, struct file * filp)
909 * This routine is called when the 3215 tty is closed. We wait 958 * This routine is called when the 3215 tty is closed. We wait
910 * for the remaining request to be completed. Then we clean up. 959 * for the remaining request to be completed. Then we clean up.
911 */ 960 */
912static void 961static void tty3215_close(struct tty_struct *tty, struct file * filp)
913tty3215_close(struct tty_struct *tty, struct file * filp)
914{ 962{
915 struct raw3215_info *raw; 963 struct raw3215_info *raw;
916 964
@@ -927,8 +975,7 @@ tty3215_close(struct tty_struct *tty, struct file * filp)
927/* 975/*
928 * Returns the amount of free space in the output buffer. 976 * Returns the amount of free space in the output buffer.
929 */ 977 */
930static int 978static int tty3215_write_room(struct tty_struct *tty)
931tty3215_write_room(struct tty_struct *tty)
932{ 979{
933 struct raw3215_info *raw; 980 struct raw3215_info *raw;
934 981
@@ -944,9 +991,8 @@ tty3215_write_room(struct tty_struct *tty)
944/* 991/*
945 * String write routine for 3215 ttys 992 * String write routine for 3215 ttys
946 */ 993 */
947static int 994static int tty3215_write(struct tty_struct * tty,
948tty3215_write(struct tty_struct * tty, 995 const unsigned char *buf, int count)
949 const unsigned char *buf, int count)
950{ 996{
951 struct raw3215_info *raw; 997 struct raw3215_info *raw;
952 998
@@ -960,8 +1006,7 @@ tty3215_write(struct tty_struct * tty,
960/* 1006/*
961 * Put character routine for 3215 ttys 1007 * Put character routine for 3215 ttys
962 */ 1008 */
963static int 1009static int tty3215_put_char(struct tty_struct *tty, unsigned char ch)
964tty3215_put_char(struct tty_struct *tty, unsigned char ch)
965{ 1010{
966 struct raw3215_info *raw; 1011 struct raw3215_info *raw;
967 1012
@@ -972,16 +1017,14 @@ tty3215_put_char(struct tty_struct *tty, unsigned char ch)
972 return 1; 1017 return 1;
973} 1018}
974 1019
975static void 1020static void tty3215_flush_chars(struct tty_struct *tty)
976tty3215_flush_chars(struct tty_struct *tty)
977{ 1021{
978} 1022}
979 1023
980/* 1024/*
981 * Returns the number of characters in the output buffer 1025 * Returns the number of characters in the output buffer
982 */ 1026 */
983static int 1027static int tty3215_chars_in_buffer(struct tty_struct *tty)
984tty3215_chars_in_buffer(struct tty_struct *tty)
985{ 1028{
986 struct raw3215_info *raw; 1029 struct raw3215_info *raw;
987 1030
@@ -989,8 +1032,7 @@ tty3215_chars_in_buffer(struct tty_struct *tty)
989 return raw->count; 1032 return raw->count;
990} 1033}
991 1034
992static void 1035static void tty3215_flush_buffer(struct tty_struct *tty)
993tty3215_flush_buffer(struct tty_struct *tty)
994{ 1036{
995 struct raw3215_info *raw; 1037 struct raw3215_info *raw;
996 1038
@@ -1002,9 +1044,8 @@ tty3215_flush_buffer(struct tty_struct *tty)
1002/* 1044/*
1003 * Currently we don't have any io controls for 3215 ttys 1045 * Currently we don't have any io controls for 3215 ttys
1004 */ 1046 */
1005static int 1047static int tty3215_ioctl(struct tty_struct *tty, struct file * file,
1006tty3215_ioctl(struct tty_struct *tty, struct file * file, 1048 unsigned int cmd, unsigned long arg)
1007 unsigned int cmd, unsigned long arg)
1008{ 1049{
1009 if (tty->flags & (1 << TTY_IO_ERROR)) 1050 if (tty->flags & (1 << TTY_IO_ERROR))
1010 return -EIO; 1051 return -EIO;
@@ -1019,8 +1060,7 @@ tty3215_ioctl(struct tty_struct *tty, struct file * file,
1019/* 1060/*
1020 * Disable reading from a 3215 tty 1061 * Disable reading from a 3215 tty
1021 */ 1062 */
1022static void 1063static void tty3215_throttle(struct tty_struct * tty)
1023tty3215_throttle(struct tty_struct * tty)
1024{ 1064{
1025 struct raw3215_info *raw; 1065 struct raw3215_info *raw;
1026 1066
@@ -1031,8 +1071,7 @@ tty3215_throttle(struct tty_struct * tty)
1031/* 1071/*
1032 * Enable reading from a 3215 tty 1072 * Enable reading from a 3215 tty
1033 */ 1073 */
1034static void 1074static void tty3215_unthrottle(struct tty_struct * tty)
1035tty3215_unthrottle(struct tty_struct * tty)
1036{ 1075{
1037 struct raw3215_info *raw; 1076 struct raw3215_info *raw;
1038 unsigned long flags; 1077 unsigned long flags;
@@ -1049,8 +1088,7 @@ tty3215_unthrottle(struct tty_struct * tty)
1049/* 1088/*
1050 * Disable writing to a 3215 tty 1089 * Disable writing to a 3215 tty
1051 */ 1090 */
1052static void 1091static void tty3215_stop(struct tty_struct *tty)
1053tty3215_stop(struct tty_struct *tty)
1054{ 1092{
1055 struct raw3215_info *raw; 1093 struct raw3215_info *raw;
1056 1094
@@ -1061,8 +1099,7 @@ tty3215_stop(struct tty_struct *tty)
1061/* 1099/*
1062 * Enable writing to a 3215 tty 1100 * Enable writing to a 3215 tty
1063 */ 1101 */
1064static void 1102static void tty3215_start(struct tty_struct *tty)
1065tty3215_start(struct tty_struct *tty)
1066{ 1103{
1067 struct raw3215_info *raw; 1104 struct raw3215_info *raw;
1068 unsigned long flags; 1105 unsigned long flags;
@@ -1096,8 +1133,7 @@ static const struct tty_operations tty3215_ops = {
1096 * 3215 tty registration code called from tty_init(). 1133 * 3215 tty registration code called from tty_init().
1097 * Most kernel services (incl. kmalloc) are available at this poimt. 1134 * Most kernel services (incl. kmalloc) are available at this poimt.
1098 */ 1135 */
1099static int __init 1136static int __init tty3215_init(void)
1100tty3215_init(void)
1101{ 1137{
1102 struct tty_driver *driver; 1138 struct tty_driver *driver;
1103 int ret; 1139 int ret;
@@ -1142,8 +1178,7 @@ tty3215_init(void)
1142 return 0; 1178 return 0;
1143} 1179}
1144 1180
1145static void __exit 1181static void __exit tty3215_exit(void)
1146tty3215_exit(void)
1147{ 1182{
1148 tty_unregister_driver(tty3215_driver); 1183 tty_unregister_driver(tty3215_driver);
1149 put_tty_driver(tty3215_driver); 1184 put_tty_driver(tty3215_driver);
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index ed5396dae58e..44d02e371c04 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/con3270.c 2 * IBM/3270 Driver - console view.
3 * IBM/3270 Driver - console view.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -530,6 +529,7 @@ con3270_flush(void)
530 cp = condev; 529 cp = condev;
531 if (!cp->view.dev) 530 if (!cp->view.dev)
532 return; 531 return;
532 raw3270_pm_unfreeze(&cp->view);
533 spin_lock_irqsave(&cp->view.lock, flags); 533 spin_lock_irqsave(&cp->view.lock, flags);
534 con3270_wait_write(cp); 534 con3270_wait_write(cp);
535 cp->nr_up = 0; 535 cp->nr_up = 0;
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index 40759c33477d..097d3846a828 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/fs3270.c 2 * IBM/3270 Driver - fullscreen driver.
3 * IBM/3270 Driver - fullscreen driver.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5/2.6 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -399,6 +398,11 @@ fs3270_free_view(struct raw3270_view *view)
399static void 398static void
400fs3270_release(struct raw3270_view *view) 399fs3270_release(struct raw3270_view *view)
401{ 400{
401 struct fs3270 *fp;
402
403 fp = (struct fs3270 *) view;
404 if (fp->fs_pid)
405 kill_pid(fp->fs_pid, SIGHUP, 1);
402} 406}
403 407
404/* View to a 3270 device. Can be console, tty or fullscreen. */ 408/* View to a 3270 device. Can be console, tty or fullscreen. */
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c
index 97e63cf46944..75a8831eebbc 100644
--- a/drivers/s390/char/monreader.c
+++ b/drivers/s390/char/monreader.c
@@ -1,10 +1,9 @@
1/* 1/*
2 * drivers/s390/char/monreader.c
3 *
4 * Character device driver for reading z/VM *MONITOR service records. 2 * Character device driver for reading z/VM *MONITOR service records.
5 * 3 *
6 * Copyright IBM Corp. 2004, 2008 4 * Copyright IBM Corp. 2004, 2009
7 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com> 5 *
6 * Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
8 */ 7 */
9 8
10#define KMSG_COMPONENT "monreader" 9#define KMSG_COMPONENT "monreader"
@@ -22,6 +21,7 @@
22#include <linux/spinlock.h> 21#include <linux/spinlock.h>
23#include <linux/interrupt.h> 22#include <linux/interrupt.h>
24#include <linux/poll.h> 23#include <linux/poll.h>
24#include <linux/device.h>
25#include <net/iucv/iucv.h> 25#include <net/iucv/iucv.h>
26#include <asm/uaccess.h> 26#include <asm/uaccess.h>
27#include <asm/ebcdic.h> 27#include <asm/ebcdic.h>
@@ -78,6 +78,7 @@ static u8 user_data_sever[16] = {
78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 78 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
79}; 79};
80 80
81static struct device *monreader_device;
81 82
82/****************************************************************************** 83/******************************************************************************
83 * helper functions * 84 * helper functions *
@@ -319,11 +320,12 @@ static int mon_open(struct inode *inode, struct file *filp)
319 goto out_path; 320 goto out_path;
320 } 321 }
321 filp->private_data = monpriv; 322 filp->private_data = monpriv;
323 monreader_device->driver_data = monpriv;
322 unlock_kernel(); 324 unlock_kernel();
323 return nonseekable_open(inode, filp); 325 return nonseekable_open(inode, filp);
324 326
325out_path: 327out_path:
326 kfree(monpriv->path); 328 iucv_path_free(monpriv->path);
327out_priv: 329out_priv:
328 mon_free_mem(monpriv); 330 mon_free_mem(monpriv);
329out_use: 331out_use:
@@ -341,10 +343,13 @@ static int mon_close(struct inode *inode, struct file *filp)
341 /* 343 /*
342 * Close IUCV connection and unregister 344 * Close IUCV connection and unregister
343 */ 345 */
344 rc = iucv_path_sever(monpriv->path, user_data_sever); 346 if (monpriv->path) {
345 if (rc) 347 rc = iucv_path_sever(monpriv->path, user_data_sever);
346 pr_warning("Disconnecting the z/VM *MONITOR system service " 348 if (rc)
347 "failed with rc=%i\n", rc); 349 pr_warning("Disconnecting the z/VM *MONITOR system "
350 "service failed with rc=%i\n", rc);
351 iucv_path_free(monpriv->path);
352 }
348 353
349 atomic_set(&monpriv->iucv_severed, 0); 354 atomic_set(&monpriv->iucv_severed, 0);
350 atomic_set(&monpriv->iucv_connected, 0); 355 atomic_set(&monpriv->iucv_connected, 0);
@@ -452,6 +457,94 @@ static struct miscdevice mon_dev = {
452 .minor = MISC_DYNAMIC_MINOR, 457 .minor = MISC_DYNAMIC_MINOR,
453}; 458};
454 459
460
461/******************************************************************************
462 * suspend / resume *
463 *****************************************************************************/
464static int monreader_freeze(struct device *dev)
465{
466 struct mon_private *monpriv = dev->driver_data;
467 int rc;
468
469 if (!monpriv)
470 return 0;
471 if (monpriv->path) {
472 rc = iucv_path_sever(monpriv->path, user_data_sever);
473 if (rc)
474 pr_warning("Disconnecting the z/VM *MONITOR system "
475 "service failed with rc=%i\n", rc);
476 iucv_path_free(monpriv->path);
477 }
478 atomic_set(&monpriv->iucv_severed, 0);
479 atomic_set(&monpriv->iucv_connected, 0);
480 atomic_set(&monpriv->read_ready, 0);
481 atomic_set(&monpriv->msglim_count, 0);
482 monpriv->write_index = 0;
483 monpriv->read_index = 0;
484 monpriv->path = NULL;
485 return 0;
486}
487
488static int monreader_thaw(struct device *dev)
489{
490 struct mon_private *monpriv = dev->driver_data;
491 int rc;
492
493 if (!monpriv)
494 return 0;
495 rc = -ENOMEM;
496 monpriv->path = iucv_path_alloc(MON_MSGLIM, IUCV_IPRMDATA, GFP_KERNEL);
497 if (!monpriv->path)
498 goto out;
499 rc = iucv_path_connect(monpriv->path, &monreader_iucv_handler,
500 MON_SERVICE, NULL, user_data_connect, monpriv);
501 if (rc) {
502 pr_err("Connecting to the z/VM *MONITOR system service "
503 "failed with rc=%i\n", rc);
504 goto out_path;
505 }
506 wait_event(mon_conn_wait_queue,
507 atomic_read(&monpriv->iucv_connected) ||
508 atomic_read(&monpriv->iucv_severed));
509 if (atomic_read(&monpriv->iucv_severed))
510 goto out_path;
511 return 0;
512out_path:
513 rc = -EIO;
514 iucv_path_free(monpriv->path);
515 monpriv->path = NULL;
516out:
517 atomic_set(&monpriv->iucv_severed, 1);
518 return rc;
519}
520
521static int monreader_restore(struct device *dev)
522{
523 int rc;
524
525 segment_unload(mon_dcss_name);
526 rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
527 &mon_dcss_start, &mon_dcss_end);
528 if (rc < 0) {
529 segment_warning(rc, mon_dcss_name);
530 panic("fatal monreader resume error: no monitor dcss\n");
531 }
532 return monreader_thaw(dev);
533}
534
535static struct dev_pm_ops monreader_pm_ops = {
536 .freeze = monreader_freeze,
537 .thaw = monreader_thaw,
538 .restore = monreader_restore,
539};
540
541static struct device_driver monreader_driver = {
542 .name = "monreader",
543 .bus = &iucv_bus,
544 .pm = &monreader_pm_ops,
545};
546
547
455/****************************************************************************** 548/******************************************************************************
456 * module init/exit * 549 * module init/exit *
457 *****************************************************************************/ 550 *****************************************************************************/
@@ -475,16 +568,33 @@ static int __init mon_init(void)
475 return rc; 568 return rc;
476 } 569 }
477 570
571 rc = driver_register(&monreader_driver);
572 if (rc)
573 goto out_iucv;
574 monreader_device = kzalloc(sizeof(struct device), GFP_KERNEL);
575 if (!monreader_device)
576 goto out_driver;
577 dev_set_name(monreader_device, "monreader-dev");
578 monreader_device->bus = &iucv_bus;
579 monreader_device->parent = iucv_root;
580 monreader_device->driver = &monreader_driver;
581 monreader_device->release = (void (*)(struct device *))kfree;
582 rc = device_register(monreader_device);
583 if (rc) {
584 kfree(monreader_device);
585 goto out_driver;
586 }
587
478 rc = segment_type(mon_dcss_name); 588 rc = segment_type(mon_dcss_name);
479 if (rc < 0) { 589 if (rc < 0) {
480 segment_warning(rc, mon_dcss_name); 590 segment_warning(rc, mon_dcss_name);
481 goto out_iucv; 591 goto out_device;
482 } 592 }
483 if (rc != SEG_TYPE_SC) { 593 if (rc != SEG_TYPE_SC) {
484 pr_err("The specified *MONITOR DCSS %s does not have the " 594 pr_err("The specified *MONITOR DCSS %s does not have the "
485 "required type SC\n", mon_dcss_name); 595 "required type SC\n", mon_dcss_name);
486 rc = -EINVAL; 596 rc = -EINVAL;
487 goto out_iucv; 597 goto out_device;
488 } 598 }
489 599
490 rc = segment_load(mon_dcss_name, SEGMENT_SHARED, 600 rc = segment_load(mon_dcss_name, SEGMENT_SHARED,
@@ -492,7 +602,7 @@ static int __init mon_init(void)
492 if (rc < 0) { 602 if (rc < 0) {
493 segment_warning(rc, mon_dcss_name); 603 segment_warning(rc, mon_dcss_name);
494 rc = -EINVAL; 604 rc = -EINVAL;
495 goto out_iucv; 605 goto out_device;
496 } 606 }
497 dcss_mkname(mon_dcss_name, &user_data_connect[8]); 607 dcss_mkname(mon_dcss_name, &user_data_connect[8]);
498 608
@@ -503,6 +613,10 @@ static int __init mon_init(void)
503 613
504out: 614out:
505 segment_unload(mon_dcss_name); 615 segment_unload(mon_dcss_name);
616out_device:
617 device_unregister(monreader_device);
618out_driver:
619 driver_unregister(&monreader_driver);
506out_iucv: 620out_iucv:
507 iucv_unregister(&monreader_iucv_handler, 1); 621 iucv_unregister(&monreader_iucv_handler, 1);
508 return rc; 622 return rc;
@@ -512,6 +626,8 @@ static void __exit mon_exit(void)
512{ 626{
513 segment_unload(mon_dcss_name); 627 segment_unload(mon_dcss_name);
514 WARN_ON(misc_deregister(&mon_dev) != 0); 628 WARN_ON(misc_deregister(&mon_dev) != 0);
629 device_unregister(monreader_device);
630 driver_unregister(&monreader_driver);
515 iucv_unregister(&monreader_iucv_handler, 1); 631 iucv_unregister(&monreader_iucv_handler, 1);
516 return; 632 return;
517} 633}
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index c7d7483bab9a..66fb8eba93f4 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -1,9 +1,7 @@
1/* 1/*
2 * drivers/s390/char/monwriter.c
3 *
4 * Character device driver for writing z/VM *MONITOR service records. 2 * Character device driver for writing z/VM *MONITOR service records.
5 * 3 *
6 * Copyright (C) IBM Corp. 2006 4 * Copyright IBM Corp. 2006, 2009
7 * 5 *
8 * Author(s): Melissa Howland <Melissa.Howland@us.ibm.com> 6 * Author(s): Melissa Howland <Melissa.Howland@us.ibm.com>
9 */ 7 */
@@ -22,6 +20,7 @@
22#include <linux/ctype.h> 20#include <linux/ctype.h>
23#include <linux/poll.h> 21#include <linux/poll.h>
24#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/platform_device.h>
25#include <asm/uaccess.h> 24#include <asm/uaccess.h>
26#include <asm/ebcdic.h> 25#include <asm/ebcdic.h>
27#include <asm/io.h> 26#include <asm/io.h>
@@ -40,7 +39,10 @@ struct mon_buf {
40 char *data; 39 char *data;
41}; 40};
42 41
42static LIST_HEAD(mon_priv_list);
43
43struct mon_private { 44struct mon_private {
45 struct list_head priv_list;
44 struct list_head list; 46 struct list_head list;
45 struct monwrite_hdr hdr; 47 struct monwrite_hdr hdr;
46 size_t hdr_to_read; 48 size_t hdr_to_read;
@@ -188,6 +190,7 @@ static int monwrite_open(struct inode *inode, struct file *filp)
188 monpriv->hdr_to_read = sizeof(monpriv->hdr); 190 monpriv->hdr_to_read = sizeof(monpriv->hdr);
189 mutex_init(&monpriv->thread_mutex); 191 mutex_init(&monpriv->thread_mutex);
190 filp->private_data = monpriv; 192 filp->private_data = monpriv;
193 list_add_tail(&monpriv->priv_list, &mon_priv_list);
191 unlock_kernel(); 194 unlock_kernel();
192 return nonseekable_open(inode, filp); 195 return nonseekable_open(inode, filp);
193} 196}
@@ -206,6 +209,7 @@ static int monwrite_close(struct inode *inode, struct file *filp)
206 kfree(entry->data); 209 kfree(entry->data);
207 kfree(entry); 210 kfree(entry);
208 } 211 }
212 list_del(&monpriv->priv_list);
209 kfree(monpriv); 213 kfree(monpriv);
210 return 0; 214 return 0;
211} 215}
@@ -281,20 +285,102 @@ static struct miscdevice mon_dev = {
281}; 285};
282 286
283/* 287/*
288 * suspend/resume
289 */
290
291static int monwriter_freeze(struct device *dev)
292{
293 struct mon_private *monpriv;
294 struct mon_buf *monbuf;
295
296 list_for_each_entry(monpriv, &mon_priv_list, priv_list) {
297 list_for_each_entry(monbuf, &monpriv->list, list) {
298 if (monbuf->hdr.mon_function != MONWRITE_GEN_EVENT)
299 monwrite_diag(&monbuf->hdr, monbuf->data,
300 APPLDATA_STOP_REC);
301 }
302 }
303 return 0;
304}
305
306static int monwriter_restore(struct device *dev)
307{
308 struct mon_private *monpriv;
309 struct mon_buf *monbuf;
310
311 list_for_each_entry(monpriv, &mon_priv_list, priv_list) {
312 list_for_each_entry(monbuf, &monpriv->list, list) {
313 if (monbuf->hdr.mon_function == MONWRITE_START_INTERVAL)
314 monwrite_diag(&monbuf->hdr, monbuf->data,
315 APPLDATA_START_INTERVAL_REC);
316 if (monbuf->hdr.mon_function == MONWRITE_START_CONFIG)
317 monwrite_diag(&monbuf->hdr, monbuf->data,
318 APPLDATA_START_CONFIG_REC);
319 }
320 }
321 return 0;
322}
323
324static int monwriter_thaw(struct device *dev)
325{
326 return monwriter_restore(dev);
327}
328
329static struct dev_pm_ops monwriter_pm_ops = {
330 .freeze = monwriter_freeze,
331 .thaw = monwriter_thaw,
332 .restore = monwriter_restore,
333};
334
335static struct platform_driver monwriter_pdrv = {
336 .driver = {
337 .name = "monwriter",
338 .owner = THIS_MODULE,
339 .pm = &monwriter_pm_ops,
340 },
341};
342
343static struct platform_device *monwriter_pdev;
344
345/*
284 * module init/exit 346 * module init/exit
285 */ 347 */
286 348
287static int __init mon_init(void) 349static int __init mon_init(void)
288{ 350{
289 if (MACHINE_IS_VM) 351 int rc;
290 return misc_register(&mon_dev); 352
291 else 353 if (!MACHINE_IS_VM)
292 return -ENODEV; 354 return -ENODEV;
355
356 rc = platform_driver_register(&monwriter_pdrv);
357 if (rc)
358 return rc;
359
360 monwriter_pdev = platform_device_register_simple("monwriter", -1, NULL,
361 0);
362 if (IS_ERR(monwriter_pdev)) {
363 rc = PTR_ERR(monwriter_pdev);
364 goto out_driver;
365 }
366
367 rc = misc_register(&mon_dev);
368 if (rc)
369 goto out_device;
370 return 0;
371
372out_device:
373 platform_device_unregister(monwriter_pdev);
374out_driver:
375 platform_driver_unregister(&monwriter_pdrv);
376 return rc;
293} 377}
294 378
295static void __exit mon_exit(void) 379static void __exit mon_exit(void)
296{ 380{
297 WARN_ON(misc_deregister(&mon_dev) != 0); 381 WARN_ON(misc_deregister(&mon_dev) != 0);
382 platform_device_unregister(monwriter_pdev);
383 platform_driver_unregister(&monwriter_pdrv);
298} 384}
299 385
300module_init(mon_init); 386module_init(mon_init);
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 0b15cf107ec9..81c151b5f0ac 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/raw3270.c 2 * IBM/3270 Driver - core functions.
3 * IBM/3270 Driver - core functions.
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <linux/bootmem.h> 10#include <linux/bootmem.h>
@@ -61,6 +60,7 @@ struct raw3270 {
61#define RAW3270_FLAGS_ATTN 2 /* Device sent an ATTN interrupt */ 60#define RAW3270_FLAGS_ATTN 2 /* Device sent an ATTN interrupt */
62#define RAW3270_FLAGS_READY 4 /* Device is useable by views */ 61#define RAW3270_FLAGS_READY 4 /* Device is useable by views */
63#define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */ 62#define RAW3270_FLAGS_CONSOLE 8 /* Device is the console. */
63#define RAW3270_FLAGS_FROZEN 16 /* set if 3270 is frozen for suspend */
64 64
65/* Semaphore to protect global data of raw3270 (devices, views, etc). */ 65/* Semaphore to protect global data of raw3270 (devices, views, etc). */
66static DEFINE_MUTEX(raw3270_mutex); 66static DEFINE_MUTEX(raw3270_mutex);
@@ -306,7 +306,8 @@ raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
306 306
307 spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags); 307 spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
308 rp = view->dev; 308 rp = view->dev;
309 if (!rp || rp->view != view) 309 if (!rp || rp->view != view ||
310 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
310 rc = -EACCES; 311 rc = -EACCES;
311 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 312 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
312 rc = -ENODEV; 313 rc = -ENODEV;
@@ -323,7 +324,8 @@ raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
323 int rc; 324 int rc;
324 325
325 rp = view->dev; 326 rp = view->dev;
326 if (!rp || rp->view != view) 327 if (!rp || rp->view != view ||
328 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
327 rc = -EACCES; 329 rc = -EACCES;
328 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 330 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
329 rc = -ENODEV; 331 rc = -ENODEV;
@@ -764,7 +766,8 @@ raw3270_reset(struct raw3270_view *view)
764 int rc; 766 int rc;
765 767
766 rp = view->dev; 768 rp = view->dev;
767 if (!rp || rp->view != view) 769 if (!rp || rp->view != view ||
770 test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
768 rc = -EACCES; 771 rc = -EACCES;
769 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 772 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
770 rc = -ENODEV; 773 rc = -ENODEV;
@@ -922,6 +925,8 @@ raw3270_activate_view(struct raw3270_view *view)
922 rc = 0; 925 rc = 0;
923 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags)) 926 else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))
924 rc = -ENODEV; 927 rc = -ENODEV;
928 else if (test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
929 rc = -EACCES;
925 else { 930 else {
926 oldview = NULL; 931 oldview = NULL;
927 if (rp->view) { 932 if (rp->view) {
@@ -969,7 +974,8 @@ raw3270_deactivate_view(struct raw3270_view *view)
969 list_del_init(&view->list); 974 list_del_init(&view->list);
970 list_add_tail(&view->list, &rp->view_list); 975 list_add_tail(&view->list, &rp->view_list);
971 /* Try to activate another view. */ 976 /* Try to activate another view. */
972 if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) { 977 if (test_bit(RAW3270_FLAGS_READY, &rp->flags) &&
978 !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
973 list_for_each_entry(view, &rp->view_list, list) { 979 list_for_each_entry(view, &rp->view_list, list) {
974 rp->view = view; 980 rp->view = view;
975 if (view->fn->activate(view) == 0) 981 if (view->fn->activate(view) == 0)
@@ -1068,7 +1074,8 @@ raw3270_del_view(struct raw3270_view *view)
1068 rp->view = NULL; 1074 rp->view = NULL;
1069 } 1075 }
1070 list_del_init(&view->list); 1076 list_del_init(&view->list);
1071 if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) { 1077 if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags) &&
1078 !test_bit(RAW3270_FLAGS_FROZEN, &rp->flags)) {
1072 /* Try to activate another view. */ 1079 /* Try to activate another view. */
1073 list_for_each_entry(nv, &rp->view_list, list) { 1080 list_for_each_entry(nv, &rp->view_list, list) {
1074 if (nv->fn->activate(nv) == 0) { 1081 if (nv->fn->activate(nv) == 0) {
@@ -1337,6 +1344,58 @@ raw3270_set_offline (struct ccw_device *cdev)
1337 return 0; 1344 return 0;
1338} 1345}
1339 1346
1347static int raw3270_pm_stop(struct ccw_device *cdev)
1348{
1349 struct raw3270 *rp;
1350 struct raw3270_view *view;
1351 unsigned long flags;
1352
1353 rp = cdev->dev.driver_data;
1354 if (!rp)
1355 return 0;
1356 spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1357 if (rp->view)
1358 rp->view->fn->deactivate(rp->view);
1359 if (!test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags)) {
1360 /*
1361 * Release tty and fullscreen for all non-console
1362 * devices.
1363 */
1364 list_for_each_entry(view, &rp->view_list, list) {
1365 if (view->fn->release)
1366 view->fn->release(view);
1367 }
1368 }
1369 set_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
1370 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1371 return 0;
1372}
1373
1374static int raw3270_pm_start(struct ccw_device *cdev)
1375{
1376 struct raw3270 *rp;
1377 unsigned long flags;
1378
1379 rp = cdev->dev.driver_data;
1380 if (!rp)
1381 return 0;
1382 spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1383 clear_bit(RAW3270_FLAGS_FROZEN, &rp->flags);
1384 if (rp->view)
1385 rp->view->fn->activate(rp->view);
1386 spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1387 return 0;
1388}
1389
1390void raw3270_pm_unfreeze(struct raw3270_view *view)
1391{
1392 struct raw3270 *rp;
1393
1394 rp = view->dev;
1395 if (rp && test_bit(RAW3270_FLAGS_FROZEN, &rp->flags))
1396 ccw_device_force_console();
1397}
1398
1340static struct ccw_device_id raw3270_id[] = { 1399static struct ccw_device_id raw3270_id[] = {
1341 { CCW_DEVICE(0x3270, 0) }, 1400 { CCW_DEVICE(0x3270, 0) },
1342 { CCW_DEVICE(0x3271, 0) }, 1401 { CCW_DEVICE(0x3271, 0) },
@@ -1360,6 +1419,9 @@ static struct ccw_driver raw3270_ccw_driver = {
1360 .remove = &raw3270_remove, 1419 .remove = &raw3270_remove,
1361 .set_online = &raw3270_set_online, 1420 .set_online = &raw3270_set_online,
1362 .set_offline = &raw3270_set_offline, 1421 .set_offline = &raw3270_set_offline,
1422 .freeze = &raw3270_pm_stop,
1423 .thaw = &raw3270_pm_start,
1424 .restore = &raw3270_pm_start,
1363}; 1425};
1364 1426
1365static int 1427static int
diff --git a/drivers/s390/char/raw3270.h b/drivers/s390/char/raw3270.h
index 90beaa80a782..ed34eb2199cc 100644
--- a/drivers/s390/char/raw3270.h
+++ b/drivers/s390/char/raw3270.h
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/raw3270.h 2 * IBM/3270 Driver
3 * IBM/3270 Driver
4 * 3 *
5 * Author(s): 4 * Author(s):
6 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global) 5 * Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
7 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com> 6 * Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * -- Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 7 * Copyright IBM Corp. 2003, 2009
9 */ 8 */
10 9
11#include <asm/idals.h> 10#include <asm/idals.h>
@@ -195,6 +194,7 @@ void raw3270_wait_cons_dev(struct raw3270 *);
195/* Notifier for device addition/removal */ 194/* Notifier for device addition/removal */
196int raw3270_register_notifier(void (*notifier)(int, int)); 195int raw3270_register_notifier(void (*notifier)(int, int));
197void raw3270_unregister_notifier(void (*notifier)(int, int)); 196void raw3270_unregister_notifier(void (*notifier)(int, int));
197void raw3270_pm_unfreeze(struct raw3270_view *);
198 198
199/* 199/*
200 * Little memory allocator for string objects. 200 * Little memory allocator for string objects.
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 4377e93a43d7..a983f5086788 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/sclp.c 2 * core function to access sclp interface
3 * core function to access sclp interface
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 1999, 2009
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 *
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
9 */ 8 */
10 9
11#include <linux/module.h> 10#include <linux/module.h>
@@ -16,6 +15,9 @@
16#include <linux/reboot.h> 15#include <linux/reboot.h>
17#include <linux/jiffies.h> 16#include <linux/jiffies.h>
18#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/suspend.h>
19#include <linux/completion.h>
20#include <linux/platform_device.h>
19#include <asm/types.h> 21#include <asm/types.h>
20#include <asm/s390_ext.h> 22#include <asm/s390_ext.h>
21 23
@@ -47,6 +49,16 @@ static struct sclp_req sclp_init_req;
47static char sclp_read_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); 49static char sclp_read_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
48static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); 50static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
49 51
52/* Suspend request */
53static DECLARE_COMPLETION(sclp_request_queue_flushed);
54
55static void sclp_suspend_req_cb(struct sclp_req *req, void *data)
56{
57 complete(&sclp_request_queue_flushed);
58}
59
60static struct sclp_req sclp_suspend_req;
61
50/* Timer for request retries. */ 62/* Timer for request retries. */
51static struct timer_list sclp_request_timer; 63static struct timer_list sclp_request_timer;
52 64
@@ -84,6 +96,12 @@ static volatile enum sclp_mask_state_t {
84 sclp_mask_state_initializing 96 sclp_mask_state_initializing
85} sclp_mask_state = sclp_mask_state_idle; 97} sclp_mask_state = sclp_mask_state_idle;
86 98
99/* Internal state: is the driver suspended? */
100static enum sclp_suspend_state_t {
101 sclp_suspend_state_running,
102 sclp_suspend_state_suspended,
103} sclp_suspend_state = sclp_suspend_state_running;
104
87/* Maximum retry counts */ 105/* Maximum retry counts */
88#define SCLP_INIT_RETRY 3 106#define SCLP_INIT_RETRY 3
89#define SCLP_MASK_RETRY 3 107#define SCLP_MASK_RETRY 3
@@ -211,6 +229,8 @@ sclp_process_queue(void)
211 del_timer(&sclp_request_timer); 229 del_timer(&sclp_request_timer);
212 while (!list_empty(&sclp_req_queue)) { 230 while (!list_empty(&sclp_req_queue)) {
213 req = list_entry(sclp_req_queue.next, struct sclp_req, list); 231 req = list_entry(sclp_req_queue.next, struct sclp_req, list);
232 if (!req->sccb)
233 goto do_post;
214 rc = __sclp_start_request(req); 234 rc = __sclp_start_request(req);
215 if (rc == 0) 235 if (rc == 0)
216 break; 236 break;
@@ -222,6 +242,7 @@ sclp_process_queue(void)
222 sclp_request_timeout, 0); 242 sclp_request_timeout, 0);
223 break; 243 break;
224 } 244 }
245do_post:
225 /* Post-processing for aborted request */ 246 /* Post-processing for aborted request */
226 list_del(&req->list); 247 list_del(&req->list);
227 if (req->callback) { 248 if (req->callback) {
@@ -233,6 +254,19 @@ sclp_process_queue(void)
233 spin_unlock_irqrestore(&sclp_lock, flags); 254 spin_unlock_irqrestore(&sclp_lock, flags);
234} 255}
235 256
257static int __sclp_can_add_request(struct sclp_req *req)
258{
259 if (req == &sclp_suspend_req || req == &sclp_init_req)
260 return 1;
261 if (sclp_suspend_state != sclp_suspend_state_running)
262 return 0;
263 if (sclp_init_state != sclp_init_state_initialized)
264 return 0;
265 if (sclp_activation_state != sclp_activation_state_active)
266 return 0;
267 return 1;
268}
269
236/* Queue a new request. Return zero on success, non-zero otherwise. */ 270/* Queue a new request. Return zero on success, non-zero otherwise. */
237int 271int
238sclp_add_request(struct sclp_req *req) 272sclp_add_request(struct sclp_req *req)
@@ -241,9 +275,7 @@ sclp_add_request(struct sclp_req *req)
241 int rc; 275 int rc;
242 276
243 spin_lock_irqsave(&sclp_lock, flags); 277 spin_lock_irqsave(&sclp_lock, flags);
244 if ((sclp_init_state != sclp_init_state_initialized || 278 if (!__sclp_can_add_request(req)) {
245 sclp_activation_state != sclp_activation_state_active) &&
246 req != &sclp_init_req) {
247 spin_unlock_irqrestore(&sclp_lock, flags); 279 spin_unlock_irqrestore(&sclp_lock, flags);
248 return -EIO; 280 return -EIO;
249 } 281 }
@@ -254,10 +286,16 @@ sclp_add_request(struct sclp_req *req)
254 /* Start if request is first in list */ 286 /* Start if request is first in list */
255 if (sclp_running_state == sclp_running_state_idle && 287 if (sclp_running_state == sclp_running_state_idle &&
256 req->list.prev == &sclp_req_queue) { 288 req->list.prev == &sclp_req_queue) {
289 if (!req->sccb) {
290 list_del(&req->list);
291 rc = -ENODATA;
292 goto out;
293 }
257 rc = __sclp_start_request(req); 294 rc = __sclp_start_request(req);
258 if (rc) 295 if (rc)
259 list_del(&req->list); 296 list_del(&req->list);
260 } 297 }
298out:
261 spin_unlock_irqrestore(&sclp_lock, flags); 299 spin_unlock_irqrestore(&sclp_lock, flags);
262 return rc; 300 return rc;
263} 301}
@@ -560,6 +598,7 @@ sclp_register(struct sclp_register *reg)
560 /* Trigger initial state change callback */ 598 /* Trigger initial state change callback */
561 reg->sclp_receive_mask = 0; 599 reg->sclp_receive_mask = 0;
562 reg->sclp_send_mask = 0; 600 reg->sclp_send_mask = 0;
601 reg->pm_event_posted = 0;
563 list_add(&reg->list, &sclp_reg_list); 602 list_add(&reg->list, &sclp_reg_list);
564 spin_unlock_irqrestore(&sclp_lock, flags); 603 spin_unlock_irqrestore(&sclp_lock, flags);
565 rc = sclp_init_mask(1); 604 rc = sclp_init_mask(1);
@@ -880,20 +919,134 @@ static struct notifier_block sclp_reboot_notifier = {
880 .notifier_call = sclp_reboot_event 919 .notifier_call = sclp_reboot_event
881}; 920};
882 921
922/*
923 * Suspend/resume SCLP notifier implementation
924 */
925
926static void sclp_pm_event(enum sclp_pm_event sclp_pm_event, int rollback)
927{
928 struct sclp_register *reg;
929 unsigned long flags;
930
931 if (!rollback) {
932 spin_lock_irqsave(&sclp_lock, flags);
933 list_for_each_entry(reg, &sclp_reg_list, list)
934 reg->pm_event_posted = 0;
935 spin_unlock_irqrestore(&sclp_lock, flags);
936 }
937 do {
938 spin_lock_irqsave(&sclp_lock, flags);
939 list_for_each_entry(reg, &sclp_reg_list, list) {
940 if (rollback && reg->pm_event_posted)
941 goto found;
942 if (!rollback && !reg->pm_event_posted)
943 goto found;
944 }
945 spin_unlock_irqrestore(&sclp_lock, flags);
946 return;
947found:
948 spin_unlock_irqrestore(&sclp_lock, flags);
949 if (reg->pm_event_fn)
950 reg->pm_event_fn(reg, sclp_pm_event);
951 reg->pm_event_posted = rollback ? 0 : 1;
952 } while (1);
953}
954
955/*
956 * Susend/resume callbacks for platform device
957 */
958
959static int sclp_freeze(struct device *dev)
960{
961 unsigned long flags;
962 int rc;
963
964 sclp_pm_event(SCLP_PM_EVENT_FREEZE, 0);
965
966 spin_lock_irqsave(&sclp_lock, flags);
967 sclp_suspend_state = sclp_suspend_state_suspended;
968 spin_unlock_irqrestore(&sclp_lock, flags);
969
970 /* Init supend data */
971 memset(&sclp_suspend_req, 0, sizeof(sclp_suspend_req));
972 sclp_suspend_req.callback = sclp_suspend_req_cb;
973 sclp_suspend_req.status = SCLP_REQ_FILLED;
974 init_completion(&sclp_request_queue_flushed);
975
976 rc = sclp_add_request(&sclp_suspend_req);
977 if (rc == 0)
978 wait_for_completion(&sclp_request_queue_flushed);
979 else if (rc != -ENODATA)
980 goto fail_thaw;
981
982 rc = sclp_deactivate();
983 if (rc)
984 goto fail_thaw;
985 return 0;
986
987fail_thaw:
988 spin_lock_irqsave(&sclp_lock, flags);
989 sclp_suspend_state = sclp_suspend_state_running;
990 spin_unlock_irqrestore(&sclp_lock, flags);
991 sclp_pm_event(SCLP_PM_EVENT_THAW, 1);
992 return rc;
993}
994
995static int sclp_undo_suspend(enum sclp_pm_event event)
996{
997 unsigned long flags;
998 int rc;
999
1000 rc = sclp_reactivate();
1001 if (rc)
1002 return rc;
1003
1004 spin_lock_irqsave(&sclp_lock, flags);
1005 sclp_suspend_state = sclp_suspend_state_running;
1006 spin_unlock_irqrestore(&sclp_lock, flags);
1007
1008 sclp_pm_event(event, 0);
1009 return 0;
1010}
1011
1012static int sclp_thaw(struct device *dev)
1013{
1014 return sclp_undo_suspend(SCLP_PM_EVENT_THAW);
1015}
1016
1017static int sclp_restore(struct device *dev)
1018{
1019 return sclp_undo_suspend(SCLP_PM_EVENT_RESTORE);
1020}
1021
1022static struct dev_pm_ops sclp_pm_ops = {
1023 .freeze = sclp_freeze,
1024 .thaw = sclp_thaw,
1025 .restore = sclp_restore,
1026};
1027
1028static struct platform_driver sclp_pdrv = {
1029 .driver = {
1030 .name = "sclp",
1031 .owner = THIS_MODULE,
1032 .pm = &sclp_pm_ops,
1033 },
1034};
1035
1036static struct platform_device *sclp_pdev;
1037
883/* Initialize SCLP driver. Return zero if driver is operational, non-zero 1038/* Initialize SCLP driver. Return zero if driver is operational, non-zero
884 * otherwise. */ 1039 * otherwise. */
885static int 1040static int
886sclp_init(void) 1041sclp_init(void)
887{ 1042{
888 unsigned long flags; 1043 unsigned long flags;
889 int rc; 1044 int rc = 0;
890 1045
891 spin_lock_irqsave(&sclp_lock, flags); 1046 spin_lock_irqsave(&sclp_lock, flags);
892 /* Check for previous or running initialization */ 1047 /* Check for previous or running initialization */
893 if (sclp_init_state != sclp_init_state_uninitialized) { 1048 if (sclp_init_state != sclp_init_state_uninitialized)
894 spin_unlock_irqrestore(&sclp_lock, flags); 1049 goto fail_unlock;
895 return 0;
896 }
897 sclp_init_state = sclp_init_state_initializing; 1050 sclp_init_state = sclp_init_state_initializing;
898 /* Set up variables */ 1051 /* Set up variables */
899 INIT_LIST_HEAD(&sclp_req_queue); 1052 INIT_LIST_HEAD(&sclp_req_queue);
@@ -904,27 +1057,17 @@ sclp_init(void)
904 spin_unlock_irqrestore(&sclp_lock, flags); 1057 spin_unlock_irqrestore(&sclp_lock, flags);
905 rc = sclp_check_interface(); 1058 rc = sclp_check_interface();
906 spin_lock_irqsave(&sclp_lock, flags); 1059 spin_lock_irqsave(&sclp_lock, flags);
907 if (rc) { 1060 if (rc)
908 sclp_init_state = sclp_init_state_uninitialized; 1061 goto fail_init_state_uninitialized;
909 spin_unlock_irqrestore(&sclp_lock, flags);
910 return rc;
911 }
912 /* Register reboot handler */ 1062 /* Register reboot handler */
913 rc = register_reboot_notifier(&sclp_reboot_notifier); 1063 rc = register_reboot_notifier(&sclp_reboot_notifier);
914 if (rc) { 1064 if (rc)
915 sclp_init_state = sclp_init_state_uninitialized; 1065 goto fail_init_state_uninitialized;
916 spin_unlock_irqrestore(&sclp_lock, flags);
917 return rc;
918 }
919 /* Register interrupt handler */ 1066 /* Register interrupt handler */
920 rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler, 1067 rc = register_early_external_interrupt(0x2401, sclp_interrupt_handler,
921 &ext_int_info_hwc); 1068 &ext_int_info_hwc);
922 if (rc) { 1069 if (rc)
923 unregister_reboot_notifier(&sclp_reboot_notifier); 1070 goto fail_unregister_reboot_notifier;
924 sclp_init_state = sclp_init_state_uninitialized;
925 spin_unlock_irqrestore(&sclp_lock, flags);
926 return rc;
927 }
928 sclp_init_state = sclp_init_state_initialized; 1071 sclp_init_state = sclp_init_state_initialized;
929 spin_unlock_irqrestore(&sclp_lock, flags); 1072 spin_unlock_irqrestore(&sclp_lock, flags);
930 /* Enable service-signal external interruption - needs to happen with 1073 /* Enable service-signal external interruption - needs to happen with
@@ -932,11 +1075,56 @@ sclp_init(void)
932 ctl_set_bit(0, 9); 1075 ctl_set_bit(0, 9);
933 sclp_init_mask(1); 1076 sclp_init_mask(1);
934 return 0; 1077 return 0;
1078
1079fail_unregister_reboot_notifier:
1080 unregister_reboot_notifier(&sclp_reboot_notifier);
1081fail_init_state_uninitialized:
1082 sclp_init_state = sclp_init_state_uninitialized;
1083fail_unlock:
1084 spin_unlock_irqrestore(&sclp_lock, flags);
1085 return rc;
935} 1086}
936 1087
1088/*
1089 * SCLP panic notifier: If we are suspended, we thaw SCLP in order to be able
1090 * to print the panic message.
1091 */
1092static int sclp_panic_notify(struct notifier_block *self,
1093 unsigned long event, void *data)
1094{
1095 if (sclp_suspend_state == sclp_suspend_state_suspended)
1096 sclp_undo_suspend(SCLP_PM_EVENT_THAW);
1097 return NOTIFY_OK;
1098}
1099
1100static struct notifier_block sclp_on_panic_nb = {
1101 .notifier_call = sclp_panic_notify,
1102 .priority = SCLP_PANIC_PRIO,
1103};
1104
937static __init int sclp_initcall(void) 1105static __init int sclp_initcall(void)
938{ 1106{
1107 int rc;
1108
1109 rc = platform_driver_register(&sclp_pdrv);
1110 if (rc)
1111 return rc;
1112 sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
1113 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
1114 if (rc)
1115 goto fail_platform_driver_unregister;
1116 rc = atomic_notifier_chain_register(&panic_notifier_list,
1117 &sclp_on_panic_nb);
1118 if (rc)
1119 goto fail_platform_device_unregister;
1120
939 return sclp_init(); 1121 return sclp_init();
1122
1123fail_platform_device_unregister:
1124 platform_device_unregister(sclp_pdev);
1125fail_platform_driver_unregister:
1126 platform_driver_unregister(&sclp_pdrv);
1127 return rc;
940} 1128}
941 1129
942arch_initcall(sclp_initcall); 1130arch_initcall(sclp_initcall);
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index bac80e856f97..60e7cb07095b 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -1,10 +1,8 @@
1/* 1/*
2 * drivers/s390/char/sclp.h 2 * Copyright IBM Corp. 1999, 2009
3 * 3 *
4 * S390 version 4 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 */ 6 */
9 7
10#ifndef __SCLP_H__ 8#ifndef __SCLP_H__
@@ -17,7 +15,7 @@
17 15
18/* maximum number of pages concerning our own memory management */ 16/* maximum number of pages concerning our own memory management */
19#define MAX_KMEM_PAGES (sizeof(unsigned long) << 3) 17#define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
20#define MAX_CONSOLE_PAGES 4 18#define MAX_CONSOLE_PAGES 6
21 19
22#define EVTYP_OPCMD 0x01 20#define EVTYP_OPCMD 0x01
23#define EVTYP_MSG 0x02 21#define EVTYP_MSG 0x02
@@ -68,6 +66,15 @@ typedef unsigned int sclp_cmdw_t;
68 66
69#define GDS_KEY_SELFDEFTEXTMSG 0x31 67#define GDS_KEY_SELFDEFTEXTMSG 0x31
70 68
69enum sclp_pm_event {
70 SCLP_PM_EVENT_FREEZE,
71 SCLP_PM_EVENT_THAW,
72 SCLP_PM_EVENT_RESTORE,
73};
74
75#define SCLP_PANIC_PRIO 1
76#define SCLP_PANIC_PRIO_CLIENT 0
77
71typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ 78typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */
72 79
73struct sccb_header { 80struct sccb_header {
@@ -134,6 +141,10 @@ struct sclp_register {
134 void (*state_change_fn)(struct sclp_register *); 141 void (*state_change_fn)(struct sclp_register *);
135 /* called for events in cp_receive_mask/sclp_receive_mask */ 142 /* called for events in cp_receive_mask/sclp_receive_mask */
136 void (*receiver_fn)(struct evbuf_header *); 143 void (*receiver_fn)(struct evbuf_header *);
144 /* called for power management events */
145 void (*pm_event_fn)(struct sclp_register *, enum sclp_pm_event);
146 /* pm event posted flag */
147 int pm_event_posted;
137}; 148};
138 149
139/* externals from sclp.c */ 150/* externals from sclp.c */
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 77ab6e34a100..5cc11c636d38 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * drivers/s390/char/sclp_cmd.c 2 * Copyright IBM Corp. 2007, 2009
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, 5 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
6 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
7 */ 6 */
8 7
9#define KMSG_COMPONENT "sclp_cmd" 8#define KMSG_COMPONENT "sclp_cmd"
@@ -12,11 +11,13 @@
12#include <linux/completion.h> 11#include <linux/completion.h>
13#include <linux/init.h> 12#include <linux/init.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/err.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/mm.h> 17#include <linux/mm.h>
18#include <linux/mmzone.h> 18#include <linux/mmzone.h>
19#include <linux/memory.h> 19#include <linux/memory.h>
20#include <linux/platform_device.h>
20#include <asm/chpid.h> 21#include <asm/chpid.h>
21#include <asm/sclp.h> 22#include <asm/sclp.h>
22#include <asm/setup.h> 23#include <asm/setup.h>
@@ -292,6 +293,7 @@ static DEFINE_MUTEX(sclp_mem_mutex);
292static LIST_HEAD(sclp_mem_list); 293static LIST_HEAD(sclp_mem_list);
293static u8 sclp_max_storage_id; 294static u8 sclp_max_storage_id;
294static unsigned long sclp_storage_ids[256 / BITS_PER_LONG]; 295static unsigned long sclp_storage_ids[256 / BITS_PER_LONG];
296static int sclp_mem_state_changed;
295 297
296struct memory_increment { 298struct memory_increment {
297 struct list_head list; 299 struct list_head list;
@@ -450,6 +452,8 @@ static int sclp_mem_notifier(struct notifier_block *nb,
450 rc = -EINVAL; 452 rc = -EINVAL;
451 break; 453 break;
452 } 454 }
455 if (!rc)
456 sclp_mem_state_changed = 1;
453 mutex_unlock(&sclp_mem_mutex); 457 mutex_unlock(&sclp_mem_mutex);
454 return rc ? NOTIFY_BAD : NOTIFY_OK; 458 return rc ? NOTIFY_BAD : NOTIFY_OK;
455} 459}
@@ -525,6 +529,14 @@ static void __init insert_increment(u16 rn, int standby, int assigned)
525 list_add(&new_incr->list, prev); 529 list_add(&new_incr->list, prev);
526} 530}
527 531
532static int sclp_mem_freeze(struct device *dev)
533{
534 if (!sclp_mem_state_changed)
535 return 0;
536 pr_err("Memory hotplug state changed, suspend refused.\n");
537 return -EPERM;
538}
539
528struct read_storage_sccb { 540struct read_storage_sccb {
529 struct sccb_header header; 541 struct sccb_header header;
530 u16 max_id; 542 u16 max_id;
@@ -534,8 +546,20 @@ struct read_storage_sccb {
534 u32 entries[0]; 546 u32 entries[0];
535} __packed; 547} __packed;
536 548
549static struct dev_pm_ops sclp_mem_pm_ops = {
550 .freeze = sclp_mem_freeze,
551};
552
553static struct platform_driver sclp_mem_pdrv = {
554 .driver = {
555 .name = "sclp_mem",
556 .pm = &sclp_mem_pm_ops,
557 },
558};
559
537static int __init sclp_detect_standby_memory(void) 560static int __init sclp_detect_standby_memory(void)
538{ 561{
562 struct platform_device *sclp_pdev;
539 struct read_storage_sccb *sccb; 563 struct read_storage_sccb *sccb;
540 int i, id, assigned, rc; 564 int i, id, assigned, rc;
541 565
@@ -588,7 +612,17 @@ static int __init sclp_detect_standby_memory(void)
588 rc = register_memory_notifier(&sclp_mem_nb); 612 rc = register_memory_notifier(&sclp_mem_nb);
589 if (rc) 613 if (rc)
590 goto out; 614 goto out;
615 rc = platform_driver_register(&sclp_mem_pdrv);
616 if (rc)
617 goto out;
618 sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0);
619 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
620 if (rc)
621 goto out_driver;
591 sclp_add_standby_memory(); 622 sclp_add_standby_memory();
623 goto out;
624out_driver:
625 platform_driver_unregister(&sclp_mem_pdrv);
592out: 626out:
593 free_page((unsigned long) sccb); 627 free_page((unsigned long) sccb);
594 return rc; 628 return rc;
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c
index 9a25c4bd1421..336811a77672 100644
--- a/drivers/s390/char/sclp_con.c
+++ b/drivers/s390/char/sclp_con.c
@@ -1,11 +1,9 @@
1/* 1/*
2 * drivers/s390/char/sclp_con.c 2 * SCLP line mode console driver
3 * SCLP line mode console driver
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 1999, 2009
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 6 * Martin Schwidefsky <schwidefsky@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com>
9 */ 7 */
10 8
11#include <linux/kmod.h> 9#include <linux/kmod.h>
@@ -32,13 +30,14 @@ static spinlock_t sclp_con_lock;
32static struct list_head sclp_con_pages; 30static struct list_head sclp_con_pages;
33/* List of full struct sclp_buffer structures ready for output */ 31/* List of full struct sclp_buffer structures ready for output */
34static struct list_head sclp_con_outqueue; 32static struct list_head sclp_con_outqueue;
35/* Counter how many buffers are emitted (max 1) and how many */
36/* are on the output queue. */
37static int sclp_con_buffer_count;
38/* Pointer to current console buffer */ 33/* Pointer to current console buffer */
39static struct sclp_buffer *sclp_conbuf; 34static struct sclp_buffer *sclp_conbuf;
40/* Timer for delayed output of console messages */ 35/* Timer for delayed output of console messages */
41static struct timer_list sclp_con_timer; 36static struct timer_list sclp_con_timer;
37/* Suspend mode flag */
38static int sclp_con_suspended;
39/* Flag that output queue is currently running */
40static int sclp_con_queue_running;
42 41
43/* Output format for console messages */ 42/* Output format for console messages */
44static unsigned short sclp_con_columns; 43static unsigned short sclp_con_columns;
@@ -53,42 +52,71 @@ sclp_conbuf_callback(struct sclp_buffer *buffer, int rc)
53 do { 52 do {
54 page = sclp_unmake_buffer(buffer); 53 page = sclp_unmake_buffer(buffer);
55 spin_lock_irqsave(&sclp_con_lock, flags); 54 spin_lock_irqsave(&sclp_con_lock, flags);
55
56 /* Remove buffer from outqueue */ 56 /* Remove buffer from outqueue */
57 list_del(&buffer->list); 57 list_del(&buffer->list);
58 sclp_con_buffer_count--;
59 list_add_tail((struct list_head *) page, &sclp_con_pages); 58 list_add_tail((struct list_head *) page, &sclp_con_pages);
59
60 /* Check if there is a pending buffer on the out queue. */ 60 /* Check if there is a pending buffer on the out queue. */
61 buffer = NULL; 61 buffer = NULL;
62 if (!list_empty(&sclp_con_outqueue)) 62 if (!list_empty(&sclp_con_outqueue))
63 buffer = list_entry(sclp_con_outqueue.next, 63 buffer = list_first_entry(&sclp_con_outqueue,
64 struct sclp_buffer, list); 64 struct sclp_buffer, list);
65 if (!buffer || sclp_con_suspended) {
66 sclp_con_queue_running = 0;
67 spin_unlock_irqrestore(&sclp_con_lock, flags);
68 break;
69 }
65 spin_unlock_irqrestore(&sclp_con_lock, flags); 70 spin_unlock_irqrestore(&sclp_con_lock, flags);
66 } while (buffer && sclp_emit_buffer(buffer, sclp_conbuf_callback)); 71 } while (sclp_emit_buffer(buffer, sclp_conbuf_callback));
67} 72}
68 73
69static void 74/*
70sclp_conbuf_emit(void) 75 * Finalize and emit first pending buffer.
76 */
77static void sclp_conbuf_emit(void)
71{ 78{
72 struct sclp_buffer* buffer; 79 struct sclp_buffer* buffer;
73 unsigned long flags; 80 unsigned long flags;
74 int count;
75 int rc; 81 int rc;
76 82
77 spin_lock_irqsave(&sclp_con_lock, flags); 83 spin_lock_irqsave(&sclp_con_lock, flags);
78 buffer = sclp_conbuf; 84 if (sclp_conbuf)
85 list_add_tail(&sclp_conbuf->list, &sclp_con_outqueue);
79 sclp_conbuf = NULL; 86 sclp_conbuf = NULL;
80 if (buffer == NULL) { 87 if (sclp_con_queue_running || sclp_con_suspended)
81 spin_unlock_irqrestore(&sclp_con_lock, flags); 88 goto out_unlock;
82 return; 89 if (list_empty(&sclp_con_outqueue))
83 } 90 goto out_unlock;
84 list_add_tail(&buffer->list, &sclp_con_outqueue); 91 buffer = list_first_entry(&sclp_con_outqueue, struct sclp_buffer,
85 count = sclp_con_buffer_count++; 92 list);
93 sclp_con_queue_running = 1;
86 spin_unlock_irqrestore(&sclp_con_lock, flags); 94 spin_unlock_irqrestore(&sclp_con_lock, flags);
87 if (count) 95
88 return;
89 rc = sclp_emit_buffer(buffer, sclp_conbuf_callback); 96 rc = sclp_emit_buffer(buffer, sclp_conbuf_callback);
90 if (rc) 97 if (rc)
91 sclp_conbuf_callback(buffer, rc); 98 sclp_conbuf_callback(buffer, rc);
99 return;
100out_unlock:
101 spin_unlock_irqrestore(&sclp_con_lock, flags);
102}
103
104/*
105 * Wait until out queue is empty
106 */
107static void sclp_console_sync_queue(void)
108{
109 unsigned long flags;
110
111 spin_lock_irqsave(&sclp_con_lock, flags);
112 if (timer_pending(&sclp_con_timer))
113 del_timer_sync(&sclp_con_timer);
114 while (sclp_con_queue_running) {
115 spin_unlock_irqrestore(&sclp_con_lock, flags);
116 sclp_sync_wait();
117 spin_lock_irqsave(&sclp_con_lock, flags);
118 }
119 spin_unlock_irqrestore(&sclp_con_lock, flags);
92} 120}
93 121
94/* 122/*
@@ -123,6 +151,8 @@ sclp_console_write(struct console *console, const char *message,
123 /* make sure we have a console output buffer */ 151 /* make sure we have a console output buffer */
124 if (sclp_conbuf == NULL) { 152 if (sclp_conbuf == NULL) {
125 while (list_empty(&sclp_con_pages)) { 153 while (list_empty(&sclp_con_pages)) {
154 if (sclp_con_suspended)
155 goto out;
126 spin_unlock_irqrestore(&sclp_con_lock, flags); 156 spin_unlock_irqrestore(&sclp_con_lock, flags);
127 sclp_sync_wait(); 157 sclp_sync_wait();
128 spin_lock_irqsave(&sclp_con_lock, flags); 158 spin_lock_irqsave(&sclp_con_lock, flags);
@@ -157,6 +187,7 @@ sclp_console_write(struct console *console, const char *message,
157 sclp_con_timer.expires = jiffies + HZ/10; 187 sclp_con_timer.expires = jiffies + HZ/10;
158 add_timer(&sclp_con_timer); 188 add_timer(&sclp_con_timer);
159 } 189 }
190out:
160 spin_unlock_irqrestore(&sclp_con_lock, flags); 191 spin_unlock_irqrestore(&sclp_con_lock, flags);
161} 192}
162 193
@@ -168,30 +199,43 @@ sclp_console_device(struct console *c, int *index)
168} 199}
169 200
170/* 201/*
171 * This routine is called from panic when the kernel 202 * Make sure that all buffers will be flushed to the SCLP.
172 * is going to give up. We have to make sure that all buffers
173 * will be flushed to the SCLP.
174 */ 203 */
175static void 204static void
176sclp_console_flush(void) 205sclp_console_flush(void)
177{ 206{
207 sclp_conbuf_emit();
208 sclp_console_sync_queue();
209}
210
211/*
212 * Resume console: If there are cached messages, emit them.
213 */
214static void sclp_console_resume(void)
215{
178 unsigned long flags; 216 unsigned long flags;
179 217
218 spin_lock_irqsave(&sclp_con_lock, flags);
219 sclp_con_suspended = 0;
220 spin_unlock_irqrestore(&sclp_con_lock, flags);
180 sclp_conbuf_emit(); 221 sclp_conbuf_emit();
222}
223
224/*
225 * Suspend console: Set suspend flag and flush console
226 */
227static void sclp_console_suspend(void)
228{
229 unsigned long flags;
230
181 spin_lock_irqsave(&sclp_con_lock, flags); 231 spin_lock_irqsave(&sclp_con_lock, flags);
182 if (timer_pending(&sclp_con_timer)) 232 sclp_con_suspended = 1;
183 del_timer(&sclp_con_timer);
184 while (sclp_con_buffer_count > 0) {
185 spin_unlock_irqrestore(&sclp_con_lock, flags);
186 sclp_sync_wait();
187 spin_lock_irqsave(&sclp_con_lock, flags);
188 }
189 spin_unlock_irqrestore(&sclp_con_lock, flags); 233 spin_unlock_irqrestore(&sclp_con_lock, flags);
234 sclp_console_flush();
190} 235}
191 236
192static int 237static int sclp_console_notify(struct notifier_block *self,
193sclp_console_notify(struct notifier_block *self, 238 unsigned long event, void *data)
194 unsigned long event, void *data)
195{ 239{
196 sclp_console_flush(); 240 sclp_console_flush();
197 return NOTIFY_OK; 241 return NOTIFY_OK;
@@ -199,7 +243,7 @@ sclp_console_notify(struct notifier_block *self,
199 243
200static struct notifier_block on_panic_nb = { 244static struct notifier_block on_panic_nb = {
201 .notifier_call = sclp_console_notify, 245 .notifier_call = sclp_console_notify,
202 .priority = 1, 246 .priority = SCLP_PANIC_PRIO_CLIENT,
203}; 247};
204 248
205static struct notifier_block on_reboot_nb = { 249static struct notifier_block on_reboot_nb = {
@@ -221,6 +265,22 @@ static struct console sclp_console =
221}; 265};
222 266
223/* 267/*
268 * This function is called for SCLP suspend and resume events.
269 */
270void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event)
271{
272 switch (sclp_pm_event) {
273 case SCLP_PM_EVENT_FREEZE:
274 sclp_console_suspend();
275 break;
276 case SCLP_PM_EVENT_RESTORE:
277 case SCLP_PM_EVENT_THAW:
278 sclp_console_resume();
279 break;
280 }
281}
282
283/*
224 * called by console_init() in drivers/char/tty_io.c at boot-time. 284 * called by console_init() in drivers/char/tty_io.c at boot-time.
225 */ 285 */
226static int __init 286static int __init
@@ -243,7 +303,6 @@ sclp_console_init(void)
243 } 303 }
244 INIT_LIST_HEAD(&sclp_con_outqueue); 304 INIT_LIST_HEAD(&sclp_con_outqueue);
245 spin_lock_init(&sclp_con_lock); 305 spin_lock_init(&sclp_con_lock);
246 sclp_con_buffer_count = 0;
247 sclp_conbuf = NULL; 306 sclp_conbuf = NULL;
248 init_timer(&sclp_con_timer); 307 init_timer(&sclp_con_timer);
249 308
diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c
index 710af42603f8..4be63be73445 100644
--- a/drivers/s390/char/sclp_rw.c
+++ b/drivers/s390/char/sclp_rw.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/sclp_rw.c 2 * driver: reading from and writing to system console on S/390 via SCLP
3 * driver: reading from and writing to system console on S/390 via SCLP
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 1999, 2009
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 *
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
9 */ 8 */
10 9
11#include <linux/kmod.h> 10#include <linux/kmod.h>
@@ -26,9 +25,16 @@
26 */ 25 */
27#define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer)) 26#define MAX_SCCB_ROOM (PAGE_SIZE - sizeof(struct sclp_buffer))
28 27
28static void sclp_rw_pm_event(struct sclp_register *reg,
29 enum sclp_pm_event sclp_pm_event)
30{
31 sclp_console_pm_event(sclp_pm_event);
32}
33
29/* Event type structure for write message and write priority message */ 34/* Event type structure for write message and write priority message */
30static struct sclp_register sclp_rw_event = { 35static struct sclp_register sclp_rw_event = {
31 .send_mask = EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK 36 .send_mask = EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK,
37 .pm_event_fn = sclp_rw_pm_event,
32}; 38};
33 39
34/* 40/*
diff --git a/drivers/s390/char/sclp_rw.h b/drivers/s390/char/sclp_rw.h
index 6aa7a6948bc9..85f491ea929c 100644
--- a/drivers/s390/char/sclp_rw.h
+++ b/drivers/s390/char/sclp_rw.h
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/char/sclp_rw.h 2 * interface to the SCLP-read/write driver
3 * interface to the SCLP-read/write driver
4 * 3 *
5 * S390 version 4 * Copyright IBM Corporation 1999, 2009
6 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 *
7 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 6 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 * Martin Schwidefsky <schwidefsky@de.ibm.com>
9 */ 8 */
10 9
11#ifndef __SCLP_RW_H__ 10#ifndef __SCLP_RW_H__
@@ -93,4 +92,5 @@ void sclp_set_columns(struct sclp_buffer *, unsigned short);
93void sclp_set_htab(struct sclp_buffer *, unsigned short); 92void sclp_set_htab(struct sclp_buffer *, unsigned short);
94int sclp_chars_in_buffer(struct sclp_buffer *); 93int sclp_chars_in_buffer(struct sclp_buffer *);
95 94
95void sclp_console_pm_event(enum sclp_pm_event sclp_pm_event);
96#endif /* __SCLP_RW_H__ */ 96#endif /* __SCLP_RW_H__ */
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index a839aa531d7c..5518e24946aa 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -1,10 +1,9 @@
1/* 1/*
2 * drivers/s390/char/sclp_vt220.c 2 * SCLP VT220 terminal driver.
3 * SCLP VT220 terminal driver.
4 * 3 *
5 * S390 version 4 * Copyright IBM Corp. 2003, 2009
6 * Copyright IBM Corp. 2003,2008 5 *
7 * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com> 6 * Author(s): Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>
8 */ 7 */
9 8
10#include <linux/module.h> 9#include <linux/module.h>
@@ -69,8 +68,11 @@ static struct list_head sclp_vt220_empty;
69/* List of pending requests */ 68/* List of pending requests */
70static struct list_head sclp_vt220_outqueue; 69static struct list_head sclp_vt220_outqueue;
71 70
72/* Number of requests in outqueue */ 71/* Suspend mode flag */
73static int sclp_vt220_outqueue_count; 72static int sclp_vt220_suspended;
73
74/* Flag that output queue is currently running */
75static int sclp_vt220_queue_running;
74 76
75/* Timer used for delaying write requests to merge subsequent messages into 77/* Timer used for delaying write requests to merge subsequent messages into
76 * a single buffer */ 78 * a single buffer */
@@ -92,6 +94,8 @@ static int __initdata sclp_vt220_init_count;
92static int sclp_vt220_flush_later; 94static int sclp_vt220_flush_later;
93 95
94static void sclp_vt220_receiver_fn(struct evbuf_header *evbuf); 96static void sclp_vt220_receiver_fn(struct evbuf_header *evbuf);
97static void sclp_vt220_pm_event_fn(struct sclp_register *reg,
98 enum sclp_pm_event sclp_pm_event);
95static int __sclp_vt220_emit(struct sclp_vt220_request *request); 99static int __sclp_vt220_emit(struct sclp_vt220_request *request);
96static void sclp_vt220_emit_current(void); 100static void sclp_vt220_emit_current(void);
97 101
@@ -100,7 +104,8 @@ static struct sclp_register sclp_vt220_register = {
100 .send_mask = EVTYP_VT220MSG_MASK, 104 .send_mask = EVTYP_VT220MSG_MASK,
101 .receive_mask = EVTYP_VT220MSG_MASK, 105 .receive_mask = EVTYP_VT220MSG_MASK,
102 .state_change_fn = NULL, 106 .state_change_fn = NULL,
103 .receiver_fn = sclp_vt220_receiver_fn 107 .receiver_fn = sclp_vt220_receiver_fn,
108 .pm_event_fn = sclp_vt220_pm_event_fn,
104}; 109};
105 110
106 111
@@ -120,15 +125,19 @@ sclp_vt220_process_queue(struct sclp_vt220_request *request)
120 spin_lock_irqsave(&sclp_vt220_lock, flags); 125 spin_lock_irqsave(&sclp_vt220_lock, flags);
121 /* Move request from outqueue to empty queue */ 126 /* Move request from outqueue to empty queue */
122 list_del(&request->list); 127 list_del(&request->list);
123 sclp_vt220_outqueue_count--;
124 list_add_tail((struct list_head *) page, &sclp_vt220_empty); 128 list_add_tail((struct list_head *) page, &sclp_vt220_empty);
125 /* Check if there is a pending buffer on the out queue. */ 129 /* Check if there is a pending buffer on the out queue. */
126 request = NULL; 130 request = NULL;
127 if (!list_empty(&sclp_vt220_outqueue)) 131 if (!list_empty(&sclp_vt220_outqueue))
128 request = list_entry(sclp_vt220_outqueue.next, 132 request = list_entry(sclp_vt220_outqueue.next,
129 struct sclp_vt220_request, list); 133 struct sclp_vt220_request, list);
134 if (!request || sclp_vt220_suspended) {
135 sclp_vt220_queue_running = 0;
136 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
137 break;
138 }
130 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 139 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
131 } while (request && __sclp_vt220_emit(request)); 140 } while (__sclp_vt220_emit(request));
132 if (request == NULL && sclp_vt220_flush_later) 141 if (request == NULL && sclp_vt220_flush_later)
133 sclp_vt220_emit_current(); 142 sclp_vt220_emit_current();
134 /* Check if the tty needs a wake up call */ 143 /* Check if the tty needs a wake up call */
@@ -212,26 +221,7 @@ __sclp_vt220_emit(struct sclp_vt220_request *request)
212} 221}
213 222
214/* 223/*
215 * Queue and emit given request. 224 * Queue and emit current request.
216 */
217static void
218sclp_vt220_emit(struct sclp_vt220_request *request)
219{
220 unsigned long flags;
221 int count;
222
223 spin_lock_irqsave(&sclp_vt220_lock, flags);
224 list_add_tail(&request->list, &sclp_vt220_outqueue);
225 count = sclp_vt220_outqueue_count++;
226 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
227 /* Emit only the first buffer immediately - callback takes care of
228 * the rest */
229 if (count == 0 && __sclp_vt220_emit(request))
230 sclp_vt220_process_queue(request);
231}
232
233/*
234 * Queue and emit current request. Return zero on success, non-zero otherwise.
235 */ 225 */
236static void 226static void
237sclp_vt220_emit_current(void) 227sclp_vt220_emit_current(void)
@@ -241,22 +231,33 @@ sclp_vt220_emit_current(void)
241 struct sclp_vt220_sccb *sccb; 231 struct sclp_vt220_sccb *sccb;
242 232
243 spin_lock_irqsave(&sclp_vt220_lock, flags); 233 spin_lock_irqsave(&sclp_vt220_lock, flags);
244 request = NULL; 234 if (sclp_vt220_current_request) {
245 if (sclp_vt220_current_request != NULL) {
246 sccb = (struct sclp_vt220_sccb *) 235 sccb = (struct sclp_vt220_sccb *)
247 sclp_vt220_current_request->sclp_req.sccb; 236 sclp_vt220_current_request->sclp_req.sccb;
248 /* Only emit buffers with content */ 237 /* Only emit buffers with content */
249 if (sccb->header.length != sizeof(struct sclp_vt220_sccb)) { 238 if (sccb->header.length != sizeof(struct sclp_vt220_sccb)) {
250 request = sclp_vt220_current_request; 239 list_add_tail(&sclp_vt220_current_request->list,
240 &sclp_vt220_outqueue);
251 sclp_vt220_current_request = NULL; 241 sclp_vt220_current_request = NULL;
252 if (timer_pending(&sclp_vt220_timer)) 242 if (timer_pending(&sclp_vt220_timer))
253 del_timer(&sclp_vt220_timer); 243 del_timer(&sclp_vt220_timer);
254 } 244 }
255 sclp_vt220_flush_later = 0; 245 sclp_vt220_flush_later = 0;
256 } 246 }
247 if (sclp_vt220_queue_running || sclp_vt220_suspended)
248 goto out_unlock;
249 if (list_empty(&sclp_vt220_outqueue))
250 goto out_unlock;
251 request = list_first_entry(&sclp_vt220_outqueue,
252 struct sclp_vt220_request, list);
253 sclp_vt220_queue_running = 1;
254 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
255
256 if (__sclp_vt220_emit(request))
257 sclp_vt220_process_queue(request);
258 return;
259out_unlock:
257 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 260 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
258 if (request != NULL)
259 sclp_vt220_emit(request);
260} 261}
261 262
262#define SCLP_NORMAL_WRITE 0x00 263#define SCLP_NORMAL_WRITE 0x00
@@ -396,7 +397,7 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule,
396 if (sclp_vt220_current_request == NULL) { 397 if (sclp_vt220_current_request == NULL) {
397 while (list_empty(&sclp_vt220_empty)) { 398 while (list_empty(&sclp_vt220_empty)) {
398 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 399 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
399 if (may_fail) 400 if (may_fail || sclp_vt220_suspended)
400 goto out; 401 goto out;
401 else 402 else
402 sclp_sync_wait(); 403 sclp_sync_wait();
@@ -531,7 +532,7 @@ sclp_vt220_put_char(struct tty_struct *tty, unsigned char ch)
531static void 532static void
532sclp_vt220_flush_chars(struct tty_struct *tty) 533sclp_vt220_flush_chars(struct tty_struct *tty)
533{ 534{
534 if (sclp_vt220_outqueue_count == 0) 535 if (!sclp_vt220_queue_running)
535 sclp_vt220_emit_current(); 536 sclp_vt220_emit_current();
536 else 537 else
537 sclp_vt220_flush_later = 1; 538 sclp_vt220_flush_later = 1;
@@ -635,7 +636,6 @@ static int __init __sclp_vt220_init(int num_pages)
635 init_timer(&sclp_vt220_timer); 636 init_timer(&sclp_vt220_timer);
636 sclp_vt220_current_request = NULL; 637 sclp_vt220_current_request = NULL;
637 sclp_vt220_buffered_chars = 0; 638 sclp_vt220_buffered_chars = 0;
638 sclp_vt220_outqueue_count = 0;
639 sclp_vt220_tty = NULL; 639 sclp_vt220_tty = NULL;
640 sclp_vt220_flush_later = 0; 640 sclp_vt220_flush_later = 0;
641 641
@@ -736,7 +736,7 @@ static void __sclp_vt220_flush_buffer(void)
736 spin_lock_irqsave(&sclp_vt220_lock, flags); 736 spin_lock_irqsave(&sclp_vt220_lock, flags);
737 if (timer_pending(&sclp_vt220_timer)) 737 if (timer_pending(&sclp_vt220_timer))
738 del_timer(&sclp_vt220_timer); 738 del_timer(&sclp_vt220_timer);
739 while (sclp_vt220_outqueue_count > 0) { 739 while (sclp_vt220_queue_running) {
740 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 740 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
741 sclp_sync_wait(); 741 sclp_sync_wait();
742 spin_lock_irqsave(&sclp_vt220_lock, flags); 742 spin_lock_irqsave(&sclp_vt220_lock, flags);
@@ -744,6 +744,46 @@ static void __sclp_vt220_flush_buffer(void)
744 spin_unlock_irqrestore(&sclp_vt220_lock, flags); 744 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
745} 745}
746 746
747/*
748 * Resume console: If there are cached messages, emit them.
749 */
750static void sclp_vt220_resume(void)
751{
752 unsigned long flags;
753
754 spin_lock_irqsave(&sclp_vt220_lock, flags);
755 sclp_vt220_suspended = 0;
756 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
757 sclp_vt220_emit_current();
758}
759
760/*
761 * Suspend console: Set suspend flag and flush console
762 */
763static void sclp_vt220_suspend(void)
764{
765 unsigned long flags;
766
767 spin_lock_irqsave(&sclp_vt220_lock, flags);
768 sclp_vt220_suspended = 1;
769 spin_unlock_irqrestore(&sclp_vt220_lock, flags);
770 __sclp_vt220_flush_buffer();
771}
772
773static void sclp_vt220_pm_event_fn(struct sclp_register *reg,
774 enum sclp_pm_event sclp_pm_event)
775{
776 switch (sclp_pm_event) {
777 case SCLP_PM_EVENT_FREEZE:
778 sclp_vt220_suspend();
779 break;
780 case SCLP_PM_EVENT_RESTORE:
781 case SCLP_PM_EVENT_THAW:
782 sclp_vt220_resume();
783 break;
784 }
785}
786
747static int 787static int
748sclp_vt220_notify(struct notifier_block *self, 788sclp_vt220_notify(struct notifier_block *self,
749 unsigned long event, void *data) 789 unsigned long event, void *data)
diff --git a/drivers/s390/char/tape.h b/drivers/s390/char/tape.h
index 5469e099597e..a26333774701 100644
--- a/drivers/s390/char/tape.h
+++ b/drivers/s390/char/tape.h
@@ -3,7 +3,7 @@
3 * tape device driver for 3480/3490E/3590 tapes. 3 * tape device driver for 3480/3490E/3590 tapes.
4 * 4 *
5 * S390 and zSeries version 5 * S390 and zSeries version
6 * Copyright IBM Corp. 2001,2006 6 * Copyright IBM Corp. 2001, 2009
7 * Author(s): Carsten Otte <cotte@de.ibm.com> 7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 8 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
9 * Martin Schwidefsky <schwidefsky@de.ibm.com> 9 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -286,6 +286,7 @@ extern void tape_state_set(struct tape_device *, enum tape_state);
286 286
287extern int tape_generic_online(struct tape_device *, struct tape_discipline *); 287extern int tape_generic_online(struct tape_device *, struct tape_discipline *);
288extern int tape_generic_offline(struct ccw_device *); 288extern int tape_generic_offline(struct ccw_device *);
289extern int tape_generic_pm_suspend(struct ccw_device *);
289 290
290/* Externals from tape_devmap.c */ 291/* Externals from tape_devmap.c */
291extern int tape_generic_probe(struct ccw_device *); 292extern int tape_generic_probe(struct ccw_device *);
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c
index 2d00a383a475..144d2a5e1a92 100644
--- a/drivers/s390/char/tape_34xx.c
+++ b/drivers/s390/char/tape_34xx.c
@@ -2,7 +2,7 @@
2 * drivers/s390/char/tape_34xx.c 2 * drivers/s390/char/tape_34xx.c
3 * tape device discipline for 3480/3490 tapes. 3 * tape device discipline for 3480/3490 tapes.
4 * 4 *
5 * Copyright (C) IBM Corp. 2001,2006 5 * Copyright IBM Corp. 2001, 2009
6 * Author(s): Carsten Otte <cotte@de.ibm.com> 6 * Author(s): Carsten Otte <cotte@de.ibm.com>
7 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 7 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 8 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -1302,6 +1302,7 @@ static struct ccw_driver tape_34xx_driver = {
1302 .remove = tape_generic_remove, 1302 .remove = tape_generic_remove,
1303 .set_online = tape_34xx_online, 1303 .set_online = tape_34xx_online,
1304 .set_offline = tape_generic_offline, 1304 .set_offline = tape_generic_offline,
1305 .freeze = tape_generic_pm_suspend,
1305}; 1306};
1306 1307
1307static int 1308static int
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c
index c453b2f3e9f4..23e6598bc4b5 100644
--- a/drivers/s390/char/tape_3590.c
+++ b/drivers/s390/char/tape_3590.c
@@ -2,7 +2,7 @@
2 * drivers/s390/char/tape_3590.c 2 * drivers/s390/char/tape_3590.c
3 * tape device discipline for 3590 tapes. 3 * tape device discipline for 3590 tapes.
4 * 4 *
5 * Copyright IBM Corp. 2001,2006 5 * Copyright IBM Corp. 2001, 2009
6 * Author(s): Stefan Bader <shbader@de.ibm.com> 6 * Author(s): Stefan Bader <shbader@de.ibm.com>
7 * Michael Holzheu <holzheu@de.ibm.com> 7 * Michael Holzheu <holzheu@de.ibm.com>
8 * Martin Schwidefsky <schwidefsky@de.ibm.com> 8 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -1715,6 +1715,7 @@ static struct ccw_driver tape_3590_driver = {
1715 .remove = tape_generic_remove, 1715 .remove = tape_generic_remove,
1716 .set_offline = tape_generic_offline, 1716 .set_offline = tape_generic_offline,
1717 .set_online = tape_3590_online, 1717 .set_online = tape_3590_online,
1718 .freeze = tape_generic_pm_suspend,
1718}; 1719};
1719 1720
1720/* 1721/*
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c
index 8a109f3b69c6..3ebaa8eb5c86 100644
--- a/drivers/s390/char/tape_core.c
+++ b/drivers/s390/char/tape_core.c
@@ -3,7 +3,7 @@
3 * basic function of the tape device driver 3 * basic function of the tape device driver
4 * 4 *
5 * S390 and zSeries version 5 * S390 and zSeries version
6 * Copyright IBM Corp. 2001,2006 6 * Copyright IBM Corp. 2001, 2009
7 * Author(s): Carsten Otte <cotte@de.ibm.com> 7 * Author(s): Carsten Otte <cotte@de.ibm.com>
8 * Michael Holzheu <holzheu@de.ibm.com> 8 * Michael Holzheu <holzheu@de.ibm.com>
9 * Tuan Ngo-Anh <ngoanh@de.ibm.com> 9 * Tuan Ngo-Anh <ngoanh@de.ibm.com>
@@ -380,6 +380,55 @@ tape_cleanup_device(struct tape_device *device)
380} 380}
381 381
382/* 382/*
383 * Suspend device.
384 *
385 * Called by the common I/O layer if the drive should be suspended on user
386 * request. We refuse to suspend if the device is loaded or in use for the
387 * following reason:
388 * While the Linux guest is suspended, it might be logged off which causes
389 * devices to be detached. Tape devices are automatically rewound and unloaded
390 * during DETACH processing (unless the tape device was attached with the
391 * NOASSIGN or MULTIUSER option). After rewind/unload, there is no way to
392 * resume the original state of the tape device, since we would need to
393 * manually re-load the cartridge which was active at suspend time.
394 */
395int tape_generic_pm_suspend(struct ccw_device *cdev)
396{
397 struct tape_device *device;
398
399 device = cdev->dev.driver_data;
400 if (!device) {
401 return -ENODEV;
402 }
403
404 DBF_LH(3, "(%08x): tape_generic_pm_suspend(%p)\n",
405 device->cdev_id, device);
406
407 if (device->medium_state != MS_UNLOADED) {
408 pr_err("A cartridge is loaded in tape device %s, "
409 "refusing to suspend\n", dev_name(&cdev->dev));
410 return -EBUSY;
411 }
412
413 spin_lock_irq(get_ccwdev_lock(device->cdev));
414 switch (device->tape_state) {
415 case TS_INIT:
416 case TS_NOT_OPER:
417 case TS_UNUSED:
418 spin_unlock_irq(get_ccwdev_lock(device->cdev));
419 break;
420 default:
421 pr_err("Tape device %s is busy, refusing to "
422 "suspend\n", dev_name(&cdev->dev));
423 spin_unlock_irq(get_ccwdev_lock(device->cdev));
424 return -EBUSY;
425 }
426
427 DBF_LH(3, "(%08x): Drive suspended.\n", device->cdev_id);
428 return 0;
429}
430
431/*
383 * Set device offline. 432 * Set device offline.
384 * 433 *
385 * Called by the common I/O layer if the drive should set offline on user 434 * Called by the common I/O layer if the drive should set offline on user
@@ -1273,6 +1322,7 @@ EXPORT_SYMBOL(tape_generic_remove);
1273EXPORT_SYMBOL(tape_generic_probe); 1322EXPORT_SYMBOL(tape_generic_probe);
1274EXPORT_SYMBOL(tape_generic_online); 1323EXPORT_SYMBOL(tape_generic_online);
1275EXPORT_SYMBOL(tape_generic_offline); 1324EXPORT_SYMBOL(tape_generic_offline);
1325EXPORT_SYMBOL(tape_generic_pm_suspend);
1276EXPORT_SYMBOL(tape_put_device); 1326EXPORT_SYMBOL(tape_put_device);
1277EXPORT_SYMBOL(tape_get_device_reference); 1327EXPORT_SYMBOL(tape_get_device_reference);
1278EXPORT_SYMBOL(tape_state_verbose); 1328EXPORT_SYMBOL(tape_state_verbose);
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index d8a2289fcb69..e925808c2149 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -3,7 +3,7 @@
3 * character device driver for reading z/VM system service records 3 * character device driver for reading z/VM system service records
4 * 4 *
5 * 5 *
6 * Copyright 2004 IBM Corporation 6 * Copyright IBM Corp. 2004, 2009
7 * character device driver for reading z/VM system service records, 7 * character device driver for reading z/VM system service records,
8 * Version 1.0 8 * Version 1.0
9 * Author(s): Xenia Tkatschow <xenia@us.ibm.com> 9 * Author(s): Xenia Tkatschow <xenia@us.ibm.com>
@@ -660,6 +660,29 @@ static struct attribute *vmlogrdr_attrs[] = {
660 NULL, 660 NULL,
661}; 661};
662 662
663static int vmlogrdr_pm_prepare(struct device *dev)
664{
665 int rc;
666 struct vmlogrdr_priv_t *priv = dev->driver_data;
667
668 rc = 0;
669 if (priv) {
670 spin_lock_bh(&priv->priv_lock);
671 if (priv->dev_in_use)
672 rc = -EBUSY;
673 spin_unlock_bh(&priv->priv_lock);
674 }
675 if (rc)
676 pr_err("vmlogrdr: device %s is busy. Refuse to suspend.\n",
677 dev_name(dev));
678 return rc;
679}
680
681
682static struct dev_pm_ops vmlogrdr_pm_ops = {
683 .prepare = vmlogrdr_pm_prepare,
684};
685
663static struct attribute_group vmlogrdr_attr_group = { 686static struct attribute_group vmlogrdr_attr_group = {
664 .attrs = vmlogrdr_attrs, 687 .attrs = vmlogrdr_attrs,
665}; 688};
@@ -668,6 +691,7 @@ static struct class *vmlogrdr_class;
668static struct device_driver vmlogrdr_driver = { 691static struct device_driver vmlogrdr_driver = {
669 .name = "vmlogrdr", 692 .name = "vmlogrdr",
670 .bus = &iucv_bus, 693 .bus = &iucv_bus,
694 .pm = &vmlogrdr_pm_ops,
671}; 695};
672 696
673 697
@@ -729,6 +753,7 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
729 dev->bus = &iucv_bus; 753 dev->bus = &iucv_bus;
730 dev->parent = iucv_root; 754 dev->parent = iucv_root;
731 dev->driver = &vmlogrdr_driver; 755 dev->driver = &vmlogrdr_driver;
756 dev->driver_data = priv;
732 /* 757 /*
733 * The release function could be called after the 758 * The release function could be called after the
734 * module has been unloaded. It's _only_ task is to 759 * module has been unloaded. It's _only_ task is to
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 5dcef81fc9d9..92458219a9e9 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -2,7 +2,7 @@
2 * Linux driver for System z and s390 unit record devices 2 * Linux driver for System z and s390 unit record devices
3 * (z/VM virtual punch, reader, printer) 3 * (z/VM virtual punch, reader, printer)
4 * 4 *
5 * Copyright IBM Corp. 2001, 2007 5 * Copyright IBM Corp. 2001, 2009
6 * Authors: Malcolm Beattie <beattiem@uk.ibm.com> 6 * Authors: Malcolm Beattie <beattiem@uk.ibm.com>
7 * Michael Holzheu <holzheu@de.ibm.com> 7 * Michael Holzheu <holzheu@de.ibm.com>
8 * Frank Munzert <munzert@de.ibm.com> 8 * Frank Munzert <munzert@de.ibm.com>
@@ -60,6 +60,7 @@ static int ur_probe(struct ccw_device *cdev);
60static void ur_remove(struct ccw_device *cdev); 60static void ur_remove(struct ccw_device *cdev);
61static int ur_set_online(struct ccw_device *cdev); 61static int ur_set_online(struct ccw_device *cdev);
62static int ur_set_offline(struct ccw_device *cdev); 62static int ur_set_offline(struct ccw_device *cdev);
63static int ur_pm_suspend(struct ccw_device *cdev);
63 64
64static struct ccw_driver ur_driver = { 65static struct ccw_driver ur_driver = {
65 .name = "vmur", 66 .name = "vmur",
@@ -69,6 +70,7 @@ static struct ccw_driver ur_driver = {
69 .remove = ur_remove, 70 .remove = ur_remove,
70 .set_online = ur_set_online, 71 .set_online = ur_set_online,
71 .set_offline = ur_set_offline, 72 .set_offline = ur_set_offline,
73 .freeze = ur_pm_suspend,
72}; 74};
73 75
74static DEFINE_MUTEX(vmur_mutex); 76static DEFINE_MUTEX(vmur_mutex);
@@ -158,6 +160,28 @@ static void urdev_put(struct urdev *urd)
158} 160}
159 161
160/* 162/*
163 * State and contents of ur devices can be changed by class D users issuing
164 * CP commands such as PURGE or TRANSFER, while the Linux guest is suspended.
165 * Also the Linux guest might be logged off, which causes all active spool
166 * files to be closed.
167 * So we cannot guarantee that spool files are still the same when the Linux
168 * guest is resumed. In order to avoid unpredictable results at resume time
169 * we simply refuse to suspend if a ur device node is open.
170 */
171static int ur_pm_suspend(struct ccw_device *cdev)
172{
173 struct urdev *urd = cdev->dev.driver_data;
174
175 TRACE("ur_pm_suspend: cdev=%p\n", cdev);
176 if (urd->open_flag) {
177 pr_err("Unit record device %s is busy, %s refusing to "
178 "suspend.\n", dev_name(&cdev->dev), ur_banner);
179 return -EBUSY;
180 }
181 return 0;
182}
183
184/*
161 * Low-level functions to do I/O to a ur device. 185 * Low-level functions to do I/O to a ur device.
162 * alloc_chan_prog 186 * alloc_chan_prog
163 * free_chan_prog 187 * free_chan_prog
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index 21a2a829bf4e..cb7854c10c04 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -1,17 +1,23 @@
1/* 1/*
2 * Watchdog implementation based on z/VM Watchdog Timer API 2 * Watchdog implementation based on z/VM Watchdog Timer API
3 * 3 *
4 * Copyright IBM Corp. 2004,2009
5 *
4 * The user space watchdog daemon can use this driver as 6 * The user space watchdog daemon can use this driver as
5 * /dev/vmwatchdog to have z/VM execute the specified CP 7 * /dev/vmwatchdog to have z/VM execute the specified CP
6 * command when the timeout expires. The default command is 8 * command when the timeout expires. The default command is
7 * "IPL", which which cause an immediate reboot. 9 * "IPL", which which cause an immediate reboot.
8 */ 10 */
11#define KMSG_COMPONENT "vmwatchdog"
12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
13
9#include <linux/init.h> 14#include <linux/init.h>
10#include <linux/fs.h> 15#include <linux/fs.h>
11#include <linux/kernel.h> 16#include <linux/kernel.h>
12#include <linux/miscdevice.h> 17#include <linux/miscdevice.h>
13#include <linux/module.h> 18#include <linux/module.h>
14#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/suspend.h>
15#include <linux/watchdog.h> 21#include <linux/watchdog.h>
16#include <linux/smp_lock.h> 22#include <linux/smp_lock.h>
17 23
@@ -43,6 +49,9 @@ static unsigned int vmwdt_interval = 60;
43static unsigned long vmwdt_is_open; 49static unsigned long vmwdt_is_open;
44static int vmwdt_expect_close; 50static int vmwdt_expect_close;
45 51
52#define VMWDT_OPEN 0 /* devnode is open or suspend in progress */
53#define VMWDT_RUNNING 1 /* The watchdog is armed */
54
46enum vmwdt_func { 55enum vmwdt_func {
47 /* function codes */ 56 /* function codes */
48 wdt_init = 0, 57 wdt_init = 0,
@@ -92,6 +101,7 @@ static int vmwdt_keepalive(void)
92 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN); 101 EBC_TOUPPER(ebc_cmd, MAX_CMDLEN);
93 102
94 func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init; 103 func = vmwdt_conceal ? (wdt_init | wdt_conceal) : wdt_init;
104 set_bit(VMWDT_RUNNING, &vmwdt_is_open);
95 ret = __diag288(func, vmwdt_interval, ebc_cmd, len); 105 ret = __diag288(func, vmwdt_interval, ebc_cmd, len);
96 WARN_ON(ret != 0); 106 WARN_ON(ret != 0);
97 kfree(ebc_cmd); 107 kfree(ebc_cmd);
@@ -102,6 +112,7 @@ static int vmwdt_disable(void)
102{ 112{
103 int ret = __diag288(wdt_cancel, 0, "", 0); 113 int ret = __diag288(wdt_cancel, 0, "", 0);
104 WARN_ON(ret != 0); 114 WARN_ON(ret != 0);
115 clear_bit(VMWDT_RUNNING, &vmwdt_is_open);
105 return ret; 116 return ret;
106} 117}
107 118
@@ -123,13 +134,13 @@ static int vmwdt_open(struct inode *i, struct file *f)
123{ 134{
124 int ret; 135 int ret;
125 lock_kernel(); 136 lock_kernel();
126 if (test_and_set_bit(0, &vmwdt_is_open)) { 137 if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
127 unlock_kernel(); 138 unlock_kernel();
128 return -EBUSY; 139 return -EBUSY;
129 } 140 }
130 ret = vmwdt_keepalive(); 141 ret = vmwdt_keepalive();
131 if (ret) 142 if (ret)
132 clear_bit(0, &vmwdt_is_open); 143 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
133 unlock_kernel(); 144 unlock_kernel();
134 return ret ? ret : nonseekable_open(i, f); 145 return ret ? ret : nonseekable_open(i, f);
135} 146}
@@ -139,7 +150,7 @@ static int vmwdt_close(struct inode *i, struct file *f)
139 if (vmwdt_expect_close == 42) 150 if (vmwdt_expect_close == 42)
140 vmwdt_disable(); 151 vmwdt_disable();
141 vmwdt_expect_close = 0; 152 vmwdt_expect_close = 0;
142 clear_bit(0, &vmwdt_is_open); 153 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
143 return 0; 154 return 0;
144} 155}
145 156
@@ -223,6 +234,57 @@ static ssize_t vmwdt_write(struct file *f, const char __user *buf,
223 return count; 234 return count;
224} 235}
225 236
237static int vmwdt_resume(void)
238{
239 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
240 return NOTIFY_DONE;
241}
242
243/*
244 * It makes no sense to go into suspend while the watchdog is running.
245 * Depending on the memory size, the watchdog might trigger, while we
246 * are still saving the memory.
247 * We reuse the open flag to ensure that suspend and watchdog open are
248 * exclusive operations
249 */
250static int vmwdt_suspend(void)
251{
252 if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) {
253 pr_err("The watchdog is in use. "
254 "This prevents hibernation or suspend.\n");
255 return NOTIFY_BAD;
256 }
257 if (test_bit(VMWDT_RUNNING, &vmwdt_is_open)) {
258 clear_bit(VMWDT_OPEN, &vmwdt_is_open);
259 pr_err("The watchdog is running. "
260 "This prevents hibernation or suspend.\n");
261 return NOTIFY_BAD;
262 }
263 return NOTIFY_DONE;
264}
265
266/*
267 * This function is called for suspend and resume.
268 */
269static int vmwdt_power_event(struct notifier_block *this, unsigned long event,
270 void *ptr)
271{
272 switch (event) {
273 case PM_POST_HIBERNATION:
274 case PM_POST_SUSPEND:
275 return vmwdt_resume();
276 case PM_HIBERNATION_PREPARE:
277 case PM_SUSPEND_PREPARE:
278 return vmwdt_suspend();
279 default:
280 return NOTIFY_DONE;
281 }
282}
283
284static struct notifier_block vmwdt_power_notifier = {
285 .notifier_call = vmwdt_power_event,
286};
287
226static const struct file_operations vmwdt_fops = { 288static const struct file_operations vmwdt_fops = {
227 .open = &vmwdt_open, 289 .open = &vmwdt_open,
228 .release = &vmwdt_close, 290 .release = &vmwdt_close,
@@ -244,12 +306,21 @@ static int __init vmwdt_init(void)
244 ret = vmwdt_probe(); 306 ret = vmwdt_probe();
245 if (ret) 307 if (ret)
246 return ret; 308 return ret;
247 return misc_register(&vmwdt_dev); 309 ret = register_pm_notifier(&vmwdt_power_notifier);
310 if (ret)
311 return ret;
312 ret = misc_register(&vmwdt_dev);
313 if (ret) {
314 unregister_pm_notifier(&vmwdt_power_notifier);
315 return ret;
316 }
317 return 0;
248} 318}
249module_init(vmwdt_init); 319module_init(vmwdt_init);
250 320
251static void __exit vmwdt_exit(void) 321static void __exit vmwdt_exit(void)
252{ 322{
253 WARN_ON(misc_deregister(&vmwdt_dev) != 0); 323 unregister_pm_notifier(&vmwdt_power_notifier);
324 misc_deregister(&vmwdt_dev);
254} 325}
255module_exit(vmwdt_exit); 326module_exit(vmwdt_exit);
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 22ce765d537e..a5a62f1f7747 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -1,11 +1,10 @@
1/* 1/*
2 * drivers/s390/cio/ccwgroup.c
3 * bus driver for ccwgroup 2 * bus driver for ccwgroup
4 * 3 *
5 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, 4 * Copyright IBM Corp. 2002, 2009
6 * IBM Corporation 5 *
7 * Author(s): Arnd Bergmann (arndb@de.ibm.com) 6 * Author(s): Arnd Bergmann (arndb@de.ibm.com)
8 * Cornelia Huck (cornelia.huck@de.ibm.com) 7 * Cornelia Huck (cornelia.huck@de.ibm.com)
9 */ 8 */
10#include <linux/module.h> 9#include <linux/module.h>
11#include <linux/errno.h> 10#include <linux/errno.h>
@@ -501,6 +500,74 @@ static void ccwgroup_shutdown(struct device *dev)
501 gdrv->shutdown(gdev); 500 gdrv->shutdown(gdev);
502} 501}
503 502
503static int ccwgroup_pm_prepare(struct device *dev)
504{
505 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
506 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
507
508 /* Fail while device is being set online/offline. */
509 if (atomic_read(&gdev->onoff))
510 return -EAGAIN;
511
512 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
513 return 0;
514
515 return gdrv->prepare ? gdrv->prepare(gdev) : 0;
516}
517
518static void ccwgroup_pm_complete(struct device *dev)
519{
520 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
521 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(dev->driver);
522
523 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
524 return;
525
526 if (gdrv->complete)
527 gdrv->complete(gdev);
528}
529
530static int ccwgroup_pm_freeze(struct device *dev)
531{
532 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
533 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
534
535 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
536 return 0;
537
538 return gdrv->freeze ? gdrv->freeze(gdev) : 0;
539}
540
541static int ccwgroup_pm_thaw(struct device *dev)
542{
543 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
544 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
545
546 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
547 return 0;
548
549 return gdrv->thaw ? gdrv->thaw(gdev) : 0;
550}
551
552static int ccwgroup_pm_restore(struct device *dev)
553{
554 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
555 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
556
557 if (!gdev->dev.driver || gdev->state != CCWGROUP_ONLINE)
558 return 0;
559
560 return gdrv->restore ? gdrv->restore(gdev) : 0;
561}
562
563static struct dev_pm_ops ccwgroup_pm_ops = {
564 .prepare = ccwgroup_pm_prepare,
565 .complete = ccwgroup_pm_complete,
566 .freeze = ccwgroup_pm_freeze,
567 .thaw = ccwgroup_pm_thaw,
568 .restore = ccwgroup_pm_restore,
569};
570
504static struct bus_type ccwgroup_bus_type = { 571static struct bus_type ccwgroup_bus_type = {
505 .name = "ccwgroup", 572 .name = "ccwgroup",
506 .match = ccwgroup_bus_match, 573 .match = ccwgroup_bus_match,
@@ -508,6 +575,7 @@ static struct bus_type ccwgroup_bus_type = {
508 .probe = ccwgroup_probe, 575 .probe = ccwgroup_probe,
509 .remove = ccwgroup_remove, 576 .remove = ccwgroup_remove,
510 .shutdown = ccwgroup_shutdown, 577 .shutdown = ccwgroup_shutdown,
578 .pm = &ccwgroup_pm_ops,
511}; 579};
512 580
513 581
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 883f16f96f22..1ecd3e567648 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -549,8 +549,7 @@ cleanup:
549 return ret; 549 return ret;
550} 550}
551 551
552static int 552int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
553__chsc_do_secm(struct channel_subsystem *css, int enable, void *page)
554{ 553{
555 struct { 554 struct {
556 struct chsc_header request; 555 struct chsc_header request;
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index ba59bceace98..425e8f89a6c5 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -90,6 +90,7 @@ extern void chsc_free_sei_area(void);
90extern int chsc_enable_facility(int); 90extern int chsc_enable_facility(int);
91struct channel_subsystem; 91struct channel_subsystem;
92extern int chsc_secm(struct channel_subsystem *, int); 92extern int chsc_secm(struct channel_subsystem *, int);
93int __chsc_do_secm(struct channel_subsystem *css, int enable, void *page);
93 94
94int chsc_chp_vary(struct chp_id chpid, int on); 95int chsc_chp_vary(struct chp_id chpid, int on);
95int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt, 96int chsc_determine_channel_path_desc(struct chp_id chpid, int fmt, int rfmt,
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 93eca1731b81..cc5144b6f9d9 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * Driver for s390 chsc subchannels 2 * Driver for s390 chsc subchannels
3 * 3 *
4 * Copyright IBM Corp. 2008 4 * Copyright IBM Corp. 2008, 2009
5 *
5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> 6 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
6 * 7 *
7 */ 8 */
@@ -112,6 +113,31 @@ static void chsc_subchannel_shutdown(struct subchannel *sch)
112 cio_disable_subchannel(sch); 113 cio_disable_subchannel(sch);
113} 114}
114 115
116static int chsc_subchannel_prepare(struct subchannel *sch)
117{
118 int cc;
119 struct schib schib;
120 /*
121 * Don't allow suspend while the subchannel is not idle
122 * since we don't have a way to clear the subchannel and
123 * cannot disable it with a request running.
124 */
125 cc = stsch(sch->schid, &schib);
126 if (!cc && scsw_stctl(&schib.scsw))
127 return -EAGAIN;
128 return 0;
129}
130
131static int chsc_subchannel_freeze(struct subchannel *sch)
132{
133 return cio_disable_subchannel(sch);
134}
135
136static int chsc_subchannel_restore(struct subchannel *sch)
137{
138 return cio_enable_subchannel(sch, (u32)(unsigned long)sch);
139}
140
115static struct css_device_id chsc_subchannel_ids[] = { 141static struct css_device_id chsc_subchannel_ids[] = {
116 { .match_flags = 0x1, .type =SUBCHANNEL_TYPE_CHSC, }, 142 { .match_flags = 0x1, .type =SUBCHANNEL_TYPE_CHSC, },
117 { /* end of list */ }, 143 { /* end of list */ },
@@ -125,6 +151,10 @@ static struct css_driver chsc_subchannel_driver = {
125 .probe = chsc_subchannel_probe, 151 .probe = chsc_subchannel_probe,
126 .remove = chsc_subchannel_remove, 152 .remove = chsc_subchannel_remove,
127 .shutdown = chsc_subchannel_shutdown, 153 .shutdown = chsc_subchannel_shutdown,
154 .prepare = chsc_subchannel_prepare,
155 .freeze = chsc_subchannel_freeze,
156 .thaw = chsc_subchannel_restore,
157 .restore = chsc_subchannel_restore,
128 .name = "chsc_subchannel", 158 .name = "chsc_subchannel",
129}; 159};
130 160
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index dc98b2c63862..30f516111307 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -1204,6 +1204,11 @@ static ssize_t cmb_enable_store(struct device *dev,
1204 1204
1205DEVICE_ATTR(cmb_enable, 0644, cmb_enable_show, cmb_enable_store); 1205DEVICE_ATTR(cmb_enable, 0644, cmb_enable_show, cmb_enable_store);
1206 1206
1207int ccw_set_cmf(struct ccw_device *cdev, int enable)
1208{
1209 return cmbops->set(cdev, enable ? 2 : 0);
1210}
1211
1207/** 1212/**
1208 * enable_cmf() - switch on the channel measurement for a specific device 1213 * enable_cmf() - switch on the channel measurement for a specific device
1209 * @cdev: The ccw device to be enabled 1214 * @cdev: The ccw device to be enabled
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 0085d8901792..85d43c6bcb66 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * drivers/s390/cio/css.c 2 * driver for channel subsystem
3 * driver for channel subsystem
4 * 3 *
5 * Copyright IBM Corp. 2002,2008 4 * Copyright IBM Corp. 2002, 2009
6 * Author(s): Arnd Bergmann (arndb@de.ibm.com) 5 *
7 * Cornelia Huck (cornelia.huck@de.ibm.com) 6 * Author(s): Arnd Bergmann (arndb@de.ibm.com)
7 * Cornelia Huck (cornelia.huck@de.ibm.com)
8 */ 8 */
9 9
10#define KMSG_COMPONENT "cio" 10#define KMSG_COMPONENT "cio"
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/reboot.h> 19#include <linux/reboot.h>
20#include <linux/suspend.h>
20#include <asm/isc.h> 21#include <asm/isc.h>
21#include <asm/crw.h> 22#include <asm/crw.h>
22 23
@@ -780,6 +781,79 @@ static struct notifier_block css_reboot_notifier = {
780}; 781};
781 782
782/* 783/*
784 * Since the css devices are neither on a bus nor have a class
785 * nor have a special device type, we cannot stop/restart channel
786 * path measurements via the normal suspend/resume callbacks, but have
787 * to use notifiers.
788 */
789static int css_power_event(struct notifier_block *this, unsigned long event,
790 void *ptr)
791{
792 void *secm_area;
793 int ret, i;
794
795 switch (event) {
796 case PM_HIBERNATION_PREPARE:
797 case PM_SUSPEND_PREPARE:
798 ret = NOTIFY_DONE;
799 for (i = 0; i <= __MAX_CSSID; i++) {
800 struct channel_subsystem *css;
801
802 css = channel_subsystems[i];
803 mutex_lock(&css->mutex);
804 if (!css->cm_enabled) {
805 mutex_unlock(&css->mutex);
806 continue;
807 }
808 secm_area = (void *)get_zeroed_page(GFP_KERNEL |
809 GFP_DMA);
810 if (secm_area) {
811 if (__chsc_do_secm(css, 0, secm_area))
812 ret = NOTIFY_BAD;
813 free_page((unsigned long)secm_area);
814 } else
815 ret = NOTIFY_BAD;
816
817 mutex_unlock(&css->mutex);
818 }
819 break;
820 case PM_POST_HIBERNATION:
821 case PM_POST_SUSPEND:
822 ret = NOTIFY_DONE;
823 for (i = 0; i <= __MAX_CSSID; i++) {
824 struct channel_subsystem *css;
825
826 css = channel_subsystems[i];
827 mutex_lock(&css->mutex);
828 if (!css->cm_enabled) {
829 mutex_unlock(&css->mutex);
830 continue;
831 }
832 secm_area = (void *)get_zeroed_page(GFP_KERNEL |
833 GFP_DMA);
834 if (secm_area) {
835 if (__chsc_do_secm(css, 1, secm_area))
836 ret = NOTIFY_BAD;
837 free_page((unsigned long)secm_area);
838 } else
839 ret = NOTIFY_BAD;
840
841 mutex_unlock(&css->mutex);
842 }
843 /* search for subchannels, which appeared during hibernation */
844 css_schedule_reprobe();
845 break;
846 default:
847 ret = NOTIFY_DONE;
848 }
849 return ret;
850
851}
852static struct notifier_block css_power_notifier = {
853 .notifier_call = css_power_event,
854};
855
856/*
783 * Now that the driver core is running, we can setup our channel subsystem. 857 * Now that the driver core is running, we can setup our channel subsystem.
784 * The struct subchannel's are created during probing (except for the 858 * The struct subchannel's are created during probing (except for the
785 * static console subchannel). 859 * static console subchannel).
@@ -852,6 +926,11 @@ init_channel_subsystem (void)
852 ret = register_reboot_notifier(&css_reboot_notifier); 926 ret = register_reboot_notifier(&css_reboot_notifier);
853 if (ret) 927 if (ret)
854 goto out_unregister; 928 goto out_unregister;
929 ret = register_pm_notifier(&css_power_notifier);
930 if (ret) {
931 unregister_reboot_notifier(&css_reboot_notifier);
932 goto out_unregister;
933 }
855 css_init_done = 1; 934 css_init_done = 1;
856 935
857 /* Enable default isc for I/O subchannels. */ 936 /* Enable default isc for I/O subchannels. */
@@ -953,6 +1032,73 @@ static int css_uevent(struct device *dev, struct kobj_uevent_env *env)
953 return ret; 1032 return ret;
954} 1033}
955 1034
1035static int css_pm_prepare(struct device *dev)
1036{
1037 struct subchannel *sch = to_subchannel(dev);
1038 struct css_driver *drv;
1039
1040 if (mutex_is_locked(&sch->reg_mutex))
1041 return -EAGAIN;
1042 if (!sch->dev.driver)
1043 return 0;
1044 drv = to_cssdriver(sch->dev.driver);
1045 /* Notify drivers that they may not register children. */
1046 return drv->prepare ? drv->prepare(sch) : 0;
1047}
1048
1049static void css_pm_complete(struct device *dev)
1050{
1051 struct subchannel *sch = to_subchannel(dev);
1052 struct css_driver *drv;
1053
1054 if (!sch->dev.driver)
1055 return;
1056 drv = to_cssdriver(sch->dev.driver);
1057 if (drv->complete)
1058 drv->complete(sch);
1059}
1060
1061static int css_pm_freeze(struct device *dev)
1062{
1063 struct subchannel *sch = to_subchannel(dev);
1064 struct css_driver *drv;
1065
1066 if (!sch->dev.driver)
1067 return 0;
1068 drv = to_cssdriver(sch->dev.driver);
1069 return drv->freeze ? drv->freeze(sch) : 0;
1070}
1071
1072static int css_pm_thaw(struct device *dev)
1073{
1074 struct subchannel *sch = to_subchannel(dev);
1075 struct css_driver *drv;
1076
1077 if (!sch->dev.driver)
1078 return 0;
1079 drv = to_cssdriver(sch->dev.driver);
1080 return drv->thaw ? drv->thaw(sch) : 0;
1081}
1082
1083static int css_pm_restore(struct device *dev)
1084{
1085 struct subchannel *sch = to_subchannel(dev);
1086 struct css_driver *drv;
1087
1088 if (!sch->dev.driver)
1089 return 0;
1090 drv = to_cssdriver(sch->dev.driver);
1091 return drv->restore ? drv->restore(sch) : 0;
1092}
1093
1094static struct dev_pm_ops css_pm_ops = {
1095 .prepare = css_pm_prepare,
1096 .complete = css_pm_complete,
1097 .freeze = css_pm_freeze,
1098 .thaw = css_pm_thaw,
1099 .restore = css_pm_restore,
1100};
1101
956struct bus_type css_bus_type = { 1102struct bus_type css_bus_type = {
957 .name = "css", 1103 .name = "css",
958 .match = css_bus_match, 1104 .match = css_bus_match,
@@ -960,6 +1106,7 @@ struct bus_type css_bus_type = {
960 .remove = css_remove, 1106 .remove = css_remove,
961 .shutdown = css_shutdown, 1107 .shutdown = css_shutdown,
962 .uevent = css_uevent, 1108 .uevent = css_uevent,
1109 .pm = &css_pm_ops,
963}; 1110};
964 1111
965/** 1112/**
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 57ebf120f825..9763eeec7458 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -70,6 +70,11 @@ struct chp_link;
70 * @probe: function called on probe 70 * @probe: function called on probe
71 * @remove: function called on remove 71 * @remove: function called on remove
72 * @shutdown: called at device shutdown 72 * @shutdown: called at device shutdown
73 * @prepare: prepare for pm state transition
74 * @complete: undo work done in @prepare
75 * @freeze: callback for freezing during hibernation snapshotting
76 * @thaw: undo work done in @freeze
77 * @restore: callback for restoring after hibernation
73 * @name: name of the device driver 78 * @name: name of the device driver
74 */ 79 */
75struct css_driver { 80struct css_driver {
@@ -82,6 +87,11 @@ struct css_driver {
82 int (*probe)(struct subchannel *); 87 int (*probe)(struct subchannel *);
83 int (*remove)(struct subchannel *); 88 int (*remove)(struct subchannel *);
84 void (*shutdown)(struct subchannel *); 89 void (*shutdown)(struct subchannel *);
90 int (*prepare) (struct subchannel *);
91 void (*complete) (struct subchannel *);
92 int (*freeze)(struct subchannel *);
93 int (*thaw) (struct subchannel *);
94 int (*restore)(struct subchannel *);
85 const char *name; 95 const char *name;
86}; 96};
87 97
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 35441fa16be1..3c57c1a18bb8 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -138,6 +138,19 @@ static struct css_device_id io_subchannel_ids[] = {
138}; 138};
139MODULE_DEVICE_TABLE(css, io_subchannel_ids); 139MODULE_DEVICE_TABLE(css, io_subchannel_ids);
140 140
141static int io_subchannel_prepare(struct subchannel *sch)
142{
143 struct ccw_device *cdev;
144 /*
145 * Don't allow suspend while a ccw device registration
146 * is still outstanding.
147 */
148 cdev = sch_get_cdev(sch);
149 if (cdev && !device_is_registered(&cdev->dev))
150 return -EAGAIN;
151 return 0;
152}
153
141static struct css_driver io_subchannel_driver = { 154static struct css_driver io_subchannel_driver = {
142 .owner = THIS_MODULE, 155 .owner = THIS_MODULE,
143 .subchannel_type = io_subchannel_ids, 156 .subchannel_type = io_subchannel_ids,
@@ -148,6 +161,7 @@ static struct css_driver io_subchannel_driver = {
148 .probe = io_subchannel_probe, 161 .probe = io_subchannel_probe,
149 .remove = io_subchannel_remove, 162 .remove = io_subchannel_remove,
150 .shutdown = io_subchannel_shutdown, 163 .shutdown = io_subchannel_shutdown,
164 .prepare = io_subchannel_prepare,
151}; 165};
152 166
153struct workqueue_struct *ccw_device_work; 167struct workqueue_struct *ccw_device_work;
@@ -1775,6 +1789,15 @@ ccw_device_probe_console(void)
1775 return &console_cdev; 1789 return &console_cdev;
1776} 1790}
1777 1791
1792static int ccw_device_pm_restore(struct device *dev);
1793
1794int ccw_device_force_console(void)
1795{
1796 if (!console_cdev_in_use)
1797 return -ENODEV;
1798 return ccw_device_pm_restore(&console_cdev.dev);
1799}
1800EXPORT_SYMBOL_GPL(ccw_device_force_console);
1778 1801
1779const char *cio_get_console_cdev_name(struct subchannel *sch) 1802const char *cio_get_console_cdev_name(struct subchannel *sch)
1780{ 1803{
@@ -1895,6 +1918,242 @@ static void ccw_device_shutdown(struct device *dev)
1895 disable_cmf(cdev); 1918 disable_cmf(cdev);
1896} 1919}
1897 1920
1921static int ccw_device_pm_prepare(struct device *dev)
1922{
1923 struct ccw_device *cdev = to_ccwdev(dev);
1924
1925 if (work_pending(&cdev->private->kick_work))
1926 return -EAGAIN;
1927 /* Fail while device is being set online/offline. */
1928 if (atomic_read(&cdev->private->onoff))
1929 return -EAGAIN;
1930
1931 if (cdev->online && cdev->drv && cdev->drv->prepare)
1932 return cdev->drv->prepare(cdev);
1933
1934 return 0;
1935}
1936
1937static void ccw_device_pm_complete(struct device *dev)
1938{
1939 struct ccw_device *cdev = to_ccwdev(dev);
1940
1941 if (cdev->online && cdev->drv && cdev->drv->complete)
1942 cdev->drv->complete(cdev);
1943}
1944
1945static int ccw_device_pm_freeze(struct device *dev)
1946{
1947 struct ccw_device *cdev = to_ccwdev(dev);
1948 struct subchannel *sch = to_subchannel(cdev->dev.parent);
1949 int ret, cm_enabled;
1950
1951 /* Fail suspend while device is in transistional state. */
1952 if (!dev_fsm_final_state(cdev))
1953 return -EAGAIN;
1954 if (!cdev->online)
1955 return 0;
1956 if (cdev->drv && cdev->drv->freeze) {
1957 ret = cdev->drv->freeze(cdev);
1958 if (ret)
1959 return ret;
1960 }
1961
1962 spin_lock_irq(sch->lock);
1963 cm_enabled = cdev->private->cmb != NULL;
1964 spin_unlock_irq(sch->lock);
1965 if (cm_enabled) {
1966 /* Don't have the css write on memory. */
1967 ret = ccw_set_cmf(cdev, 0);
1968 if (ret)
1969 return ret;
1970 }
1971 /* From here on, disallow device driver I/O. */
1972 spin_lock_irq(sch->lock);
1973 ret = cio_disable_subchannel(sch);
1974 spin_unlock_irq(sch->lock);
1975
1976 return ret;
1977}
1978
1979static int ccw_device_pm_thaw(struct device *dev)
1980{
1981 struct ccw_device *cdev = to_ccwdev(dev);
1982 struct subchannel *sch = to_subchannel(cdev->dev.parent);
1983 int ret, cm_enabled;
1984
1985 if (!cdev->online)
1986 return 0;
1987
1988 spin_lock_irq(sch->lock);
1989 /* Allow device driver I/O again. */
1990 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
1991 cm_enabled = cdev->private->cmb != NULL;
1992 spin_unlock_irq(sch->lock);
1993 if (ret)
1994 return ret;
1995
1996 if (cm_enabled) {
1997 ret = ccw_set_cmf(cdev, 1);
1998 if (ret)
1999 return ret;
2000 }
2001
2002 if (cdev->drv && cdev->drv->thaw)
2003 ret = cdev->drv->thaw(cdev);
2004
2005 return ret;
2006}
2007
2008static void __ccw_device_pm_restore(struct ccw_device *cdev)
2009{
2010 struct subchannel *sch = to_subchannel(cdev->dev.parent);
2011 int ret;
2012
2013 if (cio_is_console(sch->schid))
2014 goto out;
2015 /*
2016 * While we were sleeping, devices may have gone or become
2017 * available again. Kick re-detection.
2018 */
2019 spin_lock_irq(sch->lock);
2020 cdev->private->flags.resuming = 1;
2021 ret = ccw_device_recognition(cdev);
2022 spin_unlock_irq(sch->lock);
2023 if (ret) {
2024 CIO_MSG_EVENT(0, "Couldn't start recognition for device "
2025 "%s (ret=%d)\n", dev_name(&cdev->dev), ret);
2026 spin_lock_irq(sch->lock);
2027 cdev->private->state = DEV_STATE_DISCONNECTED;
2028 spin_unlock_irq(sch->lock);
2029 /* notify driver after the resume cb */
2030 goto out;
2031 }
2032 wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev) ||
2033 cdev->private->state == DEV_STATE_DISCONNECTED);
2034
2035out:
2036 cdev->private->flags.resuming = 0;
2037}
2038
2039static int resume_handle_boxed(struct ccw_device *cdev)
2040{
2041 cdev->private->state = DEV_STATE_BOXED;
2042 if (ccw_device_notify(cdev, CIO_BOXED))
2043 return 0;
2044 ccw_device_schedule_sch_unregister(cdev);
2045 return -ENODEV;
2046}
2047
2048static int resume_handle_disc(struct ccw_device *cdev)
2049{
2050 cdev->private->state = DEV_STATE_DISCONNECTED;
2051 if (ccw_device_notify(cdev, CIO_GONE))
2052 return 0;
2053 ccw_device_schedule_sch_unregister(cdev);
2054 return -ENODEV;
2055}
2056
2057static int ccw_device_pm_restore(struct device *dev)
2058{
2059 struct ccw_device *cdev = to_ccwdev(dev);
2060 struct subchannel *sch = to_subchannel(cdev->dev.parent);
2061 int ret = 0, cm_enabled;
2062
2063 __ccw_device_pm_restore(cdev);
2064 spin_lock_irq(sch->lock);
2065 if (cio_is_console(sch->schid)) {
2066 cio_enable_subchannel(sch, (u32)(addr_t)sch);
2067 spin_unlock_irq(sch->lock);
2068 goto out_restore;
2069 }
2070 cdev->private->flags.donotify = 0;
2071 /* check recognition results */
2072 switch (cdev->private->state) {
2073 case DEV_STATE_OFFLINE:
2074 break;
2075 case DEV_STATE_BOXED:
2076 ret = resume_handle_boxed(cdev);
2077 spin_unlock_irq(sch->lock);
2078 if (ret)
2079 goto out;
2080 goto out_restore;
2081 case DEV_STATE_DISCONNECTED:
2082 goto out_disc_unlock;
2083 default:
2084 goto out_unreg_unlock;
2085 }
2086 /* check if the device id has changed */
2087 if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) {
2088 CIO_MSG_EVENT(0, "resume: sch %s: failed (devno changed from "
2089 "%04x to %04x)\n", dev_name(&sch->dev),
2090 cdev->private->dev_id.devno,
2091 sch->schib.pmcw.dev);
2092 goto out_unreg_unlock;
2093 }
2094 /* check if the device type has changed */
2095 if (!ccw_device_test_sense_data(cdev)) {
2096 ccw_device_update_sense_data(cdev);
2097 PREPARE_WORK(&cdev->private->kick_work,
2098 ccw_device_do_unbind_bind);
2099 queue_work(ccw_device_work, &cdev->private->kick_work);
2100 ret = -ENODEV;
2101 goto out_unlock;
2102 }
2103 if (!cdev->online) {
2104 ret = 0;
2105 goto out_unlock;
2106 }
2107 ret = ccw_device_online(cdev);
2108 if (ret)
2109 goto out_disc_unlock;
2110
2111 cm_enabled = cdev->private->cmb != NULL;
2112 spin_unlock_irq(sch->lock);
2113
2114 wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev));
2115 if (cdev->private->state != DEV_STATE_ONLINE) {
2116 spin_lock_irq(sch->lock);
2117 goto out_disc_unlock;
2118 }
2119 if (cm_enabled) {
2120 ret = ccw_set_cmf(cdev, 1);
2121 if (ret) {
2122 CIO_MSG_EVENT(2, "resume: cdev %s: cmf failed "
2123 "(rc=%d)\n", dev_name(&cdev->dev), ret);
2124 ret = 0;
2125 }
2126 }
2127
2128out_restore:
2129 if (cdev->online && cdev->drv && cdev->drv->restore)
2130 ret = cdev->drv->restore(cdev);
2131out:
2132 return ret;
2133
2134out_disc_unlock:
2135 ret = resume_handle_disc(cdev);
2136 spin_unlock_irq(sch->lock);
2137 if (ret)
2138 return ret;
2139 goto out_restore;
2140
2141out_unreg_unlock:
2142 ccw_device_schedule_sch_unregister(cdev);
2143 ret = -ENODEV;
2144out_unlock:
2145 spin_unlock_irq(sch->lock);
2146 return ret;
2147}
2148
2149static struct dev_pm_ops ccw_pm_ops = {
2150 .prepare = ccw_device_pm_prepare,
2151 .complete = ccw_device_pm_complete,
2152 .freeze = ccw_device_pm_freeze,
2153 .thaw = ccw_device_pm_thaw,
2154 .restore = ccw_device_pm_restore,
2155};
2156
1898struct bus_type ccw_bus_type = { 2157struct bus_type ccw_bus_type = {
1899 .name = "ccw", 2158 .name = "ccw",
1900 .match = ccw_bus_match, 2159 .match = ccw_bus_match,
@@ -1902,6 +2161,7 @@ struct bus_type ccw_bus_type = {
1902 .probe = ccw_device_probe, 2161 .probe = ccw_device_probe,
1903 .remove = ccw_device_remove, 2162 .remove = ccw_device_remove,
1904 .shutdown = ccw_device_shutdown, 2163 .shutdown = ccw_device_shutdown,
2164 .pm = &ccw_pm_ops,
1905}; 2165};
1906 2166
1907/** 2167/**
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index f1cbbd94ad4e..e3975107a578 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -87,6 +87,8 @@ int ccw_device_is_orphan(struct ccw_device *);
87int ccw_device_recognition(struct ccw_device *); 87int ccw_device_recognition(struct ccw_device *);
88int ccw_device_online(struct ccw_device *); 88int ccw_device_online(struct ccw_device *);
89int ccw_device_offline(struct ccw_device *); 89int ccw_device_offline(struct ccw_device *);
90void ccw_device_update_sense_data(struct ccw_device *);
91int ccw_device_test_sense_data(struct ccw_device *);
90void ccw_device_schedule_sch_unregister(struct ccw_device *); 92void ccw_device_schedule_sch_unregister(struct ccw_device *);
91int ccw_purge_blacklisted(void); 93int ccw_purge_blacklisted(void);
92 94
@@ -133,5 +135,6 @@ extern struct bus_type ccw_bus_type;
133void retry_set_schib(struct ccw_device *cdev); 135void retry_set_schib(struct ccw_device *cdev);
134void cmf_retry_copy_block(struct ccw_device *); 136void cmf_retry_copy_block(struct ccw_device *);
135int cmf_reenable(struct ccw_device *); 137int cmf_reenable(struct ccw_device *);
138int ccw_set_cmf(struct ccw_device *cdev, int enable);
136extern struct device_attribute dev_attr_cmb_enable; 139extern struct device_attribute dev_attr_cmb_enable;
137#endif 140#endif
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index e46049261561..3db88c52d287 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -177,29 +177,21 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev)
177 panic("Can't stop i/o on subchannel.\n"); 177 panic("Can't stop i/o on subchannel.\n");
178} 178}
179 179
180static int 180void ccw_device_update_sense_data(struct ccw_device *cdev)
181ccw_device_handle_oper(struct ccw_device *cdev)
182{ 181{
183 struct subchannel *sch; 182 memset(&cdev->id, 0, sizeof(cdev->id));
183 cdev->id.cu_type = cdev->private->senseid.cu_type;
184 cdev->id.cu_model = cdev->private->senseid.cu_model;
185 cdev->id.dev_type = cdev->private->senseid.dev_type;
186 cdev->id.dev_model = cdev->private->senseid.dev_model;
187}
184 188
185 sch = to_subchannel(cdev->dev.parent); 189int ccw_device_test_sense_data(struct ccw_device *cdev)
186 cdev->private->flags.recog_done = 1; 190{
187 /* 191 return cdev->id.cu_type == cdev->private->senseid.cu_type &&
188 * Check if cu type and device type still match. If 192 cdev->id.cu_model == cdev->private->senseid.cu_model &&
189 * not, it is certainly another device and we have to 193 cdev->id.dev_type == cdev->private->senseid.dev_type &&
190 * de- and re-register. 194 cdev->id.dev_model == cdev->private->senseid.dev_model;
191 */
192 if (cdev->id.cu_type != cdev->private->senseid.cu_type ||
193 cdev->id.cu_model != cdev->private->senseid.cu_model ||
194 cdev->id.dev_type != cdev->private->senseid.dev_type ||
195 cdev->id.dev_model != cdev->private->senseid.dev_model) {
196 PREPARE_WORK(&cdev->private->kick_work,
197 ccw_device_do_unbind_bind);
198 queue_work(ccw_device_work, &cdev->private->kick_work);
199 return 0;
200 }
201 cdev->private->flags.donotify = 1;
202 return 1;
203} 195}
204 196
205/* 197/*
@@ -233,7 +225,7 @@ static void
233ccw_device_recog_done(struct ccw_device *cdev, int state) 225ccw_device_recog_done(struct ccw_device *cdev, int state)
234{ 226{
235 struct subchannel *sch; 227 struct subchannel *sch;
236 int notify, old_lpm, same_dev; 228 int old_lpm;
237 229
238 sch = to_subchannel(cdev->dev.parent); 230 sch = to_subchannel(cdev->dev.parent);
239 231
@@ -263,8 +255,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
263 wake_up(&cdev->private->wait_q); 255 wake_up(&cdev->private->wait_q);
264 return; 256 return;
265 } 257 }
266 notify = 0; 258 if (cdev->private->flags.resuming) {
267 same_dev = 0; /* Keep the compiler quiet... */ 259 cdev->private->state = state;
260 cdev->private->flags.recog_done = 1;
261 wake_up(&cdev->private->wait_q);
262 return;
263 }
268 switch (state) { 264 switch (state) {
269 case DEV_STATE_NOT_OPER: 265 case DEV_STATE_NOT_OPER:
270 CIO_MSG_EVENT(2, "SenseID : unknown device %04x on " 266 CIO_MSG_EVENT(2, "SenseID : unknown device %04x on "
@@ -273,34 +269,31 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
273 sch->schid.ssid, sch->schid.sch_no); 269 sch->schid.ssid, sch->schid.sch_no);
274 break; 270 break;
275 case DEV_STATE_OFFLINE: 271 case DEV_STATE_OFFLINE:
276 if (cdev->online) { 272 if (!cdev->online) {
277 same_dev = ccw_device_handle_oper(cdev); 273 ccw_device_update_sense_data(cdev);
278 notify = 1; 274 /* Issue device info message. */
275 CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: "
276 "CU Type/Mod = %04X/%02X, Dev Type/Mod "
277 "= %04X/%02X\n",
278 cdev->private->dev_id.ssid,
279 cdev->private->dev_id.devno,
280 cdev->id.cu_type, cdev->id.cu_model,
281 cdev->id.dev_type, cdev->id.dev_model);
282 break;
279 } 283 }
280 /* fill out sense information */ 284 cdev->private->state = DEV_STATE_OFFLINE;
281 memset(&cdev->id, 0, sizeof(cdev->id)); 285 cdev->private->flags.recog_done = 1;
282 cdev->id.cu_type = cdev->private->senseid.cu_type; 286 if (ccw_device_test_sense_data(cdev)) {
283 cdev->id.cu_model = cdev->private->senseid.cu_model; 287 cdev->private->flags.donotify = 1;
284 cdev->id.dev_type = cdev->private->senseid.dev_type; 288 ccw_device_online(cdev);
285 cdev->id.dev_model = cdev->private->senseid.dev_model; 289 wake_up(&cdev->private->wait_q);
286 if (notify) { 290 } else {
287 cdev->private->state = DEV_STATE_OFFLINE; 291 ccw_device_update_sense_data(cdev);
288 if (same_dev) { 292 PREPARE_WORK(&cdev->private->kick_work,
289 /* Get device online again. */ 293 ccw_device_do_unbind_bind);
290 ccw_device_online(cdev); 294 queue_work(ccw_device_work, &cdev->private->kick_work);
291 wake_up(&cdev->private->wait_q);
292 }
293 return;
294 } 295 }
295 /* Issue device info message. */ 296 return;
296 CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: "
297 "CU Type/Mod = %04X/%02X, Dev Type/Mod = "
298 "%04X/%02X\n",
299 cdev->private->dev_id.ssid,
300 cdev->private->dev_id.devno,
301 cdev->id.cu_type, cdev->id.cu_model,
302 cdev->id.dev_type, cdev->id.dev_model);
303 break;
304 case DEV_STATE_BOXED: 297 case DEV_STATE_BOXED:
305 CIO_MSG_EVENT(0, "SenseID : boxed device %04x on " 298 CIO_MSG_EVENT(0, "SenseID : boxed device %04x on "
306 " subchannel 0.%x.%04x\n", 299 " subchannel 0.%x.%04x\n",
@@ -502,9 +495,6 @@ ccw_device_recognition(struct ccw_device *cdev)
502 struct subchannel *sch; 495 struct subchannel *sch;
503 int ret; 496 int ret;
504 497
505 if ((cdev->private->state != DEV_STATE_NOT_OPER) &&
506 (cdev->private->state != DEV_STATE_BOXED))
507 return -EINVAL;
508 sch = to_subchannel(cdev->dev.parent); 498 sch = to_subchannel(cdev->dev.parent);
509 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); 499 ret = cio_enable_subchannel(sch, (u32)(addr_t)sch);
510 if (ret != 0) 500 if (ret != 0)
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index bf0a24af39a0..2d0efee8a290 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -1,10 +1,8 @@
1/* 1/*
2 * drivers/s390/cio/device_ops.c 2 * Copyright IBM Corp. 2002, 2009
3 * 3 *
4 * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, 4 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
5 * IBM Corporation 5 * Cornelia Huck (cornelia.huck@de.ibm.com)
6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
7 * Cornelia Huck (cornelia.huck@de.ibm.com)
8 */ 6 */
9#include <linux/module.h> 7#include <linux/module.h>
10#include <linux/init.h> 8#include <linux/init.h>
@@ -116,12 +114,15 @@ int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)
116 114
117 if (!cdev || !cdev->dev.parent) 115 if (!cdev || !cdev->dev.parent)
118 return -ENODEV; 116 return -ENODEV;
117 sch = to_subchannel(cdev->dev.parent);
118 if (!sch->schib.pmcw.ena)
119 return -EINVAL;
119 if (cdev->private->state == DEV_STATE_NOT_OPER) 120 if (cdev->private->state == DEV_STATE_NOT_OPER)
120 return -ENODEV; 121 return -ENODEV;
121 if (cdev->private->state != DEV_STATE_ONLINE && 122 if (cdev->private->state != DEV_STATE_ONLINE &&
122 cdev->private->state != DEV_STATE_W4SENSE) 123 cdev->private->state != DEV_STATE_W4SENSE)
123 return -EINVAL; 124 return -EINVAL;
124 sch = to_subchannel(cdev->dev.parent); 125
125 ret = cio_clear(sch); 126 ret = cio_clear(sch);
126 if (ret == 0) 127 if (ret == 0)
127 cdev->private->intparm = intparm; 128 cdev->private->intparm = intparm;
@@ -162,6 +163,8 @@ int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa,
162 if (!cdev || !cdev->dev.parent) 163 if (!cdev || !cdev->dev.parent)
163 return -ENODEV; 164 return -ENODEV;
164 sch = to_subchannel(cdev->dev.parent); 165 sch = to_subchannel(cdev->dev.parent);
166 if (!sch->schib.pmcw.ena)
167 return -EINVAL;
165 if (cdev->private->state == DEV_STATE_NOT_OPER) 168 if (cdev->private->state == DEV_STATE_NOT_OPER)
166 return -ENODEV; 169 return -ENODEV;
167 if (cdev->private->state == DEV_STATE_VERIFY || 170 if (cdev->private->state == DEV_STATE_VERIFY ||
@@ -337,12 +340,15 @@ int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)
337 340
338 if (!cdev || !cdev->dev.parent) 341 if (!cdev || !cdev->dev.parent)
339 return -ENODEV; 342 return -ENODEV;
343 sch = to_subchannel(cdev->dev.parent);
344 if (!sch->schib.pmcw.ena)
345 return -EINVAL;
340 if (cdev->private->state == DEV_STATE_NOT_OPER) 346 if (cdev->private->state == DEV_STATE_NOT_OPER)
341 return -ENODEV; 347 return -ENODEV;
342 if (cdev->private->state != DEV_STATE_ONLINE && 348 if (cdev->private->state != DEV_STATE_ONLINE &&
343 cdev->private->state != DEV_STATE_W4SENSE) 349 cdev->private->state != DEV_STATE_W4SENSE)
344 return -EINVAL; 350 return -EINVAL;
345 sch = to_subchannel(cdev->dev.parent); 351
346 ret = cio_halt(sch); 352 ret = cio_halt(sch);
347 if (ret == 0) 353 if (ret == 0)
348 cdev->private->intparm = intparm; 354 cdev->private->intparm = intparm;
@@ -369,6 +375,8 @@ int ccw_device_resume(struct ccw_device *cdev)
369 if (!cdev || !cdev->dev.parent) 375 if (!cdev || !cdev->dev.parent)
370 return -ENODEV; 376 return -ENODEV;
371 sch = to_subchannel(cdev->dev.parent); 377 sch = to_subchannel(cdev->dev.parent);
378 if (!sch->schib.pmcw.ena)
379 return -EINVAL;
372 if (cdev->private->state == DEV_STATE_NOT_OPER) 380 if (cdev->private->state == DEV_STATE_NOT_OPER)
373 return -ENODEV; 381 return -ENODEV;
374 if (cdev->private->state != DEV_STATE_ONLINE || 382 if (cdev->private->state != DEV_STATE_ONLINE ||
@@ -580,6 +588,8 @@ int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw,
580 int rc; 588 int rc;
581 589
582 sch = to_subchannel(cdev->dev.parent); 590 sch = to_subchannel(cdev->dev.parent);
591 if (!sch->schib.pmcw.ena)
592 return -EINVAL;
583 if (cdev->private->state != DEV_STATE_ONLINE) 593 if (cdev->private->state != DEV_STATE_ONLINE)
584 return -EIO; 594 return -EIO;
585 /* Adjust requested path mask to excluded varied off paths. */ 595 /* Adjust requested path mask to excluded varied off paths. */
@@ -669,6 +679,8 @@ int ccw_device_tm_intrg(struct ccw_device *cdev)
669{ 679{
670 struct subchannel *sch = to_subchannel(cdev->dev.parent); 680 struct subchannel *sch = to_subchannel(cdev->dev.parent);
671 681
682 if (!sch->schib.pmcw.ena)
683 return -EINVAL;
672 if (cdev->private->state != DEV_STATE_ONLINE) 684 if (cdev->private->state != DEV_STATE_ONLINE)
673 return -EIO; 685 return -EIO;
674 if (!scsw_is_tm(&sch->schib.scsw) || 686 if (!scsw_is_tm(&sch->schib.scsw) ||
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h
index c4f3e7c9a854..0b8f381bd20e 100644
--- a/drivers/s390/cio/io_sch.h
+++ b/drivers/s390/cio/io_sch.h
@@ -107,6 +107,7 @@ struct ccw_device_private {
107 unsigned int recog_done:1; /* dev. recog. complete */ 107 unsigned int recog_done:1; /* dev. recog. complete */
108 unsigned int fake_irb:1; /* deliver faked irb */ 108 unsigned int fake_irb:1; /* deliver faked irb */
109 unsigned int intretry:1; /* retry internal operation */ 109 unsigned int intretry:1; /* retry internal operation */
110 unsigned int resuming:1; /* recognition while resume */
110 } __attribute__((packed)) flags; 111 } __attribute__((packed)) flags;
111 unsigned long intparm; /* user interruption parameter */ 112 unsigned long intparm; /* user interruption parameter */
112 struct qdio_irq *qdio_data; 113 struct qdio_irq *qdio_data;
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index 7b6f46ddf3c3..d40f7a934f94 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -3,12 +3,12 @@
3 * ESCON CLAW network driver 3 * ESCON CLAW network driver
4 * 4 *
5 * Linux for zSeries version 5 * Linux for zSeries version
6 * Copyright (C) 2002,2005 IBM Corporation 6 * Copyright IBM Corp. 2002, 2009
7 * Author(s) Original code written by: 7 * Author(s) Original code written by:
8 * Kazuo Iimura (iimura@jp.ibm.com) 8 * Kazuo Iimura <iimura@jp.ibm.com>
9 * Rewritten by 9 * Rewritten by
10 * Andy Richter (richtera@us.ibm.com) 10 * Andy Richter <richtera@us.ibm.com>
11 * Marc Price (mwprice@us.ibm.com) 11 * Marc Price <mwprice@us.ibm.com>
12 * 12 *
13 * sysfs parms: 13 * sysfs parms:
14 * group x.x.rrrr,x.x.wwww 14 * group x.x.rrrr,x.x.wwww
@@ -253,6 +253,11 @@ static void claw_free_wrt_buf(struct net_device *dev);
253/* Functions for unpack reads */ 253/* Functions for unpack reads */
254static void unpack_read(struct net_device *dev); 254static void unpack_read(struct net_device *dev);
255 255
256static int claw_pm_prepare(struct ccwgroup_device *gdev)
257{
258 return -EPERM;
259}
260
256/* ccwgroup table */ 261/* ccwgroup table */
257 262
258static struct ccwgroup_driver claw_group_driver = { 263static struct ccwgroup_driver claw_group_driver = {
@@ -264,6 +269,7 @@ static struct ccwgroup_driver claw_group_driver = {
264 .remove = claw_remove_device, 269 .remove = claw_remove_device,
265 .set_online = claw_new_device, 270 .set_online = claw_new_device,
266 .set_offline = claw_shutdown_device, 271 .set_offline = claw_shutdown_device,
272 .prepare = claw_pm_prepare,
267}; 273};
268 274
269/* 275/*
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 54c4649a493b..222e47394437 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/net/ctcm_main.c 2 * drivers/s390/net/ctcm_main.c
3 * 3 *
4 * Copyright IBM Corp. 2001, 2007 4 * Copyright IBM Corp. 2001, 2009
5 * Author(s): 5 * Author(s):
6 * Original CTC driver(s): 6 * Original CTC driver(s):
7 * Fritz Elfert (felfert@millenux.com) 7 * Fritz Elfert (felfert@millenux.com)
@@ -1688,6 +1688,38 @@ static void ctcm_remove_device(struct ccwgroup_device *cgdev)
1688 put_device(&cgdev->dev); 1688 put_device(&cgdev->dev);
1689} 1689}
1690 1690
1691static int ctcm_pm_suspend(struct ccwgroup_device *gdev)
1692{
1693 struct ctcm_priv *priv = dev_get_drvdata(&gdev->dev);
1694
1695 if (gdev->state == CCWGROUP_OFFLINE)
1696 return 0;
1697 netif_device_detach(priv->channel[READ]->netdev);
1698 ctcm_close(priv->channel[READ]->netdev);
1699 ccw_device_set_offline(gdev->cdev[1]);
1700 ccw_device_set_offline(gdev->cdev[0]);
1701 return 0;
1702}
1703
1704static int ctcm_pm_resume(struct ccwgroup_device *gdev)
1705{
1706 struct ctcm_priv *priv = dev_get_drvdata(&gdev->dev);
1707 int rc;
1708
1709 if (gdev->state == CCWGROUP_OFFLINE)
1710 return 0;
1711 rc = ccw_device_set_online(gdev->cdev[1]);
1712 if (rc)
1713 goto err_out;
1714 rc = ccw_device_set_online(gdev->cdev[0]);
1715 if (rc)
1716 goto err_out;
1717 ctcm_open(priv->channel[READ]->netdev);
1718err_out:
1719 netif_device_attach(priv->channel[READ]->netdev);
1720 return rc;
1721}
1722
1691static struct ccwgroup_driver ctcm_group_driver = { 1723static struct ccwgroup_driver ctcm_group_driver = {
1692 .owner = THIS_MODULE, 1724 .owner = THIS_MODULE,
1693 .name = CTC_DRIVER_NAME, 1725 .name = CTC_DRIVER_NAME,
@@ -1697,6 +1729,9 @@ static struct ccwgroup_driver ctcm_group_driver = {
1697 .remove = ctcm_remove_device, 1729 .remove = ctcm_remove_device,
1698 .set_online = ctcm_new_device, 1730 .set_online = ctcm_new_device,
1699 .set_offline = ctcm_shutdown_device, 1731 .set_offline = ctcm_shutdown_device,
1732 .freeze = ctcm_pm_suspend,
1733 .thaw = ctcm_pm_resume,
1734 .restore = ctcm_pm_resume,
1700}; 1735};
1701 1736
1702 1737
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index a45bc24eb5f9..07a25c3f94b6 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1,15 +1,12 @@
1/* 1/*
2 * linux/drivers/s390/net/lcs.c
3 *
4 * Linux for S/390 Lan Channel Station Network Driver 2 * Linux for S/390 Lan Channel Station Network Driver
5 * 3 *
6 * Copyright (C) 1999-2001 IBM Deutschland Entwicklung GmbH, 4 * Copyright IBM Corp. 1999, 2009
7 * IBM Corporation 5 * Author(s): Original Code written by
8 * Author(s): Original Code written by 6 * DJ Barrow <djbarrow@de.ibm.com,barrow_dj@yahoo.com>
9 * DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 7 * Rewritten by
10 * Rewritten by 8 * Frank Pavlic <fpavlic@de.ibm.com> and
11 * Frank Pavlic (fpavlic@de.ibm.com) and 9 * Martin Schwidefsky <schwidefsky@de.ibm.com>
12 * Martin Schwidefsky <schwidefsky@de.ibm.com>
13 * 10 *
14 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
@@ -2313,6 +2310,60 @@ lcs_remove_device(struct ccwgroup_device *ccwgdev)
2313 put_device(&ccwgdev->dev); 2310 put_device(&ccwgdev->dev);
2314} 2311}
2315 2312
2313static int lcs_pm_suspend(struct lcs_card *card)
2314{
2315 if (card->dev)
2316 netif_device_detach(card->dev);
2317 lcs_set_allowed_threads(card, 0);
2318 lcs_wait_for_threads(card, 0xffffffff);
2319 if (card->state != DEV_STATE_DOWN)
2320 __lcs_shutdown_device(card->gdev, 1);
2321 return 0;
2322}
2323
2324static int lcs_pm_resume(struct lcs_card *card)
2325{
2326 int rc = 0;
2327
2328 if (card->state == DEV_STATE_RECOVER)
2329 rc = lcs_new_device(card->gdev);
2330 if (card->dev)
2331 netif_device_attach(card->dev);
2332 if (rc) {
2333 dev_warn(&card->gdev->dev, "The lcs device driver "
2334 "failed to recover the device\n");
2335 }
2336 return rc;
2337}
2338
2339static int lcs_prepare(struct ccwgroup_device *gdev)
2340{
2341 return 0;
2342}
2343
2344static void lcs_complete(struct ccwgroup_device *gdev)
2345{
2346 return;
2347}
2348
2349static int lcs_freeze(struct ccwgroup_device *gdev)
2350{
2351 struct lcs_card *card = dev_get_drvdata(&gdev->dev);
2352 return lcs_pm_suspend(card);
2353}
2354
2355static int lcs_thaw(struct ccwgroup_device *gdev)
2356{
2357 struct lcs_card *card = dev_get_drvdata(&gdev->dev);
2358 return lcs_pm_resume(card);
2359}
2360
2361static int lcs_restore(struct ccwgroup_device *gdev)
2362{
2363 struct lcs_card *card = dev_get_drvdata(&gdev->dev);
2364 return lcs_pm_resume(card);
2365}
2366
2316/** 2367/**
2317 * LCS ccwgroup driver registration 2368 * LCS ccwgroup driver registration
2318 */ 2369 */
@@ -2325,6 +2376,11 @@ static struct ccwgroup_driver lcs_group_driver = {
2325 .remove = lcs_remove_device, 2376 .remove = lcs_remove_device,
2326 .set_online = lcs_new_device, 2377 .set_online = lcs_new_device,
2327 .set_offline = lcs_shutdown_device, 2378 .set_offline = lcs_shutdown_device,
2379 .prepare = lcs_prepare,
2380 .complete = lcs_complete,
2381 .freeze = lcs_freeze,
2382 .thaw = lcs_thaw,
2383 .restore = lcs_restore,
2328}; 2384};
2329 2385
2330/** 2386/**
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index aec9e5d3cf4b..fdb02d043d3e 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1,11 +1,15 @@
1/* 1/*
2 * IUCV network driver 2 * IUCV network driver
3 * 3 *
4 * Copyright 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 * Copyright IBM Corp. 2001, 2009
5 * Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
6 * 5 *
7 * Sysfs integration and all bugs therein by Cornelia Huck 6 * Author(s):
8 * (cornelia.huck@de.ibm.com) 7 * Original netiucv driver:
8 * Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
9 * Sysfs integration and all bugs therein:
10 * Cornelia Huck (cornelia.huck@de.ibm.com)
11 * PM functions:
12 * Ursula Braun (ursula.braun@de.ibm.com)
9 * 13 *
10 * Documentation used: 14 * Documentation used:
11 * the source of the original IUCV driver by: 15 * the source of the original IUCV driver by:
@@ -149,10 +153,27 @@ PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \
149 153
150#define PRINTK_HEADER " iucv: " /* for debugging */ 154#define PRINTK_HEADER " iucv: " /* for debugging */
151 155
156/* dummy device to make sure netiucv_pm functions are called */
157static struct device *netiucv_dev;
158
159static int netiucv_pm_prepare(struct device *);
160static void netiucv_pm_complete(struct device *);
161static int netiucv_pm_freeze(struct device *);
162static int netiucv_pm_restore_thaw(struct device *);
163
164static struct dev_pm_ops netiucv_pm_ops = {
165 .prepare = netiucv_pm_prepare,
166 .complete = netiucv_pm_complete,
167 .freeze = netiucv_pm_freeze,
168 .thaw = netiucv_pm_restore_thaw,
169 .restore = netiucv_pm_restore_thaw,
170};
171
152static struct device_driver netiucv_driver = { 172static struct device_driver netiucv_driver = {
153 .owner = THIS_MODULE, 173 .owner = THIS_MODULE,
154 .name = "netiucv", 174 .name = "netiucv",
155 .bus = &iucv_bus, 175 .bus = &iucv_bus,
176 .pm = &netiucv_pm_ops,
156}; 177};
157 178
158static int netiucv_callback_connreq(struct iucv_path *, 179static int netiucv_callback_connreq(struct iucv_path *,
@@ -233,6 +254,7 @@ struct netiucv_priv {
233 fsm_instance *fsm; 254 fsm_instance *fsm;
234 struct iucv_connection *conn; 255 struct iucv_connection *conn;
235 struct device *dev; 256 struct device *dev;
257 int pm_state;
236}; 258};
237 259
238/** 260/**
@@ -1265,6 +1287,72 @@ static int netiucv_close(struct net_device *dev)
1265 return 0; 1287 return 0;
1266} 1288}
1267 1289
1290static int netiucv_pm_prepare(struct device *dev)
1291{
1292 IUCV_DBF_TEXT(trace, 3, __func__);
1293 return 0;
1294}
1295
1296static void netiucv_pm_complete(struct device *dev)
1297{
1298 IUCV_DBF_TEXT(trace, 3, __func__);
1299 return;
1300}
1301
1302/**
1303 * netiucv_pm_freeze() - Freeze PM callback
1304 * @dev: netiucv device
1305 *
1306 * close open netiucv interfaces
1307 */
1308static int netiucv_pm_freeze(struct device *dev)
1309{
1310 struct netiucv_priv *priv = dev->driver_data;
1311 struct net_device *ndev = NULL;
1312 int rc = 0;
1313
1314 IUCV_DBF_TEXT(trace, 3, __func__);
1315 if (priv && priv->conn)
1316 ndev = priv->conn->netdev;
1317 if (!ndev)
1318 goto out;
1319 netif_device_detach(ndev);
1320 priv->pm_state = fsm_getstate(priv->fsm);
1321 rc = netiucv_close(ndev);
1322out:
1323 return rc;
1324}
1325
1326/**
1327 * netiucv_pm_restore_thaw() - Thaw and restore PM callback
1328 * @dev: netiucv device
1329 *
1330 * re-open netiucv interfaces closed during freeze
1331 */
1332static int netiucv_pm_restore_thaw(struct device *dev)
1333{
1334 struct netiucv_priv *priv = dev->driver_data;
1335 struct net_device *ndev = NULL;
1336 int rc = 0;
1337
1338 IUCV_DBF_TEXT(trace, 3, __func__);
1339 if (priv && priv->conn)
1340 ndev = priv->conn->netdev;
1341 if (!ndev)
1342 goto out;
1343 switch (priv->pm_state) {
1344 case DEV_STATE_RUNNING:
1345 case DEV_STATE_STARTWAIT:
1346 rc = netiucv_open(ndev);
1347 break;
1348 default:
1349 break;
1350 }
1351 netif_device_attach(ndev);
1352out:
1353 return rc;
1354}
1355
1268/** 1356/**
1269 * Start transmission of a packet. 1357 * Start transmission of a packet.
1270 * Called from generic network device layer. 1358 * Called from generic network device layer.
@@ -1731,7 +1819,6 @@ static int netiucv_register_device(struct net_device *ndev)
1731 struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL); 1819 struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL);
1732 int ret; 1820 int ret;
1733 1821
1734
1735 IUCV_DBF_TEXT(trace, 3, __func__); 1822 IUCV_DBF_TEXT(trace, 3, __func__);
1736 1823
1737 if (dev) { 1824 if (dev) {
@@ -2100,6 +2187,7 @@ static void __exit netiucv_exit(void)
2100 netiucv_unregister_device(dev); 2187 netiucv_unregister_device(dev);
2101 } 2188 }
2102 2189
2190 device_unregister(netiucv_dev);
2103 driver_unregister(&netiucv_driver); 2191 driver_unregister(&netiucv_driver);
2104 iucv_unregister(&netiucv_handler, 1); 2192 iucv_unregister(&netiucv_handler, 1);
2105 iucv_unregister_dbf_views(); 2193 iucv_unregister_dbf_views();
@@ -2125,10 +2213,25 @@ static int __init netiucv_init(void)
2125 IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc); 2213 IUCV_DBF_TEXT_(setup, 2, "ret %d from driver_register\n", rc);
2126 goto out_iucv; 2214 goto out_iucv;
2127 } 2215 }
2128 2216 /* establish dummy device */
2217 netiucv_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
2218 if (!netiucv_dev) {
2219 rc = -ENOMEM;
2220 goto out_driver;
2221 }
2222 dev_set_name(netiucv_dev, "netiucv");
2223 netiucv_dev->bus = &iucv_bus;
2224 netiucv_dev->parent = iucv_root;
2225 netiucv_dev->release = (void (*)(struct device *))kfree;
2226 netiucv_dev->driver = &netiucv_driver;
2227 rc = device_register(netiucv_dev);
2228 if (rc)
2229 goto out_driver;
2129 netiucv_banner(); 2230 netiucv_banner();
2130 return rc; 2231 return rc;
2131 2232
2233out_driver:
2234 driver_unregister(&netiucv_driver);
2132out_iucv: 2235out_iucv:
2133 iucv_unregister(&netiucv_handler, 1); 2236 iucv_unregister(&netiucv_handler, 1);
2134out_dbf: 2237out_dbf:
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 74c49d9a8dba..d53621c4acbb 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/net/qeth_core_main.c 2 * drivers/s390/net/qeth_core_main.c
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Copyright IBM Corp. 2007, 2009
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>, 5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>, 6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>, 7 * Thomas Spatzier <tspat@de.ibm.com>,
@@ -4195,6 +4195,50 @@ static void qeth_core_shutdown(struct ccwgroup_device *gdev)
4195 card->discipline.ccwgdriver->shutdown(gdev); 4195 card->discipline.ccwgdriver->shutdown(gdev);
4196} 4196}
4197 4197
4198static int qeth_core_prepare(struct ccwgroup_device *gdev)
4199{
4200 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4201 if (card->discipline.ccwgdriver &&
4202 card->discipline.ccwgdriver->prepare)
4203 return card->discipline.ccwgdriver->prepare(gdev);
4204 return 0;
4205}
4206
4207static void qeth_core_complete(struct ccwgroup_device *gdev)
4208{
4209 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4210 if (card->discipline.ccwgdriver &&
4211 card->discipline.ccwgdriver->complete)
4212 card->discipline.ccwgdriver->complete(gdev);
4213}
4214
4215static int qeth_core_freeze(struct ccwgroup_device *gdev)
4216{
4217 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4218 if (card->discipline.ccwgdriver &&
4219 card->discipline.ccwgdriver->freeze)
4220 return card->discipline.ccwgdriver->freeze(gdev);
4221 return 0;
4222}
4223
4224static int qeth_core_thaw(struct ccwgroup_device *gdev)
4225{
4226 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4227 if (card->discipline.ccwgdriver &&
4228 card->discipline.ccwgdriver->thaw)
4229 return card->discipline.ccwgdriver->thaw(gdev);
4230 return 0;
4231}
4232
4233static int qeth_core_restore(struct ccwgroup_device *gdev)
4234{
4235 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
4236 if (card->discipline.ccwgdriver &&
4237 card->discipline.ccwgdriver->restore)
4238 return card->discipline.ccwgdriver->restore(gdev);
4239 return 0;
4240}
4241
4198static struct ccwgroup_driver qeth_core_ccwgroup_driver = { 4242static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
4199 .owner = THIS_MODULE, 4243 .owner = THIS_MODULE,
4200 .name = "qeth", 4244 .name = "qeth",
@@ -4204,6 +4248,11 @@ static struct ccwgroup_driver qeth_core_ccwgroup_driver = {
4204 .set_online = qeth_core_set_online, 4248 .set_online = qeth_core_set_online,
4205 .set_offline = qeth_core_set_offline, 4249 .set_offline = qeth_core_set_offline,
4206 .shutdown = qeth_core_shutdown, 4250 .shutdown = qeth_core_shutdown,
4251 .prepare = qeth_core_prepare,
4252 .complete = qeth_core_complete,
4253 .freeze = qeth_core_freeze,
4254 .thaw = qeth_core_thaw,
4255 .restore = qeth_core_restore,
4207}; 4256};
4208 4257
4209static ssize_t 4258static ssize_t
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index ecd3d06c0d5c..81d7f268418a 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/net/qeth_l2_main.c 2 * drivers/s390/net/qeth_l2_main.c
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Copyright IBM Corp. 2007, 2009
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>, 5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>, 6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>, 7 * Thomas Spatzier <tspat@de.ibm.com>,
@@ -1141,12 +1141,62 @@ static void qeth_l2_shutdown(struct ccwgroup_device *gdev)
1141 qeth_clear_qdio_buffers(card); 1141 qeth_clear_qdio_buffers(card);
1142} 1142}
1143 1143
1144static int qeth_l2_pm_suspend(struct ccwgroup_device *gdev)
1145{
1146 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
1147
1148 if (card->dev)
1149 netif_device_detach(card->dev);
1150 qeth_set_allowed_threads(card, 0, 1);
1151 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
1152 if (gdev->state == CCWGROUP_OFFLINE)
1153 return 0;
1154 if (card->state == CARD_STATE_UP) {
1155 card->use_hard_stop = 1;
1156 __qeth_l2_set_offline(card->gdev, 1);
1157 } else
1158 __qeth_l2_set_offline(card->gdev, 0);
1159 return 0;
1160}
1161
1162static int qeth_l2_pm_resume(struct ccwgroup_device *gdev)
1163{
1164 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
1165 int rc = 0;
1166
1167 if (gdev->state == CCWGROUP_OFFLINE)
1168 goto out;
1169
1170 if (card->state == CARD_STATE_RECOVER) {
1171 rc = __qeth_l2_set_online(card->gdev, 1);
1172 if (rc) {
1173 if (card->dev) {
1174 rtnl_lock();
1175 dev_close(card->dev);
1176 rtnl_unlock();
1177 }
1178 }
1179 } else
1180 rc = __qeth_l2_set_online(card->gdev, 0);
1181out:
1182 qeth_set_allowed_threads(card, 0xffffffff, 0);
1183 if (card->dev)
1184 netif_device_attach(card->dev);
1185 if (rc)
1186 dev_warn(&card->gdev->dev, "The qeth device driver "
1187 "failed to recover an error on the device\n");
1188 return rc;
1189}
1190
1144struct ccwgroup_driver qeth_l2_ccwgroup_driver = { 1191struct ccwgroup_driver qeth_l2_ccwgroup_driver = {
1145 .probe = qeth_l2_probe_device, 1192 .probe = qeth_l2_probe_device,
1146 .remove = qeth_l2_remove_device, 1193 .remove = qeth_l2_remove_device,
1147 .set_online = qeth_l2_set_online, 1194 .set_online = qeth_l2_set_online,
1148 .set_offline = qeth_l2_set_offline, 1195 .set_offline = qeth_l2_set_offline,
1149 .shutdown = qeth_l2_shutdown, 1196 .shutdown = qeth_l2_shutdown,
1197 .freeze = qeth_l2_pm_suspend,
1198 .thaw = qeth_l2_pm_resume,
1199 .restore = qeth_l2_pm_resume,
1150}; 1200};
1151EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver); 1201EXPORT_SYMBOL_GPL(qeth_l2_ccwgroup_driver);
1152 1202
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 6f2386e9d6e2..54872406864e 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * drivers/s390/net/qeth_l3_main.c 2 * drivers/s390/net/qeth_l3_main.c
3 * 3 *
4 * Copyright IBM Corp. 2007 4 * Copyright IBM Corp. 2007, 2009
5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>, 5 * Author(s): Utz Bacher <utz.bacher@de.ibm.com>,
6 * Frank Pavlic <fpavlic@de.ibm.com>, 6 * Frank Pavlic <fpavlic@de.ibm.com>,
7 * Thomas Spatzier <tspat@de.ibm.com>, 7 * Thomas Spatzier <tspat@de.ibm.com>,
@@ -3283,12 +3283,62 @@ static void qeth_l3_shutdown(struct ccwgroup_device *gdev)
3283 qeth_clear_qdio_buffers(card); 3283 qeth_clear_qdio_buffers(card);
3284} 3284}
3285 3285
3286static int qeth_l3_pm_suspend(struct ccwgroup_device *gdev)
3287{
3288 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3289
3290 if (card->dev)
3291 netif_device_detach(card->dev);
3292 qeth_set_allowed_threads(card, 0, 1);
3293 wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
3294 if (gdev->state == CCWGROUP_OFFLINE)
3295 return 0;
3296 if (card->state == CARD_STATE_UP) {
3297 card->use_hard_stop = 1;
3298 __qeth_l3_set_offline(card->gdev, 1);
3299 } else
3300 __qeth_l3_set_offline(card->gdev, 0);
3301 return 0;
3302}
3303
3304static int qeth_l3_pm_resume(struct ccwgroup_device *gdev)
3305{
3306 struct qeth_card *card = dev_get_drvdata(&gdev->dev);
3307 int rc = 0;
3308
3309 if (gdev->state == CCWGROUP_OFFLINE)
3310 goto out;
3311
3312 if (card->state == CARD_STATE_RECOVER) {
3313 rc = __qeth_l3_set_online(card->gdev, 1);
3314 if (rc) {
3315 if (card->dev) {
3316 rtnl_lock();
3317 dev_close(card->dev);
3318 rtnl_unlock();
3319 }
3320 }
3321 } else
3322 rc = __qeth_l3_set_online(card->gdev, 0);
3323out:
3324 qeth_set_allowed_threads(card, 0xffffffff, 0);
3325 if (card->dev)
3326 netif_device_attach(card->dev);
3327 if (rc)
3328 dev_warn(&card->gdev->dev, "The qeth device driver "
3329 "failed to recover an error on the device\n");
3330 return rc;
3331}
3332
3286struct ccwgroup_driver qeth_l3_ccwgroup_driver = { 3333struct ccwgroup_driver qeth_l3_ccwgroup_driver = {
3287 .probe = qeth_l3_probe_device, 3334 .probe = qeth_l3_probe_device,
3288 .remove = qeth_l3_remove_device, 3335 .remove = qeth_l3_remove_device,
3289 .set_online = qeth_l3_set_online, 3336 .set_online = qeth_l3_set_online,
3290 .set_offline = qeth_l3_set_offline, 3337 .set_offline = qeth_l3_set_offline,
3291 .shutdown = qeth_l3_shutdown, 3338 .shutdown = qeth_l3_shutdown,
3339 .freeze = qeth_l3_pm_suspend,
3340 .thaw = qeth_l3_pm_resume,
3341 .restore = qeth_l3_pm_resume,
3292}; 3342};
3293EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver); 3343EXPORT_SYMBOL_GPL(qeth_l3_ccwgroup_driver);
3294 3344
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 164e090c2625..e76a320d373b 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * IUCV special message driver 2 * IUCV special message driver
3 * 3 *
4 * Copyright 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 4 * Copyright IBM Corp. 2003, 2009
5 *
5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
@@ -40,6 +41,8 @@ MODULE_AUTHOR
40MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver"); 41MODULE_DESCRIPTION ("Linux for S/390 IUCV special message driver");
41 42
42static struct iucv_path *smsg_path; 43static struct iucv_path *smsg_path;
44/* dummy device used as trigger for PM functions */
45static struct device *smsg_dev;
43 46
44static DEFINE_SPINLOCK(smsg_list_lock); 47static DEFINE_SPINLOCK(smsg_list_lock);
45static LIST_HEAD(smsg_list); 48static LIST_HEAD(smsg_list);
@@ -132,14 +135,51 @@ void smsg_unregister_callback(char *prefix,
132 kfree(cb); 135 kfree(cb);
133} 136}
134 137
138static int smsg_pm_freeze(struct device *dev)
139{
140#ifdef CONFIG_PM_DEBUG
141 printk(KERN_WARNING "smsg_pm_freeze\n");
142#endif
143 if (smsg_path)
144 iucv_path_sever(smsg_path, NULL);
145 return 0;
146}
147
148static int smsg_pm_restore_thaw(struct device *dev)
149{
150 int rc;
151
152#ifdef CONFIG_PM_DEBUG
153 printk(KERN_WARNING "smsg_pm_restore_thaw\n");
154#endif
155 if (smsg_path) {
156 memset(smsg_path, 0, sizeof(*smsg_path));
157 smsg_path->msglim = 255;
158 smsg_path->flags = 0;
159 rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ",
160 NULL, NULL, NULL);
161 printk(KERN_ERR "iucv_path_connect returned with rc %i\n", rc);
162 }
163 return 0;
164}
165
166static struct dev_pm_ops smsg_pm_ops = {
167 .freeze = smsg_pm_freeze,
168 .thaw = smsg_pm_restore_thaw,
169 .restore = smsg_pm_restore_thaw,
170};
171
135static struct device_driver smsg_driver = { 172static struct device_driver smsg_driver = {
173 .owner = THIS_MODULE,
136 .name = "SMSGIUCV", 174 .name = "SMSGIUCV",
137 .bus = &iucv_bus, 175 .bus = &iucv_bus,
176 .pm = &smsg_pm_ops,
138}; 177};
139 178
140static void __exit smsg_exit(void) 179static void __exit smsg_exit(void)
141{ 180{
142 cpcmd("SET SMSG IUCV", NULL, 0, NULL); 181 cpcmd("SET SMSG IUCV", NULL, 0, NULL);
182 device_unregister(smsg_dev);
143 iucv_unregister(&smsg_handler, 1); 183 iucv_unregister(&smsg_handler, 1);
144 driver_unregister(&smsg_driver); 184 driver_unregister(&smsg_driver);
145} 185}
@@ -166,12 +206,29 @@ static int __init smsg_init(void)
166 rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ", 206 rc = iucv_path_connect(smsg_path, &smsg_handler, "*MSG ",
167 NULL, NULL, NULL); 207 NULL, NULL, NULL);
168 if (rc) 208 if (rc)
169 goto out_free; 209 goto out_free_path;
210 smsg_dev = kzalloc(sizeof(struct device), GFP_KERNEL);
211 if (!smsg_dev) {
212 rc = -ENOMEM;
213 goto out_free_path;
214 }
215 dev_set_name(smsg_dev, "smsg_iucv");
216 smsg_dev->bus = &iucv_bus;
217 smsg_dev->parent = iucv_root;
218 smsg_dev->release = (void (*)(struct device *))kfree;
219 smsg_dev->driver = &smsg_driver;
220 rc = device_register(smsg_dev);
221 if (rc)
222 goto out_free_dev;
223
170 cpcmd("SET SMSG IUCV", NULL, 0, NULL); 224 cpcmd("SET SMSG IUCV", NULL, 0, NULL);
171 return 0; 225 return 0;
172 226
173out_free: 227out_free_dev:
228 kfree(smsg_dev);
229out_free_path:
174 iucv_path_free(smsg_path); 230 iucv_path_free(smsg_path);
231 smsg_path = NULL;
175out_register: 232out_register:
176 iucv_unregister(&smsg_handler, 1); 233 iucv_unregister(&smsg_handler, 1);
177out_driver: 234out_driver:
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index b2fe5cdbcaee..d9da5c42ccbe 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -13,6 +13,36 @@
13 13
14#define ZFCP_MODEL_PRIV 0x4 14#define ZFCP_MODEL_PRIV 0x4
15 15
16static int zfcp_ccw_suspend(struct ccw_device *cdev)
17
18{
19 struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
20
21 down(&zfcp_data.config_sema);
22
23 zfcp_erp_adapter_shutdown(adapter, 0, "ccsusp1", NULL);
24 zfcp_erp_wait(adapter);
25
26 up(&zfcp_data.config_sema);
27
28 return 0;
29}
30
31static int zfcp_ccw_activate(struct ccw_device *cdev)
32
33{
34 struct zfcp_adapter *adapter = dev_get_drvdata(&cdev->dev);
35
36 zfcp_erp_modify_adapter_status(adapter, "ccresu1", NULL,
37 ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
38 zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
39 "ccresu2", NULL);
40 zfcp_erp_wait(adapter);
41 flush_work(&adapter->scan_work);
42
43 return 0;
44}
45
16static struct ccw_device_id zfcp_ccw_device_id[] = { 46static struct ccw_device_id zfcp_ccw_device_id[] = {
17 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) }, 47 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, 0x3) },
18 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) }, 48 { CCW_DEVICE_DEVTYPE(0x1731, 0x3, 0x1732, ZFCP_MODEL_PRIV) },
@@ -227,6 +257,9 @@ static struct ccw_driver zfcp_ccw_driver = {
227 .set_offline = zfcp_ccw_set_offline, 257 .set_offline = zfcp_ccw_set_offline,
228 .notify = zfcp_ccw_notify, 258 .notify = zfcp_ccw_notify,
229 .shutdown = zfcp_ccw_shutdown, 259 .shutdown = zfcp_ccw_shutdown,
260 .freeze = zfcp_ccw_suspend,
261 .thaw = zfcp_ccw_activate,
262 .restore = zfcp_ccw_activate,
230}; 263};
231 264
232/** 265/**
diff --git a/drivers/sbus/char/openprom.c b/drivers/sbus/char/openprom.c
index 124f660a0383..75ac19b1192f 100644
--- a/drivers/sbus/char/openprom.c
+++ b/drivers/sbus/char/openprom.c
@@ -303,7 +303,7 @@ static int openprom_sunos_ioctl(struct inode * inode, struct file * file,
303 struct device_node *dp) 303 struct device_node *dp)
304{ 304{
305 DATA *data = file->private_data; 305 DATA *data = file->private_data;
306 struct openpromio *opp; 306 struct openpromio *opp = NULL;
307 int bufsize, error = 0; 307 int bufsize, error = 0;
308 static int cnt; 308 static int cnt;
309 void __user *argp = (void __user *)arg; 309 void __user *argp = (void __user *)arg;
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index f014cc21e813..011c5bddba6a 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -803,7 +803,7 @@ static void bfin_spi_pump_transfers(unsigned long data)
803 drv_data->rx, drv_data->len_in_bytes); 803 drv_data->rx, drv_data->len_in_bytes);
804 804
805 /* invalidate caches, if needed */ 805 /* invalidate caches, if needed */
806 if (bfin_addr_dcachable((unsigned long) drv_data->rx)) 806 if (bfin_addr_dcacheable((unsigned long) drv_data->rx))
807 invalidate_dcache_range((unsigned long) drv_data->rx, 807 invalidate_dcache_range((unsigned long) drv_data->rx,
808 (unsigned long) (drv_data->rx + 808 (unsigned long) (drv_data->rx +
809 drv_data->len_in_bytes)); 809 drv_data->len_in_bytes));
@@ -816,7 +816,7 @@ static void bfin_spi_pump_transfers(unsigned long data)
816 dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n"); 816 dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
817 817
818 /* flush caches, if needed */ 818 /* flush caches, if needed */
819 if (bfin_addr_dcachable((unsigned long) drv_data->tx)) 819 if (bfin_addr_dcacheable((unsigned long) drv_data->tx))
820 flush_dcache_range((unsigned long) drv_data->tx, 820 flush_dcache_range((unsigned long) drv_data->tx,
821 (unsigned long) (drv_data->tx + 821 (unsigned long) (drv_data->tx +
822 drv_data->len_in_bytes)); 822 drv_data->len_in_bytes));
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
index 1ba9f9a8c308..bb870b8f81bc 100644
--- a/drivers/usb/host/ehci-ps3.c
+++ b/drivers/usb/host/ehci-ps3.c
@@ -162,7 +162,7 @@ static int ps3_ehci_probe(struct ps3_system_bus_device *dev)
162 dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, 162 dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__,
163 (unsigned long)virq); 163 (unsigned long)virq);
164 164
165 ps3_system_bus_set_driver_data(dev, hcd); 165 ps3_system_bus_set_drvdata(dev, hcd);
166 166
167 result = usb_add_hcd(hcd, virq, IRQF_DISABLED); 167 result = usb_add_hcd(hcd, virq, IRQF_DISABLED);
168 168
@@ -195,8 +195,7 @@ fail_start:
195static int ps3_ehci_remove(struct ps3_system_bus_device *dev) 195static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
196{ 196{
197 unsigned int tmp; 197 unsigned int tmp;
198 struct usb_hcd *hcd = 198 struct usb_hcd *hcd = ps3_system_bus_get_drvdata(dev);
199 (struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
200 199
201 BUG_ON(!hcd); 200 BUG_ON(!hcd);
202 201
@@ -208,7 +207,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
208 ehci_shutdown(hcd); 207 ehci_shutdown(hcd);
209 usb_remove_hcd(hcd); 208 usb_remove_hcd(hcd);
210 209
211 ps3_system_bus_set_driver_data(dev, NULL); 210 ps3_system_bus_set_drvdata(dev, NULL);
212 211
213 BUG_ON(!hcd->regs); 212 BUG_ON(!hcd->regs);
214 iounmap(hcd->regs); 213 iounmap(hcd->regs);
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
index 3d1910317328..1d56259c5db1 100644
--- a/drivers/usb/host/ohci-ps3.c
+++ b/drivers/usb/host/ohci-ps3.c
@@ -162,7 +162,7 @@ static int ps3_ohci_probe(struct ps3_system_bus_device *dev)
162 dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, 162 dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__,
163 (unsigned long)virq); 163 (unsigned long)virq);
164 164
165 ps3_system_bus_set_driver_data(dev, hcd); 165 ps3_system_bus_set_drvdata(dev, hcd);
166 166
167 result = usb_add_hcd(hcd, virq, IRQF_DISABLED); 167 result = usb_add_hcd(hcd, virq, IRQF_DISABLED);
168 168
@@ -195,8 +195,7 @@ fail_start:
195static int ps3_ohci_remove(struct ps3_system_bus_device *dev) 195static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
196{ 196{
197 unsigned int tmp; 197 unsigned int tmp;
198 struct usb_hcd *hcd = 198 struct usb_hcd *hcd = ps3_system_bus_get_drvdata(dev);
199 (struct usb_hcd *)ps3_system_bus_get_driver_data(dev);
200 199
201 BUG_ON(!hcd); 200 BUG_ON(!hcd);
202 201
@@ -208,7 +207,7 @@ static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
208 ohci_shutdown(hcd); 207 ohci_shutdown(hcd);
209 usb_remove_hcd(hcd); 208 usb_remove_hcd(hcd);
210 209
211 ps3_system_bus_set_driver_data(dev, NULL); 210 ps3_system_bus_set_drvdata(dev, NULL);
212 211
213 BUG_ON(!hcd->regs); 212 BUG_ON(!hcd->regs);
214 iounmap(hcd->regs); 213 iounmap(hcd->regs);
diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c
index 1e35ba6f18e0..b0b147cb4cb3 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/bw2.c
@@ -111,9 +111,7 @@ struct bw2_par {
111 u32 flags; 111 u32 flags;
112#define BW2_FLAG_BLANKED 0x00000001 112#define BW2_FLAG_BLANKED 0x00000001
113 113
114 unsigned long physbase;
115 unsigned long which_io; 114 unsigned long which_io;
116 unsigned long fbsize;
117}; 115};
118 116
119/** 117/**
@@ -167,17 +165,15 @@ static int bw2_mmap(struct fb_info *info, struct vm_area_struct *vma)
167 struct bw2_par *par = (struct bw2_par *)info->par; 165 struct bw2_par *par = (struct bw2_par *)info->par;
168 166
169 return sbusfb_mmap_helper(bw2_mmap_map, 167 return sbusfb_mmap_helper(bw2_mmap_map,
170 par->physbase, par->fbsize, 168 info->fix.smem_start, info->fix.smem_len,
171 par->which_io, 169 par->which_io,
172 vma); 170 vma);
173} 171}
174 172
175static int bw2_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 173static int bw2_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
176{ 174{
177 struct bw2_par *par = (struct bw2_par *) info->par;
178
179 return sbusfb_ioctl_helper(cmd, arg, info, 175 return sbusfb_ioctl_helper(cmd, arg, info,
180 FBTYPE_SUN2BW, 1, par->fbsize); 176 FBTYPE_SUN2BW, 1, info->fix.smem_len);
181} 177}
182 178
183/* 179/*
@@ -294,7 +290,7 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *
294 290
295 spin_lock_init(&par->lock); 291 spin_lock_init(&par->lock);
296 292
297 par->physbase = op->resource[0].start; 293 info->fix.smem_start = op->resource[0].start;
298 par->which_io = op->resource[0].flags & IORESOURCE_BITS; 294 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
299 295
300 sbusfb_fill_var(&info->var, dp, 1); 296 sbusfb_fill_var(&info->var, dp, 1);
@@ -317,13 +313,13 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *
317 goto out_unmap_regs; 313 goto out_unmap_regs;
318 } 314 }
319 315
320 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); 316 info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
321 317
322 info->flags = FBINFO_DEFAULT; 318 info->flags = FBINFO_DEFAULT;
323 info->fbops = &bw2_ops; 319 info->fbops = &bw2_ops;
324 320
325 info->screen_base = of_ioremap(&op->resource[0], 0, 321 info->screen_base = of_ioremap(&op->resource[0], 0,
326 par->fbsize, "bw2 ram"); 322 info->fix.smem_len, "bw2 ram");
327 if (!info->screen_base) 323 if (!info->screen_base)
328 goto out_unmap_regs; 324 goto out_unmap_regs;
329 325
@@ -338,12 +334,12 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *
338 dev_set_drvdata(&op->dev, info); 334 dev_set_drvdata(&op->dev, info);
339 335
340 printk(KERN_INFO "%s: bwtwo at %lx:%lx\n", 336 printk(KERN_INFO "%s: bwtwo at %lx:%lx\n",
341 dp->full_name, par->which_io, par->physbase); 337 dp->full_name, par->which_io, info->fix.smem_start);
342 338
343 return 0; 339 return 0;
344 340
345out_unmap_screen: 341out_unmap_screen:
346 of_iounmap(&op->resource[0], info->screen_base, par->fbsize); 342 of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);
347 343
348out_unmap_regs: 344out_unmap_regs:
349 of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs)); 345 of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs));
@@ -363,7 +359,7 @@ static int __devexit bw2_remove(struct of_device *op)
363 unregister_framebuffer(info); 359 unregister_framebuffer(info);
364 360
365 of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs)); 361 of_iounmap(&op->resource[0], par->regs, sizeof(struct bw2_regs));
366 of_iounmap(&op->resource[0], info->screen_base, par->fbsize); 362 of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);
367 363
368 framebuffer_release(info); 364 framebuffer_release(info);
369 365
diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c
index a2d1882791a5..fe45a3b8d0e0 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/cg14.c
@@ -196,9 +196,7 @@ struct cg14_par {
196 u32 flags; 196 u32 flags;
197#define CG14_FLAG_BLANKED 0x00000001 197#define CG14_FLAG_BLANKED 0x00000001
198 198
199 unsigned long physbase;
200 unsigned long iospace; 199 unsigned long iospace;
201 unsigned long fbsize;
202 200
203 struct sbus_mmap_map mmap_map[CG14_MMAP_ENTRIES]; 201 struct sbus_mmap_map mmap_map[CG14_MMAP_ENTRIES];
204 202
@@ -271,7 +269,7 @@ static int cg14_mmap(struct fb_info *info, struct vm_area_struct *vma)
271 struct cg14_par *par = (struct cg14_par *) info->par; 269 struct cg14_par *par = (struct cg14_par *) info->par;
272 270
273 return sbusfb_mmap_helper(par->mmap_map, 271 return sbusfb_mmap_helper(par->mmap_map,
274 par->physbase, par->fbsize, 272 info->fix.smem_start, info->fix.smem_len,
275 par->iospace, vma); 273 par->iospace, vma);
276} 274}
277 275
@@ -343,7 +341,8 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
343 341
344 default: 342 default:
345 ret = sbusfb_ioctl_helper(cmd, arg, info, 343 ret = sbusfb_ioctl_helper(cmd, arg, info,
346 FBTYPE_MDICOLOR, 8, par->fbsize); 344 FBTYPE_MDICOLOR, 8,
345 info->fix.smem_len);
347 break; 346 break;
348 }; 347 };
349 348
@@ -462,7 +461,7 @@ static void cg14_unmap_regs(struct of_device *op, struct fb_info *info,
462 par->cursor, sizeof(struct cg14_cursor)); 461 par->cursor, sizeof(struct cg14_cursor));
463 if (info->screen_base) 462 if (info->screen_base)
464 of_iounmap(&op->resource[1], 463 of_iounmap(&op->resource[1],
465 info->screen_base, par->fbsize); 464 info->screen_base, info->fix.smem_len);
466} 465}
467 466
468static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match) 467static int __devinit cg14_probe(struct of_device *op, const struct of_device_id *match)
@@ -488,14 +487,14 @@ static int __devinit cg14_probe(struct of_device *op, const struct of_device_id
488 487
489 linebytes = of_getintprop_default(dp, "linebytes", 488 linebytes = of_getintprop_default(dp, "linebytes",
490 info->var.xres); 489 info->var.xres);
491 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); 490 info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
492 491
493 if (!strcmp(dp->parent->name, "sbus") || 492 if (!strcmp(dp->parent->name, "sbus") ||
494 !strcmp(dp->parent->name, "sbi")) { 493 !strcmp(dp->parent->name, "sbi")) {
495 par->physbase = op->resource[0].start; 494 info->fix.smem_start = op->resource[0].start;
496 par->iospace = op->resource[0].flags & IORESOURCE_BITS; 495 par->iospace = op->resource[0].flags & IORESOURCE_BITS;
497 } else { 496 } else {
498 par->physbase = op->resource[1].start; 497 info->fix.smem_start = op->resource[1].start;
499 par->iospace = op->resource[0].flags & IORESOURCE_BITS; 498 par->iospace = op->resource[0].flags & IORESOURCE_BITS;
500 } 499 }
501 500
@@ -507,7 +506,7 @@ static int __devinit cg14_probe(struct of_device *op, const struct of_device_id
507 sizeof(struct cg14_cursor), "cg14 cursor"); 506 sizeof(struct cg14_cursor), "cg14 cursor");
508 507
509 info->screen_base = of_ioremap(&op->resource[1], 0, 508 info->screen_base = of_ioremap(&op->resource[1], 0,
510 par->fbsize, "cg14 ram"); 509 info->fix.smem_len, "cg14 ram");
511 510
512 if (!par->regs || !par->clut || !par->cursor || !info->screen_base) 511 if (!par->regs || !par->clut || !par->cursor || !info->screen_base)
513 goto out_unmap_regs; 512 goto out_unmap_regs;
@@ -557,7 +556,7 @@ static int __devinit cg14_probe(struct of_device *op, const struct of_device_id
557 556
558 printk(KERN_INFO "%s: cgfourteen at %lx:%lx, %dMB\n", 557 printk(KERN_INFO "%s: cgfourteen at %lx:%lx, %dMB\n",
559 dp->full_name, 558 dp->full_name,
560 par->iospace, par->physbase, 559 par->iospace, info->fix.smem_start,
561 par->ramsize >> 20); 560 par->ramsize >> 20);
562 561
563 return 0; 562 return 0;
diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c
index 99f87fb61d05..b2319fa7286f 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/cg3.c
@@ -118,9 +118,7 @@ struct cg3_par {
118#define CG3_FLAG_BLANKED 0x00000001 118#define CG3_FLAG_BLANKED 0x00000001
119#define CG3_FLAG_RDI 0x00000002 119#define CG3_FLAG_RDI 0x00000002
120 120
121 unsigned long physbase;
122 unsigned long which_io; 121 unsigned long which_io;
123 unsigned long fbsize;
124}; 122};
125 123
126/** 124/**
@@ -231,17 +229,15 @@ static int cg3_mmap(struct fb_info *info, struct vm_area_struct *vma)
231 struct cg3_par *par = (struct cg3_par *)info->par; 229 struct cg3_par *par = (struct cg3_par *)info->par;
232 230
233 return sbusfb_mmap_helper(cg3_mmap_map, 231 return sbusfb_mmap_helper(cg3_mmap_map,
234 par->physbase, par->fbsize, 232 info->fix.smem_start, info->fix.smem_len,
235 par->which_io, 233 par->which_io,
236 vma); 234 vma);
237} 235}
238 236
239static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 237static int cg3_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
240{ 238{
241 struct cg3_par *par = (struct cg3_par *) info->par;
242
243 return sbusfb_ioctl_helper(cmd, arg, info, 239 return sbusfb_ioctl_helper(cmd, arg, info,
244 FBTYPE_SUN3COLOR, 8, par->fbsize); 240 FBTYPE_SUN3COLOR, 8, info->fix.smem_len);
245} 241}
246 242
247/* 243/*
@@ -368,7 +364,7 @@ static int __devinit cg3_probe(struct of_device *op,
368 364
369 spin_lock_init(&par->lock); 365 spin_lock_init(&par->lock);
370 366
371 par->physbase = op->resource[0].start; 367 info->fix.smem_start = op->resource[0].start;
372 par->which_io = op->resource[0].flags & IORESOURCE_BITS; 368 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
373 369
374 sbusfb_fill_var(&info->var, dp, 8); 370 sbusfb_fill_var(&info->var, dp, 8);
@@ -382,7 +378,7 @@ static int __devinit cg3_probe(struct of_device *op,
382 378
383 linebytes = of_getintprop_default(dp, "linebytes", 379 linebytes = of_getintprop_default(dp, "linebytes",
384 info->var.xres); 380 info->var.xres);
385 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); 381 info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
386 382
387 par->regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET, 383 par->regs = of_ioremap(&op->resource[0], CG3_REGS_OFFSET,
388 sizeof(struct cg3_regs), "cg3 regs"); 384 sizeof(struct cg3_regs), "cg3 regs");
@@ -392,7 +388,7 @@ static int __devinit cg3_probe(struct of_device *op,
392 info->flags = FBINFO_DEFAULT; 388 info->flags = FBINFO_DEFAULT;
393 info->fbops = &cg3_ops; 389 info->fbops = &cg3_ops;
394 info->screen_base = of_ioremap(&op->resource[0], CG3_RAM_OFFSET, 390 info->screen_base = of_ioremap(&op->resource[0], CG3_RAM_OFFSET,
395 par->fbsize, "cg3 ram"); 391 info->fix.smem_len, "cg3 ram");
396 if (!info->screen_base) 392 if (!info->screen_base)
397 goto out_unmap_regs; 393 goto out_unmap_regs;
398 394
@@ -418,7 +414,7 @@ static int __devinit cg3_probe(struct of_device *op,
418 dev_set_drvdata(&op->dev, info); 414 dev_set_drvdata(&op->dev, info);
419 415
420 printk(KERN_INFO "%s: cg3 at %lx:%lx\n", 416 printk(KERN_INFO "%s: cg3 at %lx:%lx\n",
421 dp->full_name, par->which_io, par->physbase); 417 dp->full_name, par->which_io, info->fix.smem_start);
422 418
423 return 0; 419 return 0;
424 420
@@ -426,7 +422,7 @@ out_dealloc_cmap:
426 fb_dealloc_cmap(&info->cmap); 422 fb_dealloc_cmap(&info->cmap);
427 423
428out_unmap_screen: 424out_unmap_screen:
429 of_iounmap(&op->resource[0], info->screen_base, par->fbsize); 425 of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);
430 426
431out_unmap_regs: 427out_unmap_regs:
432 of_iounmap(&op->resource[0], par->regs, sizeof(struct cg3_regs)); 428 of_iounmap(&op->resource[0], par->regs, sizeof(struct cg3_regs));
@@ -447,7 +443,7 @@ static int __devexit cg3_remove(struct of_device *op)
447 fb_dealloc_cmap(&info->cmap); 443 fb_dealloc_cmap(&info->cmap);
448 444
449 of_iounmap(&op->resource[0], par->regs, sizeof(struct cg3_regs)); 445 of_iounmap(&op->resource[0], par->regs, sizeof(struct cg3_regs));
450 of_iounmap(&op->resource[0], info->screen_base, par->fbsize); 446 of_iounmap(&op->resource[0], info->screen_base, info->fix.smem_len);
451 447
452 framebuffer_release(info); 448 framebuffer_release(info);
453 449
diff --git a/drivers/video/cg6.c b/drivers/video/cg6.c
index 940ec04f0f1b..0d47c6030e3d 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/cg6.c
@@ -263,9 +263,7 @@ struct cg6_par {
263 u32 flags; 263 u32 flags;
264#define CG6_FLAG_BLANKED 0x00000001 264#define CG6_FLAG_BLANKED 0x00000001
265 265
266 unsigned long physbase;
267 unsigned long which_io; 266 unsigned long which_io;
268 unsigned long fbsize;
269}; 267};
270 268
271static int cg6_sync(struct fb_info *info) 269static int cg6_sync(struct fb_info *info)
@@ -596,16 +594,14 @@ static int cg6_mmap(struct fb_info *info, struct vm_area_struct *vma)
596 struct cg6_par *par = (struct cg6_par *)info->par; 594 struct cg6_par *par = (struct cg6_par *)info->par;
597 595
598 return sbusfb_mmap_helper(cg6_mmap_map, 596 return sbusfb_mmap_helper(cg6_mmap_map,
599 par->physbase, par->fbsize, 597 info->fix.smem_start, info->fix.smem_len,
600 par->which_io, vma); 598 par->which_io, vma);
601} 599}
602 600
603static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 601static int cg6_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
604{ 602{
605 struct cg6_par *par = (struct cg6_par *)info->par;
606
607 return sbusfb_ioctl_helper(cmd, arg, info, 603 return sbusfb_ioctl_helper(cmd, arg, info,
608 FBTYPE_SUNFAST_COLOR, 8, par->fbsize); 604 FBTYPE_SUNFAST_COLOR, 8, info->fix.smem_len);
609} 605}
610 606
611/* 607/*
@@ -631,12 +627,12 @@ static void __devinit cg6_init_fix(struct fb_info *info, int linebytes)
631 break; 627 break;
632 }; 628 };
633 if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) { 629 if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) {
634 if (par->fbsize <= 0x100000) 630 if (info->fix.smem_len <= 0x100000)
635 cg6_card_name = "TGX"; 631 cg6_card_name = "TGX";
636 else 632 else
637 cg6_card_name = "TGX+"; 633 cg6_card_name = "TGX+";
638 } else { 634 } else {
639 if (par->fbsize <= 0x100000) 635 if (info->fix.smem_len <= 0x100000)
640 cg6_card_name = "GX"; 636 cg6_card_name = "GX";
641 else 637 else
642 cg6_card_name = "GX+"; 638 cg6_card_name = "GX+";
@@ -738,7 +734,8 @@ static void cg6_unmap_regs(struct of_device *op, struct fb_info *info,
738 of_iounmap(&op->resource[0], par->fhc, sizeof(u32)); 734 of_iounmap(&op->resource[0], par->fhc, sizeof(u32));
739 735
740 if (info->screen_base) 736 if (info->screen_base)
741 of_iounmap(&op->resource[0], info->screen_base, par->fbsize); 737 of_iounmap(&op->resource[0], info->screen_base,
738 info->fix.smem_len);
742} 739}
743 740
744static int __devinit cg6_probe(struct of_device *op, 741static int __devinit cg6_probe(struct of_device *op,
@@ -759,7 +756,7 @@ static int __devinit cg6_probe(struct of_device *op,
759 756
760 spin_lock_init(&par->lock); 757 spin_lock_init(&par->lock);
761 758
762 par->physbase = op->resource[0].start; 759 info->fix.smem_start = op->resource[0].start;
763 par->which_io = op->resource[0].flags & IORESOURCE_BITS; 760 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
764 761
765 sbusfb_fill_var(&info->var, dp, 8); 762 sbusfb_fill_var(&info->var, dp, 8);
@@ -769,11 +766,11 @@ static int __devinit cg6_probe(struct of_device *op,
769 766
770 linebytes = of_getintprop_default(dp, "linebytes", 767 linebytes = of_getintprop_default(dp, "linebytes",
771 info->var.xres); 768 info->var.xres);
772 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); 769 info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
773 770
774 dblbuf = of_getintprop_default(dp, "dblbuf", 0); 771 dblbuf = of_getintprop_default(dp, "dblbuf", 0);
775 if (dblbuf) 772 if (dblbuf)
776 par->fbsize *= 4; 773 info->fix.smem_len *= 4;
777 774
778 par->fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET, 775 par->fbc = of_ioremap(&op->resource[0], CG6_FBC_OFFSET,
779 4096, "cgsix fbc"); 776 4096, "cgsix fbc");
@@ -792,7 +789,7 @@ static int __devinit cg6_probe(struct of_device *op,
792 info->fbops = &cg6_ops; 789 info->fbops = &cg6_ops;
793 790
794 info->screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET, 791 info->screen_base = of_ioremap(&op->resource[0], CG6_RAM_OFFSET,
795 par->fbsize, "cgsix ram"); 792 info->fix.smem_len, "cgsix ram");
796 if (!par->fbc || !par->tec || !par->thc || 793 if (!par->fbc || !par->tec || !par->thc ||
797 !par->bt || !par->fhc || !info->screen_base) 794 !par->bt || !par->fhc || !info->screen_base)
798 goto out_unmap_regs; 795 goto out_unmap_regs;
@@ -817,7 +814,7 @@ static int __devinit cg6_probe(struct of_device *op,
817 814
818 printk(KERN_INFO "%s: CGsix [%s] at %lx:%lx\n", 815 printk(KERN_INFO "%s: CGsix [%s] at %lx:%lx\n",
819 dp->full_name, info->fix.id, 816 dp->full_name, info->fix.id,
820 par->which_io, par->physbase); 817 par->which_io, info->fix.smem_start);
821 818
822 return 0; 819 return 0;
823 820
diff --git a/drivers/video/leo.c b/drivers/video/leo.c
index 7c7e8c2da9d9..e145e2d16fe3 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/leo.c
@@ -191,9 +191,7 @@ struct leo_par {
191 u32 flags; 191 u32 flags;
192#define LEO_FLAG_BLANKED 0x00000001 192#define LEO_FLAG_BLANKED 0x00000001
193 193
194 unsigned long physbase;
195 unsigned long which_io; 194 unsigned long which_io;
196 unsigned long fbsize;
197}; 195};
198 196
199static void leo_wait(struct leo_lx_krn __iomem *lx_krn) 197static void leo_wait(struct leo_lx_krn __iomem *lx_krn)
@@ -420,16 +418,14 @@ static int leo_mmap(struct fb_info *info, struct vm_area_struct *vma)
420 struct leo_par *par = (struct leo_par *)info->par; 418 struct leo_par *par = (struct leo_par *)info->par;
421 419
422 return sbusfb_mmap_helper(leo_mmap_map, 420 return sbusfb_mmap_helper(leo_mmap_map,
423 par->physbase, par->fbsize, 421 info->fix.smem_start, info->fix.smem_len,
424 par->which_io, vma); 422 par->which_io, vma);
425} 423}
426 424
427static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 425static int leo_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
428{ 426{
429 struct leo_par *par = (struct leo_par *) info->par;
430
431 return sbusfb_ioctl_helper(cmd, arg, info, 427 return sbusfb_ioctl_helper(cmd, arg, info,
432 FBTYPE_SUNLEO, 32, par->fbsize); 428 FBTYPE_SUNLEO, 32, info->fix.smem_len);
433} 429}
434 430
435/* 431/*
@@ -569,7 +565,7 @@ static int __devinit leo_probe(struct of_device *op,
569 565
570 spin_lock_init(&par->lock); 566 spin_lock_init(&par->lock);
571 567
572 par->physbase = op->resource[0].start; 568 info->fix.smem_start = op->resource[0].start;
573 par->which_io = op->resource[0].flags & IORESOURCE_BITS; 569 par->which_io = op->resource[0].flags & IORESOURCE_BITS;
574 570
575 sbusfb_fill_var(&info->var, dp, 32); 571 sbusfb_fill_var(&info->var, dp, 32);
@@ -577,7 +573,7 @@ static int __devinit leo_probe(struct of_device *op,
577 573
578 linebytes = of_getintprop_default(dp, "linebytes", 574 linebytes = of_getintprop_default(dp, "linebytes",
579 info->var.xres); 575 info->var.xres);
580 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); 576 info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
581 577
582 par->lc_ss0_usr = 578 par->lc_ss0_usr =
583 of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR, 579 of_ioremap(&op->resource[0], LEO_OFF_LC_SS0_USR,
@@ -627,7 +623,7 @@ static int __devinit leo_probe(struct of_device *op,
627 623
628 printk(KERN_INFO "%s: leo at %lx:%lx\n", 624 printk(KERN_INFO "%s: leo at %lx:%lx\n",
629 dp->full_name, 625 dp->full_name,
630 par->which_io, par->physbase); 626 par->which_io, info->fix.smem_start);
631 627
632 return 0; 628 return 0;
633 629
diff --git a/drivers/video/p9100.c b/drivers/video/p9100.c
index 7000f2cd5854..7fa4ab01b0d3 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/p9100.c
@@ -134,9 +134,7 @@ struct p9100_par {
134 u32 flags; 134 u32 flags;
135#define P9100_FLAG_BLANKED 0x00000001 135#define P9100_FLAG_BLANKED 0x00000001
136 136
137 unsigned long physbase;
138 unsigned long which_io; 137 unsigned long which_io;
139 unsigned long fbsize;
140}; 138};
141 139
142/** 140/**
@@ -224,18 +222,16 @@ static int p9100_mmap(struct fb_info *info, struct vm_area_struct *vma)
224 struct p9100_par *par = (struct p9100_par *)info->par; 222 struct p9100_par *par = (struct p9100_par *)info->par;
225 223
226 return sbusfb_mmap_helper(p9100_mmap_map, 224 return sbusfb_mmap_helper(p9100_mmap_map,
227 par->physbase, par->fbsize, 225 info->fix.smem_start, info->fix.smem_len,
228 par->which_io, vma); 226 par->which_io, vma);
229} 227}
230 228
231static int p9100_ioctl(struct fb_info *info, unsigned int cmd, 229static int p9100_ioctl(struct fb_info *info, unsigned int cmd,
232 unsigned long arg) 230 unsigned long arg)
233{ 231{
234 struct p9100_par *par = (struct p9100_par *) info->par;
235
236 /* Make it look like a cg3. */ 232 /* Make it look like a cg3. */
237 return sbusfb_ioctl_helper(cmd, arg, info, 233 return sbusfb_ioctl_helper(cmd, arg, info,
238 FBTYPE_SUN3COLOR, 8, par->fbsize); 234 FBTYPE_SUN3COLOR, 8, info->fix.smem_len);
239} 235}
240 236
241/* 237/*
@@ -271,7 +267,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id
271 spin_lock_init(&par->lock); 267 spin_lock_init(&par->lock);
272 268
273 /* This is the framebuffer and the only resource apps can mmap. */ 269 /* This is the framebuffer and the only resource apps can mmap. */
274 par->physbase = op->resource[2].start; 270 info->fix.smem_start = op->resource[2].start;
275 par->which_io = op->resource[2].flags & IORESOURCE_BITS; 271 par->which_io = op->resource[2].flags & IORESOURCE_BITS;
276 272
277 sbusfb_fill_var(&info->var, dp, 8); 273 sbusfb_fill_var(&info->var, dp, 8);
@@ -280,7 +276,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id
280 info->var.blue.length = 8; 276 info->var.blue.length = 8;
281 277
282 linebytes = of_getintprop_default(dp, "linebytes", info->var.xres); 278 linebytes = of_getintprop_default(dp, "linebytes", info->var.xres);
283 par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); 279 info->fix.smem_len = PAGE_ALIGN(linebytes * info->var.yres);
284 280
285 par->regs = of_ioremap(&op->resource[0], 0, 281 par->regs = of_ioremap(&op->resource[0], 0,
286 sizeof(struct p9100_regs), "p9100 regs"); 282 sizeof(struct p9100_regs), "p9100 regs");
@@ -290,7 +286,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id
290 info->flags = FBINFO_DEFAULT; 286 info->flags = FBINFO_DEFAULT;
291 info->fbops = &p9100_ops; 287 info->fbops = &p9100_ops;
292 info->screen_base = of_ioremap(&op->resource[2], 0, 288 info->screen_base = of_ioremap(&op->resource[2], 0,
293 par->fbsize, "p9100 ram"); 289 info->fix.smem_len, "p9100 ram");
294 if (!info->screen_base) 290 if (!info->screen_base)
295 goto out_unmap_regs; 291 goto out_unmap_regs;
296 292
@@ -311,7 +307,7 @@ static int __devinit p9100_probe(struct of_device *op, const struct of_device_id
311 307
312 printk(KERN_INFO "%s: p9100 at %lx:%lx\n", 308 printk(KERN_INFO "%s: p9100 at %lx:%lx\n",
313 dp->full_name, 309 dp->full_name,
314 par->which_io, par->physbase); 310 par->which_io, info->fix.smem_start);
315 311
316 return 0; 312 return 0;
317 313
@@ -319,7 +315,7 @@ out_dealloc_cmap:
319 fb_dealloc_cmap(&info->cmap); 315 fb_dealloc_cmap(&info->cmap);
320 316
321out_unmap_screen: 317out_unmap_screen:
322 of_iounmap(&op->resource[2], info->screen_base, par->fbsize); 318 of_iounmap(&op->resource[2], info->screen_base, info->fix.smem_len);
323 319
324out_unmap_regs: 320out_unmap_regs:
325 of_iounmap(&op->resource[0], par->regs, sizeof(struct p9100_regs)); 321 of_iounmap(&op->resource[0], par->regs, sizeof(struct p9100_regs));
@@ -340,7 +336,7 @@ static int __devexit p9100_remove(struct of_device *op)
340 fb_dealloc_cmap(&info->cmap); 336 fb_dealloc_cmap(&info->cmap);
341 337
342 of_iounmap(&op->resource[0], par->regs, sizeof(struct p9100_regs)); 338 of_iounmap(&op->resource[0], par->regs, sizeof(struct p9100_regs));
343 of_iounmap(&op->resource[2], info->screen_base, par->fbsize); 339 of_iounmap(&op->resource[2], info->screen_base, info->fix.smem_len);
344 340
345 framebuffer_release(info); 341 framebuffer_release(info);
346 342
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index e00c1dff55de..c0af638fe702 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -32,25 +32,16 @@
32#include <linux/init.h> 32#include <linux/init.h>
33 33
34#include <asm/abs_addr.h> 34#include <asm/abs_addr.h>
35#include <asm/iommu.h>
35#include <asm/lv1call.h> 36#include <asm/lv1call.h>
36#include <asm/ps3av.h> 37#include <asm/ps3av.h>
37#include <asm/ps3fb.h> 38#include <asm/ps3fb.h>
38#include <asm/ps3.h> 39#include <asm/ps3.h>
40#include <asm/ps3gpu.h>
39 41
40 42
41#define DEVICE_NAME "ps3fb" 43#define DEVICE_NAME "ps3fb"
42 44
43#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
44#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
45#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
46#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
47#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602
48
49#define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32)
50
51#define L1GPU_DISPLAY_SYNC_HSYNC 1
52#define L1GPU_DISPLAY_SYNC_VSYNC 2
53
54#define GPU_CMD_BUF_SIZE (2 * 1024 * 1024) 45#define GPU_CMD_BUF_SIZE (2 * 1024 * 1024)
55#define GPU_FB_START (64 * 1024) 46#define GPU_FB_START (64 * 1024)
56#define GPU_IOIF (0x0d000000UL) 47#define GPU_IOIF (0x0d000000UL)
@@ -462,33 +453,27 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
462 src_offset += GPU_FB_START; 453 src_offset += GPU_FB_START;
463 454
464 mutex_lock(&ps3_gpu_mutex); 455 mutex_lock(&ps3_gpu_mutex);
465 status = lv1_gpu_context_attribute(ps3fb.context_handle, 456 status = lv1_gpu_fb_blit(ps3fb.context_handle, dst_offset,
466 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 457 GPU_IOIF + src_offset,
467 dst_offset, GPU_IOIF + src_offset, 458 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
468 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | 459 (width << 16) | height,
469 (width << 16) | height, 460 line_length);
470 line_length);
471 mutex_unlock(&ps3_gpu_mutex); 461 mutex_unlock(&ps3_gpu_mutex);
472 462
473 if (status) 463 if (status)
474 dev_err(dev, 464 dev_err(dev, "%s: lv1_gpu_fb_blit failed: %d\n", __func__,
475 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", 465 status);
476 __func__, status);
477#ifdef HEAD_A 466#ifdef HEAD_A
478 status = lv1_gpu_context_attribute(ps3fb.context_handle, 467 status = lv1_gpu_display_flip(ps3fb.context_handle, 0, frame_offset);
479 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
480 0, frame_offset, 0, 0);
481 if (status) 468 if (status)
482 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 469 dev_err(dev, "%s: lv1_gpu_display_flip failed: %d\n", __func__,
483 __func__, status); 470 status);
484#endif 471#endif
485#ifdef HEAD_B 472#ifdef HEAD_B
486 status = lv1_gpu_context_attribute(ps3fb.context_handle, 473 status = lv1_gpu_display_flip(ps3fb.context_handle, 1, frame_offset);
487 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
488 1, frame_offset, 0, 0);
489 if (status) 474 if (status)
490 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 475 dev_err(dev, "%s: lv1_gpu_display_flip failed: %d\n", __func__,
491 __func__, status); 476 status);
492#endif 477#endif
493} 478}
494 479
@@ -956,73 +941,6 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
956} 941}
957 942
958 943
959static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
960 struct device *dev)
961{
962 int error;
963
964 dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver);
965 dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet);
966 dev_dbg(dev,
967 "version_gpu: %x memory_size: %x ch: %x core_freq: %d "
968 "mem_freq:%d\n",
969 dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel,
970 dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
971
972 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
973 dev_err(dev, "%s: version_driver err:%x\n", __func__,
974 dinfo->version_driver);
975 return -EINVAL;
976 }
977
978 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
979 &ps3fb.irq_no);
980 if (error) {
981 dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error);
982 return error;
983 }
984
985 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
986 DEVICE_NAME, dev);
987 if (error) {
988 dev_err(dev, "%s: request_irq failed %d\n", __func__, error);
989 ps3_irq_plug_destroy(ps3fb.irq_no);
990 return error;
991 }
992
993 dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) |
994 (1 << GPU_INTR_STATUS_FLIP_1);
995 return 0;
996}
997
998static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
999{
1000 int status;
1001
1002 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
1003 xdr_lpar, ps3fb_videomemory.size, 0);
1004 if (status) {
1005 dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n",
1006 __func__, status);
1007 return -ENXIO;
1008 }
1009 dev_dbg(dev, "video:%p ioif:%lx lpar:%llx size:%lx\n",
1010 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
1011 ps3fb_videomemory.size);
1012
1013 status = lv1_gpu_context_attribute(ps3fb.context_handle,
1014 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
1015 xdr_lpar, GPU_CMD_BUF_SIZE,
1016 GPU_IOIF, 0);
1017 if (status) {
1018 dev_err(dev,
1019 "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
1020 __func__, status);
1021 return -ENXIO;
1022 }
1023 return 0;
1024}
1025
1026static struct fb_ops ps3fb_ops = { 944static struct fb_ops ps3fb_ops = {
1027 .fb_open = ps3fb_open, 945 .fb_open = ps3fb_open,
1028 .fb_release = ps3fb_release, 946 .fb_release = ps3fb_release,
@@ -1048,49 +966,18 @@ static struct fb_fix_screeninfo ps3fb_fix __initdata = {
1048 .accel = FB_ACCEL_NONE, 966 .accel = FB_ACCEL_NONE,
1049}; 967};
1050 968
1051static int ps3fb_set_sync(struct device *dev)
1052{
1053 int status;
1054
1055#ifdef HEAD_A
1056 status = lv1_gpu_context_attribute(0x0,
1057 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
1058 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
1059 if (status) {
1060 dev_err(dev,
1061 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1062 "%d\n",
1063 __func__, status);
1064 return -1;
1065 }
1066#endif
1067#ifdef HEAD_B
1068 status = lv1_gpu_context_attribute(0x0,
1069 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
1070 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
1071
1072 if (status) {
1073 dev_err(dev,
1074 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1075 "%d\n",
1076 __func__, status);
1077 return -1;
1078 }
1079#endif
1080 return 0;
1081}
1082
1083static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) 969static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1084{ 970{
1085 struct fb_info *info; 971 struct fb_info *info;
1086 struct ps3fb_par *par; 972 struct ps3fb_par *par;
1087 int retval = -ENOMEM; 973 int retval;
1088 u64 ddr_lpar = 0; 974 u64 ddr_lpar = 0;
1089 u64 lpar_dma_control = 0; 975 u64 lpar_dma_control = 0;
1090 u64 lpar_driver_info = 0; 976 u64 lpar_driver_info = 0;
1091 u64 lpar_reports = 0; 977 u64 lpar_reports = 0;
1092 u64 lpar_reports_size = 0; 978 u64 lpar_reports_size = 0;
1093 u64 xdr_lpar; 979 u64 xdr_lpar;
980 struct gpu_driver_info *dinfo;
1094 void *fb_start; 981 void *fb_start;
1095 int status; 982 int status;
1096 struct task_struct *task; 983 struct task_struct *task;
@@ -1101,8 +988,8 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1101 return -ENOMEM; 988 return -ENOMEM;
1102 } 989 }
1103 990
1104 status = ps3_open_hv_device(dev); 991 retval = ps3_open_hv_device(dev);
1105 if (status) { 992 if (retval) {
1106 dev_err(&dev->core, "%s: ps3_open_hv_device failed\n", 993 dev_err(&dev->core, "%s: ps3_open_hv_device failed\n",
1107 __func__); 994 __func__);
1108 goto err; 995 goto err;
@@ -1116,7 +1003,24 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1116 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ 1003 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
1117 init_waitqueue_head(&ps3fb.wait_vsync); 1004 init_waitqueue_head(&ps3fb.wait_vsync);
1118 1005
1119 ps3fb_set_sync(&dev->core); 1006#ifdef HEAD_A
1007 status = lv1_gpu_display_sync(0x0, 0, L1GPU_DISPLAY_SYNC_VSYNC);
1008 if (status) {
1009 dev_err(&dev->core, "%s: lv1_gpu_display_sync failed: %d\n",
1010 __func__, status);
1011 retval = -ENODEV;
1012 goto err_close_device;
1013 }
1014#endif
1015#ifdef HEAD_B
1016 status = lv1_gpu_display_sync(0x0, 1, L1GPU_DISPLAY_SYNC_VSYNC);
1017 if (status) {
1018 dev_err(&dev->core, "%s: lv1_gpu_display_sync failed: %d\n",
1019 __func__, status);
1020 retval = -ENODEV;
1021 goto err_close_device;
1022 }
1023#endif
1120 1024
1121 max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF; 1025 max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
1122 if (ps3fb_videomemory.size > max_ps3fb_size) { 1026 if (ps3fb_videomemory.size > max_ps3fb_size) {
@@ -1131,7 +1035,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1131 if (status) { 1035 if (status) {
1132 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n", 1036 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
1133 __func__, status); 1037 __func__, status);
1134 goto err; 1038 goto err_close_device;
1135 } 1039 }
1136 dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar); 1040 dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar);
1137 1041
@@ -1141,33 +1045,85 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1141 &lpar_reports, &lpar_reports_size); 1045 &lpar_reports, &lpar_reports_size);
1142 if (status) { 1046 if (status) {
1143 dev_err(&dev->core, 1047 dev_err(&dev->core,
1144 "%s: lv1_gpu_context_attribute failed: %d\n", __func__, 1048 "%s: lv1_gpu_context_allocate failed: %d\n", __func__,
1145 status); 1049 status);
1146 goto err_gpu_memory_free; 1050 goto err_gpu_memory_free;
1147 } 1051 }
1148 1052
1149 /* vsync interrupt */ 1053 /* vsync interrupt */
1150 ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024); 1054 dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
1151 if (!ps3fb.dinfo) { 1055 if (!dinfo) {
1152 dev_err(&dev->core, "%s: ioremap failed\n", __func__); 1056 dev_err(&dev->core, "%s: ioremap failed\n", __func__);
1153 goto err_gpu_context_free; 1057 goto err_gpu_context_free;
1154 } 1058 }
1155 1059
1156 retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core); 1060 ps3fb.dinfo = dinfo;
1157 if (retval) 1061 dev_dbg(&dev->core, "version_driver:%x\n", dinfo->version_driver);
1062 dev_dbg(&dev->core, "irq outlet:%x\n", dinfo->irq.irq_outlet);
1063 dev_dbg(&dev->core, "version_gpu: %x memory_size: %x ch: %x "
1064 "core_freq: %d mem_freq:%d\n", dinfo->version_gpu,
1065 dinfo->memory_size, dinfo->hardware_channel,
1066 dinfo->nvcore_frequency/1000000,
1067 dinfo->memory_frequency/1000000);
1068
1069 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
1070 dev_err(&dev->core, "%s: version_driver err:%x\n", __func__,
1071 dinfo->version_driver);
1072 retval = -EINVAL;
1073 goto err_iounmap_dinfo;
1074 }
1075
1076 retval = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
1077 &ps3fb.irq_no);
1078 if (retval) {
1079 dev_err(&dev->core, "%s: ps3_alloc_irq failed %d\n", __func__,
1080 retval);
1158 goto err_iounmap_dinfo; 1081 goto err_iounmap_dinfo;
1082 }
1083
1084 retval = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt,
1085 IRQF_DISABLED, DEVICE_NAME, &dev->core);
1086 if (retval) {
1087 dev_err(&dev->core, "%s: request_irq failed %d\n", __func__,
1088 retval);
1089 goto err_destroy_plug;
1090 }
1091
1092 dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) |
1093 (1 << GPU_INTR_STATUS_FLIP_1);
1159 1094
1160 /* Clear memory to prevent kernel info leakage into userspace */ 1095 /* Clear memory to prevent kernel info leakage into userspace */
1161 memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size); 1096 memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size);
1162 1097
1163 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address)); 1098 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
1164 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); 1099
1165 if (retval) 1100 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
1101 xdr_lpar, ps3fb_videomemory.size,
1102 CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
1103 CBE_IOPTE_M);
1104 if (status) {
1105 dev_err(&dev->core, "%s: lv1_gpu_context_iomap failed: %d\n",
1106 __func__, status);
1107 retval = -ENXIO;
1166 goto err_free_irq; 1108 goto err_free_irq;
1109 }
1110
1111 dev_dbg(&dev->core, "video:%p ioif:%lx lpar:%llx size:%lx\n",
1112 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
1113 ps3fb_videomemory.size);
1114
1115 status = lv1_gpu_fb_setup(ps3fb.context_handle, xdr_lpar,
1116 GPU_CMD_BUF_SIZE, GPU_IOIF);
1117 if (status) {
1118 dev_err(&dev->core, "%s: lv1_gpu_fb_setup failed: %d\n",
1119 __func__, status);
1120 retval = -ENXIO;
1121 goto err_context_unmap;
1122 }
1167 1123
1168 info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core); 1124 info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
1169 if (!info) 1125 if (!info)
1170 goto err_free_irq; 1126 goto err_context_fb_close;
1171 1127
1172 par = info->par; 1128 par = info->par;
1173 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ 1129 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
@@ -1210,7 +1166,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1210 if (retval < 0) 1166 if (retval < 0)
1211 goto err_fb_dealloc; 1167 goto err_fb_dealloc;
1212 1168
1213 dev->core.driver_data = info; 1169 ps3_system_bus_set_drvdata(dev, info);
1214 1170
1215 dev_info(info->device, "%s %s, using %u KiB of video memory\n", 1171 dev_info(info->device, "%s %s, using %u KiB of video memory\n",
1216 dev_driver_string(info->dev), dev_name(info->dev), 1172 dev_driver_string(info->dev), dev_name(info->dev),
@@ -1232,8 +1188,14 @@ err_fb_dealloc:
1232 fb_dealloc_cmap(&info->cmap); 1188 fb_dealloc_cmap(&info->cmap);
1233err_framebuffer_release: 1189err_framebuffer_release:
1234 framebuffer_release(info); 1190 framebuffer_release(info);
1191err_context_fb_close:
1192 lv1_gpu_fb_close(ps3fb.context_handle);
1193err_context_unmap:
1194 lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, xdr_lpar,
1195 ps3fb_videomemory.size, CBE_IOPTE_M);
1235err_free_irq: 1196err_free_irq:
1236 free_irq(ps3fb.irq_no, &dev->core); 1197 free_irq(ps3fb.irq_no, &dev->core);
1198err_destroy_plug:
1237 ps3_irq_plug_destroy(ps3fb.irq_no); 1199 ps3_irq_plug_destroy(ps3fb.irq_no);
1238err_iounmap_dinfo: 1200err_iounmap_dinfo:
1239 iounmap((u8 __force __iomem *)ps3fb.dinfo); 1201 iounmap((u8 __force __iomem *)ps3fb.dinfo);
@@ -1241,14 +1203,16 @@ err_gpu_context_free:
1241 lv1_gpu_context_free(ps3fb.context_handle); 1203 lv1_gpu_context_free(ps3fb.context_handle);
1242err_gpu_memory_free: 1204err_gpu_memory_free:
1243 lv1_gpu_memory_free(ps3fb.memory_handle); 1205 lv1_gpu_memory_free(ps3fb.memory_handle);
1206err_close_device:
1207 ps3_close_hv_device(dev);
1244err: 1208err:
1245 return retval; 1209 return retval;
1246} 1210}
1247 1211
1248static int ps3fb_shutdown(struct ps3_system_bus_device *dev) 1212static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1249{ 1213{
1250 int status; 1214 struct fb_info *info = ps3_system_bus_get_drvdata(dev);
1251 struct fb_info *info = dev->core.driver_data; 1215 u64 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
1252 1216
1253 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__); 1217 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1254 1218
@@ -1268,20 +1232,14 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1268 unregister_framebuffer(info); 1232 unregister_framebuffer(info);
1269 fb_dealloc_cmap(&info->cmap); 1233 fb_dealloc_cmap(&info->cmap);
1270 framebuffer_release(info); 1234 framebuffer_release(info);
1271 info = dev->core.driver_data = NULL; 1235 ps3_system_bus_set_drvdata(dev, NULL);
1272 } 1236 }
1273 iounmap((u8 __force __iomem *)ps3fb.dinfo); 1237 iounmap((u8 __force __iomem *)ps3fb.dinfo);
1274 1238 lv1_gpu_fb_close(ps3fb.context_handle);
1275 status = lv1_gpu_context_free(ps3fb.context_handle); 1239 lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, xdr_lpar,
1276 if (status) 1240 ps3fb_videomemory.size, CBE_IOPTE_M);
1277 dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n", 1241 lv1_gpu_context_free(ps3fb.context_handle);
1278 status); 1242 lv1_gpu_memory_free(ps3fb.memory_handle);
1279
1280 status = lv1_gpu_memory_free(ps3fb.memory_handle);
1281 if (status)
1282 dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n",
1283 status);
1284
1285 ps3_close_hv_device(dev); 1243 ps3_close_hv_device(dev);
1286 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__); 1244 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1287 1245
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 89f231dc443f..ff43c8885028 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1315,7 +1315,6 @@ static int __devinit tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan,
1315 1315
1316 strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name)); 1316 strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name));
1317 chan->adapter.owner = THIS_MODULE; 1317 chan->adapter.owner = THIS_MODULE;
1318 chan->adapter.class = I2C_CLASS_TV_ANALOG;
1319 chan->adapter.algo_data = &chan->algo; 1318 chan->adapter.algo_data = &chan->algo;
1320 chan->adapter.dev.parent = dev; 1319 chan->adapter.dev.parent = dev;
1321 chan->algo.setsda = tdfxfb_i2c_setsda; 1320 chan->algo.setsda = tdfxfb_i2c_setsda;