diff options
247 files changed, 6303 insertions, 2855 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index d08759aa0903..d77fbd8b79ac 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1915,6 +1915,12 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1915 | Format: { 0 | 1 } | 1915 | Format: { 0 | 1 } |
1916 | See arch/parisc/kernel/pdc_chassis.c | 1916 | See arch/parisc/kernel/pdc_chassis.c |
1917 | 1917 | ||
1918 | percpu_alloc= [X86] Select which percpu first chunk allocator to use. | ||
1919 | Allowed values are one of "lpage", "embed" and "4k". | ||
1920 | See comments in arch/x86/kernel/setup_percpu.c for | ||
1921 | details on each allocator. This parameter is primarily | ||
1922 | for debugging and performance comparison. | ||
1923 | |||
1918 | pf. [PARIDE] | 1924 | pf. [PARIDE] |
1919 | See Documentation/blockdev/paride.txt. | 1925 | See Documentation/blockdev/paride.txt. |
1920 | 1926 | ||
@@ -2467,7 +2473,8 @@ and is between 256 and 4096 characters. It is defined in the file | |||
2467 | 2473 | ||
2468 | tp720= [HW,PS2] | 2474 | tp720= [HW,PS2] |
2469 | 2475 | ||
2470 | trace_buf_size=nn[KMG] [ftrace] will set tracing buffer size. | 2476 | trace_buf_size=nn[KMG] |
2477 | [FTRACE] will set tracing buffer size. | ||
2471 | 2478 | ||
2472 | trix= [HW,OSS] MediaTrix AudioTrix Pro | 2479 | trix= [HW,OSS] MediaTrix AudioTrix Pro |
2473 | Format: | 2480 | Format: |
diff --git a/Documentation/leds-lp3944.txt b/Documentation/leds-lp3944.txt new file mode 100644 index 000000000000..c6eda18b15ef --- /dev/null +++ b/Documentation/leds-lp3944.txt | |||
@@ -0,0 +1,50 @@ | |||
1 | Kernel driver lp3944 | ||
2 | ==================== | ||
3 | |||
4 | * National Semiconductor LP3944 Fun-light Chip | ||
5 | Prefix: 'lp3944' | ||
6 | Addresses scanned: None (see the Notes section below) | ||
7 | Datasheet: Publicly available at the National Semiconductor website | ||
8 | http://www.national.com/pf/LP/LP3944.html | ||
9 | |||
10 | Authors: | ||
11 | Antonio Ospite <ospite@studenti.unina.it> | ||
12 | |||
13 | |||
14 | Description | ||
15 | ----------- | ||
16 | The LP3944 is a helper chip that can drive up to 8 leds, with two programmable | ||
17 | DIM modes; it could even be used as a gpio expander but this driver assumes it | ||
18 | is used as a led controller. | ||
19 | |||
20 | The DIM modes are used to set _blink_ patterns for leds, the pattern is | ||
21 | specified supplying two parameters: | ||
22 | - period: from 0s to 1.6s | ||
23 | - duty cycle: percentage of the period the led is on, from 0 to 100 | ||
24 | |||
25 | Setting a led in DIM0 or DIM1 mode makes it blink according to the pattern. | ||
26 | See the datasheet for details. | ||
27 | |||
28 | LP3944 can be found on Motorola A910 smartphone, where it drives the rgb | ||
29 | leds, the camera flash light and the lcds power. | ||
30 | |||
31 | |||
32 | Notes | ||
33 | ----- | ||
34 | The chip is used mainly in embedded contexts, so this driver expects it is | ||
35 | registered using the i2c_board_info mechanism. | ||
36 | |||
37 | To register the chip at address 0x60 on adapter 0, set the platform data | ||
38 | according to include/linux/leds-lp3944.h, set the i2c board info: | ||
39 | |||
40 | static struct i2c_board_info __initdata a910_i2c_board_info[] = { | ||
41 | { | ||
42 | I2C_BOARD_INFO("lp3944", 0x60), | ||
43 | .platform_data = &a910_lp3944_leds, | ||
44 | }, | ||
45 | }; | ||
46 | |||
47 | and register it in the platform init function | ||
48 | |||
49 | i2c_register_board_info(0, a910_i2c_board_info, | ||
50 | ARRAY_SIZE(a910_i2c_board_info)); | ||
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 8d999d862d0e..79f533f38c61 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt | |||
@@ -1238,1122 +1238,7 @@ descriptions for the SOC devices for which new nodes have been | |||
1238 | defined; this list will expand as more and more SOC-containing | 1238 | defined; this list will expand as more and more SOC-containing |
1239 | platforms are moved over to use the flattened-device-tree model. | 1239 | platforms are moved over to use the flattened-device-tree model. |
1240 | 1240 | ||
1241 | a) PHY nodes | 1241 | VII - Specifying interrupt information for devices |
1242 | |||
1243 | Required properties: | ||
1244 | |||
1245 | - device_type : Should be "ethernet-phy" | ||
1246 | - interrupts : <a b> where a is the interrupt number and b is a | ||
1247 | field that represents an encoding of the sense and level | ||
1248 | information for the interrupt. This should be encoded based on | ||
1249 | the information in section 2) depending on the type of interrupt | ||
1250 | controller you have. | ||
1251 | - interrupt-parent : the phandle for the interrupt controller that | ||
1252 | services interrupts for this device. | ||
1253 | - reg : The ID number for the phy, usually a small integer | ||
1254 | - linux,phandle : phandle for this node; likely referenced by an | ||
1255 | ethernet controller node. | ||
1256 | |||
1257 | |||
1258 | Example: | ||
1259 | |||
1260 | ethernet-phy@0 { | ||
1261 | linux,phandle = <2452000> | ||
1262 | interrupt-parent = <40000>; | ||
1263 | interrupts = <35 1>; | ||
1264 | reg = <0>; | ||
1265 | device_type = "ethernet-phy"; | ||
1266 | }; | ||
1267 | |||
1268 | |||
1269 | b) Interrupt controllers | ||
1270 | |||
1271 | Some SOC devices contain interrupt controllers that are different | ||
1272 | from the standard Open PIC specification. The SOC device nodes for | ||
1273 | these types of controllers should be specified just like a standard | ||
1274 | OpenPIC controller. Sense and level information should be encoded | ||
1275 | as specified in section 2) of this chapter for each device that | ||
1276 | specifies an interrupt. | ||
1277 | |||
1278 | Example : | ||
1279 | |||
1280 | pic@40000 { | ||
1281 | linux,phandle = <40000>; | ||
1282 | interrupt-controller; | ||
1283 | #address-cells = <0>; | ||
1284 | reg = <40000 40000>; | ||
1285 | compatible = "chrp,open-pic"; | ||
1286 | device_type = "open-pic"; | ||
1287 | }; | ||
1288 | |||
1289 | c) 4xx/Axon EMAC ethernet nodes | ||
1290 | |||
1291 | The EMAC ethernet controller in IBM and AMCC 4xx chips, and also | ||
1292 | the Axon bridge. To operate this needs to interact with a ths | ||
1293 | special McMAL DMA controller, and sometimes an RGMII or ZMII | ||
1294 | interface. In addition to the nodes and properties described | ||
1295 | below, the node for the OPB bus on which the EMAC sits must have a | ||
1296 | correct clock-frequency property. | ||
1297 | |||
1298 | i) The EMAC node itself | ||
1299 | |||
1300 | Required properties: | ||
1301 | - device_type : "network" | ||
1302 | |||
1303 | - compatible : compatible list, contains 2 entries, first is | ||
1304 | "ibm,emac-CHIP" where CHIP is the host ASIC (440gx, | ||
1305 | 405gp, Axon) and second is either "ibm,emac" or | ||
1306 | "ibm,emac4". For Axon, thus, we have: "ibm,emac-axon", | ||
1307 | "ibm,emac4" | ||
1308 | - interrupts : <interrupt mapping for EMAC IRQ and WOL IRQ> | ||
1309 | - interrupt-parent : optional, if needed for interrupt mapping | ||
1310 | - reg : <registers mapping> | ||
1311 | - local-mac-address : 6 bytes, MAC address | ||
1312 | - mal-device : phandle of the associated McMAL node | ||
1313 | - mal-tx-channel : 1 cell, index of the tx channel on McMAL associated | ||
1314 | with this EMAC | ||
1315 | - mal-rx-channel : 1 cell, index of the rx channel on McMAL associated | ||
1316 | with this EMAC | ||
1317 | - cell-index : 1 cell, hardware index of the EMAC cell on a given | ||
1318 | ASIC (typically 0x0 and 0x1 for EMAC0 and EMAC1 on | ||
1319 | each Axon chip) | ||
1320 | - max-frame-size : 1 cell, maximum frame size supported in bytes | ||
1321 | - rx-fifo-size : 1 cell, Rx fifo size in bytes for 10 and 100 Mb/sec | ||
1322 | operations. | ||
1323 | For Axon, 2048 | ||
1324 | - tx-fifo-size : 1 cell, Tx fifo size in bytes for 10 and 100 Mb/sec | ||
1325 | operations. | ||
1326 | For Axon, 2048. | ||
1327 | - fifo-entry-size : 1 cell, size of a fifo entry (used to calculate | ||
1328 | thresholds). | ||
1329 | For Axon, 0x00000010 | ||
1330 | - mal-burst-size : 1 cell, MAL burst size (used to calculate thresholds) | ||
1331 | in bytes. | ||
1332 | For Axon, 0x00000100 (I think ...) | ||
1333 | - phy-mode : string, mode of operations of the PHY interface. | ||
1334 | Supported values are: "mii", "rmii", "smii", "rgmii", | ||
1335 | "tbi", "gmii", rtbi", "sgmii". | ||
1336 | For Axon on CAB, it is "rgmii" | ||
1337 | - mdio-device : 1 cell, required iff using shared MDIO registers | ||
1338 | (440EP). phandle of the EMAC to use to drive the | ||
1339 | MDIO lines for the PHY used by this EMAC. | ||
1340 | - zmii-device : 1 cell, required iff connected to a ZMII. phandle of | ||
1341 | the ZMII device node | ||
1342 | - zmii-channel : 1 cell, required iff connected to a ZMII. Which ZMII | ||
1343 | channel or 0xffffffff if ZMII is only used for MDIO. | ||
1344 | - rgmii-device : 1 cell, required iff connected to an RGMII. phandle | ||
1345 | of the RGMII device node. | ||
1346 | For Axon: phandle of plb5/plb4/opb/rgmii | ||
1347 | - rgmii-channel : 1 cell, required iff connected to an RGMII. Which | ||
1348 | RGMII channel is used by this EMAC. | ||
1349 | Fox Axon: present, whatever value is appropriate for each | ||
1350 | EMAC, that is the content of the current (bogus) "phy-port" | ||
1351 | property. | ||
1352 | |||
1353 | Optional properties: | ||
1354 | - phy-address : 1 cell, optional, MDIO address of the PHY. If absent, | ||
1355 | a search is performed. | ||
1356 | - phy-map : 1 cell, optional, bitmap of addresses to probe the PHY | ||
1357 | for, used if phy-address is absent. bit 0x00000001 is | ||
1358 | MDIO address 0. | ||
1359 | For Axon it can be absent, though my current driver | ||
1360 | doesn't handle phy-address yet so for now, keep | ||
1361 | 0x00ffffff in it. | ||
1362 | - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec | ||
1363 | operations (if absent the value is the same as | ||
1364 | rx-fifo-size). For Axon, either absent or 2048. | ||
1365 | - tx-fifo-size-gige : 1 cell, Tx fifo size in bytes for 1000 Mb/sec | ||
1366 | operations (if absent the value is the same as | ||
1367 | tx-fifo-size). For Axon, either absent or 2048. | ||
1368 | - tah-device : 1 cell, optional. If connected to a TAH engine for | ||
1369 | offload, phandle of the TAH device node. | ||
1370 | - tah-channel : 1 cell, optional. If appropriate, channel used on the | ||
1371 | TAH engine. | ||
1372 | |||
1373 | Example: | ||
1374 | |||
1375 | EMAC0: ethernet@40000800 { | ||
1376 | device_type = "network"; | ||
1377 | compatible = "ibm,emac-440gp", "ibm,emac"; | ||
1378 | interrupt-parent = <&UIC1>; | ||
1379 | interrupts = <1c 4 1d 4>; | ||
1380 | reg = <40000800 70>; | ||
1381 | local-mac-address = [00 04 AC E3 1B 1E]; | ||
1382 | mal-device = <&MAL0>; | ||
1383 | mal-tx-channel = <0 1>; | ||
1384 | mal-rx-channel = <0>; | ||
1385 | cell-index = <0>; | ||
1386 | max-frame-size = <5dc>; | ||
1387 | rx-fifo-size = <1000>; | ||
1388 | tx-fifo-size = <800>; | ||
1389 | phy-mode = "rmii"; | ||
1390 | phy-map = <00000001>; | ||
1391 | zmii-device = <&ZMII0>; | ||
1392 | zmii-channel = <0>; | ||
1393 | }; | ||
1394 | |||
1395 | ii) McMAL node | ||
1396 | |||
1397 | Required properties: | ||
1398 | - device_type : "dma-controller" | ||
1399 | - compatible : compatible list, containing 2 entries, first is | ||
1400 | "ibm,mcmal-CHIP" where CHIP is the host ASIC (like | ||
1401 | emac) and the second is either "ibm,mcmal" or | ||
1402 | "ibm,mcmal2". | ||
1403 | For Axon, "ibm,mcmal-axon","ibm,mcmal2" | ||
1404 | - interrupts : <interrupt mapping for the MAL interrupts sources: | ||
1405 | 5 sources: tx_eob, rx_eob, serr, txde, rxde>. | ||
1406 | For Axon: This is _different_ from the current | ||
1407 | firmware. We use the "delayed" interrupts for txeob | ||
1408 | and rxeob. Thus we end up with mapping those 5 MPIC | ||
1409 | interrupts, all level positive sensitive: 10, 11, 32, | ||
1410 | 33, 34 (in decimal) | ||
1411 | - dcr-reg : < DCR registers range > | ||
1412 | - dcr-parent : if needed for dcr-reg | ||
1413 | - num-tx-chans : 1 cell, number of Tx channels | ||
1414 | - num-rx-chans : 1 cell, number of Rx channels | ||
1415 | |||
1416 | iii) ZMII node | ||
1417 | |||
1418 | Required properties: | ||
1419 | - compatible : compatible list, containing 2 entries, first is | ||
1420 | "ibm,zmii-CHIP" where CHIP is the host ASIC (like | ||
1421 | EMAC) and the second is "ibm,zmii". | ||
1422 | For Axon, there is no ZMII node. | ||
1423 | - reg : <registers mapping> | ||
1424 | |||
1425 | iv) RGMII node | ||
1426 | |||
1427 | Required properties: | ||
1428 | - compatible : compatible list, containing 2 entries, first is | ||
1429 | "ibm,rgmii-CHIP" where CHIP is the host ASIC (like | ||
1430 | EMAC) and the second is "ibm,rgmii". | ||
1431 | For Axon, "ibm,rgmii-axon","ibm,rgmii" | ||
1432 | - reg : <registers mapping> | ||
1433 | - revision : as provided by the RGMII new version register if | ||
1434 | available. | ||
1435 | For Axon: 0x0000012a | ||
1436 | |||
1437 | d) Xilinx IP cores | ||
1438 | |||
1439 | The Xilinx EDK toolchain ships with a set of IP cores (devices) for use | ||
1440 | in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range | ||
1441 | of standard device types (network, serial, etc.) and miscellaneous | ||
1442 | devices (gpio, LCD, spi, etc). Also, since these devices are | ||
1443 | implemented within the fpga fabric every instance of the device can be | ||
1444 | synthesised with different options that change the behaviour. | ||
1445 | |||
1446 | Each IP-core has a set of parameters which the FPGA designer can use to | ||
1447 | control how the core is synthesized. Historically, the EDK tool would | ||
1448 | extract the device parameters relevant to device drivers and copy them | ||
1449 | into an 'xparameters.h' in the form of #define symbols. This tells the | ||
1450 | device drivers how the IP cores are configured, but it requres the kernel | ||
1451 | to be recompiled every time the FPGA bitstream is resynthesized. | ||
1452 | |||
1453 | The new approach is to export the parameters into the device tree and | ||
1454 | generate a new device tree each time the FPGA bitstream changes. The | ||
1455 | parameters which used to be exported as #defines will now become | ||
1456 | properties of the device node. In general, device nodes for IP-cores | ||
1457 | will take the following form: | ||
1458 | |||
1459 | (name): (generic-name)@(base-address) { | ||
1460 | compatible = "xlnx,(ip-core-name)-(HW_VER)" | ||
1461 | [, (list of compatible devices), ...]; | ||
1462 | reg = <(baseaddr) (size)>; | ||
1463 | interrupt-parent = <&interrupt-controller-phandle>; | ||
1464 | interrupts = < ... >; | ||
1465 | xlnx,(parameter1) = "(string-value)"; | ||
1466 | xlnx,(parameter2) = <(int-value)>; | ||
1467 | }; | ||
1468 | |||
1469 | (generic-name): an open firmware-style name that describes the | ||
1470 | generic class of device. Preferably, this is one word, such | ||
1471 | as 'serial' or 'ethernet'. | ||
1472 | (ip-core-name): the name of the ip block (given after the BEGIN | ||
1473 | directive in system.mhs). Should be in lowercase | ||
1474 | and all underscores '_' converted to dashes '-'. | ||
1475 | (name): is derived from the "PARAMETER INSTANCE" value. | ||
1476 | (parameter#): C_* parameters from system.mhs. The C_ prefix is | ||
1477 | dropped from the parameter name, the name is converted | ||
1478 | to lowercase and all underscore '_' characters are | ||
1479 | converted to dashes '-'. | ||
1480 | (baseaddr): the baseaddr parameter value (often named C_BASEADDR). | ||
1481 | (HW_VER): from the HW_VER parameter. | ||
1482 | (size): the address range size (often C_HIGHADDR - C_BASEADDR + 1). | ||
1483 | |||
1484 | Typically, the compatible list will include the exact IP core version | ||
1485 | followed by an older IP core version which implements the same | ||
1486 | interface or any other device with the same interface. | ||
1487 | |||
1488 | 'reg', 'interrupt-parent' and 'interrupts' are all optional properties. | ||
1489 | |||
1490 | For example, the following block from system.mhs: | ||
1491 | |||
1492 | BEGIN opb_uartlite | ||
1493 | PARAMETER INSTANCE = opb_uartlite_0 | ||
1494 | PARAMETER HW_VER = 1.00.b | ||
1495 | PARAMETER C_BAUDRATE = 115200 | ||
1496 | PARAMETER C_DATA_BITS = 8 | ||
1497 | PARAMETER C_ODD_PARITY = 0 | ||
1498 | PARAMETER C_USE_PARITY = 0 | ||
1499 | PARAMETER C_CLK_FREQ = 50000000 | ||
1500 | PARAMETER C_BASEADDR = 0xEC100000 | ||
1501 | PARAMETER C_HIGHADDR = 0xEC10FFFF | ||
1502 | BUS_INTERFACE SOPB = opb_7 | ||
1503 | PORT OPB_Clk = CLK_50MHz | ||
1504 | PORT Interrupt = opb_uartlite_0_Interrupt | ||
1505 | PORT RX = opb_uartlite_0_RX | ||
1506 | PORT TX = opb_uartlite_0_TX | ||
1507 | PORT OPB_Rst = sys_bus_reset_0 | ||
1508 | END | ||
1509 | |||
1510 | becomes the following device tree node: | ||
1511 | |||
1512 | opb_uartlite_0: serial@ec100000 { | ||
1513 | device_type = "serial"; | ||
1514 | compatible = "xlnx,opb-uartlite-1.00.b"; | ||
1515 | reg = <ec100000 10000>; | ||
1516 | interrupt-parent = <&opb_intc_0>; | ||
1517 | interrupts = <1 0>; // got this from the opb_intc parameters | ||
1518 | current-speed = <d#115200>; // standard serial device prop | ||
1519 | clock-frequency = <d#50000000>; // standard serial device prop | ||
1520 | xlnx,data-bits = <8>; | ||
1521 | xlnx,odd-parity = <0>; | ||
1522 | xlnx,use-parity = <0>; | ||
1523 | }; | ||
1524 | |||
1525 | Some IP cores actually implement 2 or more logical devices. In | ||
1526 | this case, the device should still describe the whole IP core with | ||
1527 | a single node and add a child node for each logical device. The | ||
1528 | ranges property can be used to translate from parent IP-core to the | ||
1529 | registers of each device. In addition, the parent node should be | ||
1530 | compatible with the bus type 'xlnx,compound', and should contain | ||
1531 | #address-cells and #size-cells, as with any other bus. (Note: this | ||
1532 | makes the assumption that both logical devices have the same bus | ||
1533 | binding. If this is not true, then separate nodes should be used | ||
1534 | for each logical device). The 'cell-index' property can be used to | ||
1535 | enumerate logical devices within an IP core. For example, the | ||
1536 | following is the system.mhs entry for the dual ps2 controller found | ||
1537 | on the ml403 reference design. | ||
1538 | |||
1539 | BEGIN opb_ps2_dual_ref | ||
1540 | PARAMETER INSTANCE = opb_ps2_dual_ref_0 | ||
1541 | PARAMETER HW_VER = 1.00.a | ||
1542 | PARAMETER C_BASEADDR = 0xA9000000 | ||
1543 | PARAMETER C_HIGHADDR = 0xA9001FFF | ||
1544 | BUS_INTERFACE SOPB = opb_v20_0 | ||
1545 | PORT Sys_Intr1 = ps2_1_intr | ||
1546 | PORT Sys_Intr2 = ps2_2_intr | ||
1547 | PORT Clkin1 = ps2_clk_rx_1 | ||
1548 | PORT Clkin2 = ps2_clk_rx_2 | ||
1549 | PORT Clkpd1 = ps2_clk_tx_1 | ||
1550 | PORT Clkpd2 = ps2_clk_tx_2 | ||
1551 | PORT Rx1 = ps2_d_rx_1 | ||
1552 | PORT Rx2 = ps2_d_rx_2 | ||
1553 | PORT Txpd1 = ps2_d_tx_1 | ||
1554 | PORT Txpd2 = ps2_d_tx_2 | ||
1555 | END | ||
1556 | |||
1557 | It would result in the following device tree nodes: | ||
1558 | |||
1559 | opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 { | ||
1560 | #address-cells = <1>; | ||
1561 | #size-cells = <1>; | ||
1562 | compatible = "xlnx,compound"; | ||
1563 | ranges = <0 a9000000 2000>; | ||
1564 | // If this device had extra parameters, then they would | ||
1565 | // go here. | ||
1566 | ps2@0 { | ||
1567 | compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; | ||
1568 | reg = <0 40>; | ||
1569 | interrupt-parent = <&opb_intc_0>; | ||
1570 | interrupts = <3 0>; | ||
1571 | cell-index = <0>; | ||
1572 | }; | ||
1573 | ps2@1000 { | ||
1574 | compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; | ||
1575 | reg = <1000 40>; | ||
1576 | interrupt-parent = <&opb_intc_0>; | ||
1577 | interrupts = <3 0>; | ||
1578 | cell-index = <0>; | ||
1579 | }; | ||
1580 | }; | ||
1581 | |||
1582 | Also, the system.mhs file defines bus attachments from the processor | ||
1583 | to the devices. The device tree structure should reflect the bus | ||
1584 | attachments. Again an example; this system.mhs fragment: | ||
1585 | |||
1586 | BEGIN ppc405_virtex4 | ||
1587 | PARAMETER INSTANCE = ppc405_0 | ||
1588 | PARAMETER HW_VER = 1.01.a | ||
1589 | BUS_INTERFACE DPLB = plb_v34_0 | ||
1590 | BUS_INTERFACE IPLB = plb_v34_0 | ||
1591 | END | ||
1592 | |||
1593 | BEGIN opb_intc | ||
1594 | PARAMETER INSTANCE = opb_intc_0 | ||
1595 | PARAMETER HW_VER = 1.00.c | ||
1596 | PARAMETER C_BASEADDR = 0xD1000FC0 | ||
1597 | PARAMETER C_HIGHADDR = 0xD1000FDF | ||
1598 | BUS_INTERFACE SOPB = opb_v20_0 | ||
1599 | END | ||
1600 | |||
1601 | BEGIN opb_uart16550 | ||
1602 | PARAMETER INSTANCE = opb_uart16550_0 | ||
1603 | PARAMETER HW_VER = 1.00.d | ||
1604 | PARAMETER C_BASEADDR = 0xa0000000 | ||
1605 | PARAMETER C_HIGHADDR = 0xa0001FFF | ||
1606 | BUS_INTERFACE SOPB = opb_v20_0 | ||
1607 | END | ||
1608 | |||
1609 | BEGIN plb_v34 | ||
1610 | PARAMETER INSTANCE = plb_v34_0 | ||
1611 | PARAMETER HW_VER = 1.02.a | ||
1612 | END | ||
1613 | |||
1614 | BEGIN plb_bram_if_cntlr | ||
1615 | PARAMETER INSTANCE = plb_bram_if_cntlr_0 | ||
1616 | PARAMETER HW_VER = 1.00.b | ||
1617 | PARAMETER C_BASEADDR = 0xFFFF0000 | ||
1618 | PARAMETER C_HIGHADDR = 0xFFFFFFFF | ||
1619 | BUS_INTERFACE SPLB = plb_v34_0 | ||
1620 | END | ||
1621 | |||
1622 | BEGIN plb2opb_bridge | ||
1623 | PARAMETER INSTANCE = plb2opb_bridge_0 | ||
1624 | PARAMETER HW_VER = 1.01.a | ||
1625 | PARAMETER C_RNG0_BASEADDR = 0x20000000 | ||
1626 | PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF | ||
1627 | PARAMETER C_RNG1_BASEADDR = 0x60000000 | ||
1628 | PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF | ||
1629 | PARAMETER C_RNG2_BASEADDR = 0x80000000 | ||
1630 | PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF | ||
1631 | PARAMETER C_RNG3_BASEADDR = 0xC0000000 | ||
1632 | PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF | ||
1633 | BUS_INTERFACE SPLB = plb_v34_0 | ||
1634 | BUS_INTERFACE MOPB = opb_v20_0 | ||
1635 | END | ||
1636 | |||
1637 | Gives this device tree (some properties removed for clarity): | ||
1638 | |||
1639 | plb@0 { | ||
1640 | #address-cells = <1>; | ||
1641 | #size-cells = <1>; | ||
1642 | compatible = "xlnx,plb-v34-1.02.a"; | ||
1643 | device_type = "ibm,plb"; | ||
1644 | ranges; // 1:1 translation | ||
1645 | |||
1646 | plb_bram_if_cntrl_0: bram@ffff0000 { | ||
1647 | reg = <ffff0000 10000>; | ||
1648 | } | ||
1649 | |||
1650 | opb@20000000 { | ||
1651 | #address-cells = <1>; | ||
1652 | #size-cells = <1>; | ||
1653 | ranges = <20000000 20000000 20000000 | ||
1654 | 60000000 60000000 20000000 | ||
1655 | 80000000 80000000 40000000 | ||
1656 | c0000000 c0000000 20000000>; | ||
1657 | |||
1658 | opb_uart16550_0: serial@a0000000 { | ||
1659 | reg = <a00000000 2000>; | ||
1660 | }; | ||
1661 | |||
1662 | opb_intc_0: interrupt-controller@d1000fc0 { | ||
1663 | reg = <d1000fc0 20>; | ||
1664 | }; | ||
1665 | }; | ||
1666 | }; | ||
1667 | |||
1668 | That covers the general approach to binding xilinx IP cores into the | ||
1669 | device tree. The following are bindings for specific devices: | ||
1670 | |||
1671 | i) Xilinx ML300 Framebuffer | ||
1672 | |||
1673 | Simple framebuffer device from the ML300 reference design (also on the | ||
1674 | ML403 reference design as well as others). | ||
1675 | |||
1676 | Optional properties: | ||
1677 | - resolution = <xres yres> : pixel resolution of framebuffer. Some | ||
1678 | implementations use a different resolution. | ||
1679 | Default is <d#640 d#480> | ||
1680 | - virt-resolution = <xvirt yvirt> : Size of framebuffer in memory. | ||
1681 | Default is <d#1024 d#480>. | ||
1682 | - rotate-display (empty) : rotate display 180 degrees. | ||
1683 | |||
1684 | ii) Xilinx SystemACE | ||
1685 | |||
1686 | The Xilinx SystemACE device is used to program FPGAs from an FPGA | ||
1687 | bitstream stored on a CF card. It can also be used as a generic CF | ||
1688 | interface device. | ||
1689 | |||
1690 | Optional properties: | ||
1691 | - 8-bit (empty) : Set this property for SystemACE in 8 bit mode | ||
1692 | |||
1693 | iii) Xilinx EMAC and Xilinx TEMAC | ||
1694 | |||
1695 | Xilinx Ethernet devices. In addition to general xilinx properties | ||
1696 | listed above, nodes for these devices should include a phy-handle | ||
1697 | property, and may include other common network device properties | ||
1698 | like local-mac-address. | ||
1699 | |||
1700 | iv) Xilinx Uartlite | ||
1701 | |||
1702 | Xilinx uartlite devices are simple fixed speed serial ports. | ||
1703 | |||
1704 | Required properties: | ||
1705 | - current-speed : Baud rate of uartlite | ||
1706 | |||
1707 | v) Xilinx hwicap | ||
1708 | |||
1709 | Xilinx hwicap devices provide access to the configuration logic | ||
1710 | of the FPGA through the Internal Configuration Access Port | ||
1711 | (ICAP). The ICAP enables partial reconfiguration of the FPGA, | ||
1712 | readback of the configuration information, and some control over | ||
1713 | 'warm boots' of the FPGA fabric. | ||
1714 | |||
1715 | Required properties: | ||
1716 | - xlnx,family : The family of the FPGA, necessary since the | ||
1717 | capabilities of the underlying ICAP hardware | ||
1718 | differ between different families. May be | ||
1719 | 'virtex2p', 'virtex4', or 'virtex5'. | ||
1720 | |||
1721 | vi) Xilinx Uart 16550 | ||
1722 | |||
1723 | Xilinx UART 16550 devices are very similar to the NS16550 but with | ||
1724 | different register spacing and an offset from the base address. | ||
1725 | |||
1726 | Required properties: | ||
1727 | - clock-frequency : Frequency of the clock input | ||
1728 | - reg-offset : A value of 3 is required | ||
1729 | - reg-shift : A value of 2 is required | ||
1730 | |||
1731 | e) USB EHCI controllers | ||
1732 | |||
1733 | Required properties: | ||
1734 | - compatible : should be "usb-ehci". | ||
1735 | - reg : should contain at least address and length of the standard EHCI | ||
1736 | register set for the device. Optional platform-dependent registers | ||
1737 | (debug-port or other) can be also specified here, but only after | ||
1738 | definition of standard EHCI registers. | ||
1739 | - interrupts : one EHCI interrupt should be described here. | ||
1740 | If device registers are implemented in big endian mode, the device | ||
1741 | node should have "big-endian-regs" property. | ||
1742 | If controller implementation operates with big endian descriptors, | ||
1743 | "big-endian-desc" property should be specified. | ||
1744 | If both big endian registers and descriptors are used by the controller | ||
1745 | implementation, "big-endian" property can be specified instead of having | ||
1746 | both "big-endian-regs" and "big-endian-desc". | ||
1747 | |||
1748 | Example (Sequoia 440EPx): | ||
1749 | ehci@e0000300 { | ||
1750 | compatible = "ibm,usb-ehci-440epx", "usb-ehci"; | ||
1751 | interrupt-parent = <&UIC0>; | ||
1752 | interrupts = <1a 4>; | ||
1753 | reg = <0 e0000300 90 0 e0000390 70>; | ||
1754 | big-endian; | ||
1755 | }; | ||
1756 | |||
1757 | f) MDIO on GPIOs | ||
1758 | |||
1759 | Currently defined compatibles: | ||
1760 | - virtual,gpio-mdio | ||
1761 | |||
1762 | MDC and MDIO lines connected to GPIO controllers are listed in the | ||
1763 | gpios property as described in section VIII.1 in the following order: | ||
1764 | |||
1765 | MDC, MDIO. | ||
1766 | |||
1767 | Example: | ||
1768 | |||
1769 | mdio { | ||
1770 | compatible = "virtual,mdio-gpio"; | ||
1771 | #address-cells = <1>; | ||
1772 | #size-cells = <0>; | ||
1773 | gpios = <&qe_pio_a 11 | ||
1774 | &qe_pio_c 6>; | ||
1775 | }; | ||
1776 | |||
1777 | g) SPI (Serial Peripheral Interface) busses | ||
1778 | |||
1779 | SPI busses can be described with a node for the SPI master device | ||
1780 | and a set of child nodes for each SPI slave on the bus. For this | ||
1781 | discussion, it is assumed that the system's SPI controller is in | ||
1782 | SPI master mode. This binding does not describe SPI controllers | ||
1783 | in slave mode. | ||
1784 | |||
1785 | The SPI master node requires the following properties: | ||
1786 | - #address-cells - number of cells required to define a chip select | ||
1787 | address on the SPI bus. | ||
1788 | - #size-cells - should be zero. | ||
1789 | - compatible - name of SPI bus controller following generic names | ||
1790 | recommended practice. | ||
1791 | No other properties are required in the SPI bus node. It is assumed | ||
1792 | that a driver for an SPI bus device will understand that it is an SPI bus. | ||
1793 | However, the binding does not attempt to define the specific method for | ||
1794 | assigning chip select numbers. Since SPI chip select configuration is | ||
1795 | flexible and non-standardized, it is left out of this binding with the | ||
1796 | assumption that board specific platform code will be used to manage | ||
1797 | chip selects. Individual drivers can define additional properties to | ||
1798 | support describing the chip select layout. | ||
1799 | |||
1800 | SPI slave nodes must be children of the SPI master node and can | ||
1801 | contain the following properties. | ||
1802 | - reg - (required) chip select address of device. | ||
1803 | - compatible - (required) name of SPI device following generic names | ||
1804 | recommended practice | ||
1805 | - spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz | ||
1806 | - spi-cpol - (optional) Empty property indicating device requires | ||
1807 | inverse clock polarity (CPOL) mode | ||
1808 | - spi-cpha - (optional) Empty property indicating device requires | ||
1809 | shifted clock phase (CPHA) mode | ||
1810 | - spi-cs-high - (optional) Empty property indicating device requires | ||
1811 | chip select active high | ||
1812 | |||
1813 | SPI example for an MPC5200 SPI bus: | ||
1814 | spi@f00 { | ||
1815 | #address-cells = <1>; | ||
1816 | #size-cells = <0>; | ||
1817 | compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; | ||
1818 | reg = <0xf00 0x20>; | ||
1819 | interrupts = <2 13 0 2 14 0>; | ||
1820 | interrupt-parent = <&mpc5200_pic>; | ||
1821 | |||
1822 | ethernet-switch@0 { | ||
1823 | compatible = "micrel,ks8995m"; | ||
1824 | spi-max-frequency = <1000000>; | ||
1825 | reg = <0>; | ||
1826 | }; | ||
1827 | |||
1828 | codec@1 { | ||
1829 | compatible = "ti,tlv320aic26"; | ||
1830 | spi-max-frequency = <100000>; | ||
1831 | reg = <1>; | ||
1832 | }; | ||
1833 | }; | ||
1834 | |||
1835 | VII - Marvell Discovery mv64[345]6x System Controller chips | ||
1836 | =========================================================== | ||
1837 | |||
1838 | The Marvell mv64[345]60 series of system controller chips contain | ||
1839 | many of the peripherals needed to implement a complete computer | ||
1840 | system. In this section, we define device tree nodes to describe | ||
1841 | the system controller chip itself and each of the peripherals | ||
1842 | which it contains. Compatible string values for each node are | ||
1843 | prefixed with the string "marvell,", for Marvell Technology Group Ltd. | ||
1844 | |||
1845 | 1) The /system-controller node | ||
1846 | |||
1847 | This node is used to represent the system-controller and must be | ||
1848 | present when the system uses a system controller chip. The top-level | ||
1849 | system-controller node contains information that is global to all | ||
1850 | devices within the system controller chip. The node name begins | ||
1851 | with "system-controller" followed by the unit address, which is | ||
1852 | the base address of the memory-mapped register set for the system | ||
1853 | controller chip. | ||
1854 | |||
1855 | Required properties: | ||
1856 | |||
1857 | - ranges : Describes the translation of system controller addresses | ||
1858 | for memory mapped registers. | ||
1859 | - clock-frequency: Contains the main clock frequency for the system | ||
1860 | controller chip. | ||
1861 | - reg : This property defines the address and size of the | ||
1862 | memory-mapped registers contained within the system controller | ||
1863 | chip. The address specified in the "reg" property should match | ||
1864 | the unit address of the system-controller node. | ||
1865 | - #address-cells : Address representation for system controller | ||
1866 | devices. This field represents the number of cells needed to | ||
1867 | represent the address of the memory-mapped registers of devices | ||
1868 | within the system controller chip. | ||
1869 | - #size-cells : Size representation for for the memory-mapped | ||
1870 | registers within the system controller chip. | ||
1871 | - #interrupt-cells : Defines the width of cells used to represent | ||
1872 | interrupts. | ||
1873 | |||
1874 | Optional properties: | ||
1875 | |||
1876 | - model : The specific model of the system controller chip. Such | ||
1877 | as, "mv64360", "mv64460", or "mv64560". | ||
1878 | - compatible : A string identifying the compatibility identifiers | ||
1879 | of the system controller chip. | ||
1880 | |||
1881 | The system-controller node contains child nodes for each system | ||
1882 | controller device that the platform uses. Nodes should not be created | ||
1883 | for devices which exist on the system controller chip but are not used | ||
1884 | |||
1885 | Example Marvell Discovery mv64360 system-controller node: | ||
1886 | |||
1887 | system-controller@f1000000 { /* Marvell Discovery mv64360 */ | ||
1888 | #address-cells = <1>; | ||
1889 | #size-cells = <1>; | ||
1890 | model = "mv64360"; /* Default */ | ||
1891 | compatible = "marvell,mv64360"; | ||
1892 | clock-frequency = <133333333>; | ||
1893 | reg = <0xf1000000 0x10000>; | ||
1894 | virtual-reg = <0xf1000000>; | ||
1895 | ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */ | ||
1896 | 0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */ | ||
1897 | 0xa0000000 0xa0000000 0x4000000 /* User FLASH */ | ||
1898 | 0x00000000 0xf1000000 0x0010000 /* Bridge's regs */ | ||
1899 | 0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */ | ||
1900 | |||
1901 | [ child node definitions... ] | ||
1902 | } | ||
1903 | |||
1904 | 2) Child nodes of /system-controller | ||
1905 | |||
1906 | a) Marvell Discovery MDIO bus | ||
1907 | |||
1908 | The MDIO is a bus to which the PHY devices are connected. For each | ||
1909 | device that exists on this bus, a child node should be created. See | ||
1910 | the definition of the PHY node below for an example of how to define | ||
1911 | a PHY. | ||
1912 | |||
1913 | Required properties: | ||
1914 | - #address-cells : Should be <1> | ||
1915 | - #size-cells : Should be <0> | ||
1916 | - device_type : Should be "mdio" | ||
1917 | - compatible : Should be "marvell,mv64360-mdio" | ||
1918 | |||
1919 | Example: | ||
1920 | |||
1921 | mdio { | ||
1922 | #address-cells = <1>; | ||
1923 | #size-cells = <0>; | ||
1924 | device_type = "mdio"; | ||
1925 | compatible = "marvell,mv64360-mdio"; | ||
1926 | |||
1927 | ethernet-phy@0 { | ||
1928 | ...... | ||
1929 | }; | ||
1930 | }; | ||
1931 | |||
1932 | |||
1933 | b) Marvell Discovery ethernet controller | ||
1934 | |||
1935 | The Discover ethernet controller is described with two levels | ||
1936 | of nodes. The first level describes an ethernet silicon block | ||
1937 | and the second level describes up to 3 ethernet nodes within | ||
1938 | that block. The reason for the multiple levels is that the | ||
1939 | registers for the node are interleaved within a single set | ||
1940 | of registers. The "ethernet-block" level describes the | ||
1941 | shared register set, and the "ethernet" nodes describe ethernet | ||
1942 | port-specific properties. | ||
1943 | |||
1944 | Ethernet block node | ||
1945 | |||
1946 | Required properties: | ||
1947 | - #address-cells : <1> | ||
1948 | - #size-cells : <0> | ||
1949 | - compatible : "marvell,mv64360-eth-block" | ||
1950 | - reg : Offset and length of the register set for this block | ||
1951 | |||
1952 | Example Discovery Ethernet block node: | ||
1953 | ethernet-block@2000 { | ||
1954 | #address-cells = <1>; | ||
1955 | #size-cells = <0>; | ||
1956 | compatible = "marvell,mv64360-eth-block"; | ||
1957 | reg = <0x2000 0x2000>; | ||
1958 | ethernet@0 { | ||
1959 | ....... | ||
1960 | }; | ||
1961 | }; | ||
1962 | |||
1963 | Ethernet port node | ||
1964 | |||
1965 | Required properties: | ||
1966 | - device_type : Should be "network". | ||
1967 | - compatible : Should be "marvell,mv64360-eth". | ||
1968 | - reg : Should be <0>, <1>, or <2>, according to which registers | ||
1969 | within the silicon block the device uses. | ||
1970 | - interrupts : <a> where a is the interrupt number for the port. | ||
1971 | - interrupt-parent : the phandle for the interrupt controller | ||
1972 | that services interrupts for this device. | ||
1973 | - phy : the phandle for the PHY connected to this ethernet | ||
1974 | controller. | ||
1975 | - local-mac-address : 6 bytes, MAC address | ||
1976 | |||
1977 | Example Discovery Ethernet port node: | ||
1978 | ethernet@0 { | ||
1979 | device_type = "network"; | ||
1980 | compatible = "marvell,mv64360-eth"; | ||
1981 | reg = <0>; | ||
1982 | interrupts = <32>; | ||
1983 | interrupt-parent = <&PIC>; | ||
1984 | phy = <&PHY0>; | ||
1985 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
1986 | }; | ||
1987 | |||
1988 | |||
1989 | |||
1990 | c) Marvell Discovery PHY nodes | ||
1991 | |||
1992 | Required properties: | ||
1993 | - device_type : Should be "ethernet-phy" | ||
1994 | - interrupts : <a> where a is the interrupt number for this phy. | ||
1995 | - interrupt-parent : the phandle for the interrupt controller that | ||
1996 | services interrupts for this device. | ||
1997 | - reg : The ID number for the phy, usually a small integer | ||
1998 | |||
1999 | Example Discovery PHY node: | ||
2000 | ethernet-phy@1 { | ||
2001 | device_type = "ethernet-phy"; | ||
2002 | compatible = "broadcom,bcm5421"; | ||
2003 | interrupts = <76>; /* GPP 12 */ | ||
2004 | interrupt-parent = <&PIC>; | ||
2005 | reg = <1>; | ||
2006 | }; | ||
2007 | |||
2008 | |||
2009 | d) Marvell Discovery SDMA nodes | ||
2010 | |||
2011 | Represent DMA hardware associated with the MPSC (multiprotocol | ||
2012 | serial controllers). | ||
2013 | |||
2014 | Required properties: | ||
2015 | - compatible : "marvell,mv64360-sdma" | ||
2016 | - reg : Offset and length of the register set for this device | ||
2017 | - interrupts : <a> where a is the interrupt number for the DMA | ||
2018 | device. | ||
2019 | - interrupt-parent : the phandle for the interrupt controller | ||
2020 | that services interrupts for this device. | ||
2021 | |||
2022 | Example Discovery SDMA node: | ||
2023 | sdma@4000 { | ||
2024 | compatible = "marvell,mv64360-sdma"; | ||
2025 | reg = <0x4000 0xc18>; | ||
2026 | virtual-reg = <0xf1004000>; | ||
2027 | interrupts = <36>; | ||
2028 | interrupt-parent = <&PIC>; | ||
2029 | }; | ||
2030 | |||
2031 | |||
2032 | e) Marvell Discovery BRG nodes | ||
2033 | |||
2034 | Represent baud rate generator hardware associated with the MPSC | ||
2035 | (multiprotocol serial controllers). | ||
2036 | |||
2037 | Required properties: | ||
2038 | - compatible : "marvell,mv64360-brg" | ||
2039 | - reg : Offset and length of the register set for this device | ||
2040 | - clock-src : A value from 0 to 15 which selects the clock | ||
2041 | source for the baud rate generator. This value corresponds | ||
2042 | to the CLKS value in the BRGx configuration register. See | ||
2043 | the mv64x60 User's Manual. | ||
2044 | - clock-frequence : The frequency (in Hz) of the baud rate | ||
2045 | generator's input clock. | ||
2046 | - current-speed : The current speed setting (presumably by | ||
2047 | firmware) of the baud rate generator. | ||
2048 | |||
2049 | Example Discovery BRG node: | ||
2050 | brg@b200 { | ||
2051 | compatible = "marvell,mv64360-brg"; | ||
2052 | reg = <0xb200 0x8>; | ||
2053 | clock-src = <8>; | ||
2054 | clock-frequency = <133333333>; | ||
2055 | current-speed = <9600>; | ||
2056 | }; | ||
2057 | |||
2058 | |||
2059 | f) Marvell Discovery CUNIT nodes | ||
2060 | |||
2061 | Represent the Serial Communications Unit device hardware. | ||
2062 | |||
2063 | Required properties: | ||
2064 | - reg : Offset and length of the register set for this device | ||
2065 | |||
2066 | Example Discovery CUNIT node: | ||
2067 | cunit@f200 { | ||
2068 | reg = <0xf200 0x200>; | ||
2069 | }; | ||
2070 | |||
2071 | |||
2072 | g) Marvell Discovery MPSCROUTING nodes | ||
2073 | |||
2074 | Represent the Discovery's MPSC routing hardware | ||
2075 | |||
2076 | Required properties: | ||
2077 | - reg : Offset and length of the register set for this device | ||
2078 | |||
2079 | Example Discovery CUNIT node: | ||
2080 | mpscrouting@b500 { | ||
2081 | reg = <0xb400 0xc>; | ||
2082 | }; | ||
2083 | |||
2084 | |||
2085 | h) Marvell Discovery MPSCINTR nodes | ||
2086 | |||
2087 | Represent the Discovery's MPSC DMA interrupt hardware registers | ||
2088 | (SDMA cause and mask registers). | ||
2089 | |||
2090 | Required properties: | ||
2091 | - reg : Offset and length of the register set for this device | ||
2092 | |||
2093 | Example Discovery MPSCINTR node: | ||
2094 | mpsintr@b800 { | ||
2095 | reg = <0xb800 0x100>; | ||
2096 | }; | ||
2097 | |||
2098 | |||
2099 | i) Marvell Discovery MPSC nodes | ||
2100 | |||
2101 | Represent the Discovery's MPSC (Multiprotocol Serial Controller) | ||
2102 | serial port. | ||
2103 | |||
2104 | Required properties: | ||
2105 | - device_type : "serial" | ||
2106 | - compatible : "marvell,mv64360-mpsc" | ||
2107 | - reg : Offset and length of the register set for this device | ||
2108 | - sdma : the phandle for the SDMA node used by this port | ||
2109 | - brg : the phandle for the BRG node used by this port | ||
2110 | - cunit : the phandle for the CUNIT node used by this port | ||
2111 | - mpscrouting : the phandle for the MPSCROUTING node used by this port | ||
2112 | - mpscintr : the phandle for the MPSCINTR node used by this port | ||
2113 | - cell-index : the hardware index of this cell in the MPSC core | ||
2114 | - max_idle : value needed for MPSC CHR3 (Maximum Frame Length) | ||
2115 | register | ||
2116 | - interrupts : <a> where a is the interrupt number for the MPSC. | ||
2117 | - interrupt-parent : the phandle for the interrupt controller | ||
2118 | that services interrupts for this device. | ||
2119 | |||
2120 | Example Discovery MPSCINTR node: | ||
2121 | mpsc@8000 { | ||
2122 | device_type = "serial"; | ||
2123 | compatible = "marvell,mv64360-mpsc"; | ||
2124 | reg = <0x8000 0x38>; | ||
2125 | virtual-reg = <0xf1008000>; | ||
2126 | sdma = <&SDMA0>; | ||
2127 | brg = <&BRG0>; | ||
2128 | cunit = <&CUNIT>; | ||
2129 | mpscrouting = <&MPSCROUTING>; | ||
2130 | mpscintr = <&MPSCINTR>; | ||
2131 | cell-index = <0>; | ||
2132 | max_idle = <40>; | ||
2133 | interrupts = <40>; | ||
2134 | interrupt-parent = <&PIC>; | ||
2135 | }; | ||
2136 | |||
2137 | |||
2138 | j) Marvell Discovery Watch Dog Timer nodes | ||
2139 | |||
2140 | Represent the Discovery's watchdog timer hardware | ||
2141 | |||
2142 | Required properties: | ||
2143 | - compatible : "marvell,mv64360-wdt" | ||
2144 | - reg : Offset and length of the register set for this device | ||
2145 | |||
2146 | Example Discovery Watch Dog Timer node: | ||
2147 | wdt@b410 { | ||
2148 | compatible = "marvell,mv64360-wdt"; | ||
2149 | reg = <0xb410 0x8>; | ||
2150 | }; | ||
2151 | |||
2152 | |||
2153 | k) Marvell Discovery I2C nodes | ||
2154 | |||
2155 | Represent the Discovery's I2C hardware | ||
2156 | |||
2157 | Required properties: | ||
2158 | - device_type : "i2c" | ||
2159 | - compatible : "marvell,mv64360-i2c" | ||
2160 | - reg : Offset and length of the register set for this device | ||
2161 | - interrupts : <a> where a is the interrupt number for the I2C. | ||
2162 | - interrupt-parent : the phandle for the interrupt controller | ||
2163 | that services interrupts for this device. | ||
2164 | |||
2165 | Example Discovery I2C node: | ||
2166 | compatible = "marvell,mv64360-i2c"; | ||
2167 | reg = <0xc000 0x20>; | ||
2168 | virtual-reg = <0xf100c000>; | ||
2169 | interrupts = <37>; | ||
2170 | interrupt-parent = <&PIC>; | ||
2171 | }; | ||
2172 | |||
2173 | |||
2174 | l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes | ||
2175 | |||
2176 | Represent the Discovery's PIC hardware | ||
2177 | |||
2178 | Required properties: | ||
2179 | - #interrupt-cells : <1> | ||
2180 | - #address-cells : <0> | ||
2181 | - compatible : "marvell,mv64360-pic" | ||
2182 | - reg : Offset and length of the register set for this device | ||
2183 | - interrupt-controller | ||
2184 | |||
2185 | Example Discovery PIC node: | ||
2186 | pic { | ||
2187 | #interrupt-cells = <1>; | ||
2188 | #address-cells = <0>; | ||
2189 | compatible = "marvell,mv64360-pic"; | ||
2190 | reg = <0x0 0x88>; | ||
2191 | interrupt-controller; | ||
2192 | }; | ||
2193 | |||
2194 | |||
2195 | m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes | ||
2196 | |||
2197 | Represent the Discovery's MPP hardware | ||
2198 | |||
2199 | Required properties: | ||
2200 | - compatible : "marvell,mv64360-mpp" | ||
2201 | - reg : Offset and length of the register set for this device | ||
2202 | |||
2203 | Example Discovery MPP node: | ||
2204 | mpp@f000 { | ||
2205 | compatible = "marvell,mv64360-mpp"; | ||
2206 | reg = <0xf000 0x10>; | ||
2207 | }; | ||
2208 | |||
2209 | |||
2210 | n) Marvell Discovery GPP (General Purpose Pins) nodes | ||
2211 | |||
2212 | Represent the Discovery's GPP hardware | ||
2213 | |||
2214 | Required properties: | ||
2215 | - compatible : "marvell,mv64360-gpp" | ||
2216 | - reg : Offset and length of the register set for this device | ||
2217 | |||
2218 | Example Discovery GPP node: | ||
2219 | gpp@f000 { | ||
2220 | compatible = "marvell,mv64360-gpp"; | ||
2221 | reg = <0xf100 0x20>; | ||
2222 | }; | ||
2223 | |||
2224 | |||
2225 | o) Marvell Discovery PCI host bridge node | ||
2226 | |||
2227 | Represents the Discovery's PCI host bridge device. The properties | ||
2228 | for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE | ||
2229 | 1275-1994. A typical value for the compatible property is | ||
2230 | "marvell,mv64360-pci". | ||
2231 | |||
2232 | Example Discovery PCI host bridge node | ||
2233 | pci@80000000 { | ||
2234 | #address-cells = <3>; | ||
2235 | #size-cells = <2>; | ||
2236 | #interrupt-cells = <1>; | ||
2237 | device_type = "pci"; | ||
2238 | compatible = "marvell,mv64360-pci"; | ||
2239 | reg = <0xcf8 0x8>; | ||
2240 | ranges = <0x01000000 0x0 0x0 | ||
2241 | 0x88000000 0x0 0x01000000 | ||
2242 | 0x02000000 0x0 0x80000000 | ||
2243 | 0x80000000 0x0 0x08000000>; | ||
2244 | bus-range = <0 255>; | ||
2245 | clock-frequency = <66000000>; | ||
2246 | interrupt-parent = <&PIC>; | ||
2247 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
2248 | interrupt-map = < | ||
2249 | /* IDSEL 0x0a */ | ||
2250 | 0x5000 0 0 1 &PIC 80 | ||
2251 | 0x5000 0 0 2 &PIC 81 | ||
2252 | 0x5000 0 0 3 &PIC 91 | ||
2253 | 0x5000 0 0 4 &PIC 93 | ||
2254 | |||
2255 | /* IDSEL 0x0b */ | ||
2256 | 0x5800 0 0 1 &PIC 91 | ||
2257 | 0x5800 0 0 2 &PIC 93 | ||
2258 | 0x5800 0 0 3 &PIC 80 | ||
2259 | 0x5800 0 0 4 &PIC 81 | ||
2260 | |||
2261 | /* IDSEL 0x0c */ | ||
2262 | 0x6000 0 0 1 &PIC 91 | ||
2263 | 0x6000 0 0 2 &PIC 93 | ||
2264 | 0x6000 0 0 3 &PIC 80 | ||
2265 | 0x6000 0 0 4 &PIC 81 | ||
2266 | |||
2267 | /* IDSEL 0x0d */ | ||
2268 | 0x6800 0 0 1 &PIC 93 | ||
2269 | 0x6800 0 0 2 &PIC 80 | ||
2270 | 0x6800 0 0 3 &PIC 81 | ||
2271 | 0x6800 0 0 4 &PIC 91 | ||
2272 | >; | ||
2273 | }; | ||
2274 | |||
2275 | |||
2276 | p) Marvell Discovery CPU Error nodes | ||
2277 | |||
2278 | Represent the Discovery's CPU error handler device. | ||
2279 | |||
2280 | Required properties: | ||
2281 | - compatible : "marvell,mv64360-cpu-error" | ||
2282 | - reg : Offset and length of the register set for this device | ||
2283 | - interrupts : the interrupt number for this device | ||
2284 | - interrupt-parent : the phandle for the interrupt controller | ||
2285 | that services interrupts for this device. | ||
2286 | |||
2287 | Example Discovery CPU Error node: | ||
2288 | cpu-error@0070 { | ||
2289 | compatible = "marvell,mv64360-cpu-error"; | ||
2290 | reg = <0x70 0x10 0x128 0x28>; | ||
2291 | interrupts = <3>; | ||
2292 | interrupt-parent = <&PIC>; | ||
2293 | }; | ||
2294 | |||
2295 | |||
2296 | q) Marvell Discovery SRAM Controller nodes | ||
2297 | |||
2298 | Represent the Discovery's SRAM controller device. | ||
2299 | |||
2300 | Required properties: | ||
2301 | - compatible : "marvell,mv64360-sram-ctrl" | ||
2302 | - reg : Offset and length of the register set for this device | ||
2303 | - interrupts : the interrupt number for this device | ||
2304 | - interrupt-parent : the phandle for the interrupt controller | ||
2305 | that services interrupts for this device. | ||
2306 | |||
2307 | Example Discovery SRAM Controller node: | ||
2308 | sram-ctrl@0380 { | ||
2309 | compatible = "marvell,mv64360-sram-ctrl"; | ||
2310 | reg = <0x380 0x80>; | ||
2311 | interrupts = <13>; | ||
2312 | interrupt-parent = <&PIC>; | ||
2313 | }; | ||
2314 | |||
2315 | |||
2316 | r) Marvell Discovery PCI Error Handler nodes | ||
2317 | |||
2318 | Represent the Discovery's PCI error handler device. | ||
2319 | |||
2320 | Required properties: | ||
2321 | - compatible : "marvell,mv64360-pci-error" | ||
2322 | - reg : Offset and length of the register set for this device | ||
2323 | - interrupts : the interrupt number for this device | ||
2324 | - interrupt-parent : the phandle for the interrupt controller | ||
2325 | that services interrupts for this device. | ||
2326 | |||
2327 | Example Discovery PCI Error Handler node: | ||
2328 | pci-error@1d40 { | ||
2329 | compatible = "marvell,mv64360-pci-error"; | ||
2330 | reg = <0x1d40 0x40 0xc28 0x4>; | ||
2331 | interrupts = <12>; | ||
2332 | interrupt-parent = <&PIC>; | ||
2333 | }; | ||
2334 | |||
2335 | |||
2336 | s) Marvell Discovery Memory Controller nodes | ||
2337 | |||
2338 | Represent the Discovery's memory controller device. | ||
2339 | |||
2340 | Required properties: | ||
2341 | - compatible : "marvell,mv64360-mem-ctrl" | ||
2342 | - reg : Offset and length of the register set for this device | ||
2343 | - interrupts : the interrupt number for this device | ||
2344 | - interrupt-parent : the phandle for the interrupt controller | ||
2345 | that services interrupts for this device. | ||
2346 | |||
2347 | Example Discovery Memory Controller node: | ||
2348 | mem-ctrl@1400 { | ||
2349 | compatible = "marvell,mv64360-mem-ctrl"; | ||
2350 | reg = <0x1400 0x60>; | ||
2351 | interrupts = <17>; | ||
2352 | interrupt-parent = <&PIC>; | ||
2353 | }; | ||
2354 | |||
2355 | |||
2356 | VIII - Specifying interrupt information for devices | ||
2357 | =================================================== | 1242 | =================================================== |
2358 | 1243 | ||
2359 | The device tree represents the busses and devices of a hardware | 1244 | The device tree represents the busses and devices of a hardware |
@@ -2439,56 +1324,7 @@ encodings listed below: | |||
2439 | 2 = high to low edge sensitive type enabled | 1324 | 2 = high to low edge sensitive type enabled |
2440 | 3 = low to high edge sensitive type enabled | 1325 | 3 = low to high edge sensitive type enabled |
2441 | 1326 | ||
2442 | IX - Specifying GPIO information for devices | 1327 | VIII - Specifying Device Power Management Information (sleep property) |
2443 | ============================================ | ||
2444 | |||
2445 | 1) gpios property | ||
2446 | ----------------- | ||
2447 | |||
2448 | Nodes that makes use of GPIOs should define them using `gpios' property, | ||
2449 | format of which is: <&gpio-controller1-phandle gpio1-specifier | ||
2450 | &gpio-controller2-phandle gpio2-specifier | ||
2451 | 0 /* holes are permitted, means no GPIO 3 */ | ||
2452 | &gpio-controller4-phandle gpio4-specifier | ||
2453 | ...>; | ||
2454 | |||
2455 | Note that gpio-specifier length is controller dependent. | ||
2456 | |||
2457 | gpio-specifier may encode: bank, pin position inside the bank, | ||
2458 | whether pin is open-drain and whether pin is logically inverted. | ||
2459 | |||
2460 | Example of the node using GPIOs: | ||
2461 | |||
2462 | node { | ||
2463 | gpios = <&qe_pio_e 18 0>; | ||
2464 | }; | ||
2465 | |||
2466 | In this example gpio-specifier is "18 0" and encodes GPIO pin number, | ||
2467 | and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller. | ||
2468 | |||
2469 | 2) gpio-controller nodes | ||
2470 | ------------------------ | ||
2471 | |||
2472 | Every GPIO controller node must have #gpio-cells property defined, | ||
2473 | this information will be used to translate gpio-specifiers. | ||
2474 | |||
2475 | Example of two SOC GPIO banks defined as gpio-controller nodes: | ||
2476 | |||
2477 | qe_pio_a: gpio-controller@1400 { | ||
2478 | #gpio-cells = <2>; | ||
2479 | compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; | ||
2480 | reg = <0x1400 0x18>; | ||
2481 | gpio-controller; | ||
2482 | }; | ||
2483 | |||
2484 | qe_pio_e: gpio-controller@1460 { | ||
2485 | #gpio-cells = <2>; | ||
2486 | compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; | ||
2487 | reg = <0x1460 0x18>; | ||
2488 | gpio-controller; | ||
2489 | }; | ||
2490 | |||
2491 | X - Specifying Device Power Management Information (sleep property) | ||
2492 | =================================================================== | 1328 | =================================================================== |
2493 | 1329 | ||
2494 | Devices on SOCs often have mechanisms for placing devices into low-power | 1330 | Devices on SOCs often have mechanisms for placing devices into low-power |
diff --git a/Documentation/powerpc/dts-bindings/4xx/emac.txt b/Documentation/powerpc/dts-bindings/4xx/emac.txt new file mode 100644 index 000000000000..2161334a7ca5 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/4xx/emac.txt | |||
@@ -0,0 +1,148 @@ | |||
1 | 4xx/Axon EMAC ethernet nodes | ||
2 | |||
3 | The EMAC ethernet controller in IBM and AMCC 4xx chips, and also | ||
4 | the Axon bridge. To operate this needs to interact with a ths | ||
5 | special McMAL DMA controller, and sometimes an RGMII or ZMII | ||
6 | interface. In addition to the nodes and properties described | ||
7 | below, the node for the OPB bus on which the EMAC sits must have a | ||
8 | correct clock-frequency property. | ||
9 | |||
10 | i) The EMAC node itself | ||
11 | |||
12 | Required properties: | ||
13 | - device_type : "network" | ||
14 | |||
15 | - compatible : compatible list, contains 2 entries, first is | ||
16 | "ibm,emac-CHIP" where CHIP is the host ASIC (440gx, | ||
17 | 405gp, Axon) and second is either "ibm,emac" or | ||
18 | "ibm,emac4". For Axon, thus, we have: "ibm,emac-axon", | ||
19 | "ibm,emac4" | ||
20 | - interrupts : <interrupt mapping for EMAC IRQ and WOL IRQ> | ||
21 | - interrupt-parent : optional, if needed for interrupt mapping | ||
22 | - reg : <registers mapping> | ||
23 | - local-mac-address : 6 bytes, MAC address | ||
24 | - mal-device : phandle of the associated McMAL node | ||
25 | - mal-tx-channel : 1 cell, index of the tx channel on McMAL associated | ||
26 | with this EMAC | ||
27 | - mal-rx-channel : 1 cell, index of the rx channel on McMAL associated | ||
28 | with this EMAC | ||
29 | - cell-index : 1 cell, hardware index of the EMAC cell on a given | ||
30 | ASIC (typically 0x0 and 0x1 for EMAC0 and EMAC1 on | ||
31 | each Axon chip) | ||
32 | - max-frame-size : 1 cell, maximum frame size supported in bytes | ||
33 | - rx-fifo-size : 1 cell, Rx fifo size in bytes for 10 and 100 Mb/sec | ||
34 | operations. | ||
35 | For Axon, 2048 | ||
36 | - tx-fifo-size : 1 cell, Tx fifo size in bytes for 10 and 100 Mb/sec | ||
37 | operations. | ||
38 | For Axon, 2048. | ||
39 | - fifo-entry-size : 1 cell, size of a fifo entry (used to calculate | ||
40 | thresholds). | ||
41 | For Axon, 0x00000010 | ||
42 | - mal-burst-size : 1 cell, MAL burst size (used to calculate thresholds) | ||
43 | in bytes. | ||
44 | For Axon, 0x00000100 (I think ...) | ||
45 | - phy-mode : string, mode of operations of the PHY interface. | ||
46 | Supported values are: "mii", "rmii", "smii", "rgmii", | ||
47 | "tbi", "gmii", rtbi", "sgmii". | ||
48 | For Axon on CAB, it is "rgmii" | ||
49 | - mdio-device : 1 cell, required iff using shared MDIO registers | ||
50 | (440EP). phandle of the EMAC to use to drive the | ||
51 | MDIO lines for the PHY used by this EMAC. | ||
52 | - zmii-device : 1 cell, required iff connected to a ZMII. phandle of | ||
53 | the ZMII device node | ||
54 | - zmii-channel : 1 cell, required iff connected to a ZMII. Which ZMII | ||
55 | channel or 0xffffffff if ZMII is only used for MDIO. | ||
56 | - rgmii-device : 1 cell, required iff connected to an RGMII. phandle | ||
57 | of the RGMII device node. | ||
58 | For Axon: phandle of plb5/plb4/opb/rgmii | ||
59 | - rgmii-channel : 1 cell, required iff connected to an RGMII. Which | ||
60 | RGMII channel is used by this EMAC. | ||
61 | Fox Axon: present, whatever value is appropriate for each | ||
62 | EMAC, that is the content of the current (bogus) "phy-port" | ||
63 | property. | ||
64 | |||
65 | Optional properties: | ||
66 | - phy-address : 1 cell, optional, MDIO address of the PHY. If absent, | ||
67 | a search is performed. | ||
68 | - phy-map : 1 cell, optional, bitmap of addresses to probe the PHY | ||
69 | for, used if phy-address is absent. bit 0x00000001 is | ||
70 | MDIO address 0. | ||
71 | For Axon it can be absent, though my current driver | ||
72 | doesn't handle phy-address yet so for now, keep | ||
73 | 0x00ffffff in it. | ||
74 | - rx-fifo-size-gige : 1 cell, Rx fifo size in bytes for 1000 Mb/sec | ||
75 | operations (if absent the value is the same as | ||
76 | rx-fifo-size). For Axon, either absent or 2048. | ||
77 | - tx-fifo-size-gige : 1 cell, Tx fifo size in bytes for 1000 Mb/sec | ||
78 | operations (if absent the value is the same as | ||
79 | tx-fifo-size). For Axon, either absent or 2048. | ||
80 | - tah-device : 1 cell, optional. If connected to a TAH engine for | ||
81 | offload, phandle of the TAH device node. | ||
82 | - tah-channel : 1 cell, optional. If appropriate, channel used on the | ||
83 | TAH engine. | ||
84 | |||
85 | Example: | ||
86 | |||
87 | EMAC0: ethernet@40000800 { | ||
88 | device_type = "network"; | ||
89 | compatible = "ibm,emac-440gp", "ibm,emac"; | ||
90 | interrupt-parent = <&UIC1>; | ||
91 | interrupts = <1c 4 1d 4>; | ||
92 | reg = <40000800 70>; | ||
93 | local-mac-address = [00 04 AC E3 1B 1E]; | ||
94 | mal-device = <&MAL0>; | ||
95 | mal-tx-channel = <0 1>; | ||
96 | mal-rx-channel = <0>; | ||
97 | cell-index = <0>; | ||
98 | max-frame-size = <5dc>; | ||
99 | rx-fifo-size = <1000>; | ||
100 | tx-fifo-size = <800>; | ||
101 | phy-mode = "rmii"; | ||
102 | phy-map = <00000001>; | ||
103 | zmii-device = <&ZMII0>; | ||
104 | zmii-channel = <0>; | ||
105 | }; | ||
106 | |||
107 | ii) McMAL node | ||
108 | |||
109 | Required properties: | ||
110 | - device_type : "dma-controller" | ||
111 | - compatible : compatible list, containing 2 entries, first is | ||
112 | "ibm,mcmal-CHIP" where CHIP is the host ASIC (like | ||
113 | emac) and the second is either "ibm,mcmal" or | ||
114 | "ibm,mcmal2". | ||
115 | For Axon, "ibm,mcmal-axon","ibm,mcmal2" | ||
116 | - interrupts : <interrupt mapping for the MAL interrupts sources: | ||
117 | 5 sources: tx_eob, rx_eob, serr, txde, rxde>. | ||
118 | For Axon: This is _different_ from the current | ||
119 | firmware. We use the "delayed" interrupts for txeob | ||
120 | and rxeob. Thus we end up with mapping those 5 MPIC | ||
121 | interrupts, all level positive sensitive: 10, 11, 32, | ||
122 | 33, 34 (in decimal) | ||
123 | - dcr-reg : < DCR registers range > | ||
124 | - dcr-parent : if needed for dcr-reg | ||
125 | - num-tx-chans : 1 cell, number of Tx channels | ||
126 | - num-rx-chans : 1 cell, number of Rx channels | ||
127 | |||
128 | iii) ZMII node | ||
129 | |||
130 | Required properties: | ||
131 | - compatible : compatible list, containing 2 entries, first is | ||
132 | "ibm,zmii-CHIP" where CHIP is the host ASIC (like | ||
133 | EMAC) and the second is "ibm,zmii". | ||
134 | For Axon, there is no ZMII node. | ||
135 | - reg : <registers mapping> | ||
136 | |||
137 | iv) RGMII node | ||
138 | |||
139 | Required properties: | ||
140 | - compatible : compatible list, containing 2 entries, first is | ||
141 | "ibm,rgmii-CHIP" where CHIP is the host ASIC (like | ||
142 | EMAC) and the second is "ibm,rgmii". | ||
143 | For Axon, "ibm,rgmii-axon","ibm,rgmii" | ||
144 | - reg : <registers mapping> | ||
145 | - revision : as provided by the RGMII new version register if | ||
146 | available. | ||
147 | For Axon: 0x0000012a | ||
148 | |||
diff --git a/Documentation/powerpc/dts-bindings/gpio/gpio.txt b/Documentation/powerpc/dts-bindings/gpio/gpio.txt new file mode 100644 index 000000000000..edaa84d288a1 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/gpio/gpio.txt | |||
@@ -0,0 +1,50 @@ | |||
1 | Specifying GPIO information for devices | ||
2 | ============================================ | ||
3 | |||
4 | 1) gpios property | ||
5 | ----------------- | ||
6 | |||
7 | Nodes that makes use of GPIOs should define them using `gpios' property, | ||
8 | format of which is: <&gpio-controller1-phandle gpio1-specifier | ||
9 | &gpio-controller2-phandle gpio2-specifier | ||
10 | 0 /* holes are permitted, means no GPIO 3 */ | ||
11 | &gpio-controller4-phandle gpio4-specifier | ||
12 | ...>; | ||
13 | |||
14 | Note that gpio-specifier length is controller dependent. | ||
15 | |||
16 | gpio-specifier may encode: bank, pin position inside the bank, | ||
17 | whether pin is open-drain and whether pin is logically inverted. | ||
18 | |||
19 | Example of the node using GPIOs: | ||
20 | |||
21 | node { | ||
22 | gpios = <&qe_pio_e 18 0>; | ||
23 | }; | ||
24 | |||
25 | In this example gpio-specifier is "18 0" and encodes GPIO pin number, | ||
26 | and empty GPIO flags as accepted by the "qe_pio_e" gpio-controller. | ||
27 | |||
28 | 2) gpio-controller nodes | ||
29 | ------------------------ | ||
30 | |||
31 | Every GPIO controller node must have #gpio-cells property defined, | ||
32 | this information will be used to translate gpio-specifiers. | ||
33 | |||
34 | Example of two SOC GPIO banks defined as gpio-controller nodes: | ||
35 | |||
36 | qe_pio_a: gpio-controller@1400 { | ||
37 | #gpio-cells = <2>; | ||
38 | compatible = "fsl,qe-pario-bank-a", "fsl,qe-pario-bank"; | ||
39 | reg = <0x1400 0x18>; | ||
40 | gpio-controller; | ||
41 | }; | ||
42 | |||
43 | qe_pio_e: gpio-controller@1460 { | ||
44 | #gpio-cells = <2>; | ||
45 | compatible = "fsl,qe-pario-bank-e", "fsl,qe-pario-bank"; | ||
46 | reg = <0x1460 0x18>; | ||
47 | gpio-controller; | ||
48 | }; | ||
49 | |||
50 | |||
diff --git a/Documentation/powerpc/dts-bindings/gpio/led.txt b/Documentation/powerpc/dts-bindings/gpio/led.txt index 4fe14deedc0a..064db928c3c1 100644 --- a/Documentation/powerpc/dts-bindings/gpio/led.txt +++ b/Documentation/powerpc/dts-bindings/gpio/led.txt | |||
@@ -16,10 +16,17 @@ LED sub-node properties: | |||
16 | string defining the trigger assigned to the LED. Current triggers are: | 16 | string defining the trigger assigned to the LED. Current triggers are: |
17 | "backlight" - LED will act as a back-light, controlled by the framebuffer | 17 | "backlight" - LED will act as a back-light, controlled by the framebuffer |
18 | system | 18 | system |
19 | "default-on" - LED will turn on | 19 | "default-on" - LED will turn on, but see "default-state" below |
20 | "heartbeat" - LED "double" flashes at a load average based rate | 20 | "heartbeat" - LED "double" flashes at a load average based rate |
21 | "ide-disk" - LED indicates disk activity | 21 | "ide-disk" - LED indicates disk activity |
22 | "timer" - LED flashes at a fixed, configurable rate | 22 | "timer" - LED flashes at a fixed, configurable rate |
23 | - default-state: (optional) The initial state of the LED. Valid | ||
24 | values are "on", "off", and "keep". If the LED is already on or off | ||
25 | and the default-state property is set the to same value, then no | ||
26 | glitch should be produced where the LED momentarily turns off (or | ||
27 | on). The "keep" setting will keep the LED at whatever its current | ||
28 | state is, without producing a glitch. The default is off if this | ||
29 | property is not present. | ||
23 | 30 | ||
24 | Examples: | 31 | Examples: |
25 | 32 | ||
@@ -30,14 +37,22 @@ leds { | |||
30 | gpios = <&mcu_pio 0 1>; /* Active low */ | 37 | gpios = <&mcu_pio 0 1>; /* Active low */ |
31 | linux,default-trigger = "ide-disk"; | 38 | linux,default-trigger = "ide-disk"; |
32 | }; | 39 | }; |
40 | |||
41 | fault { | ||
42 | gpios = <&mcu_pio 1 0>; | ||
43 | /* Keep LED on if BIOS detected hardware fault */ | ||
44 | default-state = "keep"; | ||
45 | }; | ||
33 | }; | 46 | }; |
34 | 47 | ||
35 | run-control { | 48 | run-control { |
36 | compatible = "gpio-leds"; | 49 | compatible = "gpio-leds"; |
37 | red { | 50 | red { |
38 | gpios = <&mpc8572 6 0>; | 51 | gpios = <&mpc8572 6 0>; |
52 | default-state = "off"; | ||
39 | }; | 53 | }; |
40 | green { | 54 | green { |
41 | gpios = <&mpc8572 7 0>; | 55 | gpios = <&mpc8572 7 0>; |
56 | default-state = "on"; | ||
42 | }; | 57 | }; |
43 | } | 58 | } |
diff --git a/Documentation/powerpc/dts-bindings/gpio/mdio.txt b/Documentation/powerpc/dts-bindings/gpio/mdio.txt new file mode 100644 index 000000000000..bc9549529014 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/gpio/mdio.txt | |||
@@ -0,0 +1,19 @@ | |||
1 | MDIO on GPIOs | ||
2 | |||
3 | Currently defined compatibles: | ||
4 | - virtual,gpio-mdio | ||
5 | |||
6 | MDC and MDIO lines connected to GPIO controllers are listed in the | ||
7 | gpios property as described in section VIII.1 in the following order: | ||
8 | |||
9 | MDC, MDIO. | ||
10 | |||
11 | Example: | ||
12 | |||
13 | mdio { | ||
14 | compatible = "virtual,mdio-gpio"; | ||
15 | #address-cells = <1>; | ||
16 | #size-cells = <0>; | ||
17 | gpios = <&qe_pio_a 11 | ||
18 | &qe_pio_c 6>; | ||
19 | }; | ||
diff --git a/Documentation/powerpc/dts-bindings/marvell.txt b/Documentation/powerpc/dts-bindings/marvell.txt new file mode 100644 index 000000000000..3708a2fd4747 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/marvell.txt | |||
@@ -0,0 +1,521 @@ | |||
1 | Marvell Discovery mv64[345]6x System Controller chips | ||
2 | =========================================================== | ||
3 | |||
4 | The Marvell mv64[345]60 series of system controller chips contain | ||
5 | many of the peripherals needed to implement a complete computer | ||
6 | system. In this section, we define device tree nodes to describe | ||
7 | the system controller chip itself and each of the peripherals | ||
8 | which it contains. Compatible string values for each node are | ||
9 | prefixed with the string "marvell,", for Marvell Technology Group Ltd. | ||
10 | |||
11 | 1) The /system-controller node | ||
12 | |||
13 | This node is used to represent the system-controller and must be | ||
14 | present when the system uses a system controller chip. The top-level | ||
15 | system-controller node contains information that is global to all | ||
16 | devices within the system controller chip. The node name begins | ||
17 | with "system-controller" followed by the unit address, which is | ||
18 | the base address of the memory-mapped register set for the system | ||
19 | controller chip. | ||
20 | |||
21 | Required properties: | ||
22 | |||
23 | - ranges : Describes the translation of system controller addresses | ||
24 | for memory mapped registers. | ||
25 | - clock-frequency: Contains the main clock frequency for the system | ||
26 | controller chip. | ||
27 | - reg : This property defines the address and size of the | ||
28 | memory-mapped registers contained within the system controller | ||
29 | chip. The address specified in the "reg" property should match | ||
30 | the unit address of the system-controller node. | ||
31 | - #address-cells : Address representation for system controller | ||
32 | devices. This field represents the number of cells needed to | ||
33 | represent the address of the memory-mapped registers of devices | ||
34 | within the system controller chip. | ||
35 | - #size-cells : Size representation for for the memory-mapped | ||
36 | registers within the system controller chip. | ||
37 | - #interrupt-cells : Defines the width of cells used to represent | ||
38 | interrupts. | ||
39 | |||
40 | Optional properties: | ||
41 | |||
42 | - model : The specific model of the system controller chip. Such | ||
43 | as, "mv64360", "mv64460", or "mv64560". | ||
44 | - compatible : A string identifying the compatibility identifiers | ||
45 | of the system controller chip. | ||
46 | |||
47 | The system-controller node contains child nodes for each system | ||
48 | controller device that the platform uses. Nodes should not be created | ||
49 | for devices which exist on the system controller chip but are not used | ||
50 | |||
51 | Example Marvell Discovery mv64360 system-controller node: | ||
52 | |||
53 | system-controller@f1000000 { /* Marvell Discovery mv64360 */ | ||
54 | #address-cells = <1>; | ||
55 | #size-cells = <1>; | ||
56 | model = "mv64360"; /* Default */ | ||
57 | compatible = "marvell,mv64360"; | ||
58 | clock-frequency = <133333333>; | ||
59 | reg = <0xf1000000 0x10000>; | ||
60 | virtual-reg = <0xf1000000>; | ||
61 | ranges = <0x88000000 0x88000000 0x1000000 /* PCI 0 I/O Space */ | ||
62 | 0x80000000 0x80000000 0x8000000 /* PCI 0 MEM Space */ | ||
63 | 0xa0000000 0xa0000000 0x4000000 /* User FLASH */ | ||
64 | 0x00000000 0xf1000000 0x0010000 /* Bridge's regs */ | ||
65 | 0xf2000000 0xf2000000 0x0040000>;/* Integrated SRAM */ | ||
66 | |||
67 | [ child node definitions... ] | ||
68 | } | ||
69 | |||
70 | 2) Child nodes of /system-controller | ||
71 | |||
72 | a) Marvell Discovery MDIO bus | ||
73 | |||
74 | The MDIO is a bus to which the PHY devices are connected. For each | ||
75 | device that exists on this bus, a child node should be created. See | ||
76 | the definition of the PHY node below for an example of how to define | ||
77 | a PHY. | ||
78 | |||
79 | Required properties: | ||
80 | - #address-cells : Should be <1> | ||
81 | - #size-cells : Should be <0> | ||
82 | - device_type : Should be "mdio" | ||
83 | - compatible : Should be "marvell,mv64360-mdio" | ||
84 | |||
85 | Example: | ||
86 | |||
87 | mdio { | ||
88 | #address-cells = <1>; | ||
89 | #size-cells = <0>; | ||
90 | device_type = "mdio"; | ||
91 | compatible = "marvell,mv64360-mdio"; | ||
92 | |||
93 | ethernet-phy@0 { | ||
94 | ...... | ||
95 | }; | ||
96 | }; | ||
97 | |||
98 | |||
99 | b) Marvell Discovery ethernet controller | ||
100 | |||
101 | The Discover ethernet controller is described with two levels | ||
102 | of nodes. The first level describes an ethernet silicon block | ||
103 | and the second level describes up to 3 ethernet nodes within | ||
104 | that block. The reason for the multiple levels is that the | ||
105 | registers for the node are interleaved within a single set | ||
106 | of registers. The "ethernet-block" level describes the | ||
107 | shared register set, and the "ethernet" nodes describe ethernet | ||
108 | port-specific properties. | ||
109 | |||
110 | Ethernet block node | ||
111 | |||
112 | Required properties: | ||
113 | - #address-cells : <1> | ||
114 | - #size-cells : <0> | ||
115 | - compatible : "marvell,mv64360-eth-block" | ||
116 | - reg : Offset and length of the register set for this block | ||
117 | |||
118 | Example Discovery Ethernet block node: | ||
119 | ethernet-block@2000 { | ||
120 | #address-cells = <1>; | ||
121 | #size-cells = <0>; | ||
122 | compatible = "marvell,mv64360-eth-block"; | ||
123 | reg = <0x2000 0x2000>; | ||
124 | ethernet@0 { | ||
125 | ....... | ||
126 | }; | ||
127 | }; | ||
128 | |||
129 | Ethernet port node | ||
130 | |||
131 | Required properties: | ||
132 | - device_type : Should be "network". | ||
133 | - compatible : Should be "marvell,mv64360-eth". | ||
134 | - reg : Should be <0>, <1>, or <2>, according to which registers | ||
135 | within the silicon block the device uses. | ||
136 | - interrupts : <a> where a is the interrupt number for the port. | ||
137 | - interrupt-parent : the phandle for the interrupt controller | ||
138 | that services interrupts for this device. | ||
139 | - phy : the phandle for the PHY connected to this ethernet | ||
140 | controller. | ||
141 | - local-mac-address : 6 bytes, MAC address | ||
142 | |||
143 | Example Discovery Ethernet port node: | ||
144 | ethernet@0 { | ||
145 | device_type = "network"; | ||
146 | compatible = "marvell,mv64360-eth"; | ||
147 | reg = <0>; | ||
148 | interrupts = <32>; | ||
149 | interrupt-parent = <&PIC>; | ||
150 | phy = <&PHY0>; | ||
151 | local-mac-address = [ 00 00 00 00 00 00 ]; | ||
152 | }; | ||
153 | |||
154 | |||
155 | |||
156 | c) Marvell Discovery PHY nodes | ||
157 | |||
158 | Required properties: | ||
159 | - device_type : Should be "ethernet-phy" | ||
160 | - interrupts : <a> where a is the interrupt number for this phy. | ||
161 | - interrupt-parent : the phandle for the interrupt controller that | ||
162 | services interrupts for this device. | ||
163 | - reg : The ID number for the phy, usually a small integer | ||
164 | |||
165 | Example Discovery PHY node: | ||
166 | ethernet-phy@1 { | ||
167 | device_type = "ethernet-phy"; | ||
168 | compatible = "broadcom,bcm5421"; | ||
169 | interrupts = <76>; /* GPP 12 */ | ||
170 | interrupt-parent = <&PIC>; | ||
171 | reg = <1>; | ||
172 | }; | ||
173 | |||
174 | |||
175 | d) Marvell Discovery SDMA nodes | ||
176 | |||
177 | Represent DMA hardware associated with the MPSC (multiprotocol | ||
178 | serial controllers). | ||
179 | |||
180 | Required properties: | ||
181 | - compatible : "marvell,mv64360-sdma" | ||
182 | - reg : Offset and length of the register set for this device | ||
183 | - interrupts : <a> where a is the interrupt number for the DMA | ||
184 | device. | ||
185 | - interrupt-parent : the phandle for the interrupt controller | ||
186 | that services interrupts for this device. | ||
187 | |||
188 | Example Discovery SDMA node: | ||
189 | sdma@4000 { | ||
190 | compatible = "marvell,mv64360-sdma"; | ||
191 | reg = <0x4000 0xc18>; | ||
192 | virtual-reg = <0xf1004000>; | ||
193 | interrupts = <36>; | ||
194 | interrupt-parent = <&PIC>; | ||
195 | }; | ||
196 | |||
197 | |||
198 | e) Marvell Discovery BRG nodes | ||
199 | |||
200 | Represent baud rate generator hardware associated with the MPSC | ||
201 | (multiprotocol serial controllers). | ||
202 | |||
203 | Required properties: | ||
204 | - compatible : "marvell,mv64360-brg" | ||
205 | - reg : Offset and length of the register set for this device | ||
206 | - clock-src : A value from 0 to 15 which selects the clock | ||
207 | source for the baud rate generator. This value corresponds | ||
208 | to the CLKS value in the BRGx configuration register. See | ||
209 | the mv64x60 User's Manual. | ||
210 | - clock-frequence : The frequency (in Hz) of the baud rate | ||
211 | generator's input clock. | ||
212 | - current-speed : The current speed setting (presumably by | ||
213 | firmware) of the baud rate generator. | ||
214 | |||
215 | Example Discovery BRG node: | ||
216 | brg@b200 { | ||
217 | compatible = "marvell,mv64360-brg"; | ||
218 | reg = <0xb200 0x8>; | ||
219 | clock-src = <8>; | ||
220 | clock-frequency = <133333333>; | ||
221 | current-speed = <9600>; | ||
222 | }; | ||
223 | |||
224 | |||
225 | f) Marvell Discovery CUNIT nodes | ||
226 | |||
227 | Represent the Serial Communications Unit device hardware. | ||
228 | |||
229 | Required properties: | ||
230 | - reg : Offset and length of the register set for this device | ||
231 | |||
232 | Example Discovery CUNIT node: | ||
233 | cunit@f200 { | ||
234 | reg = <0xf200 0x200>; | ||
235 | }; | ||
236 | |||
237 | |||
238 | g) Marvell Discovery MPSCROUTING nodes | ||
239 | |||
240 | Represent the Discovery's MPSC routing hardware | ||
241 | |||
242 | Required properties: | ||
243 | - reg : Offset and length of the register set for this device | ||
244 | |||
245 | Example Discovery CUNIT node: | ||
246 | mpscrouting@b500 { | ||
247 | reg = <0xb400 0xc>; | ||
248 | }; | ||
249 | |||
250 | |||
251 | h) Marvell Discovery MPSCINTR nodes | ||
252 | |||
253 | Represent the Discovery's MPSC DMA interrupt hardware registers | ||
254 | (SDMA cause and mask registers). | ||
255 | |||
256 | Required properties: | ||
257 | - reg : Offset and length of the register set for this device | ||
258 | |||
259 | Example Discovery MPSCINTR node: | ||
260 | mpsintr@b800 { | ||
261 | reg = <0xb800 0x100>; | ||
262 | }; | ||
263 | |||
264 | |||
265 | i) Marvell Discovery MPSC nodes | ||
266 | |||
267 | Represent the Discovery's MPSC (Multiprotocol Serial Controller) | ||
268 | serial port. | ||
269 | |||
270 | Required properties: | ||
271 | - device_type : "serial" | ||
272 | - compatible : "marvell,mv64360-mpsc" | ||
273 | - reg : Offset and length of the register set for this device | ||
274 | - sdma : the phandle for the SDMA node used by this port | ||
275 | - brg : the phandle for the BRG node used by this port | ||
276 | - cunit : the phandle for the CUNIT node used by this port | ||
277 | - mpscrouting : the phandle for the MPSCROUTING node used by this port | ||
278 | - mpscintr : the phandle for the MPSCINTR node used by this port | ||
279 | - cell-index : the hardware index of this cell in the MPSC core | ||
280 | - max_idle : value needed for MPSC CHR3 (Maximum Frame Length) | ||
281 | register | ||
282 | - interrupts : <a> where a is the interrupt number for the MPSC. | ||
283 | - interrupt-parent : the phandle for the interrupt controller | ||
284 | that services interrupts for this device. | ||
285 | |||
286 | Example Discovery MPSCINTR node: | ||
287 | mpsc@8000 { | ||
288 | device_type = "serial"; | ||
289 | compatible = "marvell,mv64360-mpsc"; | ||
290 | reg = <0x8000 0x38>; | ||
291 | virtual-reg = <0xf1008000>; | ||
292 | sdma = <&SDMA0>; | ||
293 | brg = <&BRG0>; | ||
294 | cunit = <&CUNIT>; | ||
295 | mpscrouting = <&MPSCROUTING>; | ||
296 | mpscintr = <&MPSCINTR>; | ||
297 | cell-index = <0>; | ||
298 | max_idle = <40>; | ||
299 | interrupts = <40>; | ||
300 | interrupt-parent = <&PIC>; | ||
301 | }; | ||
302 | |||
303 | |||
304 | j) Marvell Discovery Watch Dog Timer nodes | ||
305 | |||
306 | Represent the Discovery's watchdog timer hardware | ||
307 | |||
308 | Required properties: | ||
309 | - compatible : "marvell,mv64360-wdt" | ||
310 | - reg : Offset and length of the register set for this device | ||
311 | |||
312 | Example Discovery Watch Dog Timer node: | ||
313 | wdt@b410 { | ||
314 | compatible = "marvell,mv64360-wdt"; | ||
315 | reg = <0xb410 0x8>; | ||
316 | }; | ||
317 | |||
318 | |||
319 | k) Marvell Discovery I2C nodes | ||
320 | |||
321 | Represent the Discovery's I2C hardware | ||
322 | |||
323 | Required properties: | ||
324 | - device_type : "i2c" | ||
325 | - compatible : "marvell,mv64360-i2c" | ||
326 | - reg : Offset and length of the register set for this device | ||
327 | - interrupts : <a> where a is the interrupt number for the I2C. | ||
328 | - interrupt-parent : the phandle for the interrupt controller | ||
329 | that services interrupts for this device. | ||
330 | |||
331 | Example Discovery I2C node: | ||
332 | compatible = "marvell,mv64360-i2c"; | ||
333 | reg = <0xc000 0x20>; | ||
334 | virtual-reg = <0xf100c000>; | ||
335 | interrupts = <37>; | ||
336 | interrupt-parent = <&PIC>; | ||
337 | }; | ||
338 | |||
339 | |||
340 | l) Marvell Discovery PIC (Programmable Interrupt Controller) nodes | ||
341 | |||
342 | Represent the Discovery's PIC hardware | ||
343 | |||
344 | Required properties: | ||
345 | - #interrupt-cells : <1> | ||
346 | - #address-cells : <0> | ||
347 | - compatible : "marvell,mv64360-pic" | ||
348 | - reg : Offset and length of the register set for this device | ||
349 | - interrupt-controller | ||
350 | |||
351 | Example Discovery PIC node: | ||
352 | pic { | ||
353 | #interrupt-cells = <1>; | ||
354 | #address-cells = <0>; | ||
355 | compatible = "marvell,mv64360-pic"; | ||
356 | reg = <0x0 0x88>; | ||
357 | interrupt-controller; | ||
358 | }; | ||
359 | |||
360 | |||
361 | m) Marvell Discovery MPP (Multipurpose Pins) multiplexing nodes | ||
362 | |||
363 | Represent the Discovery's MPP hardware | ||
364 | |||
365 | Required properties: | ||
366 | - compatible : "marvell,mv64360-mpp" | ||
367 | - reg : Offset and length of the register set for this device | ||
368 | |||
369 | Example Discovery MPP node: | ||
370 | mpp@f000 { | ||
371 | compatible = "marvell,mv64360-mpp"; | ||
372 | reg = <0xf000 0x10>; | ||
373 | }; | ||
374 | |||
375 | |||
376 | n) Marvell Discovery GPP (General Purpose Pins) nodes | ||
377 | |||
378 | Represent the Discovery's GPP hardware | ||
379 | |||
380 | Required properties: | ||
381 | - compatible : "marvell,mv64360-gpp" | ||
382 | - reg : Offset and length of the register set for this device | ||
383 | |||
384 | Example Discovery GPP node: | ||
385 | gpp@f000 { | ||
386 | compatible = "marvell,mv64360-gpp"; | ||
387 | reg = <0xf100 0x20>; | ||
388 | }; | ||
389 | |||
390 | |||
391 | o) Marvell Discovery PCI host bridge node | ||
392 | |||
393 | Represents the Discovery's PCI host bridge device. The properties | ||
394 | for this node conform to Rev 2.1 of the PCI Bus Binding to IEEE | ||
395 | 1275-1994. A typical value for the compatible property is | ||
396 | "marvell,mv64360-pci". | ||
397 | |||
398 | Example Discovery PCI host bridge node | ||
399 | pci@80000000 { | ||
400 | #address-cells = <3>; | ||
401 | #size-cells = <2>; | ||
402 | #interrupt-cells = <1>; | ||
403 | device_type = "pci"; | ||
404 | compatible = "marvell,mv64360-pci"; | ||
405 | reg = <0xcf8 0x8>; | ||
406 | ranges = <0x01000000 0x0 0x0 | ||
407 | 0x88000000 0x0 0x01000000 | ||
408 | 0x02000000 0x0 0x80000000 | ||
409 | 0x80000000 0x0 0x08000000>; | ||
410 | bus-range = <0 255>; | ||
411 | clock-frequency = <66000000>; | ||
412 | interrupt-parent = <&PIC>; | ||
413 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
414 | interrupt-map = < | ||
415 | /* IDSEL 0x0a */ | ||
416 | 0x5000 0 0 1 &PIC 80 | ||
417 | 0x5000 0 0 2 &PIC 81 | ||
418 | 0x5000 0 0 3 &PIC 91 | ||
419 | 0x5000 0 0 4 &PIC 93 | ||
420 | |||
421 | /* IDSEL 0x0b */ | ||
422 | 0x5800 0 0 1 &PIC 91 | ||
423 | 0x5800 0 0 2 &PIC 93 | ||
424 | 0x5800 0 0 3 &PIC 80 | ||
425 | 0x5800 0 0 4 &PIC 81 | ||
426 | |||
427 | /* IDSEL 0x0c */ | ||
428 | 0x6000 0 0 1 &PIC 91 | ||
429 | 0x6000 0 0 2 &PIC 93 | ||
430 | 0x6000 0 0 3 &PIC 80 | ||
431 | 0x6000 0 0 4 &PIC 81 | ||
432 | |||
433 | /* IDSEL 0x0d */ | ||
434 | 0x6800 0 0 1 &PIC 93 | ||
435 | 0x6800 0 0 2 &PIC 80 | ||
436 | 0x6800 0 0 3 &PIC 81 | ||
437 | 0x6800 0 0 4 &PIC 91 | ||
438 | >; | ||
439 | }; | ||
440 | |||
441 | |||
442 | p) Marvell Discovery CPU Error nodes | ||
443 | |||
444 | Represent the Discovery's CPU error handler device. | ||
445 | |||
446 | Required properties: | ||
447 | - compatible : "marvell,mv64360-cpu-error" | ||
448 | - reg : Offset and length of the register set for this device | ||
449 | - interrupts : the interrupt number for this device | ||
450 | - interrupt-parent : the phandle for the interrupt controller | ||
451 | that services interrupts for this device. | ||
452 | |||
453 | Example Discovery CPU Error node: | ||
454 | cpu-error@0070 { | ||
455 | compatible = "marvell,mv64360-cpu-error"; | ||
456 | reg = <0x70 0x10 0x128 0x28>; | ||
457 | interrupts = <3>; | ||
458 | interrupt-parent = <&PIC>; | ||
459 | }; | ||
460 | |||
461 | |||
462 | q) Marvell Discovery SRAM Controller nodes | ||
463 | |||
464 | Represent the Discovery's SRAM controller device. | ||
465 | |||
466 | Required properties: | ||
467 | - compatible : "marvell,mv64360-sram-ctrl" | ||
468 | - reg : Offset and length of the register set for this device | ||
469 | - interrupts : the interrupt number for this device | ||
470 | - interrupt-parent : the phandle for the interrupt controller | ||
471 | that services interrupts for this device. | ||
472 | |||
473 | Example Discovery SRAM Controller node: | ||
474 | sram-ctrl@0380 { | ||
475 | compatible = "marvell,mv64360-sram-ctrl"; | ||
476 | reg = <0x380 0x80>; | ||
477 | interrupts = <13>; | ||
478 | interrupt-parent = <&PIC>; | ||
479 | }; | ||
480 | |||
481 | |||
482 | r) Marvell Discovery PCI Error Handler nodes | ||
483 | |||
484 | Represent the Discovery's PCI error handler device. | ||
485 | |||
486 | Required properties: | ||
487 | - compatible : "marvell,mv64360-pci-error" | ||
488 | - reg : Offset and length of the register set for this device | ||
489 | - interrupts : the interrupt number for this device | ||
490 | - interrupt-parent : the phandle for the interrupt controller | ||
491 | that services interrupts for this device. | ||
492 | |||
493 | Example Discovery PCI Error Handler node: | ||
494 | pci-error@1d40 { | ||
495 | compatible = "marvell,mv64360-pci-error"; | ||
496 | reg = <0x1d40 0x40 0xc28 0x4>; | ||
497 | interrupts = <12>; | ||
498 | interrupt-parent = <&PIC>; | ||
499 | }; | ||
500 | |||
501 | |||
502 | s) Marvell Discovery Memory Controller nodes | ||
503 | |||
504 | Represent the Discovery's memory controller device. | ||
505 | |||
506 | Required properties: | ||
507 | - compatible : "marvell,mv64360-mem-ctrl" | ||
508 | - reg : Offset and length of the register set for this device | ||
509 | - interrupts : the interrupt number for this device | ||
510 | - interrupt-parent : the phandle for the interrupt controller | ||
511 | that services interrupts for this device. | ||
512 | |||
513 | Example Discovery Memory Controller node: | ||
514 | mem-ctrl@1400 { | ||
515 | compatible = "marvell,mv64360-mem-ctrl"; | ||
516 | reg = <0x1400 0x60>; | ||
517 | interrupts = <17>; | ||
518 | interrupt-parent = <&PIC>; | ||
519 | }; | ||
520 | |||
521 | |||
diff --git a/Documentation/powerpc/dts-bindings/phy.txt b/Documentation/powerpc/dts-bindings/phy.txt new file mode 100644 index 000000000000..bb8c742eb8c5 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/phy.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | PHY nodes | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - device_type : Should be "ethernet-phy" | ||
6 | - interrupts : <a b> where a is the interrupt number and b is a | ||
7 | field that represents an encoding of the sense and level | ||
8 | information for the interrupt. This should be encoded based on | ||
9 | the information in section 2) depending on the type of interrupt | ||
10 | controller you have. | ||
11 | - interrupt-parent : the phandle for the interrupt controller that | ||
12 | services interrupts for this device. | ||
13 | - reg : The ID number for the phy, usually a small integer | ||
14 | - linux,phandle : phandle for this node; likely referenced by an | ||
15 | ethernet controller node. | ||
16 | |||
17 | Example: | ||
18 | |||
19 | ethernet-phy@0 { | ||
20 | linux,phandle = <2452000> | ||
21 | interrupt-parent = <40000>; | ||
22 | interrupts = <35 1>; | ||
23 | reg = <0>; | ||
24 | device_type = "ethernet-phy"; | ||
25 | }; | ||
diff --git a/Documentation/powerpc/dts-bindings/spi-bus.txt b/Documentation/powerpc/dts-bindings/spi-bus.txt new file mode 100644 index 000000000000..e782add2e457 --- /dev/null +++ b/Documentation/powerpc/dts-bindings/spi-bus.txt | |||
@@ -0,0 +1,57 @@ | |||
1 | SPI (Serial Peripheral Interface) busses | ||
2 | |||
3 | SPI busses can be described with a node for the SPI master device | ||
4 | and a set of child nodes for each SPI slave on the bus. For this | ||
5 | discussion, it is assumed that the system's SPI controller is in | ||
6 | SPI master mode. This binding does not describe SPI controllers | ||
7 | in slave mode. | ||
8 | |||
9 | The SPI master node requires the following properties: | ||
10 | - #address-cells - number of cells required to define a chip select | ||
11 | address on the SPI bus. | ||
12 | - #size-cells - should be zero. | ||
13 | - compatible - name of SPI bus controller following generic names | ||
14 | recommended practice. | ||
15 | No other properties are required in the SPI bus node. It is assumed | ||
16 | that a driver for an SPI bus device will understand that it is an SPI bus. | ||
17 | However, the binding does not attempt to define the specific method for | ||
18 | assigning chip select numbers. Since SPI chip select configuration is | ||
19 | flexible and non-standardized, it is left out of this binding with the | ||
20 | assumption that board specific platform code will be used to manage | ||
21 | chip selects. Individual drivers can define additional properties to | ||
22 | support describing the chip select layout. | ||
23 | |||
24 | SPI slave nodes must be children of the SPI master node and can | ||
25 | contain the following properties. | ||
26 | - reg - (required) chip select address of device. | ||
27 | - compatible - (required) name of SPI device following generic names | ||
28 | recommended practice | ||
29 | - spi-max-frequency - (required) Maximum SPI clocking speed of device in Hz | ||
30 | - spi-cpol - (optional) Empty property indicating device requires | ||
31 | inverse clock polarity (CPOL) mode | ||
32 | - spi-cpha - (optional) Empty property indicating device requires | ||
33 | shifted clock phase (CPHA) mode | ||
34 | - spi-cs-high - (optional) Empty property indicating device requires | ||
35 | chip select active high | ||
36 | |||
37 | SPI example for an MPC5200 SPI bus: | ||
38 | spi@f00 { | ||
39 | #address-cells = <1>; | ||
40 | #size-cells = <0>; | ||
41 | compatible = "fsl,mpc5200b-spi","fsl,mpc5200-spi"; | ||
42 | reg = <0xf00 0x20>; | ||
43 | interrupts = <2 13 0 2 14 0>; | ||
44 | interrupt-parent = <&mpc5200_pic>; | ||
45 | |||
46 | ethernet-switch@0 { | ||
47 | compatible = "micrel,ks8995m"; | ||
48 | spi-max-frequency = <1000000>; | ||
49 | reg = <0>; | ||
50 | }; | ||
51 | |||
52 | codec@1 { | ||
53 | compatible = "ti,tlv320aic26"; | ||
54 | spi-max-frequency = <100000>; | ||
55 | reg = <1>; | ||
56 | }; | ||
57 | }; | ||
diff --git a/Documentation/powerpc/dts-bindings/usb-ehci.txt b/Documentation/powerpc/dts-bindings/usb-ehci.txt new file mode 100644 index 000000000000..fa18612f757b --- /dev/null +++ b/Documentation/powerpc/dts-bindings/usb-ehci.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | USB EHCI controllers | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : should be "usb-ehci". | ||
5 | - reg : should contain at least address and length of the standard EHCI | ||
6 | register set for the device. Optional platform-dependent registers | ||
7 | (debug-port or other) can be also specified here, but only after | ||
8 | definition of standard EHCI registers. | ||
9 | - interrupts : one EHCI interrupt should be described here. | ||
10 | If device registers are implemented in big endian mode, the device | ||
11 | node should have "big-endian-regs" property. | ||
12 | If controller implementation operates with big endian descriptors, | ||
13 | "big-endian-desc" property should be specified. | ||
14 | If both big endian registers and descriptors are used by the controller | ||
15 | implementation, "big-endian" property can be specified instead of having | ||
16 | both "big-endian-regs" and "big-endian-desc". | ||
17 | |||
18 | Example (Sequoia 440EPx): | ||
19 | ehci@e0000300 { | ||
20 | compatible = "ibm,usb-ehci-440epx", "usb-ehci"; | ||
21 | interrupt-parent = <&UIC0>; | ||
22 | interrupts = <1a 4>; | ||
23 | reg = <0 e0000300 90 0 e0000390 70>; | ||
24 | big-endian; | ||
25 | }; | ||
diff --git a/Documentation/powerpc/dts-bindings/xilinx.txt b/Documentation/powerpc/dts-bindings/xilinx.txt new file mode 100644 index 000000000000..80339fe4300b --- /dev/null +++ b/Documentation/powerpc/dts-bindings/xilinx.txt | |||
@@ -0,0 +1,295 @@ | |||
1 | d) Xilinx IP cores | ||
2 | |||
3 | The Xilinx EDK toolchain ships with a set of IP cores (devices) for use | ||
4 | in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range | ||
5 | of standard device types (network, serial, etc.) and miscellaneous | ||
6 | devices (gpio, LCD, spi, etc). Also, since these devices are | ||
7 | implemented within the fpga fabric every instance of the device can be | ||
8 | synthesised with different options that change the behaviour. | ||
9 | |||
10 | Each IP-core has a set of parameters which the FPGA designer can use to | ||
11 | control how the core is synthesized. Historically, the EDK tool would | ||
12 | extract the device parameters relevant to device drivers and copy them | ||
13 | into an 'xparameters.h' in the form of #define symbols. This tells the | ||
14 | device drivers how the IP cores are configured, but it requres the kernel | ||
15 | to be recompiled every time the FPGA bitstream is resynthesized. | ||
16 | |||
17 | The new approach is to export the parameters into the device tree and | ||
18 | generate a new device tree each time the FPGA bitstream changes. The | ||
19 | parameters which used to be exported as #defines will now become | ||
20 | properties of the device node. In general, device nodes for IP-cores | ||
21 | will take the following form: | ||
22 | |||
23 | (name): (generic-name)@(base-address) { | ||
24 | compatible = "xlnx,(ip-core-name)-(HW_VER)" | ||
25 | [, (list of compatible devices), ...]; | ||
26 | reg = <(baseaddr) (size)>; | ||
27 | interrupt-parent = <&interrupt-controller-phandle>; | ||
28 | interrupts = < ... >; | ||
29 | xlnx,(parameter1) = "(string-value)"; | ||
30 | xlnx,(parameter2) = <(int-value)>; | ||
31 | }; | ||
32 | |||
33 | (generic-name): an open firmware-style name that describes the | ||
34 | generic class of device. Preferably, this is one word, such | ||
35 | as 'serial' or 'ethernet'. | ||
36 | (ip-core-name): the name of the ip block (given after the BEGIN | ||
37 | directive in system.mhs). Should be in lowercase | ||
38 | and all underscores '_' converted to dashes '-'. | ||
39 | (name): is derived from the "PARAMETER INSTANCE" value. | ||
40 | (parameter#): C_* parameters from system.mhs. The C_ prefix is | ||
41 | dropped from the parameter name, the name is converted | ||
42 | to lowercase and all underscore '_' characters are | ||
43 | converted to dashes '-'. | ||
44 | (baseaddr): the baseaddr parameter value (often named C_BASEADDR). | ||
45 | (HW_VER): from the HW_VER parameter. | ||
46 | (size): the address range size (often C_HIGHADDR - C_BASEADDR + 1). | ||
47 | |||
48 | Typically, the compatible list will include the exact IP core version | ||
49 | followed by an older IP core version which implements the same | ||
50 | interface or any other device with the same interface. | ||
51 | |||
52 | 'reg', 'interrupt-parent' and 'interrupts' are all optional properties. | ||
53 | |||
54 | For example, the following block from system.mhs: | ||
55 | |||
56 | BEGIN opb_uartlite | ||
57 | PARAMETER INSTANCE = opb_uartlite_0 | ||
58 | PARAMETER HW_VER = 1.00.b | ||
59 | PARAMETER C_BAUDRATE = 115200 | ||
60 | PARAMETER C_DATA_BITS = 8 | ||
61 | PARAMETER C_ODD_PARITY = 0 | ||
62 | PARAMETER C_USE_PARITY = 0 | ||
63 | PARAMETER C_CLK_FREQ = 50000000 | ||
64 | PARAMETER C_BASEADDR = 0xEC100000 | ||
65 | PARAMETER C_HIGHADDR = 0xEC10FFFF | ||
66 | BUS_INTERFACE SOPB = opb_7 | ||
67 | PORT OPB_Clk = CLK_50MHz | ||
68 | PORT Interrupt = opb_uartlite_0_Interrupt | ||
69 | PORT RX = opb_uartlite_0_RX | ||
70 | PORT TX = opb_uartlite_0_TX | ||
71 | PORT OPB_Rst = sys_bus_reset_0 | ||
72 | END | ||
73 | |||
74 | becomes the following device tree node: | ||
75 | |||
76 | opb_uartlite_0: serial@ec100000 { | ||
77 | device_type = "serial"; | ||
78 | compatible = "xlnx,opb-uartlite-1.00.b"; | ||
79 | reg = <ec100000 10000>; | ||
80 | interrupt-parent = <&opb_intc_0>; | ||
81 | interrupts = <1 0>; // got this from the opb_intc parameters | ||
82 | current-speed = <d#115200>; // standard serial device prop | ||
83 | clock-frequency = <d#50000000>; // standard serial device prop | ||
84 | xlnx,data-bits = <8>; | ||
85 | xlnx,odd-parity = <0>; | ||
86 | xlnx,use-parity = <0>; | ||
87 | }; | ||
88 | |||
89 | Some IP cores actually implement 2 or more logical devices. In | ||
90 | this case, the device should still describe the whole IP core with | ||
91 | a single node and add a child node for each logical device. The | ||
92 | ranges property can be used to translate from parent IP-core to the | ||
93 | registers of each device. In addition, the parent node should be | ||
94 | compatible with the bus type 'xlnx,compound', and should contain | ||
95 | #address-cells and #size-cells, as with any other bus. (Note: this | ||
96 | makes the assumption that both logical devices have the same bus | ||
97 | binding. If this is not true, then separate nodes should be used | ||
98 | for each logical device). The 'cell-index' property can be used to | ||
99 | enumerate logical devices within an IP core. For example, the | ||
100 | following is the system.mhs entry for the dual ps2 controller found | ||
101 | on the ml403 reference design. | ||
102 | |||
103 | BEGIN opb_ps2_dual_ref | ||
104 | PARAMETER INSTANCE = opb_ps2_dual_ref_0 | ||
105 | PARAMETER HW_VER = 1.00.a | ||
106 | PARAMETER C_BASEADDR = 0xA9000000 | ||
107 | PARAMETER C_HIGHADDR = 0xA9001FFF | ||
108 | BUS_INTERFACE SOPB = opb_v20_0 | ||
109 | PORT Sys_Intr1 = ps2_1_intr | ||
110 | PORT Sys_Intr2 = ps2_2_intr | ||
111 | PORT Clkin1 = ps2_clk_rx_1 | ||
112 | PORT Clkin2 = ps2_clk_rx_2 | ||
113 | PORT Clkpd1 = ps2_clk_tx_1 | ||
114 | PORT Clkpd2 = ps2_clk_tx_2 | ||
115 | PORT Rx1 = ps2_d_rx_1 | ||
116 | PORT Rx2 = ps2_d_rx_2 | ||
117 | PORT Txpd1 = ps2_d_tx_1 | ||
118 | PORT Txpd2 = ps2_d_tx_2 | ||
119 | END | ||
120 | |||
121 | It would result in the following device tree nodes: | ||
122 | |||
123 | opb_ps2_dual_ref_0: opb-ps2-dual-ref@a9000000 { | ||
124 | #address-cells = <1>; | ||
125 | #size-cells = <1>; | ||
126 | compatible = "xlnx,compound"; | ||
127 | ranges = <0 a9000000 2000>; | ||
128 | // If this device had extra parameters, then they would | ||
129 | // go here. | ||
130 | ps2@0 { | ||
131 | compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; | ||
132 | reg = <0 40>; | ||
133 | interrupt-parent = <&opb_intc_0>; | ||
134 | interrupts = <3 0>; | ||
135 | cell-index = <0>; | ||
136 | }; | ||
137 | ps2@1000 { | ||
138 | compatible = "xlnx,opb-ps2-dual-ref-1.00.a"; | ||
139 | reg = <1000 40>; | ||
140 | interrupt-parent = <&opb_intc_0>; | ||
141 | interrupts = <3 0>; | ||
142 | cell-index = <0>; | ||
143 | }; | ||
144 | }; | ||
145 | |||
146 | Also, the system.mhs file defines bus attachments from the processor | ||
147 | to the devices. The device tree structure should reflect the bus | ||
148 | attachments. Again an example; this system.mhs fragment: | ||
149 | |||
150 | BEGIN ppc405_virtex4 | ||
151 | PARAMETER INSTANCE = ppc405_0 | ||
152 | PARAMETER HW_VER = 1.01.a | ||
153 | BUS_INTERFACE DPLB = plb_v34_0 | ||
154 | BUS_INTERFACE IPLB = plb_v34_0 | ||
155 | END | ||
156 | |||
157 | BEGIN opb_intc | ||
158 | PARAMETER INSTANCE = opb_intc_0 | ||
159 | PARAMETER HW_VER = 1.00.c | ||
160 | PARAMETER C_BASEADDR = 0xD1000FC0 | ||
161 | PARAMETER C_HIGHADDR = 0xD1000FDF | ||
162 | BUS_INTERFACE SOPB = opb_v20_0 | ||
163 | END | ||
164 | |||
165 | BEGIN opb_uart16550 | ||
166 | PARAMETER INSTANCE = opb_uart16550_0 | ||
167 | PARAMETER HW_VER = 1.00.d | ||
168 | PARAMETER C_BASEADDR = 0xa0000000 | ||
169 | PARAMETER C_HIGHADDR = 0xa0001FFF | ||
170 | BUS_INTERFACE SOPB = opb_v20_0 | ||
171 | END | ||
172 | |||
173 | BEGIN plb_v34 | ||
174 | PARAMETER INSTANCE = plb_v34_0 | ||
175 | PARAMETER HW_VER = 1.02.a | ||
176 | END | ||
177 | |||
178 | BEGIN plb_bram_if_cntlr | ||
179 | PARAMETER INSTANCE = plb_bram_if_cntlr_0 | ||
180 | PARAMETER HW_VER = 1.00.b | ||
181 | PARAMETER C_BASEADDR = 0xFFFF0000 | ||
182 | PARAMETER C_HIGHADDR = 0xFFFFFFFF | ||
183 | BUS_INTERFACE SPLB = plb_v34_0 | ||
184 | END | ||
185 | |||
186 | BEGIN plb2opb_bridge | ||
187 | PARAMETER INSTANCE = plb2opb_bridge_0 | ||
188 | PARAMETER HW_VER = 1.01.a | ||
189 | PARAMETER C_RNG0_BASEADDR = 0x20000000 | ||
190 | PARAMETER C_RNG0_HIGHADDR = 0x3FFFFFFF | ||
191 | PARAMETER C_RNG1_BASEADDR = 0x60000000 | ||
192 | PARAMETER C_RNG1_HIGHADDR = 0x7FFFFFFF | ||
193 | PARAMETER C_RNG2_BASEADDR = 0x80000000 | ||
194 | PARAMETER C_RNG2_HIGHADDR = 0xBFFFFFFF | ||
195 | PARAMETER C_RNG3_BASEADDR = 0xC0000000 | ||
196 | PARAMETER C_RNG3_HIGHADDR = 0xDFFFFFFF | ||
197 | BUS_INTERFACE SPLB = plb_v34_0 | ||
198 | BUS_INTERFACE MOPB = opb_v20_0 | ||
199 | END | ||
200 | |||
201 | Gives this device tree (some properties removed for clarity): | ||
202 | |||
203 | plb@0 { | ||
204 | #address-cells = <1>; | ||
205 | #size-cells = <1>; | ||
206 | compatible = "xlnx,plb-v34-1.02.a"; | ||
207 | device_type = "ibm,plb"; | ||
208 | ranges; // 1:1 translation | ||
209 | |||
210 | plb_bram_if_cntrl_0: bram@ffff0000 { | ||
211 | reg = <ffff0000 10000>; | ||
212 | } | ||
213 | |||
214 | opb@20000000 { | ||
215 | #address-cells = <1>; | ||
216 | #size-cells = <1>; | ||
217 | ranges = <20000000 20000000 20000000 | ||
218 | 60000000 60000000 20000000 | ||
219 | 80000000 80000000 40000000 | ||
220 | c0000000 c0000000 20000000>; | ||
221 | |||
222 | opb_uart16550_0: serial@a0000000 { | ||
223 | reg = <a00000000 2000>; | ||
224 | }; | ||
225 | |||
226 | opb_intc_0: interrupt-controller@d1000fc0 { | ||
227 | reg = <d1000fc0 20>; | ||
228 | }; | ||
229 | }; | ||
230 | }; | ||
231 | |||
232 | That covers the general approach to binding xilinx IP cores into the | ||
233 | device tree. The following are bindings for specific devices: | ||
234 | |||
235 | i) Xilinx ML300 Framebuffer | ||
236 | |||
237 | Simple framebuffer device from the ML300 reference design (also on the | ||
238 | ML403 reference design as well as others). | ||
239 | |||
240 | Optional properties: | ||
241 | - resolution = <xres yres> : pixel resolution of framebuffer. Some | ||
242 | implementations use a different resolution. | ||
243 | Default is <d#640 d#480> | ||
244 | - virt-resolution = <xvirt yvirt> : Size of framebuffer in memory. | ||
245 | Default is <d#1024 d#480>. | ||
246 | - rotate-display (empty) : rotate display 180 degrees. | ||
247 | |||
248 | ii) Xilinx SystemACE | ||
249 | |||
250 | The Xilinx SystemACE device is used to program FPGAs from an FPGA | ||
251 | bitstream stored on a CF card. It can also be used as a generic CF | ||
252 | interface device. | ||
253 | |||
254 | Optional properties: | ||
255 | - 8-bit (empty) : Set this property for SystemACE in 8 bit mode | ||
256 | |||
257 | iii) Xilinx EMAC and Xilinx TEMAC | ||
258 | |||
259 | Xilinx Ethernet devices. In addition to general xilinx properties | ||
260 | listed above, nodes for these devices should include a phy-handle | ||
261 | property, and may include other common network device properties | ||
262 | like local-mac-address. | ||
263 | |||
264 | iv) Xilinx Uartlite | ||
265 | |||
266 | Xilinx uartlite devices are simple fixed speed serial ports. | ||
267 | |||
268 | Required properties: | ||
269 | - current-speed : Baud rate of uartlite | ||
270 | |||
271 | v) Xilinx hwicap | ||
272 | |||
273 | Xilinx hwicap devices provide access to the configuration logic | ||
274 | of the FPGA through the Internal Configuration Access Port | ||
275 | (ICAP). The ICAP enables partial reconfiguration of the FPGA, | ||
276 | readback of the configuration information, and some control over | ||
277 | 'warm boots' of the FPGA fabric. | ||
278 | |||
279 | Required properties: | ||
280 | - xlnx,family : The family of the FPGA, necessary since the | ||
281 | capabilities of the underlying ICAP hardware | ||
282 | differ between different families. May be | ||
283 | 'virtex2p', 'virtex4', or 'virtex5'. | ||
284 | |||
285 | vi) Xilinx Uart 16550 | ||
286 | |||
287 | Xilinx UART 16550 devices are very similar to the NS16550 but with | ||
288 | different register spacing and an offset from the base address. | ||
289 | |||
290 | Required properties: | ||
291 | - clock-frequency : Frequency of the clock input | ||
292 | - reg-offset : A value of 3 is required | ||
293 | - reg-shift : A value of 2 is required | ||
294 | |||
295 | |||
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 0d8d23581c44..939a3dd58148 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
@@ -240,6 +240,7 @@ AD1986A | |||
240 | laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) | 240 | laptop-automute 2-channel with EAPD and HP-automute (Lenovo N100) |
241 | ultra 2-channel with EAPD (Samsung Ultra tablet PC) | 241 | ultra 2-channel with EAPD (Samsung Ultra tablet PC) |
242 | samsung 2-channel with EAPD (Samsung R65) | 242 | samsung 2-channel with EAPD (Samsung R65) |
243 | samsung-p50 2-channel with HP-automute (Samsung P50) | ||
243 | 244 | ||
244 | AD1988/AD1988B/AD1989A/AD1989B | 245 | AD1988/AD1988B/AD1989A/AD1989B |
245 | ============================== | 246 | ============================== |
diff --git a/MAINTAINERS b/MAINTAINERS index 0e3942af54e6..05a9a563042f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5711,6 +5711,13 @@ F: drivers/misc/tifm* | |||
5711 | F: drivers/mmc/host/tifm_sd.c | 5711 | F: drivers/mmc/host/tifm_sd.c |
5712 | F: include/linux/tifm.h | 5712 | F: include/linux/tifm.h |
5713 | 5713 | ||
5714 | TI TWL4030 SERIES SOC CODEC DRIVER | ||
5715 | P: Peter Ujfalusi | ||
5716 | M: peter.ujfalusi@nokia.com | ||
5717 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | ||
5718 | S: Maintained | ||
5719 | F: sound/soc/codecs/twl4030* | ||
5720 | |||
5714 | TIPC NETWORK LAYER | 5721 | TIPC NETWORK LAYER |
5715 | P: Per Liden | 5722 | P: Per Liden |
5716 | M: per.liden@ericsson.com | 5723 | M: per.liden@ericsson.com |
diff --git a/arch/ia64/kvm/kvm_lib.c b/arch/ia64/kvm/kvm_lib.c index a85cb611ecd7..f1268b8e6f9e 100644 --- a/arch/ia64/kvm/kvm_lib.c +++ b/arch/ia64/kvm/kvm_lib.c | |||
@@ -11,5 +11,11 @@ | |||
11 | * | 11 | * |
12 | */ | 12 | */ |
13 | #undef CONFIG_MODULES | 13 | #undef CONFIG_MODULES |
14 | #include <linux/module.h> | ||
15 | #undef CONFIG_KALLSYMS | ||
16 | #undef EXPORT_SYMBOL | ||
17 | #undef EXPORT_SYMBOL_GPL | ||
18 | #define EXPORT_SYMBOL(sym) | ||
19 | #define EXPORT_SYMBOL_GPL(sym) | ||
14 | #include "../../../lib/vsprintf.c" | 20 | #include "../../../lib/vsprintf.c" |
15 | #include "../../../lib/ctype.c" | 21 | #include "../../../lib/ctype.c" |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index bf6cedfa05db..d00131ca0835 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -62,7 +62,6 @@ config HAVE_LATENCYTOP_SUPPORT | |||
62 | 62 | ||
63 | config TRACE_IRQFLAGS_SUPPORT | 63 | config TRACE_IRQFLAGS_SUPPORT |
64 | bool | 64 | bool |
65 | depends on PPC64 | ||
66 | default y | 65 | default y |
67 | 66 | ||
68 | config LOCKDEP_SUPPORT | 67 | config LOCKDEP_SUPPORT |
diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore index 2f50acd11a60..3d80c3e9cf60 100644 --- a/arch/powerpc/boot/.gitignore +++ b/arch/powerpc/boot/.gitignore | |||
@@ -36,3 +36,13 @@ zImage.pseries | |||
36 | zconf.h | 36 | zconf.h |
37 | zlib.h | 37 | zlib.h |
38 | zutil.h | 38 | zutil.h |
39 | fdt.c | ||
40 | fdt.h | ||
41 | fdt_ro.c | ||
42 | fdt_rw.c | ||
43 | fdt_strerror.c | ||
44 | fdt_sw.c | ||
45 | fdt_wip.c | ||
46 | libfdt.h | ||
47 | libfdt_internal.h | ||
48 | |||
diff --git a/arch/powerpc/boot/dts/amigaone.dts b/arch/powerpc/boot/dts/amigaone.dts index 26549fca2ed4..49ac36b16dd7 100644 --- a/arch/powerpc/boot/dts/amigaone.dts +++ b/arch/powerpc/boot/dts/amigaone.dts | |||
@@ -70,8 +70,8 @@ | |||
70 | devsel-speed = <0x00000001>; | 70 | devsel-speed = <0x00000001>; |
71 | min-grant = <0>; | 71 | min-grant = <0>; |
72 | max-latency = <0>; | 72 | max-latency = <0>; |
73 | /* First 64k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */ | 73 | /* First 4k for I/O at 0x0 on PCI mapped to 0x0 on ISA. */ |
74 | ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00010000>; | 74 | ranges = <0x00000001 0 0x01000000 0 0x00000000 0x00001000>; |
75 | interrupt-parent = <&i8259>; | 75 | interrupt-parent = <&i8259>; |
76 | #interrupt-cells = <2>; | 76 | #interrupt-cells = <2>; |
77 | #address-cells = <2>; | 77 | #address-cells = <2>; |
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts index a8dcb018c4a5..a680165292f2 100644 --- a/arch/powerpc/boot/dts/mpc8569mds.dts +++ b/arch/powerpc/boot/dts/mpc8569mds.dts | |||
@@ -253,6 +253,7 @@ | |||
253 | /* Filled in by U-Boot */ | 253 | /* Filled in by U-Boot */ |
254 | clock-frequency = <0>; | 254 | clock-frequency = <0>; |
255 | status = "disabled"; | 255 | status = "disabled"; |
256 | sdhci,1-bit-only; | ||
256 | }; | 257 | }; |
257 | 258 | ||
258 | crypto@30000 { | 259 | crypto@30000 { |
diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h index 2ff798744c1d..7685ffde8821 100644 --- a/arch/powerpc/include/asm/cpm1.h +++ b/arch/powerpc/include/asm/cpm1.h | |||
@@ -598,8 +598,6 @@ typedef struct risc_timer_pram { | |||
598 | #define CICR_IEN ((uint)0x00000080) /* Int. enable */ | 598 | #define CICR_IEN ((uint)0x00000080) /* Int. enable */ |
599 | #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ | 599 | #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ |
600 | 600 | ||
601 | #define IMAP_ADDR (get_immrbase()) | ||
602 | |||
603 | #define CPM_PIN_INPUT 0 | 601 | #define CPM_PIN_INPUT 0 |
604 | #define CPM_PIN_OUTPUT 1 | 602 | #define CPM_PIN_OUTPUT 1 |
605 | #define CPM_PIN_PRIMARY 0 | 603 | #define CPM_PIN_PRIMARY 0 |
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h index 3d9e887c3c0c..b44aaabdd1a6 100644 --- a/arch/powerpc/include/asm/dma-mapping.h +++ b/arch/powerpc/include/asm/dma-mapping.h | |||
@@ -309,7 +309,9 @@ static inline void dma_sync_single_for_cpu(struct device *dev, | |||
309 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 309 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); |
310 | 310 | ||
311 | BUG_ON(!dma_ops); | 311 | BUG_ON(!dma_ops); |
312 | dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, | 312 | |
313 | if (dma_ops->sync_single_range_for_cpu) | ||
314 | dma_ops->sync_single_range_for_cpu(dev, dma_handle, 0, | ||
313 | size, direction); | 315 | size, direction); |
314 | } | 316 | } |
315 | 317 | ||
@@ -320,7 +322,9 @@ static inline void dma_sync_single_for_device(struct device *dev, | |||
320 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 322 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); |
321 | 323 | ||
322 | BUG_ON(!dma_ops); | 324 | BUG_ON(!dma_ops); |
323 | dma_ops->sync_single_range_for_device(dev, dma_handle, | 325 | |
326 | if (dma_ops->sync_single_range_for_device) | ||
327 | dma_ops->sync_single_range_for_device(dev, dma_handle, | ||
324 | 0, size, direction); | 328 | 0, size, direction); |
325 | } | 329 | } |
326 | 330 | ||
@@ -331,7 +335,9 @@ static inline void dma_sync_sg_for_cpu(struct device *dev, | |||
331 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 335 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); |
332 | 336 | ||
333 | BUG_ON(!dma_ops); | 337 | BUG_ON(!dma_ops); |
334 | dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); | 338 | |
339 | if (dma_ops->sync_sg_for_cpu) | ||
340 | dma_ops->sync_sg_for_cpu(dev, sgl, nents, direction); | ||
335 | } | 341 | } |
336 | 342 | ||
337 | static inline void dma_sync_sg_for_device(struct device *dev, | 343 | static inline void dma_sync_sg_for_device(struct device *dev, |
@@ -341,7 +347,9 @@ static inline void dma_sync_sg_for_device(struct device *dev, | |||
341 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 347 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); |
342 | 348 | ||
343 | BUG_ON(!dma_ops); | 349 | BUG_ON(!dma_ops); |
344 | dma_ops->sync_sg_for_device(dev, sgl, nents, direction); | 350 | |
351 | if (dma_ops->sync_sg_for_device) | ||
352 | dma_ops->sync_sg_for_device(dev, sgl, nents, direction); | ||
345 | } | 353 | } |
346 | 354 | ||
347 | static inline void dma_sync_single_range_for_cpu(struct device *dev, | 355 | static inline void dma_sync_single_range_for_cpu(struct device *dev, |
@@ -351,7 +359,9 @@ static inline void dma_sync_single_range_for_cpu(struct device *dev, | |||
351 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 359 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); |
352 | 360 | ||
353 | BUG_ON(!dma_ops); | 361 | BUG_ON(!dma_ops); |
354 | dma_ops->sync_single_range_for_cpu(dev, dma_handle, | 362 | |
363 | if (dma_ops->sync_single_range_for_cpu) | ||
364 | dma_ops->sync_single_range_for_cpu(dev, dma_handle, | ||
355 | offset, size, direction); | 365 | offset, size, direction); |
356 | } | 366 | } |
357 | 367 | ||
@@ -362,7 +372,9 @@ static inline void dma_sync_single_range_for_device(struct device *dev, | |||
362 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); | 372 | struct dma_mapping_ops *dma_ops = get_dma_ops(dev); |
363 | 373 | ||
364 | BUG_ON(!dma_ops); | 374 | BUG_ON(!dma_ops); |
365 | dma_ops->sync_single_range_for_device(dev, dma_handle, offset, | 375 | |
376 | if (dma_ops->sync_single_range_for_device) | ||
377 | dma_ops->sync_single_range_for_device(dev, dma_handle, offset, | ||
366 | size, direction); | 378 | size, direction); |
367 | } | 379 | } |
368 | #else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */ | 380 | #else /* CONFIG_PPC_NEED_DMA_SYNC_OPS */ |
diff --git a/arch/powerpc/include/asm/highmem.h b/arch/powerpc/include/asm/highmem.h index 684a73f4324f..a74c4ee6c020 100644 --- a/arch/powerpc/include/asm/highmem.h +++ b/arch/powerpc/include/asm/highmem.h | |||
@@ -22,9 +22,7 @@ | |||
22 | 22 | ||
23 | #ifdef __KERNEL__ | 23 | #ifdef __KERNEL__ |
24 | 24 | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
27 | #include <linux/highmem.h> | ||
28 | #include <asm/kmap_types.h> | 26 | #include <asm/kmap_types.h> |
29 | #include <asm/tlbflush.h> | 27 | #include <asm/tlbflush.h> |
30 | #include <asm/page.h> | 28 | #include <asm/page.h> |
@@ -62,6 +60,9 @@ extern pte_t *pkmap_page_table; | |||
62 | 60 | ||
63 | extern void *kmap_high(struct page *page); | 61 | extern void *kmap_high(struct page *page); |
64 | extern void kunmap_high(struct page *page); | 62 | extern void kunmap_high(struct page *page); |
63 | extern void *kmap_atomic_prot(struct page *page, enum km_type type, | ||
64 | pgprot_t prot); | ||
65 | extern void kunmap_atomic(void *kvaddr, enum km_type type); | ||
65 | 66 | ||
66 | static inline void *kmap(struct page *page) | 67 | static inline void *kmap(struct page *page) |
67 | { | 68 | { |
@@ -79,62 +80,11 @@ static inline void kunmap(struct page *page) | |||
79 | kunmap_high(page); | 80 | kunmap_high(page); |
80 | } | 81 | } |
81 | 82 | ||
82 | /* | ||
83 | * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap | ||
84 | * gives a more generic (and caching) interface. But kmap_atomic can | ||
85 | * be used in IRQ contexts, so in some (very limited) cases we need | ||
86 | * it. | ||
87 | */ | ||
88 | static inline void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | ||
89 | { | ||
90 | unsigned int idx; | ||
91 | unsigned long vaddr; | ||
92 | |||
93 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ | ||
94 | pagefault_disable(); | ||
95 | if (!PageHighMem(page)) | ||
96 | return page_address(page); | ||
97 | |||
98 | debug_kmap_atomic(type); | ||
99 | idx = type + KM_TYPE_NR*smp_processor_id(); | ||
100 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
101 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
102 | BUG_ON(!pte_none(*(kmap_pte-idx))); | ||
103 | #endif | ||
104 | __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1); | ||
105 | local_flush_tlb_page(NULL, vaddr); | ||
106 | |||
107 | return (void*) vaddr; | ||
108 | } | ||
109 | |||
110 | static inline void *kmap_atomic(struct page *page, enum km_type type) | 83 | static inline void *kmap_atomic(struct page *page, enum km_type type) |
111 | { | 84 | { |
112 | return kmap_atomic_prot(page, type, kmap_prot); | 85 | return kmap_atomic_prot(page, type, kmap_prot); |
113 | } | 86 | } |
114 | 87 | ||
115 | static inline void kunmap_atomic(void *kvaddr, enum km_type type) | ||
116 | { | ||
117 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
118 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | ||
119 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | ||
120 | |||
121 | if (vaddr < __fix_to_virt(FIX_KMAP_END)) { | ||
122 | pagefault_enable(); | ||
123 | return; | ||
124 | } | ||
125 | |||
126 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); | ||
127 | |||
128 | /* | ||
129 | * force other mappings to Oops if they'll try to access | ||
130 | * this pte without first remap it | ||
131 | */ | ||
132 | pte_clear(&init_mm, vaddr, kmap_pte-idx); | ||
133 | local_flush_tlb_page(NULL, vaddr); | ||
134 | #endif | ||
135 | pagefault_enable(); | ||
136 | } | ||
137 | |||
138 | static inline struct page *kmap_atomic_to_page(void *ptr) | 88 | static inline struct page *kmap_atomic_to_page(void *ptr) |
139 | { | 89 | { |
140 | unsigned long idx, vaddr = (unsigned long) ptr; | 90 | unsigned long idx, vaddr = (unsigned long) ptr; |
@@ -148,6 +98,7 @@ static inline struct page *kmap_atomic_to_page(void *ptr) | |||
148 | return pte_page(*pte); | 98 | return pte_page(*pte); |
149 | } | 99 | } |
150 | 100 | ||
101 | |||
151 | #define flush_cache_kmaps() flush_cache_all() | 102 | #define flush_cache_kmaps() flush_cache_all() |
152 | 103 | ||
153 | #endif /* __KERNEL__ */ | 104 | #endif /* __KERNEL__ */ |
diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h index 867ab8ed69b3..8b505eaaa38a 100644 --- a/arch/powerpc/include/asm/hw_irq.h +++ b/arch/powerpc/include/asm/hw_irq.h | |||
@@ -68,13 +68,13 @@ static inline int irqs_disabled_flags(unsigned long flags) | |||
68 | 68 | ||
69 | #if defined(CONFIG_BOOKE) | 69 | #if defined(CONFIG_BOOKE) |
70 | #define SET_MSR_EE(x) mtmsr(x) | 70 | #define SET_MSR_EE(x) mtmsr(x) |
71 | #define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") | 71 | #define raw_local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") |
72 | #else | 72 | #else |
73 | #define SET_MSR_EE(x) mtmsr(x) | 73 | #define SET_MSR_EE(x) mtmsr(x) |
74 | #define local_irq_restore(flags) mtmsr(flags) | 74 | #define raw_local_irq_restore(flags) mtmsr(flags) |
75 | #endif | 75 | #endif |
76 | 76 | ||
77 | static inline void local_irq_disable(void) | 77 | static inline void raw_local_irq_disable(void) |
78 | { | 78 | { |
79 | #ifdef CONFIG_BOOKE | 79 | #ifdef CONFIG_BOOKE |
80 | __asm__ __volatile__("wrteei 0": : :"memory"); | 80 | __asm__ __volatile__("wrteei 0": : :"memory"); |
@@ -86,7 +86,7 @@ static inline void local_irq_disable(void) | |||
86 | #endif | 86 | #endif |
87 | } | 87 | } |
88 | 88 | ||
89 | static inline void local_irq_enable(void) | 89 | static inline void raw_local_irq_enable(void) |
90 | { | 90 | { |
91 | #ifdef CONFIG_BOOKE | 91 | #ifdef CONFIG_BOOKE |
92 | __asm__ __volatile__("wrteei 1": : :"memory"); | 92 | __asm__ __volatile__("wrteei 1": : :"memory"); |
@@ -98,7 +98,7 @@ static inline void local_irq_enable(void) | |||
98 | #endif | 98 | #endif |
99 | } | 99 | } |
100 | 100 | ||
101 | static inline void local_irq_save_ptr(unsigned long *flags) | 101 | static inline void raw_local_irq_save_ptr(unsigned long *flags) |
102 | { | 102 | { |
103 | unsigned long msr; | 103 | unsigned long msr; |
104 | msr = mfmsr(); | 104 | msr = mfmsr(); |
@@ -110,12 +110,12 @@ static inline void local_irq_save_ptr(unsigned long *flags) | |||
110 | #endif | 110 | #endif |
111 | } | 111 | } |
112 | 112 | ||
113 | #define local_save_flags(flags) ((flags) = mfmsr()) | 113 | #define raw_local_save_flags(flags) ((flags) = mfmsr()) |
114 | #define local_irq_save(flags) local_irq_save_ptr(&flags) | 114 | #define raw_local_irq_save(flags) raw_local_irq_save_ptr(&flags) |
115 | #define irqs_disabled() ((mfmsr() & MSR_EE) == 0) | 115 | #define raw_irqs_disabled() ((mfmsr() & MSR_EE) == 0) |
116 | #define raw_irqs_disabled_flags(flags) (((flags) & MSR_EE) == 0) | ||
116 | 117 | ||
117 | #define hard_irq_enable() local_irq_enable() | 118 | #define hard_irq_disable() raw_local_irq_disable() |
118 | #define hard_irq_disable() local_irq_disable() | ||
119 | 119 | ||
120 | static inline int irqs_disabled_flags(unsigned long flags) | 120 | static inline int irqs_disabled_flags(unsigned long flags) |
121 | { | 121 | { |
diff --git a/arch/powerpc/include/asm/pte-hash64-64k.h b/arch/powerpc/include/asm/pte-hash64-64k.h index e05d26fa372f..82b72207c51c 100644 --- a/arch/powerpc/include/asm/pte-hash64-64k.h +++ b/arch/powerpc/include/asm/pte-hash64-64k.h | |||
@@ -47,7 +47,8 @@ | |||
47 | * generic accessors and iterators here | 47 | * generic accessors and iterators here |
48 | */ | 48 | */ |
49 | #define __real_pte(e,p) ((real_pte_t) { \ | 49 | #define __real_pte(e,p) ((real_pte_t) { \ |
50 | (e), pte_val(*((p) + PTRS_PER_PTE)) }) | 50 | (e), ((e) & _PAGE_COMBO) ? \ |
51 | (pte_val(*((p) + PTRS_PER_PTE))) : 0 }) | ||
51 | #define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \ | 52 | #define __rpte_to_hidx(r,index) ((pte_val((r).pte) & _PAGE_COMBO) ? \ |
52 | (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf)) | 53 | (((r).hidx >> ((index)<<2)) & 0xf) : ((pte_val((r).pte) >> 12) & 0xf)) |
53 | #define __rpte_to_pte(r) ((r).pte) | 54 | #define __rpte_to_pte(r) ((r).pte) |
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index 01c12339b304..168fce726201 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h | |||
@@ -58,7 +58,7 @@ struct rtas_t { | |||
58 | unsigned long entry; /* physical address pointer */ | 58 | unsigned long entry; /* physical address pointer */ |
59 | unsigned long base; /* physical address pointer */ | 59 | unsigned long base; /* physical address pointer */ |
60 | unsigned long size; | 60 | unsigned long size; |
61 | spinlock_t lock; | 61 | raw_spinlock_t lock; |
62 | struct rtas_args args; | 62 | struct rtas_args args; |
63 | struct device_node *dev; /* virtual address pointer */ | 63 | struct device_node *dev; /* virtual address pointer */ |
64 | }; | 64 | }; |
@@ -245,5 +245,8 @@ static inline u32 rtas_config_addr(int busno, int devfn, int reg) | |||
245 | (devfn << 8) | (reg & 0xff); | 245 | (devfn << 8) | (reg & 0xff); |
246 | } | 246 | } |
247 | 247 | ||
248 | extern void __cpuinit rtas_give_timebase(void); | ||
249 | extern void __cpuinit rtas_take_timebase(void); | ||
250 | |||
248 | #endif /* __KERNEL__ */ | 251 | #endif /* __KERNEL__ */ |
249 | #endif /* _POWERPC_RTAS_H */ | 252 | #endif /* _POWERPC_RTAS_H */ |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index 4dd38f129153..3cadba60a4b6 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
@@ -191,11 +191,49 @@ transfer_to_handler_cont: | |||
191 | mflr r9 | 191 | mflr r9 |
192 | lwz r11,0(r9) /* virtual address of handler */ | 192 | lwz r11,0(r9) /* virtual address of handler */ |
193 | lwz r9,4(r9) /* where to go when done */ | 193 | lwz r9,4(r9) /* where to go when done */ |
194 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
195 | lis r12,reenable_mmu@h | ||
196 | ori r12,r12,reenable_mmu@l | ||
197 | mtspr SPRN_SRR0,r12 | ||
198 | mtspr SPRN_SRR1,r10 | ||
199 | SYNC | ||
200 | RFI | ||
201 | reenable_mmu: /* re-enable mmu so we can */ | ||
202 | mfmsr r10 | ||
203 | lwz r12,_MSR(r1) | ||
204 | xor r10,r10,r12 | ||
205 | andi. r10,r10,MSR_EE /* Did EE change? */ | ||
206 | beq 1f | ||
207 | |||
208 | /* Save handler and return address into the 2 unused words | ||
209 | * of the STACK_FRAME_OVERHEAD (sneak sneak sneak). Everything | ||
210 | * else can be recovered from the pt_regs except r3 which for | ||
211 | * normal interrupts has been set to pt_regs and for syscalls | ||
212 | * is an argument, so we temporarily use ORIG_GPR3 to save it | ||
213 | */ | ||
214 | stw r9,8(r1) | ||
215 | stw r11,12(r1) | ||
216 | stw r3,ORIG_GPR3(r1) | ||
217 | bl trace_hardirqs_off | ||
218 | lwz r0,GPR0(r1) | ||
219 | lwz r3,ORIG_GPR3(r1) | ||
220 | lwz r4,GPR4(r1) | ||
221 | lwz r5,GPR5(r1) | ||
222 | lwz r6,GPR6(r1) | ||
223 | lwz r7,GPR7(r1) | ||
224 | lwz r8,GPR8(r1) | ||
225 | lwz r9,8(r1) | ||
226 | lwz r11,12(r1) | ||
227 | 1: mtctr r11 | ||
228 | mtlr r9 | ||
229 | bctr /* jump to handler */ | ||
230 | #else /* CONFIG_TRACE_IRQFLAGS */ | ||
194 | mtspr SPRN_SRR0,r11 | 231 | mtspr SPRN_SRR0,r11 |
195 | mtspr SPRN_SRR1,r10 | 232 | mtspr SPRN_SRR1,r10 |
196 | mtlr r9 | 233 | mtlr r9 |
197 | SYNC | 234 | SYNC |
198 | RFI /* jump to handler, enable MMU */ | 235 | RFI /* jump to handler, enable MMU */ |
236 | #endif /* CONFIG_TRACE_IRQFLAGS */ | ||
199 | 237 | ||
200 | #if defined (CONFIG_6xx) || defined(CONFIG_E500) | 238 | #if defined (CONFIG_6xx) || defined(CONFIG_E500) |
201 | 4: rlwinm r12,r12,0,~_TLF_NAPPING | 239 | 4: rlwinm r12,r12,0,~_TLF_NAPPING |
@@ -251,6 +289,31 @@ _GLOBAL(DoSyscall) | |||
251 | #ifdef SHOW_SYSCALLS | 289 | #ifdef SHOW_SYSCALLS |
252 | bl do_show_syscall | 290 | bl do_show_syscall |
253 | #endif /* SHOW_SYSCALLS */ | 291 | #endif /* SHOW_SYSCALLS */ |
292 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
293 | /* Return from syscalls can (and generally will) hard enable | ||
294 | * interrupts. You aren't supposed to call a syscall with | ||
295 | * interrupts disabled in the first place. However, to ensure | ||
296 | * that we get it right vs. lockdep if it happens, we force | ||
297 | * that hard enable here with appropriate tracing if we see | ||
298 | * that we have been called with interrupts off | ||
299 | */ | ||
300 | mfmsr r11 | ||
301 | andi. r12,r11,MSR_EE | ||
302 | bne+ 1f | ||
303 | /* We came in with interrupts disabled, we enable them now */ | ||
304 | bl trace_hardirqs_on | ||
305 | mfmsr r11 | ||
306 | lwz r0,GPR0(r1) | ||
307 | lwz r3,GPR3(r1) | ||
308 | lwz r4,GPR4(r1) | ||
309 | ori r11,r11,MSR_EE | ||
310 | lwz r5,GPR5(r1) | ||
311 | lwz r6,GPR6(r1) | ||
312 | lwz r7,GPR7(r1) | ||
313 | lwz r8,GPR8(r1) | ||
314 | mtmsr r11 | ||
315 | 1: | ||
316 | #endif /* CONFIG_TRACE_IRQFLAGS */ | ||
254 | rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ | 317 | rlwinm r10,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ |
255 | lwz r11,TI_FLAGS(r10) | 318 | lwz r11,TI_FLAGS(r10) |
256 | andi. r11,r11,_TIF_SYSCALL_T_OR_A | 319 | andi. r11,r11,_TIF_SYSCALL_T_OR_A |
@@ -275,6 +338,7 @@ ret_from_syscall: | |||
275 | rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ | 338 | rlwinm r12,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */ |
276 | /* disable interrupts so current_thread_info()->flags can't change */ | 339 | /* disable interrupts so current_thread_info()->flags can't change */ |
277 | LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ | 340 | LOAD_MSR_KERNEL(r10,MSR_KERNEL) /* doesn't include MSR_EE */ |
341 | /* Note: We don't bother telling lockdep about it */ | ||
278 | SYNC | 342 | SYNC |
279 | MTMSRD(r10) | 343 | MTMSRD(r10) |
280 | lwz r9,TI_FLAGS(r12) | 344 | lwz r9,TI_FLAGS(r12) |
@@ -288,6 +352,19 @@ ret_from_syscall: | |||
288 | oris r11,r11,0x1000 /* Set SO bit in CR */ | 352 | oris r11,r11,0x1000 /* Set SO bit in CR */ |
289 | stw r11,_CCR(r1) | 353 | stw r11,_CCR(r1) |
290 | syscall_exit_cont: | 354 | syscall_exit_cont: |
355 | lwz r8,_MSR(r1) | ||
356 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
357 | /* If we are going to return from the syscall with interrupts | ||
358 | * off, we trace that here. It shouldn't happen though but we | ||
359 | * want to catch the bugger if it does right ? | ||
360 | */ | ||
361 | andi. r10,r8,MSR_EE | ||
362 | bne+ 1f | ||
363 | stw r3,GPR3(r1) | ||
364 | bl trace_hardirqs_off | ||
365 | lwz r3,GPR3(r1) | ||
366 | 1: | ||
367 | #endif /* CONFIG_TRACE_IRQFLAGS */ | ||
291 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | 368 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) |
292 | /* If the process has its own DBCR0 value, load it up. The internal | 369 | /* If the process has its own DBCR0 value, load it up. The internal |
293 | debug mode bit tells us that dbcr0 should be loaded. */ | 370 | debug mode bit tells us that dbcr0 should be loaded. */ |
@@ -311,7 +388,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) | |||
311 | mtlr r4 | 388 | mtlr r4 |
312 | mtcr r5 | 389 | mtcr r5 |
313 | lwz r7,_NIP(r1) | 390 | lwz r7,_NIP(r1) |
314 | lwz r8,_MSR(r1) | ||
315 | FIX_SRR1(r8, r0) | 391 | FIX_SRR1(r8, r0) |
316 | lwz r2,GPR2(r1) | 392 | lwz r2,GPR2(r1) |
317 | lwz r1,GPR1(r1) | 393 | lwz r1,GPR1(r1) |
@@ -394,7 +470,9 @@ syscall_exit_work: | |||
394 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) | 470 | andi. r0,r9,(_TIF_SYSCALL_T_OR_A|_TIF_SINGLESTEP) |
395 | beq ret_from_except | 471 | beq ret_from_except |
396 | 472 | ||
397 | /* Re-enable interrupts */ | 473 | /* Re-enable interrupts. There is no need to trace that with |
474 | * lockdep as we are supposed to have IRQs on at this point | ||
475 | */ | ||
398 | ori r10,r10,MSR_EE | 476 | ori r10,r10,MSR_EE |
399 | SYNC | 477 | SYNC |
400 | MTMSRD(r10) | 478 | MTMSRD(r10) |
@@ -705,6 +783,7 @@ ret_from_except: | |||
705 | /* Hard-disable interrupts so that current_thread_info()->flags | 783 | /* Hard-disable interrupts so that current_thread_info()->flags |
706 | * can't change between when we test it and when we return | 784 | * can't change between when we test it and when we return |
707 | * from the interrupt. */ | 785 | * from the interrupt. */ |
786 | /* Note: We don't bother telling lockdep about it */ | ||
708 | LOAD_MSR_KERNEL(r10,MSR_KERNEL) | 787 | LOAD_MSR_KERNEL(r10,MSR_KERNEL) |
709 | SYNC /* Some chip revs have problems here... */ | 788 | SYNC /* Some chip revs have problems here... */ |
710 | MTMSRD(r10) /* disable interrupts */ | 789 | MTMSRD(r10) /* disable interrupts */ |
@@ -744,11 +823,24 @@ resume_kernel: | |||
744 | beq+ restore | 823 | beq+ restore |
745 | andi. r0,r3,MSR_EE /* interrupts off? */ | 824 | andi. r0,r3,MSR_EE /* interrupts off? */ |
746 | beq restore /* don't schedule if so */ | 825 | beq restore /* don't schedule if so */ |
826 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
827 | /* Lockdep thinks irqs are enabled, we need to call | ||
828 | * preempt_schedule_irq with IRQs off, so we inform lockdep | ||
829 | * now that we -did- turn them off already | ||
830 | */ | ||
831 | bl trace_hardirqs_off | ||
832 | #endif | ||
747 | 1: bl preempt_schedule_irq | 833 | 1: bl preempt_schedule_irq |
748 | rlwinm r9,r1,0,0,(31-THREAD_SHIFT) | 834 | rlwinm r9,r1,0,0,(31-THREAD_SHIFT) |
749 | lwz r3,TI_FLAGS(r9) | 835 | lwz r3,TI_FLAGS(r9) |
750 | andi. r0,r3,_TIF_NEED_RESCHED | 836 | andi. r0,r3,_TIF_NEED_RESCHED |
751 | bne- 1b | 837 | bne- 1b |
838 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
839 | /* And now, to properly rebalance the above, we tell lockdep they | ||
840 | * are being turned back on, which will happen when we return | ||
841 | */ | ||
842 | bl trace_hardirqs_on | ||
843 | #endif | ||
752 | #else | 844 | #else |
753 | resume_kernel: | 845 | resume_kernel: |
754 | #endif /* CONFIG_PREEMPT */ | 846 | #endif /* CONFIG_PREEMPT */ |
@@ -765,6 +857,28 @@ restore: | |||
765 | stw r6,icache_44x_need_flush@l(r4) | 857 | stw r6,icache_44x_need_flush@l(r4) |
766 | 1: | 858 | 1: |
767 | #endif /* CONFIG_44x */ | 859 | #endif /* CONFIG_44x */ |
860 | |||
861 | lwz r9,_MSR(r1) | ||
862 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
863 | /* Lockdep doesn't know about the fact that IRQs are temporarily turned | ||
864 | * off in this assembly code while peeking at TI_FLAGS() and such. However | ||
865 | * we need to inform it if the exception turned interrupts off, and we | ||
866 | * are about to trun them back on. | ||
867 | * | ||
868 | * The problem here sadly is that we don't know whether the exceptions was | ||
869 | * one that turned interrupts off or not. So we always tell lockdep about | ||
870 | * turning them on here when we go back to wherever we came from with EE | ||
871 | * on, even if that may meen some redudant calls being tracked. Maybe later | ||
872 | * we could encode what the exception did somewhere or test the exception | ||
873 | * type in the pt_regs but that sounds overkill | ||
874 | */ | ||
875 | andi. r10,r9,MSR_EE | ||
876 | beq 1f | ||
877 | bl trace_hardirqs_on | ||
878 | lwz r9,_MSR(r1) | ||
879 | 1: | ||
880 | #endif /* CONFIG_TRACE_IRQFLAGS */ | ||
881 | |||
768 | lwz r0,GPR0(r1) | 882 | lwz r0,GPR0(r1) |
769 | lwz r2,GPR2(r1) | 883 | lwz r2,GPR2(r1) |
770 | REST_4GPRS(3, r1) | 884 | REST_4GPRS(3, r1) |
@@ -782,7 +896,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) | |||
782 | stwcx. r0,0,r1 /* to clear the reservation */ | 896 | stwcx. r0,0,r1 /* to clear the reservation */ |
783 | 897 | ||
784 | #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) | 898 | #if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE)) |
785 | lwz r9,_MSR(r1) | ||
786 | andi. r10,r9,MSR_RI /* check if this exception occurred */ | 899 | andi. r10,r9,MSR_RI /* check if this exception occurred */ |
787 | beql nonrecoverable /* at a bad place (MSR:RI = 0) */ | 900 | beql nonrecoverable /* at a bad place (MSR:RI = 0) */ |
788 | 901 | ||
@@ -805,7 +918,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) | |||
805 | MTMSRD(r10) /* clear the RI bit */ | 918 | MTMSRD(r10) /* clear the RI bit */ |
806 | .globl exc_exit_restart | 919 | .globl exc_exit_restart |
807 | exc_exit_restart: | 920 | exc_exit_restart: |
808 | lwz r9,_MSR(r1) | ||
809 | lwz r12,_NIP(r1) | 921 | lwz r12,_NIP(r1) |
810 | FIX_SRR1(r9,r10) | 922 | FIX_SRR1(r9,r10) |
811 | mtspr SPRN_SRR0,r12 | 923 | mtspr SPRN_SRR0,r12 |
@@ -1035,11 +1147,18 @@ do_work: /* r10 contains MSR_KERNEL here */ | |||
1035 | beq do_user_signal | 1147 | beq do_user_signal |
1036 | 1148 | ||
1037 | do_resched: /* r10 contains MSR_KERNEL here */ | 1149 | do_resched: /* r10 contains MSR_KERNEL here */ |
1150 | /* Note: We don't need to inform lockdep that we are enabling | ||
1151 | * interrupts here. As far as it knows, they are already enabled | ||
1152 | */ | ||
1038 | ori r10,r10,MSR_EE | 1153 | ori r10,r10,MSR_EE |
1039 | SYNC | 1154 | SYNC |
1040 | MTMSRD(r10) /* hard-enable interrupts */ | 1155 | MTMSRD(r10) /* hard-enable interrupts */ |
1041 | bl schedule | 1156 | bl schedule |
1042 | recheck: | 1157 | recheck: |
1158 | /* Note: And we don't tell it we are disabling them again | ||
1159 | * neither. Those disable/enable cycles used to peek at | ||
1160 | * TI_FLAGS aren't advertised. | ||
1161 | */ | ||
1043 | LOAD_MSR_KERNEL(r10,MSR_KERNEL) | 1162 | LOAD_MSR_KERNEL(r10,MSR_KERNEL) |
1044 | SYNC | 1163 | SYNC |
1045 | MTMSRD(r10) /* disable interrupts */ | 1164 | MTMSRD(r10) /* disable interrupts */ |
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index 48469463f89e..fc2132942754 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S | |||
@@ -1124,9 +1124,8 @@ mmu_off: | |||
1124 | RFI | 1124 | RFI |
1125 | 1125 | ||
1126 | /* | 1126 | /* |
1127 | * Use the first pair of BAT registers to map the 1st 16MB | 1127 | * On 601, we use 3 BATs to map up to 24M of RAM at _PAGE_OFFSET |
1128 | * of RAM to PAGE_OFFSET. From this point on we can't safely | 1128 | * (we keep one for debugging) and on others, we use one 256M BAT. |
1129 | * call OF any more. | ||
1130 | */ | 1129 | */ |
1131 | initial_bats: | 1130 | initial_bats: |
1132 | lis r11,PAGE_OFFSET@h | 1131 | lis r11,PAGE_OFFSET@h |
@@ -1136,12 +1135,16 @@ initial_bats: | |||
1136 | bne 4f | 1135 | bne 4f |
1137 | ori r11,r11,4 /* set up BAT registers for 601 */ | 1136 | ori r11,r11,4 /* set up BAT registers for 601 */ |
1138 | li r8,0x7f /* valid, block length = 8MB */ | 1137 | li r8,0x7f /* valid, block length = 8MB */ |
1139 | oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */ | ||
1140 | oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */ | ||
1141 | mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */ | 1138 | mtspr SPRN_IBAT0U,r11 /* N.B. 601 has valid bit in */ |
1142 | mtspr SPRN_IBAT0L,r8 /* lower BAT register */ | 1139 | mtspr SPRN_IBAT0L,r8 /* lower BAT register */ |
1143 | mtspr SPRN_IBAT1U,r9 | 1140 | addis r11,r11,0x800000@h |
1144 | mtspr SPRN_IBAT1L,r10 | 1141 | addis r8,r8,0x800000@h |
1142 | mtspr SPRN_IBAT1U,r11 | ||
1143 | mtspr SPRN_IBAT1L,r8 | ||
1144 | addis r11,r11,0x800000@h | ||
1145 | addis r8,r8,0x800000@h | ||
1146 | mtspr SPRN_IBAT2U,r11 | ||
1147 | mtspr SPRN_IBAT2L,r8 | ||
1145 | isync | 1148 | isync |
1146 | blr | 1149 | blr |
1147 | 1150 | ||
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c index fa983a59c4ce..a359cb08e900 100644 --- a/arch/powerpc/kernel/of_device.c +++ b/arch/powerpc/kernel/of_device.c | |||
@@ -76,7 +76,7 @@ struct of_device *of_device_alloc(struct device_node *np, | |||
76 | dev->dev.archdata.of_node = np; | 76 | dev->dev.archdata.of_node = np; |
77 | 77 | ||
78 | if (bus_id) | 78 | if (bus_id) |
79 | dev_set_name(&dev->dev, bus_id); | 79 | dev_set_name(&dev->dev, "%s", bus_id); |
80 | else | 80 | else |
81 | of_device_make_bus_id(dev); | 81 | of_device_make_bus_id(dev); |
82 | 82 | ||
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 3e7135bbe40f..892a9f2e6d76 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c | |||
@@ -528,7 +528,7 @@ void show_regs(struct pt_regs * regs) | |||
528 | 528 | ||
529 | for (i = 0; i < 32; i++) { | 529 | for (i = 0; i < 32; i++) { |
530 | if ((i % REGS_PER_LINE) == 0) | 530 | if ((i % REGS_PER_LINE) == 0) |
531 | printk("\n" KERN_INFO "GPR%02d: ", i); | 531 | printk("\nGPR%02d: ", i); |
532 | printk(REG " ", regs->gpr[i]); | 532 | printk(REG " ", regs->gpr[i]); |
533 | if (i == LAST_VOLATILE && !FULL_REGS(regs)) | 533 | if (i == LAST_VOLATILE && !FULL_REGS(regs)) |
534 | break; | 534 | break; |
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index ee4c7609b649..c434823b8c83 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c | |||
@@ -38,9 +38,10 @@ | |||
38 | #include <asm/syscalls.h> | 38 | #include <asm/syscalls.h> |
39 | #include <asm/smp.h> | 39 | #include <asm/smp.h> |
40 | #include <asm/atomic.h> | 40 | #include <asm/atomic.h> |
41 | #include <asm/time.h> | ||
41 | 42 | ||
42 | struct rtas_t rtas = { | 43 | struct rtas_t rtas = { |
43 | .lock = SPIN_LOCK_UNLOCKED | 44 | .lock = __RAW_SPIN_LOCK_UNLOCKED |
44 | }; | 45 | }; |
45 | EXPORT_SYMBOL(rtas); | 46 | EXPORT_SYMBOL(rtas); |
46 | 47 | ||
@@ -67,6 +68,28 @@ unsigned long rtas_rmo_buf; | |||
67 | void (*rtas_flash_term_hook)(int); | 68 | void (*rtas_flash_term_hook)(int); |
68 | EXPORT_SYMBOL(rtas_flash_term_hook); | 69 | EXPORT_SYMBOL(rtas_flash_term_hook); |
69 | 70 | ||
71 | /* RTAS use home made raw locking instead of spin_lock_irqsave | ||
72 | * because those can be called from within really nasty contexts | ||
73 | * such as having the timebase stopped which would lockup with | ||
74 | * normal locks and spinlock debugging enabled | ||
75 | */ | ||
76 | static unsigned long lock_rtas(void) | ||
77 | { | ||
78 | unsigned long flags; | ||
79 | |||
80 | local_irq_save(flags); | ||
81 | preempt_disable(); | ||
82 | __raw_spin_lock_flags(&rtas.lock, flags); | ||
83 | return flags; | ||
84 | } | ||
85 | |||
86 | static void unlock_rtas(unsigned long flags) | ||
87 | { | ||
88 | __raw_spin_unlock(&rtas.lock); | ||
89 | local_irq_restore(flags); | ||
90 | preempt_enable(); | ||
91 | } | ||
92 | |||
70 | /* | 93 | /* |
71 | * call_rtas_display_status and call_rtas_display_status_delay | 94 | * call_rtas_display_status and call_rtas_display_status_delay |
72 | * are designed only for very early low-level debugging, which | 95 | * are designed only for very early low-level debugging, which |
@@ -79,7 +102,7 @@ static void call_rtas_display_status(char c) | |||
79 | 102 | ||
80 | if (!rtas.base) | 103 | if (!rtas.base) |
81 | return; | 104 | return; |
82 | spin_lock_irqsave(&rtas.lock, s); | 105 | s = lock_rtas(); |
83 | 106 | ||
84 | args->token = 10; | 107 | args->token = 10; |
85 | args->nargs = 1; | 108 | args->nargs = 1; |
@@ -89,7 +112,7 @@ static void call_rtas_display_status(char c) | |||
89 | 112 | ||
90 | enter_rtas(__pa(args)); | 113 | enter_rtas(__pa(args)); |
91 | 114 | ||
92 | spin_unlock_irqrestore(&rtas.lock, s); | 115 | unlock_rtas(s); |
93 | } | 116 | } |
94 | 117 | ||
95 | static void call_rtas_display_status_delay(char c) | 118 | static void call_rtas_display_status_delay(char c) |
@@ -411,8 +434,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) | |||
411 | if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) | 434 | if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) |
412 | return -1; | 435 | return -1; |
413 | 436 | ||
414 | /* Gotta do something different here, use global lock for now... */ | 437 | s = lock_rtas(); |
415 | spin_lock_irqsave(&rtas.lock, s); | ||
416 | rtas_args = &rtas.args; | 438 | rtas_args = &rtas.args; |
417 | 439 | ||
418 | rtas_args->token = token; | 440 | rtas_args->token = token; |
@@ -439,8 +461,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) | |||
439 | outputs[i] = rtas_args->rets[i+1]; | 461 | outputs[i] = rtas_args->rets[i+1]; |
440 | ret = (nret > 0)? rtas_args->rets[0]: 0; | 462 | ret = (nret > 0)? rtas_args->rets[0]: 0; |
441 | 463 | ||
442 | /* Gotta do something different here, use global lock for now... */ | 464 | unlock_rtas(s); |
443 | spin_unlock_irqrestore(&rtas.lock, s); | ||
444 | 465 | ||
445 | if (buff_copy) { | 466 | if (buff_copy) { |
446 | log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0); | 467 | log_error(buff_copy, ERR_TYPE_RTAS_LOG, 0); |
@@ -837,7 +858,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) | |||
837 | 858 | ||
838 | buff_copy = get_errorlog_buffer(); | 859 | buff_copy = get_errorlog_buffer(); |
839 | 860 | ||
840 | spin_lock_irqsave(&rtas.lock, flags); | 861 | flags = lock_rtas(); |
841 | 862 | ||
842 | rtas.args = args; | 863 | rtas.args = args; |
843 | enter_rtas(__pa(&rtas.args)); | 864 | enter_rtas(__pa(&rtas.args)); |
@@ -848,7 +869,7 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs) | |||
848 | if (args.rets[0] == -1) | 869 | if (args.rets[0] == -1) |
849 | errbuf = __fetch_rtas_last_error(buff_copy); | 870 | errbuf = __fetch_rtas_last_error(buff_copy); |
850 | 871 | ||
851 | spin_unlock_irqrestore(&rtas.lock, flags); | 872 | unlock_rtas(flags); |
852 | 873 | ||
853 | if (buff_copy) { | 874 | if (buff_copy) { |
854 | if (errbuf) | 875 | if (errbuf) |
@@ -951,3 +972,33 @@ int __init early_init_dt_scan_rtas(unsigned long node, | |||
951 | /* break now */ | 972 | /* break now */ |
952 | return 1; | 973 | return 1; |
953 | } | 974 | } |
975 | |||
976 | static raw_spinlock_t timebase_lock; | ||
977 | static u64 timebase = 0; | ||
978 | |||
979 | void __cpuinit rtas_give_timebase(void) | ||
980 | { | ||
981 | unsigned long flags; | ||
982 | |||
983 | local_irq_save(flags); | ||
984 | hard_irq_disable(); | ||
985 | __raw_spin_lock(&timebase_lock); | ||
986 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
987 | timebase = get_tb(); | ||
988 | __raw_spin_unlock(&timebase_lock); | ||
989 | |||
990 | while (timebase) | ||
991 | barrier(); | ||
992 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
993 | local_irq_restore(flags); | ||
994 | } | ||
995 | |||
996 | void __cpuinit rtas_take_timebase(void) | ||
997 | { | ||
998 | while (!timebase) | ||
999 | barrier(); | ||
1000 | __raw_spin_lock(&timebase_lock); | ||
1001 | set_tb(timebase >> 32, timebase & 0xffffffff); | ||
1002 | timebase = 0; | ||
1003 | __raw_spin_unlock(&timebase_lock); | ||
1004 | } | ||
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 1d154248cf40..e1e3059cf34b 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c | |||
@@ -119,6 +119,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr) | |||
119 | */ | 119 | */ |
120 | notrace void __init machine_init(unsigned long dt_ptr) | 120 | notrace void __init machine_init(unsigned long dt_ptr) |
121 | { | 121 | { |
122 | lockdep_init(); | ||
123 | |||
122 | /* Enable early debugging if any specified (see udbg.h) */ | 124 | /* Enable early debugging if any specified (see udbg.h) */ |
123 | udbg_early_init(); | 125 | udbg_early_init(); |
124 | 126 | ||
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 65484b2200b3..0b47de07302d 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c | |||
@@ -68,7 +68,8 @@ EXPORT_PER_CPU_SYMBOL(cpu_core_map); | |||
68 | /* SMP operations for this machine */ | 68 | /* SMP operations for this machine */ |
69 | struct smp_ops_t *smp_ops; | 69 | struct smp_ops_t *smp_ops; |
70 | 70 | ||
71 | static volatile unsigned int cpu_callin_map[NR_CPUS]; | 71 | /* Can't be static due to PowerMac hackery */ |
72 | volatile unsigned int cpu_callin_map[NR_CPUS]; | ||
72 | 73 | ||
73 | int smt_enabled_at_boot = 1; | 74 | int smt_enabled_at_boot = 1; |
74 | 75 | ||
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index 0362a891e54e..acb74a17bbbf 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c | |||
@@ -219,7 +219,7 @@ void udbg_init_pas_realmode(void) | |||
219 | #ifdef CONFIG_PPC_EARLY_DEBUG_44x | 219 | #ifdef CONFIG_PPC_EARLY_DEBUG_44x |
220 | #include <platforms/44x/44x.h> | 220 | #include <platforms/44x/44x.h> |
221 | 221 | ||
222 | static int udbg_44x_as1_flush(void) | 222 | static void udbg_44x_as1_flush(void) |
223 | { | 223 | { |
224 | if (udbg_comport) { | 224 | if (udbg_comport) { |
225 | while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) | 225 | while ((as1_readb(&udbg_comport->lsr) & LSR_THRE) == 0) |
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile index 2d2192e48de7..3e68363405b7 100644 --- a/arch/powerpc/mm/Makefile +++ b/arch/powerpc/mm/Makefile | |||
@@ -30,3 +30,4 @@ obj-$(CONFIG_PPC_MM_SLICES) += slice.o | |||
30 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 30 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
31 | obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o | 31 | obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o |
32 | obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o | 32 | obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o |
33 | obj-$(CONFIG_HIGHMEM) += highmem.o | ||
diff --git a/arch/powerpc/mm/highmem.c b/arch/powerpc/mm/highmem.c new file mode 100644 index 000000000000..c2186c74c85a --- /dev/null +++ b/arch/powerpc/mm/highmem.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * highmem.c: virtual kernel memory mappings for high memory | ||
3 | * | ||
4 | * PowerPC version, stolen from the i386 version. | ||
5 | * | ||
6 | * Used in CONFIG_HIGHMEM systems for memory pages which | ||
7 | * are not addressable by direct kernel virtual addresses. | ||
8 | * | ||
9 | * Copyright (C) 1999 Gerhard Wichert, Siemens AG | ||
10 | * Gerhard.Wichert@pdb.siemens.de | ||
11 | * | ||
12 | * | ||
13 | * Redesigned the x86 32-bit VM architecture to deal with | ||
14 | * up to 16 Terrabyte physical memory. With current x86 CPUs | ||
15 | * we now support up to 64 Gigabytes physical RAM. | ||
16 | * | ||
17 | * Copyright (C) 1999 Ingo Molnar <mingo@redhat.com> | ||
18 | * | ||
19 | * Reworked for PowerPC by various contributors. Moved from | ||
20 | * highmem.h by Benjamin Herrenschmidt (c) 2009 IBM Corp. | ||
21 | */ | ||
22 | |||
23 | #include <linux/highmem.h> | ||
24 | #include <linux/module.h> | ||
25 | |||
26 | /* | ||
27 | * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap | ||
28 | * gives a more generic (and caching) interface. But kmap_atomic can | ||
29 | * be used in IRQ contexts, so in some (very limited) cases we need | ||
30 | * it. | ||
31 | */ | ||
32 | void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot) | ||
33 | { | ||
34 | unsigned int idx; | ||
35 | unsigned long vaddr; | ||
36 | |||
37 | /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ | ||
38 | pagefault_disable(); | ||
39 | if (!PageHighMem(page)) | ||
40 | return page_address(page); | ||
41 | |||
42 | debug_kmap_atomic(type); | ||
43 | idx = type + KM_TYPE_NR*smp_processor_id(); | ||
44 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
45 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
46 | BUG_ON(!pte_none(*(kmap_pte-idx))); | ||
47 | #endif | ||
48 | __set_pte_at(&init_mm, vaddr, kmap_pte-idx, mk_pte(page, prot), 1); | ||
49 | local_flush_tlb_page(NULL, vaddr); | ||
50 | |||
51 | return (void*) vaddr; | ||
52 | } | ||
53 | EXPORT_SYMBOL(kmap_atomic_prot); | ||
54 | |||
55 | void kunmap_atomic(void *kvaddr, enum km_type type) | ||
56 | { | ||
57 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
58 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | ||
59 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | ||
60 | |||
61 | if (vaddr < __fix_to_virt(FIX_KMAP_END)) { | ||
62 | pagefault_enable(); | ||
63 | return; | ||
64 | } | ||
65 | |||
66 | BUG_ON(vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx)); | ||
67 | |||
68 | /* | ||
69 | * force other mappings to Oops if they'll try to access | ||
70 | * this pte without first remap it | ||
71 | */ | ||
72 | pte_clear(&init_mm, vaddr, kmap_pte-idx); | ||
73 | local_flush_tlb_page(NULL, vaddr); | ||
74 | #endif | ||
75 | pagefault_enable(); | ||
76 | } | ||
77 | EXPORT_SYMBOL(kunmap_atomic); | ||
diff --git a/arch/powerpc/platforms/44x/warp.c b/arch/powerpc/platforms/44x/warp.c index 42e09a9f77e2..0362c88f47d7 100644 --- a/arch/powerpc/platforms/44x/warp.c +++ b/arch/powerpc/platforms/44x/warp.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/of_gpio.h> | 18 | #include <linux/of_gpio.h> |
19 | #include <linux/of_i2c.h> | ||
19 | 20 | ||
20 | #include <asm/machdep.h> | 21 | #include <asm/machdep.h> |
21 | #include <asm/prom.h> | 22 | #include <asm/prom.h> |
@@ -65,7 +66,6 @@ define_machine(warp) { | |||
65 | 66 | ||
66 | static u32 post_info; | 67 | static u32 post_info; |
67 | 68 | ||
68 | /* I am not sure this is the best place for this... */ | ||
69 | static int __init warp_post_info(void) | 69 | static int __init warp_post_info(void) |
70 | { | 70 | { |
71 | struct device_node *np; | 71 | struct device_node *np; |
@@ -194,9 +194,9 @@ static int pika_setup_leds(void) | |||
194 | return 0; | 194 | return 0; |
195 | } | 195 | } |
196 | 196 | ||
197 | static void pika_setup_critical_temp(struct i2c_client *client) | 197 | static void pika_setup_critical_temp(struct device_node *np, |
198 | struct i2c_client *client) | ||
198 | { | 199 | { |
199 | struct device_node *np; | ||
200 | int irq, rc; | 200 | int irq, rc; |
201 | 201 | ||
202 | /* Do this before enabling critical temp interrupt since we | 202 | /* Do this before enabling critical temp interrupt since we |
@@ -208,14 +208,7 @@ static void pika_setup_critical_temp(struct i2c_client *client) | |||
208 | i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */ | 208 | i2c_smbus_write_byte_data(client, 2, 65); /* Thigh */ |
209 | i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */ | 209 | i2c_smbus_write_byte_data(client, 3, 0); /* Tlow */ |
210 | 210 | ||
211 | np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); | ||
212 | if (np == NULL) { | ||
213 | printk(KERN_ERR __FILE__ ": Unable to find ad7414\n"); | ||
214 | return; | ||
215 | } | ||
216 | |||
217 | irq = irq_of_parse_and_map(np, 0); | 211 | irq = irq_of_parse_and_map(np, 0); |
218 | of_node_put(np); | ||
219 | if (irq == NO_IRQ) { | 212 | if (irq == NO_IRQ) { |
220 | printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n"); | 213 | printk(KERN_ERR __FILE__ ": Unable to get ad7414 irq\n"); |
221 | return; | 214 | return; |
@@ -244,32 +237,24 @@ static inline void pika_dtm_check_fan(void __iomem *fpga) | |||
244 | 237 | ||
245 | static int pika_dtm_thread(void __iomem *fpga) | 238 | static int pika_dtm_thread(void __iomem *fpga) |
246 | { | 239 | { |
247 | struct i2c_adapter *adap; | 240 | struct device_node *np; |
248 | struct i2c_client *client; | 241 | struct i2c_client *client; |
249 | 242 | ||
250 | /* We loop in case either driver was compiled as a module and | 243 | np = of_find_compatible_node(NULL, NULL, "adi,ad7414"); |
251 | * has not been insmoded yet. | 244 | if (np == NULL) |
252 | */ | 245 | return -ENOENT; |
253 | while (!(adap = i2c_get_adapter(0))) { | ||
254 | set_current_state(TASK_INTERRUPTIBLE); | ||
255 | schedule_timeout(HZ); | ||
256 | } | ||
257 | |||
258 | while (1) { | ||
259 | list_for_each_entry(client, &adap->clients, list) | ||
260 | if (client->addr == 0x4a) | ||
261 | goto found_it; | ||
262 | 246 | ||
263 | set_current_state(TASK_INTERRUPTIBLE); | 247 | client = of_find_i2c_device_by_node(np); |
264 | schedule_timeout(HZ); | 248 | if (client == NULL) { |
249 | of_node_put(np); | ||
250 | return -ENOENT; | ||
265 | } | 251 | } |
266 | 252 | ||
267 | found_it: | 253 | pika_setup_critical_temp(np, client); |
268 | pika_setup_critical_temp(client); | ||
269 | 254 | ||
270 | i2c_put_adapter(adap); | 255 | of_node_put(np); |
271 | 256 | ||
272 | printk(KERN_INFO "PIKA DTM thread running.\n"); | 257 | printk(KERN_INFO "Warp DTM thread running.\n"); |
273 | 258 | ||
274 | while (!kthread_should_stop()) { | 259 | while (!kthread_should_stop()) { |
275 | int val; | 260 | int val; |
@@ -291,7 +276,6 @@ found_it: | |||
291 | return 0; | 276 | return 0; |
292 | } | 277 | } |
293 | 278 | ||
294 | |||
295 | static int __init pika_dtm_start(void) | 279 | static int __init pika_dtm_start(void) |
296 | { | 280 | { |
297 | struct task_struct *dtm_thread; | 281 | struct task_struct *dtm_thread; |
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 77f90b356356..60ed9c067b1d 100644 --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c | |||
@@ -285,6 +285,7 @@ static struct of_device_id mpc85xx_ids[] = { | |||
285 | { .type = "qe", }, | 285 | { .type = "qe", }, |
286 | { .compatible = "fsl,qe", }, | 286 | { .compatible = "fsl,qe", }, |
287 | { .compatible = "gianfar", }, | 287 | { .compatible = "gianfar", }, |
288 | { .compatible = "fsl,rapidio-delta", }, | ||
288 | {}, | 289 | {}, |
289 | }; | 290 | }; |
290 | 291 | ||
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c index cc0b0db8a6f3..62c592ede641 100644 --- a/arch/powerpc/platforms/85xx/smp.c +++ b/arch/powerpc/platforms/85xx/smp.c | |||
@@ -52,20 +52,19 @@ smp_85xx_kick_cpu(int nr) | |||
52 | 52 | ||
53 | pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); | 53 | pr_debug("smp_85xx_kick_cpu: kick CPU #%d\n", nr); |
54 | 54 | ||
55 | local_irq_save(flags); | ||
56 | |||
57 | np = of_get_cpu_node(nr, NULL); | 55 | np = of_get_cpu_node(nr, NULL); |
58 | cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); | 56 | cpu_rel_addr = of_get_property(np, "cpu-release-addr", NULL); |
59 | 57 | ||
60 | if (cpu_rel_addr == NULL) { | 58 | if (cpu_rel_addr == NULL) { |
61 | printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr); | 59 | printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr); |
62 | local_irq_restore(flags); | ||
63 | return; | 60 | return; |
64 | } | 61 | } |
65 | 62 | ||
66 | /* Map the spin table */ | 63 | /* Map the spin table */ |
67 | bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); | 64 | bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); |
68 | 65 | ||
66 | local_irq_save(flags); | ||
67 | |||
69 | out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); | 68 | out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); |
70 | out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); | 69 | out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); |
71 | 70 | ||
@@ -73,10 +72,10 @@ smp_85xx_kick_cpu(int nr) | |||
73 | while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) | 72 | while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) |
74 | mdelay(1); | 73 | mdelay(1); |
75 | 74 | ||
76 | iounmap(bptr_vaddr); | ||
77 | |||
78 | local_irq_restore(flags); | 75 | local_irq_restore(flags); |
79 | 76 | ||
77 | iounmap(bptr_vaddr); | ||
78 | |||
80 | pr_debug("waited %d msecs for CPU #%d.\n", n, nr); | 79 | pr_debug("waited %d msecs for CPU #%d.\n", n, nr); |
81 | } | 80 | } |
82 | 81 | ||
diff --git a/arch/powerpc/platforms/85xx/socrates.c b/arch/powerpc/platforms/85xx/socrates.c index d0e8443b12c6..747d8fb3ab82 100644 --- a/arch/powerpc/platforms/85xx/socrates.c +++ b/arch/powerpc/platforms/85xx/socrates.c | |||
@@ -102,10 +102,11 @@ static struct of_device_id __initdata socrates_of_bus_ids[] = { | |||
102 | {}, | 102 | {}, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static void __init socrates_init(void) | 105 | static int __init socrates_publish_devices(void) |
106 | { | 106 | { |
107 | of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); | 107 | return of_platform_bus_probe(NULL, socrates_of_bus_ids, NULL); |
108 | } | 108 | } |
109 | machine_device_initcall(socrates, socrates_publish_devices); | ||
109 | 110 | ||
110 | /* | 111 | /* |
111 | * Called very early, device-tree isn't unflattened | 112 | * Called very early, device-tree isn't unflattened |
@@ -124,7 +125,6 @@ define_machine(socrates) { | |||
124 | .name = "Socrates", | 125 | .name = "Socrates", |
125 | .probe = socrates_probe, | 126 | .probe = socrates_probe, |
126 | .setup_arch = socrates_setup_arch, | 127 | .setup_arch = socrates_setup_arch, |
127 | .init = socrates_init, | ||
128 | .init_IRQ = socrates_pic_init, | 128 | .init_IRQ = socrates_pic_init, |
129 | .get_irq = mpic_get_irq, | 129 | .get_irq = mpic_get_irq, |
130 | .restart = fsl_rstcr_restart, | 130 | .restart = fsl_rstcr_restart, |
diff --git a/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/arch/powerpc/platforms/85xx/xes_mpc85xx.c index ee01532786e4..1b426050a2f9 100644 --- a/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/arch/powerpc/platforms/85xx/xes_mpc85xx.c | |||
@@ -32,7 +32,6 @@ | |||
32 | 32 | ||
33 | #include <sysdev/fsl_soc.h> | 33 | #include <sysdev/fsl_soc.h> |
34 | #include <sysdev/fsl_pci.h> | 34 | #include <sysdev/fsl_pci.h> |
35 | #include <linux/of_platform.h> | ||
36 | 35 | ||
37 | /* A few bit definitions needed for fixups on some boards */ | 36 | /* A few bit definitions needed for fixups on some boards */ |
38 | #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ | 37 | #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ |
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c index 9046803c8276..bc97fada48c6 100644 --- a/arch/powerpc/platforms/cell/smp.c +++ b/arch/powerpc/platforms/cell/smp.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <asm/prom.h> | 36 | #include <asm/prom.h> |
37 | #include <asm/smp.h> | 37 | #include <asm/smp.h> |
38 | #include <asm/paca.h> | 38 | #include <asm/paca.h> |
39 | #include <asm/time.h> | ||
40 | #include <asm/machdep.h> | 39 | #include <asm/machdep.h> |
41 | #include <asm/cputable.h> | 40 | #include <asm/cputable.h> |
42 | #include <asm/firmware.h> | 41 | #include <asm/firmware.h> |
@@ -140,31 +139,6 @@ static void __devinit smp_cell_setup_cpu(int cpu) | |||
140 | mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); | 139 | mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER); |
141 | } | 140 | } |
142 | 141 | ||
143 | static DEFINE_SPINLOCK(timebase_lock); | ||
144 | static unsigned long timebase = 0; | ||
145 | |||
146 | static void __devinit cell_give_timebase(void) | ||
147 | { | ||
148 | spin_lock(&timebase_lock); | ||
149 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
150 | timebase = get_tb(); | ||
151 | spin_unlock(&timebase_lock); | ||
152 | |||
153 | while (timebase) | ||
154 | barrier(); | ||
155 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
156 | } | ||
157 | |||
158 | static void __devinit cell_take_timebase(void) | ||
159 | { | ||
160 | while (!timebase) | ||
161 | barrier(); | ||
162 | spin_lock(&timebase_lock); | ||
163 | set_tb(timebase >> 32, timebase & 0xffffffff); | ||
164 | timebase = 0; | ||
165 | spin_unlock(&timebase_lock); | ||
166 | } | ||
167 | |||
168 | static void __devinit smp_cell_kick_cpu(int nr) | 142 | static void __devinit smp_cell_kick_cpu(int nr) |
169 | { | 143 | { |
170 | BUG_ON(nr < 0 || nr >= NR_CPUS); | 144 | BUG_ON(nr < 0 || nr >= NR_CPUS); |
@@ -224,8 +198,8 @@ void __init smp_init_cell(void) | |||
224 | 198 | ||
225 | /* Non-lpar has additional take/give timebase */ | 199 | /* Non-lpar has additional take/give timebase */ |
226 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { | 200 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { |
227 | smp_ops->give_timebase = cell_give_timebase; | 201 | smp_ops->give_timebase = rtas_give_timebase; |
228 | smp_ops->take_timebase = cell_take_timebase; | 202 | smp_ops->take_timebase = rtas_take_timebase; |
229 | } | 203 | } |
230 | 204 | ||
231 | DBG(" <- smp_init_cell()\n"); | 205 | DBG(" <- smp_init_cell()\n"); |
diff --git a/arch/powerpc/platforms/chrp/smp.c b/arch/powerpc/platforms/chrp/smp.c index 10a4a4d063b6..02cafecc90e3 100644 --- a/arch/powerpc/platforms/chrp/smp.c +++ b/arch/powerpc/platforms/chrp/smp.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | #include <asm/prom.h> | 27 | #include <asm/prom.h> |
28 | #include <asm/smp.h> | 28 | #include <asm/smp.h> |
29 | #include <asm/time.h> | ||
30 | #include <asm/machdep.h> | 29 | #include <asm/machdep.h> |
31 | #include <asm/mpic.h> | 30 | #include <asm/mpic.h> |
32 | #include <asm/rtas.h> | 31 | #include <asm/rtas.h> |
@@ -42,40 +41,12 @@ static void __devinit smp_chrp_setup_cpu(int cpu_nr) | |||
42 | mpic_setup_this_cpu(); | 41 | mpic_setup_this_cpu(); |
43 | } | 42 | } |
44 | 43 | ||
45 | static DEFINE_SPINLOCK(timebase_lock); | ||
46 | static unsigned int timebase_upper = 0, timebase_lower = 0; | ||
47 | |||
48 | void __devinit smp_chrp_give_timebase(void) | ||
49 | { | ||
50 | spin_lock(&timebase_lock); | ||
51 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
52 | timebase_upper = get_tbu(); | ||
53 | timebase_lower = get_tbl(); | ||
54 | spin_unlock(&timebase_lock); | ||
55 | |||
56 | while (timebase_upper || timebase_lower) | ||
57 | barrier(); | ||
58 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
59 | } | ||
60 | |||
61 | void __devinit smp_chrp_take_timebase(void) | ||
62 | { | ||
63 | while (!(timebase_upper || timebase_lower)) | ||
64 | barrier(); | ||
65 | spin_lock(&timebase_lock); | ||
66 | set_tb(timebase_upper, timebase_lower); | ||
67 | timebase_upper = 0; | ||
68 | timebase_lower = 0; | ||
69 | spin_unlock(&timebase_lock); | ||
70 | printk("CPU %i taken timebase\n", smp_processor_id()); | ||
71 | } | ||
72 | |||
73 | /* CHRP with openpic */ | 44 | /* CHRP with openpic */ |
74 | struct smp_ops_t chrp_smp_ops = { | 45 | struct smp_ops_t chrp_smp_ops = { |
75 | .message_pass = smp_mpic_message_pass, | 46 | .message_pass = smp_mpic_message_pass, |
76 | .probe = smp_mpic_probe, | 47 | .probe = smp_mpic_probe, |
77 | .kick_cpu = smp_chrp_kick_cpu, | 48 | .kick_cpu = smp_chrp_kick_cpu, |
78 | .setup_cpu = smp_chrp_setup_cpu, | 49 | .setup_cpu = smp_chrp_setup_cpu, |
79 | .give_timebase = smp_chrp_give_timebase, | 50 | .give_timebase = rtas_give_timebase, |
80 | .take_timebase = smp_chrp_take_timebase, | 51 | .take_timebase = rtas_take_timebase, |
81 | }; | 52 | }; |
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c index 153051eb6d93..a4619347aa7e 100644 --- a/arch/powerpc/platforms/pasemi/setup.c +++ b/arch/powerpc/platforms/pasemi/setup.c | |||
@@ -71,20 +71,25 @@ static void pas_restart(char *cmd) | |||
71 | } | 71 | } |
72 | 72 | ||
73 | #ifdef CONFIG_SMP | 73 | #ifdef CONFIG_SMP |
74 | static DEFINE_SPINLOCK(timebase_lock); | 74 | static raw_spinlock_t timebase_lock; |
75 | static unsigned long timebase; | 75 | static unsigned long timebase; |
76 | 76 | ||
77 | static void __devinit pas_give_timebase(void) | 77 | static void __devinit pas_give_timebase(void) |
78 | { | 78 | { |
79 | spin_lock(&timebase_lock); | 79 | unsigned long flags; |
80 | |||
81 | local_irq_save(flags); | ||
82 | hard_irq_disable(); | ||
83 | __raw_spin_lock(&timebase_lock); | ||
80 | mtspr(SPRN_TBCTL, TBCTL_FREEZE); | 84 | mtspr(SPRN_TBCTL, TBCTL_FREEZE); |
81 | isync(); | 85 | isync(); |
82 | timebase = get_tb(); | 86 | timebase = get_tb(); |
83 | spin_unlock(&timebase_lock); | 87 | __raw_spin_unlock(&timebase_lock); |
84 | 88 | ||
85 | while (timebase) | 89 | while (timebase) |
86 | barrier(); | 90 | barrier(); |
87 | mtspr(SPRN_TBCTL, TBCTL_RESTART); | 91 | mtspr(SPRN_TBCTL, TBCTL_RESTART); |
92 | local_irq_restore(flags); | ||
88 | } | 93 | } |
89 | 94 | ||
90 | static void __devinit pas_take_timebase(void) | 95 | static void __devinit pas_take_timebase(void) |
@@ -92,10 +97,10 @@ static void __devinit pas_take_timebase(void) | |||
92 | while (!timebase) | 97 | while (!timebase) |
93 | smp_rmb(); | 98 | smp_rmb(); |
94 | 99 | ||
95 | spin_lock(&timebase_lock); | 100 | __raw_spin_lock(&timebase_lock); |
96 | set_tb(timebase >> 32, timebase & 0xffffffff); | 101 | set_tb(timebase >> 32, timebase & 0xffffffff); |
97 | timebase = 0; | 102 | timebase = 0; |
98 | spin_unlock(&timebase_lock); | 103 | __raw_spin_unlock(&timebase_lock); |
99 | } | 104 | } |
100 | 105 | ||
101 | struct smp_ops_t pas_smp_ops = { | 106 | struct smp_ops_t pas_smp_ops = { |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 86f69a4eb49b..c20522656367 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -103,11 +103,6 @@ unsigned long smu_cmdbuf_abs; | |||
103 | EXPORT_SYMBOL(smu_cmdbuf_abs); | 103 | EXPORT_SYMBOL(smu_cmdbuf_abs); |
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | #ifdef CONFIG_SMP | ||
107 | extern struct smp_ops_t psurge_smp_ops; | ||
108 | extern struct smp_ops_t core99_smp_ops; | ||
109 | #endif /* CONFIG_SMP */ | ||
110 | |||
111 | static void pmac_show_cpuinfo(struct seq_file *m) | 106 | static void pmac_show_cpuinfo(struct seq_file *m) |
112 | { | 107 | { |
113 | struct device_node *np; | 108 | struct device_node *np; |
@@ -341,34 +336,6 @@ static void __init pmac_setup_arch(void) | |||
341 | ROOT_DEV = DEFAULT_ROOT_DEVICE; | 336 | ROOT_DEV = DEFAULT_ROOT_DEVICE; |
342 | #endif | 337 | #endif |
343 | 338 | ||
344 | #ifdef CONFIG_SMP | ||
345 | /* Check for Core99 */ | ||
346 | ic = of_find_node_by_name(NULL, "uni-n"); | ||
347 | if (!ic) | ||
348 | ic = of_find_node_by_name(NULL, "u3"); | ||
349 | if (!ic) | ||
350 | ic = of_find_node_by_name(NULL, "u4"); | ||
351 | if (ic) { | ||
352 | of_node_put(ic); | ||
353 | smp_ops = &core99_smp_ops; | ||
354 | } | ||
355 | #ifdef CONFIG_PPC32 | ||
356 | else { | ||
357 | /* | ||
358 | * We have to set bits in cpu_possible_map here since the | ||
359 | * secondary CPU(s) aren't in the device tree, and | ||
360 | * setup_per_cpu_areas only allocates per-cpu data for | ||
361 | * CPUs in the cpu_possible_map. | ||
362 | */ | ||
363 | int cpu; | ||
364 | |||
365 | for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu) | ||
366 | cpu_set(cpu, cpu_possible_map); | ||
367 | smp_ops = &psurge_smp_ops; | ||
368 | } | ||
369 | #endif | ||
370 | #endif /* CONFIG_SMP */ | ||
371 | |||
372 | #ifdef CONFIG_ADB | 339 | #ifdef CONFIG_ADB |
373 | if (strstr(cmd_line, "adb_sync")) { | 340 | if (strstr(cmd_line, "adb_sync")) { |
374 | extern int __adb_probe_sync; | 341 | extern int __adb_probe_sync; |
@@ -512,6 +479,14 @@ static void __init pmac_init_early(void) | |||
512 | #ifdef CONFIG_PPC64 | 479 | #ifdef CONFIG_PPC64 |
513 | iommu_init_early_dart(); | 480 | iommu_init_early_dart(); |
514 | #endif | 481 | #endif |
482 | |||
483 | /* SMP Init has to be done early as we need to patch up | ||
484 | * cpu_possible_map before interrupt stacks are allocated | ||
485 | * or kaboom... | ||
486 | */ | ||
487 | #ifdef CONFIG_SMP | ||
488 | pmac_setup_smp(); | ||
489 | #endif | ||
515 | } | 490 | } |
516 | 491 | ||
517 | static int __init pmac_declare_of_platform_devices(void) | 492 | static int __init pmac_declare_of_platform_devices(void) |
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c index cf1dbe758890..6d4da7b46b41 100644 --- a/arch/powerpc/platforms/powermac/smp.c +++ b/arch/powerpc/platforms/powermac/smp.c | |||
@@ -64,10 +64,11 @@ | |||
64 | extern void __secondary_start_pmac_0(void); | 64 | extern void __secondary_start_pmac_0(void); |
65 | extern int pmac_pfunc_base_install(void); | 65 | extern int pmac_pfunc_base_install(void); |
66 | 66 | ||
67 | #ifdef CONFIG_PPC32 | 67 | static void (*pmac_tb_freeze)(int freeze); |
68 | static u64 timebase; | ||
69 | static int tb_req; | ||
68 | 70 | ||
69 | /* Sync flag for HW tb sync */ | 71 | #ifdef CONFIG_PPC32 |
70 | static volatile int sec_tb_reset = 0; | ||
71 | 72 | ||
72 | /* | 73 | /* |
73 | * Powersurge (old powermac SMP) support. | 74 | * Powersurge (old powermac SMP) support. |
@@ -294,6 +295,9 @@ static int __init smp_psurge_probe(void) | |||
294 | psurge_quad_init(); | 295 | psurge_quad_init(); |
295 | /* All released cards using this HW design have 4 CPUs */ | 296 | /* All released cards using this HW design have 4 CPUs */ |
296 | ncpus = 4; | 297 | ncpus = 4; |
298 | /* No sure how timebase sync works on those, let's use SW */ | ||
299 | smp_ops->give_timebase = smp_generic_give_timebase; | ||
300 | smp_ops->take_timebase = smp_generic_take_timebase; | ||
297 | } else { | 301 | } else { |
298 | iounmap(quad_base); | 302 | iounmap(quad_base); |
299 | if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) { | 303 | if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) { |
@@ -308,18 +312,15 @@ static int __init smp_psurge_probe(void) | |||
308 | psurge_start = ioremap(PSURGE_START, 4); | 312 | psurge_start = ioremap(PSURGE_START, 4); |
309 | psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); | 313 | psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); |
310 | 314 | ||
311 | /* | 315 | /* This is necessary because OF doesn't know about the |
312 | * This is necessary because OF doesn't know about the | ||
313 | * secondary cpu(s), and thus there aren't nodes in the | 316 | * secondary cpu(s), and thus there aren't nodes in the |
314 | * device tree for them, and smp_setup_cpu_maps hasn't | 317 | * device tree for them, and smp_setup_cpu_maps hasn't |
315 | * set their bits in cpu_possible_map and cpu_present_map. | 318 | * set their bits in cpu_present_map. |
316 | */ | 319 | */ |
317 | if (ncpus > NR_CPUS) | 320 | if (ncpus > NR_CPUS) |
318 | ncpus = NR_CPUS; | 321 | ncpus = NR_CPUS; |
319 | for (i = 1; i < ncpus ; ++i) { | 322 | for (i = 1; i < ncpus ; ++i) |
320 | cpu_set(i, cpu_present_map); | 323 | cpu_set(i, cpu_present_map); |
321 | set_hard_smp_processor_id(i, i); | ||
322 | } | ||
323 | 324 | ||
324 | if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); | 325 | if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); |
325 | 326 | ||
@@ -329,8 +330,14 @@ static int __init smp_psurge_probe(void) | |||
329 | static void __init smp_psurge_kick_cpu(int nr) | 330 | static void __init smp_psurge_kick_cpu(int nr) |
330 | { | 331 | { |
331 | unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; | 332 | unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8; |
332 | unsigned long a; | 333 | unsigned long a, flags; |
333 | int i; | 334 | int i, j; |
335 | |||
336 | /* Defining this here is evil ... but I prefer hiding that | ||
337 | * crap to avoid giving people ideas that they can do the | ||
338 | * same. | ||
339 | */ | ||
340 | extern volatile unsigned int cpu_callin_map[NR_CPUS]; | ||
334 | 341 | ||
335 | /* may need to flush here if secondary bats aren't setup */ | 342 | /* may need to flush here if secondary bats aren't setup */ |
336 | for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) | 343 | for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32) |
@@ -339,47 +346,52 @@ static void __init smp_psurge_kick_cpu(int nr) | |||
339 | 346 | ||
340 | if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353); | 347 | if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353); |
341 | 348 | ||
349 | /* This is going to freeze the timeebase, we disable interrupts */ | ||
350 | local_irq_save(flags); | ||
351 | |||
342 | out_be32(psurge_start, start); | 352 | out_be32(psurge_start, start); |
343 | mb(); | 353 | mb(); |
344 | 354 | ||
345 | psurge_set_ipi(nr); | 355 | psurge_set_ipi(nr); |
356 | |||
346 | /* | 357 | /* |
347 | * We can't use udelay here because the timebase is now frozen. | 358 | * We can't use udelay here because the timebase is now frozen. |
348 | */ | 359 | */ |
349 | for (i = 0; i < 2000; ++i) | 360 | for (i = 0; i < 2000; ++i) |
350 | barrier(); | 361 | asm volatile("nop" : : : "memory"); |
351 | psurge_clr_ipi(nr); | 362 | psurge_clr_ipi(nr); |
352 | 363 | ||
353 | if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); | 364 | /* |
354 | } | 365 | * Also, because the timebase is frozen, we must not return to the |
355 | 366 | * caller which will try to do udelay's etc... Instead, we wait -here- | |
356 | /* | 367 | * for the CPU to callin. |
357 | * With the dual-cpu powersurge board, the decrementers and timebases | 368 | */ |
358 | * of both cpus are frozen after the secondary cpu is started up, | 369 | for (i = 0; i < 100000 && !cpu_callin_map[nr]; ++i) { |
359 | * until we give the secondary cpu another interrupt. This routine | 370 | for (j = 1; j < 10000; j++) |
360 | * uses this to get the timebases synchronized. | 371 | asm volatile("nop" : : : "memory"); |
361 | * -- paulus. | 372 | asm volatile("sync" : : : "memory"); |
362 | */ | 373 | } |
363 | static void __init psurge_dual_sync_tb(int cpu_nr) | 374 | if (!cpu_callin_map[nr]) |
364 | { | 375 | goto stuck; |
365 | int t; | 376 | |
366 | 377 | /* And we do the TB sync here too for standard dual CPU cards */ | |
367 | set_dec(tb_ticks_per_jiffy); | 378 | if (psurge_type == PSURGE_DUAL) { |
368 | /* XXX fixme */ | 379 | while(!tb_req) |
369 | set_tb(0, 0); | 380 | barrier(); |
370 | 381 | tb_req = 0; | |
371 | if (cpu_nr > 0) { | 382 | mb(); |
383 | timebase = get_tb(); | ||
384 | mb(); | ||
385 | while (timebase) | ||
386 | barrier(); | ||
372 | mb(); | 387 | mb(); |
373 | sec_tb_reset = 1; | ||
374 | return; | ||
375 | } | 388 | } |
389 | stuck: | ||
390 | /* now interrupt the secondary, restarting both TBs */ | ||
391 | if (psurge_type == PSURGE_DUAL) | ||
392 | psurge_set_ipi(1); | ||
376 | 393 | ||
377 | /* wait for the secondary to have reset its TB before proceeding */ | 394 | if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); |
378 | for (t = 10000000; t > 0 && !sec_tb_reset; --t) | ||
379 | ; | ||
380 | |||
381 | /* now interrupt the secondary, starting both TBs */ | ||
382 | psurge_set_ipi(1); | ||
383 | } | 395 | } |
384 | 396 | ||
385 | static struct irqaction psurge_irqaction = { | 397 | static struct irqaction psurge_irqaction = { |
@@ -390,36 +402,35 @@ static struct irqaction psurge_irqaction = { | |||
390 | 402 | ||
391 | static void __init smp_psurge_setup_cpu(int cpu_nr) | 403 | static void __init smp_psurge_setup_cpu(int cpu_nr) |
392 | { | 404 | { |
405 | if (cpu_nr != 0) | ||
406 | return; | ||
393 | 407 | ||
394 | if (cpu_nr == 0) { | 408 | /* reset the entry point so if we get another intr we won't |
395 | /* If we failed to start the second CPU, we should still | 409 | * try to startup again */ |
396 | * send it an IPI to start the timebase & DEC or we might | 410 | out_be32(psurge_start, 0x100); |
397 | * have them stuck. | 411 | if (setup_irq(30, &psurge_irqaction)) |
398 | */ | 412 | printk(KERN_ERR "Couldn't get primary IPI interrupt"); |
399 | if (num_online_cpus() < 2) { | ||
400 | if (psurge_type == PSURGE_DUAL) | ||
401 | psurge_set_ipi(1); | ||
402 | return; | ||
403 | } | ||
404 | /* reset the entry point so if we get another intr we won't | ||
405 | * try to startup again */ | ||
406 | out_be32(psurge_start, 0x100); | ||
407 | if (setup_irq(30, &psurge_irqaction)) | ||
408 | printk(KERN_ERR "Couldn't get primary IPI interrupt"); | ||
409 | } | ||
410 | |||
411 | if (psurge_type == PSURGE_DUAL) | ||
412 | psurge_dual_sync_tb(cpu_nr); | ||
413 | } | 413 | } |
414 | 414 | ||
415 | void __init smp_psurge_take_timebase(void) | 415 | void __init smp_psurge_take_timebase(void) |
416 | { | 416 | { |
417 | /* Dummy implementation */ | 417 | if (psurge_type != PSURGE_DUAL) |
418 | return; | ||
419 | |||
420 | tb_req = 1; | ||
421 | mb(); | ||
422 | while (!timebase) | ||
423 | barrier(); | ||
424 | mb(); | ||
425 | set_tb(timebase >> 32, timebase & 0xffffffff); | ||
426 | timebase = 0; | ||
427 | mb(); | ||
428 | set_dec(tb_ticks_per_jiffy/2); | ||
418 | } | 429 | } |
419 | 430 | ||
420 | void __init smp_psurge_give_timebase(void) | 431 | void __init smp_psurge_give_timebase(void) |
421 | { | 432 | { |
422 | /* Dummy implementation */ | 433 | /* Nothing to do here */ |
423 | } | 434 | } |
424 | 435 | ||
425 | /* PowerSurge-style Macs */ | 436 | /* PowerSurge-style Macs */ |
@@ -437,9 +448,6 @@ struct smp_ops_t psurge_smp_ops = { | |||
437 | * Core 99 and later support | 448 | * Core 99 and later support |
438 | */ | 449 | */ |
439 | 450 | ||
440 | static void (*pmac_tb_freeze)(int freeze); | ||
441 | static u64 timebase; | ||
442 | static int tb_req; | ||
443 | 451 | ||
444 | static void smp_core99_give_timebase(void) | 452 | static void smp_core99_give_timebase(void) |
445 | { | 453 | { |
@@ -478,7 +486,6 @@ static void __devinit smp_core99_take_timebase(void) | |||
478 | set_tb(timebase >> 32, timebase & 0xffffffff); | 486 | set_tb(timebase >> 32, timebase & 0xffffffff); |
479 | timebase = 0; | 487 | timebase = 0; |
480 | mb(); | 488 | mb(); |
481 | set_dec(tb_ticks_per_jiffy/2); | ||
482 | 489 | ||
483 | local_irq_restore(flags); | 490 | local_irq_restore(flags); |
484 | } | 491 | } |
@@ -920,3 +927,34 @@ struct smp_ops_t core99_smp_ops = { | |||
920 | # endif | 927 | # endif |
921 | #endif | 928 | #endif |
922 | }; | 929 | }; |
930 | |||
931 | void __init pmac_setup_smp(void) | ||
932 | { | ||
933 | struct device_node *np; | ||
934 | |||
935 | /* Check for Core99 */ | ||
936 | np = of_find_node_by_name(NULL, "uni-n"); | ||
937 | if (!np) | ||
938 | np = of_find_node_by_name(NULL, "u3"); | ||
939 | if (!np) | ||
940 | np = of_find_node_by_name(NULL, "u4"); | ||
941 | if (np) { | ||
942 | of_node_put(np); | ||
943 | smp_ops = &core99_smp_ops; | ||
944 | } | ||
945 | #ifdef CONFIG_PPC32 | ||
946 | else { | ||
947 | /* We have to set bits in cpu_possible_map here since the | ||
948 | * secondary CPU(s) aren't in the device tree. Various | ||
949 | * things won't be initialized for CPUs not in the possible | ||
950 | * map, so we really need to fix it up here. | ||
951 | */ | ||
952 | int cpu; | ||
953 | |||
954 | for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu) | ||
955 | cpu_set(cpu, cpu_possible_map); | ||
956 | smp_ops = &psurge_smp_ops; | ||
957 | } | ||
958 | #endif /* CONFIG_PPC32 */ | ||
959 | } | ||
960 | |||
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c index 1a231c389ba0..1f8f6cfb94f7 100644 --- a/arch/powerpc/platforms/pseries/smp.c +++ b/arch/powerpc/platforms/pseries/smp.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <asm/prom.h> | 35 | #include <asm/prom.h> |
36 | #include <asm/smp.h> | 36 | #include <asm/smp.h> |
37 | #include <asm/paca.h> | 37 | #include <asm/paca.h> |
38 | #include <asm/time.h> | ||
39 | #include <asm/machdep.h> | 38 | #include <asm/machdep.h> |
40 | #include <asm/cputable.h> | 39 | #include <asm/cputable.h> |
41 | #include <asm/firmware.h> | 40 | #include <asm/firmware.h> |
@@ -118,31 +117,6 @@ static void __devinit smp_xics_setup_cpu(int cpu) | |||
118 | } | 117 | } |
119 | #endif /* CONFIG_XICS */ | 118 | #endif /* CONFIG_XICS */ |
120 | 119 | ||
121 | static DEFINE_SPINLOCK(timebase_lock); | ||
122 | static unsigned long timebase = 0; | ||
123 | |||
124 | static void __devinit pSeries_give_timebase(void) | ||
125 | { | ||
126 | spin_lock(&timebase_lock); | ||
127 | rtas_call(rtas_token("freeze-time-base"), 0, 1, NULL); | ||
128 | timebase = get_tb(); | ||
129 | spin_unlock(&timebase_lock); | ||
130 | |||
131 | while (timebase) | ||
132 | barrier(); | ||
133 | rtas_call(rtas_token("thaw-time-base"), 0, 1, NULL); | ||
134 | } | ||
135 | |||
136 | static void __devinit pSeries_take_timebase(void) | ||
137 | { | ||
138 | while (!timebase) | ||
139 | barrier(); | ||
140 | spin_lock(&timebase_lock); | ||
141 | set_tb(timebase >> 32, timebase & 0xffffffff); | ||
142 | timebase = 0; | ||
143 | spin_unlock(&timebase_lock); | ||
144 | } | ||
145 | |||
146 | static void __devinit smp_pSeries_kick_cpu(int nr) | 120 | static void __devinit smp_pSeries_kick_cpu(int nr) |
147 | { | 121 | { |
148 | BUG_ON(nr < 0 || nr >= NR_CPUS); | 122 | BUG_ON(nr < 0 || nr >= NR_CPUS); |
@@ -209,8 +183,8 @@ static void __init smp_init_pseries(void) | |||
209 | 183 | ||
210 | /* Non-lpar has additional take/give timebase */ | 184 | /* Non-lpar has additional take/give timebase */ |
211 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { | 185 | if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) { |
212 | smp_ops->give_timebase = pSeries_give_timebase; | 186 | smp_ops->give_timebase = rtas_give_timebase; |
213 | smp_ops->take_timebase = pSeries_take_timebase; | 187 | smp_ops->take_timebase = rtas_take_timebase; |
214 | } | 188 | } |
215 | 189 | ||
216 | pr_debug(" <- smp_init_pSeries()\n"); | 190 | pr_debug(" <- smp_init_pSeries()\n"); |
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 9c3af5045495..d46de1f0f3ee 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c | |||
@@ -279,28 +279,29 @@ static void _mpic_map_mmio(struct mpic *mpic, phys_addr_t phys_addr, | |||
279 | } | 279 | } |
280 | 280 | ||
281 | #ifdef CONFIG_PPC_DCR | 281 | #ifdef CONFIG_PPC_DCR |
282 | static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb, | 282 | static void _mpic_map_dcr(struct mpic *mpic, struct device_node *node, |
283 | struct mpic_reg_bank *rb, | ||
283 | unsigned int offset, unsigned int size) | 284 | unsigned int offset, unsigned int size) |
284 | { | 285 | { |
285 | const u32 *dbasep; | 286 | const u32 *dbasep; |
286 | 287 | ||
287 | dbasep = of_get_property(mpic->irqhost->of_node, "dcr-reg", NULL); | 288 | dbasep = of_get_property(node, "dcr-reg", NULL); |
288 | 289 | ||
289 | rb->dhost = dcr_map(mpic->irqhost->of_node, *dbasep + offset, size); | 290 | rb->dhost = dcr_map(node, *dbasep + offset, size); |
290 | BUG_ON(!DCR_MAP_OK(rb->dhost)); | 291 | BUG_ON(!DCR_MAP_OK(rb->dhost)); |
291 | } | 292 | } |
292 | 293 | ||
293 | static inline void mpic_map(struct mpic *mpic, phys_addr_t phys_addr, | 294 | static inline void mpic_map(struct mpic *mpic, struct device_node *node, |
294 | struct mpic_reg_bank *rb, unsigned int offset, | 295 | phys_addr_t phys_addr, struct mpic_reg_bank *rb, |
295 | unsigned int size) | 296 | unsigned int offset, unsigned int size) |
296 | { | 297 | { |
297 | if (mpic->flags & MPIC_USES_DCR) | 298 | if (mpic->flags & MPIC_USES_DCR) |
298 | _mpic_map_dcr(mpic, rb, offset, size); | 299 | _mpic_map_dcr(mpic, node, rb, offset, size); |
299 | else | 300 | else |
300 | _mpic_map_mmio(mpic, phys_addr, rb, offset, size); | 301 | _mpic_map_mmio(mpic, phys_addr, rb, offset, size); |
301 | } | 302 | } |
302 | #else /* CONFIG_PPC_DCR */ | 303 | #else /* CONFIG_PPC_DCR */ |
303 | #define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) | 304 | #define mpic_map(m,n,p,b,o,s) _mpic_map_mmio(m,p,b,o,s) |
304 | #endif /* !CONFIG_PPC_DCR */ | 305 | #endif /* !CONFIG_PPC_DCR */ |
305 | 306 | ||
306 | 307 | ||
@@ -1052,11 +1053,10 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1052 | int intvec_top; | 1053 | int intvec_top; |
1053 | u64 paddr = phys_addr; | 1054 | u64 paddr = phys_addr; |
1054 | 1055 | ||
1055 | mpic = alloc_bootmem(sizeof(struct mpic)); | 1056 | mpic = kzalloc(sizeof(struct mpic), GFP_KERNEL); |
1056 | if (mpic == NULL) | 1057 | if (mpic == NULL) |
1057 | return NULL; | 1058 | return NULL; |
1058 | 1059 | ||
1059 | memset(mpic, 0, sizeof(struct mpic)); | ||
1060 | mpic->name = name; | 1060 | mpic->name = name; |
1061 | 1061 | ||
1062 | mpic->hc_irq = mpic_irq_chip; | 1062 | mpic->hc_irq = mpic_irq_chip; |
@@ -1152,8 +1152,8 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | /* Map the global registers */ | 1154 | /* Map the global registers */ |
1155 | mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); | 1155 | mpic_map(mpic, node, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); |
1156 | mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); | 1156 | mpic_map(mpic, node, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); |
1157 | 1157 | ||
1158 | /* Reset */ | 1158 | /* Reset */ |
1159 | if (flags & MPIC_WANTS_RESET) { | 1159 | if (flags & MPIC_WANTS_RESET) { |
@@ -1194,7 +1194,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1194 | 1194 | ||
1195 | /* Map the per-CPU registers */ | 1195 | /* Map the per-CPU registers */ |
1196 | for (i = 0; i < mpic->num_cpus; i++) { | 1196 | for (i = 0; i < mpic->num_cpus; i++) { |
1197 | mpic_map(mpic, paddr, &mpic->cpuregs[i], | 1197 | mpic_map(mpic, node, paddr, &mpic->cpuregs[i], |
1198 | MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), | 1198 | MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE), |
1199 | 0x1000); | 1199 | 0x1000); |
1200 | } | 1200 | } |
@@ -1202,7 +1202,7 @@ struct mpic * __init mpic_alloc(struct device_node *node, | |||
1202 | /* Initialize main ISU if none provided */ | 1202 | /* Initialize main ISU if none provided */ |
1203 | if (mpic->isu_size == 0) { | 1203 | if (mpic->isu_size == 0) { |
1204 | mpic->isu_size = mpic->num_sources; | 1204 | mpic->isu_size = mpic->num_sources; |
1205 | mpic_map(mpic, paddr, &mpic->isus[0], | 1205 | mpic_map(mpic, node, paddr, &mpic->isus[0], |
1206 | MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); | 1206 | MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); |
1207 | } | 1207 | } |
1208 | mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); | 1208 | mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); |
@@ -1256,8 +1256,10 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, | |||
1256 | 1256 | ||
1257 | BUG_ON(isu_num >= MPIC_MAX_ISU); | 1257 | BUG_ON(isu_num >= MPIC_MAX_ISU); |
1258 | 1258 | ||
1259 | mpic_map(mpic, paddr, &mpic->isus[isu_num], 0, | 1259 | mpic_map(mpic, mpic->irqhost->of_node, |
1260 | paddr, &mpic->isus[isu_num], 0, | ||
1260 | MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); | 1261 | MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); |
1262 | |||
1261 | if ((isu_first + mpic->isu_size) > mpic->num_sources) | 1263 | if ((isu_first + mpic->isu_size) > mpic->num_sources) |
1262 | mpic->num_sources = isu_first + mpic->isu_size; | 1264 | mpic->num_sources = isu_first + mpic->isu_size; |
1263 | } | 1265 | } |
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c index b28b0e512d67..237e3654f48c 100644 --- a/arch/powerpc/sysdev/qe_lib/qe.c +++ b/arch/powerpc/sysdev/qe_lib/qe.c | |||
@@ -112,6 +112,7 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) | |||
112 | { | 112 | { |
113 | unsigned long flags; | 113 | unsigned long flags; |
114 | u8 mcn_shift = 0, dev_shift = 0; | 114 | u8 mcn_shift = 0, dev_shift = 0; |
115 | u32 ret; | ||
115 | 116 | ||
116 | spin_lock_irqsave(&qe_lock, flags); | 117 | spin_lock_irqsave(&qe_lock, flags); |
117 | if (cmd == QE_RESET) { | 118 | if (cmd == QE_RESET) { |
@@ -139,11 +140,13 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input) | |||
139 | } | 140 | } |
140 | 141 | ||
141 | /* wait for the QE_CR_FLG to clear */ | 142 | /* wait for the QE_CR_FLG to clear */ |
142 | while(in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) | 143 | ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0, |
143 | cpu_relax(); | 144 | 100, 0); |
145 | /* On timeout (e.g. failure), the expression will be false (ret == 0), | ||
146 | otherwise it will be true (ret == 1). */ | ||
144 | spin_unlock_irqrestore(&qe_lock, flags); | 147 | spin_unlock_irqrestore(&qe_lock, flags); |
145 | 148 | ||
146 | return 0; | 149 | return ret == 1; |
147 | } | 150 | } |
148 | EXPORT_SYMBOL(qe_issue_cmd); | 151 | EXPORT_SYMBOL(qe_issue_cmd); |
149 | 152 | ||
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h index a27d0d5a6f86..1cd02f6073a0 100644 --- a/arch/s390/include/asm/kvm_host.h +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -99,7 +99,9 @@ struct kvm_s390_sie_block { | |||
99 | __u8 reservedd0[48]; /* 0x00d0 */ | 99 | __u8 reservedd0[48]; /* 0x00d0 */ |
100 | __u64 gcr[16]; /* 0x0100 */ | 100 | __u64 gcr[16]; /* 0x0100 */ |
101 | __u64 gbea; /* 0x0180 */ | 101 | __u64 gbea; /* 0x0180 */ |
102 | __u8 reserved188[120]; /* 0x0188 */ | 102 | __u8 reserved188[24]; /* 0x0188 */ |
103 | __u32 fac; /* 0x01a0 */ | ||
104 | __u8 reserved1a4[92]; /* 0x01a4 */ | ||
103 | } __attribute__((packed)); | 105 | } __attribute__((packed)); |
104 | 106 | ||
105 | struct kvm_vcpu_stat { | 107 | struct kvm_vcpu_stat { |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index c18b21d6991c..90d9d1ba258b 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <asm/lowcore.h> | 25 | #include <asm/lowcore.h> |
26 | #include <asm/pgtable.h> | 26 | #include <asm/pgtable.h> |
27 | #include <asm/nmi.h> | 27 | #include <asm/nmi.h> |
28 | #include <asm/system.h> | ||
28 | #include "kvm-s390.h" | 29 | #include "kvm-s390.h" |
29 | #include "gaccess.h" | 30 | #include "gaccess.h" |
30 | 31 | ||
@@ -69,6 +70,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
69 | { NULL } | 70 | { NULL } |
70 | }; | 71 | }; |
71 | 72 | ||
73 | static unsigned long long *facilities; | ||
72 | 74 | ||
73 | /* Section: not file related */ | 75 | /* Section: not file related */ |
74 | void kvm_arch_hardware_enable(void *garbage) | 76 | void kvm_arch_hardware_enable(void *garbage) |
@@ -288,6 +290,7 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) | |||
288 | vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin; | 290 | vcpu->arch.sie_block->gmsor = vcpu->kvm->arch.guest_origin; |
289 | vcpu->arch.sie_block->ecb = 2; | 291 | vcpu->arch.sie_block->ecb = 2; |
290 | vcpu->arch.sie_block->eca = 0xC1002001U; | 292 | vcpu->arch.sie_block->eca = 0xC1002001U; |
293 | vcpu->arch.sie_block->fac = (int) (long) facilities; | ||
291 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); | 294 | hrtimer_init(&vcpu->arch.ckc_timer, CLOCK_REALTIME, HRTIMER_MODE_ABS); |
292 | tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, | 295 | tasklet_init(&vcpu->arch.tasklet, kvm_s390_tasklet, |
293 | (unsigned long) vcpu); | 296 | (unsigned long) vcpu); |
@@ -739,11 +742,29 @@ gfn_t unalias_gfn(struct kvm *kvm, gfn_t gfn) | |||
739 | 742 | ||
740 | static int __init kvm_s390_init(void) | 743 | static int __init kvm_s390_init(void) |
741 | { | 744 | { |
742 | return kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); | 745 | int ret; |
746 | ret = kvm_init(NULL, sizeof(struct kvm_vcpu), THIS_MODULE); | ||
747 | if (ret) | ||
748 | return ret; | ||
749 | |||
750 | /* | ||
751 | * guests can ask for up to 255+1 double words, we need a full page | ||
752 | * to hold the maximum amount of facilites. On the other hand, we | ||
753 | * only set facilities that are known to work in KVM. | ||
754 | */ | ||
755 | facilities = (unsigned long long *) get_zeroed_page(GFP_DMA); | ||
756 | if (!facilities) { | ||
757 | kvm_exit(); | ||
758 | return -ENOMEM; | ||
759 | } | ||
760 | stfle(facilities, 1); | ||
761 | facilities[0] &= 0xff00fff3f0700000ULL; | ||
762 | return 0; | ||
743 | } | 763 | } |
744 | 764 | ||
745 | static void __exit kvm_s390_exit(void) | 765 | static void __exit kvm_s390_exit(void) |
746 | { | 766 | { |
767 | free_page((unsigned long) facilities); | ||
747 | kvm_exit(); | 768 | kvm_exit(); |
748 | } | 769 | } |
749 | 770 | ||
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index 93ecd06e1a74..d426aac8095d 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -158,7 +158,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) | |||
158 | 158 | ||
159 | vcpu->stat.instruction_stfl++; | 159 | vcpu->stat.instruction_stfl++; |
160 | /* only pass the facility bits, which we can handle */ | 160 | /* only pass the facility bits, which we can handle */ |
161 | facility_list &= 0xfe00fff3; | 161 | facility_list &= 0xff00fff3; |
162 | 162 | ||
163 | rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), | 163 | rc = copy_to_guest(vcpu, offsetof(struct _lowcore, stfl_fac_list), |
164 | &facility_list, sizeof(facility_list)); | 164 | &facility_list, sizeof(facility_list)); |
diff --git a/arch/sparc/boot/Makefile b/arch/sparc/boot/Makefile index 96041a8d39e8..1ff0fd924756 100644 --- a/arch/sparc/boot/Makefile +++ b/arch/sparc/boot/Makefile | |||
@@ -15,7 +15,7 @@ quiet_cmd_elftoaout = ELFTOAOUT $@ | |||
15 | 15 | ||
16 | ifeq ($(CONFIG_SPARC32),y) | 16 | ifeq ($(CONFIG_SPARC32),y) |
17 | quiet_cmd_piggy = PIGGY $@ | 17 | quiet_cmd_piggy = PIGGY $@ |
18 | cmd_piggy = $(obj)/piggyback_32 $@ $(obj)/System.map $(ROOT_IMG) | 18 | cmd_piggy = $(obj)/piggyback_32 $@ System.map $(ROOT_IMG) |
19 | quiet_cmd_btfix = BTFIX $@ | 19 | quiet_cmd_btfix = BTFIX $@ |
20 | cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ | 20 | cmd_btfix = $(OBJDUMP) -x vmlinux | $(obj)/btfixupprep > $@ |
21 | quiet_cmd_sysmap = SYSMAP $(obj)/System.map | 21 | quiet_cmd_sysmap = SYSMAP $(obj)/System.map |
@@ -58,7 +58,7 @@ $(obj)/image: $(obj)/btfix.o FORCE | |||
58 | $(obj)/zImage: $(obj)/image | 58 | $(obj)/zImage: $(obj)/image |
59 | $(call if_changed,strip) | 59 | $(call if_changed,strip) |
60 | 60 | ||
61 | $(obj)/tftpboot.img: $(obj)/piggyback $(obj)/System.map $(obj)/image FORCE | 61 | $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_32 System.map $(ROOT_IMG) FORCE |
62 | $(call if_changed,elftoaout) | 62 | $(call if_changed,elftoaout) |
63 | $(call if_changed,piggy) | 63 | $(call if_changed,piggy) |
64 | 64 | ||
@@ -79,7 +79,7 @@ $(obj)/image: vmlinux FORCE | |||
79 | $(call if_changed,strip) | 79 | $(call if_changed,strip) |
80 | @echo ' kernel: $@ is ready' | 80 | @echo ' kernel: $@ is ready' |
81 | 81 | ||
82 | $(obj)/tftpboot.img: vmlinux $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE | 82 | $(obj)/tftpboot.img: $(obj)/image $(obj)/piggyback_64 System.map $(ROOT_IMG) FORCE |
83 | $(call if_changed,elftoaout) | 83 | $(call if_changed,elftoaout) |
84 | $(call if_changed,piggy) | 84 | $(call if_changed,piggy) |
85 | @echo ' kernel: $@ is ready' | 85 | @echo ' kernel: $@ is ready' |
diff --git a/arch/sparc/boot/piggyback_32.c b/arch/sparc/boot/piggyback_32.c index c9f500c1a8b2..e8dc9adfcd61 100644 --- a/arch/sparc/boot/piggyback_32.c +++ b/arch/sparc/boot/piggyback_32.c | |||
@@ -70,7 +70,7 @@ void die(char *str) | |||
70 | int main(int argc,char **argv) | 70 | int main(int argc,char **argv) |
71 | { | 71 | { |
72 | static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 }; | 72 | static char aout_magic[] = { 0x01, 0x03, 0x01, 0x07 }; |
73 | unsigned char buffer[1024], *q, *r; | 73 | char buffer[1024], *q, *r; |
74 | unsigned int i, j, k, start, end, offset; | 74 | unsigned int i, j, k, start, end, offset; |
75 | FILE *map; | 75 | FILE *map; |
76 | struct stat s; | 76 | struct stat s; |
@@ -84,7 +84,7 @@ int main(int argc,char **argv) | |||
84 | while (fgets (buffer, 1024, map)) { | 84 | while (fgets (buffer, 1024, map)) { |
85 | if (!strcmp (buffer + 8, " T start\n") || !strcmp (buffer + 16, " T start\n")) | 85 | if (!strcmp (buffer + 8, " T start\n") || !strcmp (buffer + 16, " T start\n")) |
86 | start = strtoul (buffer, NULL, 16); | 86 | start = strtoul (buffer, NULL, 16); |
87 | else if (!strcmp (buffer + 8, " A end\n") || !strcmp (buffer + 16, " A end\n")) | 87 | else if (!strcmp (buffer + 8, " A _end\n") || !strcmp (buffer + 16, " A _end\n")) |
88 | end = strtoul (buffer, NULL, 16); | 88 | end = strtoul (buffer, NULL, 16); |
89 | } | 89 | } |
90 | fclose (map); | 90 | fclose (map); |
diff --git a/arch/sparc/boot/piggyback_64.c b/arch/sparc/boot/piggyback_64.c index de364bfed0bb..c63fd1b6bdd4 100644 --- a/arch/sparc/boot/piggyback_64.c +++ b/arch/sparc/boot/piggyback_64.c | |||
@@ -46,6 +46,7 @@ int main(int argc,char **argv) | |||
46 | struct stat s; | 46 | struct stat s; |
47 | int image, tail; | 47 | int image, tail; |
48 | 48 | ||
49 | start = end = 0; | ||
49 | if (stat (argv[3], &s) < 0) die (argv[3]); | 50 | if (stat (argv[3], &s) < 0) die (argv[3]); |
50 | map = fopen (argv[2], "r"); | 51 | map = fopen (argv[2], "r"); |
51 | if (!map) die(argv[2]); | 52 | if (!map) die(argv[2]); |
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c index bd075054942b..f0ee79055409 100644 --- a/arch/sparc/kernel/irq_64.c +++ b/arch/sparc/kernel/irq_64.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
22 | #include <linux/seq_file.h> | 22 | #include <linux/seq_file.h> |
23 | #include <linux/bootmem.h> | ||
24 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
25 | 24 | ||
26 | #include <asm/ptrace.h> | 25 | #include <asm/ptrace.h> |
@@ -914,25 +913,19 @@ void __cpuinit notrace sun4v_register_mondo_queues(int this_cpu) | |||
914 | tb->nonresum_qmask); | 913 | tb->nonresum_qmask); |
915 | } | 914 | } |
916 | 915 | ||
917 | static void __init alloc_one_mondo(unsigned long *pa_ptr, unsigned long qmask) | 916 | /* Each queue region must be a power of 2 multiple of 64 bytes in |
918 | { | 917 | * size. The base real address must be aligned to the size of the |
919 | unsigned long size = PAGE_ALIGN(qmask + 1); | 918 | * region. Thus, an 8KB queue must be 8KB aligned, for example. |
920 | void *p = __alloc_bootmem(size, size, 0); | 919 | */ |
921 | if (!p) { | 920 | static void __init alloc_one_queue(unsigned long *pa_ptr, unsigned long qmask) |
922 | prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); | ||
923 | prom_halt(); | ||
924 | } | ||
925 | |||
926 | *pa_ptr = __pa(p); | ||
927 | } | ||
928 | |||
929 | static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) | ||
930 | { | 921 | { |
931 | unsigned long size = PAGE_ALIGN(qmask + 1); | 922 | unsigned long size = PAGE_ALIGN(qmask + 1); |
932 | void *p = __alloc_bootmem(size, size, 0); | 923 | unsigned long order = get_order(size); |
924 | unsigned long p; | ||
933 | 925 | ||
926 | p = __get_free_pages(GFP_KERNEL, order); | ||
934 | if (!p) { | 927 | if (!p) { |
935 | prom_printf("SUN4V: Error, cannot allocate kbuf page.\n"); | 928 | prom_printf("SUN4V: Error, cannot allocate queue.\n"); |
936 | prom_halt(); | 929 | prom_halt(); |
937 | } | 930 | } |
938 | 931 | ||
@@ -942,11 +935,11 @@ static void __init alloc_one_kbuf(unsigned long *pa_ptr, unsigned long qmask) | |||
942 | static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb) | 935 | static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb) |
943 | { | 936 | { |
944 | #ifdef CONFIG_SMP | 937 | #ifdef CONFIG_SMP |
945 | void *page; | 938 | unsigned long page; |
946 | 939 | ||
947 | BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); | 940 | BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64)); |
948 | 941 | ||
949 | page = alloc_bootmem_pages(PAGE_SIZE); | 942 | page = get_zeroed_page(GFP_KERNEL); |
950 | if (!page) { | 943 | if (!page) { |
951 | prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); | 944 | prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n"); |
952 | prom_halt(); | 945 | prom_halt(); |
@@ -965,13 +958,13 @@ static void __init sun4v_init_mondo_queues(void) | |||
965 | for_each_possible_cpu(cpu) { | 958 | for_each_possible_cpu(cpu) { |
966 | struct trap_per_cpu *tb = &trap_block[cpu]; | 959 | struct trap_per_cpu *tb = &trap_block[cpu]; |
967 | 960 | ||
968 | alloc_one_mondo(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask); | 961 | alloc_one_queue(&tb->cpu_mondo_pa, tb->cpu_mondo_qmask); |
969 | alloc_one_mondo(&tb->dev_mondo_pa, tb->dev_mondo_qmask); | 962 | alloc_one_queue(&tb->dev_mondo_pa, tb->dev_mondo_qmask); |
970 | alloc_one_mondo(&tb->resum_mondo_pa, tb->resum_qmask); | 963 | alloc_one_queue(&tb->resum_mondo_pa, tb->resum_qmask); |
971 | alloc_one_kbuf(&tb->resum_kernel_buf_pa, tb->resum_qmask); | 964 | alloc_one_queue(&tb->resum_kernel_buf_pa, tb->resum_qmask); |
972 | alloc_one_mondo(&tb->nonresum_mondo_pa, tb->nonresum_qmask); | 965 | alloc_one_queue(&tb->nonresum_mondo_pa, tb->nonresum_qmask); |
973 | alloc_one_kbuf(&tb->nonresum_kernel_buf_pa, | 966 | alloc_one_queue(&tb->nonresum_kernel_buf_pa, |
974 | tb->nonresum_qmask); | 967 | tb->nonresum_qmask); |
975 | } | 968 | } |
976 | } | 969 | } |
977 | 970 | ||
@@ -999,7 +992,7 @@ void __init init_IRQ(void) | |||
999 | kill_prom_timer(); | 992 | kill_prom_timer(); |
1000 | 993 | ||
1001 | size = sizeof(struct ino_bucket) * NUM_IVECS; | 994 | size = sizeof(struct ino_bucket) * NUM_IVECS; |
1002 | ivector_table = alloc_bootmem(size); | 995 | ivector_table = kzalloc(size, GFP_KERNEL); |
1003 | if (!ivector_table) { | 996 | if (!ivector_table) { |
1004 | prom_printf("Fatal error, cannot allocate ivector_table\n"); | 997 | prom_printf("Fatal error, cannot allocate ivector_table\n"); |
1005 | prom_halt(); | 998 | prom_halt(); |
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c index 5ec17563142e..dd2aadc14af0 100644 --- a/arch/um/drivers/slip_kern.c +++ b/arch/um/drivers/slip_kern.c | |||
@@ -30,7 +30,6 @@ static void slip_init(struct net_device *dev, void *data) | |||
30 | 30 | ||
31 | slip_proto_init(&spri->slip); | 31 | slip_proto_init(&spri->slip); |
32 | 32 | ||
33 | dev->init = NULL; | ||
34 | dev->hard_header_len = 0; | 33 | dev->hard_header_len = 0; |
35 | dev->header_ops = NULL; | 34 | dev->header_ops = NULL; |
36 | dev->addr_len = 0; | 35 | dev->addr_len = 0; |
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c index f15a6e7654f3..e376284f0fb7 100644 --- a/arch/um/drivers/slirp_kern.c +++ b/arch/um/drivers/slirp_kern.c | |||
@@ -32,7 +32,6 @@ void slirp_init(struct net_device *dev, void *data) | |||
32 | 32 | ||
33 | slip_proto_init(&spri->slip); | 33 | slip_proto_init(&spri->slip); |
34 | 34 | ||
35 | dev->init = NULL; | ||
36 | dev->hard_header_len = 0; | 35 | dev->hard_header_len = 0; |
37 | dev->header_ops = NULL; | 36 | dev->header_ops = NULL; |
38 | dev->addr_len = 0; | 37 | dev->addr_len = 0; |
diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h index 90fc708b320e..378de4bbf49f 100644 --- a/arch/um/include/asm/dma-mapping.h +++ b/arch/um/include/asm/dma-mapping.h | |||
@@ -79,14 +79,14 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, | |||
79 | } | 79 | } |
80 | 80 | ||
81 | static inline void | 81 | static inline void |
82 | dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size, | 82 | dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, |
83 | enum dma_data_direction direction) | 83 | enum dma_data_direction direction) |
84 | { | 84 | { |
85 | BUG(); | 85 | BUG(); |
86 | } | 86 | } |
87 | 87 | ||
88 | static inline void | 88 | static inline void |
89 | dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, | 89 | dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems, |
90 | enum dma_data_direction direction) | 90 | enum dma_data_direction direction) |
91 | { | 91 | { |
92 | BUG(); | 92 | BUG(); |
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h index 418e632d4a80..7a1065958ba9 100644 --- a/arch/x86/include/asm/boot.h +++ b/arch/x86/include/asm/boot.h | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | #ifdef __KERNEL__ | 9 | #ifdef __KERNEL__ |
10 | 10 | ||
11 | #include <asm/page_types.h> | 11 | #include <asm/pgtable_types.h> |
12 | 12 | ||
13 | /* Physical address where kernel should be loaded. */ | 13 | /* Physical address where kernel should be loaded. */ |
14 | #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ | 14 | #define LOAD_PHYSICAL_ADDR ((CONFIG_PHYSICAL_START \ |
@@ -16,10 +16,10 @@ | |||
16 | & ~(CONFIG_PHYSICAL_ALIGN - 1)) | 16 | & ~(CONFIG_PHYSICAL_ALIGN - 1)) |
17 | 17 | ||
18 | /* Minimum kernel alignment, as a power of two */ | 18 | /* Minimum kernel alignment, as a power of two */ |
19 | #ifdef CONFIG_x86_64 | 19 | #ifdef CONFIG_X86_64 |
20 | #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT | 20 | #define MIN_KERNEL_ALIGN_LG2 PMD_SHIFT |
21 | #else | 21 | #else |
22 | #define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT+1) | 22 | #define MIN_KERNEL_ALIGN_LG2 (PAGE_SHIFT + THREAD_ORDER) |
23 | #endif | 23 | #endif |
24 | #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2) | 24 | #define MIN_KERNEL_ALIGN (_AC(1, UL) << MIN_KERNEL_ALIGN_LG2) |
25 | 25 | ||
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 02ecb30982a3..103f1ddb0d85 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h | |||
@@ -42,6 +42,7 @@ | |||
42 | 42 | ||
43 | #else /* ...!ASSEMBLY */ | 43 | #else /* ...!ASSEMBLY */ |
44 | 44 | ||
45 | #include <linux/kernel.h> | ||
45 | #include <linux/stringify.h> | 46 | #include <linux/stringify.h> |
46 | 47 | ||
47 | #ifdef CONFIG_SMP | 48 | #ifdef CONFIG_SMP |
@@ -155,6 +156,15 @@ do { \ | |||
155 | /* We can use this directly for local CPU (faster). */ | 156 | /* We can use this directly for local CPU (faster). */ |
156 | DECLARE_PER_CPU(unsigned long, this_cpu_off); | 157 | DECLARE_PER_CPU(unsigned long, this_cpu_off); |
157 | 158 | ||
159 | #ifdef CONFIG_NEED_MULTIPLE_NODES | ||
160 | void *pcpu_lpage_remapped(void *kaddr); | ||
161 | #else | ||
162 | static inline void *pcpu_lpage_remapped(void *kaddr) | ||
163 | { | ||
164 | return NULL; | ||
165 | } | ||
166 | #endif | ||
167 | |||
158 | #endif /* !__ASSEMBLY__ */ | 168 | #endif /* !__ASSEMBLY__ */ |
159 | 169 | ||
160 | #ifdef CONFIG_SMP | 170 | #ifdef CONFIG_SMP |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index e5b27d8f1b47..28e5f5956042 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
@@ -258,13 +258,15 @@ static void __cpuinit amd_detect_cmp(struct cpuinfo_x86 *c) | |||
258 | { | 258 | { |
259 | #ifdef CONFIG_X86_HT | 259 | #ifdef CONFIG_X86_HT |
260 | unsigned bits; | 260 | unsigned bits; |
261 | int cpu = smp_processor_id(); | ||
261 | 262 | ||
262 | bits = c->x86_coreid_bits; | 263 | bits = c->x86_coreid_bits; |
263 | |||
264 | /* Low order bits define the core id (index of core in socket) */ | 264 | /* Low order bits define the core id (index of core in socket) */ |
265 | c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); | 265 | c->cpu_core_id = c->initial_apicid & ((1 << bits)-1); |
266 | /* Convert the initial APIC ID into the socket ID */ | 266 | /* Convert the initial APIC ID into the socket ID */ |
267 | c->phys_proc_id = c->initial_apicid >> bits; | 267 | c->phys_proc_id = c->initial_apicid >> bits; |
268 | /* use socket ID also for last level cache */ | ||
269 | per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; | ||
268 | #endif | 270 | #endif |
269 | } | 271 | } |
270 | 272 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 6b26d4deada0..f1961c07af9a 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -848,9 +848,6 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c) | |||
848 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) | 848 | #if defined(CONFIG_NUMA) && defined(CONFIG_X86_64) |
849 | numa_add_cpu(smp_processor_id()); | 849 | numa_add_cpu(smp_processor_id()); |
850 | #endif | 850 | #endif |
851 | |||
852 | /* Cap the iomem address space to what is addressable on all CPUs */ | ||
853 | iomem_resource.end &= (1ULL << c->x86_phys_bits) - 1; | ||
854 | } | 851 | } |
855 | 852 | ||
856 | #ifdef CONFIG_X86_64 | 853 | #ifdef CONFIG_X86_64 |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 284d1de968bc..af425b83202b 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -1117,7 +1117,7 @@ static void mcheck_timer(unsigned long data) | |||
1117 | *n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ)); | 1117 | *n = min(*n*2, (int)round_jiffies_relative(check_interval*HZ)); |
1118 | 1118 | ||
1119 | t->expires = jiffies + *n; | 1119 | t->expires = jiffies + *n; |
1120 | add_timer(t); | 1120 | add_timer_on(t, smp_processor_id()); |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | static void mce_do_trigger(struct work_struct *work) | 1123 | static void mce_do_trigger(struct work_struct *work) |
@@ -1321,7 +1321,7 @@ static void mce_init_timer(void) | |||
1321 | return; | 1321 | return; |
1322 | setup_timer(t, mcheck_timer, smp_processor_id()); | 1322 | setup_timer(t, mcheck_timer, smp_processor_id()); |
1323 | t->expires = round_jiffies(jiffies + *n); | 1323 | t->expires = round_jiffies(jiffies + *n); |
1324 | add_timer(t); | 1324 | add_timer_on(t, smp_processor_id()); |
1325 | } | 1325 | } |
1326 | 1326 | ||
1327 | /* | 1327 | /* |
diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c index 95ea5fa7d444..c8405718a4c3 100644 --- a/arch/x86/kernel/dumpstack.c +++ b/arch/x86/kernel/dumpstack.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "dumpstack.h" | 22 | #include "dumpstack.h" |
23 | 23 | ||
24 | int panic_on_unrecovered_nmi; | 24 | int panic_on_unrecovered_nmi; |
25 | int panic_on_io_nmi; | ||
25 | unsigned int code_bytes = 64; | 26 | unsigned int code_bytes = 64; |
26 | int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; | 27 | int kstack_depth_to_print = 3 * STACKSLOTS_PER_LINE; |
27 | static int die_counter; | 28 | static int die_counter; |
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index be5ae80f897f..de2cab132844 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -289,6 +289,20 @@ void * __init extend_brk(size_t size, size_t align) | |||
289 | return ret; | 289 | return ret; |
290 | } | 290 | } |
291 | 291 | ||
292 | #ifdef CONFIG_X86_64 | ||
293 | static void __init init_gbpages(void) | ||
294 | { | ||
295 | if (direct_gbpages && cpu_has_gbpages) | ||
296 | printk(KERN_INFO "Using GB pages for direct mapping\n"); | ||
297 | else | ||
298 | direct_gbpages = 0; | ||
299 | } | ||
300 | #else | ||
301 | static inline void init_gbpages(void) | ||
302 | { | ||
303 | } | ||
304 | #endif | ||
305 | |||
292 | static void __init reserve_brk(void) | 306 | static void __init reserve_brk(void) |
293 | { | 307 | { |
294 | if (_brk_end > _brk_start) | 308 | if (_brk_end > _brk_start) |
@@ -871,6 +885,8 @@ void __init setup_arch(char **cmdline_p) | |||
871 | 885 | ||
872 | reserve_brk(); | 886 | reserve_brk(); |
873 | 887 | ||
888 | init_gbpages(); | ||
889 | |||
874 | /* max_pfn_mapped is updated here */ | 890 | /* max_pfn_mapped is updated here */ |
875 | max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); | 891 | max_low_pfn_mapped = init_memory_mapping(0, max_low_pfn<<PAGE_SHIFT); |
876 | max_pfn_mapped = max_low_pfn_mapped; | 892 | max_pfn_mapped = max_low_pfn_mapped; |
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index 9c3f0823e6aa..29a3eef7cf4a 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
@@ -124,7 +124,7 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, | |||
124 | } | 124 | } |
125 | 125 | ||
126 | /* | 126 | /* |
127 | * Remap allocator | 127 | * Large page remap allocator |
128 | * | 128 | * |
129 | * This allocator uses PMD page as unit. A PMD page is allocated for | 129 | * This allocator uses PMD page as unit. A PMD page is allocated for |
130 | * each cpu and each is remapped into vmalloc area using PMD mapping. | 130 | * each cpu and each is remapped into vmalloc area using PMD mapping. |
@@ -137,105 +137,185 @@ static void * __init pcpu_alloc_bootmem(unsigned int cpu, unsigned long size, | |||
137 | * better than only using 4k mappings while still being NUMA friendly. | 137 | * better than only using 4k mappings while still being NUMA friendly. |
138 | */ | 138 | */ |
139 | #ifdef CONFIG_NEED_MULTIPLE_NODES | 139 | #ifdef CONFIG_NEED_MULTIPLE_NODES |
140 | static size_t pcpur_size __initdata; | 140 | struct pcpul_ent { |
141 | static void **pcpur_ptrs __initdata; | 141 | unsigned int cpu; |
142 | void *ptr; | ||
143 | }; | ||
144 | |||
145 | static size_t pcpul_size; | ||
146 | static struct pcpul_ent *pcpul_map; | ||
147 | static struct vm_struct pcpul_vm; | ||
142 | 148 | ||
143 | static struct page * __init pcpur_get_page(unsigned int cpu, int pageno) | 149 | static struct page * __init pcpul_get_page(unsigned int cpu, int pageno) |
144 | { | 150 | { |
145 | size_t off = (size_t)pageno << PAGE_SHIFT; | 151 | size_t off = (size_t)pageno << PAGE_SHIFT; |
146 | 152 | ||
147 | if (off >= pcpur_size) | 153 | if (off >= pcpul_size) |
148 | return NULL; | 154 | return NULL; |
149 | 155 | ||
150 | return virt_to_page(pcpur_ptrs[cpu] + off); | 156 | return virt_to_page(pcpul_map[cpu].ptr + off); |
151 | } | 157 | } |
152 | 158 | ||
153 | static ssize_t __init setup_pcpu_remap(size_t static_size) | 159 | static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) |
154 | { | 160 | { |
155 | static struct vm_struct vm; | 161 | size_t map_size, dyn_size; |
156 | size_t ptrs_size, dyn_size; | ||
157 | unsigned int cpu; | 162 | unsigned int cpu; |
163 | int i, j; | ||
158 | ssize_t ret; | 164 | ssize_t ret; |
159 | 165 | ||
160 | /* | 166 | if (!chosen) { |
161 | * If large page isn't supported, there's no benefit in doing | 167 | size_t vm_size = VMALLOC_END - VMALLOC_START; |
162 | * this. Also, on non-NUMA, embedding is better. | 168 | size_t tot_size = num_possible_cpus() * PMD_SIZE; |
163 | * | 169 | |
164 | * NOTE: disabled for now. | 170 | /* on non-NUMA, embedding is better */ |
165 | */ | 171 | if (!pcpu_need_numa()) |
166 | if (true || !cpu_has_pse || !pcpu_need_numa()) | 172 | return -EINVAL; |
173 | |||
174 | /* don't consume more than 20% of vmalloc area */ | ||
175 | if (tot_size > vm_size / 5) { | ||
176 | pr_info("PERCPU: too large chunk size %zuMB for " | ||
177 | "large page remap\n", tot_size >> 20); | ||
178 | return -EINVAL; | ||
179 | } | ||
180 | } | ||
181 | |||
182 | /* need PSE */ | ||
183 | if (!cpu_has_pse) { | ||
184 | pr_warning("PERCPU: lpage allocator requires PSE\n"); | ||
167 | return -EINVAL; | 185 | return -EINVAL; |
186 | } | ||
168 | 187 | ||
169 | /* | 188 | /* |
170 | * Currently supports only single page. Supporting multiple | 189 | * Currently supports only single page. Supporting multiple |
171 | * pages won't be too difficult if it ever becomes necessary. | 190 | * pages won't be too difficult if it ever becomes necessary. |
172 | */ | 191 | */ |
173 | pcpur_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE + | 192 | pcpul_size = PFN_ALIGN(static_size + PERCPU_MODULE_RESERVE + |
174 | PERCPU_DYNAMIC_RESERVE); | 193 | PERCPU_DYNAMIC_RESERVE); |
175 | if (pcpur_size > PMD_SIZE) { | 194 | if (pcpul_size > PMD_SIZE) { |
176 | pr_warning("PERCPU: static data is larger than large page, " | 195 | pr_warning("PERCPU: static data is larger than large page, " |
177 | "can't use large page\n"); | 196 | "can't use large page\n"); |
178 | return -EINVAL; | 197 | return -EINVAL; |
179 | } | 198 | } |
180 | dyn_size = pcpur_size - static_size - PERCPU_FIRST_CHUNK_RESERVE; | 199 | dyn_size = pcpul_size - static_size - PERCPU_FIRST_CHUNK_RESERVE; |
181 | 200 | ||
182 | /* allocate pointer array and alloc large pages */ | 201 | /* allocate pointer array and alloc large pages */ |
183 | ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0])); | 202 | map_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpul_map[0])); |
184 | pcpur_ptrs = alloc_bootmem(ptrs_size); | 203 | pcpul_map = alloc_bootmem(map_size); |
185 | 204 | ||
186 | for_each_possible_cpu(cpu) { | 205 | for_each_possible_cpu(cpu) { |
187 | pcpur_ptrs[cpu] = pcpu_alloc_bootmem(cpu, PMD_SIZE, PMD_SIZE); | 206 | pcpul_map[cpu].cpu = cpu; |
188 | if (!pcpur_ptrs[cpu]) | 207 | pcpul_map[cpu].ptr = pcpu_alloc_bootmem(cpu, PMD_SIZE, |
208 | PMD_SIZE); | ||
209 | if (!pcpul_map[cpu].ptr) { | ||
210 | pr_warning("PERCPU: failed to allocate large page " | ||
211 | "for cpu%u\n", cpu); | ||
189 | goto enomem; | 212 | goto enomem; |
213 | } | ||
190 | 214 | ||
191 | /* | 215 | /* |
192 | * Only use pcpur_size bytes and give back the rest. | 216 | * Only use pcpul_size bytes and give back the rest. |
193 | * | 217 | * |
194 | * Ingo: The 2MB up-rounding bootmem is needed to make | 218 | * Ingo: The 2MB up-rounding bootmem is needed to make |
195 | * sure the partial 2MB page is still fully RAM - it's | 219 | * sure the partial 2MB page is still fully RAM - it's |
196 | * not well-specified to have a PAT-incompatible area | 220 | * not well-specified to have a PAT-incompatible area |
197 | * (unmapped RAM, device memory, etc.) in that hole. | 221 | * (unmapped RAM, device memory, etc.) in that hole. |
198 | */ | 222 | */ |
199 | free_bootmem(__pa(pcpur_ptrs[cpu] + pcpur_size), | 223 | free_bootmem(__pa(pcpul_map[cpu].ptr + pcpul_size), |
200 | PMD_SIZE - pcpur_size); | 224 | PMD_SIZE - pcpul_size); |
201 | 225 | ||
202 | memcpy(pcpur_ptrs[cpu], __per_cpu_load, static_size); | 226 | memcpy(pcpul_map[cpu].ptr, __per_cpu_load, static_size); |
203 | } | 227 | } |
204 | 228 | ||
205 | /* allocate address and map */ | 229 | /* allocate address and map */ |
206 | vm.flags = VM_ALLOC; | 230 | pcpul_vm.flags = VM_ALLOC; |
207 | vm.size = num_possible_cpus() * PMD_SIZE; | 231 | pcpul_vm.size = num_possible_cpus() * PMD_SIZE; |
208 | vm_area_register_early(&vm, PMD_SIZE); | 232 | vm_area_register_early(&pcpul_vm, PMD_SIZE); |
209 | 233 | ||
210 | for_each_possible_cpu(cpu) { | 234 | for_each_possible_cpu(cpu) { |
211 | pmd_t *pmd; | 235 | pmd_t *pmd, pmd_v; |
212 | 236 | ||
213 | pmd = populate_extra_pmd((unsigned long)vm.addr | 237 | pmd = populate_extra_pmd((unsigned long)pcpul_vm.addr + |
214 | + cpu * PMD_SIZE); | 238 | cpu * PMD_SIZE); |
215 | set_pmd(pmd, pfn_pmd(page_to_pfn(virt_to_page(pcpur_ptrs[cpu])), | 239 | pmd_v = pfn_pmd(page_to_pfn(virt_to_page(pcpul_map[cpu].ptr)), |
216 | PAGE_KERNEL_LARGE)); | 240 | PAGE_KERNEL_LARGE); |
241 | set_pmd(pmd, pmd_v); | ||
217 | } | 242 | } |
218 | 243 | ||
219 | /* we're ready, commit */ | 244 | /* we're ready, commit */ |
220 | pr_info("PERCPU: Remapped at %p with large pages, static data " | 245 | pr_info("PERCPU: Remapped at %p with large pages, static data " |
221 | "%zu bytes\n", vm.addr, static_size); | 246 | "%zu bytes\n", pcpul_vm.addr, static_size); |
222 | 247 | ||
223 | ret = pcpu_setup_first_chunk(pcpur_get_page, static_size, | 248 | ret = pcpu_setup_first_chunk(pcpul_get_page, static_size, |
224 | PERCPU_FIRST_CHUNK_RESERVE, dyn_size, | 249 | PERCPU_FIRST_CHUNK_RESERVE, dyn_size, |
225 | PMD_SIZE, vm.addr, NULL); | 250 | PMD_SIZE, pcpul_vm.addr, NULL); |
226 | goto out_free_ar; | 251 | |
252 | /* sort pcpul_map array for pcpu_lpage_remapped() */ | ||
253 | for (i = 0; i < num_possible_cpus() - 1; i++) | ||
254 | for (j = i + 1; j < num_possible_cpus(); j++) | ||
255 | if (pcpul_map[i].ptr > pcpul_map[j].ptr) { | ||
256 | struct pcpul_ent tmp = pcpul_map[i]; | ||
257 | pcpul_map[i] = pcpul_map[j]; | ||
258 | pcpul_map[j] = tmp; | ||
259 | } | ||
260 | |||
261 | return ret; | ||
227 | 262 | ||
228 | enomem: | 263 | enomem: |
229 | for_each_possible_cpu(cpu) | 264 | for_each_possible_cpu(cpu) |
230 | if (pcpur_ptrs[cpu]) | 265 | if (pcpul_map[cpu].ptr) |
231 | free_bootmem(__pa(pcpur_ptrs[cpu]), PMD_SIZE); | 266 | free_bootmem(__pa(pcpul_map[cpu].ptr), pcpul_size); |
232 | ret = -ENOMEM; | 267 | free_bootmem(__pa(pcpul_map), map_size); |
233 | out_free_ar: | 268 | return -ENOMEM; |
234 | free_bootmem(__pa(pcpur_ptrs), ptrs_size); | 269 | } |
235 | return ret; | 270 | |
271 | /** | ||
272 | * pcpu_lpage_remapped - determine whether a kaddr is in pcpul recycled area | ||
273 | * @kaddr: the kernel address in question | ||
274 | * | ||
275 | * Determine whether @kaddr falls in the pcpul recycled area. This is | ||
276 | * used by pageattr to detect VM aliases and break up the pcpu PMD | ||
277 | * mapping such that the same physical page is not mapped under | ||
278 | * different attributes. | ||
279 | * | ||
280 | * The recycled area is always at the tail of a partially used PMD | ||
281 | * page. | ||
282 | * | ||
283 | * RETURNS: | ||
284 | * Address of corresponding remapped pcpu address if match is found; | ||
285 | * otherwise, NULL. | ||
286 | */ | ||
287 | void *pcpu_lpage_remapped(void *kaddr) | ||
288 | { | ||
289 | void *pmd_addr = (void *)((unsigned long)kaddr & PMD_MASK); | ||
290 | unsigned long offset = (unsigned long)kaddr & ~PMD_MASK; | ||
291 | int left = 0, right = num_possible_cpus() - 1; | ||
292 | int pos; | ||
293 | |||
294 | /* pcpul in use at all? */ | ||
295 | if (!pcpul_map) | ||
296 | return NULL; | ||
297 | |||
298 | /* okay, perform binary search */ | ||
299 | while (left <= right) { | ||
300 | pos = (left + right) / 2; | ||
301 | |||
302 | if (pcpul_map[pos].ptr < pmd_addr) | ||
303 | left = pos + 1; | ||
304 | else if (pcpul_map[pos].ptr > pmd_addr) | ||
305 | right = pos - 1; | ||
306 | else { | ||
307 | /* it shouldn't be in the area for the first chunk */ | ||
308 | WARN_ON(offset < pcpul_size); | ||
309 | |||
310 | return pcpul_vm.addr + | ||
311 | pcpul_map[pos].cpu * PMD_SIZE + offset; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | return NULL; | ||
236 | } | 316 | } |
237 | #else | 317 | #else |
238 | static ssize_t __init setup_pcpu_remap(size_t static_size) | 318 | static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen) |
239 | { | 319 | { |
240 | return -EINVAL; | 320 | return -EINVAL; |
241 | } | 321 | } |
@@ -249,7 +329,7 @@ static ssize_t __init setup_pcpu_remap(size_t static_size) | |||
249 | * mapping so that it can use PMD mapping without additional TLB | 329 | * mapping so that it can use PMD mapping without additional TLB |
250 | * pressure. | 330 | * pressure. |
251 | */ | 331 | */ |
252 | static ssize_t __init setup_pcpu_embed(size_t static_size) | 332 | static ssize_t __init setup_pcpu_embed(size_t static_size, bool chosen) |
253 | { | 333 | { |
254 | size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; | 334 | size_t reserve = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE; |
255 | 335 | ||
@@ -258,7 +338,7 @@ static ssize_t __init setup_pcpu_embed(size_t static_size) | |||
258 | * this. Also, embedding allocation doesn't play well with | 338 | * this. Also, embedding allocation doesn't play well with |
259 | * NUMA. | 339 | * NUMA. |
260 | */ | 340 | */ |
261 | if (!cpu_has_pse || pcpu_need_numa()) | 341 | if (!chosen && (!cpu_has_pse || pcpu_need_numa())) |
262 | return -EINVAL; | 342 | return -EINVAL; |
263 | 343 | ||
264 | return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE, | 344 | return pcpu_embed_first_chunk(static_size, PERCPU_FIRST_CHUNK_RESERVE, |
@@ -308,8 +388,11 @@ static ssize_t __init setup_pcpu_4k(size_t static_size) | |||
308 | void *ptr; | 388 | void *ptr; |
309 | 389 | ||
310 | ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE); | 390 | ptr = pcpu_alloc_bootmem(cpu, PAGE_SIZE, PAGE_SIZE); |
311 | if (!ptr) | 391 | if (!ptr) { |
392 | pr_warning("PERCPU: failed to allocate " | ||
393 | "4k page for cpu%u\n", cpu); | ||
312 | goto enomem; | 394 | goto enomem; |
395 | } | ||
313 | 396 | ||
314 | memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); | 397 | memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE); |
315 | pcpu4k_pages[j++] = virt_to_page(ptr); | 398 | pcpu4k_pages[j++] = virt_to_page(ptr); |
@@ -333,6 +416,16 @@ out_free_ar: | |||
333 | return ret; | 416 | return ret; |
334 | } | 417 | } |
335 | 418 | ||
419 | /* for explicit first chunk allocator selection */ | ||
420 | static char pcpu_chosen_alloc[16] __initdata; | ||
421 | |||
422 | static int __init percpu_alloc_setup(char *str) | ||
423 | { | ||
424 | strncpy(pcpu_chosen_alloc, str, sizeof(pcpu_chosen_alloc) - 1); | ||
425 | return 0; | ||
426 | } | ||
427 | early_param("percpu_alloc", percpu_alloc_setup); | ||
428 | |||
336 | static inline void setup_percpu_segment(int cpu) | 429 | static inline void setup_percpu_segment(int cpu) |
337 | { | 430 | { |
338 | #ifdef CONFIG_X86_32 | 431 | #ifdef CONFIG_X86_32 |
@@ -346,11 +439,6 @@ static inline void setup_percpu_segment(int cpu) | |||
346 | #endif | 439 | #endif |
347 | } | 440 | } |
348 | 441 | ||
349 | /* | ||
350 | * Great future plan: | ||
351 | * Declare PDA itself and support (irqstack,tss,pgd) as per cpu data. | ||
352 | * Always point %gs to its beginning | ||
353 | */ | ||
354 | void __init setup_per_cpu_areas(void) | 442 | void __init setup_per_cpu_areas(void) |
355 | { | 443 | { |
356 | size_t static_size = __per_cpu_end - __per_cpu_start; | 444 | size_t static_size = __per_cpu_end - __per_cpu_start; |
@@ -367,9 +455,26 @@ void __init setup_per_cpu_areas(void) | |||
367 | * of large page mappings. Please read comments on top of | 455 | * of large page mappings. Please read comments on top of |
368 | * each allocator for details. | 456 | * each allocator for details. |
369 | */ | 457 | */ |
370 | ret = setup_pcpu_remap(static_size); | 458 | ret = -EINVAL; |
371 | if (ret < 0) | 459 | if (strlen(pcpu_chosen_alloc)) { |
372 | ret = setup_pcpu_embed(static_size); | 460 | if (strcmp(pcpu_chosen_alloc, "4k")) { |
461 | if (!strcmp(pcpu_chosen_alloc, "lpage")) | ||
462 | ret = setup_pcpu_lpage(static_size, true); | ||
463 | else if (!strcmp(pcpu_chosen_alloc, "embed")) | ||
464 | ret = setup_pcpu_embed(static_size, true); | ||
465 | else | ||
466 | pr_warning("PERCPU: unknown allocator %s " | ||
467 | "specified\n", pcpu_chosen_alloc); | ||
468 | if (ret < 0) | ||
469 | pr_warning("PERCPU: %s allocator failed (%zd), " | ||
470 | "falling back to 4k\n", | ||
471 | pcpu_chosen_alloc, ret); | ||
472 | } | ||
473 | } else { | ||
474 | ret = setup_pcpu_lpage(static_size, false); | ||
475 | if (ret < 0) | ||
476 | ret = setup_pcpu_embed(static_size, false); | ||
477 | } | ||
373 | if (ret < 0) | 478 | if (ret < 0) |
374 | ret = setup_pcpu_4k(static_size); | 479 | ret = setup_pcpu_4k(static_size); |
375 | if (ret < 0) | 480 | if (ret < 0) |
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c index 124d40c575df..8ccabb8a2f6a 100644 --- a/arch/x86/kernel/tlb_uv.c +++ b/arch/x86/kernel/tlb_uv.c | |||
@@ -711,7 +711,6 @@ uv_activation_descriptor_init(int node, int pnode) | |||
711 | unsigned long pa; | 711 | unsigned long pa; |
712 | unsigned long m; | 712 | unsigned long m; |
713 | unsigned long n; | 713 | unsigned long n; |
714 | unsigned long mmr_image; | ||
715 | struct bau_desc *adp; | 714 | struct bau_desc *adp; |
716 | struct bau_desc *ad2; | 715 | struct bau_desc *ad2; |
717 | 716 | ||
@@ -727,12 +726,8 @@ uv_activation_descriptor_init(int node, int pnode) | |||
727 | n = pa >> uv_nshift; | 726 | n = pa >> uv_nshift; |
728 | m = pa & uv_mmask; | 727 | m = pa & uv_mmask; |
729 | 728 | ||
730 | mmr_image = uv_read_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE); | 729 | uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, |
731 | if (mmr_image) { | 730 | (n << UV_DESC_BASE_PNODE_SHIFT | m)); |
732 | uv_write_global_mmr64(pnode, (unsigned long) | ||
733 | UVH_LB_BAU_SB_DESCRIPTOR_BASE, | ||
734 | (n << UV_DESC_BASE_PNODE_SHIFT | m)); | ||
735 | } | ||
736 | 731 | ||
737 | /* | 732 | /* |
738 | * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each | 733 | * initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index a0f48f5671c0..5204332f475d 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -346,6 +346,9 @@ io_check_error(unsigned char reason, struct pt_regs *regs) | |||
346 | printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); | 346 | printk(KERN_EMERG "NMI: IOCK error (debug interrupt?)\n"); |
347 | show_registers(regs); | 347 | show_registers(regs); |
348 | 348 | ||
349 | if (panic_on_io_nmi) | ||
350 | panic("NMI IOCK error: Not continuing"); | ||
351 | |||
349 | /* Re-enable the IOCK line, wait for a few seconds */ | 352 | /* Re-enable the IOCK line, wait for a few seconds */ |
350 | reason = (reason & 0xf) | 8; | 353 | reason = (reason & 0xf) | 8; |
351 | outb(reason, 0x61); | 354 | outb(reason, 0x61); |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 5c3d6e81a7dc..7030b5f911bf 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -2157,7 +2157,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
2157 | else | 2157 | else |
2158 | /* 32 bits PSE 4MB page */ | 2158 | /* 32 bits PSE 4MB page */ |
2159 | context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); | 2159 | context->rsvd_bits_mask[1][1] = rsvd_bits(13, 21); |
2160 | context->rsvd_bits_mask[1][0] = ~0ull; | 2160 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; |
2161 | break; | 2161 | break; |
2162 | case PT32E_ROOT_LEVEL: | 2162 | case PT32E_ROOT_LEVEL: |
2163 | context->rsvd_bits_mask[0][2] = | 2163 | context->rsvd_bits_mask[0][2] = |
@@ -2170,7 +2170,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
2170 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | | 2170 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | |
2171 | rsvd_bits(maxphyaddr, 62) | | 2171 | rsvd_bits(maxphyaddr, 62) | |
2172 | rsvd_bits(13, 20); /* large page */ | 2172 | rsvd_bits(13, 20); /* large page */ |
2173 | context->rsvd_bits_mask[1][0] = ~0ull; | 2173 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; |
2174 | break; | 2174 | break; |
2175 | case PT64_ROOT_LEVEL: | 2175 | case PT64_ROOT_LEVEL: |
2176 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | | 2176 | context->rsvd_bits_mask[0][3] = exb_bit_rsvd | |
@@ -2186,7 +2186,7 @@ static void reset_rsvds_bits_mask(struct kvm_vcpu *vcpu, int level) | |||
2186 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | | 2186 | context->rsvd_bits_mask[1][1] = exb_bit_rsvd | |
2187 | rsvd_bits(maxphyaddr, 51) | | 2187 | rsvd_bits(maxphyaddr, 51) | |
2188 | rsvd_bits(13, 20); /* large page */ | 2188 | rsvd_bits(13, 20); /* large page */ |
2189 | context->rsvd_bits_mask[1][0] = ~0ull; | 2189 | context->rsvd_bits_mask[1][0] = context->rsvd_bits_mask[1][0]; |
2190 | break; | 2190 | break; |
2191 | } | 2191 | } |
2192 | } | 2192 | } |
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 258e4591e1ca..67785f635399 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
@@ -281,7 +281,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | |||
281 | { | 281 | { |
282 | unsigned access = gw->pt_access; | 282 | unsigned access = gw->pt_access; |
283 | struct kvm_mmu_page *shadow_page; | 283 | struct kvm_mmu_page *shadow_page; |
284 | u64 spte, *sptep; | 284 | u64 spte, *sptep = NULL; |
285 | int direct; | 285 | int direct; |
286 | gfn_t table_gfn; | 286 | gfn_t table_gfn; |
287 | int r; | 287 | int r; |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e770bf349ec4..356a0ce85c68 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -3012,6 +3012,12 @@ static int handle_vmcall(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
3012 | return 1; | 3012 | return 1; |
3013 | } | 3013 | } |
3014 | 3014 | ||
3015 | static int handle_vmx_insn(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
3016 | { | ||
3017 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
3018 | return 1; | ||
3019 | } | ||
3020 | |||
3015 | static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | 3021 | static int handle_invlpg(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) |
3016 | { | 3022 | { |
3017 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | 3023 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
@@ -3198,6 +3204,15 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, | |||
3198 | [EXIT_REASON_HLT] = handle_halt, | 3204 | [EXIT_REASON_HLT] = handle_halt, |
3199 | [EXIT_REASON_INVLPG] = handle_invlpg, | 3205 | [EXIT_REASON_INVLPG] = handle_invlpg, |
3200 | [EXIT_REASON_VMCALL] = handle_vmcall, | 3206 | [EXIT_REASON_VMCALL] = handle_vmcall, |
3207 | [EXIT_REASON_VMCLEAR] = handle_vmx_insn, | ||
3208 | [EXIT_REASON_VMLAUNCH] = handle_vmx_insn, | ||
3209 | [EXIT_REASON_VMPTRLD] = handle_vmx_insn, | ||
3210 | [EXIT_REASON_VMPTRST] = handle_vmx_insn, | ||
3211 | [EXIT_REASON_VMREAD] = handle_vmx_insn, | ||
3212 | [EXIT_REASON_VMRESUME] = handle_vmx_insn, | ||
3213 | [EXIT_REASON_VMWRITE] = handle_vmx_insn, | ||
3214 | [EXIT_REASON_VMOFF] = handle_vmx_insn, | ||
3215 | [EXIT_REASON_VMON] = handle_vmx_insn, | ||
3201 | [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, | 3216 | [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, |
3202 | [EXIT_REASON_APIC_ACCESS] = handle_apic_access, | 3217 | [EXIT_REASON_APIC_ACCESS] = handle_apic_access, |
3203 | [EXIT_REASON_WBINVD] = handle_wbinvd, | 3218 | [EXIT_REASON_WBINVD] = handle_wbinvd, |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 249540f98513..fe5474aec41a 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -898,6 +898,7 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
898 | case MSR_VM_HSAVE_PA: | 898 | case MSR_VM_HSAVE_PA: |
899 | case MSR_P6_EVNTSEL0: | 899 | case MSR_P6_EVNTSEL0: |
900 | case MSR_P6_EVNTSEL1: | 900 | case MSR_P6_EVNTSEL1: |
901 | case MSR_K7_EVNTSEL0: | ||
901 | data = 0; | 902 | data = 0; |
902 | break; | 903 | break; |
903 | case MSR_MTRRcap: | 904 | case MSR_MTRRcap: |
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index c1b6c232e02b..616de4628d60 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -1361,7 +1361,7 @@ static inline int writeback(struct x86_emulate_ctxt *ctxt, | |||
1361 | return 0; | 1361 | return 0; |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) | 1364 | static void toggle_interruptibility(struct x86_emulate_ctxt *ctxt, u32 mask) |
1365 | { | 1365 | { |
1366 | u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask); | 1366 | u32 int_shadow = kvm_x86_ops->get_interrupt_shadow(ctxt->vcpu, mask); |
1367 | /* | 1367 | /* |
diff --git a/arch/x86/lib/delay.c b/arch/x86/lib/delay.c index f4568605d7d5..ff485d361182 100644 --- a/arch/x86/lib/delay.c +++ b/arch/x86/lib/delay.c | |||
@@ -55,8 +55,10 @@ static void delay_tsc(unsigned long loops) | |||
55 | 55 | ||
56 | preempt_disable(); | 56 | preempt_disable(); |
57 | cpu = smp_processor_id(); | 57 | cpu = smp_processor_id(); |
58 | rdtsc_barrier(); | ||
58 | rdtscl(bclock); | 59 | rdtscl(bclock); |
59 | for (;;) { | 60 | for (;;) { |
61 | rdtsc_barrier(); | ||
60 | rdtscl(now); | 62 | rdtscl(now); |
61 | if ((now - bclock) >= loops) | 63 | if ((now - bclock) >= loops) |
62 | break; | 64 | break; |
@@ -78,6 +80,7 @@ static void delay_tsc(unsigned long loops) | |||
78 | if (unlikely(cpu != smp_processor_id())) { | 80 | if (unlikely(cpu != smp_processor_id())) { |
79 | loops -= (now - bclock); | 81 | loops -= (now - bclock); |
80 | cpu = smp_processor_id(); | 82 | cpu = smp_processor_id(); |
83 | rdtsc_barrier(); | ||
81 | rdtscl(bclock); | 84 | rdtscl(bclock); |
82 | } | 85 | } |
83 | } | 86 | } |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index f53b57e4086f..47ce9a2ce5e7 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
@@ -177,20 +177,6 @@ static int __meminit save_mr(struct map_range *mr, int nr_range, | |||
177 | return nr_range; | 177 | return nr_range; |
178 | } | 178 | } |
179 | 179 | ||
180 | #ifdef CONFIG_X86_64 | ||
181 | static void __init init_gbpages(void) | ||
182 | { | ||
183 | if (direct_gbpages && cpu_has_gbpages) | ||
184 | printk(KERN_INFO "Using GB pages for direct mapping\n"); | ||
185 | else | ||
186 | direct_gbpages = 0; | ||
187 | } | ||
188 | #else | ||
189 | static inline void init_gbpages(void) | ||
190 | { | ||
191 | } | ||
192 | #endif | ||
193 | |||
194 | /* | 180 | /* |
195 | * Setup the direct mapping of the physical memory at PAGE_OFFSET. | 181 | * Setup the direct mapping of the physical memory at PAGE_OFFSET. |
196 | * This runs before bootmem is initialized and gets pages directly from | 182 | * This runs before bootmem is initialized and gets pages directly from |
@@ -210,9 +196,6 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, | |||
210 | 196 | ||
211 | printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); | 197 | printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); |
212 | 198 | ||
213 | if (!after_bootmem) | ||
214 | init_gbpages(); | ||
215 | |||
216 | #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK) | 199 | #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK) |
217 | /* | 200 | /* |
218 | * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages. | 201 | * For CONFIG_DEBUG_PAGEALLOC, identity mapping will use small pages. |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 3cfe9ced8a4c..1b734d7a8966 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/interrupt.h> | 11 | #include <linux/interrupt.h> |
12 | #include <linux/seq_file.h> | 12 | #include <linux/seq_file.h> |
13 | #include <linux/debugfs.h> | 13 | #include <linux/debugfs.h> |
14 | #include <linux/pfn.h> | ||
14 | 15 | ||
15 | #include <asm/e820.h> | 16 | #include <asm/e820.h> |
16 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
@@ -681,8 +682,9 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias); | |||
681 | static int cpa_process_alias(struct cpa_data *cpa) | 682 | static int cpa_process_alias(struct cpa_data *cpa) |
682 | { | 683 | { |
683 | struct cpa_data alias_cpa; | 684 | struct cpa_data alias_cpa; |
684 | int ret = 0; | 685 | unsigned long laddr = (unsigned long)__va(cpa->pfn << PAGE_SHIFT); |
685 | unsigned long temp_cpa_vaddr, vaddr; | 686 | unsigned long vaddr, remapped; |
687 | int ret; | ||
686 | 688 | ||
687 | if (cpa->pfn >= max_pfn_mapped) | 689 | if (cpa->pfn >= max_pfn_mapped) |
688 | return 0; | 690 | return 0; |
@@ -706,42 +708,55 @@ static int cpa_process_alias(struct cpa_data *cpa) | |||
706 | PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { | 708 | PAGE_OFFSET + (max_pfn_mapped << PAGE_SHIFT)))) { |
707 | 709 | ||
708 | alias_cpa = *cpa; | 710 | alias_cpa = *cpa; |
709 | temp_cpa_vaddr = (unsigned long) __va(cpa->pfn << PAGE_SHIFT); | 711 | alias_cpa.vaddr = &laddr; |
710 | alias_cpa.vaddr = &temp_cpa_vaddr; | ||
711 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | 712 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); |
712 | 713 | ||
713 | |||
714 | ret = __change_page_attr_set_clr(&alias_cpa, 0); | 714 | ret = __change_page_attr_set_clr(&alias_cpa, 0); |
715 | if (ret) | ||
716 | return ret; | ||
715 | } | 717 | } |
716 | 718 | ||
717 | #ifdef CONFIG_X86_64 | 719 | #ifdef CONFIG_X86_64 |
718 | if (ret) | ||
719 | return ret; | ||
720 | /* | 720 | /* |
721 | * No need to redo, when the primary call touched the high | 721 | * If the primary call didn't touch the high mapping already |
722 | * mapping already: | 722 | * and the physical address is inside the kernel map, we need |
723 | */ | ||
724 | if (within(vaddr, (unsigned long) _text, _brk_end)) | ||
725 | return 0; | ||
726 | |||
727 | /* | ||
728 | * If the physical address is inside the kernel map, we need | ||
729 | * to touch the high mapped kernel as well: | 723 | * to touch the high mapped kernel as well: |
730 | */ | 724 | */ |
731 | if (!within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) | 725 | if (!within(vaddr, (unsigned long)_text, _brk_end) && |
732 | return 0; | 726 | within(cpa->pfn, highmap_start_pfn(), highmap_end_pfn())) { |
727 | unsigned long temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + | ||
728 | __START_KERNEL_map - phys_base; | ||
729 | alias_cpa = *cpa; | ||
730 | alias_cpa.vaddr = &temp_cpa_vaddr; | ||
731 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | ||
733 | 732 | ||
734 | alias_cpa = *cpa; | 733 | /* |
735 | temp_cpa_vaddr = (cpa->pfn << PAGE_SHIFT) + __START_KERNEL_map - phys_base; | 734 | * The high mapping range is imprecise, so ignore the |
736 | alias_cpa.vaddr = &temp_cpa_vaddr; | 735 | * return value. |
737 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | 736 | */ |
737 | __change_page_attr_set_clr(&alias_cpa, 0); | ||
738 | } | ||
739 | #endif | ||
738 | 740 | ||
739 | /* | 741 | /* |
740 | * The high mapping range is imprecise, so ignore the return value. | 742 | * If the PMD page was partially used for per-cpu remapping, |
743 | * the recycled area needs to be split and modified. Because | ||
744 | * the area is always proper subset of a PMD page | ||
745 | * cpa->numpages is guaranteed to be 1 for these areas, so | ||
746 | * there's no need to loop over and check for further remaps. | ||
741 | */ | 747 | */ |
742 | __change_page_attr_set_clr(&alias_cpa, 0); | 748 | remapped = (unsigned long)pcpu_lpage_remapped((void *)laddr); |
743 | #endif | 749 | if (remapped) { |
744 | return ret; | 750 | WARN_ON(cpa->numpages > 1); |
751 | alias_cpa = *cpa; | ||
752 | alias_cpa.vaddr = &remapped; | ||
753 | alias_cpa.flags &= ~(CPA_PAGES_ARRAY | CPA_ARRAY); | ||
754 | ret = __change_page_attr_set_clr(&alias_cpa, 0); | ||
755 | if (ret) | ||
756 | return ret; | ||
757 | } | ||
758 | |||
759 | return 0; | ||
745 | } | 760 | } |
746 | 761 | ||
747 | static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) | 762 | static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias) |
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index d277ef1eea51..b3d20b9cac63 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c | |||
@@ -244,7 +244,7 @@ static void __restore_processor_state(struct saved_context *ctxt) | |||
244 | do_fpu_end(); | 244 | do_fpu_end(); |
245 | mtrr_ap_init(); | 245 | mtrr_ap_init(); |
246 | 246 | ||
247 | #ifdef CONFIG_X86_32 | 247 | #ifdef CONFIG_X86_OLD_MCE |
248 | mcheck_init(&boot_cpu_data); | 248 | mcheck_init(&boot_cpu_data); |
249 | #endif | 249 | #endif |
250 | } | 250 | } |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 8a5bf3b356fa..55b5b90c2a44 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -395,7 +395,7 @@ struct pci_dev *acpi_get_pci_dev(acpi_handle handle) | |||
395 | fn = adr & 0xffff; | 395 | fn = adr & 0xffff; |
396 | 396 | ||
397 | pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); | 397 | pdev = pci_get_slot(pbus, PCI_DEVFN(dev, fn)); |
398 | if (hnd == handle) | 398 | if (!pdev || hnd == handle) |
399 | break; | 399 | break; |
400 | 400 | ||
401 | pbus = pdev->subordinate; | 401 | pbus = pdev->subordinate; |
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 140ea10ecb88..c02db01f736e 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/cdev.h> | 27 | #include <linux/cdev.h> |
28 | #include <linux/list.h> | 28 | #include <linux/list.h> |
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <asm/pgtable.h> | ||
30 | #include <asm/io.h> | 31 | #include <asm/io.h> |
31 | 32 | ||
32 | /* | 33 | /* |
@@ -75,12 +76,13 @@ static struct class *bsr_class; | |||
75 | static int bsr_major; | 76 | static int bsr_major; |
76 | 77 | ||
77 | enum { | 78 | enum { |
78 | BSR_8 = 0, | 79 | BSR_8 = 0, |
79 | BSR_16 = 1, | 80 | BSR_16 = 1, |
80 | BSR_64 = 2, | 81 | BSR_64 = 2, |
81 | BSR_128 = 3, | 82 | BSR_128 = 3, |
82 | BSR_UNKNOWN = 4, | 83 | BSR_4096 = 4, |
83 | BSR_MAX = 5, | 84 | BSR_UNKNOWN = 5, |
85 | BSR_MAX = 6, | ||
84 | }; | 86 | }; |
85 | 87 | ||
86 | static unsigned bsr_types[BSR_MAX]; | 88 | static unsigned bsr_types[BSR_MAX]; |
@@ -117,15 +119,22 @@ static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) | |||
117 | { | 119 | { |
118 | unsigned long size = vma->vm_end - vma->vm_start; | 120 | unsigned long size = vma->vm_end - vma->vm_start; |
119 | struct bsr_dev *dev = filp->private_data; | 121 | struct bsr_dev *dev = filp->private_data; |
122 | int ret; | ||
120 | 123 | ||
121 | if (size > dev->bsr_len || (size & (PAGE_SIZE-1))) | ||
122 | return -EINVAL; | ||
123 | |||
124 | vma->vm_flags |= (VM_IO | VM_DONTEXPAND); | ||
125 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 124 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
126 | 125 | ||
127 | if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT, | 126 | /* check for the case of a small BSR device and map one 4k page for it*/ |
128 | size, vma->vm_page_prot)) | 127 | if (dev->bsr_len < PAGE_SIZE && size == PAGE_SIZE) |
128 | ret = remap_4k_pfn(vma, vma->vm_start, dev->bsr_addr >> 12, | ||
129 | vma->vm_page_prot); | ||
130 | else if (size <= dev->bsr_len) | ||
131 | ret = io_remap_pfn_range(vma, vma->vm_start, | ||
132 | dev->bsr_addr >> PAGE_SHIFT, | ||
133 | size, vma->vm_page_prot); | ||
134 | else | ||
135 | return -EINVAL; | ||
136 | |||
137 | if (ret) | ||
129 | return -EAGAIN; | 138 | return -EAGAIN; |
130 | 139 | ||
131 | return 0; | 140 | return 0; |
@@ -205,6 +214,11 @@ static int bsr_add_node(struct device_node *bn) | |||
205 | cur->bsr_stride = bsr_stride[i]; | 214 | cur->bsr_stride = bsr_stride[i]; |
206 | cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs); | 215 | cur->bsr_dev = MKDEV(bsr_major, i + total_bsr_devs); |
207 | 216 | ||
217 | /* if we have a bsr_len of > 4k and less then PAGE_SIZE (64k pages) */ | ||
218 | /* we can only map 4k of it, so only advertise the 4k in sysfs */ | ||
219 | if (cur->bsr_len > 4096 && cur->bsr_len < PAGE_SIZE) | ||
220 | cur->bsr_len = 4096; | ||
221 | |||
208 | switch(cur->bsr_bytes) { | 222 | switch(cur->bsr_bytes) { |
209 | case 8: | 223 | case 8: |
210 | cur->bsr_type = BSR_8; | 224 | cur->bsr_type = BSR_8; |
@@ -218,9 +232,11 @@ static int bsr_add_node(struct device_node *bn) | |||
218 | case 128: | 232 | case 128: |
219 | cur->bsr_type = BSR_128; | 233 | cur->bsr_type = BSR_128; |
220 | break; | 234 | break; |
235 | case 4096: | ||
236 | cur->bsr_type = BSR_4096; | ||
237 | break; | ||
221 | default: | 238 | default: |
222 | cur->bsr_type = BSR_UNKNOWN; | 239 | cur->bsr_type = BSR_UNKNOWN; |
223 | printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes); | ||
224 | } | 240 | } |
225 | 241 | ||
226 | cur->bsr_num = bsr_types[cur->bsr_type]; | 242 | cur->bsr_num = bsr_types[cur->bsr_type]; |
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c index a19e935847b0..913aa8d3f1c5 100644 --- a/drivers/char/tty_ldisc.c +++ b/drivers/char/tty_ldisc.c | |||
@@ -867,15 +867,22 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
867 | tty_ldisc_wait_idle(tty); | 867 | tty_ldisc_wait_idle(tty); |
868 | 868 | ||
869 | /* | 869 | /* |
870 | * Shutdown the current line discipline, and reset it to N_TTY. | 870 | * Now kill off the ldisc |
871 | * | ||
872 | * FIXME: this MUST get fixed for the new reflocking | ||
873 | */ | 871 | */ |
872 | tty_ldisc_close(tty, tty->ldisc); | ||
873 | tty_ldisc_put(tty->ldisc); | ||
874 | /* Force an oops if we mess this up */ | ||
875 | tty->ldisc = NULL; | ||
876 | |||
877 | /* Ensure the next open requests the N_TTY ldisc */ | ||
878 | tty_set_termios_ldisc(tty, N_TTY); | ||
874 | 879 | ||
875 | tty_ldisc_reinit(tty); | ||
876 | /* This will need doing differently if we need to lock */ | 880 | /* This will need doing differently if we need to lock */ |
877 | if (o_tty) | 881 | if (o_tty) |
878 | tty_ldisc_release(o_tty, NULL); | 882 | tty_ldisc_release(o_tty, NULL); |
883 | |||
884 | /* And the memory resources remaining (buffers, termios) will be | ||
885 | disposed of when the kref hits zero */ | ||
879 | } | 886 | } |
880 | 887 | ||
881 | /** | 888 | /** |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index c36bf40568cf..858fe6037223 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -754,13 +754,13 @@ static void amd64_cpu_display_info(struct amd64_pvt *pvt) | |||
754 | static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt) | 754 | static enum edac_type amd64_determine_edac_cap(struct amd64_pvt *pvt) |
755 | { | 755 | { |
756 | int bit; | 756 | int bit; |
757 | enum dev_type edac_cap = EDAC_NONE; | 757 | enum dev_type edac_cap = EDAC_FLAG_NONE; |
758 | 758 | ||
759 | bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F) | 759 | bit = (boot_cpu_data.x86 > 0xf || pvt->ext_model >= OPTERON_CPU_REV_F) |
760 | ? 19 | 760 | ? 19 |
761 | : 17; | 761 | : 17; |
762 | 762 | ||
763 | if (pvt->dclr0 >> BIT(bit)) | 763 | if (pvt->dclr0 & BIT(bit)) |
764 | edac_cap = EDAC_FLAG_SECDED; | 764 | edac_cap = EDAC_FLAG_SECDED; |
765 | 765 | ||
766 | return edac_cap; | 766 | return edac_cap; |
@@ -1269,7 +1269,7 @@ static int f10_early_channel_count(struct amd64_pvt *pvt) | |||
1269 | if (channels == 0) | 1269 | if (channels == 0) |
1270 | channels = 1; | 1270 | channels = 1; |
1271 | 1271 | ||
1272 | debugf0("DIMM count= %d\n", channels); | 1272 | debugf0("MCT channel count: %d\n", channels); |
1273 | 1273 | ||
1274 | return channels; | 1274 | return channels; |
1275 | 1275 | ||
@@ -2966,7 +2966,12 @@ static int amd64_check_ecc_enabled(struct amd64_pvt *pvt) | |||
2966 | " Use of the override can cause " | 2966 | " Use of the override can cause " |
2967 | "unknown side effects.\n"); | 2967 | "unknown side effects.\n"); |
2968 | ret = -ENODEV; | 2968 | ret = -ENODEV; |
2969 | } | 2969 | } else |
2970 | /* | ||
2971 | * enable further driver loading if ECC enable is | ||
2972 | * overridden. | ||
2973 | */ | ||
2974 | ret = 0; | ||
2970 | } else { | 2975 | } else { |
2971 | amd64_printk(KERN_INFO, | 2976 | amd64_printk(KERN_INFO, |
2972 | "ECC is enabled by BIOS, Proceeding " | 2977 | "ECC is enabled by BIOS, Proceeding " |
@@ -3006,7 +3011,6 @@ static void amd64_setup_mci_misc_attributes(struct mem_ctl_info *mci) | |||
3006 | 3011 | ||
3007 | mci->mtype_cap = MEM_FLAG_DDR2 | MEM_FLAG_RDDR2; | 3012 | mci->mtype_cap = MEM_FLAG_DDR2 | MEM_FLAG_RDDR2; |
3008 | mci->edac_ctl_cap = EDAC_FLAG_NONE; | 3013 | mci->edac_ctl_cap = EDAC_FLAG_NONE; |
3009 | mci->edac_cap = EDAC_FLAG_NONE; | ||
3010 | 3014 | ||
3011 | if (pvt->nbcap & K8_NBCAP_SECDED) | 3015 | if (pvt->nbcap & K8_NBCAP_SECDED) |
3012 | mci->edac_ctl_cap |= EDAC_FLAG_SECDED; | 3016 | mci->edac_ctl_cap |= EDAC_FLAG_SECDED; |
@@ -3052,7 +3056,7 @@ static int amd64_probe_one_instance(struct pci_dev *dram_f2_ctl, | |||
3052 | if (!pvt) | 3056 | if (!pvt) |
3053 | goto err_exit; | 3057 | goto err_exit; |
3054 | 3058 | ||
3055 | pvt->mc_node_id = get_mc_node_id_from_pdev(dram_f2_ctl); | 3059 | pvt->mc_node_id = get_node_id(dram_f2_ctl); |
3056 | 3060 | ||
3057 | pvt->dram_f2_ctl = dram_f2_ctl; | 3061 | pvt->dram_f2_ctl = dram_f2_ctl; |
3058 | pvt->ext_model = boot_cpu_data.x86_model >> 4; | 3062 | pvt->ext_model = boot_cpu_data.x86_model >> 4; |
@@ -3179,8 +3183,7 @@ static int __devinit amd64_init_one_instance(struct pci_dev *pdev, | |||
3179 | { | 3183 | { |
3180 | int ret = 0; | 3184 | int ret = 0; |
3181 | 3185 | ||
3182 | debugf0("(MC node=%d,mc_type='%s')\n", | 3186 | debugf0("(MC node=%d,mc_type='%s')\n", get_node_id(pdev), |
3183 | get_mc_node_id_from_pdev(pdev), | ||
3184 | get_amd_family_name(mc_type->driver_data)); | 3187 | get_amd_family_name(mc_type->driver_data)); |
3185 | 3188 | ||
3186 | ret = pci_enable_device(pdev); | 3189 | ret = pci_enable_device(pdev); |
@@ -3319,15 +3322,17 @@ static int __init amd64_edac_init(void) | |||
3319 | 3322 | ||
3320 | err = amd64_init_2nd_stage(pvt_lookup[nb]); | 3323 | err = amd64_init_2nd_stage(pvt_lookup[nb]); |
3321 | if (err) | 3324 | if (err) |
3322 | goto err_exit; | 3325 | goto err_2nd_stage; |
3323 | } | 3326 | } |
3324 | 3327 | ||
3325 | amd64_setup_pci_device(); | 3328 | amd64_setup_pci_device(); |
3326 | 3329 | ||
3327 | return 0; | 3330 | return 0; |
3328 | 3331 | ||
3332 | err_2nd_stage: | ||
3333 | debugf0("2nd stage failed\n"); | ||
3334 | |||
3329 | err_exit: | 3335 | err_exit: |
3330 | debugf0("'finish_setup' stage failed\n"); | ||
3331 | pci_unregister_driver(&amd64_pci_driver); | 3336 | pci_unregister_driver(&amd64_pci_driver); |
3332 | 3337 | ||
3333 | return err; | 3338 | return err; |
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index a159957e167b..ba73015af8e4 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -444,7 +444,7 @@ enum { | |||
444 | #define K8_MSR_MC4ADDR 0x0412 | 444 | #define K8_MSR_MC4ADDR 0x0412 |
445 | 445 | ||
446 | /* AMD sets the first MC device at device ID 0x18. */ | 446 | /* AMD sets the first MC device at device ID 0x18. */ |
447 | static inline int get_mc_node_id_from_pdev(struct pci_dev *pdev) | 447 | static inline int get_node_id(struct pci_dev *pdev) |
448 | { | 448 | { |
449 | return PCI_SLOT(pdev->devfn) - 0x18; | 449 | return PCI_SLOT(pdev->devfn) - 0x18; |
450 | } | 450 | } |
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index c961fe415aef..39b393d38bb3 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -81,6 +81,7 @@ config DRM_I830 | |||
81 | 81 | ||
82 | config DRM_I915 | 82 | config DRM_I915 |
83 | tristate "i915 driver" | 83 | tristate "i915 driver" |
84 | depends on AGP_INTEL | ||
84 | select FB_CFB_FILLRECT | 85 | select FB_CFB_FILLRECT |
85 | select FB_CFB_COPYAREA | 86 | select FB_CFB_COPYAREA |
86 | select FB_CFB_IMAGEBLIT | 87 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 4e89ab08b7b8..fe23f29f7cba 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -16,6 +16,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ | |||
16 | drm-$(CONFIG_COMPAT) += drm_ioc32.o | 16 | drm-$(CONFIG_COMPAT) += drm_ioc32.o |
17 | 17 | ||
18 | obj-$(CONFIG_DRM) += drm.o | 18 | obj-$(CONFIG_DRM) += drm.o |
19 | obj-$(CONFIG_DRM_TTM) += ttm/ | ||
19 | obj-$(CONFIG_DRM_TDFX) += tdfx/ | 20 | obj-$(CONFIG_DRM_TDFX) += tdfx/ |
20 | obj-$(CONFIG_DRM_R128) += r128/ | 21 | obj-$(CONFIG_DRM_R128) += r128/ |
21 | obj-$(CONFIG_DRM_RADEON)+= radeon/ | 22 | obj-$(CONFIG_DRM_RADEON)+= radeon/ |
@@ -26,4 +27,3 @@ obj-$(CONFIG_DRM_I915) += i915/ | |||
26 | obj-$(CONFIG_DRM_SIS) += sis/ | 27 | obj-$(CONFIG_DRM_SIS) += sis/ |
27 | obj-$(CONFIG_DRM_SAVAGE)+= savage/ | 28 | obj-$(CONFIG_DRM_SAVAGE)+= savage/ |
28 | obj-$(CONFIG_DRM_VIA) +=via/ | 29 | obj-$(CONFIG_DRM_VIA) +=via/ |
29 | obj-$(CONFIG_DRM_TTM) += ttm/ | ||
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 7d0835226f6e..80cc6d06d61b 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -294,10 +294,10 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
294 | unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; | 294 | unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; |
295 | unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; | 295 | unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; |
296 | unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; | 296 | unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; |
297 | unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 8 | pt->hsync_offset_lo; | 297 | unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) << 2 | pt->hsync_offset_lo; |
298 | unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 6 | pt->hsync_pulse_width_lo; | 298 | unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) << 4 | pt->hsync_pulse_width_lo; |
299 | unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) | (pt->vsync_offset_pulse_width_lo & 0xf); | 299 | unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; |
300 | unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; | 300 | unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 4 | (pt->vsync_offset_pulse_width_lo & 0xf); |
301 | 301 | ||
302 | /* ignore tiny modes */ | 302 | /* ignore tiny modes */ |
303 | if (hactive < 64 || vactive < 64) | 303 | if (hactive < 64 || vactive < 64) |
@@ -347,8 +347,8 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
347 | mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? | 347 | mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? |
348 | DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; | 348 | DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; |
349 | 349 | ||
350 | mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; | 350 | mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; |
351 | mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; | 351 | mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; |
352 | 352 | ||
353 | if (quirks & EDID_QUIRK_DETAILED_IN_CM) { | 353 | if (quirks & EDID_QUIRK_DETAILED_IN_CM) { |
354 | mode->width_mm *= 10; | 354 | mode->width_mm *= 10; |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 51c5a050aa73..30d6b99fb302 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -13,6 +13,8 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
13 | intel_crt.o \ | 13 | intel_crt.o \ |
14 | intel_lvds.o \ | 14 | intel_lvds.o \ |
15 | intel_bios.o \ | 15 | intel_bios.o \ |
16 | intel_dp.o \ | ||
17 | intel_dp_i2c.o \ | ||
16 | intel_hdmi.o \ | 18 | intel_hdmi.o \ |
17 | intel_sdvo.o \ | 19 | intel_sdvo.o \ |
18 | intel_modes.o \ | 20 | intel_modes.o \ |
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index e747ac42fe3a..288fc50627e2 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
@@ -37,7 +37,7 @@ struct intel_dvo_device { | |||
37 | /* GPIO register used for i2c bus to control this device */ | 37 | /* GPIO register used for i2c bus to control this device */ |
38 | u32 gpio; | 38 | u32 gpio; |
39 | int slave_addr; | 39 | int slave_addr; |
40 | struct intel_i2c_chan *i2c_bus; | 40 | struct i2c_adapter *i2c_bus; |
41 | 41 | ||
42 | const struct intel_dvo_dev_ops *dev_ops; | 42 | const struct intel_dvo_dev_ops *dev_ops; |
43 | void *dev_priv; | 43 | void *dev_priv; |
@@ -52,7 +52,7 @@ struct intel_dvo_dev_ops { | |||
52 | * Returns NULL if the device does not exist. | 52 | * Returns NULL if the device does not exist. |
53 | */ | 53 | */ |
54 | bool (*init)(struct intel_dvo_device *dvo, | 54 | bool (*init)(struct intel_dvo_device *dvo, |
55 | struct intel_i2c_chan *i2cbus); | 55 | struct i2c_adapter *i2cbus); |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * Called to allow the output a chance to create properties after the | 58 | * Called to allow the output a chance to create properties after the |
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index 03d4b4973b02..621815b531db 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c | |||
@@ -176,19 +176,20 @@ static void ch7017_dpms(struct intel_dvo_device *dvo, int mode); | |||
176 | 176 | ||
177 | static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) | 177 | static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) |
178 | { | 178 | { |
179 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 179 | struct i2c_adapter *adapter = dvo->i2c_bus; |
180 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
180 | u8 out_buf[2]; | 181 | u8 out_buf[2]; |
181 | u8 in_buf[2]; | 182 | u8 in_buf[2]; |
182 | 183 | ||
183 | struct i2c_msg msgs[] = { | 184 | struct i2c_msg msgs[] = { |
184 | { | 185 | { |
185 | .addr = i2cbus->slave_addr, | 186 | .addr = dvo->slave_addr, |
186 | .flags = 0, | 187 | .flags = 0, |
187 | .len = 1, | 188 | .len = 1, |
188 | .buf = out_buf, | 189 | .buf = out_buf, |
189 | }, | 190 | }, |
190 | { | 191 | { |
191 | .addr = i2cbus->slave_addr, | 192 | .addr = dvo->slave_addr, |
192 | .flags = I2C_M_RD, | 193 | .flags = I2C_M_RD, |
193 | .len = 1, | 194 | .len = 1, |
194 | .buf = in_buf, | 195 | .buf = in_buf, |
@@ -208,10 +209,11 @@ static bool ch7017_read(struct intel_dvo_device *dvo, int addr, uint8_t *val) | |||
208 | 209 | ||
209 | static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) | 210 | static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) |
210 | { | 211 | { |
211 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 212 | struct i2c_adapter *adapter = dvo->i2c_bus; |
213 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
212 | uint8_t out_buf[2]; | 214 | uint8_t out_buf[2]; |
213 | struct i2c_msg msg = { | 215 | struct i2c_msg msg = { |
214 | .addr = i2cbus->slave_addr, | 216 | .addr = dvo->slave_addr, |
215 | .flags = 0, | 217 | .flags = 0, |
216 | .len = 2, | 218 | .len = 2, |
217 | .buf = out_buf, | 219 | .buf = out_buf, |
@@ -228,8 +230,9 @@ static bool ch7017_write(struct intel_dvo_device *dvo, int addr, uint8_t val) | |||
228 | 230 | ||
229 | /** Probes for a CH7017 on the given bus and slave address. */ | 231 | /** Probes for a CH7017 on the given bus and slave address. */ |
230 | static bool ch7017_init(struct intel_dvo_device *dvo, | 232 | static bool ch7017_init(struct intel_dvo_device *dvo, |
231 | struct intel_i2c_chan *i2cbus) | 233 | struct i2c_adapter *adapter) |
232 | { | 234 | { |
235 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
233 | struct ch7017_priv *priv; | 236 | struct ch7017_priv *priv; |
234 | uint8_t val; | 237 | uint8_t val; |
235 | 238 | ||
@@ -237,8 +240,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo, | |||
237 | if (priv == NULL) | 240 | if (priv == NULL) |
238 | return false; | 241 | return false; |
239 | 242 | ||
240 | dvo->i2c_bus = i2cbus; | 243 | dvo->i2c_bus = adapter; |
241 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
242 | dvo->dev_priv = priv; | 244 | dvo->dev_priv = priv; |
243 | 245 | ||
244 | if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val)) | 246 | if (!ch7017_read(dvo, CH7017_DEVICE_ID, &val)) |
@@ -248,7 +250,7 @@ static bool ch7017_init(struct intel_dvo_device *dvo, | |||
248 | val != CH7018_DEVICE_ID_VALUE && | 250 | val != CH7018_DEVICE_ID_VALUE && |
249 | val != CH7019_DEVICE_ID_VALUE) { | 251 | val != CH7019_DEVICE_ID_VALUE) { |
250 | DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n", | 252 | DRM_DEBUG("ch701x not detected, got %d: from %s Slave %d.\n", |
251 | val, i2cbus->adapter.name,i2cbus->slave_addr); | 253 | val, i2cbus->adapter.name,dvo->slave_addr); |
252 | goto fail; | 254 | goto fail; |
253 | } | 255 | } |
254 | 256 | ||
diff --git a/drivers/gpu/drm/i915/dvo_ch7xxx.c b/drivers/gpu/drm/i915/dvo_ch7xxx.c index d2fd95dbd034..a9b896289680 100644 --- a/drivers/gpu/drm/i915/dvo_ch7xxx.c +++ b/drivers/gpu/drm/i915/dvo_ch7xxx.c | |||
@@ -123,19 +123,20 @@ static char *ch7xxx_get_id(uint8_t vid) | |||
123 | static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | 123 | static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) |
124 | { | 124 | { |
125 | struct ch7xxx_priv *ch7xxx= dvo->dev_priv; | 125 | struct ch7xxx_priv *ch7xxx= dvo->dev_priv; |
126 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 126 | struct i2c_adapter *adapter = dvo->i2c_bus; |
127 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
127 | u8 out_buf[2]; | 128 | u8 out_buf[2]; |
128 | u8 in_buf[2]; | 129 | u8 in_buf[2]; |
129 | 130 | ||
130 | struct i2c_msg msgs[] = { | 131 | struct i2c_msg msgs[] = { |
131 | { | 132 | { |
132 | .addr = i2cbus->slave_addr, | 133 | .addr = dvo->slave_addr, |
133 | .flags = 0, | 134 | .flags = 0, |
134 | .len = 1, | 135 | .len = 1, |
135 | .buf = out_buf, | 136 | .buf = out_buf, |
136 | }, | 137 | }, |
137 | { | 138 | { |
138 | .addr = i2cbus->slave_addr, | 139 | .addr = dvo->slave_addr, |
139 | .flags = I2C_M_RD, | 140 | .flags = I2C_M_RD, |
140 | .len = 1, | 141 | .len = 1, |
141 | .buf = in_buf, | 142 | .buf = in_buf, |
@@ -152,7 +153,7 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
152 | 153 | ||
153 | if (!ch7xxx->quiet) { | 154 | if (!ch7xxx->quiet) { |
154 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", | 155 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", |
155 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 156 | addr, i2cbus->adapter.name, dvo->slave_addr); |
156 | } | 157 | } |
157 | return false; | 158 | return false; |
158 | } | 159 | } |
@@ -161,10 +162,11 @@ static bool ch7xxx_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
161 | static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | 162 | static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) |
162 | { | 163 | { |
163 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; | 164 | struct ch7xxx_priv *ch7xxx = dvo->dev_priv; |
164 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 165 | struct i2c_adapter *adapter = dvo->i2c_bus; |
166 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
165 | uint8_t out_buf[2]; | 167 | uint8_t out_buf[2]; |
166 | struct i2c_msg msg = { | 168 | struct i2c_msg msg = { |
167 | .addr = i2cbus->slave_addr, | 169 | .addr = dvo->slave_addr, |
168 | .flags = 0, | 170 | .flags = 0, |
169 | .len = 2, | 171 | .len = 2, |
170 | .buf = out_buf, | 172 | .buf = out_buf, |
@@ -178,14 +180,14 @@ static bool ch7xxx_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
178 | 180 | ||
179 | if (!ch7xxx->quiet) { | 181 | if (!ch7xxx->quiet) { |
180 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", | 182 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", |
181 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 183 | addr, i2cbus->adapter.name, dvo->slave_addr); |
182 | } | 184 | } |
183 | 185 | ||
184 | return false; | 186 | return false; |
185 | } | 187 | } |
186 | 188 | ||
187 | static bool ch7xxx_init(struct intel_dvo_device *dvo, | 189 | static bool ch7xxx_init(struct intel_dvo_device *dvo, |
188 | struct intel_i2c_chan *i2cbus) | 190 | struct i2c_adapter *adapter) |
189 | { | 191 | { |
190 | /* this will detect the CH7xxx chip on the specified i2c bus */ | 192 | /* this will detect the CH7xxx chip on the specified i2c bus */ |
191 | struct ch7xxx_priv *ch7xxx; | 193 | struct ch7xxx_priv *ch7xxx; |
@@ -196,8 +198,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, | |||
196 | if (ch7xxx == NULL) | 198 | if (ch7xxx == NULL) |
197 | return false; | 199 | return false; |
198 | 200 | ||
199 | dvo->i2c_bus = i2cbus; | 201 | dvo->i2c_bus = adapter; |
200 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
201 | dvo->dev_priv = ch7xxx; | 202 | dvo->dev_priv = ch7xxx; |
202 | ch7xxx->quiet = true; | 203 | ch7xxx->quiet = true; |
203 | 204 | ||
@@ -207,7 +208,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, | |||
207 | name = ch7xxx_get_id(vendor); | 208 | name = ch7xxx_get_id(vendor); |
208 | if (!name) { | 209 | if (!name) { |
209 | DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", | 210 | DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", |
210 | vendor, i2cbus->adapter.name, i2cbus->slave_addr); | 211 | vendor, adapter->name, dvo->slave_addr); |
211 | goto out; | 212 | goto out; |
212 | } | 213 | } |
213 | 214 | ||
@@ -217,7 +218,7 @@ static bool ch7xxx_init(struct intel_dvo_device *dvo, | |||
217 | 218 | ||
218 | if (device != CH7xxx_DID) { | 219 | if (device != CH7xxx_DID) { |
219 | DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", | 220 | DRM_DEBUG("ch7xxx not detected; got 0x%02x from %s slave %d.\n", |
220 | vendor, i2cbus->adapter.name, i2cbus->slave_addr); | 221 | vendor, adapter->name, dvo->slave_addr); |
221 | goto out; | 222 | goto out; |
222 | } | 223 | } |
223 | 224 | ||
diff --git a/drivers/gpu/drm/i915/dvo_ivch.c b/drivers/gpu/drm/i915/dvo_ivch.c index 0c8d375e8e37..aa176f9921fe 100644 --- a/drivers/gpu/drm/i915/dvo_ivch.c +++ b/drivers/gpu/drm/i915/dvo_ivch.c | |||
@@ -169,13 +169,14 @@ static void ivch_dump_regs(struct intel_dvo_device *dvo); | |||
169 | static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | 169 | static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) |
170 | { | 170 | { |
171 | struct ivch_priv *priv = dvo->dev_priv; | 171 | struct ivch_priv *priv = dvo->dev_priv; |
172 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 172 | struct i2c_adapter *adapter = dvo->i2c_bus; |
173 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
173 | u8 out_buf[1]; | 174 | u8 out_buf[1]; |
174 | u8 in_buf[2]; | 175 | u8 in_buf[2]; |
175 | 176 | ||
176 | struct i2c_msg msgs[] = { | 177 | struct i2c_msg msgs[] = { |
177 | { | 178 | { |
178 | .addr = i2cbus->slave_addr, | 179 | .addr = dvo->slave_addr, |
179 | .flags = I2C_M_RD, | 180 | .flags = I2C_M_RD, |
180 | .len = 0, | 181 | .len = 0, |
181 | }, | 182 | }, |
@@ -186,7 +187,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
186 | .buf = out_buf, | 187 | .buf = out_buf, |
187 | }, | 188 | }, |
188 | { | 189 | { |
189 | .addr = i2cbus->slave_addr, | 190 | .addr = dvo->slave_addr, |
190 | .flags = I2C_M_RD | I2C_M_NOSTART, | 191 | .flags = I2C_M_RD | I2C_M_NOSTART, |
191 | .len = 2, | 192 | .len = 2, |
192 | .buf = in_buf, | 193 | .buf = in_buf, |
@@ -202,7 +203,7 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
202 | 203 | ||
203 | if (!priv->quiet) { | 204 | if (!priv->quiet) { |
204 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", | 205 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", |
205 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 206 | addr, i2cbus->adapter.name, dvo->slave_addr); |
206 | } | 207 | } |
207 | return false; | 208 | return false; |
208 | } | 209 | } |
@@ -211,10 +212,11 @@ static bool ivch_read(struct intel_dvo_device *dvo, int addr, uint16_t *data) | |||
211 | static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) | 212 | static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) |
212 | { | 213 | { |
213 | struct ivch_priv *priv = dvo->dev_priv; | 214 | struct ivch_priv *priv = dvo->dev_priv; |
214 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 215 | struct i2c_adapter *adapter = dvo->i2c_bus; |
216 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
215 | u8 out_buf[3]; | 217 | u8 out_buf[3]; |
216 | struct i2c_msg msg = { | 218 | struct i2c_msg msg = { |
217 | .addr = i2cbus->slave_addr, | 219 | .addr = dvo->slave_addr, |
218 | .flags = 0, | 220 | .flags = 0, |
219 | .len = 3, | 221 | .len = 3, |
220 | .buf = out_buf, | 222 | .buf = out_buf, |
@@ -229,7 +231,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) | |||
229 | 231 | ||
230 | if (!priv->quiet) { | 232 | if (!priv->quiet) { |
231 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", | 233 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", |
232 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 234 | addr, i2cbus->adapter.name, dvo->slave_addr); |
233 | } | 235 | } |
234 | 236 | ||
235 | return false; | 237 | return false; |
@@ -237,7 +239,7 @@ static bool ivch_write(struct intel_dvo_device *dvo, int addr, uint16_t data) | |||
237 | 239 | ||
238 | /** Probes the given bus and slave address for an ivch */ | 240 | /** Probes the given bus and slave address for an ivch */ |
239 | static bool ivch_init(struct intel_dvo_device *dvo, | 241 | static bool ivch_init(struct intel_dvo_device *dvo, |
240 | struct intel_i2c_chan *i2cbus) | 242 | struct i2c_adapter *adapter) |
241 | { | 243 | { |
242 | struct ivch_priv *priv; | 244 | struct ivch_priv *priv; |
243 | uint16_t temp; | 245 | uint16_t temp; |
@@ -246,8 +248,7 @@ static bool ivch_init(struct intel_dvo_device *dvo, | |||
246 | if (priv == NULL) | 248 | if (priv == NULL) |
247 | return false; | 249 | return false; |
248 | 250 | ||
249 | dvo->i2c_bus = i2cbus; | 251 | dvo->i2c_bus = adapter; |
250 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
251 | dvo->dev_priv = priv; | 252 | dvo->dev_priv = priv; |
252 | priv->quiet = true; | 253 | priv->quiet = true; |
253 | 254 | ||
diff --git a/drivers/gpu/drm/i915/dvo_sil164.c b/drivers/gpu/drm/i915/dvo_sil164.c index 033a4bb070b2..e1c1f7341e5c 100644 --- a/drivers/gpu/drm/i915/dvo_sil164.c +++ b/drivers/gpu/drm/i915/dvo_sil164.c | |||
@@ -76,19 +76,20 @@ struct sil164_priv { | |||
76 | static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | 76 | static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) |
77 | { | 77 | { |
78 | struct sil164_priv *sil = dvo->dev_priv; | 78 | struct sil164_priv *sil = dvo->dev_priv; |
79 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 79 | struct i2c_adapter *adapter = dvo->i2c_bus; |
80 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
80 | u8 out_buf[2]; | 81 | u8 out_buf[2]; |
81 | u8 in_buf[2]; | 82 | u8 in_buf[2]; |
82 | 83 | ||
83 | struct i2c_msg msgs[] = { | 84 | struct i2c_msg msgs[] = { |
84 | { | 85 | { |
85 | .addr = i2cbus->slave_addr, | 86 | .addr = dvo->slave_addr, |
86 | .flags = 0, | 87 | .flags = 0, |
87 | .len = 1, | 88 | .len = 1, |
88 | .buf = out_buf, | 89 | .buf = out_buf, |
89 | }, | 90 | }, |
90 | { | 91 | { |
91 | .addr = i2cbus->slave_addr, | 92 | .addr = dvo->slave_addr, |
92 | .flags = I2C_M_RD, | 93 | .flags = I2C_M_RD, |
93 | .len = 1, | 94 | .len = 1, |
94 | .buf = in_buf, | 95 | .buf = in_buf, |
@@ -105,7 +106,7 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
105 | 106 | ||
106 | if (!sil->quiet) { | 107 | if (!sil->quiet) { |
107 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", | 108 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", |
108 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 109 | addr, i2cbus->adapter.name, dvo->slave_addr); |
109 | } | 110 | } |
110 | return false; | 111 | return false; |
111 | } | 112 | } |
@@ -113,10 +114,11 @@ static bool sil164_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
113 | static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | 114 | static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) |
114 | { | 115 | { |
115 | struct sil164_priv *sil= dvo->dev_priv; | 116 | struct sil164_priv *sil= dvo->dev_priv; |
116 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 117 | struct i2c_adapter *adapter = dvo->i2c_bus; |
118 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
117 | uint8_t out_buf[2]; | 119 | uint8_t out_buf[2]; |
118 | struct i2c_msg msg = { | 120 | struct i2c_msg msg = { |
119 | .addr = i2cbus->slave_addr, | 121 | .addr = dvo->slave_addr, |
120 | .flags = 0, | 122 | .flags = 0, |
121 | .len = 2, | 123 | .len = 2, |
122 | .buf = out_buf, | 124 | .buf = out_buf, |
@@ -130,7 +132,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
130 | 132 | ||
131 | if (!sil->quiet) { | 133 | if (!sil->quiet) { |
132 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", | 134 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", |
133 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 135 | addr, i2cbus->adapter.name, dvo->slave_addr); |
134 | } | 136 | } |
135 | 137 | ||
136 | return false; | 138 | return false; |
@@ -138,7 +140,7 @@ static bool sil164_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
138 | 140 | ||
139 | /* Silicon Image 164 driver for chip on i2c bus */ | 141 | /* Silicon Image 164 driver for chip on i2c bus */ |
140 | static bool sil164_init(struct intel_dvo_device *dvo, | 142 | static bool sil164_init(struct intel_dvo_device *dvo, |
141 | struct intel_i2c_chan *i2cbus) | 143 | struct i2c_adapter *adapter) |
142 | { | 144 | { |
143 | /* this will detect the SIL164 chip on the specified i2c bus */ | 145 | /* this will detect the SIL164 chip on the specified i2c bus */ |
144 | struct sil164_priv *sil; | 146 | struct sil164_priv *sil; |
@@ -148,8 +150,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, | |||
148 | if (sil == NULL) | 150 | if (sil == NULL) |
149 | return false; | 151 | return false; |
150 | 152 | ||
151 | dvo->i2c_bus = i2cbus; | 153 | dvo->i2c_bus = adapter; |
152 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
153 | dvo->dev_priv = sil; | 154 | dvo->dev_priv = sil; |
154 | sil->quiet = true; | 155 | sil->quiet = true; |
155 | 156 | ||
@@ -158,7 +159,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, | |||
158 | 159 | ||
159 | if (ch != (SIL164_VID & 0xff)) { | 160 | if (ch != (SIL164_VID & 0xff)) { |
160 | DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", | 161 | DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", |
161 | ch, i2cbus->adapter.name, i2cbus->slave_addr); | 162 | ch, adapter->name, dvo->slave_addr); |
162 | goto out; | 163 | goto out; |
163 | } | 164 | } |
164 | 165 | ||
@@ -167,7 +168,7 @@ static bool sil164_init(struct intel_dvo_device *dvo, | |||
167 | 168 | ||
168 | if (ch != (SIL164_DID & 0xff)) { | 169 | if (ch != (SIL164_DID & 0xff)) { |
169 | DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", | 170 | DRM_DEBUG("sil164 not detected got %d: from %s Slave %d.\n", |
170 | ch, i2cbus->adapter.name, i2cbus->slave_addr); | 171 | ch, adapter->name, dvo->slave_addr); |
171 | goto out; | 172 | goto out; |
172 | } | 173 | } |
173 | sil->quiet = false; | 174 | sil->quiet = false; |
diff --git a/drivers/gpu/drm/i915/dvo_tfp410.c b/drivers/gpu/drm/i915/dvo_tfp410.c index 207fda806ebf..9ecc907384ec 100644 --- a/drivers/gpu/drm/i915/dvo_tfp410.c +++ b/drivers/gpu/drm/i915/dvo_tfp410.c | |||
@@ -101,19 +101,20 @@ struct tfp410_priv { | |||
101 | static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | 101 | static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) |
102 | { | 102 | { |
103 | struct tfp410_priv *tfp = dvo->dev_priv; | 103 | struct tfp410_priv *tfp = dvo->dev_priv; |
104 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 104 | struct i2c_adapter *adapter = dvo->i2c_bus; |
105 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
105 | u8 out_buf[2]; | 106 | u8 out_buf[2]; |
106 | u8 in_buf[2]; | 107 | u8 in_buf[2]; |
107 | 108 | ||
108 | struct i2c_msg msgs[] = { | 109 | struct i2c_msg msgs[] = { |
109 | { | 110 | { |
110 | .addr = i2cbus->slave_addr, | 111 | .addr = dvo->slave_addr, |
111 | .flags = 0, | 112 | .flags = 0, |
112 | .len = 1, | 113 | .len = 1, |
113 | .buf = out_buf, | 114 | .buf = out_buf, |
114 | }, | 115 | }, |
115 | { | 116 | { |
116 | .addr = i2cbus->slave_addr, | 117 | .addr = dvo->slave_addr, |
117 | .flags = I2C_M_RD, | 118 | .flags = I2C_M_RD, |
118 | .len = 1, | 119 | .len = 1, |
119 | .buf = in_buf, | 120 | .buf = in_buf, |
@@ -130,7 +131,7 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
130 | 131 | ||
131 | if (!tfp->quiet) { | 132 | if (!tfp->quiet) { |
132 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", | 133 | DRM_DEBUG("Unable to read register 0x%02x from %s:%02x.\n", |
133 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 134 | addr, i2cbus->adapter.name, dvo->slave_addr); |
134 | } | 135 | } |
135 | return false; | 136 | return false; |
136 | } | 137 | } |
@@ -138,10 +139,11 @@ static bool tfp410_readb(struct intel_dvo_device *dvo, int addr, uint8_t *ch) | |||
138 | static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | 139 | static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) |
139 | { | 140 | { |
140 | struct tfp410_priv *tfp = dvo->dev_priv; | 141 | struct tfp410_priv *tfp = dvo->dev_priv; |
141 | struct intel_i2c_chan *i2cbus = dvo->i2c_bus; | 142 | struct i2c_adapter *adapter = dvo->i2c_bus; |
143 | struct intel_i2c_chan *i2cbus = container_of(adapter, struct intel_i2c_chan, adapter); | ||
142 | uint8_t out_buf[2]; | 144 | uint8_t out_buf[2]; |
143 | struct i2c_msg msg = { | 145 | struct i2c_msg msg = { |
144 | .addr = i2cbus->slave_addr, | 146 | .addr = dvo->slave_addr, |
145 | .flags = 0, | 147 | .flags = 0, |
146 | .len = 2, | 148 | .len = 2, |
147 | .buf = out_buf, | 149 | .buf = out_buf, |
@@ -155,7 +157,7 @@ static bool tfp410_writeb(struct intel_dvo_device *dvo, int addr, uint8_t ch) | |||
155 | 157 | ||
156 | if (!tfp->quiet) { | 158 | if (!tfp->quiet) { |
157 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", | 159 | DRM_DEBUG("Unable to write register 0x%02x to %s:%d.\n", |
158 | addr, i2cbus->adapter.name, i2cbus->slave_addr); | 160 | addr, i2cbus->adapter.name, dvo->slave_addr); |
159 | } | 161 | } |
160 | 162 | ||
161 | return false; | 163 | return false; |
@@ -174,7 +176,7 @@ static int tfp410_getid(struct intel_dvo_device *dvo, int addr) | |||
174 | 176 | ||
175 | /* Ti TFP410 driver for chip on i2c bus */ | 177 | /* Ti TFP410 driver for chip on i2c bus */ |
176 | static bool tfp410_init(struct intel_dvo_device *dvo, | 178 | static bool tfp410_init(struct intel_dvo_device *dvo, |
177 | struct intel_i2c_chan *i2cbus) | 179 | struct i2c_adapter *adapter) |
178 | { | 180 | { |
179 | /* this will detect the tfp410 chip on the specified i2c bus */ | 181 | /* this will detect the tfp410 chip on the specified i2c bus */ |
180 | struct tfp410_priv *tfp; | 182 | struct tfp410_priv *tfp; |
@@ -184,20 +186,19 @@ static bool tfp410_init(struct intel_dvo_device *dvo, | |||
184 | if (tfp == NULL) | 186 | if (tfp == NULL) |
185 | return false; | 187 | return false; |
186 | 188 | ||
187 | dvo->i2c_bus = i2cbus; | 189 | dvo->i2c_bus = adapter; |
188 | dvo->i2c_bus->slave_addr = dvo->slave_addr; | ||
189 | dvo->dev_priv = tfp; | 190 | dvo->dev_priv = tfp; |
190 | tfp->quiet = true; | 191 | tfp->quiet = true; |
191 | 192 | ||
192 | if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) { | 193 | if ((id = tfp410_getid(dvo, TFP410_VID_LO)) != TFP410_VID) { |
193 | DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n", | 194 | DRM_DEBUG("tfp410 not detected got VID %X: from %s Slave %d.\n", |
194 | id, i2cbus->adapter.name, i2cbus->slave_addr); | 195 | id, adapter->name, dvo->slave_addr); |
195 | goto out; | 196 | goto out; |
196 | } | 197 | } |
197 | 198 | ||
198 | if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) { | 199 | if ((id = tfp410_getid(dvo, TFP410_DID_LO)) != TFP410_DID) { |
199 | DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n", | 200 | DRM_DEBUG("tfp410 not detected got DID %X: from %s Slave %d.\n", |
200 | id, i2cbus->adapter.name, i2cbus->slave_addr); | 201 | id, adapter->name, dvo->slave_addr); |
201 | goto out; | 202 | goto out; |
202 | } | 203 | } |
203 | tfp->quiet = false; | 204 | tfp->quiet = false; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 98560e1e899a..e3cb4025e323 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -67,8 +67,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
67 | 67 | ||
68 | pci_save_state(dev->pdev); | 68 | pci_save_state(dev->pdev); |
69 | 69 | ||
70 | i915_save_state(dev); | ||
71 | |||
72 | /* If KMS is active, we do the leavevt stuff here */ | 70 | /* If KMS is active, we do the leavevt stuff here */ |
73 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 71 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
74 | if (i915_gem_idle(dev)) | 72 | if (i915_gem_idle(dev)) |
@@ -77,6 +75,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) | |||
77 | drm_irq_uninstall(dev); | 75 | drm_irq_uninstall(dev); |
78 | } | 76 | } |
79 | 77 | ||
78 | i915_save_state(dev); | ||
79 | |||
80 | intel_opregion_free(dev, 1); | 80 | intel_opregion_free(dev, 1); |
81 | 81 | ||
82 | if (state.event == PM_EVENT_SUSPEND) { | 82 | if (state.event == PM_EVENT_SUSPEND) { |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7a84f04e8439..bb4c2d387b6c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -306,6 +306,17 @@ typedef struct drm_i915_private { | |||
306 | u32 saveCURBPOS; | 306 | u32 saveCURBPOS; |
307 | u32 saveCURBBASE; | 307 | u32 saveCURBBASE; |
308 | u32 saveCURSIZE; | 308 | u32 saveCURSIZE; |
309 | u32 saveDP_B; | ||
310 | u32 saveDP_C; | ||
311 | u32 saveDP_D; | ||
312 | u32 savePIPEA_GMCH_DATA_M; | ||
313 | u32 savePIPEB_GMCH_DATA_M; | ||
314 | u32 savePIPEA_GMCH_DATA_N; | ||
315 | u32 savePIPEB_GMCH_DATA_N; | ||
316 | u32 savePIPEA_DP_LINK_M; | ||
317 | u32 savePIPEB_DP_LINK_M; | ||
318 | u32 savePIPEA_DP_LINK_N; | ||
319 | u32 savePIPEB_DP_LINK_N; | ||
309 | 320 | ||
310 | struct { | 321 | struct { |
311 | struct drm_mm gtt_space; | 322 | struct drm_mm gtt_space; |
@@ -857,6 +868,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); | |||
857 | #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ | 868 | #define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \ |
858 | IS_I915GM(dev))) | 869 | IS_I915GM(dev))) |
859 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | 870 | #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) |
871 | #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) | ||
860 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) | 872 | #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) |
861 | 873 | ||
862 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) | 874 | #define PRIMARY_RINGBUFFER_SIZE (128*1024) |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index fd2b8bdffe3f..876b65cb7629 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1006,7 +1006,7 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1006 | 1006 | ||
1007 | mutex_lock(&dev->struct_mutex); | 1007 | mutex_lock(&dev->struct_mutex); |
1008 | #if WATCH_BUF | 1008 | #if WATCH_BUF |
1009 | DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n", | 1009 | DRM_INFO("set_domain_ioctl %p(%zd), %08x %08x\n", |
1010 | obj, obj->size, read_domains, write_domain); | 1010 | obj, obj->size, read_domains, write_domain); |
1011 | #endif | 1011 | #endif |
1012 | if (read_domains & I915_GEM_DOMAIN_GTT) { | 1012 | if (read_domains & I915_GEM_DOMAIN_GTT) { |
@@ -1050,7 +1050,7 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, | |||
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | #if WATCH_BUF | 1052 | #if WATCH_BUF |
1053 | DRM_INFO("%s: sw_finish %d (%p %d)\n", | 1053 | DRM_INFO("%s: sw_finish %d (%p %zd)\n", |
1054 | __func__, args->handle, obj, obj->size); | 1054 | __func__, args->handle, obj, obj->size); |
1055 | #endif | 1055 | #endif |
1056 | obj_priv = obj->driver_private; | 1056 | obj_priv = obj->driver_private; |
@@ -2423,7 +2423,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2423 | } | 2423 | } |
2424 | 2424 | ||
2425 | #if WATCH_BUF | 2425 | #if WATCH_BUF |
2426 | DRM_INFO("Binding object of size %d at 0x%08x\n", | 2426 | DRM_INFO("Binding object of size %zd at 0x%08x\n", |
2427 | obj->size, obj_priv->gtt_offset); | 2427 | obj->size, obj_priv->gtt_offset); |
2428 | #endif | 2428 | #endif |
2429 | ret = i915_gem_object_get_pages(obj); | 2429 | ret = i915_gem_object_get_pages(obj); |
@@ -4227,6 +4227,7 @@ i915_gem_lastclose(struct drm_device *dev) | |||
4227 | void | 4227 | void |
4228 | i915_gem_load(struct drm_device *dev) | 4228 | i915_gem_load(struct drm_device *dev) |
4229 | { | 4229 | { |
4230 | int i; | ||
4230 | drm_i915_private_t *dev_priv = dev->dev_private; | 4231 | drm_i915_private_t *dev_priv = dev->dev_private; |
4231 | 4232 | ||
4232 | spin_lock_init(&dev_priv->mm.active_list_lock); | 4233 | spin_lock_init(&dev_priv->mm.active_list_lock); |
@@ -4246,6 +4247,18 @@ i915_gem_load(struct drm_device *dev) | |||
4246 | else | 4247 | else |
4247 | dev_priv->num_fence_regs = 8; | 4248 | dev_priv->num_fence_regs = 8; |
4248 | 4249 | ||
4250 | /* Initialize fence registers to zero */ | ||
4251 | if (IS_I965G(dev)) { | ||
4252 | for (i = 0; i < 16; i++) | ||
4253 | I915_WRITE64(FENCE_REG_965_0 + (i * 8), 0); | ||
4254 | } else { | ||
4255 | for (i = 0; i < 8; i++) | ||
4256 | I915_WRITE(FENCE_REG_830_0 + (i * 4), 0); | ||
4257 | if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) | ||
4258 | for (i = 0; i < 8; i++) | ||
4259 | I915_WRITE(FENCE_REG_945_8 + (i * 4), 0); | ||
4260 | } | ||
4261 | |||
4249 | i915_gem_detect_bit_6_swizzle(dev); | 4262 | i915_gem_detect_bit_6_swizzle(dev); |
4250 | } | 4263 | } |
4251 | 4264 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index 8d0b943e2c5a..e602614bd3f8 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c | |||
@@ -87,7 +87,7 @@ i915_gem_dump_object(struct drm_gem_object *obj, int len, | |||
87 | chunk_len = page_len - chunk; | 87 | chunk_len = page_len - chunk; |
88 | if (chunk_len > 128) | 88 | if (chunk_len > 128) |
89 | chunk_len = 128; | 89 | chunk_len = 128; |
90 | i915_gem_dump_page(obj_priv->page_list[page], | 90 | i915_gem_dump_page(obj_priv->pages[page], |
91 | chunk, chunk + chunk_len, | 91 | chunk, chunk + chunk_len, |
92 | obj_priv->gtt_offset + | 92 | obj_priv->gtt_offset + |
93 | page * PAGE_SIZE, | 93 | page * PAGE_SIZE, |
@@ -143,7 +143,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | |||
143 | uint32_t *backing_map = NULL; | 143 | uint32_t *backing_map = NULL; |
144 | int bad_count = 0; | 144 | int bad_count = 0; |
145 | 145 | ||
146 | DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n", | 146 | DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", |
147 | __func__, obj, obj_priv->gtt_offset, handle, | 147 | __func__, obj, obj_priv->gtt_offset, handle, |
148 | obj->size / 1024); | 148 | obj->size / 1024); |
149 | 149 | ||
@@ -157,7 +157,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) | |||
157 | for (page = 0; page < obj->size / PAGE_SIZE; page++) { | 157 | for (page = 0; page < obj->size / PAGE_SIZE; page++) { |
158 | int i; | 158 | int i; |
159 | 159 | ||
160 | backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0); | 160 | backing_map = kmap_atomic(obj_priv->pages[page], KM_USER0); |
161 | 161 | ||
162 | if (backing_map == NULL) { | 162 | if (backing_map == NULL) { |
163 | DRM_ERROR("failed to map backing page\n"); | 163 | DRM_ERROR("failed to map backing page\n"); |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 5c1ceec49f5b..daeae62e1c28 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
@@ -114,11 +114,13 @@ intel_alloc_mchbar_resource(struct drm_device *dev) | |||
114 | mchbar_addr = ((u64)temp_hi << 32) | temp_lo; | 114 | mchbar_addr = ((u64)temp_hi << 32) | temp_lo; |
115 | 115 | ||
116 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ | 116 | /* If ACPI doesn't have it, assume we need to allocate it ourselves */ |
117 | #ifdef CONFIG_PNP | ||
117 | if (mchbar_addr && | 118 | if (mchbar_addr && |
118 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { | 119 | pnp_range_reserved(mchbar_addr, mchbar_addr + MCHBAR_SIZE)) { |
119 | ret = 0; | 120 | ret = 0; |
120 | goto out_put; | 121 | goto out_put; |
121 | } | 122 | } |
123 | #endif | ||
122 | 124 | ||
123 | /* Get some space for it */ | 125 | /* Get some space for it */ |
124 | ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, | 126 | ret = pci_bus_alloc_resource(bridge_dev->bus, &dev_priv->mch_res, |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b86b7b7130c6..228546f6eaa4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -232,7 +232,17 @@ static void i915_hotplug_work_func(struct work_struct *work) | |||
232 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, | 232 | drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t, |
233 | hotplug_work); | 233 | hotplug_work); |
234 | struct drm_device *dev = dev_priv->dev; | 234 | struct drm_device *dev = dev_priv->dev; |
235 | 235 | struct drm_mode_config *mode_config = &dev->mode_config; | |
236 | struct drm_connector *connector; | ||
237 | |||
238 | if (mode_config->num_connector) { | ||
239 | list_for_each_entry(connector, &mode_config->connector_list, head) { | ||
240 | struct intel_output *intel_output = to_intel_output(connector); | ||
241 | |||
242 | if (intel_output->hot_plug) | ||
243 | (*intel_output->hot_plug) (intel_output); | ||
244 | } | ||
245 | } | ||
236 | /* Just fire off a uevent and let userspace tell us what to do */ | 246 | /* Just fire off a uevent and let userspace tell us what to do */ |
237 | drm_sysfs_hotplug_event(dev); | 247 | drm_sysfs_hotplug_event(dev); |
238 | } | 248 | } |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f6237a0b1133..88bf7521405f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -569,6 +569,19 @@ | |||
569 | #define C0DRB3 0x10206 | 569 | #define C0DRB3 0x10206 |
570 | #define C1DRB3 0x10606 | 570 | #define C1DRB3 0x10606 |
571 | 571 | ||
572 | /* Clocking configuration register */ | ||
573 | #define CLKCFG 0x10c00 | ||
574 | #define CLKCFG_FSB_400 (0 << 0) /* hrawclk 100 */ | ||
575 | #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ | ||
576 | #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ | ||
577 | #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ | ||
578 | #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ | ||
579 | #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ | ||
580 | /* this is a guess, could be 5 as well */ | ||
581 | #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ | ||
582 | #define CLKCFG_FSB_1600_ALT (5 << 0) /* hrawclk 400 */ | ||
583 | #define CLKCFG_FSB_MASK (7 << 0) | ||
584 | |||
572 | /** GM965 GM45 render standby register */ | 585 | /** GM965 GM45 render standby register */ |
573 | #define MCHBAR_RENDER_STANDBY 0x111B8 | 586 | #define MCHBAR_RENDER_STANDBY 0x111B8 |
574 | 587 | ||
@@ -834,9 +847,25 @@ | |||
834 | #define HORIZ_INTERP_MASK (3 << 6) | 847 | #define HORIZ_INTERP_MASK (3 << 6) |
835 | #define HORIZ_AUTO_SCALE (1 << 5) | 848 | #define HORIZ_AUTO_SCALE (1 << 5) |
836 | #define PANEL_8TO6_DITHER_ENABLE (1 << 3) | 849 | #define PANEL_8TO6_DITHER_ENABLE (1 << 3) |
850 | #define PFIT_FILTER_FUZZY (0 << 24) | ||
851 | #define PFIT_SCALING_AUTO (0 << 26) | ||
852 | #define PFIT_SCALING_PROGRAMMED (1 << 26) | ||
853 | #define PFIT_SCALING_PILLAR (2 << 26) | ||
854 | #define PFIT_SCALING_LETTER (3 << 26) | ||
837 | #define PFIT_PGM_RATIOS 0x61234 | 855 | #define PFIT_PGM_RATIOS 0x61234 |
838 | #define PFIT_VERT_SCALE_MASK 0xfff00000 | 856 | #define PFIT_VERT_SCALE_MASK 0xfff00000 |
839 | #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 | 857 | #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 |
858 | /* Pre-965 */ | ||
859 | #define PFIT_VERT_SCALE_SHIFT 20 | ||
860 | #define PFIT_VERT_SCALE_MASK 0xfff00000 | ||
861 | #define PFIT_HORIZ_SCALE_SHIFT 4 | ||
862 | #define PFIT_HORIZ_SCALE_MASK 0x0000fff0 | ||
863 | /* 965+ */ | ||
864 | #define PFIT_VERT_SCALE_SHIFT_965 16 | ||
865 | #define PFIT_VERT_SCALE_MASK_965 0x1fff0000 | ||
866 | #define PFIT_HORIZ_SCALE_SHIFT_965 0 | ||
867 | #define PFIT_HORIZ_SCALE_MASK_965 0x00001fff | ||
868 | |||
840 | #define PFIT_AUTO_RATIOS 0x61238 | 869 | #define PFIT_AUTO_RATIOS 0x61238 |
841 | 870 | ||
842 | /* Backlight control */ | 871 | /* Backlight control */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index a98e2831ed31..8d8e083d14ab 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -322,6 +322,20 @@ int i915_save_state(struct drm_device *dev) | |||
322 | dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); | 322 | dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS); |
323 | dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); | 323 | dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR); |
324 | 324 | ||
325 | /* Display Port state */ | ||
326 | if (SUPPORTS_INTEGRATED_DP(dev)) { | ||
327 | dev_priv->saveDP_B = I915_READ(DP_B); | ||
328 | dev_priv->saveDP_C = I915_READ(DP_C); | ||
329 | dev_priv->saveDP_D = I915_READ(DP_D); | ||
330 | dev_priv->savePIPEA_GMCH_DATA_M = I915_READ(PIPEA_GMCH_DATA_M); | ||
331 | dev_priv->savePIPEB_GMCH_DATA_M = I915_READ(PIPEB_GMCH_DATA_M); | ||
332 | dev_priv->savePIPEA_GMCH_DATA_N = I915_READ(PIPEA_GMCH_DATA_N); | ||
333 | dev_priv->savePIPEB_GMCH_DATA_N = I915_READ(PIPEB_GMCH_DATA_N); | ||
334 | dev_priv->savePIPEA_DP_LINK_M = I915_READ(PIPEA_DP_LINK_M); | ||
335 | dev_priv->savePIPEB_DP_LINK_M = I915_READ(PIPEB_DP_LINK_M); | ||
336 | dev_priv->savePIPEA_DP_LINK_N = I915_READ(PIPEA_DP_LINK_N); | ||
337 | dev_priv->savePIPEB_DP_LINK_N = I915_READ(PIPEB_DP_LINK_N); | ||
338 | } | ||
325 | /* FIXME: save TV & SDVO state */ | 339 | /* FIXME: save TV & SDVO state */ |
326 | 340 | ||
327 | /* FBC state */ | 341 | /* FBC state */ |
@@ -404,7 +418,19 @@ int i915_restore_state(struct drm_device *dev) | |||
404 | for (i = 0; i < 8; i++) | 418 | for (i = 0; i < 8; i++) |
405 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); | 419 | I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); |
406 | } | 420 | } |
407 | 421 | ||
422 | /* Display port ratios (must be done before clock is set) */ | ||
423 | if (SUPPORTS_INTEGRATED_DP(dev)) { | ||
424 | I915_WRITE(PIPEA_GMCH_DATA_M, dev_priv->savePIPEA_GMCH_DATA_M); | ||
425 | I915_WRITE(PIPEB_GMCH_DATA_M, dev_priv->savePIPEB_GMCH_DATA_M); | ||
426 | I915_WRITE(PIPEA_GMCH_DATA_N, dev_priv->savePIPEA_GMCH_DATA_N); | ||
427 | I915_WRITE(PIPEB_GMCH_DATA_N, dev_priv->savePIPEB_GMCH_DATA_N); | ||
428 | I915_WRITE(PIPEA_DP_LINK_M, dev_priv->savePIPEA_DP_LINK_M); | ||
429 | I915_WRITE(PIPEB_DP_LINK_M, dev_priv->savePIPEB_DP_LINK_M); | ||
430 | I915_WRITE(PIPEA_DP_LINK_N, dev_priv->savePIPEA_DP_LINK_N); | ||
431 | I915_WRITE(PIPEB_DP_LINK_N, dev_priv->savePIPEB_DP_LINK_N); | ||
432 | } | ||
433 | |||
408 | /* Pipe & plane A info */ | 434 | /* Pipe & plane A info */ |
409 | /* Prime the clock */ | 435 | /* Prime the clock */ |
410 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 436 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { |
@@ -518,6 +544,12 @@ int i915_restore_state(struct drm_device *dev) | |||
518 | I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); | 544 | I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR); |
519 | I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); | 545 | I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL); |
520 | 546 | ||
547 | /* Display Port state */ | ||
548 | if (SUPPORTS_INTEGRATED_DP(dev)) { | ||
549 | I915_WRITE(DP_B, dev_priv->saveDP_B); | ||
550 | I915_WRITE(DP_C, dev_priv->saveDP_C); | ||
551 | I915_WRITE(DP_D, dev_priv->saveDP_D); | ||
552 | } | ||
521 | /* FIXME: restore TV & SDVO state */ | 553 | /* FIXME: restore TV & SDVO state */ |
522 | 554 | ||
523 | /* FBC info */ | 555 | /* FBC info */ |
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index cdd126d068a7..716409a57244 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
@@ -99,9 +99,11 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
99 | { | 99 | { |
100 | struct bdb_lvds_options *lvds_options; | 100 | struct bdb_lvds_options *lvds_options; |
101 | struct bdb_lvds_lfp_data *lvds_lfp_data; | 101 | struct bdb_lvds_lfp_data *lvds_lfp_data; |
102 | struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs; | ||
102 | struct bdb_lvds_lfp_data_entry *entry; | 103 | struct bdb_lvds_lfp_data_entry *entry; |
103 | struct lvds_dvo_timing *dvo_timing; | 104 | struct lvds_dvo_timing *dvo_timing; |
104 | struct drm_display_mode *panel_fixed_mode; | 105 | struct drm_display_mode *panel_fixed_mode; |
106 | int lfp_data_size; | ||
105 | 107 | ||
106 | /* Defaults if we can't find VBT info */ | 108 | /* Defaults if we can't find VBT info */ |
107 | dev_priv->lvds_dither = 0; | 109 | dev_priv->lvds_dither = 0; |
@@ -119,9 +121,17 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
119 | if (!lvds_lfp_data) | 121 | if (!lvds_lfp_data) |
120 | return; | 122 | return; |
121 | 123 | ||
124 | lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS); | ||
125 | if (!lvds_lfp_data_ptrs) | ||
126 | return; | ||
127 | |||
122 | dev_priv->lvds_vbt = 1; | 128 | dev_priv->lvds_vbt = 1; |
123 | 129 | ||
124 | entry = &lvds_lfp_data->data[lvds_options->panel_type]; | 130 | lfp_data_size = lvds_lfp_data_ptrs->ptr[1].dvo_timing_offset - |
131 | lvds_lfp_data_ptrs->ptr[0].dvo_timing_offset; | ||
132 | entry = (struct bdb_lvds_lfp_data_entry *) | ||
133 | ((uint8_t *)lvds_lfp_data->data + (lfp_data_size * | ||
134 | lvds_options->panel_type)); | ||
125 | dvo_timing = &entry->dvo_timing; | 135 | dvo_timing = &entry->dvo_timing; |
126 | 136 | ||
127 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); | 137 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3e1c78162119..73e7b9cecac8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "intel_drv.h" | 29 | #include "intel_drv.h" |
30 | #include "i915_drm.h" | 30 | #include "i915_drm.h" |
31 | #include "i915_drv.h" | 31 | #include "i915_drv.h" |
32 | #include "intel_dp.h" | ||
32 | 33 | ||
33 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
34 | 35 | ||
@@ -127,19 +128,6 @@ struct intel_limit { | |||
127 | #define I9XX_P2_LVDS_FAST 7 | 128 | #define I9XX_P2_LVDS_FAST 7 |
128 | #define I9XX_P2_LVDS_SLOW_LIMIT 112000 | 129 | #define I9XX_P2_LVDS_SLOW_LIMIT 112000 |
129 | 130 | ||
130 | #define INTEL_LIMIT_I8XX_DVO_DAC 0 | ||
131 | #define INTEL_LIMIT_I8XX_LVDS 1 | ||
132 | #define INTEL_LIMIT_I9XX_SDVO_DAC 2 | ||
133 | #define INTEL_LIMIT_I9XX_LVDS 3 | ||
134 | #define INTEL_LIMIT_G4X_SDVO 4 | ||
135 | #define INTEL_LIMIT_G4X_HDMI_DAC 5 | ||
136 | #define INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS 6 | ||
137 | #define INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS 7 | ||
138 | #define INTEL_LIMIT_IGD_SDVO_DAC 8 | ||
139 | #define INTEL_LIMIT_IGD_LVDS 9 | ||
140 | #define INTEL_LIMIT_IGDNG_SDVO_DAC 10 | ||
141 | #define INTEL_LIMIT_IGDNG_LVDS 11 | ||
142 | |||
143 | /*The parameter is for SDVO on G4x platform*/ | 131 | /*The parameter is for SDVO on G4x platform*/ |
144 | #define G4X_DOT_SDVO_MIN 25000 | 132 | #define G4X_DOT_SDVO_MIN 25000 |
145 | #define G4X_DOT_SDVO_MAX 270000 | 133 | #define G4X_DOT_SDVO_MAX 270000 |
@@ -218,6 +206,25 @@ struct intel_limit { | |||
218 | #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 | 206 | #define G4X_P2_DUAL_CHANNEL_LVDS_FAST 7 |
219 | #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 | 207 | #define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT 0 |
220 | 208 | ||
209 | /*The parameter is for DISPLAY PORT on G4x platform*/ | ||
210 | #define G4X_DOT_DISPLAY_PORT_MIN 161670 | ||
211 | #define G4X_DOT_DISPLAY_PORT_MAX 227000 | ||
212 | #define G4X_N_DISPLAY_PORT_MIN 1 | ||
213 | #define G4X_N_DISPLAY_PORT_MAX 2 | ||
214 | #define G4X_M_DISPLAY_PORT_MIN 97 | ||
215 | #define G4X_M_DISPLAY_PORT_MAX 108 | ||
216 | #define G4X_M1_DISPLAY_PORT_MIN 0x10 | ||
217 | #define G4X_M1_DISPLAY_PORT_MAX 0x12 | ||
218 | #define G4X_M2_DISPLAY_PORT_MIN 0x05 | ||
219 | #define G4X_M2_DISPLAY_PORT_MAX 0x06 | ||
220 | #define G4X_P_DISPLAY_PORT_MIN 10 | ||
221 | #define G4X_P_DISPLAY_PORT_MAX 20 | ||
222 | #define G4X_P1_DISPLAY_PORT_MIN 1 | ||
223 | #define G4X_P1_DISPLAY_PORT_MAX 2 | ||
224 | #define G4X_P2_DISPLAY_PORT_SLOW 10 | ||
225 | #define G4X_P2_DISPLAY_PORT_FAST 10 | ||
226 | #define G4X_P2_DISPLAY_PORT_LIMIT 0 | ||
227 | |||
221 | /* IGDNG */ | 228 | /* IGDNG */ |
222 | /* as we calculate clock using (register_value + 2) for | 229 | /* as we calculate clock using (register_value + 2) for |
223 | N/M1/M2, so here the range value for them is (actual_value-2). | 230 | N/M1/M2, so here the range value for them is (actual_value-2). |
@@ -256,8 +263,11 @@ static bool | |||
256 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | 263 | intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
257 | int target, int refclk, intel_clock_t *best_clock); | 264 | int target, int refclk, intel_clock_t *best_clock); |
258 | 265 | ||
259 | static const intel_limit_t intel_limits[] = { | 266 | static bool |
260 | { /* INTEL_LIMIT_I8XX_DVO_DAC */ | 267 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
268 | int target, int refclk, intel_clock_t *best_clock); | ||
269 | |||
270 | static const intel_limit_t intel_limits_i8xx_dvo = { | ||
261 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 271 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
262 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, | 272 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, |
263 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, | 273 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, |
@@ -269,8 +279,9 @@ static const intel_limit_t intel_limits[] = { | |||
269 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 279 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
270 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, | 280 | .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, |
271 | .find_pll = intel_find_best_PLL, | 281 | .find_pll = intel_find_best_PLL, |
272 | }, | 282 | }; |
273 | { /* INTEL_LIMIT_I8XX_LVDS */ | 283 | |
284 | static const intel_limit_t intel_limits_i8xx_lvds = { | ||
274 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, | 285 | .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, |
275 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, | 286 | .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, |
276 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, | 287 | .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, |
@@ -282,8 +293,9 @@ static const intel_limit_t intel_limits[] = { | |||
282 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, | 293 | .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, |
283 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, | 294 | .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, |
284 | .find_pll = intel_find_best_PLL, | 295 | .find_pll = intel_find_best_PLL, |
285 | }, | 296 | }; |
286 | { /* INTEL_LIMIT_I9XX_SDVO_DAC */ | 297 | |
298 | static const intel_limit_t intel_limits_i9xx_sdvo = { | ||
287 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 299 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
288 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, | 300 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, |
289 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, | 301 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, |
@@ -295,8 +307,9 @@ static const intel_limit_t intel_limits[] = { | |||
295 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 307 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
296 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 308 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
297 | .find_pll = intel_find_best_PLL, | 309 | .find_pll = intel_find_best_PLL, |
298 | }, | 310 | }; |
299 | { /* INTEL_LIMIT_I9XX_LVDS */ | 311 | |
312 | static const intel_limit_t intel_limits_i9xx_lvds = { | ||
300 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 313 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
301 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, | 314 | .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, |
302 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, | 315 | .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, |
@@ -311,9 +324,10 @@ static const intel_limit_t intel_limits[] = { | |||
311 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 324 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
312 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, | 325 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, |
313 | .find_pll = intel_find_best_PLL, | 326 | .find_pll = intel_find_best_PLL, |
314 | }, | 327 | }; |
328 | |||
315 | /* below parameter and function is for G4X Chipset Family*/ | 329 | /* below parameter and function is for G4X Chipset Family*/ |
316 | { /* INTEL_LIMIT_G4X_SDVO */ | 330 | static const intel_limit_t intel_limits_g4x_sdvo = { |
317 | .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, | 331 | .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, |
318 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, | 332 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, |
319 | .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, | 333 | .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, |
@@ -327,8 +341,9 @@ static const intel_limit_t intel_limits[] = { | |||
327 | .p2_fast = G4X_P2_SDVO_FAST | 341 | .p2_fast = G4X_P2_SDVO_FAST |
328 | }, | 342 | }, |
329 | .find_pll = intel_g4x_find_best_PLL, | 343 | .find_pll = intel_g4x_find_best_PLL, |
330 | }, | 344 | }; |
331 | { /* INTEL_LIMIT_G4X_HDMI_DAC */ | 345 | |
346 | static const intel_limit_t intel_limits_g4x_hdmi = { | ||
332 | .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, | 347 | .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, |
333 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, | 348 | .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, |
334 | .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, | 349 | .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, |
@@ -342,8 +357,9 @@ static const intel_limit_t intel_limits[] = { | |||
342 | .p2_fast = G4X_P2_HDMI_DAC_FAST | 357 | .p2_fast = G4X_P2_HDMI_DAC_FAST |
343 | }, | 358 | }, |
344 | .find_pll = intel_g4x_find_best_PLL, | 359 | .find_pll = intel_g4x_find_best_PLL, |
345 | }, | 360 | }; |
346 | { /* INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS */ | 361 | |
362 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | ||
347 | .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, | 363 | .dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN, |
348 | .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, | 364 | .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX }, |
349 | .vco = { .min = G4X_VCO_MIN, | 365 | .vco = { .min = G4X_VCO_MIN, |
@@ -365,8 +381,9 @@ static const intel_limit_t intel_limits[] = { | |||
365 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST | 381 | .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST |
366 | }, | 382 | }, |
367 | .find_pll = intel_g4x_find_best_PLL, | 383 | .find_pll = intel_g4x_find_best_PLL, |
368 | }, | 384 | }; |
369 | { /* INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS */ | 385 | |
386 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | ||
370 | .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, | 387 | .dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN, |
371 | .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, | 388 | .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX }, |
372 | .vco = { .min = G4X_VCO_MIN, | 389 | .vco = { .min = G4X_VCO_MIN, |
@@ -388,8 +405,32 @@ static const intel_limit_t intel_limits[] = { | |||
388 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST | 405 | .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST |
389 | }, | 406 | }, |
390 | .find_pll = intel_g4x_find_best_PLL, | 407 | .find_pll = intel_g4x_find_best_PLL, |
391 | }, | 408 | }; |
392 | { /* INTEL_LIMIT_IGD_SDVO */ | 409 | |
410 | static const intel_limit_t intel_limits_g4x_display_port = { | ||
411 | .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN, | ||
412 | .max = G4X_DOT_DISPLAY_PORT_MAX }, | ||
413 | .vco = { .min = G4X_VCO_MIN, | ||
414 | .max = G4X_VCO_MAX}, | ||
415 | .n = { .min = G4X_N_DISPLAY_PORT_MIN, | ||
416 | .max = G4X_N_DISPLAY_PORT_MAX }, | ||
417 | .m = { .min = G4X_M_DISPLAY_PORT_MIN, | ||
418 | .max = G4X_M_DISPLAY_PORT_MAX }, | ||
419 | .m1 = { .min = G4X_M1_DISPLAY_PORT_MIN, | ||
420 | .max = G4X_M1_DISPLAY_PORT_MAX }, | ||
421 | .m2 = { .min = G4X_M2_DISPLAY_PORT_MIN, | ||
422 | .max = G4X_M2_DISPLAY_PORT_MAX }, | ||
423 | .p = { .min = G4X_P_DISPLAY_PORT_MIN, | ||
424 | .max = G4X_P_DISPLAY_PORT_MAX }, | ||
425 | .p1 = { .min = G4X_P1_DISPLAY_PORT_MIN, | ||
426 | .max = G4X_P1_DISPLAY_PORT_MAX}, | ||
427 | .p2 = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT, | ||
428 | .p2_slow = G4X_P2_DISPLAY_PORT_SLOW, | ||
429 | .p2_fast = G4X_P2_DISPLAY_PORT_FAST }, | ||
430 | .find_pll = intel_find_pll_g4x_dp, | ||
431 | }; | ||
432 | |||
433 | static const intel_limit_t intel_limits_igd_sdvo = { | ||
393 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, | 434 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, |
394 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, | 435 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, |
395 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, | 436 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, |
@@ -401,8 +442,9 @@ static const intel_limit_t intel_limits[] = { | |||
401 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, | 442 | .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, |
402 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, | 443 | .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, |
403 | .find_pll = intel_find_best_PLL, | 444 | .find_pll = intel_find_best_PLL, |
404 | }, | 445 | }; |
405 | { /* INTEL_LIMIT_IGD_LVDS */ | 446 | |
447 | static const intel_limit_t intel_limits_igd_lvds = { | ||
406 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, | 448 | .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, |
407 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, | 449 | .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, |
408 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, | 450 | .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, |
@@ -415,8 +457,9 @@ static const intel_limit_t intel_limits[] = { | |||
415 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, | 457 | .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, |
416 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, | 458 | .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, |
417 | .find_pll = intel_find_best_PLL, | 459 | .find_pll = intel_find_best_PLL, |
418 | }, | 460 | }; |
419 | { /* INTEL_LIMIT_IGDNG_SDVO_DAC */ | 461 | |
462 | static const intel_limit_t intel_limits_igdng_sdvo = { | ||
420 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, | 463 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, |
421 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, | 464 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, |
422 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, | 465 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, |
@@ -429,8 +472,9 @@ static const intel_limit_t intel_limits[] = { | |||
429 | .p2_slow = IGDNG_P2_SDVO_DAC_SLOW, | 472 | .p2_slow = IGDNG_P2_SDVO_DAC_SLOW, |
430 | .p2_fast = IGDNG_P2_SDVO_DAC_FAST }, | 473 | .p2_fast = IGDNG_P2_SDVO_DAC_FAST }, |
431 | .find_pll = intel_igdng_find_best_PLL, | 474 | .find_pll = intel_igdng_find_best_PLL, |
432 | }, | 475 | }; |
433 | { /* INTEL_LIMIT_IGDNG_LVDS */ | 476 | |
477 | static const intel_limit_t intel_limits_igdng_lvds = { | ||
434 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, | 478 | .dot = { .min = IGDNG_DOT_MIN, .max = IGDNG_DOT_MAX }, |
435 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, | 479 | .vco = { .min = IGDNG_VCO_MIN, .max = IGDNG_VCO_MAX }, |
436 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, | 480 | .n = { .min = IGDNG_N_MIN, .max = IGDNG_N_MAX }, |
@@ -443,16 +487,15 @@ static const intel_limit_t intel_limits[] = { | |||
443 | .p2_slow = IGDNG_P2_LVDS_SLOW, | 487 | .p2_slow = IGDNG_P2_LVDS_SLOW, |
444 | .p2_fast = IGDNG_P2_LVDS_FAST }, | 488 | .p2_fast = IGDNG_P2_LVDS_FAST }, |
445 | .find_pll = intel_igdng_find_best_PLL, | 489 | .find_pll = intel_igdng_find_best_PLL, |
446 | }, | ||
447 | }; | 490 | }; |
448 | 491 | ||
449 | static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc) | 492 | static const intel_limit_t *intel_igdng_limit(struct drm_crtc *crtc) |
450 | { | 493 | { |
451 | const intel_limit_t *limit; | 494 | const intel_limit_t *limit; |
452 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 495 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
453 | limit = &intel_limits[INTEL_LIMIT_IGDNG_LVDS]; | 496 | limit = &intel_limits_igdng_lvds; |
454 | else | 497 | else |
455 | limit = &intel_limits[INTEL_LIMIT_IGDNG_SDVO_DAC]; | 498 | limit = &intel_limits_igdng_sdvo; |
456 | 499 | ||
457 | return limit; | 500 | return limit; |
458 | } | 501 | } |
@@ -467,19 +510,19 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) | |||
467 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == | 510 | if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == |
468 | LVDS_CLKB_POWER_UP) | 511 | LVDS_CLKB_POWER_UP) |
469 | /* LVDS with dual channel */ | 512 | /* LVDS with dual channel */ |
470 | limit = &intel_limits | 513 | limit = &intel_limits_g4x_dual_channel_lvds; |
471 | [INTEL_LIMIT_G4X_DUAL_CHANNEL_LVDS]; | ||
472 | else | 514 | else |
473 | /* LVDS with dual channel */ | 515 | /* LVDS with dual channel */ |
474 | limit = &intel_limits | 516 | limit = &intel_limits_g4x_single_channel_lvds; |
475 | [INTEL_LIMIT_G4X_SINGLE_CHANNEL_LVDS]; | ||
476 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || | 517 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || |
477 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { | 518 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { |
478 | limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; | 519 | limit = &intel_limits_g4x_hdmi; |
479 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { | 520 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { |
480 | limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; | 521 | limit = &intel_limits_g4x_sdvo; |
522 | } else if (intel_pipe_has_type (crtc, INTEL_OUTPUT_DISPLAYPORT)) { | ||
523 | limit = &intel_limits_g4x_display_port; | ||
481 | } else /* The option is for other outputs */ | 524 | } else /* The option is for other outputs */ |
482 | limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; | 525 | limit = &intel_limits_i9xx_sdvo; |
483 | 526 | ||
484 | return limit; | 527 | return limit; |
485 | } | 528 | } |
@@ -495,19 +538,19 @@ static const intel_limit_t *intel_limit(struct drm_crtc *crtc) | |||
495 | limit = intel_g4x_limit(crtc); | 538 | limit = intel_g4x_limit(crtc); |
496 | } else if (IS_I9XX(dev) && !IS_IGD(dev)) { | 539 | } else if (IS_I9XX(dev) && !IS_IGD(dev)) { |
497 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 540 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
498 | limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; | 541 | limit = &intel_limits_i9xx_lvds; |
499 | else | 542 | else |
500 | limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; | 543 | limit = &intel_limits_i9xx_sdvo; |
501 | } else if (IS_IGD(dev)) { | 544 | } else if (IS_IGD(dev)) { |
502 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 545 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
503 | limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; | 546 | limit = &intel_limits_igd_lvds; |
504 | else | 547 | else |
505 | limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; | 548 | limit = &intel_limits_igd_sdvo; |
506 | } else { | 549 | } else { |
507 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | 550 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
508 | limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; | 551 | limit = &intel_limits_i8xx_lvds; |
509 | else | 552 | else |
510 | limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; | 553 | limit = &intel_limits_i8xx_dvo; |
511 | } | 554 | } |
512 | return limit; | 555 | return limit; |
513 | } | 556 | } |
@@ -764,6 +807,35 @@ out: | |||
764 | return found; | 807 | return found; |
765 | } | 808 | } |
766 | 809 | ||
810 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ | ||
811 | static bool | ||
812 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | ||
813 | int target, int refclk, intel_clock_t *best_clock) | ||
814 | { | ||
815 | intel_clock_t clock; | ||
816 | if (target < 200000) { | ||
817 | clock.dot = 161670; | ||
818 | clock.p = 20; | ||
819 | clock.p1 = 2; | ||
820 | clock.p2 = 10; | ||
821 | clock.n = 0x01; | ||
822 | clock.m = 97; | ||
823 | clock.m1 = 0x10; | ||
824 | clock.m2 = 0x05; | ||
825 | } else { | ||
826 | clock.dot = 270000; | ||
827 | clock.p = 10; | ||
828 | clock.p1 = 1; | ||
829 | clock.p2 = 10; | ||
830 | clock.n = 0x02; | ||
831 | clock.m = 108; | ||
832 | clock.m1 = 0x12; | ||
833 | clock.m2 = 0x06; | ||
834 | } | ||
835 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | ||
836 | return true; | ||
837 | } | ||
838 | |||
767 | void | 839 | void |
768 | intel_wait_for_vblank(struct drm_device *dev) | 840 | intel_wait_for_vblank(struct drm_device *dev) |
769 | { | 841 | { |
@@ -1541,7 +1613,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1541 | intel_clock_t clock; | 1613 | intel_clock_t clock; |
1542 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; | 1614 | u32 dpll = 0, fp = 0, dspcntr, pipeconf; |
1543 | bool ok, is_sdvo = false, is_dvo = false; | 1615 | bool ok, is_sdvo = false, is_dvo = false; |
1544 | bool is_crt = false, is_lvds = false, is_tv = false; | 1616 | bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; |
1545 | struct drm_mode_config *mode_config = &dev->mode_config; | 1617 | struct drm_mode_config *mode_config = &dev->mode_config; |
1546 | struct drm_connector *connector; | 1618 | struct drm_connector *connector; |
1547 | const intel_limit_t *limit; | 1619 | const intel_limit_t *limit; |
@@ -1585,6 +1657,9 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1585 | case INTEL_OUTPUT_ANALOG: | 1657 | case INTEL_OUTPUT_ANALOG: |
1586 | is_crt = true; | 1658 | is_crt = true; |
1587 | break; | 1659 | break; |
1660 | case INTEL_OUTPUT_DISPLAYPORT: | ||
1661 | is_dp = true; | ||
1662 | break; | ||
1588 | } | 1663 | } |
1589 | 1664 | ||
1590 | num_outputs++; | 1665 | num_outputs++; |
@@ -1600,6 +1675,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1600 | } else { | 1675 | } else { |
1601 | refclk = 48000; | 1676 | refclk = 48000; |
1602 | } | 1677 | } |
1678 | |||
1603 | 1679 | ||
1604 | /* | 1680 | /* |
1605 | * Returns a set of divisors for the desired target clock with the given | 1681 | * Returns a set of divisors for the desired target clock with the given |
@@ -1662,6 +1738,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1662 | else if (IS_IGDNG(dev)) | 1738 | else if (IS_IGDNG(dev)) |
1663 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; | 1739 | dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; |
1664 | } | 1740 | } |
1741 | if (is_dp) | ||
1742 | dpll |= DPLL_DVO_HIGH_SPEED; | ||
1665 | 1743 | ||
1666 | /* compute bitmask from p1 value */ | 1744 | /* compute bitmask from p1 value */ |
1667 | if (IS_IGD(dev)) | 1745 | if (IS_IGD(dev)) |
@@ -1809,6 +1887,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
1809 | I915_WRITE(lvds_reg, lvds); | 1887 | I915_WRITE(lvds_reg, lvds); |
1810 | I915_READ(lvds_reg); | 1888 | I915_READ(lvds_reg); |
1811 | } | 1889 | } |
1890 | if (is_dp) | ||
1891 | intel_dp_set_m_n(crtc, mode, adjusted_mode); | ||
1812 | 1892 | ||
1813 | I915_WRITE(fp_reg, fp); | 1893 | I915_WRITE(fp_reg, fp); |
1814 | I915_WRITE(dpll_reg, dpll); | 1894 | I915_WRITE(dpll_reg, dpll); |
@@ -2475,6 +2555,8 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2475 | found = intel_sdvo_init(dev, SDVOB); | 2555 | found = intel_sdvo_init(dev, SDVOB); |
2476 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 2556 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) |
2477 | intel_hdmi_init(dev, SDVOB); | 2557 | intel_hdmi_init(dev, SDVOB); |
2558 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | ||
2559 | intel_dp_init(dev, DP_B); | ||
2478 | } | 2560 | } |
2479 | 2561 | ||
2480 | /* Before G4X SDVOC doesn't have its own detect register */ | 2562 | /* Before G4X SDVOC doesn't have its own detect register */ |
@@ -2487,7 +2569,11 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2487 | found = intel_sdvo_init(dev, SDVOC); | 2569 | found = intel_sdvo_init(dev, SDVOC); |
2488 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) | 2570 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) |
2489 | intel_hdmi_init(dev, SDVOC); | 2571 | intel_hdmi_init(dev, SDVOC); |
2572 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) | ||
2573 | intel_dp_init(dev, DP_C); | ||
2490 | } | 2574 | } |
2575 | if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) | ||
2576 | intel_dp_init(dev, DP_D); | ||
2491 | } else | 2577 | } else |
2492 | intel_dvo_init(dev); | 2578 | intel_dvo_init(dev); |
2493 | 2579 | ||
@@ -2530,6 +2616,11 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
2530 | (1 << 1)); | 2616 | (1 << 1)); |
2531 | clone_mask = (1 << INTEL_OUTPUT_TVOUT); | 2617 | clone_mask = (1 << INTEL_OUTPUT_TVOUT); |
2532 | break; | 2618 | break; |
2619 | case INTEL_OUTPUT_DISPLAYPORT: | ||
2620 | crtc_mask = ((1 << 0) | | ||
2621 | (1 << 1)); | ||
2622 | clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT); | ||
2623 | break; | ||
2533 | } | 2624 | } |
2534 | encoder->possible_crtcs = crtc_mask; | 2625 | encoder->possible_crtcs = crtc_mask; |
2535 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); | 2626 | encoder->possible_clones = intel_connector_clones(dev, clone_mask); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c new file mode 100644 index 000000000000..8f8d37d5663a --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -0,0 +1,1153 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Intel Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | * | ||
23 | * Authors: | ||
24 | * Keith Packard <keithp@keithp.com> | ||
25 | * | ||
26 | */ | ||
27 | |||
28 | #include <linux/i2c.h> | ||
29 | #include "drmP.h" | ||
30 | #include "drm.h" | ||
31 | #include "drm_crtc.h" | ||
32 | #include "drm_crtc_helper.h" | ||
33 | #include "intel_drv.h" | ||
34 | #include "i915_drm.h" | ||
35 | #include "i915_drv.h" | ||
36 | #include "intel_dp.h" | ||
37 | |||
38 | #define DP_LINK_STATUS_SIZE 6 | ||
39 | #define DP_LINK_CHECK_TIMEOUT (10 * 1000) | ||
40 | |||
41 | #define DP_LINK_CONFIGURATION_SIZE 9 | ||
42 | |||
43 | struct intel_dp_priv { | ||
44 | uint32_t output_reg; | ||
45 | uint32_t DP; | ||
46 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
47 | uint32_t save_DP; | ||
48 | uint8_t save_link_configuration[DP_LINK_CONFIGURATION_SIZE]; | ||
49 | bool has_audio; | ||
50 | int dpms_mode; | ||
51 | uint8_t link_bw; | ||
52 | uint8_t lane_count; | ||
53 | uint8_t dpcd[4]; | ||
54 | struct intel_output *intel_output; | ||
55 | struct i2c_adapter adapter; | ||
56 | struct i2c_algo_dp_aux_data algo; | ||
57 | }; | ||
58 | |||
59 | static void | ||
60 | intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | ||
61 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); | ||
62 | |||
63 | static void | ||
64 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP); | ||
65 | |||
66 | static int | ||
67 | intel_dp_max_lane_count(struct intel_output *intel_output) | ||
68 | { | ||
69 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
70 | int max_lane_count = 4; | ||
71 | |||
72 | if (dp_priv->dpcd[0] >= 0x11) { | ||
73 | max_lane_count = dp_priv->dpcd[2] & 0x1f; | ||
74 | switch (max_lane_count) { | ||
75 | case 1: case 2: case 4: | ||
76 | break; | ||
77 | default: | ||
78 | max_lane_count = 4; | ||
79 | } | ||
80 | } | ||
81 | return max_lane_count; | ||
82 | } | ||
83 | |||
84 | static int | ||
85 | intel_dp_max_link_bw(struct intel_output *intel_output) | ||
86 | { | ||
87 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
88 | int max_link_bw = dp_priv->dpcd[1]; | ||
89 | |||
90 | switch (max_link_bw) { | ||
91 | case DP_LINK_BW_1_62: | ||
92 | case DP_LINK_BW_2_7: | ||
93 | break; | ||
94 | default: | ||
95 | max_link_bw = DP_LINK_BW_1_62; | ||
96 | break; | ||
97 | } | ||
98 | return max_link_bw; | ||
99 | } | ||
100 | |||
101 | static int | ||
102 | intel_dp_link_clock(uint8_t link_bw) | ||
103 | { | ||
104 | if (link_bw == DP_LINK_BW_2_7) | ||
105 | return 270000; | ||
106 | else | ||
107 | return 162000; | ||
108 | } | ||
109 | |||
110 | /* I think this is a fiction */ | ||
111 | static int | ||
112 | intel_dp_link_required(int pixel_clock) | ||
113 | { | ||
114 | return pixel_clock * 3; | ||
115 | } | ||
116 | |||
117 | static int | ||
118 | intel_dp_mode_valid(struct drm_connector *connector, | ||
119 | struct drm_display_mode *mode) | ||
120 | { | ||
121 | struct intel_output *intel_output = to_intel_output(connector); | ||
122 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_output)); | ||
123 | int max_lanes = intel_dp_max_lane_count(intel_output); | ||
124 | |||
125 | if (intel_dp_link_required(mode->clock) > max_link_clock * max_lanes) | ||
126 | return MODE_CLOCK_HIGH; | ||
127 | |||
128 | if (mode->clock < 10000) | ||
129 | return MODE_CLOCK_LOW; | ||
130 | |||
131 | return MODE_OK; | ||
132 | } | ||
133 | |||
134 | static uint32_t | ||
135 | pack_aux(uint8_t *src, int src_bytes) | ||
136 | { | ||
137 | int i; | ||
138 | uint32_t v = 0; | ||
139 | |||
140 | if (src_bytes > 4) | ||
141 | src_bytes = 4; | ||
142 | for (i = 0; i < src_bytes; i++) | ||
143 | v |= ((uint32_t) src[i]) << ((3-i) * 8); | ||
144 | return v; | ||
145 | } | ||
146 | |||
147 | static void | ||
148 | unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) | ||
149 | { | ||
150 | int i; | ||
151 | if (dst_bytes > 4) | ||
152 | dst_bytes = 4; | ||
153 | for (i = 0; i < dst_bytes; i++) | ||
154 | dst[i] = src >> ((3-i) * 8); | ||
155 | } | ||
156 | |||
157 | /* hrawclock is 1/4 the FSB frequency */ | ||
158 | static int | ||
159 | intel_hrawclk(struct drm_device *dev) | ||
160 | { | ||
161 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
162 | uint32_t clkcfg; | ||
163 | |||
164 | clkcfg = I915_READ(CLKCFG); | ||
165 | switch (clkcfg & CLKCFG_FSB_MASK) { | ||
166 | case CLKCFG_FSB_400: | ||
167 | return 100; | ||
168 | case CLKCFG_FSB_533: | ||
169 | return 133; | ||
170 | case CLKCFG_FSB_667: | ||
171 | return 166; | ||
172 | case CLKCFG_FSB_800: | ||
173 | return 200; | ||
174 | case CLKCFG_FSB_1067: | ||
175 | return 266; | ||
176 | case CLKCFG_FSB_1333: | ||
177 | return 333; | ||
178 | /* these two are just a guess; one of them might be right */ | ||
179 | case CLKCFG_FSB_1600: | ||
180 | case CLKCFG_FSB_1600_ALT: | ||
181 | return 400; | ||
182 | default: | ||
183 | return 133; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | static int | ||
188 | intel_dp_aux_ch(struct intel_output *intel_output, | ||
189 | uint8_t *send, int send_bytes, | ||
190 | uint8_t *recv, int recv_size) | ||
191 | { | ||
192 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
193 | uint32_t output_reg = dp_priv->output_reg; | ||
194 | struct drm_device *dev = intel_output->base.dev; | ||
195 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
196 | uint32_t ch_ctl = output_reg + 0x10; | ||
197 | uint32_t ch_data = ch_ctl + 4; | ||
198 | int i; | ||
199 | int recv_bytes; | ||
200 | uint32_t ctl; | ||
201 | uint32_t status; | ||
202 | uint32_t aux_clock_divider; | ||
203 | int try; | ||
204 | |||
205 | /* The clock divider is based off the hrawclk, | ||
206 | * and would like to run at 2MHz. So, take the | ||
207 | * hrawclk value and divide by 2 and use that | ||
208 | */ | ||
209 | aux_clock_divider = intel_hrawclk(dev) / 2; | ||
210 | /* Must try at least 3 times according to DP spec */ | ||
211 | for (try = 0; try < 5; try++) { | ||
212 | /* Load the send data into the aux channel data registers */ | ||
213 | for (i = 0; i < send_bytes; i += 4) { | ||
214 | uint32_t d = pack_aux(send + i, send_bytes - i);; | ||
215 | |||
216 | I915_WRITE(ch_data + i, d); | ||
217 | } | ||
218 | |||
219 | ctl = (DP_AUX_CH_CTL_SEND_BUSY | | ||
220 | DP_AUX_CH_CTL_TIME_OUT_400us | | ||
221 | (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | | ||
222 | (5 << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | | ||
223 | (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | | ||
224 | DP_AUX_CH_CTL_DONE | | ||
225 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
226 | DP_AUX_CH_CTL_RECEIVE_ERROR); | ||
227 | |||
228 | /* Send the command and wait for it to complete */ | ||
229 | I915_WRITE(ch_ctl, ctl); | ||
230 | (void) I915_READ(ch_ctl); | ||
231 | for (;;) { | ||
232 | udelay(100); | ||
233 | status = I915_READ(ch_ctl); | ||
234 | if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) | ||
235 | break; | ||
236 | } | ||
237 | |||
238 | /* Clear done status and any errors */ | ||
239 | I915_WRITE(ch_ctl, (ctl | | ||
240 | DP_AUX_CH_CTL_DONE | | ||
241 | DP_AUX_CH_CTL_TIME_OUT_ERROR | | ||
242 | DP_AUX_CH_CTL_RECEIVE_ERROR)); | ||
243 | (void) I915_READ(ch_ctl); | ||
244 | if ((status & DP_AUX_CH_CTL_TIME_OUT_ERROR) == 0) | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | if ((status & DP_AUX_CH_CTL_DONE) == 0) { | ||
249 | printk(KERN_ERR "dp_aux_ch not done status 0x%08x\n", status); | ||
250 | return -EBUSY; | ||
251 | } | ||
252 | |||
253 | /* Check for timeout or receive error. | ||
254 | * Timeouts occur when the sink is not connected | ||
255 | */ | ||
256 | if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { | ||
257 | printk(KERN_ERR "dp_aux_ch receive error status 0x%08x\n", status); | ||
258 | return -EIO; | ||
259 | } | ||
260 | if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { | ||
261 | printk(KERN_ERR "dp_aux_ch timeout status 0x%08x\n", status); | ||
262 | return -ETIMEDOUT; | ||
263 | } | ||
264 | |||
265 | /* Unload any bytes sent back from the other side */ | ||
266 | recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> | ||
267 | DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); | ||
268 | |||
269 | if (recv_bytes > recv_size) | ||
270 | recv_bytes = recv_size; | ||
271 | |||
272 | for (i = 0; i < recv_bytes; i += 4) { | ||
273 | uint32_t d = I915_READ(ch_data + i); | ||
274 | |||
275 | unpack_aux(d, recv + i, recv_bytes - i); | ||
276 | } | ||
277 | |||
278 | return recv_bytes; | ||
279 | } | ||
280 | |||
281 | /* Write data to the aux channel in native mode */ | ||
282 | static int | ||
283 | intel_dp_aux_native_write(struct intel_output *intel_output, | ||
284 | uint16_t address, uint8_t *send, int send_bytes) | ||
285 | { | ||
286 | int ret; | ||
287 | uint8_t msg[20]; | ||
288 | int msg_bytes; | ||
289 | uint8_t ack; | ||
290 | |||
291 | if (send_bytes > 16) | ||
292 | return -1; | ||
293 | msg[0] = AUX_NATIVE_WRITE << 4; | ||
294 | msg[1] = address >> 8; | ||
295 | msg[2] = address; | ||
296 | msg[3] = send_bytes - 1; | ||
297 | memcpy(&msg[4], send, send_bytes); | ||
298 | msg_bytes = send_bytes + 4; | ||
299 | for (;;) { | ||
300 | ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, &ack, 1); | ||
301 | if (ret < 0) | ||
302 | return ret; | ||
303 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) | ||
304 | break; | ||
305 | else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) | ||
306 | udelay(100); | ||
307 | else | ||
308 | return -EIO; | ||
309 | } | ||
310 | return send_bytes; | ||
311 | } | ||
312 | |||
313 | /* Write a single byte to the aux channel in native mode */ | ||
314 | static int | ||
315 | intel_dp_aux_native_write_1(struct intel_output *intel_output, | ||
316 | uint16_t address, uint8_t byte) | ||
317 | { | ||
318 | return intel_dp_aux_native_write(intel_output, address, &byte, 1); | ||
319 | } | ||
320 | |||
321 | /* read bytes from a native aux channel */ | ||
322 | static int | ||
323 | intel_dp_aux_native_read(struct intel_output *intel_output, | ||
324 | uint16_t address, uint8_t *recv, int recv_bytes) | ||
325 | { | ||
326 | uint8_t msg[4]; | ||
327 | int msg_bytes; | ||
328 | uint8_t reply[20]; | ||
329 | int reply_bytes; | ||
330 | uint8_t ack; | ||
331 | int ret; | ||
332 | |||
333 | msg[0] = AUX_NATIVE_READ << 4; | ||
334 | msg[1] = address >> 8; | ||
335 | msg[2] = address & 0xff; | ||
336 | msg[3] = recv_bytes - 1; | ||
337 | |||
338 | msg_bytes = 4; | ||
339 | reply_bytes = recv_bytes + 1; | ||
340 | |||
341 | for (;;) { | ||
342 | ret = intel_dp_aux_ch(intel_output, msg, msg_bytes, | ||
343 | reply, reply_bytes); | ||
344 | if (ret == 0) | ||
345 | return -EPROTO; | ||
346 | if (ret < 0) | ||
347 | return ret; | ||
348 | ack = reply[0]; | ||
349 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) { | ||
350 | memcpy(recv, reply + 1, ret - 1); | ||
351 | return ret - 1; | ||
352 | } | ||
353 | else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER) | ||
354 | udelay(100); | ||
355 | else | ||
356 | return -EIO; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static int | ||
361 | intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, | ||
362 | uint8_t *send, int send_bytes, | ||
363 | uint8_t *recv, int recv_bytes) | ||
364 | { | ||
365 | struct intel_dp_priv *dp_priv = container_of(adapter, | ||
366 | struct intel_dp_priv, | ||
367 | adapter); | ||
368 | struct intel_output *intel_output = dp_priv->intel_output; | ||
369 | |||
370 | return intel_dp_aux_ch(intel_output, | ||
371 | send, send_bytes, recv, recv_bytes); | ||
372 | } | ||
373 | |||
374 | static int | ||
375 | intel_dp_i2c_init(struct intel_output *intel_output, const char *name) | ||
376 | { | ||
377 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
378 | |||
379 | DRM_ERROR("i2c_init %s\n", name); | ||
380 | dp_priv->algo.running = false; | ||
381 | dp_priv->algo.address = 0; | ||
382 | dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; | ||
383 | |||
384 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); | ||
385 | dp_priv->adapter.owner = THIS_MODULE; | ||
386 | dp_priv->adapter.class = I2C_CLASS_DDC; | ||
387 | strncpy (dp_priv->adapter.name, name, sizeof dp_priv->adapter.name - 1); | ||
388 | dp_priv->adapter.name[sizeof dp_priv->adapter.name - 1] = '\0'; | ||
389 | dp_priv->adapter.algo_data = &dp_priv->algo; | ||
390 | dp_priv->adapter.dev.parent = &intel_output->base.kdev; | ||
391 | |||
392 | return i2c_dp_aux_add_bus(&dp_priv->adapter); | ||
393 | } | ||
394 | |||
395 | static bool | ||
396 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | ||
397 | struct drm_display_mode *adjusted_mode) | ||
398 | { | ||
399 | struct intel_output *intel_output = enc_to_intel_output(encoder); | ||
400 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
401 | int lane_count, clock; | ||
402 | int max_lane_count = intel_dp_max_lane_count(intel_output); | ||
403 | int max_clock = intel_dp_max_link_bw(intel_output) == DP_LINK_BW_2_7 ? 1 : 0; | ||
404 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | ||
405 | |||
406 | for (lane_count = 1; lane_count <= max_lane_count; lane_count <<= 1) { | ||
407 | for (clock = 0; clock <= max_clock; clock++) { | ||
408 | int link_avail = intel_dp_link_clock(bws[clock]) * lane_count; | ||
409 | |||
410 | if (intel_dp_link_required(mode->clock) <= link_avail) { | ||
411 | dp_priv->link_bw = bws[clock]; | ||
412 | dp_priv->lane_count = lane_count; | ||
413 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | ||
414 | printk(KERN_ERR "link bw %02x lane count %d clock %d\n", | ||
415 | dp_priv->link_bw, dp_priv->lane_count, | ||
416 | adjusted_mode->clock); | ||
417 | return true; | ||
418 | } | ||
419 | } | ||
420 | } | ||
421 | return false; | ||
422 | } | ||
423 | |||
424 | struct intel_dp_m_n { | ||
425 | uint32_t tu; | ||
426 | uint32_t gmch_m; | ||
427 | uint32_t gmch_n; | ||
428 | uint32_t link_m; | ||
429 | uint32_t link_n; | ||
430 | }; | ||
431 | |||
432 | static void | ||
433 | intel_reduce_ratio(uint32_t *num, uint32_t *den) | ||
434 | { | ||
435 | while (*num > 0xffffff || *den > 0xffffff) { | ||
436 | *num >>= 1; | ||
437 | *den >>= 1; | ||
438 | } | ||
439 | } | ||
440 | |||
441 | static void | ||
442 | intel_dp_compute_m_n(int bytes_per_pixel, | ||
443 | int nlanes, | ||
444 | int pixel_clock, | ||
445 | int link_clock, | ||
446 | struct intel_dp_m_n *m_n) | ||
447 | { | ||
448 | m_n->tu = 64; | ||
449 | m_n->gmch_m = pixel_clock * bytes_per_pixel; | ||
450 | m_n->gmch_n = link_clock * nlanes; | ||
451 | intel_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | ||
452 | m_n->link_m = pixel_clock; | ||
453 | m_n->link_n = link_clock; | ||
454 | intel_reduce_ratio(&m_n->link_m, &m_n->link_n); | ||
455 | } | ||
456 | |||
457 | void | ||
458 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | ||
459 | struct drm_display_mode *adjusted_mode) | ||
460 | { | ||
461 | struct drm_device *dev = crtc->dev; | ||
462 | struct drm_mode_config *mode_config = &dev->mode_config; | ||
463 | struct drm_connector *connector; | ||
464 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
465 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
466 | int lane_count = 4; | ||
467 | struct intel_dp_m_n m_n; | ||
468 | |||
469 | /* | ||
470 | * Find the lane count in the intel_output private | ||
471 | */ | ||
472 | list_for_each_entry(connector, &mode_config->connector_list, head) { | ||
473 | struct intel_output *intel_output = to_intel_output(connector); | ||
474 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
475 | |||
476 | if (!connector->encoder || connector->encoder->crtc != crtc) | ||
477 | continue; | ||
478 | |||
479 | if (intel_output->type == INTEL_OUTPUT_DISPLAYPORT) { | ||
480 | lane_count = dp_priv->lane_count; | ||
481 | break; | ||
482 | } | ||
483 | } | ||
484 | |||
485 | /* | ||
486 | * Compute the GMCH and Link ratios. The '3' here is | ||
487 | * the number of bytes_per_pixel post-LUT, which we always | ||
488 | * set up for 8-bits of R/G/B, or 3 bytes total. | ||
489 | */ | ||
490 | intel_dp_compute_m_n(3, lane_count, | ||
491 | mode->clock, adjusted_mode->clock, &m_n); | ||
492 | |||
493 | if (intel_crtc->pipe == 0) { | ||
494 | I915_WRITE(PIPEA_GMCH_DATA_M, | ||
495 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
496 | m_n.gmch_m); | ||
497 | I915_WRITE(PIPEA_GMCH_DATA_N, | ||
498 | m_n.gmch_n); | ||
499 | I915_WRITE(PIPEA_DP_LINK_M, m_n.link_m); | ||
500 | I915_WRITE(PIPEA_DP_LINK_N, m_n.link_n); | ||
501 | } else { | ||
502 | I915_WRITE(PIPEB_GMCH_DATA_M, | ||
503 | ((m_n.tu - 1) << PIPE_GMCH_DATA_M_TU_SIZE_SHIFT) | | ||
504 | m_n.gmch_m); | ||
505 | I915_WRITE(PIPEB_GMCH_DATA_N, | ||
506 | m_n.gmch_n); | ||
507 | I915_WRITE(PIPEB_DP_LINK_M, m_n.link_m); | ||
508 | I915_WRITE(PIPEB_DP_LINK_N, m_n.link_n); | ||
509 | } | ||
510 | } | ||
511 | |||
512 | static void | ||
513 | intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | ||
514 | struct drm_display_mode *adjusted_mode) | ||
515 | { | ||
516 | struct intel_output *intel_output = enc_to_intel_output(encoder); | ||
517 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
518 | struct drm_crtc *crtc = intel_output->enc.crtc; | ||
519 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
520 | |||
521 | dp_priv->DP = (DP_LINK_TRAIN_OFF | | ||
522 | DP_VOLTAGE_0_4 | | ||
523 | DP_PRE_EMPHASIS_0 | | ||
524 | DP_SYNC_VS_HIGH | | ||
525 | DP_SYNC_HS_HIGH); | ||
526 | |||
527 | switch (dp_priv->lane_count) { | ||
528 | case 1: | ||
529 | dp_priv->DP |= DP_PORT_WIDTH_1; | ||
530 | break; | ||
531 | case 2: | ||
532 | dp_priv->DP |= DP_PORT_WIDTH_2; | ||
533 | break; | ||
534 | case 4: | ||
535 | dp_priv->DP |= DP_PORT_WIDTH_4; | ||
536 | break; | ||
537 | } | ||
538 | if (dp_priv->has_audio) | ||
539 | dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE; | ||
540 | |||
541 | memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | ||
542 | dp_priv->link_configuration[0] = dp_priv->link_bw; | ||
543 | dp_priv->link_configuration[1] = dp_priv->lane_count; | ||
544 | |||
545 | /* | ||
546 | * Check for DPCD version > 1.1, | ||
547 | * enable enahanced frame stuff in that case | ||
548 | */ | ||
549 | if (dp_priv->dpcd[0] >= 0x11) { | ||
550 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | ||
551 | dp_priv->DP |= DP_ENHANCED_FRAMING; | ||
552 | } | ||
553 | |||
554 | if (intel_crtc->pipe == 1) | ||
555 | dp_priv->DP |= DP_PIPEB_SELECT; | ||
556 | } | ||
557 | |||
558 | |||
559 | static void | ||
560 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | ||
561 | { | ||
562 | struct intel_output *intel_output = enc_to_intel_output(encoder); | ||
563 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
564 | struct drm_device *dev = intel_output->base.dev; | ||
565 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
566 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | ||
567 | |||
568 | if (mode != DRM_MODE_DPMS_ON) { | ||
569 | if (dp_reg & DP_PORT_EN) | ||
570 | intel_dp_link_down(intel_output, dp_priv->DP); | ||
571 | } else { | ||
572 | if (!(dp_reg & DP_PORT_EN)) | ||
573 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | ||
574 | } | ||
575 | dp_priv->dpms_mode = mode; | ||
576 | } | ||
577 | |||
578 | /* | ||
579 | * Fetch AUX CH registers 0x202 - 0x207 which contain | ||
580 | * link status information | ||
581 | */ | ||
582 | static bool | ||
583 | intel_dp_get_link_status(struct intel_output *intel_output, | ||
584 | uint8_t link_status[DP_LINK_STATUS_SIZE]) | ||
585 | { | ||
586 | int ret; | ||
587 | |||
588 | ret = intel_dp_aux_native_read(intel_output, | ||
589 | DP_LANE0_1_STATUS, | ||
590 | link_status, DP_LINK_STATUS_SIZE); | ||
591 | if (ret != DP_LINK_STATUS_SIZE) | ||
592 | return false; | ||
593 | return true; | ||
594 | } | ||
595 | |||
596 | static uint8_t | ||
597 | intel_dp_link_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
598 | int r) | ||
599 | { | ||
600 | return link_status[r - DP_LANE0_1_STATUS]; | ||
601 | } | ||
602 | |||
603 | static void | ||
604 | intel_dp_save(struct drm_connector *connector) | ||
605 | { | ||
606 | struct intel_output *intel_output = to_intel_output(connector); | ||
607 | struct drm_device *dev = intel_output->base.dev; | ||
608 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
609 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
610 | |||
611 | dp_priv->save_DP = I915_READ(dp_priv->output_reg); | ||
612 | intel_dp_aux_native_read(intel_output, DP_LINK_BW_SET, | ||
613 | dp_priv->save_link_configuration, | ||
614 | sizeof (dp_priv->save_link_configuration)); | ||
615 | } | ||
616 | |||
617 | static uint8_t | ||
618 | intel_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
619 | int lane) | ||
620 | { | ||
621 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
622 | int s = ((lane & 1) ? | ||
623 | DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT : | ||
624 | DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT); | ||
625 | uint8_t l = intel_dp_link_status(link_status, i); | ||
626 | |||
627 | return ((l >> s) & 3) << DP_TRAIN_VOLTAGE_SWING_SHIFT; | ||
628 | } | ||
629 | |||
630 | static uint8_t | ||
631 | intel_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
632 | int lane) | ||
633 | { | ||
634 | int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1); | ||
635 | int s = ((lane & 1) ? | ||
636 | DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT : | ||
637 | DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT); | ||
638 | uint8_t l = intel_dp_link_status(link_status, i); | ||
639 | |||
640 | return ((l >> s) & 3) << DP_TRAIN_PRE_EMPHASIS_SHIFT; | ||
641 | } | ||
642 | |||
643 | |||
644 | #if 0 | ||
645 | static char *voltage_names[] = { | ||
646 | "0.4V", "0.6V", "0.8V", "1.2V" | ||
647 | }; | ||
648 | static char *pre_emph_names[] = { | ||
649 | "0dB", "3.5dB", "6dB", "9.5dB" | ||
650 | }; | ||
651 | static char *link_train_names[] = { | ||
652 | "pattern 1", "pattern 2", "idle", "off" | ||
653 | }; | ||
654 | #endif | ||
655 | |||
656 | /* | ||
657 | * These are source-specific values; current Intel hardware supports | ||
658 | * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB | ||
659 | */ | ||
660 | #define I830_DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_800 | ||
661 | |||
662 | static uint8_t | ||
663 | intel_dp_pre_emphasis_max(uint8_t voltage_swing) | ||
664 | { | ||
665 | switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
666 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
667 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
668 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
669 | return DP_TRAIN_PRE_EMPHASIS_6; | ||
670 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
671 | return DP_TRAIN_PRE_EMPHASIS_3_5; | ||
672 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
673 | default: | ||
674 | return DP_TRAIN_PRE_EMPHASIS_0; | ||
675 | } | ||
676 | } | ||
677 | |||
678 | static void | ||
679 | intel_get_adjust_train(struct intel_output *intel_output, | ||
680 | uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
681 | int lane_count, | ||
682 | uint8_t train_set[4]) | ||
683 | { | ||
684 | uint8_t v = 0; | ||
685 | uint8_t p = 0; | ||
686 | int lane; | ||
687 | |||
688 | for (lane = 0; lane < lane_count; lane++) { | ||
689 | uint8_t this_v = intel_get_adjust_request_voltage(link_status, lane); | ||
690 | uint8_t this_p = intel_get_adjust_request_pre_emphasis(link_status, lane); | ||
691 | |||
692 | if (this_v > v) | ||
693 | v = this_v; | ||
694 | if (this_p > p) | ||
695 | p = this_p; | ||
696 | } | ||
697 | |||
698 | if (v >= I830_DP_VOLTAGE_MAX) | ||
699 | v = I830_DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED; | ||
700 | |||
701 | if (p >= intel_dp_pre_emphasis_max(v)) | ||
702 | p = intel_dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | ||
703 | |||
704 | for (lane = 0; lane < 4; lane++) | ||
705 | train_set[lane] = v | p; | ||
706 | } | ||
707 | |||
708 | static uint32_t | ||
709 | intel_dp_signal_levels(uint8_t train_set, int lane_count) | ||
710 | { | ||
711 | uint32_t signal_levels = 0; | ||
712 | |||
713 | switch (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) { | ||
714 | case DP_TRAIN_VOLTAGE_SWING_400: | ||
715 | default: | ||
716 | signal_levels |= DP_VOLTAGE_0_4; | ||
717 | break; | ||
718 | case DP_TRAIN_VOLTAGE_SWING_600: | ||
719 | signal_levels |= DP_VOLTAGE_0_6; | ||
720 | break; | ||
721 | case DP_TRAIN_VOLTAGE_SWING_800: | ||
722 | signal_levels |= DP_VOLTAGE_0_8; | ||
723 | break; | ||
724 | case DP_TRAIN_VOLTAGE_SWING_1200: | ||
725 | signal_levels |= DP_VOLTAGE_1_2; | ||
726 | break; | ||
727 | } | ||
728 | switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) { | ||
729 | case DP_TRAIN_PRE_EMPHASIS_0: | ||
730 | default: | ||
731 | signal_levels |= DP_PRE_EMPHASIS_0; | ||
732 | break; | ||
733 | case DP_TRAIN_PRE_EMPHASIS_3_5: | ||
734 | signal_levels |= DP_PRE_EMPHASIS_3_5; | ||
735 | break; | ||
736 | case DP_TRAIN_PRE_EMPHASIS_6: | ||
737 | signal_levels |= DP_PRE_EMPHASIS_6; | ||
738 | break; | ||
739 | case DP_TRAIN_PRE_EMPHASIS_9_5: | ||
740 | signal_levels |= DP_PRE_EMPHASIS_9_5; | ||
741 | break; | ||
742 | } | ||
743 | return signal_levels; | ||
744 | } | ||
745 | |||
746 | static uint8_t | ||
747 | intel_get_lane_status(uint8_t link_status[DP_LINK_STATUS_SIZE], | ||
748 | int lane) | ||
749 | { | ||
750 | int i = DP_LANE0_1_STATUS + (lane >> 1); | ||
751 | int s = (lane & 1) * 4; | ||
752 | uint8_t l = intel_dp_link_status(link_status, i); | ||
753 | |||
754 | return (l >> s) & 0xf; | ||
755 | } | ||
756 | |||
757 | /* Check for clock recovery is done on all channels */ | ||
758 | static bool | ||
759 | intel_clock_recovery_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | ||
760 | { | ||
761 | int lane; | ||
762 | uint8_t lane_status; | ||
763 | |||
764 | for (lane = 0; lane < lane_count; lane++) { | ||
765 | lane_status = intel_get_lane_status(link_status, lane); | ||
766 | if ((lane_status & DP_LANE_CR_DONE) == 0) | ||
767 | return false; | ||
768 | } | ||
769 | return true; | ||
770 | } | ||
771 | |||
772 | /* Check to see if channel eq is done on all channels */ | ||
773 | #define CHANNEL_EQ_BITS (DP_LANE_CR_DONE|\ | ||
774 | DP_LANE_CHANNEL_EQ_DONE|\ | ||
775 | DP_LANE_SYMBOL_LOCKED) | ||
776 | static bool | ||
777 | intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | ||
778 | { | ||
779 | uint8_t lane_align; | ||
780 | uint8_t lane_status; | ||
781 | int lane; | ||
782 | |||
783 | lane_align = intel_dp_link_status(link_status, | ||
784 | DP_LANE_ALIGN_STATUS_UPDATED); | ||
785 | if ((lane_align & DP_INTERLANE_ALIGN_DONE) == 0) | ||
786 | return false; | ||
787 | for (lane = 0; lane < lane_count; lane++) { | ||
788 | lane_status = intel_get_lane_status(link_status, lane); | ||
789 | if ((lane_status & CHANNEL_EQ_BITS) != CHANNEL_EQ_BITS) | ||
790 | return false; | ||
791 | } | ||
792 | return true; | ||
793 | } | ||
794 | |||
795 | static bool | ||
796 | intel_dp_set_link_train(struct intel_output *intel_output, | ||
797 | uint32_t dp_reg_value, | ||
798 | uint8_t dp_train_pat, | ||
799 | uint8_t train_set[4], | ||
800 | bool first) | ||
801 | { | ||
802 | struct drm_device *dev = intel_output->base.dev; | ||
803 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
804 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
805 | int ret; | ||
806 | |||
807 | I915_WRITE(dp_priv->output_reg, dp_reg_value); | ||
808 | POSTING_READ(dp_priv->output_reg); | ||
809 | if (first) | ||
810 | intel_wait_for_vblank(dev); | ||
811 | |||
812 | intel_dp_aux_native_write_1(intel_output, | ||
813 | DP_TRAINING_PATTERN_SET, | ||
814 | dp_train_pat); | ||
815 | |||
816 | ret = intel_dp_aux_native_write(intel_output, | ||
817 | DP_TRAINING_LANE0_SET, train_set, 4); | ||
818 | if (ret != 4) | ||
819 | return false; | ||
820 | |||
821 | return true; | ||
822 | } | ||
823 | |||
824 | static void | ||
825 | intel_dp_link_train(struct intel_output *intel_output, uint32_t DP, | ||
826 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
827 | { | ||
828 | struct drm_device *dev = intel_output->base.dev; | ||
829 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
830 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
831 | uint8_t train_set[4]; | ||
832 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
833 | int i; | ||
834 | uint8_t voltage; | ||
835 | bool clock_recovery = false; | ||
836 | bool channel_eq = false; | ||
837 | bool first = true; | ||
838 | int tries; | ||
839 | |||
840 | /* Write the link configuration data */ | ||
841 | intel_dp_aux_native_write(intel_output, 0x100, | ||
842 | link_configuration, DP_LINK_CONFIGURATION_SIZE); | ||
843 | |||
844 | DP |= DP_PORT_EN; | ||
845 | DP &= ~DP_LINK_TRAIN_MASK; | ||
846 | memset(train_set, 0, 4); | ||
847 | voltage = 0xff; | ||
848 | tries = 0; | ||
849 | clock_recovery = false; | ||
850 | for (;;) { | ||
851 | /* Use train_set[0] to set the voltage and pre emphasis values */ | ||
852 | uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | ||
853 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | ||
854 | |||
855 | if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_1, | ||
856 | DP_TRAINING_PATTERN_1, train_set, first)) | ||
857 | break; | ||
858 | first = false; | ||
859 | /* Set training pattern 1 */ | ||
860 | |||
861 | udelay(100); | ||
862 | if (!intel_dp_get_link_status(intel_output, link_status)) | ||
863 | break; | ||
864 | |||
865 | if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { | ||
866 | clock_recovery = true; | ||
867 | break; | ||
868 | } | ||
869 | |||
870 | /* Check to see if we've tried the max voltage */ | ||
871 | for (i = 0; i < dp_priv->lane_count; i++) | ||
872 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | ||
873 | break; | ||
874 | if (i == dp_priv->lane_count) | ||
875 | break; | ||
876 | |||
877 | /* Check to see if we've tried the same voltage 5 times */ | ||
878 | if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) { | ||
879 | ++tries; | ||
880 | if (tries == 5) | ||
881 | break; | ||
882 | } else | ||
883 | tries = 0; | ||
884 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | ||
885 | |||
886 | /* Compute new train_set as requested by target */ | ||
887 | intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); | ||
888 | } | ||
889 | |||
890 | /* channel equalization */ | ||
891 | tries = 0; | ||
892 | channel_eq = false; | ||
893 | for (;;) { | ||
894 | /* Use train_set[0] to set the voltage and pre emphasis values */ | ||
895 | uint32_t signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | ||
896 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | ||
897 | |||
898 | /* channel eq pattern */ | ||
899 | if (!intel_dp_set_link_train(intel_output, DP | DP_LINK_TRAIN_PAT_2, | ||
900 | DP_TRAINING_PATTERN_2, train_set, | ||
901 | false)) | ||
902 | break; | ||
903 | |||
904 | udelay(400); | ||
905 | if (!intel_dp_get_link_status(intel_output, link_status)) | ||
906 | break; | ||
907 | |||
908 | if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { | ||
909 | channel_eq = true; | ||
910 | break; | ||
911 | } | ||
912 | |||
913 | /* Try 5 times */ | ||
914 | if (tries > 5) | ||
915 | break; | ||
916 | |||
917 | /* Compute new train_set as requested by target */ | ||
918 | intel_get_adjust_train(intel_output, link_status, dp_priv->lane_count, train_set); | ||
919 | ++tries; | ||
920 | } | ||
921 | |||
922 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_OFF); | ||
923 | POSTING_READ(dp_priv->output_reg); | ||
924 | intel_dp_aux_native_write_1(intel_output, | ||
925 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | ||
926 | } | ||
927 | |||
928 | static void | ||
929 | intel_dp_link_down(struct intel_output *intel_output, uint32_t DP) | ||
930 | { | ||
931 | struct drm_device *dev = intel_output->base.dev; | ||
932 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
933 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
934 | |||
935 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | ||
936 | POSTING_READ(dp_priv->output_reg); | ||
937 | } | ||
938 | |||
939 | static void | ||
940 | intel_dp_restore(struct drm_connector *connector) | ||
941 | { | ||
942 | struct intel_output *intel_output = to_intel_output(connector); | ||
943 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
944 | |||
945 | if (dp_priv->save_DP & DP_PORT_EN) | ||
946 | intel_dp_link_train(intel_output, dp_priv->save_DP, dp_priv->save_link_configuration); | ||
947 | else | ||
948 | intel_dp_link_down(intel_output, dp_priv->save_DP); | ||
949 | } | ||
950 | |||
951 | /* | ||
952 | * According to DP spec | ||
953 | * 5.1.2: | ||
954 | * 1. Read DPCD | ||
955 | * 2. Configure link according to Receiver Capabilities | ||
956 | * 3. Use Link Training from 2.5.3.3 and 3.5.1.3 | ||
957 | * 4. Check link status on receipt of hot-plug interrupt | ||
958 | */ | ||
959 | |||
960 | static void | ||
961 | intel_dp_check_link_status(struct intel_output *intel_output) | ||
962 | { | ||
963 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
964 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | ||
965 | |||
966 | if (!intel_output->enc.crtc) | ||
967 | return; | ||
968 | |||
969 | if (!intel_dp_get_link_status(intel_output, link_status)) { | ||
970 | intel_dp_link_down(intel_output, dp_priv->DP); | ||
971 | return; | ||
972 | } | ||
973 | |||
974 | if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) | ||
975 | intel_dp_link_train(intel_output, dp_priv->DP, dp_priv->link_configuration); | ||
976 | } | ||
977 | |||
978 | /** | ||
979 | * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect DP connection. | ||
980 | * | ||
981 | * \return true if DP port is connected. | ||
982 | * \return false if DP port is disconnected. | ||
983 | */ | ||
984 | static enum drm_connector_status | ||
985 | intel_dp_detect(struct drm_connector *connector) | ||
986 | { | ||
987 | struct intel_output *intel_output = to_intel_output(connector); | ||
988 | struct drm_device *dev = intel_output->base.dev; | ||
989 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
990 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
991 | uint32_t temp, bit; | ||
992 | enum drm_connector_status status; | ||
993 | |||
994 | dp_priv->has_audio = false; | ||
995 | |||
996 | temp = I915_READ(PORT_HOTPLUG_EN); | ||
997 | |||
998 | I915_WRITE(PORT_HOTPLUG_EN, | ||
999 | temp | | ||
1000 | DPB_HOTPLUG_INT_EN | | ||
1001 | DPC_HOTPLUG_INT_EN | | ||
1002 | DPD_HOTPLUG_INT_EN); | ||
1003 | |||
1004 | POSTING_READ(PORT_HOTPLUG_EN); | ||
1005 | |||
1006 | switch (dp_priv->output_reg) { | ||
1007 | case DP_B: | ||
1008 | bit = DPB_HOTPLUG_INT_STATUS; | ||
1009 | break; | ||
1010 | case DP_C: | ||
1011 | bit = DPC_HOTPLUG_INT_STATUS; | ||
1012 | break; | ||
1013 | case DP_D: | ||
1014 | bit = DPD_HOTPLUG_INT_STATUS; | ||
1015 | break; | ||
1016 | default: | ||
1017 | return connector_status_unknown; | ||
1018 | } | ||
1019 | |||
1020 | temp = I915_READ(PORT_HOTPLUG_STAT); | ||
1021 | |||
1022 | if ((temp & bit) == 0) | ||
1023 | return connector_status_disconnected; | ||
1024 | |||
1025 | status = connector_status_disconnected; | ||
1026 | if (intel_dp_aux_native_read(intel_output, | ||
1027 | 0x000, dp_priv->dpcd, | ||
1028 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | ||
1029 | { | ||
1030 | if (dp_priv->dpcd[0] != 0) | ||
1031 | status = connector_status_connected; | ||
1032 | } | ||
1033 | return status; | ||
1034 | } | ||
1035 | |||
1036 | static int intel_dp_get_modes(struct drm_connector *connector) | ||
1037 | { | ||
1038 | struct intel_output *intel_output = to_intel_output(connector); | ||
1039 | |||
1040 | /* We should parse the EDID data and find out if it has an audio sink | ||
1041 | */ | ||
1042 | |||
1043 | return intel_ddc_get_modes(intel_output); | ||
1044 | } | ||
1045 | |||
1046 | static void | ||
1047 | intel_dp_destroy (struct drm_connector *connector) | ||
1048 | { | ||
1049 | struct intel_output *intel_output = to_intel_output(connector); | ||
1050 | |||
1051 | if (intel_output->i2c_bus) | ||
1052 | intel_i2c_destroy(intel_output->i2c_bus); | ||
1053 | drm_sysfs_connector_remove(connector); | ||
1054 | drm_connector_cleanup(connector); | ||
1055 | kfree(intel_output); | ||
1056 | } | ||
1057 | |||
1058 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | ||
1059 | .dpms = intel_dp_dpms, | ||
1060 | .mode_fixup = intel_dp_mode_fixup, | ||
1061 | .prepare = intel_encoder_prepare, | ||
1062 | .mode_set = intel_dp_mode_set, | ||
1063 | .commit = intel_encoder_commit, | ||
1064 | }; | ||
1065 | |||
1066 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | ||
1067 | .dpms = drm_helper_connector_dpms, | ||
1068 | .save = intel_dp_save, | ||
1069 | .restore = intel_dp_restore, | ||
1070 | .detect = intel_dp_detect, | ||
1071 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
1072 | .destroy = intel_dp_destroy, | ||
1073 | }; | ||
1074 | |||
1075 | static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = { | ||
1076 | .get_modes = intel_dp_get_modes, | ||
1077 | .mode_valid = intel_dp_mode_valid, | ||
1078 | .best_encoder = intel_best_encoder, | ||
1079 | }; | ||
1080 | |||
1081 | static void intel_dp_enc_destroy(struct drm_encoder *encoder) | ||
1082 | { | ||
1083 | drm_encoder_cleanup(encoder); | ||
1084 | } | ||
1085 | |||
1086 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { | ||
1087 | .destroy = intel_dp_enc_destroy, | ||
1088 | }; | ||
1089 | |||
1090 | void | ||
1091 | intel_dp_hot_plug(struct intel_output *intel_output) | ||
1092 | { | ||
1093 | struct intel_dp_priv *dp_priv = intel_output->dev_priv; | ||
1094 | |||
1095 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) | ||
1096 | intel_dp_check_link_status(intel_output); | ||
1097 | } | ||
1098 | |||
1099 | void | ||
1100 | intel_dp_init(struct drm_device *dev, int output_reg) | ||
1101 | { | ||
1102 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1103 | struct drm_connector *connector; | ||
1104 | struct intel_output *intel_output; | ||
1105 | struct intel_dp_priv *dp_priv; | ||
1106 | |||
1107 | intel_output = kcalloc(sizeof(struct intel_output) + | ||
1108 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | ||
1109 | if (!intel_output) | ||
1110 | return; | ||
1111 | |||
1112 | dp_priv = (struct intel_dp_priv *)(intel_output + 1); | ||
1113 | |||
1114 | connector = &intel_output->base; | ||
1115 | drm_connector_init(dev, connector, &intel_dp_connector_funcs, | ||
1116 | DRM_MODE_CONNECTOR_DisplayPort); | ||
1117 | drm_connector_helper_add(connector, &intel_dp_connector_helper_funcs); | ||
1118 | |||
1119 | intel_output->type = INTEL_OUTPUT_DISPLAYPORT; | ||
1120 | |||
1121 | connector->interlace_allowed = true; | ||
1122 | connector->doublescan_allowed = 0; | ||
1123 | |||
1124 | dp_priv->intel_output = intel_output; | ||
1125 | dp_priv->output_reg = output_reg; | ||
1126 | dp_priv->has_audio = false; | ||
1127 | dp_priv->dpms_mode = DRM_MODE_DPMS_ON; | ||
1128 | intel_output->dev_priv = dp_priv; | ||
1129 | |||
1130 | drm_encoder_init(dev, &intel_output->enc, &intel_dp_enc_funcs, | ||
1131 | DRM_MODE_ENCODER_TMDS); | ||
1132 | drm_encoder_helper_add(&intel_output->enc, &intel_dp_helper_funcs); | ||
1133 | |||
1134 | drm_mode_connector_attach_encoder(&intel_output->base, | ||
1135 | &intel_output->enc); | ||
1136 | drm_sysfs_connector_add(connector); | ||
1137 | |||
1138 | /* Set up the DDC bus. */ | ||
1139 | intel_dp_i2c_init(intel_output, | ||
1140 | (output_reg == DP_B) ? "DPDDC-B" : | ||
1141 | (output_reg == DP_C) ? "DPDDC-C" : "DPDDC-D"); | ||
1142 | intel_output->ddc_bus = &dp_priv->adapter; | ||
1143 | intel_output->hot_plug = intel_dp_hot_plug; | ||
1144 | |||
1145 | /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written | ||
1146 | * 0xd. Failure to do so will result in spurious interrupts being | ||
1147 | * generated on the port when a cable is not attached. | ||
1148 | */ | ||
1149 | if (IS_G4X(dev) && !IS_GM45(dev)) { | ||
1150 | u32 temp = I915_READ(PEG_BAND_GAP_DATA); | ||
1151 | I915_WRITE(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); | ||
1152 | } | ||
1153 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.h b/drivers/gpu/drm/i915/intel_dp.h new file mode 100644 index 000000000000..2b38054d3b6d --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dp.h | |||
@@ -0,0 +1,144 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Keith Packard | ||
3 | * | ||
4 | * Permission to use, copy, modify, distribute, and sell this software and its | ||
5 | * documentation for any purpose is hereby granted without fee, provided that | ||
6 | * the above copyright notice appear in all copies and that both that copyright | ||
7 | * notice and this permission notice appear in supporting documentation, and | ||
8 | * that the name of the copyright holders not be used in advertising or | ||
9 | * publicity pertaining to distribution of the software without specific, | ||
10 | * written prior permission. The copyright holders make no representations | ||
11 | * about the suitability of this software for any purpose. It is provided "as | ||
12 | * is" without express or implied warranty. | ||
13 | * | ||
14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||
16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | ||
20 | * OF THIS SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #ifndef _INTEL_DP_H_ | ||
24 | #define _INTEL_DP_H_ | ||
25 | |||
26 | /* From the VESA DisplayPort spec */ | ||
27 | |||
28 | #define AUX_NATIVE_WRITE 0x8 | ||
29 | #define AUX_NATIVE_READ 0x9 | ||
30 | #define AUX_I2C_WRITE 0x0 | ||
31 | #define AUX_I2C_READ 0x1 | ||
32 | #define AUX_I2C_STATUS 0x2 | ||
33 | #define AUX_I2C_MOT 0x4 | ||
34 | |||
35 | #define AUX_NATIVE_REPLY_ACK (0x0 << 4) | ||
36 | #define AUX_NATIVE_REPLY_NACK (0x1 << 4) | ||
37 | #define AUX_NATIVE_REPLY_DEFER (0x2 << 4) | ||
38 | #define AUX_NATIVE_REPLY_MASK (0x3 << 4) | ||
39 | |||
40 | #define AUX_I2C_REPLY_ACK (0x0 << 6) | ||
41 | #define AUX_I2C_REPLY_NACK (0x1 << 6) | ||
42 | #define AUX_I2C_REPLY_DEFER (0x2 << 6) | ||
43 | #define AUX_I2C_REPLY_MASK (0x3 << 6) | ||
44 | |||
45 | /* AUX CH addresses */ | ||
46 | #define DP_LINK_BW_SET 0x100 | ||
47 | # define DP_LINK_BW_1_62 0x06 | ||
48 | # define DP_LINK_BW_2_7 0x0a | ||
49 | |||
50 | #define DP_LANE_COUNT_SET 0x101 | ||
51 | # define DP_LANE_COUNT_MASK 0x0f | ||
52 | # define DP_LANE_COUNT_ENHANCED_FRAME_EN (1 << 7) | ||
53 | |||
54 | #define DP_TRAINING_PATTERN_SET 0x102 | ||
55 | |||
56 | # define DP_TRAINING_PATTERN_DISABLE 0 | ||
57 | # define DP_TRAINING_PATTERN_1 1 | ||
58 | # define DP_TRAINING_PATTERN_2 2 | ||
59 | # define DP_TRAINING_PATTERN_MASK 0x3 | ||
60 | |||
61 | # define DP_LINK_QUAL_PATTERN_DISABLE (0 << 2) | ||
62 | # define DP_LINK_QUAL_PATTERN_D10_2 (1 << 2) | ||
63 | # define DP_LINK_QUAL_PATTERN_ERROR_RATE (2 << 2) | ||
64 | # define DP_LINK_QUAL_PATTERN_PRBS7 (3 << 2) | ||
65 | # define DP_LINK_QUAL_PATTERN_MASK (3 << 2) | ||
66 | |||
67 | # define DP_RECOVERED_CLOCK_OUT_EN (1 << 4) | ||
68 | # define DP_LINK_SCRAMBLING_DISABLE (1 << 5) | ||
69 | |||
70 | # define DP_SYMBOL_ERROR_COUNT_BOTH (0 << 6) | ||
71 | # define DP_SYMBOL_ERROR_COUNT_DISPARITY (1 << 6) | ||
72 | # define DP_SYMBOL_ERROR_COUNT_SYMBOL (2 << 6) | ||
73 | # define DP_SYMBOL_ERROR_COUNT_MASK (3 << 6) | ||
74 | |||
75 | #define DP_TRAINING_LANE0_SET 0x103 | ||
76 | #define DP_TRAINING_LANE1_SET 0x104 | ||
77 | #define DP_TRAINING_LANE2_SET 0x105 | ||
78 | #define DP_TRAINING_LANE3_SET 0x106 | ||
79 | |||
80 | # define DP_TRAIN_VOLTAGE_SWING_MASK 0x3 | ||
81 | # define DP_TRAIN_VOLTAGE_SWING_SHIFT 0 | ||
82 | # define DP_TRAIN_MAX_SWING_REACHED (1 << 2) | ||
83 | # define DP_TRAIN_VOLTAGE_SWING_400 (0 << 0) | ||
84 | # define DP_TRAIN_VOLTAGE_SWING_600 (1 << 0) | ||
85 | # define DP_TRAIN_VOLTAGE_SWING_800 (2 << 0) | ||
86 | # define DP_TRAIN_VOLTAGE_SWING_1200 (3 << 0) | ||
87 | |||
88 | # define DP_TRAIN_PRE_EMPHASIS_MASK (3 << 3) | ||
89 | # define DP_TRAIN_PRE_EMPHASIS_0 (0 << 3) | ||
90 | # define DP_TRAIN_PRE_EMPHASIS_3_5 (1 << 3) | ||
91 | # define DP_TRAIN_PRE_EMPHASIS_6 (2 << 3) | ||
92 | # define DP_TRAIN_PRE_EMPHASIS_9_5 (3 << 3) | ||
93 | |||
94 | # define DP_TRAIN_PRE_EMPHASIS_SHIFT 3 | ||
95 | # define DP_TRAIN_MAX_PRE_EMPHASIS_REACHED (1 << 5) | ||
96 | |||
97 | #define DP_DOWNSPREAD_CTRL 0x107 | ||
98 | # define DP_SPREAD_AMP_0_5 (1 << 4) | ||
99 | |||
100 | #define DP_MAIN_LINK_CHANNEL_CODING_SET 0x108 | ||
101 | # define DP_SET_ANSI_8B10B (1 << 0) | ||
102 | |||
103 | #define DP_LANE0_1_STATUS 0x202 | ||
104 | #define DP_LANE2_3_STATUS 0x203 | ||
105 | |||
106 | # define DP_LANE_CR_DONE (1 << 0) | ||
107 | # define DP_LANE_CHANNEL_EQ_DONE (1 << 1) | ||
108 | # define DP_LANE_SYMBOL_LOCKED (1 << 2) | ||
109 | |||
110 | #define DP_LANE_ALIGN_STATUS_UPDATED 0x204 | ||
111 | |||
112 | #define DP_INTERLANE_ALIGN_DONE (1 << 0) | ||
113 | #define DP_DOWNSTREAM_PORT_STATUS_CHANGED (1 << 6) | ||
114 | #define DP_LINK_STATUS_UPDATED (1 << 7) | ||
115 | |||
116 | #define DP_SINK_STATUS 0x205 | ||
117 | |||
118 | #define DP_RECEIVE_PORT_0_STATUS (1 << 0) | ||
119 | #define DP_RECEIVE_PORT_1_STATUS (1 << 1) | ||
120 | |||
121 | #define DP_ADJUST_REQUEST_LANE0_1 0x206 | ||
122 | #define DP_ADJUST_REQUEST_LANE2_3 0x207 | ||
123 | |||
124 | #define DP_ADJUST_VOLTAGE_SWING_LANE0_MASK 0x03 | ||
125 | #define DP_ADJUST_VOLTAGE_SWING_LANE0_SHIFT 0 | ||
126 | #define DP_ADJUST_PRE_EMPHASIS_LANE0_MASK 0x0c | ||
127 | #define DP_ADJUST_PRE_EMPHASIS_LANE0_SHIFT 2 | ||
128 | #define DP_ADJUST_VOLTAGE_SWING_LANE1_MASK 0x30 | ||
129 | #define DP_ADJUST_VOLTAGE_SWING_LANE1_SHIFT 4 | ||
130 | #define DP_ADJUST_PRE_EMPHASIS_LANE1_MASK 0xc0 | ||
131 | #define DP_ADJUST_PRE_EMPHASIS_LANE1_SHIFT 6 | ||
132 | |||
133 | struct i2c_algo_dp_aux_data { | ||
134 | bool running; | ||
135 | u16 address; | ||
136 | int (*aux_ch) (struct i2c_adapter *adapter, | ||
137 | uint8_t *send, int send_bytes, | ||
138 | uint8_t *recv, int recv_bytes); | ||
139 | }; | ||
140 | |||
141 | int | ||
142 | i2c_dp_aux_add_bus(struct i2c_adapter *adapter); | ||
143 | |||
144 | #endif /* _INTEL_DP_H_ */ | ||
diff --git a/drivers/gpu/drm/i915/intel_dp_i2c.c b/drivers/gpu/drm/i915/intel_dp_i2c.c new file mode 100644 index 000000000000..4e60f14b1a6d --- /dev/null +++ b/drivers/gpu/drm/i915/intel_dp_i2c.c | |||
@@ -0,0 +1,272 @@ | |||
1 | /* | ||
2 | * Copyright © 2009 Keith Packard | ||
3 | * | ||
4 | * Permission to use, copy, modify, distribute, and sell this software and its | ||
5 | * documentation for any purpose is hereby granted without fee, provided that | ||
6 | * the above copyright notice appear in all copies and that both that copyright | ||
7 | * notice and this permission notice appear in supporting documentation, and | ||
8 | * that the name of the copyright holders not be used in advertising or | ||
9 | * publicity pertaining to distribution of the software without specific, | ||
10 | * written prior permission. The copyright holders make no representations | ||
11 | * about the suitability of this software for any purpose. It is provided "as | ||
12 | * is" without express or implied warranty. | ||
13 | * | ||
14 | * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
15 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||
16 | * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
17 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||
18 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
19 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | ||
20 | * OF THIS SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include "intel_dp.h" | ||
32 | |||
33 | /* Run a single AUX_CH I2C transaction, writing/reading data as necessary */ | ||
34 | |||
35 | #define MODE_I2C_START 1 | ||
36 | #define MODE_I2C_WRITE 2 | ||
37 | #define MODE_I2C_READ 4 | ||
38 | #define MODE_I2C_STOP 8 | ||
39 | |||
40 | static int | ||
41 | i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode, | ||
42 | uint8_t write_byte, uint8_t *read_byte) | ||
43 | { | ||
44 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
45 | uint16_t address = algo_data->address; | ||
46 | uint8_t msg[5]; | ||
47 | uint8_t reply[2]; | ||
48 | int msg_bytes; | ||
49 | int reply_bytes; | ||
50 | int ret; | ||
51 | |||
52 | /* Set up the command byte */ | ||
53 | if (mode & MODE_I2C_READ) | ||
54 | msg[0] = AUX_I2C_READ << 4; | ||
55 | else | ||
56 | msg[0] = AUX_I2C_WRITE << 4; | ||
57 | |||
58 | if (!(mode & MODE_I2C_STOP)) | ||
59 | msg[0] |= AUX_I2C_MOT << 4; | ||
60 | |||
61 | msg[1] = address >> 8; | ||
62 | msg[2] = address; | ||
63 | |||
64 | switch (mode) { | ||
65 | case MODE_I2C_WRITE: | ||
66 | msg[3] = 0; | ||
67 | msg[4] = write_byte; | ||
68 | msg_bytes = 5; | ||
69 | reply_bytes = 1; | ||
70 | break; | ||
71 | case MODE_I2C_READ: | ||
72 | msg[3] = 0; | ||
73 | msg_bytes = 4; | ||
74 | reply_bytes = 2; | ||
75 | break; | ||
76 | default: | ||
77 | msg_bytes = 3; | ||
78 | reply_bytes = 1; | ||
79 | break; | ||
80 | } | ||
81 | |||
82 | for (;;) { | ||
83 | ret = (*algo_data->aux_ch)(adapter, | ||
84 | msg, msg_bytes, | ||
85 | reply, reply_bytes); | ||
86 | if (ret < 0) { | ||
87 | printk(KERN_ERR "aux_ch failed %d\n", ret); | ||
88 | return ret; | ||
89 | } | ||
90 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | ||
91 | case AUX_I2C_REPLY_ACK: | ||
92 | if (mode == MODE_I2C_READ) { | ||
93 | *read_byte = reply[1]; | ||
94 | } | ||
95 | return reply_bytes - 1; | ||
96 | case AUX_I2C_REPLY_NACK: | ||
97 | printk(KERN_ERR "aux_ch nack\n"); | ||
98 | return -EREMOTEIO; | ||
99 | case AUX_I2C_REPLY_DEFER: | ||
100 | printk(KERN_ERR "aux_ch defer\n"); | ||
101 | udelay(100); | ||
102 | break; | ||
103 | default: | ||
104 | printk(KERN_ERR "aux_ch invalid reply 0x%02x\n", reply[0]); | ||
105 | return -EREMOTEIO; | ||
106 | } | ||
107 | } | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * I2C over AUX CH | ||
112 | */ | ||
113 | |||
114 | /* | ||
115 | * Send the address. If the I2C link is running, this 'restarts' | ||
116 | * the connection with the new address, this is used for doing | ||
117 | * a write followed by a read (as needed for DDC) | ||
118 | */ | ||
119 | static int | ||
120 | i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading) | ||
121 | { | ||
122 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
123 | int mode = MODE_I2C_START; | ||
124 | int ret; | ||
125 | |||
126 | if (reading) | ||
127 | mode |= MODE_I2C_READ; | ||
128 | else | ||
129 | mode |= MODE_I2C_WRITE; | ||
130 | algo_data->address = address; | ||
131 | algo_data->running = true; | ||
132 | ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); | ||
133 | return ret; | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Stop the I2C transaction. This closes out the link, sending | ||
138 | * a bare address packet with the MOT bit turned off | ||
139 | */ | ||
140 | static void | ||
141 | i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading) | ||
142 | { | ||
143 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
144 | int mode = MODE_I2C_STOP; | ||
145 | |||
146 | if (reading) | ||
147 | mode |= MODE_I2C_READ; | ||
148 | else | ||
149 | mode |= MODE_I2C_WRITE; | ||
150 | if (algo_data->running) { | ||
151 | (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL); | ||
152 | algo_data->running = false; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | /* | ||
157 | * Write a single byte to the current I2C address, the | ||
158 | * the I2C link must be running or this returns -EIO | ||
159 | */ | ||
160 | static int | ||
161 | i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte) | ||
162 | { | ||
163 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
164 | int ret; | ||
165 | |||
166 | if (!algo_data->running) | ||
167 | return -EIO; | ||
168 | |||
169 | ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL); | ||
170 | return ret; | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Read a single byte from the current I2C address, the | ||
175 | * I2C link must be running or this returns -EIO | ||
176 | */ | ||
177 | static int | ||
178 | i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret) | ||
179 | { | ||
180 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | ||
181 | int ret; | ||
182 | |||
183 | if (!algo_data->running) | ||
184 | return -EIO; | ||
185 | |||
186 | ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret); | ||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | static int | ||
191 | i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter, | ||
192 | struct i2c_msg *msgs, | ||
193 | int num) | ||
194 | { | ||
195 | int ret = 0; | ||
196 | bool reading = false; | ||
197 | int m; | ||
198 | int b; | ||
199 | |||
200 | for (m = 0; m < num; m++) { | ||
201 | u16 len = msgs[m].len; | ||
202 | u8 *buf = msgs[m].buf; | ||
203 | reading = (msgs[m].flags & I2C_M_RD) != 0; | ||
204 | ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading); | ||
205 | if (ret < 0) | ||
206 | break; | ||
207 | if (reading) { | ||
208 | for (b = 0; b < len; b++) { | ||
209 | ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]); | ||
210 | if (ret < 0) | ||
211 | break; | ||
212 | } | ||
213 | } else { | ||
214 | for (b = 0; b < len; b++) { | ||
215 | ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]); | ||
216 | if (ret < 0) | ||
217 | break; | ||
218 | } | ||
219 | } | ||
220 | if (ret < 0) | ||
221 | break; | ||
222 | } | ||
223 | if (ret >= 0) | ||
224 | ret = num; | ||
225 | i2c_algo_dp_aux_stop(adapter, reading); | ||
226 | printk(KERN_ERR "dp_aux_xfer return %d\n", ret); | ||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static u32 | ||
231 | i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter) | ||
232 | { | ||
233 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | ||
234 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | | ||
235 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL | | ||
236 | I2C_FUNC_10BIT_ADDR; | ||
237 | } | ||
238 | |||
239 | static const struct i2c_algorithm i2c_dp_aux_algo = { | ||
240 | .master_xfer = i2c_algo_dp_aux_xfer, | ||
241 | .functionality = i2c_algo_dp_aux_functionality, | ||
242 | }; | ||
243 | |||
244 | static void | ||
245 | i2c_dp_aux_reset_bus(struct i2c_adapter *adapter) | ||
246 | { | ||
247 | (void) i2c_algo_dp_aux_address(adapter, 0, false); | ||
248 | (void) i2c_algo_dp_aux_stop(adapter, false); | ||
249 | |||
250 | } | ||
251 | |||
252 | static int | ||
253 | i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter) | ||
254 | { | ||
255 | adapter->algo = &i2c_dp_aux_algo; | ||
256 | adapter->retries = 3; | ||
257 | i2c_dp_aux_reset_bus(adapter); | ||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | int | ||
262 | i2c_dp_aux_add_bus(struct i2c_adapter *adapter) | ||
263 | { | ||
264 | int error; | ||
265 | |||
266 | error = i2c_dp_aux_prepare_bus(adapter); | ||
267 | if (error) | ||
268 | return error; | ||
269 | error = i2c_add_adapter(adapter); | ||
270 | return error; | ||
271 | } | ||
272 | EXPORT_SYMBOL(i2c_dp_aux_add_bus); | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index cd4b9c5f715e..004541c935a8 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -54,6 +54,7 @@ | |||
54 | #define INTEL_OUTPUT_LVDS 4 | 54 | #define INTEL_OUTPUT_LVDS 4 |
55 | #define INTEL_OUTPUT_TVOUT 5 | 55 | #define INTEL_OUTPUT_TVOUT 5 |
56 | #define INTEL_OUTPUT_HDMI 6 | 56 | #define INTEL_OUTPUT_HDMI 6 |
57 | #define INTEL_OUTPUT_DISPLAYPORT 7 | ||
57 | 58 | ||
58 | #define INTEL_DVO_CHIP_NONE 0 | 59 | #define INTEL_DVO_CHIP_NONE 0 |
59 | #define INTEL_DVO_CHIP_LVDS 1 | 60 | #define INTEL_DVO_CHIP_LVDS 1 |
@@ -65,7 +66,6 @@ struct intel_i2c_chan { | |||
65 | u32 reg; /* GPIO reg */ | 66 | u32 reg; /* GPIO reg */ |
66 | struct i2c_adapter adapter; | 67 | struct i2c_adapter adapter; |
67 | struct i2c_algo_bit_data algo; | 68 | struct i2c_algo_bit_data algo; |
68 | u8 slave_addr; | ||
69 | }; | 69 | }; |
70 | 70 | ||
71 | struct intel_framebuffer { | 71 | struct intel_framebuffer { |
@@ -79,11 +79,12 @@ struct intel_output { | |||
79 | 79 | ||
80 | struct drm_encoder enc; | 80 | struct drm_encoder enc; |
81 | int type; | 81 | int type; |
82 | struct intel_i2c_chan *i2c_bus; /* for control functions */ | 82 | struct i2c_adapter *i2c_bus; |
83 | struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */ | 83 | struct i2c_adapter *ddc_bus; |
84 | bool load_detect_temp; | 84 | bool load_detect_temp; |
85 | bool needs_tv_clock; | 85 | bool needs_tv_clock; |
86 | void *dev_priv; | 86 | void *dev_priv; |
87 | void (*hot_plug)(struct intel_output *); | ||
87 | }; | 88 | }; |
88 | 89 | ||
89 | struct intel_crtc { | 90 | struct intel_crtc { |
@@ -104,9 +105,9 @@ struct intel_crtc { | |||
104 | #define enc_to_intel_output(x) container_of(x, struct intel_output, enc) | 105 | #define enc_to_intel_output(x) container_of(x, struct intel_output, enc) |
105 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 106 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
106 | 107 | ||
107 | struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, | 108 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
108 | const char *name); | 109 | const char *name); |
109 | void intel_i2c_destroy(struct intel_i2c_chan *chan); | 110 | void intel_i2c_destroy(struct i2c_adapter *adapter); |
110 | int intel_ddc_get_modes(struct intel_output *intel_output); | 111 | int intel_ddc_get_modes(struct intel_output *intel_output); |
111 | extern bool intel_ddc_probe(struct intel_output *intel_output); | 112 | extern bool intel_ddc_probe(struct intel_output *intel_output); |
112 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); | 113 | void intel_i2c_quirk_set(struct drm_device *dev, bool enable); |
@@ -116,6 +117,10 @@ extern bool intel_sdvo_init(struct drm_device *dev, int output_device); | |||
116 | extern void intel_dvo_init(struct drm_device *dev); | 117 | extern void intel_dvo_init(struct drm_device *dev); |
117 | extern void intel_tv_init(struct drm_device *dev); | 118 | extern void intel_tv_init(struct drm_device *dev); |
118 | extern void intel_lvds_init(struct drm_device *dev); | 119 | extern void intel_lvds_init(struct drm_device *dev); |
120 | extern void intel_dp_init(struct drm_device *dev, int dp_reg); | ||
121 | void | ||
122 | intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | ||
123 | struct drm_display_mode *adjusted_mode); | ||
119 | 124 | ||
120 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 125 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
121 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 126 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 1ee3007d6ec0..13bff20930e8 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -384,10 +384,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
384 | { | 384 | { |
385 | struct intel_output *intel_output; | 385 | struct intel_output *intel_output; |
386 | struct intel_dvo_device *dvo; | 386 | struct intel_dvo_device *dvo; |
387 | struct intel_i2c_chan *i2cbus = NULL; | 387 | struct i2c_adapter *i2cbus = NULL; |
388 | int ret = 0; | 388 | int ret = 0; |
389 | int i; | 389 | int i; |
390 | int gpio_inited = 0; | ||
391 | int encoder_type = DRM_MODE_ENCODER_NONE; | 390 | int encoder_type = DRM_MODE_ENCODER_NONE; |
392 | intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); | 391 | intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL); |
393 | if (!intel_output) | 392 | if (!intel_output) |
@@ -420,14 +419,11 @@ void intel_dvo_init(struct drm_device *dev) | |||
420 | * It appears that everything is on GPIOE except for panels | 419 | * It appears that everything is on GPIOE except for panels |
421 | * on i830 laptops, which are on GPIOB (DVOA). | 420 | * on i830 laptops, which are on GPIOB (DVOA). |
422 | */ | 421 | */ |
423 | if (gpio_inited != gpio) { | 422 | if (i2cbus != NULL) |
424 | if (i2cbus != NULL) | 423 | intel_i2c_destroy(i2cbus); |
425 | intel_i2c_destroy(i2cbus); | 424 | if (!(i2cbus = intel_i2c_create(dev, gpio, |
426 | if (!(i2cbus = intel_i2c_create(dev, gpio, | 425 | gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { |
427 | gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E"))) { | 426 | continue; |
428 | continue; | ||
429 | } | ||
430 | gpio_inited = gpio; | ||
431 | } | 427 | } |
432 | 428 | ||
433 | if (dvo->dev_ops!= NULL) | 429 | if (dvo->dev_ops!= NULL) |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 4ea2a651b92c..9e30daae37dc 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "drmP.h" | 31 | #include "drmP.h" |
32 | #include "drm.h" | 32 | #include "drm.h" |
33 | #include "drm_crtc.h" | 33 | #include "drm_crtc.h" |
34 | #include "drm_edid.h" | ||
34 | #include "intel_drv.h" | 35 | #include "intel_drv.h" |
35 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
36 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
@@ -56,8 +57,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
56 | sdvox = SDVO_ENCODING_HDMI | | 57 | sdvox = SDVO_ENCODING_HDMI | |
57 | SDVO_BORDER_ENABLE | | 58 | SDVO_BORDER_ENABLE | |
58 | SDVO_VSYNC_ACTIVE_HIGH | | 59 | SDVO_VSYNC_ACTIVE_HIGH | |
59 | SDVO_HSYNC_ACTIVE_HIGH | | 60 | SDVO_HSYNC_ACTIVE_HIGH; |
60 | SDVO_NULL_PACKETS_DURING_VSYNC; | ||
61 | 61 | ||
62 | if (hdmi_priv->has_hdmi_sink) | 62 | if (hdmi_priv->has_hdmi_sink) |
63 | sdvox |= SDVO_AUDIO_ENABLE; | 63 | sdvox |= SDVO_AUDIO_ENABLE; |
@@ -129,20 +129,26 @@ static bool intel_hdmi_mode_fixup(struct drm_encoder *encoder, | |||
129 | return true; | 129 | return true; |
130 | } | 130 | } |
131 | 131 | ||
132 | static void | 132 | static enum drm_connector_status |
133 | intel_hdmi_sink_detect(struct drm_connector *connector) | 133 | intel_hdmi_edid_detect(struct drm_connector *connector) |
134 | { | 134 | { |
135 | struct intel_output *intel_output = to_intel_output(connector); | 135 | struct intel_output *intel_output = to_intel_output(connector); |
136 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 136 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; |
137 | struct edid *edid = NULL; | 137 | struct edid *edid = NULL; |
138 | enum drm_connector_status status = connector_status_disconnected; | ||
138 | 139 | ||
139 | edid = drm_get_edid(&intel_output->base, | 140 | edid = drm_get_edid(&intel_output->base, |
140 | &intel_output->ddc_bus->adapter); | 141 | intel_output->ddc_bus); |
141 | if (edid != NULL) { | 142 | hdmi_priv->has_hdmi_sink = false; |
142 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | 143 | if (edid) { |
143 | kfree(edid); | 144 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
145 | status = connector_status_connected; | ||
146 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | ||
147 | } | ||
144 | intel_output->base.display_info.raw_edid = NULL; | 148 | intel_output->base.display_info.raw_edid = NULL; |
149 | kfree(edid); | ||
145 | } | 150 | } |
151 | return status; | ||
146 | } | 152 | } |
147 | 153 | ||
148 | static enum drm_connector_status | 154 | static enum drm_connector_status |
@@ -154,11 +160,7 @@ igdng_hdmi_detect(struct drm_connector *connector) | |||
154 | /* FIXME hotplug detect */ | 160 | /* FIXME hotplug detect */ |
155 | 161 | ||
156 | hdmi_priv->has_hdmi_sink = false; | 162 | hdmi_priv->has_hdmi_sink = false; |
157 | intel_hdmi_sink_detect(connector); | 163 | return intel_hdmi_edid_detect(connector); |
158 | if (hdmi_priv->has_hdmi_sink) | ||
159 | return connector_status_connected; | ||
160 | else | ||
161 | return connector_status_disconnected; | ||
162 | } | 164 | } |
163 | 165 | ||
164 | static enum drm_connector_status | 166 | static enum drm_connector_status |
@@ -201,10 +203,9 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
201 | return connector_status_unknown; | 203 | return connector_status_unknown; |
202 | } | 204 | } |
203 | 205 | ||
204 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) { | 206 | if ((I915_READ(PORT_HOTPLUG_STAT) & bit) != 0) |
205 | intel_hdmi_sink_detect(connector); | 207 | return intel_hdmi_edid_detect(connector); |
206 | return connector_status_connected; | 208 | else |
207 | } else | ||
208 | return connector_status_disconnected; | 209 | return connector_status_disconnected; |
209 | } | 210 | } |
210 | 211 | ||
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index f7061f68d050..62b8bead7652 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -124,6 +124,7 @@ static void set_data(void *data, int state_high) | |||
124 | * @output: driver specific output device | 124 | * @output: driver specific output device |
125 | * @reg: GPIO reg to use | 125 | * @reg: GPIO reg to use |
126 | * @name: name for this bus | 126 | * @name: name for this bus |
127 | * @slave_addr: slave address (if fixed) | ||
127 | * | 128 | * |
128 | * Creates and registers a new i2c bus with the Linux i2c layer, for use | 129 | * Creates and registers a new i2c bus with the Linux i2c layer, for use |
129 | * in output probing and control (e.g. DDC or SDVO control functions). | 130 | * in output probing and control (e.g. DDC or SDVO control functions). |
@@ -139,8 +140,8 @@ static void set_data(void *data, int state_high) | |||
139 | * %GPIOH | 140 | * %GPIOH |
140 | * see PRM for details on how these different busses are used. | 141 | * see PRM for details on how these different busses are used. |
141 | */ | 142 | */ |
142 | struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, | 143 | struct i2c_adapter *intel_i2c_create(struct drm_device *dev, const u32 reg, |
143 | const char *name) | 144 | const char *name) |
144 | { | 145 | { |
145 | struct intel_i2c_chan *chan; | 146 | struct intel_i2c_chan *chan; |
146 | 147 | ||
@@ -174,7 +175,7 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg, | |||
174 | intel_i2c_quirk_set(dev, false); | 175 | intel_i2c_quirk_set(dev, false); |
175 | udelay(20); | 176 | udelay(20); |
176 | 177 | ||
177 | return chan; | 178 | return &chan->adapter; |
178 | 179 | ||
179 | out_free: | 180 | out_free: |
180 | kfree(chan); | 181 | kfree(chan); |
@@ -187,11 +188,16 @@ out_free: | |||
187 | * | 188 | * |
188 | * Unregister the adapter from the i2c layer, then free the structure. | 189 | * Unregister the adapter from the i2c layer, then free the structure. |
189 | */ | 190 | */ |
190 | void intel_i2c_destroy(struct intel_i2c_chan *chan) | 191 | void intel_i2c_destroy(struct i2c_adapter *adapter) |
191 | { | 192 | { |
192 | if (!chan) | 193 | struct intel_i2c_chan *chan; |
194 | |||
195 | if (!adapter) | ||
193 | return; | 196 | return; |
194 | 197 | ||
198 | chan = container_of(adapter, | ||
199 | struct intel_i2c_chan, | ||
200 | adapter); | ||
195 | i2c_del_adapter(&chan->adapter); | 201 | i2c_del_adapter(&chan->adapter); |
196 | kfree(chan); | 202 | kfree(chan); |
197 | } | 203 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f073ed8432e8..9564ca44a977 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -39,6 +39,21 @@ | |||
39 | 39 | ||
40 | #define I915_LVDS "i915_lvds" | 40 | #define I915_LVDS "i915_lvds" |
41 | 41 | ||
42 | /* | ||
43 | * the following four scaling options are defined. | ||
44 | * #define DRM_MODE_SCALE_NON_GPU 0 | ||
45 | * #define DRM_MODE_SCALE_FULLSCREEN 1 | ||
46 | * #define DRM_MODE_SCALE_NO_SCALE 2 | ||
47 | * #define DRM_MODE_SCALE_ASPECT 3 | ||
48 | */ | ||
49 | |||
50 | /* Private structure for the integrated LVDS support */ | ||
51 | struct intel_lvds_priv { | ||
52 | int fitting_mode; | ||
53 | u32 pfit_control; | ||
54 | u32 pfit_pgm_ratios; | ||
55 | }; | ||
56 | |||
42 | /** | 57 | /** |
43 | * Sets the backlight level. | 58 | * Sets the backlight level. |
44 | * | 59 | * |
@@ -213,10 +228,27 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
213 | struct drm_display_mode *mode, | 228 | struct drm_display_mode *mode, |
214 | struct drm_display_mode *adjusted_mode) | 229 | struct drm_display_mode *adjusted_mode) |
215 | { | 230 | { |
231 | /* | ||
232 | * float point operation is not supported . So the PANEL_RATIO_FACTOR | ||
233 | * is defined, which can avoid the float point computation when | ||
234 | * calculating the panel ratio. | ||
235 | */ | ||
236 | #define PANEL_RATIO_FACTOR 8192 | ||
216 | struct drm_device *dev = encoder->dev; | 237 | struct drm_device *dev = encoder->dev; |
217 | struct drm_i915_private *dev_priv = dev->dev_private; | 238 | struct drm_i915_private *dev_priv = dev->dev_private; |
218 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 239 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
219 | struct drm_encoder *tmp_encoder; | 240 | struct drm_encoder *tmp_encoder; |
241 | struct intel_output *intel_output = enc_to_intel_output(encoder); | ||
242 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; | ||
243 | u32 pfit_control = 0, pfit_pgm_ratios = 0; | ||
244 | int left_border = 0, right_border = 0, top_border = 0; | ||
245 | int bottom_border = 0; | ||
246 | bool border = 0; | ||
247 | int panel_ratio, desired_ratio, vert_scale, horiz_scale; | ||
248 | int horiz_ratio, vert_ratio; | ||
249 | u32 hsync_width, vsync_width; | ||
250 | u32 hblank_width, vblank_width; | ||
251 | u32 hsync_pos, vsync_pos; | ||
220 | 252 | ||
221 | /* Should never happen!! */ | 253 | /* Should never happen!! */ |
222 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { | 254 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { |
@@ -232,7 +264,9 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
232 | return false; | 264 | return false; |
233 | } | 265 | } |
234 | } | 266 | } |
235 | 267 | /* If we don't have a panel mode, there is nothing we can do */ | |
268 | if (dev_priv->panel_fixed_mode == NULL) | ||
269 | return true; | ||
236 | /* | 270 | /* |
237 | * If we have timings from the BIOS for the panel, put them in | 271 | * If we have timings from the BIOS for the panel, put them in |
238 | * to the adjusted mode. The CRTC will be set up for this mode, | 272 | * to the adjusted mode. The CRTC will be set up for this mode, |
@@ -256,6 +290,243 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
256 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | 290 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); |
257 | } | 291 | } |
258 | 292 | ||
293 | /* Make sure pre-965s set dither correctly */ | ||
294 | if (!IS_I965G(dev)) { | ||
295 | if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) | ||
296 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; | ||
297 | } | ||
298 | |||
299 | /* Native modes don't need fitting */ | ||
300 | if (adjusted_mode->hdisplay == mode->hdisplay && | ||
301 | adjusted_mode->vdisplay == mode->vdisplay) { | ||
302 | pfit_pgm_ratios = 0; | ||
303 | border = 0; | ||
304 | goto out; | ||
305 | } | ||
306 | |||
307 | /* 965+ wants fuzzy fitting */ | ||
308 | if (IS_I965G(dev)) | ||
309 | pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | | ||
310 | PFIT_FILTER_FUZZY; | ||
311 | |||
312 | hsync_width = adjusted_mode->crtc_hsync_end - | ||
313 | adjusted_mode->crtc_hsync_start; | ||
314 | vsync_width = adjusted_mode->crtc_vsync_end - | ||
315 | adjusted_mode->crtc_vsync_start; | ||
316 | hblank_width = adjusted_mode->crtc_hblank_end - | ||
317 | adjusted_mode->crtc_hblank_start; | ||
318 | vblank_width = adjusted_mode->crtc_vblank_end - | ||
319 | adjusted_mode->crtc_vblank_start; | ||
320 | /* | ||
321 | * Deal with panel fitting options. Figure out how to stretch the | ||
322 | * image based on its aspect ratio & the current panel fitting mode. | ||
323 | */ | ||
324 | panel_ratio = adjusted_mode->hdisplay * PANEL_RATIO_FACTOR / | ||
325 | adjusted_mode->vdisplay; | ||
326 | desired_ratio = mode->hdisplay * PANEL_RATIO_FACTOR / | ||
327 | mode->vdisplay; | ||
328 | /* | ||
329 | * Enable automatic panel scaling for non-native modes so that they fill | ||
330 | * the screen. Should be enabled before the pipe is enabled, according | ||
331 | * to register description and PRM. | ||
332 | * Change the value here to see the borders for debugging | ||
333 | */ | ||
334 | I915_WRITE(BCLRPAT_A, 0); | ||
335 | I915_WRITE(BCLRPAT_B, 0); | ||
336 | |||
337 | switch (lvds_priv->fitting_mode) { | ||
338 | case DRM_MODE_SCALE_NO_SCALE: | ||
339 | /* | ||
340 | * For centered modes, we have to calculate border widths & | ||
341 | * heights and modify the values programmed into the CRTC. | ||
342 | */ | ||
343 | left_border = (adjusted_mode->hdisplay - mode->hdisplay) / 2; | ||
344 | right_border = left_border; | ||
345 | if (mode->hdisplay & 1) | ||
346 | right_border++; | ||
347 | top_border = (adjusted_mode->vdisplay - mode->vdisplay) / 2; | ||
348 | bottom_border = top_border; | ||
349 | if (mode->vdisplay & 1) | ||
350 | bottom_border++; | ||
351 | /* Set active & border values */ | ||
352 | adjusted_mode->crtc_hdisplay = mode->hdisplay; | ||
353 | /* Keep the boder be even */ | ||
354 | if (right_border & 1) | ||
355 | right_border++; | ||
356 | /* use the border directly instead of border minuse one */ | ||
357 | adjusted_mode->crtc_hblank_start = mode->hdisplay + | ||
358 | right_border; | ||
359 | /* keep the blank width constant */ | ||
360 | adjusted_mode->crtc_hblank_end = | ||
361 | adjusted_mode->crtc_hblank_start + hblank_width; | ||
362 | /* get the hsync pos relative to hblank start */ | ||
363 | hsync_pos = (hblank_width - hsync_width) / 2; | ||
364 | /* keep the hsync pos be even */ | ||
365 | if (hsync_pos & 1) | ||
366 | hsync_pos++; | ||
367 | adjusted_mode->crtc_hsync_start = | ||
368 | adjusted_mode->crtc_hblank_start + hsync_pos; | ||
369 | /* keep the hsync width constant */ | ||
370 | adjusted_mode->crtc_hsync_end = | ||
371 | adjusted_mode->crtc_hsync_start + hsync_width; | ||
372 | adjusted_mode->crtc_vdisplay = mode->vdisplay; | ||
373 | /* use the border instead of border minus one */ | ||
374 | adjusted_mode->crtc_vblank_start = mode->vdisplay + | ||
375 | bottom_border; | ||
376 | /* keep the vblank width constant */ | ||
377 | adjusted_mode->crtc_vblank_end = | ||
378 | adjusted_mode->crtc_vblank_start + vblank_width; | ||
379 | /* get the vsync start postion relative to vblank start */ | ||
380 | vsync_pos = (vblank_width - vsync_width) / 2; | ||
381 | adjusted_mode->crtc_vsync_start = | ||
382 | adjusted_mode->crtc_vblank_start + vsync_pos; | ||
383 | /* keep the vsync width constant */ | ||
384 | adjusted_mode->crtc_vsync_end = | ||
385 | adjusted_mode->crtc_vblank_start + vsync_width; | ||
386 | border = 1; | ||
387 | break; | ||
388 | case DRM_MODE_SCALE_ASPECT: | ||
389 | /* Scale but preserve the spect ratio */ | ||
390 | pfit_control |= PFIT_ENABLE; | ||
391 | if (IS_I965G(dev)) { | ||
392 | /* 965+ is easy, it does everything in hw */ | ||
393 | if (panel_ratio > desired_ratio) | ||
394 | pfit_control |= PFIT_SCALING_PILLAR; | ||
395 | else if (panel_ratio < desired_ratio) | ||
396 | pfit_control |= PFIT_SCALING_LETTER; | ||
397 | else | ||
398 | pfit_control |= PFIT_SCALING_AUTO; | ||
399 | } else { | ||
400 | /* | ||
401 | * For earlier chips we have to calculate the scaling | ||
402 | * ratio by hand and program it into the | ||
403 | * PFIT_PGM_RATIO register | ||
404 | */ | ||
405 | u32 horiz_bits, vert_bits, bits = 12; | ||
406 | horiz_ratio = mode->hdisplay * PANEL_RATIO_FACTOR/ | ||
407 | adjusted_mode->hdisplay; | ||
408 | vert_ratio = mode->vdisplay * PANEL_RATIO_FACTOR/ | ||
409 | adjusted_mode->vdisplay; | ||
410 | horiz_scale = adjusted_mode->hdisplay * | ||
411 | PANEL_RATIO_FACTOR / mode->hdisplay; | ||
412 | vert_scale = adjusted_mode->vdisplay * | ||
413 | PANEL_RATIO_FACTOR / mode->vdisplay; | ||
414 | |||
415 | /* retain aspect ratio */ | ||
416 | if (panel_ratio > desired_ratio) { /* Pillar */ | ||
417 | u32 scaled_width; | ||
418 | scaled_width = mode->hdisplay * vert_scale / | ||
419 | PANEL_RATIO_FACTOR; | ||
420 | horiz_ratio = vert_ratio; | ||
421 | pfit_control |= (VERT_AUTO_SCALE | | ||
422 | VERT_INTERP_BILINEAR | | ||
423 | HORIZ_INTERP_BILINEAR); | ||
424 | /* Pillar will have left/right borders */ | ||
425 | left_border = (adjusted_mode->hdisplay - | ||
426 | scaled_width) / 2; | ||
427 | right_border = left_border; | ||
428 | if (mode->hdisplay & 1) /* odd resolutions */ | ||
429 | right_border++; | ||
430 | /* keep the border be even */ | ||
431 | if (right_border & 1) | ||
432 | right_border++; | ||
433 | adjusted_mode->crtc_hdisplay = scaled_width; | ||
434 | /* use border instead of border minus one */ | ||
435 | adjusted_mode->crtc_hblank_start = | ||
436 | scaled_width + right_border; | ||
437 | /* keep the hblank width constant */ | ||
438 | adjusted_mode->crtc_hblank_end = | ||
439 | adjusted_mode->crtc_hblank_start + | ||
440 | hblank_width; | ||
441 | /* | ||
442 | * get the hsync start pos relative to | ||
443 | * hblank start | ||
444 | */ | ||
445 | hsync_pos = (hblank_width - hsync_width) / 2; | ||
446 | /* keep the hsync_pos be even */ | ||
447 | if (hsync_pos & 1) | ||
448 | hsync_pos++; | ||
449 | adjusted_mode->crtc_hsync_start = | ||
450 | adjusted_mode->crtc_hblank_start + | ||
451 | hsync_pos; | ||
452 | /* keept hsync width constant */ | ||
453 | adjusted_mode->crtc_hsync_end = | ||
454 | adjusted_mode->crtc_hsync_start + | ||
455 | hsync_width; | ||
456 | border = 1; | ||
457 | } else if (panel_ratio < desired_ratio) { /* letter */ | ||
458 | u32 scaled_height = mode->vdisplay * | ||
459 | horiz_scale / PANEL_RATIO_FACTOR; | ||
460 | vert_ratio = horiz_ratio; | ||
461 | pfit_control |= (HORIZ_AUTO_SCALE | | ||
462 | VERT_INTERP_BILINEAR | | ||
463 | HORIZ_INTERP_BILINEAR); | ||
464 | /* Letterbox will have top/bottom border */ | ||
465 | top_border = (adjusted_mode->vdisplay - | ||
466 | scaled_height) / 2; | ||
467 | bottom_border = top_border; | ||
468 | if (mode->vdisplay & 1) | ||
469 | bottom_border++; | ||
470 | adjusted_mode->crtc_vdisplay = scaled_height; | ||
471 | /* use border instead of border minus one */ | ||
472 | adjusted_mode->crtc_vblank_start = | ||
473 | scaled_height + bottom_border; | ||
474 | /* keep the vblank width constant */ | ||
475 | adjusted_mode->crtc_vblank_end = | ||
476 | adjusted_mode->crtc_vblank_start + | ||
477 | vblank_width; | ||
478 | /* | ||
479 | * get the vsync start pos relative to | ||
480 | * vblank start | ||
481 | */ | ||
482 | vsync_pos = (vblank_width - vsync_width) / 2; | ||
483 | adjusted_mode->crtc_vsync_start = | ||
484 | adjusted_mode->crtc_vblank_start + | ||
485 | vsync_pos; | ||
486 | /* keep the vsync width constant */ | ||
487 | adjusted_mode->crtc_vsync_end = | ||
488 | adjusted_mode->crtc_vsync_start + | ||
489 | vsync_width; | ||
490 | border = 1; | ||
491 | } else { | ||
492 | /* Aspects match, Let hw scale both directions */ | ||
493 | pfit_control |= (VERT_AUTO_SCALE | | ||
494 | HORIZ_AUTO_SCALE | | ||
495 | VERT_INTERP_BILINEAR | | ||
496 | HORIZ_INTERP_BILINEAR); | ||
497 | } | ||
498 | horiz_bits = (1 << bits) * horiz_ratio / | ||
499 | PANEL_RATIO_FACTOR; | ||
500 | vert_bits = (1 << bits) * vert_ratio / | ||
501 | PANEL_RATIO_FACTOR; | ||
502 | pfit_pgm_ratios = | ||
503 | ((vert_bits << PFIT_VERT_SCALE_SHIFT) & | ||
504 | PFIT_VERT_SCALE_MASK) | | ||
505 | ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) & | ||
506 | PFIT_HORIZ_SCALE_MASK); | ||
507 | } | ||
508 | break; | ||
509 | |||
510 | case DRM_MODE_SCALE_FULLSCREEN: | ||
511 | /* | ||
512 | * Full scaling, even if it changes the aspect ratio. | ||
513 | * Fortunately this is all done for us in hw. | ||
514 | */ | ||
515 | pfit_control |= PFIT_ENABLE; | ||
516 | if (IS_I965G(dev)) | ||
517 | pfit_control |= PFIT_SCALING_AUTO; | ||
518 | else | ||
519 | pfit_control |= (VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | | ||
520 | VERT_INTERP_BILINEAR | | ||
521 | HORIZ_INTERP_BILINEAR); | ||
522 | break; | ||
523 | default: | ||
524 | break; | ||
525 | } | ||
526 | |||
527 | out: | ||
528 | lvds_priv->pfit_control = pfit_control; | ||
529 | lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; | ||
259 | /* | 530 | /* |
260 | * XXX: It would be nice to support lower refresh rates on the | 531 | * XXX: It would be nice to support lower refresh rates on the |
261 | * panels to reduce power consumption, and perhaps match the | 532 | * panels to reduce power consumption, and perhaps match the |
@@ -301,8 +572,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
301 | { | 572 | { |
302 | struct drm_device *dev = encoder->dev; | 573 | struct drm_device *dev = encoder->dev; |
303 | struct drm_i915_private *dev_priv = dev->dev_private; | 574 | struct drm_i915_private *dev_priv = dev->dev_private; |
304 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 575 | struct intel_output *intel_output = enc_to_intel_output(encoder); |
305 | u32 pfit_control; | 576 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; |
306 | 577 | ||
307 | /* | 578 | /* |
308 | * The LVDS pin pair will already have been turned on in the | 579 | * The LVDS pin pair will already have been turned on in the |
@@ -319,22 +590,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
319 | * screen. Should be enabled before the pipe is enabled, according to | 590 | * screen. Should be enabled before the pipe is enabled, according to |
320 | * register description and PRM. | 591 | * register description and PRM. |
321 | */ | 592 | */ |
322 | if (mode->hdisplay != adjusted_mode->hdisplay || | 593 | I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); |
323 | mode->vdisplay != adjusted_mode->vdisplay) | 594 | I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); |
324 | pfit_control = (PFIT_ENABLE | VERT_AUTO_SCALE | | ||
325 | HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | | ||
326 | HORIZ_INTERP_BILINEAR); | ||
327 | else | ||
328 | pfit_control = 0; | ||
329 | |||
330 | if (!IS_I965G(dev)) { | ||
331 | if (dev_priv->panel_wants_dither || dev_priv->lvds_dither) | ||
332 | pfit_control |= PANEL_8TO6_DITHER_ENABLE; | ||
333 | } | ||
334 | else | ||
335 | pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT; | ||
336 | |||
337 | I915_WRITE(PFIT_CONTROL, pfit_control); | ||
338 | } | 595 | } |
339 | 596 | ||
340 | /** | 597 | /** |
@@ -406,6 +663,34 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
406 | struct drm_property *property, | 663 | struct drm_property *property, |
407 | uint64_t value) | 664 | uint64_t value) |
408 | { | 665 | { |
666 | struct drm_device *dev = connector->dev; | ||
667 | struct intel_output *intel_output = | ||
668 | to_intel_output(connector); | ||
669 | |||
670 | if (property == dev->mode_config.scaling_mode_property && | ||
671 | connector->encoder) { | ||
672 | struct drm_crtc *crtc = connector->encoder->crtc; | ||
673 | struct intel_lvds_priv *lvds_priv = intel_output->dev_priv; | ||
674 | if (value == DRM_MODE_SCALE_NON_GPU) { | ||
675 | DRM_DEBUG_KMS(I915_LVDS, | ||
676 | "non_GPU property is unsupported\n"); | ||
677 | return 0; | ||
678 | } | ||
679 | if (lvds_priv->fitting_mode == value) { | ||
680 | /* the LVDS scaling property is not changed */ | ||
681 | return 0; | ||
682 | } | ||
683 | lvds_priv->fitting_mode = value; | ||
684 | if (crtc && crtc->enabled) { | ||
685 | /* | ||
686 | * If the CRTC is enabled, the display will be changed | ||
687 | * according to the new panel fitting mode. | ||
688 | */ | ||
689 | drm_crtc_helper_set_mode(crtc, &crtc->mode, | ||
690 | crtc->x, crtc->y, crtc->fb); | ||
691 | } | ||
692 | } | ||
693 | |||
409 | return 0; | 694 | return 0; |
410 | } | 695 | } |
411 | 696 | ||
@@ -456,7 +741,7 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
456 | .callback = intel_no_lvds_dmi_callback, | 741 | .callback = intel_no_lvds_dmi_callback, |
457 | .ident = "Apple Mac Mini (Core series)", | 742 | .ident = "Apple Mac Mini (Core series)", |
458 | .matches = { | 743 | .matches = { |
459 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | 744 | DMI_MATCH(DMI_SYS_VENDOR, "Apple"), |
460 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), | 745 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"), |
461 | }, | 746 | }, |
462 | }, | 747 | }, |
@@ -464,7 +749,7 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
464 | .callback = intel_no_lvds_dmi_callback, | 749 | .callback = intel_no_lvds_dmi_callback, |
465 | .ident = "Apple Mac Mini (Core 2 series)", | 750 | .ident = "Apple Mac Mini (Core 2 series)", |
466 | .matches = { | 751 | .matches = { |
467 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | 752 | DMI_MATCH(DMI_SYS_VENDOR, "Apple"), |
468 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), | 753 | DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"), |
469 | }, | 754 | }, |
470 | }, | 755 | }, |
@@ -518,6 +803,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
518 | struct drm_encoder *encoder; | 803 | struct drm_encoder *encoder; |
519 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 804 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
520 | struct drm_crtc *crtc; | 805 | struct drm_crtc *crtc; |
806 | struct intel_lvds_priv *lvds_priv; | ||
521 | u32 lvds; | 807 | u32 lvds; |
522 | int pipe, gpio = GPIOC; | 808 | int pipe, gpio = GPIOC; |
523 | 809 | ||
@@ -531,7 +817,8 @@ void intel_lvds_init(struct drm_device *dev) | |||
531 | gpio = PCH_GPIOC; | 817 | gpio = PCH_GPIOC; |
532 | } | 818 | } |
533 | 819 | ||
534 | intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); | 820 | intel_output = kzalloc(sizeof(struct intel_output) + |
821 | sizeof(struct intel_lvds_priv), GFP_KERNEL); | ||
535 | if (!intel_output) { | 822 | if (!intel_output) { |
536 | return; | 823 | return; |
537 | } | 824 | } |
@@ -553,7 +840,18 @@ void intel_lvds_init(struct drm_device *dev) | |||
553 | connector->interlace_allowed = false; | 840 | connector->interlace_allowed = false; |
554 | connector->doublescan_allowed = false; | 841 | connector->doublescan_allowed = false; |
555 | 842 | ||
843 | lvds_priv = (struct intel_lvds_priv *)(intel_output + 1); | ||
844 | intel_output->dev_priv = lvds_priv; | ||
845 | /* create the scaling mode property */ | ||
846 | drm_mode_create_scaling_mode_property(dev); | ||
847 | /* | ||
848 | * the initial panel fitting mode will be FULL_SCREEN. | ||
849 | */ | ||
556 | 850 | ||
851 | drm_connector_attach_property(&intel_output->base, | ||
852 | dev->mode_config.scaling_mode_property, | ||
853 | DRM_MODE_SCALE_FULLSCREEN); | ||
854 | lvds_priv->fitting_mode = DRM_MODE_SCALE_FULLSCREEN; | ||
557 | /* | 855 | /* |
558 | * LVDS discovery: | 856 | * LVDS discovery: |
559 | * 1) check for EDID on DDC | 857 | * 1) check for EDID on DDC |
@@ -649,5 +947,5 @@ failed: | |||
649 | if (intel_output->ddc_bus) | 947 | if (intel_output->ddc_bus) |
650 | intel_i2c_destroy(intel_output->ddc_bus); | 948 | intel_i2c_destroy(intel_output->ddc_bus); |
651 | drm_connector_cleanup(connector); | 949 | drm_connector_cleanup(connector); |
652 | kfree(connector); | 950 | kfree(intel_output); |
653 | } | 951 | } |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index e0910fefce87..67e2f4632a24 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -53,10 +53,9 @@ bool intel_ddc_probe(struct intel_output *intel_output) | |||
53 | } | 53 | } |
54 | }; | 54 | }; |
55 | 55 | ||
56 | intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); | 56 | intel_i2c_quirk_set(intel_output->base.dev, true); |
57 | ret = i2c_transfer(&intel_output->ddc_bus->adapter, msgs, 2); | 57 | ret = i2c_transfer(intel_output->ddc_bus, msgs, 2); |
58 | intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); | 58 | intel_i2c_quirk_set(intel_output->base.dev, false); |
59 | |||
60 | if (ret == 2) | 59 | if (ret == 2) |
61 | return true; | 60 | return true; |
62 | 61 | ||
@@ -74,10 +73,9 @@ int intel_ddc_get_modes(struct intel_output *intel_output) | |||
74 | struct edid *edid; | 73 | struct edid *edid; |
75 | int ret = 0; | 74 | int ret = 0; |
76 | 75 | ||
77 | intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, true); | 76 | intel_i2c_quirk_set(intel_output->base.dev, true); |
78 | edid = drm_get_edid(&intel_output->base, | 77 | edid = drm_get_edid(&intel_output->base, intel_output->ddc_bus); |
79 | &intel_output->ddc_bus->adapter); | 78 | intel_i2c_quirk_set(intel_output->base.dev, false); |
80 | intel_i2c_quirk_set(intel_output->ddc_bus->drm_dev, false); | ||
81 | if (edid) { | 79 | if (edid) { |
82 | drm_mode_connector_update_edid_property(&intel_output->base, | 80 | drm_mode_connector_update_edid_property(&intel_output->base, |
83 | edid); | 81 | edid); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9a00adb3a508..f03473779feb 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -38,8 +38,7 @@ | |||
38 | #undef SDVO_DEBUG | 38 | #undef SDVO_DEBUG |
39 | #define I915_SDVO "i915_sdvo" | 39 | #define I915_SDVO "i915_sdvo" |
40 | struct intel_sdvo_priv { | 40 | struct intel_sdvo_priv { |
41 | struct intel_i2c_chan *i2c_bus; | 41 | u8 slave_addr; |
42 | int slaveaddr; | ||
43 | 42 | ||
44 | /* Register for the SDVO device: SDVOB or SDVOC */ | 43 | /* Register for the SDVO device: SDVOB or SDVOC */ |
45 | int output_device; | 44 | int output_device; |
@@ -146,13 +145,13 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
146 | 145 | ||
147 | struct i2c_msg msgs[] = { | 146 | struct i2c_msg msgs[] = { |
148 | { | 147 | { |
149 | .addr = sdvo_priv->i2c_bus->slave_addr, | 148 | .addr = sdvo_priv->slave_addr >> 1, |
150 | .flags = 0, | 149 | .flags = 0, |
151 | .len = 1, | 150 | .len = 1, |
152 | .buf = out_buf, | 151 | .buf = out_buf, |
153 | }, | 152 | }, |
154 | { | 153 | { |
155 | .addr = sdvo_priv->i2c_bus->slave_addr, | 154 | .addr = sdvo_priv->slave_addr >> 1, |
156 | .flags = I2C_M_RD, | 155 | .flags = I2C_M_RD, |
157 | .len = 1, | 156 | .len = 1, |
158 | .buf = buf, | 157 | .buf = buf, |
@@ -162,7 +161,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
162 | out_buf[0] = addr; | 161 | out_buf[0] = addr; |
163 | out_buf[1] = 0; | 162 | out_buf[1] = 0; |
164 | 163 | ||
165 | if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2) | 164 | if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) |
166 | { | 165 | { |
167 | *ch = buf[0]; | 166 | *ch = buf[0]; |
168 | return true; | 167 | return true; |
@@ -175,10 +174,11 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
175 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | 174 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, |
176 | u8 ch) | 175 | u8 ch) |
177 | { | 176 | { |
177 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
178 | u8 out_buf[2]; | 178 | u8 out_buf[2]; |
179 | struct i2c_msg msgs[] = { | 179 | struct i2c_msg msgs[] = { |
180 | { | 180 | { |
181 | .addr = intel_output->i2c_bus->slave_addr, | 181 | .addr = sdvo_priv->slave_addr >> 1, |
182 | .flags = 0, | 182 | .flags = 0, |
183 | .len = 2, | 183 | .len = 2, |
184 | .buf = out_buf, | 184 | .buf = out_buf, |
@@ -188,7 +188,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | |||
188 | out_buf[0] = addr; | 188 | out_buf[0] = addr; |
189 | out_buf[1] = ch; | 189 | out_buf[1] = ch; |
190 | 190 | ||
191 | if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1) | 191 | if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) |
192 | { | 192 | { |
193 | return true; | 193 | return true; |
194 | } | 194 | } |
@@ -1369,9 +1369,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1369 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1369 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1370 | struct edid *edid = NULL; | 1370 | struct edid *edid = NULL; |
1371 | 1371 | ||
1372 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1373 | edid = drm_get_edid(&intel_output->base, | 1372 | edid = drm_get_edid(&intel_output->base, |
1374 | &intel_output->ddc_bus->adapter); | 1373 | intel_output->ddc_bus); |
1375 | if (edid != NULL) { | 1374 | if (edid != NULL) { |
1376 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1375 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); |
1377 | kfree(edid); | 1376 | kfree(edid); |
@@ -1549,7 +1548,6 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1549 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1548 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1550 | { | 1549 | { |
1551 | struct intel_output *intel_output = to_intel_output(connector); | 1550 | struct intel_output *intel_output = to_intel_output(connector); |
1552 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1553 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1551 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1554 | 1552 | ||
1555 | /* | 1553 | /* |
@@ -1557,8 +1555,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1557 | * Assume that the preferred modes are | 1555 | * Assume that the preferred modes are |
1558 | * arranged in priority order. | 1556 | * arranged in priority order. |
1559 | */ | 1557 | */ |
1560 | /* set the bus switch and get the modes */ | ||
1561 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1562 | intel_ddc_get_modes(intel_output); | 1558 | intel_ddc_get_modes(intel_output); |
1563 | if (list_empty(&connector->probed_modes) == false) | 1559 | if (list_empty(&connector->probed_modes) == false) |
1564 | return; | 1560 | return; |
@@ -1709,7 +1705,7 @@ intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) | |||
1709 | 1705 | ||
1710 | list_for_each_entry(connector, | 1706 | list_for_each_entry(connector, |
1711 | &dev->mode_config.connector_list, head) { | 1707 | &dev->mode_config.connector_list, head) { |
1712 | if (to_intel_output(connector)->ddc_bus == chan) { | 1708 | if (to_intel_output(connector)->ddc_bus == &chan->adapter) { |
1713 | intel_output = to_intel_output(connector); | 1709 | intel_output = to_intel_output(connector); |
1714 | break; | 1710 | break; |
1715 | } | 1711 | } |
@@ -1723,7 +1719,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | |||
1723 | struct intel_output *intel_output; | 1719 | struct intel_output *intel_output; |
1724 | struct intel_sdvo_priv *sdvo_priv; | 1720 | struct intel_sdvo_priv *sdvo_priv; |
1725 | struct i2c_algo_bit_data *algo_data; | 1721 | struct i2c_algo_bit_data *algo_data; |
1726 | struct i2c_algorithm *algo; | 1722 | const struct i2c_algorithm *algo; |
1727 | 1723 | ||
1728 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 1724 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
1729 | intel_output = | 1725 | intel_output = |
@@ -1733,7 +1729,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | |||
1733 | return -EINVAL; | 1729 | return -EINVAL; |
1734 | 1730 | ||
1735 | sdvo_priv = intel_output->dev_priv; | 1731 | sdvo_priv = intel_output->dev_priv; |
1736 | algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo; | 1732 | algo = intel_output->i2c_bus->algo; |
1737 | 1733 | ||
1738 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | 1734 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); |
1739 | return algo->master_xfer(i2c_adap, msgs, num); | 1735 | return algo->master_xfer(i2c_adap, msgs, num); |
@@ -1785,13 +1781,11 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1785 | struct drm_connector *connector; | 1781 | struct drm_connector *connector; |
1786 | struct intel_output *intel_output; | 1782 | struct intel_output *intel_output; |
1787 | struct intel_sdvo_priv *sdvo_priv; | 1783 | struct intel_sdvo_priv *sdvo_priv; |
1788 | struct intel_i2c_chan *i2cbus = NULL; | 1784 | |
1789 | struct intel_i2c_chan *ddcbus = NULL; | ||
1790 | int connector_type; | 1785 | int connector_type; |
1791 | u8 ch[0x40]; | 1786 | u8 ch[0x40]; |
1792 | int i; | 1787 | int i; |
1793 | int encoder_type, output_id; | 1788 | int encoder_type; |
1794 | u8 slave_addr; | ||
1795 | 1789 | ||
1796 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 1790 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
1797 | if (!intel_output) { | 1791 | if (!intel_output) { |
@@ -1799,29 +1793,24 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1799 | } | 1793 | } |
1800 | 1794 | ||
1801 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); | 1795 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); |
1796 | sdvo_priv->output_device = output_device; | ||
1797 | |||
1798 | intel_output->dev_priv = sdvo_priv; | ||
1802 | intel_output->type = INTEL_OUTPUT_SDVO; | 1799 | intel_output->type = INTEL_OUTPUT_SDVO; |
1803 | 1800 | ||
1804 | /* setup the DDC bus. */ | 1801 | /* setup the DDC bus. */ |
1805 | if (output_device == SDVOB) | 1802 | if (output_device == SDVOB) |
1806 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 1803 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); |
1807 | else | 1804 | else |
1808 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 1805 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); |
1809 | 1806 | ||
1810 | if (!i2cbus) | 1807 | if (!intel_output->i2c_bus) |
1811 | goto err_inteloutput; | 1808 | goto err_inteloutput; |
1812 | 1809 | ||
1813 | slave_addr = intel_sdvo_get_slave_addr(dev, output_device); | 1810 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); |
1814 | sdvo_priv->i2c_bus = i2cbus; | ||
1815 | 1811 | ||
1816 | if (output_device == SDVOB) { | 1812 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
1817 | output_id = 1; | 1813 | intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; |
1818 | } else { | ||
1819 | output_id = 2; | ||
1820 | } | ||
1821 | sdvo_priv->i2c_bus->slave_addr = slave_addr >> 1; | ||
1822 | sdvo_priv->output_device = output_device; | ||
1823 | intel_output->i2c_bus = i2cbus; | ||
1824 | intel_output->dev_priv = sdvo_priv; | ||
1825 | 1814 | ||
1826 | /* Read the regs to test if we can talk to the device */ | 1815 | /* Read the regs to test if we can talk to the device */ |
1827 | for (i = 0; i < 0x40; i++) { | 1816 | for (i = 0; i < 0x40; i++) { |
@@ -1835,17 +1824,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1835 | 1824 | ||
1836 | /* setup the DDC bus. */ | 1825 | /* setup the DDC bus. */ |
1837 | if (output_device == SDVOB) | 1826 | if (output_device == SDVOB) |
1838 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 1827 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); |
1839 | else | 1828 | else |
1840 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 1829 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); |
1841 | 1830 | ||
1842 | if (ddcbus == NULL) | 1831 | if (intel_output->ddc_bus == NULL) |
1843 | goto err_i2c; | 1832 | goto err_i2c; |
1844 | 1833 | ||
1845 | intel_sdvo_i2c_bit_algo.functionality = | 1834 | /* Wrap with our custom algo which switches to DDC mode */ |
1846 | intel_output->i2c_bus->adapter.algo->functionality; | 1835 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
1847 | ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo; | ||
1848 | intel_output->ddc_bus = ddcbus; | ||
1849 | 1836 | ||
1850 | /* In defaut case sdvo lvds is false */ | 1837 | /* In defaut case sdvo lvds is false */ |
1851 | sdvo_priv->is_lvds = false; | 1838 | sdvo_priv->is_lvds = false; |
@@ -1965,9 +1952,10 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1965 | return true; | 1952 | return true; |
1966 | 1953 | ||
1967 | err_i2c: | 1954 | err_i2c: |
1968 | if (ddcbus != NULL) | 1955 | if (intel_output->ddc_bus != NULL) |
1969 | intel_i2c_destroy(intel_output->ddc_bus); | 1956 | intel_i2c_destroy(intel_output->ddc_bus); |
1970 | intel_i2c_destroy(intel_output->i2c_bus); | 1957 | if (intel_output->i2c_bus != NULL) |
1958 | intel_i2c_destroy(intel_output->i2c_bus); | ||
1971 | err_inteloutput: | 1959 | err_inteloutput: |
1972 | kfree(intel_output); | 1960 | kfree(intel_output); |
1973 | 1961 | ||
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index ea68992e4416..a43c98e3f077 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1383,34 +1383,31 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output) | |||
1383 | /* | 1383 | /* |
1384 | * Detect TV by polling) | 1384 | * Detect TV by polling) |
1385 | */ | 1385 | */ |
1386 | if (intel_output->load_detect_temp) { | 1386 | save_tv_dac = tv_dac; |
1387 | /* TV not currently running, prod it with destructive detect */ | 1387 | tv_ctl = I915_READ(TV_CTL); |
1388 | save_tv_dac = tv_dac; | 1388 | save_tv_ctl = tv_ctl; |
1389 | tv_ctl = I915_READ(TV_CTL); | 1389 | tv_ctl &= ~TV_ENC_ENABLE; |
1390 | save_tv_ctl = tv_ctl; | 1390 | tv_ctl &= ~TV_TEST_MODE_MASK; |
1391 | tv_ctl &= ~TV_ENC_ENABLE; | 1391 | tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; |
1392 | tv_ctl &= ~TV_TEST_MODE_MASK; | 1392 | tv_dac &= ~TVDAC_SENSE_MASK; |
1393 | tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; | 1393 | tv_dac &= ~DAC_A_MASK; |
1394 | tv_dac &= ~TVDAC_SENSE_MASK; | 1394 | tv_dac &= ~DAC_B_MASK; |
1395 | tv_dac &= ~DAC_A_MASK; | 1395 | tv_dac &= ~DAC_C_MASK; |
1396 | tv_dac &= ~DAC_B_MASK; | 1396 | tv_dac |= (TVDAC_STATE_CHG_EN | |
1397 | tv_dac &= ~DAC_C_MASK; | 1397 | TVDAC_A_SENSE_CTL | |
1398 | tv_dac |= (TVDAC_STATE_CHG_EN | | 1398 | TVDAC_B_SENSE_CTL | |
1399 | TVDAC_A_SENSE_CTL | | 1399 | TVDAC_C_SENSE_CTL | |
1400 | TVDAC_B_SENSE_CTL | | 1400 | DAC_CTL_OVERRIDE | |
1401 | TVDAC_C_SENSE_CTL | | 1401 | DAC_A_0_7_V | |
1402 | DAC_CTL_OVERRIDE | | 1402 | DAC_B_0_7_V | |
1403 | DAC_A_0_7_V | | 1403 | DAC_C_0_7_V); |
1404 | DAC_B_0_7_V | | 1404 | I915_WRITE(TV_CTL, tv_ctl); |
1405 | DAC_C_0_7_V); | 1405 | I915_WRITE(TV_DAC, tv_dac); |
1406 | I915_WRITE(TV_CTL, tv_ctl); | 1406 | intel_wait_for_vblank(dev); |
1407 | I915_WRITE(TV_DAC, tv_dac); | 1407 | tv_dac = I915_READ(TV_DAC); |
1408 | intel_wait_for_vblank(dev); | 1408 | I915_WRITE(TV_DAC, save_tv_dac); |
1409 | tv_dac = I915_READ(TV_DAC); | 1409 | I915_WRITE(TV_CTL, save_tv_ctl); |
1410 | I915_WRITE(TV_DAC, save_tv_dac); | 1410 | intel_wait_for_vblank(dev); |
1411 | I915_WRITE(TV_CTL, save_tv_ctl); | ||
1412 | intel_wait_for_vblank(dev); | ||
1413 | } | ||
1414 | /* | 1411 | /* |
1415 | * A B C | 1412 | * A B C |
1416 | * 0 1 1 Composite | 1413 | * 0 1 1 Composite |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index f30aa7274a54..f97563db4e59 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -35,6 +35,23 @@ | |||
35 | #include "atom.h" | 35 | #include "atom.h" |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Clear GPU surface registers. | ||
39 | */ | ||
40 | static void radeon_surface_init(struct radeon_device *rdev) | ||
41 | { | ||
42 | /* FIXME: check this out */ | ||
43 | if (rdev->family < CHIP_R600) { | ||
44 | int i; | ||
45 | |||
46 | for (i = 0; i < 8; i++) { | ||
47 | WREG32(RADEON_SURFACE0_INFO + | ||
48 | i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO), | ||
49 | 0); | ||
50 | } | ||
51 | } | ||
52 | } | ||
53 | |||
54 | /* | ||
38 | * GPU scratch registers helpers function. | 55 | * GPU scratch registers helpers function. |
39 | */ | 56 | */ |
40 | static void radeon_scratch_init(struct radeon_device *rdev) | 57 | static void radeon_scratch_init(struct radeon_device *rdev) |
@@ -496,6 +513,8 @@ int radeon_device_init(struct radeon_device *rdev, | |||
496 | radeon_errata(rdev); | 513 | radeon_errata(rdev); |
497 | /* Initialize scratch registers */ | 514 | /* Initialize scratch registers */ |
498 | radeon_scratch_init(rdev); | 515 | radeon_scratch_init(rdev); |
516 | /* Initialize surface registers */ | ||
517 | radeon_surface_init(rdev); | ||
499 | 518 | ||
500 | /* TODO: disable VGA need to use VGA request */ | 519 | /* TODO: disable VGA need to use VGA request */ |
501 | /* BIOS*/ | 520 | /* BIOS*/ |
@@ -604,9 +623,6 @@ int radeon_device_init(struct radeon_device *rdev, | |||
604 | if (r) { | 623 | if (r) { |
605 | return r; | 624 | return r; |
606 | } | 625 | } |
607 | if (rdev->fbdev_rfb && rdev->fbdev_rfb->obj) { | ||
608 | rdev->fbdev_robj = rdev->fbdev_rfb->obj->driver_private; | ||
609 | } | ||
610 | if (!ret) { | 626 | if (!ret) { |
611 | DRM_INFO("radeon: kernel modesetting successfully initialized.\n"); | 627 | DRM_INFO("radeon: kernel modesetting successfully initialized.\n"); |
612 | } | 628 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 09c9fb9f6210..84ba69f48784 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -345,7 +345,7 @@ static void __exit radeon_exit(void) | |||
345 | drm_exit(driver); | 345 | drm_exit(driver); |
346 | } | 346 | } |
347 | 347 | ||
348 | late_initcall(radeon_init); | 348 | module_init(radeon_init); |
349 | module_exit(radeon_exit); | 349 | module_exit(radeon_exit); |
350 | 350 | ||
351 | MODULE_AUTHOR(DRIVER_AUTHOR); | 351 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index fa86d398945e..9e8f191eb64a 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -478,14 +478,16 @@ int radeonfb_create(struct radeon_device *rdev, | |||
478 | { | 478 | { |
479 | struct fb_info *info; | 479 | struct fb_info *info; |
480 | struct radeon_fb_device *rfbdev; | 480 | struct radeon_fb_device *rfbdev; |
481 | struct drm_framebuffer *fb; | 481 | struct drm_framebuffer *fb = NULL; |
482 | struct radeon_framebuffer *rfb; | 482 | struct radeon_framebuffer *rfb; |
483 | struct drm_mode_fb_cmd mode_cmd; | 483 | struct drm_mode_fb_cmd mode_cmd; |
484 | struct drm_gem_object *gobj = NULL; | 484 | struct drm_gem_object *gobj = NULL; |
485 | struct radeon_object *robj = NULL; | 485 | struct radeon_object *robj = NULL; |
486 | struct device *device = &rdev->pdev->dev; | 486 | struct device *device = &rdev->pdev->dev; |
487 | int size, aligned_size, ret; | 487 | int size, aligned_size, ret; |
488 | u64 fb_gpuaddr; | ||
488 | void *fbptr = NULL; | 489 | void *fbptr = NULL; |
490 | unsigned long tmp; | ||
489 | 491 | ||
490 | mode_cmd.width = surface_width; | 492 | mode_cmd.width = surface_width; |
491 | mode_cmd.height = surface_height; | 493 | mode_cmd.height = surface_height; |
@@ -498,11 +500,12 @@ int radeonfb_create(struct radeon_device *rdev, | |||
498 | aligned_size = ALIGN(size, PAGE_SIZE); | 500 | aligned_size = ALIGN(size, PAGE_SIZE); |
499 | 501 | ||
500 | ret = radeon_gem_object_create(rdev, aligned_size, 0, | 502 | ret = radeon_gem_object_create(rdev, aligned_size, 0, |
501 | RADEON_GEM_DOMAIN_VRAM, | 503 | RADEON_GEM_DOMAIN_VRAM, |
502 | false, ttm_bo_type_kernel, | 504 | false, ttm_bo_type_kernel, |
503 | false, &gobj); | 505 | false, &gobj); |
504 | if (ret) { | 506 | if (ret) { |
505 | printk(KERN_ERR "failed to allocate framebuffer\n"); | 507 | printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", |
508 | surface_width, surface_height); | ||
506 | ret = -ENOMEM; | 509 | ret = -ENOMEM; |
507 | goto out; | 510 | goto out; |
508 | } | 511 | } |
@@ -515,12 +518,19 @@ int radeonfb_create(struct radeon_device *rdev, | |||
515 | ret = -ENOMEM; | 518 | ret = -ENOMEM; |
516 | goto out_unref; | 519 | goto out_unref; |
517 | } | 520 | } |
521 | ret = radeon_object_pin(robj, RADEON_GEM_DOMAIN_VRAM, &fb_gpuaddr); | ||
522 | if (ret) { | ||
523 | printk(KERN_ERR "failed to pin framebuffer\n"); | ||
524 | ret = -ENOMEM; | ||
525 | goto out_unref; | ||
526 | } | ||
518 | 527 | ||
519 | list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); | 528 | list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); |
520 | 529 | ||
521 | rfb = to_radeon_framebuffer(fb); | 530 | rfb = to_radeon_framebuffer(fb); |
522 | *rfb_p = rfb; | 531 | *rfb_p = rfb; |
523 | rdev->fbdev_rfb = rfb; | 532 | rdev->fbdev_rfb = rfb; |
533 | rdev->fbdev_robj = robj; | ||
524 | 534 | ||
525 | info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); | 535 | info = framebuffer_alloc(sizeof(struct radeon_fb_device), device); |
526 | if (info == NULL) { | 536 | if (info == NULL) { |
@@ -541,13 +551,13 @@ int radeonfb_create(struct radeon_device *rdev, | |||
541 | info->fix.xpanstep = 1; /* doing it in hw */ | 551 | info->fix.xpanstep = 1; /* doing it in hw */ |
542 | info->fix.ypanstep = 1; /* doing it in hw */ | 552 | info->fix.ypanstep = 1; /* doing it in hw */ |
543 | info->fix.ywrapstep = 0; | 553 | info->fix.ywrapstep = 0; |
544 | info->fix.accel = FB_ACCEL_I830; | 554 | info->fix.accel = FB_ACCEL_NONE; |
545 | info->fix.type_aux = 0; | 555 | info->fix.type_aux = 0; |
546 | info->flags = FBINFO_DEFAULT; | 556 | info->flags = FBINFO_DEFAULT; |
547 | info->fbops = &radeonfb_ops; | 557 | info->fbops = &radeonfb_ops; |
548 | info->fix.line_length = fb->pitch; | 558 | info->fix.line_length = fb->pitch; |
549 | info->screen_base = fbptr; | 559 | tmp = fb_gpuaddr - rdev->mc.vram_location; |
550 | info->fix.smem_start = (unsigned long)fbptr; | 560 | info->fix.smem_start = rdev->mc.aper_base + tmp; |
551 | info->fix.smem_len = size; | 561 | info->fix.smem_len = size; |
552 | info->screen_base = fbptr; | 562 | info->screen_base = fbptr; |
553 | info->screen_size = size; | 563 | info->screen_size = size; |
@@ -562,8 +572,8 @@ int radeonfb_create(struct radeon_device *rdev, | |||
562 | info->var.width = -1; | 572 | info->var.width = -1; |
563 | info->var.xres = fb_width; | 573 | info->var.xres = fb_width; |
564 | info->var.yres = fb_height; | 574 | info->var.yres = fb_height; |
565 | info->fix.mmio_start = pci_resource_start(rdev->pdev, 2); | 575 | info->fix.mmio_start = 0; |
566 | info->fix.mmio_len = pci_resource_len(rdev->pdev, 2); | 576 | info->fix.mmio_len = 0; |
567 | info->pixmap.size = 64*1024; | 577 | info->pixmap.size = 64*1024; |
568 | info->pixmap.buf_align = 8; | 578 | info->pixmap.buf_align = 8; |
569 | info->pixmap.access_align = 32; | 579 | info->pixmap.access_align = 32; |
@@ -644,7 +654,7 @@ out_unref: | |||
644 | if (robj) { | 654 | if (robj) { |
645 | radeon_object_kunmap(robj); | 655 | radeon_object_kunmap(robj); |
646 | } | 656 | } |
647 | if (ret) { | 657 | if (fb && ret) { |
648 | list_del(&fb->filp_head); | 658 | list_del(&fb->filp_head); |
649 | drm_gem_object_unreference(gobj); | 659 | drm_gem_object_unreference(gobj); |
650 | drm_framebuffer_cleanup(fb); | 660 | drm_framebuffer_cleanup(fb); |
@@ -813,6 +823,7 @@ int radeonfb_remove(struct drm_device *dev, struct drm_framebuffer *fb) | |||
813 | robj = rfb->obj->driver_private; | 823 | robj = rfb->obj->driver_private; |
814 | unregister_framebuffer(info); | 824 | unregister_framebuffer(info); |
815 | radeon_object_kunmap(robj); | 825 | radeon_object_kunmap(robj); |
826 | radeon_object_unpin(robj); | ||
816 | framebuffer_release(info); | 827 | framebuffer_release(info); |
817 | } | 828 | } |
818 | 829 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 983e8df5e000..bac0d06c52ac 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -223,7 +223,6 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | |||
223 | { | 223 | { |
224 | uint32_t flags; | 224 | uint32_t flags; |
225 | uint32_t tmp; | 225 | uint32_t tmp; |
226 | void *fbptr; | ||
227 | int r; | 226 | int r; |
228 | 227 | ||
229 | flags = radeon_object_flags_from_domain(domain); | 228 | flags = radeon_object_flags_from_domain(domain); |
@@ -242,10 +241,6 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | |||
242 | DRM_ERROR("radeon: failed to reserve object for pinning it.\n"); | 241 | DRM_ERROR("radeon: failed to reserve object for pinning it.\n"); |
243 | return r; | 242 | return r; |
244 | } | 243 | } |
245 | if (robj->rdev->fbdev_robj == robj) { | ||
246 | mutex_lock(&robj->rdev->fbdev_info->lock); | ||
247 | radeon_object_kunmap(robj); | ||
248 | } | ||
249 | tmp = robj->tobj.mem.placement; | 244 | tmp = robj->tobj.mem.placement; |
250 | ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM); | 245 | ttm_flag_masked(&tmp, flags, TTM_PL_MASK_MEM); |
251 | robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING; | 246 | robj->tobj.proposed_placement = tmp | TTM_PL_FLAG_NO_EVICT | TTM_PL_MASK_CACHING; |
@@ -261,23 +256,12 @@ int radeon_object_pin(struct radeon_object *robj, uint32_t domain, | |||
261 | DRM_ERROR("radeon: failed to pin object.\n"); | 256 | DRM_ERROR("radeon: failed to pin object.\n"); |
262 | } | 257 | } |
263 | radeon_object_unreserve(robj); | 258 | radeon_object_unreserve(robj); |
264 | if (robj->rdev->fbdev_robj == robj) { | ||
265 | if (!r) { | ||
266 | r = radeon_object_kmap(robj, &fbptr); | ||
267 | } | ||
268 | if (!r) { | ||
269 | robj->rdev->fbdev_info->screen_base = fbptr; | ||
270 | robj->rdev->fbdev_info->fix.smem_start = (unsigned long)fbptr; | ||
271 | } | ||
272 | mutex_unlock(&robj->rdev->fbdev_info->lock); | ||
273 | } | ||
274 | return r; | 259 | return r; |
275 | } | 260 | } |
276 | 261 | ||
277 | void radeon_object_unpin(struct radeon_object *robj) | 262 | void radeon_object_unpin(struct radeon_object *robj) |
278 | { | 263 | { |
279 | uint32_t flags; | 264 | uint32_t flags; |
280 | void *fbptr; | ||
281 | int r; | 265 | int r; |
282 | 266 | ||
283 | spin_lock(&robj->tobj.lock); | 267 | spin_lock(&robj->tobj.lock); |
@@ -297,10 +281,6 @@ void radeon_object_unpin(struct radeon_object *robj) | |||
297 | DRM_ERROR("radeon: failed to reserve object for unpinning it.\n"); | 281 | DRM_ERROR("radeon: failed to reserve object for unpinning it.\n"); |
298 | return; | 282 | return; |
299 | } | 283 | } |
300 | if (robj->rdev->fbdev_robj == robj) { | ||
301 | mutex_lock(&robj->rdev->fbdev_info->lock); | ||
302 | radeon_object_kunmap(robj); | ||
303 | } | ||
304 | flags = robj->tobj.mem.placement; | 284 | flags = robj->tobj.mem.placement; |
305 | robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT; | 285 | robj->tobj.proposed_placement = flags & ~TTM_PL_FLAG_NO_EVICT; |
306 | r = ttm_buffer_object_validate(&robj->tobj, | 286 | r = ttm_buffer_object_validate(&robj->tobj, |
@@ -310,16 +290,6 @@ void radeon_object_unpin(struct radeon_object *robj) | |||
310 | DRM_ERROR("radeon: failed to unpin buffer.\n"); | 290 | DRM_ERROR("radeon: failed to unpin buffer.\n"); |
311 | } | 291 | } |
312 | radeon_object_unreserve(robj); | 292 | radeon_object_unreserve(robj); |
313 | if (robj->rdev->fbdev_robj == robj) { | ||
314 | if (!r) { | ||
315 | r = radeon_object_kmap(robj, &fbptr); | ||
316 | } | ||
317 | if (!r) { | ||
318 | robj->rdev->fbdev_info->screen_base = fbptr; | ||
319 | robj->rdev->fbdev_info->fix.smem_start = (unsigned long)fbptr; | ||
320 | } | ||
321 | mutex_unlock(&robj->rdev->fbdev_info->lock); | ||
322 | } | ||
323 | } | 293 | } |
324 | 294 | ||
325 | int radeon_object_wait(struct radeon_object *robj) | 295 | int radeon_object_wait(struct radeon_object *robj) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 517c84559633..bdec583901eb 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
35 | #include <linux/wait.h> | 35 | #include <linux/wait.h> |
36 | #include <linux/vmalloc.h> | 36 | #include <linux/vmalloc.h> |
37 | #include <linux/version.h> | ||
38 | #include <linux/module.h> | 37 | #include <linux/module.h> |
39 | 38 | ||
40 | void ttm_bo_free_old_node(struct ttm_buffer_object *bo) | 39 | void ttm_bo_free_old_node(struct ttm_buffer_object *bo) |
diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 27b146c54fbc..40b75032ea47 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <ttm/ttm_bo_driver.h> | 32 | #include <ttm/ttm_bo_driver.h> |
33 | #include <ttm/ttm_placement.h> | 33 | #include <ttm/ttm_placement.h> |
34 | #include <linux/mm.h> | 34 | #include <linux/mm.h> |
35 | #include <linux/version.h> | ||
36 | #include <linux/rbtree.h> | 35 | #include <linux/rbtree.h> |
37 | #include <linux/module.h> | 36 | #include <linux/module.h> |
38 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index 0331fa74cd3f..75dc8bd24592 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
@@ -28,7 +28,6 @@ | |||
28 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> | 28 | * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/version.h> | ||
32 | #include <linux/vmalloc.h> | 31 | #include <linux/vmalloc.h> |
33 | #include <linux/sched.h> | 32 | #include <linux/sched.h> |
34 | #include <linux/highmem.h> | 33 | #include <linux/highmem.h> |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index aa87b6a3bbef..8206442fbabd 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -328,6 +328,7 @@ config I2C_DAVINCI | |||
328 | 328 | ||
329 | config I2C_DESIGNWARE | 329 | config I2C_DESIGNWARE |
330 | tristate "Synopsys DesignWare" | 330 | tristate "Synopsys DesignWare" |
331 | depends on HAVE_CLK | ||
331 | help | 332 | help |
332 | If you say yes to this option, support will be included for the | 333 | If you say yes to this option, support will be included for the |
333 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 334 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
diff --git a/drivers/ide/cs5520.c b/drivers/ide/cs5520.c index bd066bb9d611..09f98ed0731f 100644 --- a/drivers/ide/cs5520.c +++ b/drivers/ide/cs5520.c | |||
@@ -135,6 +135,7 @@ static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_devic | |||
135 | 135 | ||
136 | ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); | 136 | ide_pci_setup_ports(dev, d, &hw[0], &hws[0]); |
137 | hw[0].irq = 14; | 137 | hw[0].irq = 14; |
138 | hw[1].irq = 15; | ||
138 | 139 | ||
139 | return ide_host_add(d, hws, 2, NULL); | 140 | return ide_host_add(d, hws, 2, NULL); |
140 | } | 141 | } |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 4a19686fcfe9..f0ede5953af8 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -876,9 +876,12 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
876 | return stat; | 876 | return stat; |
877 | 877 | ||
878 | /* | 878 | /* |
879 | * Sanity check the given block size | 879 | * Sanity check the given block size, in so far as making |
880 | * sure the sectors_per_frame we give to the caller won't | ||
881 | * end up being bogus. | ||
880 | */ | 882 | */ |
881 | blocklen = be32_to_cpu(capbuf.blocklen); | 883 | blocklen = be32_to_cpu(capbuf.blocklen); |
884 | blocklen = (blocklen >> SECTOR_BITS) << SECTOR_BITS; | ||
882 | switch (blocklen) { | 885 | switch (blocklen) { |
883 | case 512: | 886 | case 512: |
884 | case 1024: | 887 | case 1024: |
@@ -886,10 +889,9 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity, | |||
886 | case 4096: | 889 | case 4096: |
887 | break; | 890 | break; |
888 | default: | 891 | default: |
889 | printk(KERN_ERR PFX "%s: weird block size %u\n", | 892 | printk_once(KERN_ERR PFX "%s: weird block size %u; " |
893 | "setting default block size to 2048\n", | ||
890 | drive->name, blocklen); | 894 | drive->name, blocklen); |
891 | printk(KERN_ERR PFX "%s: default to 2kb block size\n", | ||
892 | drive->name); | ||
893 | blocklen = 2048; | 895 | blocklen = 2048; |
894 | break; | 896 | break; |
895 | } | 897 | } |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 219e6fb78dc6..ee58c88dee5a 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -361,9 +361,6 @@ static int ide_tune_dma(ide_drive_t *drive) | |||
361 | if (__ide_dma_bad_drive(drive)) | 361 | if (__ide_dma_bad_drive(drive)) |
362 | return 0; | 362 | return 0; |
363 | 363 | ||
364 | if (ide_id_dma_bug(drive)) | ||
365 | return 0; | ||
366 | |||
367 | if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) | 364 | if (hwif->host_flags & IDE_HFLAG_TRUST_BIOS_FOR_DMA) |
368 | return config_drive_for_dma(drive); | 365 | return config_drive_for_dma(drive); |
369 | 366 | ||
@@ -394,24 +391,6 @@ static int ide_dma_check(ide_drive_t *drive) | |||
394 | return -1; | 391 | return -1; |
395 | } | 392 | } |
396 | 393 | ||
397 | int ide_id_dma_bug(ide_drive_t *drive) | ||
398 | { | ||
399 | u16 *id = drive->id; | ||
400 | |||
401 | if (id[ATA_ID_FIELD_VALID] & 4) { | ||
402 | if ((id[ATA_ID_UDMA_MODES] >> 8) && | ||
403 | (id[ATA_ID_MWDMA_MODES] >> 8)) | ||
404 | goto err_out; | ||
405 | } else if ((id[ATA_ID_MWDMA_MODES] >> 8) && | ||
406 | (id[ATA_ID_SWDMA_MODES] >> 8)) | ||
407 | goto err_out; | ||
408 | |||
409 | return 0; | ||
410 | err_out: | ||
411 | printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name); | ||
412 | return 1; | ||
413 | } | ||
414 | |||
415 | int ide_set_dma(ide_drive_t *drive) | 394 | int ide_set_dma(ide_drive_t *drive) |
416 | { | 395 | { |
417 | int rc; | 396 | int rc; |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1059f809b809..93b7886a2d6e 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -476,10 +476,14 @@ void do_ide_request(struct request_queue *q) | |||
476 | 476 | ||
477 | if (!ide_lock_port(hwif)) { | 477 | if (!ide_lock_port(hwif)) { |
478 | ide_hwif_t *prev_port; | 478 | ide_hwif_t *prev_port; |
479 | |||
480 | WARN_ON_ONCE(hwif->rq); | ||
481 | repeat: | 479 | repeat: |
482 | prev_port = hwif->host->cur_port; | 480 | prev_port = hwif->host->cur_port; |
481 | |||
482 | if (drive->dev_flags & IDE_DFLAG_BLOCKED) | ||
483 | rq = hwif->rq; | ||
484 | else | ||
485 | WARN_ON_ONCE(hwif->rq); | ||
486 | |||
483 | if (drive->dev_flags & IDE_DFLAG_SLEEPING && | 487 | if (drive->dev_flags & IDE_DFLAG_SLEEPING && |
484 | time_after(drive->sleep, jiffies)) { | 488 | time_after(drive->sleep, jiffies)) { |
485 | ide_unlock_port(hwif); | 489 | ide_unlock_port(hwif); |
@@ -506,43 +510,29 @@ repeat: | |||
506 | hwif->cur_dev = drive; | 510 | hwif->cur_dev = drive; |
507 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); | 511 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); |
508 | 512 | ||
509 | spin_unlock_irq(&hwif->lock); | 513 | if (rq == NULL) { |
510 | spin_lock_irq(q->queue_lock); | 514 | spin_unlock_irq(&hwif->lock); |
511 | /* | 515 | spin_lock_irq(q->queue_lock); |
512 | * we know that the queue isn't empty, but this can happen | 516 | /* |
513 | * if the q->prep_rq_fn() decides to kill a request | 517 | * we know that the queue isn't empty, but this can |
514 | */ | 518 | * happen if ->prep_rq_fn() decides to kill a request |
515 | if (!rq) | 519 | */ |
516 | rq = blk_fetch_request(drive->queue); | 520 | rq = blk_fetch_request(drive->queue); |
521 | spin_unlock_irq(q->queue_lock); | ||
522 | spin_lock_irq(&hwif->lock); | ||
517 | 523 | ||
518 | spin_unlock_irq(q->queue_lock); | 524 | if (rq == NULL) { |
519 | spin_lock_irq(&hwif->lock); | 525 | ide_unlock_port(hwif); |
520 | 526 | goto out; | |
521 | if (!rq) { | 527 | } |
522 | ide_unlock_port(hwif); | ||
523 | goto out; | ||
524 | } | 528 | } |
525 | 529 | ||
526 | /* | 530 | /* |
527 | * Sanity: don't accept a request that isn't a PM request | 531 | * Sanity: don't accept a request that isn't a PM request |
528 | * if we are currently power managed. This is very important as | 532 | * if we are currently power managed. |
529 | * blk_stop_queue() doesn't prevent the blk_fetch_request() | ||
530 | * above to return us whatever is in the queue. Since we call | ||
531 | * ide_do_request() ourselves, we end up taking requests while | ||
532 | * the queue is blocked... | ||
533 | * | ||
534 | * We let requests forced at head of queue with ide-preempt | ||
535 | * though. I hope that doesn't happen too much, hopefully not | ||
536 | * unless the subdriver triggers such a thing in its own PM | ||
537 | * state machine. | ||
538 | */ | 533 | */ |
539 | if ((drive->dev_flags & IDE_DFLAG_BLOCKED) && | 534 | BUG_ON((drive->dev_flags & IDE_DFLAG_BLOCKED) && |
540 | blk_pm_request(rq) == 0 && | 535 | blk_pm_request(rq) == 0); |
541 | (rq->cmd_flags & REQ_PREEMPT) == 0) { | ||
542 | /* there should be no pending command at this point */ | ||
543 | ide_unlock_port(hwif); | ||
544 | goto plug_device; | ||
545 | } | ||
546 | 536 | ||
547 | hwif->rq = rq; | 537 | hwif->rq = rq; |
548 | 538 | ||
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index fa047150a1c6..2892b242bbe1 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -210,6 +210,7 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list); | |||
210 | */ | 210 | */ |
211 | static const struct drive_list_entry ivb_list[] = { | 211 | static const struct drive_list_entry ivb_list[] = { |
212 | { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, | 212 | { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, |
213 | { "QUANTUM FIREBALLlct20 30" , "APL.0900" }, | ||
213 | { "TSSTcorp CDDVDW SH-S202J" , "SB00" }, | 214 | { "TSSTcorp CDDVDW SH-S202J" , "SB00" }, |
214 | { "TSSTcorp CDDVDW SH-S202J" , "SB01" }, | 215 | { "TSSTcorp CDDVDW SH-S202J" , "SB01" }, |
215 | { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, | 216 | { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, |
@@ -329,9 +330,6 @@ int ide_driveid_update(ide_drive_t *drive) | |||
329 | 330 | ||
330 | kfree(id); | 331 | kfree(id); |
331 | 332 | ||
332 | if ((drive->dev_flags & IDE_DFLAG_USING_DMA) && ide_id_dma_bug(drive)) | ||
333 | ide_dma_off(drive); | ||
334 | |||
335 | return 1; | 333 | return 1; |
336 | out_err: | 334 | out_err: |
337 | if (rc == 2) | 335 | if (rc == 2) |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 51af4eea0d36..1bb106f6221a 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -818,6 +818,24 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) | |||
818 | return j; | 818 | return j; |
819 | } | 819 | } |
820 | 820 | ||
821 | static void ide_host_enable_irqs(struct ide_host *host) | ||
822 | { | ||
823 | ide_hwif_t *hwif; | ||
824 | int i; | ||
825 | |||
826 | ide_host_for_each_port(i, hwif, host) { | ||
827 | if (hwif == NULL) | ||
828 | continue; | ||
829 | |||
830 | /* clear any pending IRQs */ | ||
831 | hwif->tp_ops->read_status(hwif); | ||
832 | |||
833 | /* unmask IRQs */ | ||
834 | if (hwif->io_ports.ctl_addr) | ||
835 | hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); | ||
836 | } | ||
837 | } | ||
838 | |||
821 | /* | 839 | /* |
822 | * This routine sets up the IRQ for an IDE interface. | 840 | * This routine sets up the IRQ for an IDE interface. |
823 | */ | 841 | */ |
@@ -831,9 +849,6 @@ static int init_irq (ide_hwif_t *hwif) | |||
831 | if (irq_handler == NULL) | 849 | if (irq_handler == NULL) |
832 | irq_handler = ide_intr; | 850 | irq_handler = ide_intr; |
833 | 851 | ||
834 | if (io_ports->ctl_addr) | ||
835 | hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS); | ||
836 | |||
837 | if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) | 852 | if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif)) |
838 | goto out_up; | 853 | goto out_up; |
839 | 854 | ||
@@ -1404,6 +1419,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
1404 | ide_port_tune_devices(hwif); | 1419 | ide_port_tune_devices(hwif); |
1405 | } | 1420 | } |
1406 | 1421 | ||
1422 | ide_host_enable_irqs(host); | ||
1423 | |||
1407 | ide_host_for_each_port(i, hwif, host) { | 1424 | ide_host_for_each_port(i, hwif, host) { |
1408 | if (hwif == NULL) | 1425 | if (hwif == NULL) |
1409 | continue; | 1426 | continue; |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 9b60b6b684d9..7c8e7122aaa9 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -75,6 +75,7 @@ config LEDS_ALIX2 | |||
75 | depends on LEDS_CLASS && X86 && EXPERIMENTAL | 75 | depends on LEDS_CLASS && X86 && EXPERIMENTAL |
76 | help | 76 | help |
77 | This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. | 77 | This option enables support for the PCEngines ALIX.2 and ALIX.3 LEDs. |
78 | You have to set leds-alix2.force=1 for boards with Award BIOS. | ||
78 | 79 | ||
79 | config LEDS_H1940 | 80 | config LEDS_H1940 |
80 | tristate "LED Support for iPAQ H1940 device" | 81 | tristate "LED Support for iPAQ H1940 device" |
@@ -145,15 +146,16 @@ config LEDS_GPIO_OF | |||
145 | of_platform devices. For instance, LEDs which are listed in a "dts" | 146 | of_platform devices. For instance, LEDs which are listed in a "dts" |
146 | file. | 147 | file. |
147 | 148 | ||
148 | config LEDS_LP5521 | 149 | config LEDS_LP3944 |
149 | tristate "LED Support for the LP5521 LEDs" | 150 | tristate "LED Support for N.S. LP3944 (Fun Light) I2C chip" |
150 | depends on LEDS_CLASS && I2C | 151 | depends on LEDS_CLASS && I2C |
151 | help | 152 | help |
152 | If you say 'Y' here you get support for the National Semiconductor | 153 | This option enables support for LEDs connected to the National |
153 | LP5521 LED driver used in n8x0 boards. | 154 | Semiconductor LP3944 Lighting Management Unit (LMU) also known as |
155 | Fun Light Chip. | ||
154 | 156 | ||
155 | This driver can be built as a module by choosing 'M'. The module | 157 | To compile this driver as a module, choose M here: the |
156 | will be called leds-lp5521. | 158 | module will be called leds-lp3944. |
157 | 159 | ||
158 | config LEDS_CLEVO_MAIL | 160 | config LEDS_CLEVO_MAIL |
159 | tristate "Mail LED on Clevo notebook" | 161 | tristate "Mail LED on Clevo notebook" |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 2d41c4dcf92f..e8cdcf77a4c3 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -20,6 +20,7 @@ obj-$(CONFIG_LEDS_COBALT_RAQ) += leds-cobalt-raq.o | |||
20 | obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o | 20 | obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o |
21 | obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o | 21 | obj-$(CONFIG_LEDS_PCA9532) += leds-pca9532.o |
22 | obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o | 22 | obj-$(CONFIG_LEDS_GPIO) += leds-gpio.o |
23 | obj-$(CONFIG_LEDS_LP3944) += leds-lp3944.o | ||
23 | obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o | 24 | obj-$(CONFIG_LEDS_CLEVO_MAIL) += leds-clevo-mail.o |
24 | obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o | 25 | obj-$(CONFIG_LEDS_HP6XX) += leds-hp6xx.o |
25 | obj-$(CONFIG_LEDS_FSG) += leds-fsg.o | 26 | obj-$(CONFIG_LEDS_FSG) += leds-fsg.o |
diff --git a/drivers/leds/leds-alix2.c b/drivers/leds/leds-alix2.c index ddbd7730dfc8..731d4eef3425 100644 --- a/drivers/leds/leds-alix2.c +++ b/drivers/leds/leds-alix2.c | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | static int force = 0; | 15 | static int force = 0; |
16 | module_param(force, bool, 0444); | 16 | module_param(force, bool, 0444); |
17 | MODULE_PARM_DESC(force, "Assume system has ALIX.2 style LEDs"); | 17 | MODULE_PARM_DESC(force, "Assume system has ALIX.2/ALIX.3 style LEDs"); |
18 | 18 | ||
19 | struct alix_led { | 19 | struct alix_led { |
20 | struct led_classdev cdev; | 20 | struct led_classdev cdev; |
@@ -155,6 +155,11 @@ static int __init alix_led_init(void) | |||
155 | goto out; | 155 | goto out; |
156 | } | 156 | } |
157 | 157 | ||
158 | /* enable output on GPIO for LED 1,2,3 */ | ||
159 | outl(1 << 6, 0x6104); | ||
160 | outl(1 << 9, 0x6184); | ||
161 | outl(1 << 11, 0x6184); | ||
162 | |||
158 | pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); | 163 | pdev = platform_device_register_simple(KBUILD_MODNAME, -1, NULL, 0); |
159 | if (!IS_ERR(pdev)) { | 164 | if (!IS_ERR(pdev)) { |
160 | ret = platform_driver_probe(&alix_led_driver, alix_led_probe); | 165 | ret = platform_driver_probe(&alix_led_driver, alix_led_probe); |
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c index 4149ecb3a9b2..779d7f262c04 100644 --- a/drivers/leds/leds-bd2802.c +++ b/drivers/leds/leds-bd2802.c | |||
@@ -97,6 +97,10 @@ struct bd2802_led { | |||
97 | enum led_ids led_id; | 97 | enum led_ids led_id; |
98 | enum led_colors color; | 98 | enum led_colors color; |
99 | enum led_bits state; | 99 | enum led_bits state; |
100 | |||
101 | /* General attributes of RGB LEDs */ | ||
102 | int wave_pattern; | ||
103 | int rgb_current; | ||
100 | }; | 104 | }; |
101 | 105 | ||
102 | 106 | ||
@@ -254,7 +258,7 @@ static void bd2802_set_on(struct bd2802_led *led, enum led_ids id, | |||
254 | bd2802_reset_cancel(led); | 258 | bd2802_reset_cancel(led); |
255 | 259 | ||
256 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); | 260 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); |
257 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_032); | 261 | bd2802_write_byte(led->client, reg, led->rgb_current); |
258 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); | 262 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); |
259 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); | 263 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); |
260 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); | 264 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); |
@@ -275,9 +279,9 @@ static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id, | |||
275 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); | 279 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); |
276 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); | 280 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); |
277 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); | 281 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); |
278 | bd2802_write_byte(led->client, reg, BD2802_CURRENT_032); | 282 | bd2802_write_byte(led->client, reg, led->rgb_current); |
279 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); | 283 | reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); |
280 | bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF); | 284 | bd2802_write_byte(led->client, reg, led->wave_pattern); |
281 | 285 | ||
282 | bd2802_enable(led, id); | 286 | bd2802_enable(led, id); |
283 | bd2802_update_state(led, id, color, BD2802_BLINK); | 287 | bd2802_update_state(led, id, color, BD2802_BLINK); |
@@ -406,7 +410,7 @@ static void bd2802_enable_adv_conf(struct bd2802_led *led) | |||
406 | ret = device_create_file(&led->client->dev, | 410 | ret = device_create_file(&led->client->dev, |
407 | bd2802_addr_attributes[i]); | 411 | bd2802_addr_attributes[i]); |
408 | if (ret) { | 412 | if (ret) { |
409 | dev_err(&led->client->dev, "failed to sysfs file %s\n", | 413 | dev_err(&led->client->dev, "failed: sysfs file %s\n", |
410 | bd2802_addr_attributes[i]->attr.name); | 414 | bd2802_addr_attributes[i]->attr.name); |
411 | goto failed_remove_files; | 415 | goto failed_remove_files; |
412 | } | 416 | } |
@@ -483,6 +487,52 @@ static struct device_attribute bd2802_adv_conf_attr = { | |||
483 | .store = bd2802_store_adv_conf, | 487 | .store = bd2802_store_adv_conf, |
484 | }; | 488 | }; |
485 | 489 | ||
490 | #define BD2802_CONTROL_ATTR(attr_name, name_str) \ | ||
491 | static ssize_t bd2802_show_##attr_name(struct device *dev, \ | ||
492 | struct device_attribute *attr, char *buf) \ | ||
493 | { \ | ||
494 | struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ | ||
495 | ssize_t ret; \ | ||
496 | down_read(&led->rwsem); \ | ||
497 | ret = sprintf(buf, "0x%02x\n", led->attr_name); \ | ||
498 | up_read(&led->rwsem); \ | ||
499 | return ret; \ | ||
500 | } \ | ||
501 | static ssize_t bd2802_store_##attr_name(struct device *dev, \ | ||
502 | struct device_attribute *attr, const char *buf, size_t count) \ | ||
503 | { \ | ||
504 | struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ | ||
505 | unsigned long val; \ | ||
506 | int ret; \ | ||
507 | if (!count) \ | ||
508 | return -EINVAL; \ | ||
509 | ret = strict_strtoul(buf, 16, &val); \ | ||
510 | if (ret) \ | ||
511 | return ret; \ | ||
512 | down_write(&led->rwsem); \ | ||
513 | led->attr_name = val; \ | ||
514 | up_write(&led->rwsem); \ | ||
515 | return count; \ | ||
516 | } \ | ||
517 | static struct device_attribute bd2802_##attr_name##_attr = { \ | ||
518 | .attr = { \ | ||
519 | .name = name_str, \ | ||
520 | .mode = 0644, \ | ||
521 | .owner = THIS_MODULE \ | ||
522 | }, \ | ||
523 | .show = bd2802_show_##attr_name, \ | ||
524 | .store = bd2802_store_##attr_name, \ | ||
525 | }; | ||
526 | |||
527 | BD2802_CONTROL_ATTR(wave_pattern, "wave_pattern"); | ||
528 | BD2802_CONTROL_ATTR(rgb_current, "rgb_current"); | ||
529 | |||
530 | static struct device_attribute *bd2802_attributes[] = { | ||
531 | &bd2802_adv_conf_attr, | ||
532 | &bd2802_wave_pattern_attr, | ||
533 | &bd2802_rgb_current_attr, | ||
534 | }; | ||
535 | |||
486 | static void bd2802_led_work(struct work_struct *work) | 536 | static void bd2802_led_work(struct work_struct *work) |
487 | { | 537 | { |
488 | struct bd2802_led *led = container_of(work, struct bd2802_led, work); | 538 | struct bd2802_led *led = container_of(work, struct bd2802_led, work); |
@@ -538,7 +588,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
538 | led->cdev_led1r.brightness = LED_OFF; | 588 | led->cdev_led1r.brightness = LED_OFF; |
539 | led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness; | 589 | led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness; |
540 | led->cdev_led1r.blink_set = bd2802_set_led1r_blink; | 590 | led->cdev_led1r.blink_set = bd2802_set_led1r_blink; |
541 | led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME; | ||
542 | 591 | ||
543 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1r); | 592 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1r); |
544 | if (ret < 0) { | 593 | if (ret < 0) { |
@@ -551,7 +600,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
551 | led->cdev_led1g.brightness = LED_OFF; | 600 | led->cdev_led1g.brightness = LED_OFF; |
552 | led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness; | 601 | led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness; |
553 | led->cdev_led1g.blink_set = bd2802_set_led1g_blink; | 602 | led->cdev_led1g.blink_set = bd2802_set_led1g_blink; |
554 | led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME; | ||
555 | 603 | ||
556 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1g); | 604 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1g); |
557 | if (ret < 0) { | 605 | if (ret < 0) { |
@@ -564,7 +612,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
564 | led->cdev_led1b.brightness = LED_OFF; | 612 | led->cdev_led1b.brightness = LED_OFF; |
565 | led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness; | 613 | led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness; |
566 | led->cdev_led1b.blink_set = bd2802_set_led1b_blink; | 614 | led->cdev_led1b.blink_set = bd2802_set_led1b_blink; |
567 | led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME; | ||
568 | 615 | ||
569 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1b); | 616 | ret = led_classdev_register(&led->client->dev, &led->cdev_led1b); |
570 | if (ret < 0) { | 617 | if (ret < 0) { |
@@ -577,7 +624,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
577 | led->cdev_led2r.brightness = LED_OFF; | 624 | led->cdev_led2r.brightness = LED_OFF; |
578 | led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness; | 625 | led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness; |
579 | led->cdev_led2r.blink_set = bd2802_set_led2r_blink; | 626 | led->cdev_led2r.blink_set = bd2802_set_led2r_blink; |
580 | led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME; | ||
581 | 627 | ||
582 | ret = led_classdev_register(&led->client->dev, &led->cdev_led2r); | 628 | ret = led_classdev_register(&led->client->dev, &led->cdev_led2r); |
583 | if (ret < 0) { | 629 | if (ret < 0) { |
@@ -590,7 +636,6 @@ static int bd2802_register_led_classdev(struct bd2802_led *led) | |||
590 | led->cdev_led2g.brightness = LED_OFF; | 636 | led->cdev_led2g.brightness = LED_OFF; |
591 | led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness; | 637 | led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness; |
592 | led->cdev_led2g.blink_set = bd2802_set_led2g_blink; | 638 | led->cdev_led2g.blink_set = bd2802_set_led2g_blink; |
593 | led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME; | ||
594 | 639 | ||
595 | ret = led_classdev_register(&led->client->dev, &led->cdev_led2g); | 640 | ret = led_classdev_register(&led->client->dev, &led->cdev_led2g); |
596 | if (ret < 0) { | 641 | if (ret < 0) { |
@@ -640,7 +685,7 @@ static int __devinit bd2802_probe(struct i2c_client *client, | |||
640 | { | 685 | { |
641 | struct bd2802_led *led; | 686 | struct bd2802_led *led; |
642 | struct bd2802_led_platform_data *pdata; | 687 | struct bd2802_led_platform_data *pdata; |
643 | int ret; | 688 | int ret, i; |
644 | 689 | ||
645 | led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL); | 690 | led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL); |
646 | if (!led) { | 691 | if (!led) { |
@@ -670,13 +715,20 @@ static int __devinit bd2802_probe(struct i2c_client *client, | |||
670 | /* To save the power, reset BD2802 after detecting */ | 715 | /* To save the power, reset BD2802 after detecting */ |
671 | gpio_set_value(led->pdata->reset_gpio, 0); | 716 | gpio_set_value(led->pdata->reset_gpio, 0); |
672 | 717 | ||
718 | /* Default attributes */ | ||
719 | led->wave_pattern = BD2802_PATTERN_HALF; | ||
720 | led->rgb_current = BD2802_CURRENT_032; | ||
721 | |||
673 | init_rwsem(&led->rwsem); | 722 | init_rwsem(&led->rwsem); |
674 | 723 | ||
675 | ret = device_create_file(&client->dev, &bd2802_adv_conf_attr); | 724 | for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) { |
676 | if (ret) { | 725 | ret = device_create_file(&led->client->dev, |
677 | dev_err(&client->dev, "failed to create sysfs file %s\n", | 726 | bd2802_attributes[i]); |
678 | bd2802_adv_conf_attr.attr.name); | 727 | if (ret) { |
679 | goto failed_free; | 728 | dev_err(&led->client->dev, "failed: sysfs file %s\n", |
729 | bd2802_attributes[i]->attr.name); | ||
730 | goto failed_unregister_dev_file; | ||
731 | } | ||
680 | } | 732 | } |
681 | 733 | ||
682 | ret = bd2802_register_led_classdev(led); | 734 | ret = bd2802_register_led_classdev(led); |
@@ -686,7 +738,8 @@ static int __devinit bd2802_probe(struct i2c_client *client, | |||
686 | return 0; | 738 | return 0; |
687 | 739 | ||
688 | failed_unregister_dev_file: | 740 | failed_unregister_dev_file: |
689 | device_remove_file(&client->dev, &bd2802_adv_conf_attr); | 741 | for (i--; i >= 0; i--) |
742 | device_remove_file(&led->client->dev, bd2802_attributes[i]); | ||
690 | failed_free: | 743 | failed_free: |
691 | i2c_set_clientdata(client, NULL); | 744 | i2c_set_clientdata(client, NULL); |
692 | kfree(led); | 745 | kfree(led); |
@@ -697,12 +750,14 @@ failed_free: | |||
697 | static int __exit bd2802_remove(struct i2c_client *client) | 750 | static int __exit bd2802_remove(struct i2c_client *client) |
698 | { | 751 | { |
699 | struct bd2802_led *led = i2c_get_clientdata(client); | 752 | struct bd2802_led *led = i2c_get_clientdata(client); |
753 | int i; | ||
700 | 754 | ||
701 | bd2802_unregister_led_classdev(led); | ||
702 | gpio_set_value(led->pdata->reset_gpio, 0); | 755 | gpio_set_value(led->pdata->reset_gpio, 0); |
756 | bd2802_unregister_led_classdev(led); | ||
703 | if (led->adf_on) | 757 | if (led->adf_on) |
704 | bd2802_disable_adv_conf(led); | 758 | bd2802_disable_adv_conf(led); |
705 | device_remove_file(&client->dev, &bd2802_adv_conf_attr); | 759 | for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) |
760 | device_remove_file(&led->client->dev, bd2802_attributes[i]); | ||
706 | i2c_set_clientdata(client, NULL); | 761 | i2c_set_clientdata(client, NULL); |
707 | kfree(led); | 762 | kfree(led); |
708 | 763 | ||
@@ -723,8 +778,7 @@ static int bd2802_resume(struct i2c_client *client) | |||
723 | struct bd2802_led *led = i2c_get_clientdata(client); | 778 | struct bd2802_led *led = i2c_get_clientdata(client); |
724 | 779 | ||
725 | if (!bd2802_is_all_off(led) || led->adf_on) { | 780 | if (!bd2802_is_all_off(led) || led->adf_on) { |
726 | gpio_set_value(led->pdata->reset_gpio, 1); | 781 | bd2802_reset_cancel(led); |
727 | udelay(100); | ||
728 | bd2802_restore_state(led); | 782 | bd2802_restore_state(led); |
729 | } | 783 | } |
730 | 784 | ||
@@ -762,4 +816,4 @@ module_exit(bd2802_exit); | |||
762 | 816 | ||
763 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); | 817 | MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); |
764 | MODULE_DESCRIPTION("BD2802 LED driver"); | 818 | MODULE_DESCRIPTION("BD2802 LED driver"); |
765 | MODULE_LICENSE("GPL"); | 819 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index d2109054de85..6b06638eb5b4 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -76,7 +76,7 @@ static int __devinit create_gpio_led(const struct gpio_led *template, | |||
76 | struct gpio_led_data *led_dat, struct device *parent, | 76 | struct gpio_led_data *led_dat, struct device *parent, |
77 | int (*blink_set)(unsigned, unsigned long *, unsigned long *)) | 77 | int (*blink_set)(unsigned, unsigned long *, unsigned long *)) |
78 | { | 78 | { |
79 | int ret; | 79 | int ret, state; |
80 | 80 | ||
81 | /* skip leds that aren't available */ | 81 | /* skip leds that aren't available */ |
82 | if (!gpio_is_valid(template->gpio)) { | 82 | if (!gpio_is_valid(template->gpio)) { |
@@ -99,11 +99,15 @@ static int __devinit create_gpio_led(const struct gpio_led *template, | |||
99 | led_dat->cdev.blink_set = gpio_blink_set; | 99 | led_dat->cdev.blink_set = gpio_blink_set; |
100 | } | 100 | } |
101 | led_dat->cdev.brightness_set = gpio_led_set; | 101 | led_dat->cdev.brightness_set = gpio_led_set; |
102 | led_dat->cdev.brightness = LED_OFF; | 102 | if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) |
103 | state = !!gpio_get_value(led_dat->gpio) ^ led_dat->active_low; | ||
104 | else | ||
105 | state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); | ||
106 | led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; | ||
103 | if (!template->retain_state_suspended) | 107 | if (!template->retain_state_suspended) |
104 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; | 108 | led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; |
105 | 109 | ||
106 | ret = gpio_direction_output(led_dat->gpio, led_dat->active_low); | 110 | ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); |
107 | if (ret < 0) | 111 | if (ret < 0) |
108 | goto err; | 112 | goto err; |
109 | 113 | ||
@@ -129,7 +133,7 @@ static void delete_gpio_led(struct gpio_led_data *led) | |||
129 | } | 133 | } |
130 | 134 | ||
131 | #ifdef CONFIG_LEDS_GPIO_PLATFORM | 135 | #ifdef CONFIG_LEDS_GPIO_PLATFORM |
132 | static int gpio_led_probe(struct platform_device *pdev) | 136 | static int __devinit gpio_led_probe(struct platform_device *pdev) |
133 | { | 137 | { |
134 | struct gpio_led_platform_data *pdata = pdev->dev.platform_data; | 138 | struct gpio_led_platform_data *pdata = pdev->dev.platform_data; |
135 | struct gpio_led_data *leds_data; | 139 | struct gpio_led_data *leds_data; |
@@ -223,12 +227,22 @@ static int __devinit of_gpio_leds_probe(struct of_device *ofdev, | |||
223 | memset(&led, 0, sizeof(led)); | 227 | memset(&led, 0, sizeof(led)); |
224 | for_each_child_of_node(np, child) { | 228 | for_each_child_of_node(np, child) { |
225 | enum of_gpio_flags flags; | 229 | enum of_gpio_flags flags; |
230 | const char *state; | ||
226 | 231 | ||
227 | led.gpio = of_get_gpio_flags(child, 0, &flags); | 232 | led.gpio = of_get_gpio_flags(child, 0, &flags); |
228 | led.active_low = flags & OF_GPIO_ACTIVE_LOW; | 233 | led.active_low = flags & OF_GPIO_ACTIVE_LOW; |
229 | led.name = of_get_property(child, "label", NULL) ? : child->name; | 234 | led.name = of_get_property(child, "label", NULL) ? : child->name; |
230 | led.default_trigger = | 235 | led.default_trigger = |
231 | of_get_property(child, "linux,default-trigger", NULL); | 236 | of_get_property(child, "linux,default-trigger", NULL); |
237 | state = of_get_property(child, "default-state", NULL); | ||
238 | if (state) { | ||
239 | if (!strcmp(state, "keep")) | ||
240 | led.default_state = LEDS_GPIO_DEFSTATE_KEEP; | ||
241 | else if(!strcmp(state, "on")) | ||
242 | led.default_state = LEDS_GPIO_DEFSTATE_ON; | ||
243 | else | ||
244 | led.default_state = LEDS_GPIO_DEFSTATE_OFF; | ||
245 | } | ||
232 | 246 | ||
233 | ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++], | 247 | ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++], |
234 | &ofdev->dev, NULL); | 248 | &ofdev->dev, NULL); |
diff --git a/drivers/leds/leds-lp3944.c b/drivers/leds/leds-lp3944.c new file mode 100644 index 000000000000..5946208ba26e --- /dev/null +++ b/drivers/leds/leds-lp3944.c | |||
@@ -0,0 +1,466 @@ | |||
1 | /* | ||
2 | * leds-lp3944.c - driver for National Semiconductor LP3944 Funlight Chip | ||
3 | * | ||
4 | * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * I2C driver for National Semiconductor LP3944 Funlight Chip | ||
14 | * http://www.national.com/pf/LP/LP3944.html | ||
15 | * | ||
16 | * This helper chip can drive up to 8 leds, with two programmable DIM modes; | ||
17 | * it could even be used as a gpio expander but this driver assumes it is used | ||
18 | * as a led controller. | ||
19 | * | ||
20 | * The DIM modes are used to set _blink_ patterns for leds, the pattern is | ||
21 | * specified supplying two parameters: | ||
22 | * - period: from 0s to 1.6s | ||
23 | * - duty cycle: percentage of the period the led is on, from 0 to 100 | ||
24 | * | ||
25 | * LP3944 can be found on Motorola A910 smartphone, where it drives the rgb | ||
26 | * leds, the camera flash light and the displays backlights. | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/i2c.h> | ||
31 | #include <linux/leds.h> | ||
32 | #include <linux/mutex.h> | ||
33 | #include <linux/workqueue.h> | ||
34 | #include <linux/leds-lp3944.h> | ||
35 | |||
36 | /* Read Only Registers */ | ||
37 | #define LP3944_REG_INPUT1 0x00 /* LEDs 0-7 InputRegister (Read Only) */ | ||
38 | #define LP3944_REG_REGISTER1 0x01 /* None (Read Only) */ | ||
39 | |||
40 | #define LP3944_REG_PSC0 0x02 /* Frequency Prescaler 0 (R/W) */ | ||
41 | #define LP3944_REG_PWM0 0x03 /* PWM Register 0 (R/W) */ | ||
42 | #define LP3944_REG_PSC1 0x04 /* Frequency Prescaler 1 (R/W) */ | ||
43 | #define LP3944_REG_PWM1 0x05 /* PWM Register 1 (R/W) */ | ||
44 | #define LP3944_REG_LS0 0x06 /* LEDs 0-3 Selector (R/W) */ | ||
45 | #define LP3944_REG_LS1 0x07 /* LEDs 4-7 Selector (R/W) */ | ||
46 | |||
47 | /* These registers are not used to control leds in LP3944, they can store | ||
48 | * arbitrary values which the chip will ignore. | ||
49 | */ | ||
50 | #define LP3944_REG_REGISTER8 0x08 | ||
51 | #define LP3944_REG_REGISTER9 0x09 | ||
52 | |||
53 | #define LP3944_DIM0 0 | ||
54 | #define LP3944_DIM1 1 | ||
55 | |||
56 | /* period in ms */ | ||
57 | #define LP3944_PERIOD_MIN 0 | ||
58 | #define LP3944_PERIOD_MAX 1600 | ||
59 | |||
60 | /* duty cycle is a percentage */ | ||
61 | #define LP3944_DUTY_CYCLE_MIN 0 | ||
62 | #define LP3944_DUTY_CYCLE_MAX 100 | ||
63 | |||
64 | #define ldev_to_led(c) container_of(c, struct lp3944_led_data, ldev) | ||
65 | |||
66 | /* Saved data */ | ||
67 | struct lp3944_led_data { | ||
68 | u8 id; | ||
69 | enum lp3944_type type; | ||
70 | enum lp3944_status status; | ||
71 | struct led_classdev ldev; | ||
72 | struct i2c_client *client; | ||
73 | struct work_struct work; | ||
74 | }; | ||
75 | |||
76 | struct lp3944_data { | ||
77 | struct mutex lock; | ||
78 | struct i2c_client *client; | ||
79 | struct lp3944_led_data leds[LP3944_LEDS_MAX]; | ||
80 | }; | ||
81 | |||
82 | static int lp3944_reg_read(struct i2c_client *client, u8 reg, u8 *value) | ||
83 | { | ||
84 | int tmp; | ||
85 | |||
86 | tmp = i2c_smbus_read_byte_data(client, reg); | ||
87 | if (tmp < 0) | ||
88 | return -EINVAL; | ||
89 | |||
90 | *value = tmp; | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | static int lp3944_reg_write(struct i2c_client *client, u8 reg, u8 value) | ||
96 | { | ||
97 | return i2c_smbus_write_byte_data(client, reg, value); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * Set the period for DIM status | ||
102 | * | ||
103 | * @client: the i2c client | ||
104 | * @dim: either LP3944_DIM0 or LP3944_DIM1 | ||
105 | * @period: period of a blink, that is a on/off cycle, expressed in ms. | ||
106 | */ | ||
107 | static int lp3944_dim_set_period(struct i2c_client *client, u8 dim, u16 period) | ||
108 | { | ||
109 | u8 psc_reg; | ||
110 | u8 psc_value; | ||
111 | int err; | ||
112 | |||
113 | if (dim == LP3944_DIM0) | ||
114 | psc_reg = LP3944_REG_PSC0; | ||
115 | else if (dim == LP3944_DIM1) | ||
116 | psc_reg = LP3944_REG_PSC1; | ||
117 | else | ||
118 | return -EINVAL; | ||
119 | |||
120 | /* Convert period to Prescaler value */ | ||
121 | if (period > LP3944_PERIOD_MAX) | ||
122 | return -EINVAL; | ||
123 | |||
124 | psc_value = (period * 255) / LP3944_PERIOD_MAX; | ||
125 | |||
126 | err = lp3944_reg_write(client, psc_reg, psc_value); | ||
127 | |||
128 | return err; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * Set the duty cycle for DIM status | ||
133 | * | ||
134 | * @client: the i2c client | ||
135 | * @dim: either LP3944_DIM0 or LP3944_DIM1 | ||
136 | * @duty_cycle: percentage of a period during which a led is ON | ||
137 | */ | ||
138 | static int lp3944_dim_set_dutycycle(struct i2c_client *client, u8 dim, | ||
139 | u8 duty_cycle) | ||
140 | { | ||
141 | u8 pwm_reg; | ||
142 | u8 pwm_value; | ||
143 | int err; | ||
144 | |||
145 | if (dim == LP3944_DIM0) | ||
146 | pwm_reg = LP3944_REG_PWM0; | ||
147 | else if (dim == LP3944_DIM1) | ||
148 | pwm_reg = LP3944_REG_PWM1; | ||
149 | else | ||
150 | return -EINVAL; | ||
151 | |||
152 | /* Convert duty cycle to PWM value */ | ||
153 | if (duty_cycle > LP3944_DUTY_CYCLE_MAX) | ||
154 | return -EINVAL; | ||
155 | |||
156 | pwm_value = (duty_cycle * 255) / LP3944_DUTY_CYCLE_MAX; | ||
157 | |||
158 | err = lp3944_reg_write(client, pwm_reg, pwm_value); | ||
159 | |||
160 | return err; | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Set the led status | ||
165 | * | ||
166 | * @led: a lp3944_led_data structure | ||
167 | * @status: one of LP3944_LED_STATUS_OFF | ||
168 | * LP3944_LED_STATUS_ON | ||
169 | * LP3944_LED_STATUS_DIM0 | ||
170 | * LP3944_LED_STATUS_DIM1 | ||
171 | */ | ||
172 | static int lp3944_led_set(struct lp3944_led_data *led, u8 status) | ||
173 | { | ||
174 | struct lp3944_data *data = i2c_get_clientdata(led->client); | ||
175 | u8 id = led->id; | ||
176 | u8 reg; | ||
177 | u8 val = 0; | ||
178 | int err; | ||
179 | |||
180 | dev_dbg(&led->client->dev, "%s: %s, status before normalization:%d\n", | ||
181 | __func__, led->ldev.name, status); | ||
182 | |||
183 | switch (id) { | ||
184 | case LP3944_LED0: | ||
185 | case LP3944_LED1: | ||
186 | case LP3944_LED2: | ||
187 | case LP3944_LED3: | ||
188 | reg = LP3944_REG_LS0; | ||
189 | break; | ||
190 | case LP3944_LED4: | ||
191 | case LP3944_LED5: | ||
192 | case LP3944_LED6: | ||
193 | case LP3944_LED7: | ||
194 | id -= LP3944_LED4; | ||
195 | reg = LP3944_REG_LS1; | ||
196 | break; | ||
197 | default: | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | if (status > LP3944_LED_STATUS_DIM1) | ||
202 | return -EINVAL; | ||
203 | |||
204 | /* invert only 0 and 1, leave unchanged the other values, | ||
205 | * remember we are abusing status to set blink patterns | ||
206 | */ | ||
207 | if (led->type == LP3944_LED_TYPE_LED_INVERTED && status < 2) | ||
208 | status = 1 - status; | ||
209 | |||
210 | mutex_lock(&data->lock); | ||
211 | lp3944_reg_read(led->client, reg, &val); | ||
212 | |||
213 | val &= ~(LP3944_LED_STATUS_MASK << (id << 1)); | ||
214 | val |= (status << (id << 1)); | ||
215 | |||
216 | dev_dbg(&led->client->dev, "%s: %s, reg:%d id:%d status:%d val:%#x\n", | ||
217 | __func__, led->ldev.name, reg, id, status, val); | ||
218 | |||
219 | /* set led status */ | ||
220 | err = lp3944_reg_write(led->client, reg, val); | ||
221 | mutex_unlock(&data->lock); | ||
222 | |||
223 | return err; | ||
224 | } | ||
225 | |||
226 | static int lp3944_led_set_blink(struct led_classdev *led_cdev, | ||
227 | unsigned long *delay_on, | ||
228 | unsigned long *delay_off) | ||
229 | { | ||
230 | struct lp3944_led_data *led = ldev_to_led(led_cdev); | ||
231 | u16 period; | ||
232 | u8 duty_cycle; | ||
233 | int err; | ||
234 | |||
235 | /* units are in ms */ | ||
236 | if (*delay_on + *delay_off > LP3944_PERIOD_MAX) | ||
237 | return -EINVAL; | ||
238 | |||
239 | if (*delay_on == 0 && *delay_off == 0) { | ||
240 | /* Special case: the leds subsystem requires a default user | ||
241 | * friendly blink pattern for the LED. Let's blink the led | ||
242 | * slowly (1Hz). | ||
243 | */ | ||
244 | *delay_on = 500; | ||
245 | *delay_off = 500; | ||
246 | } | ||
247 | |||
248 | period = (*delay_on) + (*delay_off); | ||
249 | |||
250 | /* duty_cycle is the percentage of period during which the led is ON */ | ||
251 | duty_cycle = 100 * (*delay_on) / period; | ||
252 | |||
253 | /* invert duty cycle for inverted leds, this has the same effect of | ||
254 | * swapping delay_on and delay_off | ||
255 | */ | ||
256 | if (led->type == LP3944_LED_TYPE_LED_INVERTED) | ||
257 | duty_cycle = 100 - duty_cycle; | ||
258 | |||
259 | /* NOTE: using always the first DIM mode, this means that all leds | ||
260 | * will have the same blinking pattern. | ||
261 | * | ||
262 | * We could find a way later to have two leds blinking in hardware | ||
263 | * with different patterns at the same time, falling back to software | ||
264 | * control for the other ones. | ||
265 | */ | ||
266 | err = lp3944_dim_set_period(led->client, LP3944_DIM0, period); | ||
267 | if (err) | ||
268 | return err; | ||
269 | |||
270 | err = lp3944_dim_set_dutycycle(led->client, LP3944_DIM0, duty_cycle); | ||
271 | if (err) | ||
272 | return err; | ||
273 | |||
274 | dev_dbg(&led->client->dev, "%s: OK hardware accelerated blink!\n", | ||
275 | __func__); | ||
276 | |||
277 | led->status = LP3944_LED_STATUS_DIM0; | ||
278 | schedule_work(&led->work); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static void lp3944_led_set_brightness(struct led_classdev *led_cdev, | ||
284 | enum led_brightness brightness) | ||
285 | { | ||
286 | struct lp3944_led_data *led = ldev_to_led(led_cdev); | ||
287 | |||
288 | dev_dbg(&led->client->dev, "%s: %s, %d\n", | ||
289 | __func__, led_cdev->name, brightness); | ||
290 | |||
291 | led->status = brightness; | ||
292 | schedule_work(&led->work); | ||
293 | } | ||
294 | |||
295 | static void lp3944_led_work(struct work_struct *work) | ||
296 | { | ||
297 | struct lp3944_led_data *led; | ||
298 | |||
299 | led = container_of(work, struct lp3944_led_data, work); | ||
300 | lp3944_led_set(led, led->status); | ||
301 | } | ||
302 | |||
303 | static int lp3944_configure(struct i2c_client *client, | ||
304 | struct lp3944_data *data, | ||
305 | struct lp3944_platform_data *pdata) | ||
306 | { | ||
307 | int i, err = 0; | ||
308 | |||
309 | for (i = 0; i < pdata->leds_size; i++) { | ||
310 | struct lp3944_led *pled = &pdata->leds[i]; | ||
311 | struct lp3944_led_data *led = &data->leds[i]; | ||
312 | led->client = client; | ||
313 | led->id = i; | ||
314 | |||
315 | switch (pled->type) { | ||
316 | |||
317 | case LP3944_LED_TYPE_LED: | ||
318 | case LP3944_LED_TYPE_LED_INVERTED: | ||
319 | led->type = pled->type; | ||
320 | led->status = pled->status; | ||
321 | led->ldev.name = pled->name; | ||
322 | led->ldev.max_brightness = 1; | ||
323 | led->ldev.brightness_set = lp3944_led_set_brightness; | ||
324 | led->ldev.blink_set = lp3944_led_set_blink; | ||
325 | led->ldev.flags = LED_CORE_SUSPENDRESUME; | ||
326 | |||
327 | INIT_WORK(&led->work, lp3944_led_work); | ||
328 | err = led_classdev_register(&client->dev, &led->ldev); | ||
329 | if (err < 0) { | ||
330 | dev_err(&client->dev, | ||
331 | "couldn't register LED %s\n", | ||
332 | led->ldev.name); | ||
333 | goto exit; | ||
334 | } | ||
335 | |||
336 | /* to expose the default value to userspace */ | ||
337 | led->ldev.brightness = led->status; | ||
338 | |||
339 | /* Set the default led status */ | ||
340 | err = lp3944_led_set(led, led->status); | ||
341 | if (err < 0) { | ||
342 | dev_err(&client->dev, | ||
343 | "%s couldn't set STATUS %d\n", | ||
344 | led->ldev.name, led->status); | ||
345 | goto exit; | ||
346 | } | ||
347 | break; | ||
348 | |||
349 | case LP3944_LED_TYPE_NONE: | ||
350 | default: | ||
351 | break; | ||
352 | |||
353 | } | ||
354 | } | ||
355 | return 0; | ||
356 | |||
357 | exit: | ||
358 | if (i > 0) | ||
359 | for (i = i - 1; i >= 0; i--) | ||
360 | switch (pdata->leds[i].type) { | ||
361 | |||
362 | case LP3944_LED_TYPE_LED: | ||
363 | case LP3944_LED_TYPE_LED_INVERTED: | ||
364 | led_classdev_unregister(&data->leds[i].ldev); | ||
365 | cancel_work_sync(&data->leds[i].work); | ||
366 | break; | ||
367 | |||
368 | case LP3944_LED_TYPE_NONE: | ||
369 | default: | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | return err; | ||
374 | } | ||
375 | |||
376 | static int __devinit lp3944_probe(struct i2c_client *client, | ||
377 | const struct i2c_device_id *id) | ||
378 | { | ||
379 | struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; | ||
380 | struct lp3944_data *data; | ||
381 | |||
382 | if (lp3944_pdata == NULL) { | ||
383 | dev_err(&client->dev, "no platform data\n"); | ||
384 | return -EINVAL; | ||
385 | } | ||
386 | |||
387 | /* Let's see whether this adapter can support what we need. */ | ||
388 | if (!i2c_check_functionality(client->adapter, | ||
389 | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
390 | dev_err(&client->dev, "insufficient functionality!\n"); | ||
391 | return -ENODEV; | ||
392 | } | ||
393 | |||
394 | data = kzalloc(sizeof(struct lp3944_data), GFP_KERNEL); | ||
395 | if (!data) | ||
396 | return -ENOMEM; | ||
397 | |||
398 | data->client = client; | ||
399 | i2c_set_clientdata(client, data); | ||
400 | |||
401 | mutex_init(&data->lock); | ||
402 | |||
403 | dev_info(&client->dev, "lp3944 enabled\n"); | ||
404 | |||
405 | lp3944_configure(client, data, lp3944_pdata); | ||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static int __devexit lp3944_remove(struct i2c_client *client) | ||
410 | { | ||
411 | struct lp3944_platform_data *pdata = client->dev.platform_data; | ||
412 | struct lp3944_data *data = i2c_get_clientdata(client); | ||
413 | int i; | ||
414 | |||
415 | for (i = 0; i < pdata->leds_size; i++) | ||
416 | switch (data->leds[i].type) { | ||
417 | case LP3944_LED_TYPE_LED: | ||
418 | case LP3944_LED_TYPE_LED_INVERTED: | ||
419 | led_classdev_unregister(&data->leds[i].ldev); | ||
420 | cancel_work_sync(&data->leds[i].work); | ||
421 | break; | ||
422 | |||
423 | case LP3944_LED_TYPE_NONE: | ||
424 | default: | ||
425 | break; | ||
426 | } | ||
427 | |||
428 | kfree(data); | ||
429 | i2c_set_clientdata(client, NULL); | ||
430 | |||
431 | return 0; | ||
432 | } | ||
433 | |||
434 | /* lp3944 i2c driver struct */ | ||
435 | static const struct i2c_device_id lp3944_id[] = { | ||
436 | {"lp3944", 0}, | ||
437 | {} | ||
438 | }; | ||
439 | |||
440 | MODULE_DEVICE_TABLE(i2c, lp3944_id); | ||
441 | |||
442 | static struct i2c_driver lp3944_driver = { | ||
443 | .driver = { | ||
444 | .name = "lp3944", | ||
445 | }, | ||
446 | .probe = lp3944_probe, | ||
447 | .remove = __devexit_p(lp3944_remove), | ||
448 | .id_table = lp3944_id, | ||
449 | }; | ||
450 | |||
451 | static int __init lp3944_module_init(void) | ||
452 | { | ||
453 | return i2c_add_driver(&lp3944_driver); | ||
454 | } | ||
455 | |||
456 | static void __exit lp3944_module_exit(void) | ||
457 | { | ||
458 | i2c_del_driver(&lp3944_driver); | ||
459 | } | ||
460 | |||
461 | module_init(lp3944_module_init); | ||
462 | module_exit(lp3944_module_exit); | ||
463 | |||
464 | MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); | ||
465 | MODULE_DESCRIPTION("LP3944 Fun Light Chip"); | ||
466 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index 3937244fdcab..dba8921240f2 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c | |||
@@ -35,7 +35,7 @@ struct pca9532_data { | |||
35 | struct pca9532_led leds[16]; | 35 | struct pca9532_led leds[16]; |
36 | struct mutex update_lock; | 36 | struct mutex update_lock; |
37 | struct input_dev *idev; | 37 | struct input_dev *idev; |
38 | struct work_struct work; | 38 | struct work_struct work; |
39 | u8 pwm[2]; | 39 | u8 pwm[2]; |
40 | u8 psc[2]; | 40 | u8 psc[2]; |
41 | }; | 41 | }; |
@@ -87,14 +87,14 @@ static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink, | |||
87 | if (b > 0xFF) | 87 | if (b > 0xFF) |
88 | return -EINVAL; | 88 | return -EINVAL; |
89 | data->pwm[pwm] = b; | 89 | data->pwm[pwm] = b; |
90 | data->psc[pwm] = blink; | 90 | data->psc[pwm] = blink; |
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | 93 | ||
94 | static int pca9532_setpwm(struct i2c_client *client, int pwm) | 94 | static int pca9532_setpwm(struct i2c_client *client, int pwm) |
95 | { | 95 | { |
96 | struct pca9532_data *data = i2c_get_clientdata(client); | 96 | struct pca9532_data *data = i2c_get_clientdata(client); |
97 | mutex_lock(&data->update_lock); | 97 | mutex_lock(&data->update_lock); |
98 | i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm), | 98 | i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm), |
99 | data->pwm[pwm]); | 99 | data->pwm[pwm]); |
100 | i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm), | 100 | i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm), |
@@ -132,11 +132,11 @@ static void pca9532_set_brightness(struct led_classdev *led_cdev, | |||
132 | led->state = PCA9532_ON; | 132 | led->state = PCA9532_ON; |
133 | else { | 133 | else { |
134 | led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ | 134 | led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ |
135 | err = pca9532_calcpwm(led->client, 0, 0, value); | 135 | err = pca9532_calcpwm(led->client, 0, 0, value); |
136 | if (err) | 136 | if (err) |
137 | return; /* XXX: led api doesn't allow error code? */ | 137 | return; /* XXX: led api doesn't allow error code? */ |
138 | } | 138 | } |
139 | schedule_work(&led->work); | 139 | schedule_work(&led->work); |
140 | } | 140 | } |
141 | 141 | ||
142 | static int pca9532_set_blink(struct led_classdev *led_cdev, | 142 | static int pca9532_set_blink(struct led_classdev *led_cdev, |
@@ -145,7 +145,7 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, | |||
145 | struct pca9532_led *led = ldev_to_led(led_cdev); | 145 | struct pca9532_led *led = ldev_to_led(led_cdev); |
146 | struct i2c_client *client = led->client; | 146 | struct i2c_client *client = led->client; |
147 | int psc; | 147 | int psc; |
148 | int err = 0; | 148 | int err = 0; |
149 | 149 | ||
150 | if (*delay_on == 0 && *delay_off == 0) { | 150 | if (*delay_on == 0 && *delay_off == 0) { |
151 | /* led subsystem ask us for a blink rate */ | 151 | /* led subsystem ask us for a blink rate */ |
@@ -157,11 +157,11 @@ static int pca9532_set_blink(struct led_classdev *led_cdev, | |||
157 | 157 | ||
158 | /* Thecus specific: only use PSC/PWM 0 */ | 158 | /* Thecus specific: only use PSC/PWM 0 */ |
159 | psc = (*delay_on * 152-1)/1000; | 159 | psc = (*delay_on * 152-1)/1000; |
160 | err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); | 160 | err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); |
161 | if (err) | 161 | if (err) |
162 | return err; | 162 | return err; |
163 | schedule_work(&led->work); | 163 | schedule_work(&led->work); |
164 | return 0; | 164 | return 0; |
165 | } | 165 | } |
166 | 166 | ||
167 | static int pca9532_event(struct input_dev *dev, unsigned int type, | 167 | static int pca9532_event(struct input_dev *dev, unsigned int type, |
@@ -178,15 +178,15 @@ static int pca9532_event(struct input_dev *dev, unsigned int type, | |||
178 | else | 178 | else |
179 | data->pwm[1] = 0; | 179 | data->pwm[1] = 0; |
180 | 180 | ||
181 | schedule_work(&data->work); | 181 | schedule_work(&data->work); |
182 | 182 | ||
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | static void pca9532_input_work(struct work_struct *work) | 186 | static void pca9532_input_work(struct work_struct *work) |
187 | { | 187 | { |
188 | struct pca9532_data *data; | 188 | struct pca9532_data *data; |
189 | data = container_of(work, struct pca9532_data, work); | 189 | data = container_of(work, struct pca9532_data, work); |
190 | mutex_lock(&data->update_lock); | 190 | mutex_lock(&data->update_lock); |
191 | i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1), | 191 | i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1), |
192 | data->pwm[1]); | 192 | data->pwm[1]); |
@@ -195,11 +195,11 @@ static void pca9532_input_work(struct work_struct *work) | |||
195 | 195 | ||
196 | static void pca9532_led_work(struct work_struct *work) | 196 | static void pca9532_led_work(struct work_struct *work) |
197 | { | 197 | { |
198 | struct pca9532_led *led; | 198 | struct pca9532_led *led; |
199 | led = container_of(work, struct pca9532_led, work); | 199 | led = container_of(work, struct pca9532_led, work); |
200 | if (led->state == PCA9532_PWM0) | 200 | if (led->state == PCA9532_PWM0) |
201 | pca9532_setpwm(led->client, 0); | 201 | pca9532_setpwm(led->client, 0); |
202 | pca9532_setled(led); | 202 | pca9532_setled(led); |
203 | } | 203 | } |
204 | 204 | ||
205 | static int pca9532_configure(struct i2c_client *client, | 205 | static int pca9532_configure(struct i2c_client *client, |
@@ -232,7 +232,7 @@ static int pca9532_configure(struct i2c_client *client, | |||
232 | led->ldev.brightness = LED_OFF; | 232 | led->ldev.brightness = LED_OFF; |
233 | led->ldev.brightness_set = pca9532_set_brightness; | 233 | led->ldev.brightness_set = pca9532_set_brightness; |
234 | led->ldev.blink_set = pca9532_set_blink; | 234 | led->ldev.blink_set = pca9532_set_blink; |
235 | INIT_WORK(&led->work, pca9532_led_work); | 235 | INIT_WORK(&led->work, pca9532_led_work); |
236 | err = led_classdev_register(&client->dev, &led->ldev); | 236 | err = led_classdev_register(&client->dev, &led->ldev); |
237 | if (err < 0) { | 237 | if (err < 0) { |
238 | dev_err(&client->dev, | 238 | dev_err(&client->dev, |
@@ -262,11 +262,11 @@ static int pca9532_configure(struct i2c_client *client, | |||
262 | BIT_MASK(SND_TONE); | 262 | BIT_MASK(SND_TONE); |
263 | data->idev->event = pca9532_event; | 263 | data->idev->event = pca9532_event; |
264 | input_set_drvdata(data->idev, data); | 264 | input_set_drvdata(data->idev, data); |
265 | INIT_WORK(&data->work, pca9532_input_work); | 265 | INIT_WORK(&data->work, pca9532_input_work); |
266 | err = input_register_device(data->idev); | 266 | err = input_register_device(data->idev); |
267 | if (err) { | 267 | if (err) { |
268 | input_free_device(data->idev); | 268 | input_free_device(data->idev); |
269 | cancel_work_sync(&data->work); | 269 | cancel_work_sync(&data->work); |
270 | data->idev = NULL; | 270 | data->idev = NULL; |
271 | goto exit; | 271 | goto exit; |
272 | } | 272 | } |
@@ -283,13 +283,13 @@ exit: | |||
283 | break; | 283 | break; |
284 | case PCA9532_TYPE_LED: | 284 | case PCA9532_TYPE_LED: |
285 | led_classdev_unregister(&data->leds[i].ldev); | 285 | led_classdev_unregister(&data->leds[i].ldev); |
286 | cancel_work_sync(&data->leds[i].work); | 286 | cancel_work_sync(&data->leds[i].work); |
287 | break; | 287 | break; |
288 | case PCA9532_TYPE_N2100_BEEP: | 288 | case PCA9532_TYPE_N2100_BEEP: |
289 | if (data->idev != NULL) { | 289 | if (data->idev != NULL) { |
290 | input_unregister_device(data->idev); | 290 | input_unregister_device(data->idev); |
291 | input_free_device(data->idev); | 291 | input_free_device(data->idev); |
292 | cancel_work_sync(&data->work); | 292 | cancel_work_sync(&data->work); |
293 | data->idev = NULL; | 293 | data->idev = NULL; |
294 | } | 294 | } |
295 | break; | 295 | break; |
@@ -340,13 +340,13 @@ static int pca9532_remove(struct i2c_client *client) | |||
340 | break; | 340 | break; |
341 | case PCA9532_TYPE_LED: | 341 | case PCA9532_TYPE_LED: |
342 | led_classdev_unregister(&data->leds[i].ldev); | 342 | led_classdev_unregister(&data->leds[i].ldev); |
343 | cancel_work_sync(&data->leds[i].work); | 343 | cancel_work_sync(&data->leds[i].work); |
344 | break; | 344 | break; |
345 | case PCA9532_TYPE_N2100_BEEP: | 345 | case PCA9532_TYPE_N2100_BEEP: |
346 | if (data->idev != NULL) { | 346 | if (data->idev != NULL) { |
347 | input_unregister_device(data->idev); | 347 | input_unregister_device(data->idev); |
348 | input_free_device(data->idev); | 348 | input_free_device(data->idev); |
349 | cancel_work_sync(&data->work); | 349 | cancel_work_sync(&data->work); |
350 | data->idev = NULL; | 350 | data->idev = NULL; |
351 | } | 351 | } |
352 | break; | 352 | break; |
diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 6e149f4a1fff..a0f68386c12f 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c | |||
@@ -378,6 +378,17 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, | |||
378 | dev->ofdev.dev.bus = &macio_bus_type; | 378 | dev->ofdev.dev.bus = &macio_bus_type; |
379 | dev->ofdev.dev.release = macio_release_dev; | 379 | dev->ofdev.dev.release = macio_release_dev; |
380 | 380 | ||
381 | #ifdef CONFIG_PCI | ||
382 | /* Set the DMA ops to the ones from the PCI device, this could be | ||
383 | * fishy if we didn't know that on PowerMac it's always direct ops | ||
384 | * or iommu ops that will work fine | ||
385 | */ | ||
386 | dev->ofdev.dev.archdata.dma_ops = | ||
387 | chip->lbus.pdev->dev.archdata.dma_ops; | ||
388 | dev->ofdev.dev.archdata.dma_data = | ||
389 | chip->lbus.pdev->dev.archdata.dma_data; | ||
390 | #endif /* CONFIG_PCI */ | ||
391 | |||
381 | #ifdef DEBUG | 392 | #ifdef DEBUG |
382 | printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n", | 393 | printk("preparing mdev @%p, ofdev @%p, dev @%p, kobj @%p\n", |
383 | dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj); | 394 | dev, &dev->ofdev, &dev->ofdev.dev, &dev->ofdev.dev.kobj); |
diff --git a/drivers/net/atl1c/atl1c_ethtool.c b/drivers/net/atl1c/atl1c_ethtool.c index e4afbd628c23..607007d75b6f 100644 --- a/drivers/net/atl1c/atl1c_ethtool.c +++ b/drivers/net/atl1c/atl1c_ethtool.c | |||
@@ -281,6 +281,8 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
281 | if (wol->wolopts & WAKE_PHY) | 281 | if (wol->wolopts & WAKE_PHY) |
282 | adapter->wol |= AT_WUFC_LNKC; | 282 | adapter->wol |= AT_WUFC_LNKC; |
283 | 283 | ||
284 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
285 | |||
284 | return 0; | 286 | return 0; |
285 | } | 287 | } |
286 | 288 | ||
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c index 619c6583e1aa..4003955d7a96 100644 --- a/drivers/net/atl1e/atl1e_ethtool.c +++ b/drivers/net/atl1e/atl1e_ethtool.c | |||
@@ -365,6 +365,8 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) | |||
365 | if (wol->wolopts & WAKE_PHY) | 365 | if (wol->wolopts & WAKE_PHY) |
366 | adapter->wol |= AT_WUFC_LNKC; | 366 | adapter->wol |= AT_WUFC_LNKC; |
367 | 367 | ||
368 | device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); | ||
369 | |||
368 | return 0; | 370 | return 0; |
369 | } | 371 | } |
370 | 372 | ||
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index f703758f0a6e..5b4bf3d2cdc2 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -73,7 +73,7 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
73 | #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) | 73 | #define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST) |
74 | 74 | ||
75 | #define BE_MAX_LRO_DESCRIPTORS 16 | 75 | #define BE_MAX_LRO_DESCRIPTORS 16 |
76 | #define BE_MAX_FRAGS_PER_FRAME 16 | 76 | #define BE_MAX_FRAGS_PER_FRAME (min((u32) 16, (u32) MAX_SKB_FRAGS)) |
77 | 77 | ||
78 | struct be_dma_mem { | 78 | struct be_dma_mem { |
79 | void *va; | 79 | void *va; |
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c index 9592f22e4c8c..cccc5419ad72 100644 --- a/drivers/net/benet/be_ethtool.c +++ b/drivers/net/benet/be_ethtool.c | |||
@@ -162,8 +162,8 @@ be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce) | |||
162 | return -EINVAL; | 162 | return -EINVAL; |
163 | 163 | ||
164 | adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; | 164 | adapter->max_rx_coal = coalesce->rx_max_coalesced_frames; |
165 | if (adapter->max_rx_coal > MAX_SKB_FRAGS) | 165 | if (adapter->max_rx_coal > BE_MAX_FRAGS_PER_FRAME) |
166 | adapter->max_rx_coal = MAX_SKB_FRAGS - 1; | 166 | adapter->max_rx_coal = BE_MAX_FRAGS_PER_FRAME; |
167 | 167 | ||
168 | /* if AIC is being turned on now, start with an EQD of 0 */ | 168 | /* if AIC is being turned on now, start with an EQD of 0 */ |
169 | if (rx_eq->enable_aic == 0 && | 169 | if (rx_eq->enable_aic == 0 && |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 66c10c87f517..308eb09ca56b 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -666,7 +666,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
666 | { | 666 | { |
667 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 667 | struct be_queue_info *rxq = &adapter->rx_obj.q; |
668 | struct be_rx_page_info *page_info; | 668 | struct be_rx_page_info *page_info; |
669 | u16 rxq_idx, i, num_rcvd; | 669 | u16 rxq_idx, i, num_rcvd, j; |
670 | u32 pktsize, hdr_len, curr_frag_len; | 670 | u32 pktsize, hdr_len, curr_frag_len; |
671 | u8 *start; | 671 | u8 *start; |
672 | 672 | ||
@@ -709,22 +709,33 @@ static void skb_fill_rx_data(struct be_adapter *adapter, | |||
709 | 709 | ||
710 | /* More frags present for this completion */ | 710 | /* More frags present for this completion */ |
711 | pktsize -= curr_frag_len; /* account for above copied frag */ | 711 | pktsize -= curr_frag_len; /* account for above copied frag */ |
712 | for (i = 1; i < num_rcvd; i++) { | 712 | for (i = 1, j = 0; i < num_rcvd; i++) { |
713 | index_inc(&rxq_idx, rxq->len); | 713 | index_inc(&rxq_idx, rxq->len); |
714 | page_info = get_rx_page_info(adapter, rxq_idx); | 714 | page_info = get_rx_page_info(adapter, rxq_idx); |
715 | 715 | ||
716 | curr_frag_len = min(pktsize, rx_frag_size); | 716 | curr_frag_len = min(pktsize, rx_frag_size); |
717 | 717 | ||
718 | skb_shinfo(skb)->frags[i].page = page_info->page; | 718 | /* Coalesce all frags from the same physical page in one slot */ |
719 | skb_shinfo(skb)->frags[i].page_offset = page_info->page_offset; | 719 | if (page_info->page_offset == 0) { |
720 | skb_shinfo(skb)->frags[i].size = curr_frag_len; | 720 | /* Fresh page */ |
721 | j++; | ||
722 | skb_shinfo(skb)->frags[j].page = page_info->page; | ||
723 | skb_shinfo(skb)->frags[j].page_offset = | ||
724 | page_info->page_offset; | ||
725 | skb_shinfo(skb)->frags[j].size = 0; | ||
726 | skb_shinfo(skb)->nr_frags++; | ||
727 | } else { | ||
728 | put_page(page_info->page); | ||
729 | } | ||
730 | |||
731 | skb_shinfo(skb)->frags[j].size += curr_frag_len; | ||
721 | skb->len += curr_frag_len; | 732 | skb->len += curr_frag_len; |
722 | skb->data_len += curr_frag_len; | 733 | skb->data_len += curr_frag_len; |
723 | skb_shinfo(skb)->nr_frags++; | ||
724 | pktsize -= curr_frag_len; | 734 | pktsize -= curr_frag_len; |
725 | 735 | ||
726 | memset(page_info, 0, sizeof(*page_info)); | 736 | memset(page_info, 0, sizeof(*page_info)); |
727 | } | 737 | } |
738 | BUG_ON(j > MAX_SKB_FRAGS); | ||
728 | 739 | ||
729 | done: | 740 | done: |
730 | be_rx_stats_update(adapter, pktsize, num_rcvd); | 741 | be_rx_stats_update(adapter, pktsize, num_rcvd); |
@@ -786,7 +797,7 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter, | |||
786 | struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; | 797 | struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME]; |
787 | struct be_queue_info *rxq = &adapter->rx_obj.q; | 798 | struct be_queue_info *rxq = &adapter->rx_obj.q; |
788 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; | 799 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; |
789 | u16 i, rxq_idx = 0, vid; | 800 | u16 i, rxq_idx = 0, vid, j; |
790 | 801 | ||
791 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | 802 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); |
792 | pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); | 803 | pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); |
@@ -794,20 +805,28 @@ static void be_rx_compl_process_lro(struct be_adapter *adapter, | |||
794 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | 805 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); |
795 | 806 | ||
796 | remaining = pkt_size; | 807 | remaining = pkt_size; |
797 | for (i = 0; i < num_rcvd; i++) { | 808 | for (i = 0, j = -1; i < num_rcvd; i++) { |
798 | page_info = get_rx_page_info(adapter, rxq_idx); | 809 | page_info = get_rx_page_info(adapter, rxq_idx); |
799 | 810 | ||
800 | curr_frag_len = min(remaining, rx_frag_size); | 811 | curr_frag_len = min(remaining, rx_frag_size); |
801 | 812 | ||
802 | rx_frags[i].page = page_info->page; | 813 | /* Coalesce all frags from the same physical page in one slot */ |
803 | rx_frags[i].page_offset = page_info->page_offset; | 814 | if (i == 0 || page_info->page_offset == 0) { |
804 | rx_frags[i].size = curr_frag_len; | 815 | /* First frag or Fresh page */ |
805 | remaining -= curr_frag_len; | 816 | j++; |
817 | rx_frags[j].page = page_info->page; | ||
818 | rx_frags[j].page_offset = page_info->page_offset; | ||
819 | rx_frags[j].size = 0; | ||
820 | } else { | ||
821 | put_page(page_info->page); | ||
822 | } | ||
823 | rx_frags[j].size += curr_frag_len; | ||
806 | 824 | ||
825 | remaining -= curr_frag_len; | ||
807 | index_inc(&rxq_idx, rxq->len); | 826 | index_inc(&rxq_idx, rxq->len); |
808 | |||
809 | memset(page_info, 0, sizeof(*page_info)); | 827 | memset(page_info, 0, sizeof(*page_info)); |
810 | } | 828 | } |
829 | BUG_ON(j > MAX_SKB_FRAGS); | ||
811 | 830 | ||
812 | if (likely(!vlanf)) { | 831 | if (likely(!vlanf)) { |
813 | lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, | 832 | lro_receive_frags(&adapter->rx_obj.lro_mgr, rx_frags, pkt_size, |
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 58afafbd3b9c..fd5e32cbcb87 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c | |||
@@ -1097,7 +1097,7 @@ static const struct net_device_ops cpmac_netdev_ops = { | |||
1097 | .ndo_start_xmit = cpmac_start_xmit, | 1097 | .ndo_start_xmit = cpmac_start_xmit, |
1098 | .ndo_tx_timeout = cpmac_tx_timeout, | 1098 | .ndo_tx_timeout = cpmac_tx_timeout, |
1099 | .ndo_set_multicast_list = cpmac_set_multicast_list, | 1099 | .ndo_set_multicast_list = cpmac_set_multicast_list, |
1100 | .ndo_so_ioctl = cpmac_ioctl, | 1100 | .ndo_do_ioctl = cpmac_ioctl, |
1101 | .ndo_set_config = cpmac_config, | 1101 | .ndo_set_config = cpmac_config, |
1102 | .ndo_change_mtu = eth_change_mtu, | 1102 | .ndo_change_mtu = eth_change_mtu, |
1103 | .ndo_validate_addr = eth_validate_addr, | 1103 | .ndo_validate_addr = eth_validate_addr, |
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c index 3af581303ca2..d167090248e2 100644 --- a/drivers/net/fsl_pq_mdio.c +++ b/drivers/net/fsl_pq_mdio.c | |||
@@ -188,7 +188,7 @@ static int fsl_pq_mdio_find_free(struct mii_bus *new_bus) | |||
188 | } | 188 | } |
189 | 189 | ||
190 | 190 | ||
191 | #ifdef CONFIG_GIANFAR | 191 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) |
192 | static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) | 192 | static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) |
193 | { | 193 | { |
194 | struct gfar __iomem *enet_regs; | 194 | struct gfar __iomem *enet_regs; |
@@ -206,7 +206,7 @@ static u32 __iomem *get_gfar_tbipa(struct fsl_pq_mdio __iomem *regs) | |||
206 | #endif | 206 | #endif |
207 | 207 | ||
208 | 208 | ||
209 | #ifdef CONFIG_UCC_GETH | 209 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) |
210 | static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) | 210 | static int get_ucc_id_for_range(u64 start, u64 end, u32 *ucc_id) |
211 | { | 211 | { |
212 | struct device_node *np = NULL; | 212 | struct device_node *np = NULL; |
@@ -291,7 +291,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
291 | if (of_device_is_compatible(np, "fsl,gianfar-mdio") || | 291 | if (of_device_is_compatible(np, "fsl,gianfar-mdio") || |
292 | of_device_is_compatible(np, "fsl,gianfar-tbi") || | 292 | of_device_is_compatible(np, "fsl,gianfar-tbi") || |
293 | of_device_is_compatible(np, "gianfar")) { | 293 | of_device_is_compatible(np, "gianfar")) { |
294 | #ifdef CONFIG_GIANFAR | 294 | #if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE) |
295 | tbipa = get_gfar_tbipa(regs); | 295 | tbipa = get_gfar_tbipa(regs); |
296 | #else | 296 | #else |
297 | err = -ENODEV; | 297 | err = -ENODEV; |
@@ -299,7 +299,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev, | |||
299 | #endif | 299 | #endif |
300 | } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || | 300 | } else if (of_device_is_compatible(np, "fsl,ucc-mdio") || |
301 | of_device_is_compatible(np, "ucc_geth_phy")) { | 301 | of_device_is_compatible(np, "ucc_geth_phy")) { |
302 | #ifdef CONFIG_UCC_GETH | 302 | #if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE) |
303 | u32 id; | 303 | u32 id; |
304 | static u32 mii_mng_master; | 304 | static u32 mii_mng_master; |
305 | 305 | ||
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c index dc45e9856c35..6851bdb2ce29 100644 --- a/drivers/net/mdio.c +++ b/drivers/net/mdio.c | |||
@@ -14,6 +14,10 @@ | |||
14 | #include <linux/mdio.h> | 14 | #include <linux/mdio.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | 16 | ||
17 | MODULE_DESCRIPTION("Generic support for MDIO-compatible transceivers"); | ||
18 | MODULE_AUTHOR("Copyright 2006-2009 Solarflare Communications Inc."); | ||
19 | MODULE_LICENSE("GPL"); | ||
20 | |||
17 | /** | 21 | /** |
18 | * mdio45_probe - probe for an MDIO (clause 45) device | 22 | * mdio45_probe - probe for an MDIO (clause 45) device |
19 | * @mdio: MDIO interface | 23 | * @mdio: MDIO interface |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 341882f959f3..a2d82ddb3b4d 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -865,8 +865,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
865 | struct sh_eth_private *mdp = netdev_priv(ndev); | 865 | struct sh_eth_private *mdp = netdev_priv(ndev); |
866 | struct sh_eth_cpu_data *cd = mdp->cd; | 866 | struct sh_eth_cpu_data *cd = mdp->cd; |
867 | irqreturn_t ret = IRQ_NONE; | 867 | irqreturn_t ret = IRQ_NONE; |
868 | u32 ioaddr, boguscnt = RX_RING_SIZE; | 868 | u32 ioaddr, intr_status = 0; |
869 | u32 intr_status = 0; | ||
870 | 869 | ||
871 | ioaddr = ndev->base_addr; | 870 | ioaddr = ndev->base_addr; |
872 | spin_lock(&mdp->lock); | 871 | spin_lock(&mdp->lock); |
@@ -901,12 +900,6 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev) | |||
901 | if (intr_status & cd->eesr_err_check) | 900 | if (intr_status & cd->eesr_err_check) |
902 | sh_eth_error(ndev, intr_status); | 901 | sh_eth_error(ndev, intr_status); |
903 | 902 | ||
904 | if (--boguscnt < 0) { | ||
905 | printk(KERN_WARNING | ||
906 | "%s: Too much work at interrupt, status=0x%4.4x.\n", | ||
907 | ndev->name, intr_status); | ||
908 | } | ||
909 | |||
910 | other_irq: | 903 | other_irq: |
911 | spin_unlock(&mdp->lock); | 904 | spin_unlock(&mdp->lock); |
912 | 905 | ||
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 7681d28c53d7..daf961ab68bc 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -2495,7 +2495,7 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do, u16 idx) | |||
2495 | if (likely(status >> 16 == (status & 0xffff))) { | 2495 | if (likely(status >> 16 == (status & 0xffff))) { |
2496 | skb = sky2->rx_ring[sky2->rx_next].skb; | 2496 | skb = sky2->rx_ring[sky2->rx_next].skb; |
2497 | skb->ip_summed = CHECKSUM_COMPLETE; | 2497 | skb->ip_summed = CHECKSUM_COMPLETE; |
2498 | skb->csum = status & 0xffff; | 2498 | skb->csum = le16_to_cpu(status); |
2499 | } else { | 2499 | } else { |
2500 | printk(KERN_NOTICE PFX "%s: hardware receive " | 2500 | printk(KERN_NOTICE PFX "%s: hardware receive " |
2501 | "checksum problem (status = %#x)\n", | 2501 | "checksum problem (status = %#x)\n", |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 87197dd9c788..1097c72e44d5 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -208,11 +208,14 @@ rx_drop: | |||
208 | 208 | ||
209 | static struct net_device_stats *veth_get_stats(struct net_device *dev) | 209 | static struct net_device_stats *veth_get_stats(struct net_device *dev) |
210 | { | 210 | { |
211 | struct veth_priv *priv = netdev_priv(dev); | 211 | struct veth_priv *priv; |
212 | struct net_device_stats *dev_stats = &dev->stats; | 212 | struct net_device_stats *dev_stats; |
213 | unsigned int cpu; | 213 | int cpu; |
214 | struct veth_net_stats *stats; | 214 | struct veth_net_stats *stats; |
215 | 215 | ||
216 | priv = netdev_priv(dev); | ||
217 | dev_stats = &dev->stats; | ||
218 | |||
216 | dev_stats->rx_packets = 0; | 219 | dev_stats->rx_packets = 0; |
217 | dev_stats->tx_packets = 0; | 220 | dev_stats->tx_packets = 0; |
218 | dev_stats->rx_bytes = 0; | 221 | dev_stats->rx_bytes = 0; |
@@ -220,17 +223,16 @@ static struct net_device_stats *veth_get_stats(struct net_device *dev) | |||
220 | dev_stats->tx_dropped = 0; | 223 | dev_stats->tx_dropped = 0; |
221 | dev_stats->rx_dropped = 0; | 224 | dev_stats->rx_dropped = 0; |
222 | 225 | ||
223 | if (priv->stats) | 226 | for_each_online_cpu(cpu) { |
224 | for_each_online_cpu(cpu) { | 227 | stats = per_cpu_ptr(priv->stats, cpu); |
225 | stats = per_cpu_ptr(priv->stats, cpu); | ||
226 | 228 | ||
227 | dev_stats->rx_packets += stats->rx_packets; | 229 | dev_stats->rx_packets += stats->rx_packets; |
228 | dev_stats->tx_packets += stats->tx_packets; | 230 | dev_stats->tx_packets += stats->tx_packets; |
229 | dev_stats->rx_bytes += stats->rx_bytes; | 231 | dev_stats->rx_bytes += stats->rx_bytes; |
230 | dev_stats->tx_bytes += stats->tx_bytes; | 232 | dev_stats->tx_bytes += stats->tx_bytes; |
231 | dev_stats->tx_dropped += stats->tx_dropped; | 233 | dev_stats->tx_dropped += stats->tx_dropped; |
232 | dev_stats->rx_dropped += stats->rx_dropped; | 234 | dev_stats->rx_dropped += stats->rx_dropped; |
233 | } | 235 | } |
234 | 236 | ||
235 | return dev_stats; | 237 | return dev_stats; |
236 | } | 238 | } |
@@ -257,8 +259,6 @@ static int veth_close(struct net_device *dev) | |||
257 | netif_carrier_off(dev); | 259 | netif_carrier_off(dev); |
258 | netif_carrier_off(priv->peer); | 260 | netif_carrier_off(priv->peer); |
259 | 261 | ||
260 | free_percpu(priv->stats); | ||
261 | priv->stats = NULL; | ||
262 | return 0; | 262 | return 0; |
263 | } | 263 | } |
264 | 264 | ||
@@ -289,6 +289,15 @@ static int veth_dev_init(struct net_device *dev) | |||
289 | return 0; | 289 | return 0; |
290 | } | 290 | } |
291 | 291 | ||
292 | static void veth_dev_free(struct net_device *dev) | ||
293 | { | ||
294 | struct veth_priv *priv; | ||
295 | |||
296 | priv = netdev_priv(dev); | ||
297 | free_percpu(priv->stats); | ||
298 | free_netdev(dev); | ||
299 | } | ||
300 | |||
292 | static const struct net_device_ops veth_netdev_ops = { | 301 | static const struct net_device_ops veth_netdev_ops = { |
293 | .ndo_init = veth_dev_init, | 302 | .ndo_init = veth_dev_init, |
294 | .ndo_open = veth_open, | 303 | .ndo_open = veth_open, |
@@ -306,7 +315,7 @@ static void veth_setup(struct net_device *dev) | |||
306 | dev->netdev_ops = &veth_netdev_ops; | 315 | dev->netdev_ops = &veth_netdev_ops; |
307 | dev->ethtool_ops = &veth_ethtool_ops; | 316 | dev->ethtool_ops = &veth_ethtool_ops; |
308 | dev->features |= NETIF_F_LLTX; | 317 | dev->features |= NETIF_F_LLTX; |
309 | dev->destructor = free_netdev; | 318 | dev->destructor = veth_dev_free; |
310 | } | 319 | } |
311 | 320 | ||
312 | /* | 321 | /* |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index e53eacd75c8d..420afa887283 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -39,7 +39,6 @@ | |||
39 | #include <linux/sysdev.h> | 39 | #include <linux/sysdev.h> |
40 | #include <asm/cacheflush.h> | 40 | #include <asm/cacheflush.h> |
41 | #include <asm/iommu.h> | 41 | #include <asm/iommu.h> |
42 | #include <asm/e820.h> | ||
43 | #include "pci.h" | 42 | #include "pci.h" |
44 | 43 | ||
45 | #define ROOT_SIZE VTD_PAGE_SIZE | 44 | #define ROOT_SIZE VTD_PAGE_SIZE |
@@ -1908,7 +1907,6 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr, | |||
1908 | rmrr->end_address + 1); | 1907 | rmrr->end_address + 1); |
1909 | } | 1908 | } |
1910 | 1909 | ||
1911 | #ifdef CONFIG_DMAR_GFX_WA | ||
1912 | struct iommu_prepare_data { | 1910 | struct iommu_prepare_data { |
1913 | struct pci_dev *pdev; | 1911 | struct pci_dev *pdev; |
1914 | int ret; | 1912 | int ret; |
@@ -1943,6 +1941,7 @@ static int __init iommu_prepare_with_active_regions(struct pci_dev *pdev) | |||
1943 | return data.ret; | 1941 | return data.ret; |
1944 | } | 1942 | } |
1945 | 1943 | ||
1944 | #ifdef CONFIG_DMAR_GFX_WA | ||
1946 | static void __init iommu_prepare_gfx_mapping(void) | 1945 | static void __init iommu_prepare_gfx_mapping(void) |
1947 | { | 1946 | { |
1948 | struct pci_dev *pdev = NULL; | 1947 | struct pci_dev *pdev = NULL; |
@@ -2081,7 +2080,6 @@ static int domain_add_dev_info(struct dmar_domain *domain, | |||
2081 | 2080 | ||
2082 | static int iommu_prepare_static_identity_mapping(void) | 2081 | static int iommu_prepare_static_identity_mapping(void) |
2083 | { | 2082 | { |
2084 | int i; | ||
2085 | struct pci_dev *pdev = NULL; | 2083 | struct pci_dev *pdev = NULL; |
2086 | int ret; | 2084 | int ret; |
2087 | 2085 | ||
@@ -2091,17 +2089,10 @@ static int iommu_prepare_static_identity_mapping(void) | |||
2091 | 2089 | ||
2092 | printk(KERN_INFO "IOMMU: Setting identity map:\n"); | 2090 | printk(KERN_INFO "IOMMU: Setting identity map:\n"); |
2093 | for_each_pci_dev(pdev) { | 2091 | for_each_pci_dev(pdev) { |
2094 | for (i = 0; i < e820.nr_map; i++) { | 2092 | ret = iommu_prepare_with_active_regions(pdev); |
2095 | struct e820entry *ei = &e820.map[i]; | 2093 | if (ret) { |
2096 | 2094 | printk(KERN_INFO "1:1 mapping to one domain failed.\n"); | |
2097 | if (ei->type == E820_RAM) { | 2095 | return -EFAULT; |
2098 | ret = iommu_prepare_identity_map(pdev, | ||
2099 | ei->addr, ei->addr + ei->size); | ||
2100 | if (ret) { | ||
2101 | printk(KERN_INFO "1:1 mapping to one domain failed.\n"); | ||
2102 | return -EFAULT; | ||
2103 | } | ||
2104 | } | ||
2105 | } | 2096 | } |
2106 | ret = domain_add_dev_info(si_domain, pdev); | 2097 | ret = domain_add_dev_info(si_domain, pdev); |
2107 | if (ret) | 2098 | if (ret) |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 7232fe7104aa..46dad12f952f 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -355,6 +355,7 @@ config EEEPC_LAPTOP | |||
355 | depends on INPUT | 355 | depends on INPUT |
356 | depends on EXPERIMENTAL | 356 | depends on EXPERIMENTAL |
357 | depends on RFKILL || RFKILL = n | 357 | depends on RFKILL || RFKILL = n |
358 | depends on HOTPLUG_PCI | ||
358 | select BACKLIGHT_CLASS_DEVICE | 359 | select BACKLIGHT_CLASS_DEVICE |
359 | select HWMON | 360 | select HWMON |
360 | ---help--- | 361 | ---help--- |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 4207b26ff990..ec560f16d720 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -16,6 +16,8 @@ | |||
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
19 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
20 | #include <linux/module.h> | 22 | #include <linux/module.h> |
21 | #include <linux/init.h> | 23 | #include <linux/init.h> |
@@ -31,6 +33,7 @@ | |||
31 | #include <linux/input.h> | 33 | #include <linux/input.h> |
32 | #include <linux/rfkill.h> | 34 | #include <linux/rfkill.h> |
33 | #include <linux/pci.h> | 35 | #include <linux/pci.h> |
36 | #include <linux/pci_hotplug.h> | ||
34 | 37 | ||
35 | #define EEEPC_LAPTOP_VERSION "0.1" | 38 | #define EEEPC_LAPTOP_VERSION "0.1" |
36 | 39 | ||
@@ -40,11 +43,6 @@ | |||
40 | #define EEEPC_HOTK_DEVICE_NAME "Hotkey" | 43 | #define EEEPC_HOTK_DEVICE_NAME "Hotkey" |
41 | #define EEEPC_HOTK_HID "ASUS010" | 44 | #define EEEPC_HOTK_HID "ASUS010" |
42 | 45 | ||
43 | #define EEEPC_LOG EEEPC_HOTK_FILE ": " | ||
44 | #define EEEPC_ERR KERN_ERR EEEPC_LOG | ||
45 | #define EEEPC_WARNING KERN_WARNING EEEPC_LOG | ||
46 | #define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG | ||
47 | #define EEEPC_INFO KERN_INFO EEEPC_LOG | ||
48 | 46 | ||
49 | /* | 47 | /* |
50 | * Definitions for Asus EeePC | 48 | * Definitions for Asus EeePC |
@@ -141,8 +139,10 @@ struct eeepc_hotk { | |||
141 | u16 event_count[128]; /* count for each event */ | 139 | u16 event_count[128]; /* count for each event */ |
142 | struct input_dev *inputdev; | 140 | struct input_dev *inputdev; |
143 | u16 *keycode_map; | 141 | u16 *keycode_map; |
144 | struct rfkill *eeepc_wlan_rfkill; | 142 | struct rfkill *wlan_rfkill; |
145 | struct rfkill *eeepc_bluetooth_rfkill; | 143 | struct rfkill *bluetooth_rfkill; |
144 | struct rfkill *wwan3g_rfkill; | ||
145 | struct hotplug_slot *hotplug_slot; | ||
146 | }; | 146 | }; |
147 | 147 | ||
148 | /* The actual device the driver binds to */ | 148 | /* The actual device the driver binds to */ |
@@ -213,6 +213,15 @@ static struct acpi_driver eeepc_hotk_driver = { | |||
213 | }, | 213 | }, |
214 | }; | 214 | }; |
215 | 215 | ||
216 | /* PCI hotplug ops */ | ||
217 | static int eeepc_get_adapter_status(struct hotplug_slot *slot, u8 *value); | ||
218 | |||
219 | static struct hotplug_slot_ops eeepc_hotplug_slot_ops = { | ||
220 | .owner = THIS_MODULE, | ||
221 | .get_adapter_status = eeepc_get_adapter_status, | ||
222 | .get_power_status = eeepc_get_adapter_status, | ||
223 | }; | ||
224 | |||
216 | /* The backlight device /sys/class/backlight */ | 225 | /* The backlight device /sys/class/backlight */ |
217 | static struct backlight_device *eeepc_backlight_device; | 226 | static struct backlight_device *eeepc_backlight_device; |
218 | 227 | ||
@@ -274,20 +283,20 @@ static int set_acpi(int cm, int value) | |||
274 | if (method == NULL) | 283 | if (method == NULL) |
275 | return -ENODEV; | 284 | return -ENODEV; |
276 | if (write_acpi_int(ehotk->handle, method, value, NULL)) | 285 | if (write_acpi_int(ehotk->handle, method, value, NULL)) |
277 | printk(EEEPC_WARNING "Error writing %s\n", method); | 286 | pr_warning("Error writing %s\n", method); |
278 | } | 287 | } |
279 | return 0; | 288 | return 0; |
280 | } | 289 | } |
281 | 290 | ||
282 | static int get_acpi(int cm) | 291 | static int get_acpi(int cm) |
283 | { | 292 | { |
284 | int value = -1; | 293 | int value = -ENODEV; |
285 | if ((ehotk->cm_supported & (0x1 << cm))) { | 294 | if ((ehotk->cm_supported & (0x1 << cm))) { |
286 | const char *method = cm_getv[cm]; | 295 | const char *method = cm_getv[cm]; |
287 | if (method == NULL) | 296 | if (method == NULL) |
288 | return -ENODEV; | 297 | return -ENODEV; |
289 | if (read_acpi_int(ehotk->handle, method, &value)) | 298 | if (read_acpi_int(ehotk->handle, method, &value)) |
290 | printk(EEEPC_WARNING "Error reading %s\n", method); | 299 | pr_warning("Error reading %s\n", method); |
291 | } | 300 | } |
292 | return value; | 301 | return value; |
293 | } | 302 | } |
@@ -359,13 +368,19 @@ static ssize_t store_sys_acpi(int cm, const char *buf, size_t count) | |||
359 | 368 | ||
360 | rv = parse_arg(buf, count, &value); | 369 | rv = parse_arg(buf, count, &value); |
361 | if (rv > 0) | 370 | if (rv > 0) |
362 | set_acpi(cm, value); | 371 | value = set_acpi(cm, value); |
372 | if (value < 0) | ||
373 | return value; | ||
363 | return rv; | 374 | return rv; |
364 | } | 375 | } |
365 | 376 | ||
366 | static ssize_t show_sys_acpi(int cm, char *buf) | 377 | static ssize_t show_sys_acpi(int cm, char *buf) |
367 | { | 378 | { |
368 | return sprintf(buf, "%d\n", get_acpi(cm)); | 379 | int value = get_acpi(cm); |
380 | |||
381 | if (value < 0) | ||
382 | return value; | ||
383 | return sprintf(buf, "%d\n", value); | ||
369 | } | 384 | } |
370 | 385 | ||
371 | #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ | 386 | #define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \ |
@@ -539,6 +554,28 @@ static int eeepc_setkeycode(struct input_dev *dev, int scancode, int keycode) | |||
539 | return -EINVAL; | 554 | return -EINVAL; |
540 | } | 555 | } |
541 | 556 | ||
557 | static void cmsg_quirk(int cm, const char *name) | ||
558 | { | ||
559 | int dummy; | ||
560 | |||
561 | /* Some BIOSes do not report cm although it is avaliable. | ||
562 | Check if cm_getv[cm] works and, if yes, assume cm should be set. */ | ||
563 | if (!(ehotk->cm_supported & (1 << cm)) | ||
564 | && !read_acpi_int(ehotk->handle, cm_getv[cm], &dummy)) { | ||
565 | pr_info("%s (%x) not reported by BIOS," | ||
566 | " enabling anyway\n", name, 1 << cm); | ||
567 | ehotk->cm_supported |= 1 << cm; | ||
568 | } | ||
569 | } | ||
570 | |||
571 | static void cmsg_quirks(void) | ||
572 | { | ||
573 | cmsg_quirk(CM_ASL_LID, "LID"); | ||
574 | cmsg_quirk(CM_ASL_TYPE, "TYPE"); | ||
575 | cmsg_quirk(CM_ASL_PANELPOWER, "PANELPOWER"); | ||
576 | cmsg_quirk(CM_ASL_TPD, "TPD"); | ||
577 | } | ||
578 | |||
542 | static int eeepc_hotk_check(void) | 579 | static int eeepc_hotk_check(void) |
543 | { | 580 | { |
544 | const struct key_entry *key; | 581 | const struct key_entry *key; |
@@ -551,26 +588,24 @@ static int eeepc_hotk_check(void) | |||
551 | if (ehotk->device->status.present) { | 588 | if (ehotk->device->status.present) { |
552 | if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, | 589 | if (write_acpi_int(ehotk->handle, "INIT", ehotk->init_flag, |
553 | &buffer)) { | 590 | &buffer)) { |
554 | printk(EEEPC_ERR "Hotkey initialization failed\n"); | 591 | pr_err("Hotkey initialization failed\n"); |
555 | return -ENODEV; | 592 | return -ENODEV; |
556 | } else { | 593 | } else { |
557 | printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n", | 594 | pr_notice("Hotkey init flags 0x%x\n", ehotk->init_flag); |
558 | ehotk->init_flag); | ||
559 | } | 595 | } |
560 | /* get control methods supported */ | 596 | /* get control methods supported */ |
561 | if (read_acpi_int(ehotk->handle, "CMSG" | 597 | if (read_acpi_int(ehotk->handle, "CMSG" |
562 | , &ehotk->cm_supported)) { | 598 | , &ehotk->cm_supported)) { |
563 | printk(EEEPC_ERR | 599 | pr_err("Get control methods supported failed\n"); |
564 | "Get control methods supported failed\n"); | ||
565 | return -ENODEV; | 600 | return -ENODEV; |
566 | } else { | 601 | } else { |
567 | printk(EEEPC_INFO | 602 | cmsg_quirks(); |
568 | "Get control methods supported: 0x%x\n", | 603 | pr_info("Get control methods supported: 0x%x\n", |
569 | ehotk->cm_supported); | 604 | ehotk->cm_supported); |
570 | } | 605 | } |
571 | ehotk->inputdev = input_allocate_device(); | 606 | ehotk->inputdev = input_allocate_device(); |
572 | if (!ehotk->inputdev) { | 607 | if (!ehotk->inputdev) { |
573 | printk(EEEPC_INFO "Unable to allocate input device\n"); | 608 | pr_info("Unable to allocate input device\n"); |
574 | return 0; | 609 | return 0; |
575 | } | 610 | } |
576 | ehotk->inputdev->name = "Asus EeePC extra buttons"; | 611 | ehotk->inputdev->name = "Asus EeePC extra buttons"; |
@@ -589,12 +624,12 @@ static int eeepc_hotk_check(void) | |||
589 | } | 624 | } |
590 | result = input_register_device(ehotk->inputdev); | 625 | result = input_register_device(ehotk->inputdev); |
591 | if (result) { | 626 | if (result) { |
592 | printk(EEEPC_INFO "Unable to register input device\n"); | 627 | pr_info("Unable to register input device\n"); |
593 | input_free_device(ehotk->inputdev); | 628 | input_free_device(ehotk->inputdev); |
594 | return 0; | 629 | return 0; |
595 | } | 630 | } |
596 | } else { | 631 | } else { |
597 | printk(EEEPC_ERR "Hotkey device not present, aborting\n"); | 632 | pr_err("Hotkey device not present, aborting\n"); |
598 | return -EINVAL; | 633 | return -EINVAL; |
599 | } | 634 | } |
600 | return 0; | 635 | return 0; |
@@ -612,6 +647,19 @@ static int notify_brn(void) | |||
612 | return -1; | 647 | return -1; |
613 | } | 648 | } |
614 | 649 | ||
650 | static int eeepc_get_adapter_status(struct hotplug_slot *hotplug_slot, | ||
651 | u8 *value) | ||
652 | { | ||
653 | int val = get_acpi(CM_ASL_WLAN); | ||
654 | |||
655 | if (val == 1 || val == 0) | ||
656 | *value = val; | ||
657 | else | ||
658 | return -EINVAL; | ||
659 | |||
660 | return 0; | ||
661 | } | ||
662 | |||
615 | static void eeepc_rfkill_hotplug(void) | 663 | static void eeepc_rfkill_hotplug(void) |
616 | { | 664 | { |
617 | struct pci_dev *dev; | 665 | struct pci_dev *dev; |
@@ -619,7 +667,7 @@ static void eeepc_rfkill_hotplug(void) | |||
619 | bool blocked; | 667 | bool blocked; |
620 | 668 | ||
621 | if (!bus) { | 669 | if (!bus) { |
622 | printk(EEEPC_WARNING "Unable to find PCI bus 1?\n"); | 670 | pr_warning("Unable to find PCI bus 1?\n"); |
623 | return; | 671 | return; |
624 | } | 672 | } |
625 | 673 | ||
@@ -635,7 +683,7 @@ static void eeepc_rfkill_hotplug(void) | |||
635 | if (dev) { | 683 | if (dev) { |
636 | pci_bus_assign_resources(bus); | 684 | pci_bus_assign_resources(bus); |
637 | if (pci_bus_add_device(dev)) | 685 | if (pci_bus_add_device(dev)) |
638 | printk(EEEPC_ERR "Unable to hotplug wifi\n"); | 686 | pr_err("Unable to hotplug wifi\n"); |
639 | } | 687 | } |
640 | } else { | 688 | } else { |
641 | dev = pci_get_slot(bus, 0); | 689 | dev = pci_get_slot(bus, 0); |
@@ -645,7 +693,7 @@ static void eeepc_rfkill_hotplug(void) | |||
645 | } | 693 | } |
646 | } | 694 | } |
647 | 695 | ||
648 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); | 696 | rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); |
649 | } | 697 | } |
650 | 698 | ||
651 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 699 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
@@ -718,8 +766,7 @@ static int eeepc_register_rfkill_notifier(char *node) | |||
718 | eeepc_rfkill_notify, | 766 | eeepc_rfkill_notify, |
719 | NULL); | 767 | NULL); |
720 | if (ACPI_FAILURE(status)) | 768 | if (ACPI_FAILURE(status)) |
721 | printk(EEEPC_WARNING | 769 | pr_warning("Failed to register notify on %s\n", node); |
722 | "Failed to register notify on %s\n", node); | ||
723 | } else | 770 | } else |
724 | return -ENODEV; | 771 | return -ENODEV; |
725 | 772 | ||
@@ -738,19 +785,66 @@ static void eeepc_unregister_rfkill_notifier(char *node) | |||
738 | ACPI_SYSTEM_NOTIFY, | 785 | ACPI_SYSTEM_NOTIFY, |
739 | eeepc_rfkill_notify); | 786 | eeepc_rfkill_notify); |
740 | if (ACPI_FAILURE(status)) | 787 | if (ACPI_FAILURE(status)) |
741 | printk(EEEPC_ERR | 788 | pr_err("Error removing rfkill notify handler %s\n", |
742 | "Error removing rfkill notify handler %s\n", | ||
743 | node); | 789 | node); |
744 | } | 790 | } |
745 | } | 791 | } |
746 | 792 | ||
793 | static void eeepc_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot) | ||
794 | { | ||
795 | kfree(hotplug_slot->info); | ||
796 | kfree(hotplug_slot); | ||
797 | } | ||
798 | |||
799 | static int eeepc_setup_pci_hotplug(void) | ||
800 | { | ||
801 | int ret = -ENOMEM; | ||
802 | struct pci_bus *bus = pci_find_bus(0, 1); | ||
803 | |||
804 | if (!bus) { | ||
805 | pr_err("Unable to find wifi PCI bus\n"); | ||
806 | return -ENODEV; | ||
807 | } | ||
808 | |||
809 | ehotk->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL); | ||
810 | if (!ehotk->hotplug_slot) | ||
811 | goto error_slot; | ||
812 | |||
813 | ehotk->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info), | ||
814 | GFP_KERNEL); | ||
815 | if (!ehotk->hotplug_slot->info) | ||
816 | goto error_info; | ||
817 | |||
818 | ehotk->hotplug_slot->private = ehotk; | ||
819 | ehotk->hotplug_slot->release = &eeepc_cleanup_pci_hotplug; | ||
820 | ehotk->hotplug_slot->ops = &eeepc_hotplug_slot_ops; | ||
821 | eeepc_get_adapter_status(ehotk->hotplug_slot, | ||
822 | &ehotk->hotplug_slot->info->adapter_status); | ||
823 | |||
824 | ret = pci_hp_register(ehotk->hotplug_slot, bus, 0, "eeepc-wifi"); | ||
825 | if (ret) { | ||
826 | pr_err("Unable to register hotplug slot - %d\n", ret); | ||
827 | goto error_register; | ||
828 | } | ||
829 | |||
830 | return 0; | ||
831 | |||
832 | error_register: | ||
833 | kfree(ehotk->hotplug_slot->info); | ||
834 | error_info: | ||
835 | kfree(ehotk->hotplug_slot); | ||
836 | ehotk->hotplug_slot = NULL; | ||
837 | error_slot: | ||
838 | return ret; | ||
839 | } | ||
840 | |||
747 | static int eeepc_hotk_add(struct acpi_device *device) | 841 | static int eeepc_hotk_add(struct acpi_device *device) |
748 | { | 842 | { |
749 | int result; | 843 | int result; |
750 | 844 | ||
751 | if (!device) | 845 | if (!device) |
752 | return -EINVAL; | 846 | return -EINVAL; |
753 | printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n"); | 847 | pr_notice(EEEPC_HOTK_NAME "\n"); |
754 | ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); | 848 | ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL); |
755 | if (!ehotk) | 849 | if (!ehotk) |
756 | return -ENOMEM; | 850 | return -ENOMEM; |
@@ -764,53 +858,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
764 | if (result) | 858 | if (result) |
765 | goto ehotk_fail; | 859 | goto ehotk_fail; |
766 | 860 | ||
767 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
768 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
769 | |||
770 | if (get_acpi(CM_ASL_WLAN) != -1) { | ||
771 | ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan", | ||
772 | &device->dev, | ||
773 | RFKILL_TYPE_WLAN, | ||
774 | &eeepc_rfkill_ops, | ||
775 | (void *)CM_ASL_WLAN); | ||
776 | |||
777 | if (!ehotk->eeepc_wlan_rfkill) | ||
778 | goto wlan_fail; | ||
779 | |||
780 | rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill, | ||
781 | get_acpi(CM_ASL_WLAN) != 1); | ||
782 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); | ||
783 | if (result) | ||
784 | goto wlan_fail; | ||
785 | } | ||
786 | |||
787 | if (get_acpi(CM_ASL_BLUETOOTH) != -1) { | ||
788 | ehotk->eeepc_bluetooth_rfkill = | ||
789 | rfkill_alloc("eeepc-bluetooth", | ||
790 | &device->dev, | ||
791 | RFKILL_TYPE_BLUETOOTH, | ||
792 | &eeepc_rfkill_ops, | ||
793 | (void *)CM_ASL_BLUETOOTH); | ||
794 | |||
795 | if (!ehotk->eeepc_bluetooth_rfkill) | ||
796 | goto bluetooth_fail; | ||
797 | |||
798 | rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill, | ||
799 | get_acpi(CM_ASL_BLUETOOTH) != 1); | ||
800 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); | ||
801 | if (result) | ||
802 | goto bluetooth_fail; | ||
803 | } | ||
804 | |||
805 | return 0; | 861 | return 0; |
806 | 862 | ||
807 | bluetooth_fail: | ||
808 | rfkill_destroy(ehotk->eeepc_bluetooth_rfkill); | ||
809 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | ||
810 | wlan_fail: | ||
811 | rfkill_destroy(ehotk->eeepc_wlan_rfkill); | ||
812 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
813 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
814 | ehotk_fail: | 863 | ehotk_fail: |
815 | kfree(ehotk); | 864 | kfree(ehotk); |
816 | ehotk = NULL; | 865 | ehotk = NULL; |
@@ -823,16 +872,13 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) | |||
823 | if (!device || !acpi_driver_data(device)) | 872 | if (!device || !acpi_driver_data(device)) |
824 | return -EINVAL; | 873 | return -EINVAL; |
825 | 874 | ||
826 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
827 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
828 | |||
829 | kfree(ehotk); | 875 | kfree(ehotk); |
830 | return 0; | 876 | return 0; |
831 | } | 877 | } |
832 | 878 | ||
833 | static int eeepc_hotk_resume(struct acpi_device *device) | 879 | static int eeepc_hotk_resume(struct acpi_device *device) |
834 | { | 880 | { |
835 | if (ehotk->eeepc_wlan_rfkill) { | 881 | if (ehotk->wlan_rfkill) { |
836 | bool wlan; | 882 | bool wlan; |
837 | 883 | ||
838 | /* Workaround - it seems that _PTS disables the wireless | 884 | /* Workaround - it seems that _PTS disables the wireless |
@@ -844,14 +890,13 @@ static int eeepc_hotk_resume(struct acpi_device *device) | |||
844 | wlan = get_acpi(CM_ASL_WLAN); | 890 | wlan = get_acpi(CM_ASL_WLAN); |
845 | set_acpi(CM_ASL_WLAN, wlan); | 891 | set_acpi(CM_ASL_WLAN, wlan); |
846 | 892 | ||
847 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, | 893 | rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); |
848 | wlan != 1); | ||
849 | 894 | ||
850 | eeepc_rfkill_hotplug(); | 895 | eeepc_rfkill_hotplug(); |
851 | } | 896 | } |
852 | 897 | ||
853 | if (ehotk->eeepc_bluetooth_rfkill) | 898 | if (ehotk->bluetooth_rfkill) |
854 | rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, | 899 | rfkill_set_sw_state(ehotk->bluetooth_rfkill, |
855 | get_acpi(CM_ASL_BLUETOOTH) != 1); | 900 | get_acpi(CM_ASL_BLUETOOTH) != 1); |
856 | 901 | ||
857 | return 0; | 902 | return 0; |
@@ -973,10 +1018,16 @@ static void eeepc_backlight_exit(void) | |||
973 | 1018 | ||
974 | static void eeepc_rfkill_exit(void) | 1019 | static void eeepc_rfkill_exit(void) |
975 | { | 1020 | { |
976 | if (ehotk->eeepc_wlan_rfkill) | 1021 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); |
977 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | 1022 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); |
978 | if (ehotk->eeepc_bluetooth_rfkill) | 1023 | if (ehotk->wlan_rfkill) |
979 | rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); | 1024 | rfkill_unregister(ehotk->wlan_rfkill); |
1025 | if (ehotk->bluetooth_rfkill) | ||
1026 | rfkill_unregister(ehotk->bluetooth_rfkill); | ||
1027 | if (ehotk->wwan3g_rfkill) | ||
1028 | rfkill_unregister(ehotk->wwan3g_rfkill); | ||
1029 | if (ehotk->hotplug_slot) | ||
1030 | pci_hp_deregister(ehotk->hotplug_slot); | ||
980 | } | 1031 | } |
981 | 1032 | ||
982 | static void eeepc_input_exit(void) | 1033 | static void eeepc_input_exit(void) |
@@ -1011,6 +1062,75 @@ static void __exit eeepc_laptop_exit(void) | |||
1011 | platform_driver_unregister(&platform_driver); | 1062 | platform_driver_unregister(&platform_driver); |
1012 | } | 1063 | } |
1013 | 1064 | ||
1065 | static int eeepc_new_rfkill(struct rfkill **rfkill, | ||
1066 | const char *name, struct device *dev, | ||
1067 | enum rfkill_type type, int cm) | ||
1068 | { | ||
1069 | int result; | ||
1070 | |||
1071 | result = get_acpi(cm); | ||
1072 | if (result < 0) | ||
1073 | return result; | ||
1074 | |||
1075 | *rfkill = rfkill_alloc(name, dev, type, | ||
1076 | &eeepc_rfkill_ops, (void *)(unsigned long)cm); | ||
1077 | |||
1078 | if (!*rfkill) | ||
1079 | return -EINVAL; | ||
1080 | |||
1081 | rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); | ||
1082 | result = rfkill_register(*rfkill); | ||
1083 | if (result) { | ||
1084 | rfkill_destroy(*rfkill); | ||
1085 | *rfkill = NULL; | ||
1086 | return result; | ||
1087 | } | ||
1088 | return 0; | ||
1089 | } | ||
1090 | |||
1091 | |||
1092 | static int eeepc_rfkill_init(struct device *dev) | ||
1093 | { | ||
1094 | int result = 0; | ||
1095 | |||
1096 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
1097 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
1098 | |||
1099 | result = eeepc_new_rfkill(&ehotk->wlan_rfkill, | ||
1100 | "eeepc-wlan", dev, | ||
1101 | RFKILL_TYPE_WLAN, CM_ASL_WLAN); | ||
1102 | |||
1103 | if (result && result != -ENODEV) | ||
1104 | goto exit; | ||
1105 | |||
1106 | result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, | ||
1107 | "eeepc-bluetooth", dev, | ||
1108 | RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); | ||
1109 | |||
1110 | if (result && result != -ENODEV) | ||
1111 | goto exit; | ||
1112 | |||
1113 | result = eeepc_new_rfkill(&ehotk->wwan3g_rfkill, | ||
1114 | "eeepc-wwan3g", dev, | ||
1115 | RFKILL_TYPE_WWAN, CM_ASL_3G); | ||
1116 | |||
1117 | if (result && result != -ENODEV) | ||
1118 | goto exit; | ||
1119 | |||
1120 | result = eeepc_setup_pci_hotplug(); | ||
1121 | /* | ||
1122 | * If we get -EBUSY then something else is handling the PCI hotplug - | ||
1123 | * don't fail in this case | ||
1124 | */ | ||
1125 | if (result == -EBUSY) | ||
1126 | result = 0; | ||
1127 | |||
1128 | exit: | ||
1129 | if (result && result != -ENODEV) | ||
1130 | eeepc_rfkill_exit(); | ||
1131 | return result; | ||
1132 | } | ||
1133 | |||
1014 | static int eeepc_backlight_init(struct device *dev) | 1134 | static int eeepc_backlight_init(struct device *dev) |
1015 | { | 1135 | { |
1016 | struct backlight_device *bd; | 1136 | struct backlight_device *bd; |
@@ -1018,8 +1138,7 @@ static int eeepc_backlight_init(struct device *dev) | |||
1018 | bd = backlight_device_register(EEEPC_HOTK_FILE, dev, | 1138 | bd = backlight_device_register(EEEPC_HOTK_FILE, dev, |
1019 | NULL, &eeepcbl_ops); | 1139 | NULL, &eeepcbl_ops); |
1020 | if (IS_ERR(bd)) { | 1140 | if (IS_ERR(bd)) { |
1021 | printk(EEEPC_ERR | 1141 | pr_err("Could not register eeepc backlight device\n"); |
1022 | "Could not register eeepc backlight device\n"); | ||
1023 | eeepc_backlight_device = NULL; | 1142 | eeepc_backlight_device = NULL; |
1024 | return PTR_ERR(bd); | 1143 | return PTR_ERR(bd); |
1025 | } | 1144 | } |
@@ -1038,8 +1157,7 @@ static int eeepc_hwmon_init(struct device *dev) | |||
1038 | 1157 | ||
1039 | hwmon = hwmon_device_register(dev); | 1158 | hwmon = hwmon_device_register(dev); |
1040 | if (IS_ERR(hwmon)) { | 1159 | if (IS_ERR(hwmon)) { |
1041 | printk(EEEPC_ERR | 1160 | pr_err("Could not register eeepc hwmon device\n"); |
1042 | "Could not register eeepc hwmon device\n"); | ||
1043 | eeepc_hwmon_device = NULL; | 1161 | eeepc_hwmon_device = NULL; |
1044 | return PTR_ERR(hwmon); | 1162 | return PTR_ERR(hwmon); |
1045 | } | 1163 | } |
@@ -1065,19 +1183,6 @@ static int __init eeepc_laptop_init(void) | |||
1065 | acpi_bus_unregister_driver(&eeepc_hotk_driver); | 1183 | acpi_bus_unregister_driver(&eeepc_hotk_driver); |
1066 | return -ENODEV; | 1184 | return -ENODEV; |
1067 | } | 1185 | } |
1068 | dev = acpi_get_physical_device(ehotk->device->handle); | ||
1069 | |||
1070 | if (!acpi_video_backlight_support()) { | ||
1071 | result = eeepc_backlight_init(dev); | ||
1072 | if (result) | ||
1073 | goto fail_backlight; | ||
1074 | } else | ||
1075 | printk(EEEPC_INFO "Backlight controlled by ACPI video " | ||
1076 | "driver\n"); | ||
1077 | |||
1078 | result = eeepc_hwmon_init(dev); | ||
1079 | if (result) | ||
1080 | goto fail_hwmon; | ||
1081 | 1186 | ||
1082 | eeepc_enable_camera(); | 1187 | eeepc_enable_camera(); |
1083 | 1188 | ||
@@ -1097,7 +1202,33 @@ static int __init eeepc_laptop_init(void) | |||
1097 | &platform_attribute_group); | 1202 | &platform_attribute_group); |
1098 | if (result) | 1203 | if (result) |
1099 | goto fail_sysfs; | 1204 | goto fail_sysfs; |
1205 | |||
1206 | dev = &platform_device->dev; | ||
1207 | |||
1208 | if (!acpi_video_backlight_support()) { | ||
1209 | result = eeepc_backlight_init(dev); | ||
1210 | if (result) | ||
1211 | goto fail_backlight; | ||
1212 | } else | ||
1213 | pr_info("Backlight controlled by ACPI video " | ||
1214 | "driver\n"); | ||
1215 | |||
1216 | result = eeepc_hwmon_init(dev); | ||
1217 | if (result) | ||
1218 | goto fail_hwmon; | ||
1219 | |||
1220 | result = eeepc_rfkill_init(dev); | ||
1221 | if (result) | ||
1222 | goto fail_rfkill; | ||
1223 | |||
1100 | return 0; | 1224 | return 0; |
1225 | fail_rfkill: | ||
1226 | eeepc_hwmon_exit(); | ||
1227 | fail_hwmon: | ||
1228 | eeepc_backlight_exit(); | ||
1229 | fail_backlight: | ||
1230 | sysfs_remove_group(&platform_device->dev.kobj, | ||
1231 | &platform_attribute_group); | ||
1101 | fail_sysfs: | 1232 | fail_sysfs: |
1102 | platform_device_del(platform_device); | 1233 | platform_device_del(platform_device); |
1103 | fail_platform_device2: | 1234 | fail_platform_device2: |
@@ -1105,12 +1236,7 @@ fail_platform_device2: | |||
1105 | fail_platform_device1: | 1236 | fail_platform_device1: |
1106 | platform_driver_unregister(&platform_driver); | 1237 | platform_driver_unregister(&platform_driver); |
1107 | fail_platform_driver: | 1238 | fail_platform_driver: |
1108 | eeepc_hwmon_exit(); | ||
1109 | fail_hwmon: | ||
1110 | eeepc_backlight_exit(); | ||
1111 | fail_backlight: | ||
1112 | eeepc_input_exit(); | 1239 | eeepc_input_exit(); |
1113 | eeepc_rfkill_exit(); | ||
1114 | return result; | 1240 | return result; |
1115 | } | 1241 | } |
1116 | 1242 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 38bfdb0f6660..3f1045993474 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -550,7 +550,7 @@ static void acm_waker(struct work_struct *waker) | |||
550 | static int acm_tty_open(struct tty_struct *tty, struct file *filp) | 550 | static int acm_tty_open(struct tty_struct *tty, struct file *filp) |
551 | { | 551 | { |
552 | struct acm *acm; | 552 | struct acm *acm; |
553 | int rv = -EINVAL; | 553 | int rv = -ENODEV; |
554 | int i; | 554 | int i; |
555 | dbg("Entering acm_tty_open."); | 555 | dbg("Entering acm_tty_open."); |
556 | 556 | ||
@@ -677,7 +677,7 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
677 | 677 | ||
678 | /* Perform the closing process and see if we need to do the hardware | 678 | /* Perform the closing process and see if we need to do the hardware |
679 | shutdown */ | 679 | shutdown */ |
680 | if (tty_port_close_start(&acm->port, tty, filp) == 0) | 680 | if (!acm || tty_port_close_start(&acm->port, tty, filp) == 0) |
681 | return; | 681 | return; |
682 | acm_port_down(acm, 0); | 682 | acm_port_down(acm, 0); |
683 | tty_port_close_end(&acm->port, tty); | 683 | tty_port_close_end(&acm->port, tty); |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index d595aa5586a7..a84216464ca0 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -333,6 +333,9 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
333 | { | 333 | { |
334 | struct usb_serial_port *port = tty->driver_data; | 334 | struct usb_serial_port *port = tty->driver_data; |
335 | 335 | ||
336 | if (!port) | ||
337 | return; | ||
338 | |||
336 | dbg("%s - port %d", __func__, port->number); | 339 | dbg("%s - port %d", __func__, port->number); |
337 | 340 | ||
338 | 341 | ||
diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c index 1dae7f8f3c6b..51422fc4f606 100644 --- a/drivers/video/backlight/tdo24m.c +++ b/drivers/video/backlight/tdo24m.c | |||
@@ -356,7 +356,7 @@ static int __devinit tdo24m_probe(struct spi_device *spi) | |||
356 | lcd->power = FB_BLANK_POWERDOWN; | 356 | lcd->power = FB_BLANK_POWERDOWN; |
357 | lcd->mode = MODE_VGA; /* default to VGA */ | 357 | lcd->mode = MODE_VGA; /* default to VGA */ |
358 | 358 | ||
359 | lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, sizeof(GFP_KERNEL)); | 359 | lcd->buf = kmalloc(TDO24M_SPI_BUFF_SIZE, GFP_KERNEL); |
360 | if (lcd->buf == NULL) { | 360 | if (lcd->buf == NULL) { |
361 | kfree(lcd); | 361 | kfree(lcd); |
362 | return -ENOMEM; | 362 | return -ENOMEM; |
diff --git a/drivers/watchdog/wdrtas.c b/drivers/watchdog/wdrtas.c index a4fe7a38d9b0..3bde56bce63a 100644 --- a/drivers/watchdog/wdrtas.c +++ b/drivers/watchdog/wdrtas.c | |||
@@ -218,16 +218,14 @@ static void wdrtas_timer_keepalive(void) | |||
218 | */ | 218 | */ |
219 | static int wdrtas_get_temperature(void) | 219 | static int wdrtas_get_temperature(void) |
220 | { | 220 | { |
221 | long result; | 221 | int result; |
222 | int temperature = 0; | 222 | int temperature = 0; |
223 | 223 | ||
224 | result = rtas_call(wdrtas_token_get_sensor_state, 2, 2, | 224 | result = rtas_get_sensor(WDRTAS_THERMAL_SENSOR, 0, &temperature); |
225 | (void *)__pa(&temperature), | ||
226 | WDRTAS_THERMAL_SENSOR, 0); | ||
227 | 225 | ||
228 | if (result < 0) | 226 | if (result < 0) |
229 | printk(KERN_WARNING "wdrtas: reading the thermal sensor " | 227 | printk(KERN_WARNING "wdrtas: reading the thermal sensor " |
230 | "faild: %li\n", result); | 228 | "failed: %i\n", result); |
231 | else | 229 | else |
232 | temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */ | 230 | temperature = ((temperature * 9) / 5) + 32; /* fahrenheit */ |
233 | 231 | ||
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index b48689839428..3a9b7a58a51d 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -5,7 +5,7 @@ client generated ones by default (mount option "serverino" turned | |||
5 | on by default if server supports it). Add forceuid and forcegid | 5 | on by default if server supports it). Add forceuid and forcegid |
6 | mount options (so that when negotiating unix extensions specifying | 6 | mount options (so that when negotiating unix extensions specifying |
7 | which uid mounted does not immediately force the server's reported | 7 | which uid mounted does not immediately force the server's reported |
8 | uids to be overridden). | 8 | uids to be overridden). Add support for scope moutn parm. |
9 | 9 | ||
10 | Version 1.58 | 10 | Version 1.58 |
11 | ------------ | 11 | ------------ |
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index 1b09f1670061..20692fbfdb24 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #define ASN1_OJI 6 /* Object Identifier */ | 49 | #define ASN1_OJI 6 /* Object Identifier */ |
50 | #define ASN1_OJD 7 /* Object Description */ | 50 | #define ASN1_OJD 7 /* Object Description */ |
51 | #define ASN1_EXT 8 /* External */ | 51 | #define ASN1_EXT 8 /* External */ |
52 | #define ASN1_ENUM 10 /* Enumerated */ | ||
52 | #define ASN1_SEQ 16 /* Sequence */ | 53 | #define ASN1_SEQ 16 /* Sequence */ |
53 | #define ASN1_SET 17 /* Set */ | 54 | #define ASN1_SET 17 /* Set */ |
54 | #define ASN1_NUMSTR 18 /* Numerical String */ | 55 | #define ASN1_NUMSTR 18 /* Numerical String */ |
@@ -78,10 +79,12 @@ | |||
78 | #define SPNEGO_OID_LEN 7 | 79 | #define SPNEGO_OID_LEN 7 |
79 | #define NTLMSSP_OID_LEN 10 | 80 | #define NTLMSSP_OID_LEN 10 |
80 | #define KRB5_OID_LEN 7 | 81 | #define KRB5_OID_LEN 7 |
82 | #define KRB5U2U_OID_LEN 8 | ||
81 | #define MSKRB5_OID_LEN 7 | 83 | #define MSKRB5_OID_LEN 7 |
82 | static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; | 84 | static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; |
83 | static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; | 85 | static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; |
84 | static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; | 86 | static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 }; |
87 | static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 }; | ||
85 | static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; | 88 | static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 }; |
86 | 89 | ||
87 | /* | 90 | /* |
@@ -122,6 +125,28 @@ asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch) | |||
122 | return 1; | 125 | return 1; |
123 | } | 126 | } |
124 | 127 | ||
128 | #if 0 /* will be needed later by spnego decoding/encoding of ntlmssp */ | ||
129 | static unsigned char | ||
130 | asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val) | ||
131 | { | ||
132 | unsigned char ch; | ||
133 | |||
134 | if (ctx->pointer >= ctx->end) { | ||
135 | ctx->error = ASN1_ERR_DEC_EMPTY; | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to lenght octet */ | ||
140 | if ((ch) == ASN1_ENUM) /* if ch value is ENUM, 0xa */ | ||
141 | *val = *(++(ctx->pointer)); /* value has enum value */ | ||
142 | else | ||
143 | return 0; | ||
144 | |||
145 | ctx->pointer++; | ||
146 | return 1; | ||
147 | } | ||
148 | #endif | ||
149 | |||
125 | static unsigned char | 150 | static unsigned char |
126 | asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) | 151 | asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag) |
127 | { | 152 | { |
@@ -476,10 +501,9 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
476 | unsigned int cls, con, tag, oidlen, rc; | 501 | unsigned int cls, con, tag, oidlen, rc; |
477 | bool use_ntlmssp = false; | 502 | bool use_ntlmssp = false; |
478 | bool use_kerberos = false; | 503 | bool use_kerberos = false; |
504 | bool use_kerberosu2u = false; | ||
479 | bool use_mskerberos = false; | 505 | bool use_mskerberos = false; |
480 | 506 | ||
481 | *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/ | ||
482 | |||
483 | /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ | 507 | /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ |
484 | 508 | ||
485 | asn1_open(&ctx, security_blob, length); | 509 | asn1_open(&ctx, security_blob, length); |
@@ -515,6 +539,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
515 | return 0; | 539 | return 0; |
516 | } | 540 | } |
517 | 541 | ||
542 | /* SPNEGO */ | ||
518 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 543 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
519 | cFYI(1, ("Error decoding negTokenInit")); | 544 | cFYI(1, ("Error decoding negTokenInit")); |
520 | return 0; | 545 | return 0; |
@@ -526,6 +551,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
526 | return 0; | 551 | return 0; |
527 | } | 552 | } |
528 | 553 | ||
554 | /* negTokenInit */ | ||
529 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 555 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
530 | cFYI(1, ("Error decoding negTokenInit")); | 556 | cFYI(1, ("Error decoding negTokenInit")); |
531 | return 0; | 557 | return 0; |
@@ -537,6 +563,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
537 | return 0; | 563 | return 0; |
538 | } | 564 | } |
539 | 565 | ||
566 | /* sequence */ | ||
540 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 567 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
541 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); | 568 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); |
542 | return 0; | 569 | return 0; |
@@ -548,6 +575,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
548 | return 0; | 575 | return 0; |
549 | } | 576 | } |
550 | 577 | ||
578 | /* sequence of */ | ||
551 | if (asn1_header_decode | 579 | if (asn1_header_decode |
552 | (&ctx, &sequence_end, &cls, &con, &tag) == 0) { | 580 | (&ctx, &sequence_end, &cls, &con, &tag) == 0) { |
553 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); | 581 | cFYI(1, ("Error decoding 2nd part of negTokenInit")); |
@@ -560,6 +588,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
560 | return 0; | 588 | return 0; |
561 | } | 589 | } |
562 | 590 | ||
591 | /* list of security mechanisms */ | ||
563 | while (!asn1_eoc_decode(&ctx, sequence_end)) { | 592 | while (!asn1_eoc_decode(&ctx, sequence_end)) { |
564 | rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); | 593 | rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); |
565 | if (!rc) { | 594 | if (!rc) { |
@@ -576,11 +605,15 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
576 | 605 | ||
577 | if (compare_oid(oid, oidlen, MSKRB5_OID, | 606 | if (compare_oid(oid, oidlen, MSKRB5_OID, |
578 | MSKRB5_OID_LEN) && | 607 | MSKRB5_OID_LEN) && |
579 | !use_kerberos) | 608 | !use_mskerberos) |
580 | use_mskerberos = true; | 609 | use_mskerberos = true; |
610 | else if (compare_oid(oid, oidlen, KRB5U2U_OID, | ||
611 | KRB5U2U_OID_LEN) && | ||
612 | !use_kerberosu2u) | ||
613 | use_kerberosu2u = true; | ||
581 | else if (compare_oid(oid, oidlen, KRB5_OID, | 614 | else if (compare_oid(oid, oidlen, KRB5_OID, |
582 | KRB5_OID_LEN) && | 615 | KRB5_OID_LEN) && |
583 | !use_mskerberos) | 616 | !use_kerberos) |
584 | use_kerberos = true; | 617 | use_kerberos = true; |
585 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, | 618 | else if (compare_oid(oid, oidlen, NTLMSSP_OID, |
586 | NTLMSSP_OID_LEN)) | 619 | NTLMSSP_OID_LEN)) |
@@ -593,7 +626,12 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
593 | } | 626 | } |
594 | } | 627 | } |
595 | 628 | ||
629 | /* mechlistMIC */ | ||
596 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 630 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
631 | /* Check if we have reached the end of the blob, but with | ||
632 | no mechListMic (e.g. NTLMSSP instead of KRB5) */ | ||
633 | if (ctx.error == ASN1_ERR_DEC_EMPTY) | ||
634 | goto decode_negtoken_exit; | ||
597 | cFYI(1, ("Error decoding last part negTokenInit exit3")); | 635 | cFYI(1, ("Error decoding last part negTokenInit exit3")); |
598 | return 0; | 636 | return 0; |
599 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { | 637 | } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { |
@@ -602,6 +640,8 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
602 | cls, con, tag, end, *end)); | 640 | cls, con, tag, end, *end)); |
603 | return 0; | 641 | return 0; |
604 | } | 642 | } |
643 | |||
644 | /* sequence */ | ||
605 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 645 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
606 | cFYI(1, ("Error decoding last part negTokenInit exit5")); | 646 | cFYI(1, ("Error decoding last part negTokenInit exit5")); |
607 | return 0; | 647 | return 0; |
@@ -611,6 +651,7 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
611 | cls, con, tag, end, *end)); | 651 | cls, con, tag, end, *end)); |
612 | } | 652 | } |
613 | 653 | ||
654 | /* sequence of */ | ||
614 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 655 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
615 | cFYI(1, ("Error decoding last part negTokenInit exit 7")); | 656 | cFYI(1, ("Error decoding last part negTokenInit exit 7")); |
616 | return 0; | 657 | return 0; |
@@ -619,6 +660,8 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
619 | cls, con, tag, end, *end)); | 660 | cls, con, tag, end, *end)); |
620 | return 0; | 661 | return 0; |
621 | } | 662 | } |
663 | |||
664 | /* general string */ | ||
622 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 665 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
623 | cFYI(1, ("Error decoding last part negTokenInit exit9")); | 666 | cFYI(1, ("Error decoding last part negTokenInit exit9")); |
624 | return 0; | 667 | return 0; |
@@ -630,13 +673,13 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
630 | } | 673 | } |
631 | cFYI(1, ("Need to call asn1_octets_decode() function for %s", | 674 | cFYI(1, ("Need to call asn1_octets_decode() function for %s", |
632 | ctx.pointer)); /* is this UTF-8 or ASCII? */ | 675 | ctx.pointer)); /* is this UTF-8 or ASCII? */ |
633 | 676 | decode_negtoken_exit: | |
634 | if (use_kerberos) | 677 | if (use_kerberos) |
635 | *secType = Kerberos; | 678 | *secType = Kerberos; |
636 | else if (use_mskerberos) | 679 | else if (use_mskerberos) |
637 | *secType = MSKerberos; | 680 | *secType = MSKerberos; |
638 | else if (use_ntlmssp) | 681 | else if (use_ntlmssp) |
639 | *secType = NTLMSSP; | 682 | *secType = RawNTLMSSP; |
640 | 683 | ||
641 | return 1; | 684 | return 1; |
642 | } | 685 | } |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 0d92114195ab..9f669f982c4d 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -333,6 +333,27 @@ cifs_destroy_inode(struct inode *inode) | |||
333 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); | 333 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); |
334 | } | 334 | } |
335 | 335 | ||
336 | static void | ||
337 | cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) | ||
338 | { | ||
339 | seq_printf(s, ",addr="); | ||
340 | |||
341 | switch (server->addr.sockAddr.sin_family) { | ||
342 | case AF_INET: | ||
343 | seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr); | ||
344 | break; | ||
345 | case AF_INET6: | ||
346 | seq_printf(s, "%pI6", | ||
347 | &server->addr.sockAddr6.sin6_addr.s6_addr); | ||
348 | if (server->addr.sockAddr6.sin6_scope_id) | ||
349 | seq_printf(s, "%%%u", | ||
350 | server->addr.sockAddr6.sin6_scope_id); | ||
351 | break; | ||
352 | default: | ||
353 | seq_printf(s, "(unknown)"); | ||
354 | } | ||
355 | } | ||
356 | |||
336 | /* | 357 | /* |
337 | * cifs_show_options() is for displaying mount options in /proc/mounts. | 358 | * cifs_show_options() is for displaying mount options in /proc/mounts. |
338 | * Not all settable options are displayed but most of the important | 359 | * Not all settable options are displayed but most of the important |
@@ -343,83 +364,64 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
343 | { | 364 | { |
344 | struct cifs_sb_info *cifs_sb; | 365 | struct cifs_sb_info *cifs_sb; |
345 | struct cifsTconInfo *tcon; | 366 | struct cifsTconInfo *tcon; |
346 | struct TCP_Server_Info *server; | ||
347 | 367 | ||
348 | cifs_sb = CIFS_SB(m->mnt_sb); | 368 | cifs_sb = CIFS_SB(m->mnt_sb); |
369 | tcon = cifs_sb->tcon; | ||
349 | 370 | ||
350 | if (cifs_sb) { | 371 | seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName); |
351 | tcon = cifs_sb->tcon; | 372 | if (tcon->ses->userName) |
352 | if (tcon) { | 373 | seq_printf(s, ",username=%s", tcon->ses->userName); |
353 | seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName); | 374 | if (tcon->ses->domainName) |
354 | if (tcon->ses) { | 375 | seq_printf(s, ",domain=%s", tcon->ses->domainName); |
355 | if (tcon->ses->userName) | 376 | |
356 | seq_printf(s, ",username=%s", | 377 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); |
357 | tcon->ses->userName); | 378 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
358 | if (tcon->ses->domainName) | 379 | seq_printf(s, ",forceuid"); |
359 | seq_printf(s, ",domain=%s", | 380 | |
360 | tcon->ses->domainName); | 381 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); |
361 | server = tcon->ses->server; | 382 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) |
362 | if (server) { | 383 | seq_printf(s, ",forcegid"); |
363 | seq_printf(s, ",addr="); | 384 | |
364 | switch (server->addr.sockAddr6. | 385 | cifs_show_address(s, tcon->ses->server); |
365 | sin6_family) { | 386 | |
366 | case AF_INET6: | 387 | if (!tcon->unix_ext) |
367 | seq_printf(s, "%pI6", | 388 | seq_printf(s, ",file_mode=0%o,dir_mode=0%o", |
368 | &server->addr.sockAddr6.sin6_addr); | ||
369 | break; | ||
370 | case AF_INET: | ||
371 | seq_printf(s, "%pI4", | ||
372 | &server->addr.sockAddr.sin_addr.s_addr); | ||
373 | break; | ||
374 | } | ||
375 | } | ||
376 | } | ||
377 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || | ||
378 | !(tcon->unix_ext)) | ||
379 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | ||
380 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || | ||
381 | !(tcon->unix_ext)) | ||
382 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); | ||
383 | if (!tcon->unix_ext) { | ||
384 | seq_printf(s, ",file_mode=0%o,dir_mode=0%o", | ||
385 | cifs_sb->mnt_file_mode, | 389 | cifs_sb->mnt_file_mode, |
386 | cifs_sb->mnt_dir_mode); | 390 | cifs_sb->mnt_dir_mode); |
387 | } | 391 | if (tcon->seal) |
388 | if (tcon->seal) | 392 | seq_printf(s, ",seal"); |
389 | seq_printf(s, ",seal"); | 393 | if (tcon->nocase) |
390 | if (tcon->nocase) | 394 | seq_printf(s, ",nocase"); |
391 | seq_printf(s, ",nocase"); | 395 | if (tcon->retry) |
392 | if (tcon->retry) | 396 | seq_printf(s, ",hard"); |
393 | seq_printf(s, ",hard"); | 397 | if (cifs_sb->prepath) |
394 | } | 398 | seq_printf(s, ",prepath=%s", cifs_sb->prepath); |
395 | if (cifs_sb->prepath) | 399 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) |
396 | seq_printf(s, ",prepath=%s", cifs_sb->prepath); | 400 | seq_printf(s, ",posixpaths"); |
397 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) | 401 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) |
398 | seq_printf(s, ",posixpaths"); | 402 | seq_printf(s, ",setuids"); |
399 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) | 403 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) |
400 | seq_printf(s, ",setuids"); | 404 | seq_printf(s, ",serverino"); |
401 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) | 405 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) |
402 | seq_printf(s, ",serverino"); | 406 | seq_printf(s, ",directio"); |
403 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | 407 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) |
404 | seq_printf(s, ",directio"); | 408 | seq_printf(s, ",nouser_xattr"); |
405 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) | 409 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) |
406 | seq_printf(s, ",nouser_xattr"); | 410 | seq_printf(s, ",mapchars"); |
407 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) | 411 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) |
408 | seq_printf(s, ",mapchars"); | 412 | seq_printf(s, ",sfu"); |
409 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) | 413 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) |
410 | seq_printf(s, ",sfu"); | 414 | seq_printf(s, ",nobrl"); |
411 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) | 415 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) |
412 | seq_printf(s, ",nobrl"); | 416 | seq_printf(s, ",cifsacl"); |
413 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) | 417 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
414 | seq_printf(s, ",cifsacl"); | 418 | seq_printf(s, ",dynperm"); |
415 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | 419 | if (m->mnt_sb->s_flags & MS_POSIXACL) |
416 | seq_printf(s, ",dynperm"); | 420 | seq_printf(s, ",acl"); |
417 | if (m->mnt_sb->s_flags & MS_POSIXACL) | 421 | |
418 | seq_printf(s, ",acl"); | 422 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); |
419 | 423 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); | |
420 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); | 424 | |
421 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); | ||
422 | } | ||
423 | return 0; | 425 | return 0; |
424 | } | 426 | } |
425 | 427 | ||
@@ -535,9 +537,14 @@ static void cifs_umount_begin(struct super_block *sb) | |||
535 | if (tcon == NULL) | 537 | if (tcon == NULL) |
536 | return; | 538 | return; |
537 | 539 | ||
538 | lock_kernel(); | ||
539 | read_lock(&cifs_tcp_ses_lock); | 540 | read_lock(&cifs_tcp_ses_lock); |
540 | if (tcon->tc_count == 1) | 541 | if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) { |
542 | /* we have other mounts to same share or we have | ||
543 | already tried to force umount this and woken up | ||
544 | all waiting network requests, nothing to do */ | ||
545 | read_unlock(&cifs_tcp_ses_lock); | ||
546 | return; | ||
547 | } else if (tcon->tc_count == 1) | ||
541 | tcon->tidStatus = CifsExiting; | 548 | tcon->tidStatus = CifsExiting; |
542 | read_unlock(&cifs_tcp_ses_lock); | 549 | read_unlock(&cifs_tcp_ses_lock); |
543 | 550 | ||
@@ -552,9 +559,7 @@ static void cifs_umount_begin(struct super_block *sb) | |||
552 | wake_up_all(&tcon->ses->server->response_q); | 559 | wake_up_all(&tcon->ses->server->response_q); |
553 | msleep(1); | 560 | msleep(1); |
554 | } | 561 | } |
555 | /* BB FIXME - finish add checks for tidStatus BB */ | ||
556 | 562 | ||
557 | unlock_kernel(); | ||
558 | return; | 563 | return; |
559 | } | 564 | } |
560 | 565 | ||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a61ab772c6f6..e1225e6ded2f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -83,7 +83,7 @@ enum securityEnum { | |||
83 | NTLM, /* Legacy NTLM012 auth with NTLM hash */ | 83 | NTLM, /* Legacy NTLM012 auth with NTLM hash */ |
84 | NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ | 84 | NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ |
85 | RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */ | 85 | RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */ |
86 | NTLMSSP, /* NTLMSSP via SPNEGO, NTLMv2 hash */ | 86 | /* NTLMSSP, */ /* can use rawNTLMSSP instead of NTLMSSP via SPNEGO */ |
87 | Kerberos, /* Kerberos via SPNEGO */ | 87 | Kerberos, /* Kerberos via SPNEGO */ |
88 | MSKerberos, /* MS Kerberos via SPNEGO */ | 88 | MSKerberos, /* MS Kerberos via SPNEGO */ |
89 | }; | 89 | }; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index f9452329bcce..c419416a42ee 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -74,7 +74,7 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr); | |||
74 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); | 74 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); |
75 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 75 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
76 | enum securityEnum *secType); | 76 | enum securityEnum *secType); |
77 | extern int cifs_inet_pton(const int, const char *source, void *dst); | 77 | extern int cifs_convert_address(char *src, void *dst); |
78 | extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); | 78 | extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); |
79 | extern void header_assemble(struct smb_hdr *, char /* command */ , | 79 | extern void header_assemble(struct smb_hdr *, char /* command */ , |
80 | const struct cifsTconInfo *, int /* length of | 80 | const struct cifsTconInfo *, int /* length of |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index b84c61d5bca4..61007c627497 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -594,7 +594,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
594 | else if (secFlags & CIFSSEC_MAY_KRB5) | 594 | else if (secFlags & CIFSSEC_MAY_KRB5) |
595 | server->secType = Kerberos; | 595 | server->secType = Kerberos; |
596 | else if (secFlags & CIFSSEC_MAY_NTLMSSP) | 596 | else if (secFlags & CIFSSEC_MAY_NTLMSSP) |
597 | server->secType = NTLMSSP; | 597 | server->secType = RawNTLMSSP; |
598 | else if (secFlags & CIFSSEC_MAY_LANMAN) | 598 | else if (secFlags & CIFSSEC_MAY_LANMAN) |
599 | server->secType = LANMAN; | 599 | server->secType = LANMAN; |
600 | /* #ifdef CONFIG_CIFS_EXPERIMENTAL | 600 | /* #ifdef CONFIG_CIFS_EXPERIMENTAL |
@@ -729,7 +729,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) | |||
729 | * the tcon is no longer on the list, so no need to take lock before | 729 | * the tcon is no longer on the list, so no need to take lock before |
730 | * checking this. | 730 | * checking this. |
731 | */ | 731 | */ |
732 | if (tcon->need_reconnect) | 732 | if ((tcon->need_reconnect) || (tcon->ses->need_reconnect)) |
733 | return 0; | 733 | return 0; |
734 | 734 | ||
735 | rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, | 735 | rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 97f4311b9a8e..e16d7592116a 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -70,7 +70,6 @@ struct smb_vol { | |||
70 | mode_t file_mode; | 70 | mode_t file_mode; |
71 | mode_t dir_mode; | 71 | mode_t dir_mode; |
72 | unsigned secFlg; | 72 | unsigned secFlg; |
73 | bool rw:1; | ||
74 | bool retry:1; | 73 | bool retry:1; |
75 | bool intr:1; | 74 | bool intr:1; |
76 | bool setuids:1; | 75 | bool setuids:1; |
@@ -832,7 +831,6 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
832 | vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; | 831 | vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR; |
833 | 832 | ||
834 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ | 833 | /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ |
835 | vol->rw = true; | ||
836 | /* default is always to request posix paths. */ | 834 | /* default is always to request posix paths. */ |
837 | vol->posix_paths = 1; | 835 | vol->posix_paths = 1; |
838 | /* default to using server inode numbers where available */ | 836 | /* default to using server inode numbers where available */ |
@@ -1199,7 +1197,9 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1199 | } else if (strnicmp(data, "guest", 5) == 0) { | 1197 | } else if (strnicmp(data, "guest", 5) == 0) { |
1200 | /* ignore */ | 1198 | /* ignore */ |
1201 | } else if (strnicmp(data, "rw", 2) == 0) { | 1199 | } else if (strnicmp(data, "rw", 2) == 0) { |
1202 | vol->rw = true; | 1200 | /* ignore */ |
1201 | } else if (strnicmp(data, "ro", 2) == 0) { | ||
1202 | /* ignore */ | ||
1203 | } else if (strnicmp(data, "noblocksend", 11) == 0) { | 1203 | } else if (strnicmp(data, "noblocksend", 11) == 0) { |
1204 | vol->noblocksnd = 1; | 1204 | vol->noblocksnd = 1; |
1205 | } else if (strnicmp(data, "noautotune", 10) == 0) { | 1205 | } else if (strnicmp(data, "noautotune", 10) == 0) { |
@@ -1218,8 +1218,6 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1218 | parse these options again and set anything and it | 1218 | parse these options again and set anything and it |
1219 | is ok to just ignore them */ | 1219 | is ok to just ignore them */ |
1220 | continue; | 1220 | continue; |
1221 | } else if (strnicmp(data, "ro", 2) == 0) { | ||
1222 | vol->rw = false; | ||
1223 | } else if (strnicmp(data, "hard", 4) == 0) { | 1221 | } else if (strnicmp(data, "hard", 4) == 0) { |
1224 | vol->retry = 1; | 1222 | vol->retry = 1; |
1225 | } else if (strnicmp(data, "soft", 4) == 0) { | 1223 | } else if (strnicmp(data, "soft", 4) == 0) { |
@@ -1386,8 +1384,10 @@ cifs_find_tcp_session(struct sockaddr_storage *addr) | |||
1386 | server->addr.sockAddr.sin_addr.s_addr)) | 1384 | server->addr.sockAddr.sin_addr.s_addr)) |
1387 | continue; | 1385 | continue; |
1388 | else if (addr->ss_family == AF_INET6 && | 1386 | else if (addr->ss_family == AF_INET6 && |
1389 | !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, | 1387 | (!ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr, |
1390 | &addr6->sin6_addr)) | 1388 | &addr6->sin6_addr) || |
1389 | server->addr.sockAddr6.sin6_scope_id != | ||
1390 | addr6->sin6_scope_id)) | ||
1391 | continue; | 1391 | continue; |
1392 | 1392 | ||
1393 | ++server->srv_count; | 1393 | ++server->srv_count; |
@@ -1433,28 +1433,15 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
1433 | 1433 | ||
1434 | memset(&addr, 0, sizeof(struct sockaddr_storage)); | 1434 | memset(&addr, 0, sizeof(struct sockaddr_storage)); |
1435 | 1435 | ||
1436 | if (volume_info->UNCip && volume_info->UNC) { | 1436 | cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip)); |
1437 | rc = cifs_inet_pton(AF_INET, volume_info->UNCip, | ||
1438 | &sin_server->sin_addr.s_addr); | ||
1439 | |||
1440 | if (rc <= 0) { | ||
1441 | /* not ipv4 address, try ipv6 */ | ||
1442 | rc = cifs_inet_pton(AF_INET6, volume_info->UNCip, | ||
1443 | &sin_server6->sin6_addr.in6_u); | ||
1444 | if (rc > 0) | ||
1445 | addr.ss_family = AF_INET6; | ||
1446 | } else { | ||
1447 | addr.ss_family = AF_INET; | ||
1448 | } | ||
1449 | 1437 | ||
1450 | if (rc <= 0) { | 1438 | if (volume_info->UNCip && volume_info->UNC) { |
1439 | rc = cifs_convert_address(volume_info->UNCip, &addr); | ||
1440 | if (!rc) { | ||
1451 | /* we failed translating address */ | 1441 | /* we failed translating address */ |
1452 | rc = -EINVAL; | 1442 | rc = -EINVAL; |
1453 | goto out_err; | 1443 | goto out_err; |
1454 | } | 1444 | } |
1455 | |||
1456 | cFYI(1, ("UNC: %s ip: %s", volume_info->UNC, | ||
1457 | volume_info->UNCip)); | ||
1458 | } else if (volume_info->UNCip) { | 1445 | } else if (volume_info->UNCip) { |
1459 | /* BB using ip addr as tcp_ses name to connect to the | 1446 | /* BB using ip addr as tcp_ses name to connect to the |
1460 | DFS root below */ | 1447 | DFS root below */ |
@@ -1513,14 +1500,14 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
1513 | cFYI(1, ("attempting ipv6 connect")); | 1500 | cFYI(1, ("attempting ipv6 connect")); |
1514 | /* BB should we allow ipv6 on port 139? */ | 1501 | /* BB should we allow ipv6 on port 139? */ |
1515 | /* other OS never observed in Wild doing 139 with v6 */ | 1502 | /* other OS never observed in Wild doing 139 with v6 */ |
1503 | sin_server6->sin6_port = htons(volume_info->port); | ||
1516 | memcpy(&tcp_ses->addr.sockAddr6, sin_server6, | 1504 | memcpy(&tcp_ses->addr.sockAddr6, sin_server6, |
1517 | sizeof(struct sockaddr_in6)); | 1505 | sizeof(struct sockaddr_in6)); |
1518 | sin_server6->sin6_port = htons(volume_info->port); | ||
1519 | rc = ipv6_connect(tcp_ses); | 1506 | rc = ipv6_connect(tcp_ses); |
1520 | } else { | 1507 | } else { |
1508 | sin_server->sin_port = htons(volume_info->port); | ||
1521 | memcpy(&tcp_ses->addr.sockAddr, sin_server, | 1509 | memcpy(&tcp_ses->addr.sockAddr, sin_server, |
1522 | sizeof(struct sockaddr_in)); | 1510 | sizeof(struct sockaddr_in)); |
1523 | sin_server->sin_port = htons(volume_info->port); | ||
1524 | rc = ipv4_connect(tcp_ses); | 1511 | rc = ipv4_connect(tcp_ses); |
1525 | } | 1512 | } |
1526 | if (rc < 0) { | 1513 | if (rc < 0) { |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 3758965d73d5..7dc6b74f9def 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -307,8 +307,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
307 | 307 | ||
308 | full_path = build_path_from_dentry(direntry); | 308 | full_path = build_path_from_dentry(direntry); |
309 | if (full_path == NULL) { | 309 | if (full_path == NULL) { |
310 | rc = -ENOMEM; | ||
310 | FreeXid(xid); | 311 | FreeXid(xid); |
311 | return -ENOMEM; | 312 | return rc; |
312 | } | 313 | } |
313 | 314 | ||
314 | if (oplockEnabled) | 315 | if (oplockEnabled) |
@@ -540,8 +541,9 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
540 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); | 541 | buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
541 | if (buf == NULL) { | 542 | if (buf == NULL) { |
542 | kfree(full_path); | 543 | kfree(full_path); |
544 | rc = -ENOMEM; | ||
543 | FreeXid(xid); | 545 | FreeXid(xid); |
544 | return -ENOMEM; | 546 | return rc; |
545 | } | 547 | } |
546 | 548 | ||
547 | rc = CIFSSMBOpen(xid, pTcon, full_path, | 549 | rc = CIFSSMBOpen(xid, pTcon, full_path, |
diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c index df4a306f697e..87948147d7ec 100644 --- a/fs/cifs/dns_resolve.c +++ b/fs/cifs/dns_resolve.c | |||
@@ -35,26 +35,11 @@ | |||
35 | * 0 - name is not IP | 35 | * 0 - name is not IP |
36 | */ | 36 | */ |
37 | static int | 37 | static int |
38 | is_ip(const char *name) | 38 | is_ip(char *name) |
39 | { | 39 | { |
40 | int rc; | 40 | struct sockaddr_storage ss; |
41 | struct sockaddr_in sin_server; | 41 | |
42 | struct sockaddr_in6 sin_server6; | 42 | return cifs_convert_address(name, &ss); |
43 | |||
44 | rc = cifs_inet_pton(AF_INET, name, | ||
45 | &sin_server.sin_addr.s_addr); | ||
46 | |||
47 | if (rc <= 0) { | ||
48 | /* not ipv4 address, try ipv6 */ | ||
49 | rc = cifs_inet_pton(AF_INET6, name, | ||
50 | &sin_server6.sin6_addr.in6_u); | ||
51 | if (rc > 0) | ||
52 | return 1; | ||
53 | } else { | ||
54 | return 1; | ||
55 | } | ||
56 | /* we failed translating address */ | ||
57 | return 0; | ||
58 | } | 43 | } |
59 | 44 | ||
60 | static int | 45 | static int |
@@ -72,7 +57,7 @@ dns_resolver_instantiate(struct key *key, const void *data, | |||
72 | ip[datalen] = '\0'; | 57 | ip[datalen] = '\0'; |
73 | 58 | ||
74 | /* make sure this looks like an address */ | 59 | /* make sure this looks like an address */ |
75 | if (!is_ip((const char *) ip)) { | 60 | if (!is_ip(ip)) { |
76 | kfree(ip); | 61 | kfree(ip); |
77 | return -EINVAL; | 62 | return -EINVAL; |
78 | } | 63 | } |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 06866841b97f..97ce4bf89d15 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -300,14 +300,16 @@ int cifs_open(struct inode *inode, struct file *file) | |||
300 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); | 300 | pCifsInode = CIFS_I(file->f_path.dentry->d_inode); |
301 | pCifsFile = cifs_fill_filedata(file); | 301 | pCifsFile = cifs_fill_filedata(file); |
302 | if (pCifsFile) { | 302 | if (pCifsFile) { |
303 | rc = 0; | ||
303 | FreeXid(xid); | 304 | FreeXid(xid); |
304 | return 0; | 305 | return rc; |
305 | } | 306 | } |
306 | 307 | ||
307 | full_path = build_path_from_dentry(file->f_path.dentry); | 308 | full_path = build_path_from_dentry(file->f_path.dentry); |
308 | if (full_path == NULL) { | 309 | if (full_path == NULL) { |
310 | rc = -ENOMEM; | ||
309 | FreeXid(xid); | 311 | FreeXid(xid); |
310 | return -ENOMEM; | 312 | return rc; |
311 | } | 313 | } |
312 | 314 | ||
313 | cFYI(1, ("inode = 0x%p file flags are 0x%x for %s", | 315 | cFYI(1, ("inode = 0x%p file flags are 0x%x for %s", |
@@ -491,11 +493,12 @@ static int cifs_reopen_file(struct file *file, bool can_flush) | |||
491 | return -EBADF; | 493 | return -EBADF; |
492 | 494 | ||
493 | xid = GetXid(); | 495 | xid = GetXid(); |
494 | mutex_unlock(&pCifsFile->fh_mutex); | 496 | mutex_lock(&pCifsFile->fh_mutex); |
495 | if (!pCifsFile->invalidHandle) { | 497 | if (!pCifsFile->invalidHandle) { |
496 | mutex_lock(&pCifsFile->fh_mutex); | 498 | mutex_unlock(&pCifsFile->fh_mutex); |
499 | rc = 0; | ||
497 | FreeXid(xid); | 500 | FreeXid(xid); |
498 | return 0; | 501 | return rc; |
499 | } | 502 | } |
500 | 503 | ||
501 | if (file->f_path.dentry == NULL) { | 504 | if (file->f_path.dentry == NULL) { |
@@ -524,7 +527,7 @@ static int cifs_reopen_file(struct file *file, bool can_flush) | |||
524 | if (full_path == NULL) { | 527 | if (full_path == NULL) { |
525 | rc = -ENOMEM; | 528 | rc = -ENOMEM; |
526 | reopen_error_exit: | 529 | reopen_error_exit: |
527 | mutex_lock(&pCifsFile->fh_mutex); | 530 | mutex_unlock(&pCifsFile->fh_mutex); |
528 | FreeXid(xid); | 531 | FreeXid(xid); |
529 | return rc; | 532 | return rc; |
530 | } | 533 | } |
@@ -566,14 +569,14 @@ reopen_error_exit: | |||
566 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | 569 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
567 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 570 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
568 | if (rc) { | 571 | if (rc) { |
569 | mutex_lock(&pCifsFile->fh_mutex); | 572 | mutex_unlock(&pCifsFile->fh_mutex); |
570 | cFYI(1, ("cifs_open returned 0x%x", rc)); | 573 | cFYI(1, ("cifs_open returned 0x%x", rc)); |
571 | cFYI(1, ("oplock: %d", oplock)); | 574 | cFYI(1, ("oplock: %d", oplock)); |
572 | } else { | 575 | } else { |
573 | reopen_success: | 576 | reopen_success: |
574 | pCifsFile->netfid = netfid; | 577 | pCifsFile->netfid = netfid; |
575 | pCifsFile->invalidHandle = false; | 578 | pCifsFile->invalidHandle = false; |
576 | mutex_lock(&pCifsFile->fh_mutex); | 579 | mutex_unlock(&pCifsFile->fh_mutex); |
577 | pCifsInode = CIFS_I(inode); | 580 | pCifsInode = CIFS_I(inode); |
578 | if (pCifsInode) { | 581 | if (pCifsInode) { |
579 | if (can_flush) { | 582 | if (can_flush) { |
@@ -845,8 +848,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
845 | tcon = cifs_sb->tcon; | 848 | tcon = cifs_sb->tcon; |
846 | 849 | ||
847 | if (file->private_data == NULL) { | 850 | if (file->private_data == NULL) { |
851 | rc = -EBADF; | ||
848 | FreeXid(xid); | 852 | FreeXid(xid); |
849 | return -EBADF; | 853 | return rc; |
850 | } | 854 | } |
851 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; | 855 | netfid = ((struct cifsFileInfo *)file->private_data)->netfid; |
852 | 856 | ||
@@ -1805,8 +1809,9 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data, | |||
1805 | pTcon = cifs_sb->tcon; | 1809 | pTcon = cifs_sb->tcon; |
1806 | 1810 | ||
1807 | if (file->private_data == NULL) { | 1811 | if (file->private_data == NULL) { |
1812 | rc = -EBADF; | ||
1808 | FreeXid(xid); | 1813 | FreeXid(xid); |
1809 | return -EBADF; | 1814 | return rc; |
1810 | } | 1815 | } |
1811 | open_file = (struct cifsFileInfo *)file->private_data; | 1816 | open_file = (struct cifsFileInfo *)file->private_data; |
1812 | 1817 | ||
@@ -1885,8 +1890,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size, | |||
1885 | pTcon = cifs_sb->tcon; | 1890 | pTcon = cifs_sb->tcon; |
1886 | 1891 | ||
1887 | if (file->private_data == NULL) { | 1892 | if (file->private_data == NULL) { |
1893 | rc = -EBADF; | ||
1888 | FreeXid(xid); | 1894 | FreeXid(xid); |
1889 | return -EBADF; | 1895 | return rc; |
1890 | } | 1896 | } |
1891 | open_file = (struct cifsFileInfo *)file->private_data; | 1897 | open_file = (struct cifsFileInfo *)file->private_data; |
1892 | 1898 | ||
@@ -2019,8 +2025,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
2019 | 2025 | ||
2020 | xid = GetXid(); | 2026 | xid = GetXid(); |
2021 | if (file->private_data == NULL) { | 2027 | if (file->private_data == NULL) { |
2028 | rc = -EBADF; | ||
2022 | FreeXid(xid); | 2029 | FreeXid(xid); |
2023 | return -EBADF; | 2030 | return rc; |
2024 | } | 2031 | } |
2025 | open_file = (struct cifsFileInfo *)file->private_data; | 2032 | open_file = (struct cifsFileInfo *)file->private_data; |
2026 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); | 2033 | cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
@@ -2185,8 +2192,9 @@ static int cifs_readpage(struct file *file, struct page *page) | |||
2185 | xid = GetXid(); | 2192 | xid = GetXid(); |
2186 | 2193 | ||
2187 | if (file->private_data == NULL) { | 2194 | if (file->private_data == NULL) { |
2195 | rc = -EBADF; | ||
2188 | FreeXid(xid); | 2196 | FreeXid(xid); |
2189 | return -EBADF; | 2197 | return rc; |
2190 | } | 2198 | } |
2191 | 2199 | ||
2192 | cFYI(1, ("readpage %p at offset %d 0x%x\n", | 2200 | cFYI(1, ("readpage %p at offset %d 0x%x\n", |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index fad882b075ba..155c9e785d0c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -988,8 +988,9 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry) | |||
988 | * sb->s_vfs_rename_mutex here */ | 988 | * sb->s_vfs_rename_mutex here */ |
989 | full_path = build_path_from_dentry(dentry); | 989 | full_path = build_path_from_dentry(dentry); |
990 | if (full_path == NULL) { | 990 | if (full_path == NULL) { |
991 | rc = -ENOMEM; | ||
991 | FreeXid(xid); | 992 | FreeXid(xid); |
992 | return -ENOMEM; | 993 | return rc; |
993 | } | 994 | } |
994 | 995 | ||
995 | if ((tcon->ses->capabilities & CAP_UNIX) && | 996 | if ((tcon->ses->capabilities & CAP_UNIX) && |
@@ -1118,8 +1119,9 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
1118 | 1119 | ||
1119 | full_path = build_path_from_dentry(direntry); | 1120 | full_path = build_path_from_dentry(direntry); |
1120 | if (full_path == NULL) { | 1121 | if (full_path == NULL) { |
1122 | rc = -ENOMEM; | ||
1121 | FreeXid(xid); | 1123 | FreeXid(xid); |
1122 | return -ENOMEM; | 1124 | return rc; |
1123 | } | 1125 | } |
1124 | 1126 | ||
1125 | if ((pTcon->ses->capabilities & CAP_UNIX) && | 1127 | if ((pTcon->ses->capabilities & CAP_UNIX) && |
@@ -1303,8 +1305,9 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1303 | 1305 | ||
1304 | full_path = build_path_from_dentry(direntry); | 1306 | full_path = build_path_from_dentry(direntry); |
1305 | if (full_path == NULL) { | 1307 | if (full_path == NULL) { |
1308 | rc = -ENOMEM; | ||
1306 | FreeXid(xid); | 1309 | FreeXid(xid); |
1307 | return -ENOMEM; | 1310 | return rc; |
1308 | } | 1311 | } |
1309 | 1312 | ||
1310 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, | 1313 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, |
@@ -1508,8 +1511,9 @@ int cifs_revalidate(struct dentry *direntry) | |||
1508 | since that would deadlock */ | 1511 | since that would deadlock */ |
1509 | full_path = build_path_from_dentry(direntry); | 1512 | full_path = build_path_from_dentry(direntry); |
1510 | if (full_path == NULL) { | 1513 | if (full_path == NULL) { |
1514 | rc = -ENOMEM; | ||
1511 | FreeXid(xid); | 1515 | FreeXid(xid); |
1512 | return -ENOMEM; | 1516 | return rc; |
1513 | } | 1517 | } |
1514 | cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " | 1518 | cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld " |
1515 | "jiffies %ld", full_path, direntry->d_inode, | 1519 | "jiffies %ld", full_path, direntry->d_inode, |
@@ -1911,8 +1915,9 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
1911 | 1915 | ||
1912 | full_path = build_path_from_dentry(direntry); | 1916 | full_path = build_path_from_dentry(direntry); |
1913 | if (full_path == NULL) { | 1917 | if (full_path == NULL) { |
1918 | rc = -ENOMEM; | ||
1914 | FreeXid(xid); | 1919 | FreeXid(xid); |
1915 | return -ENOMEM; | 1920 | return rc; |
1916 | } | 1921 | } |
1917 | 1922 | ||
1918 | /* | 1923 | /* |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index cd83c53fcbb5..fc1e0487eaee 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -172,8 +172,9 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) | |||
172 | full_path = build_path_from_dentry(direntry); | 172 | full_path = build_path_from_dentry(direntry); |
173 | 173 | ||
174 | if (full_path == NULL) { | 174 | if (full_path == NULL) { |
175 | rc = -ENOMEM; | ||
175 | FreeXid(xid); | 176 | FreeXid(xid); |
176 | return -ENOMEM; | 177 | return rc; |
177 | } | 178 | } |
178 | 179 | ||
179 | cFYI(1, ("Full path: %s", full_path)); | 180 | cFYI(1, ("Full path: %s", full_path)); |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 32d6baa0a54f..bd6d6895730d 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -133,10 +133,12 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = { | |||
133 | {0, 0} | 133 | {0, 0} |
134 | }; | 134 | }; |
135 | 135 | ||
136 | /* Convert string containing dotted ip address to binary form */ | 136 | /* |
137 | /* returns 0 if invalid address */ | 137 | * Convert a string containing text IPv4 or IPv6 address to binary form. |
138 | 138 | * | |
139 | int | 139 | * Returns 0 on failure. |
140 | */ | ||
141 | static int | ||
140 | cifs_inet_pton(const int address_family, const char *cp, void *dst) | 142 | cifs_inet_pton(const int address_family, const char *cp, void *dst) |
141 | { | 143 | { |
142 | int ret = 0; | 144 | int ret = 0; |
@@ -153,6 +155,52 @@ cifs_inet_pton(const int address_family, const char *cp, void *dst) | |||
153 | return ret; | 155 | return ret; |
154 | } | 156 | } |
155 | 157 | ||
158 | /* | ||
159 | * Try to convert a string to an IPv4 address and then attempt to convert | ||
160 | * it to an IPv6 address if that fails. Set the family field if either | ||
161 | * succeeds. If it's an IPv6 address and it has a '%' sign in it, try to | ||
162 | * treat the part following it as a numeric sin6_scope_id. | ||
163 | * | ||
164 | * Returns 0 on failure. | ||
165 | */ | ||
166 | int | ||
167 | cifs_convert_address(char *src, void *dst) | ||
168 | { | ||
169 | int rc; | ||
170 | char *pct, *endp; | ||
171 | struct sockaddr_in *s4 = (struct sockaddr_in *) dst; | ||
172 | struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) dst; | ||
173 | |||
174 | /* IPv4 address */ | ||
175 | if (cifs_inet_pton(AF_INET, src, &s4->sin_addr.s_addr)) { | ||
176 | s4->sin_family = AF_INET; | ||
177 | return 1; | ||
178 | } | ||
179 | |||
180 | /* temporarily terminate string */ | ||
181 | pct = strchr(src, '%'); | ||
182 | if (pct) | ||
183 | *pct = '\0'; | ||
184 | |||
185 | rc = cifs_inet_pton(AF_INET6, src, &s6->sin6_addr.s6_addr); | ||
186 | |||
187 | /* repair temp termination (if any) and make pct point to scopeid */ | ||
188 | if (pct) | ||
189 | *pct++ = '%'; | ||
190 | |||
191 | if (!rc) | ||
192 | return rc; | ||
193 | |||
194 | s6->sin6_family = AF_INET6; | ||
195 | if (pct) { | ||
196 | s6->sin6_scope_id = (u32) simple_strtoul(pct, &endp, 0); | ||
197 | if (!*pct || *endp) | ||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | return rc; | ||
202 | } | ||
203 | |||
156 | /***************************************************************************** | 204 | /***************************************************************************** |
157 | convert a NT status code to a dos class/code | 205 | convert a NT status code to a dos class/code |
158 | *****************************************************************************/ | 206 | *****************************************************************************/ |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 897a052270f9..7085a6275c4c 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -802,7 +802,7 @@ ssetup_ntlmssp_authenticate: | |||
802 | #endif /* CONFIG_CIFS_UPCALL */ | 802 | #endif /* CONFIG_CIFS_UPCALL */ |
803 | } else { | 803 | } else { |
804 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 804 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
805 | if ((experimEnabled > 1) && (type == RawNTLMSSP)) { | 805 | if (type == RawNTLMSSP) { |
806 | if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { | 806 | if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { |
807 | cERROR(1, ("NTLMSSP requires Unicode support")); | 807 | cERROR(1, ("NTLMSSP requires Unicode support")); |
808 | rc = -ENOSYS; | 808 | rc = -ENOSYS; |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index e9527eedc639..a75afa3dd9e1 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -64,8 +64,9 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name) | |||
64 | 64 | ||
65 | full_path = build_path_from_dentry(direntry); | 65 | full_path = build_path_from_dentry(direntry); |
66 | if (full_path == NULL) { | 66 | if (full_path == NULL) { |
67 | rc = -ENOMEM; | ||
67 | FreeXid(xid); | 68 | FreeXid(xid); |
68 | return -ENOMEM; | 69 | return rc; |
69 | } | 70 | } |
70 | if (ea_name == NULL) { | 71 | if (ea_name == NULL) { |
71 | cFYI(1, ("Null xattr names not supported")); | 72 | cFYI(1, ("Null xattr names not supported")); |
@@ -118,8 +119,9 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, | |||
118 | 119 | ||
119 | full_path = build_path_from_dentry(direntry); | 120 | full_path = build_path_from_dentry(direntry); |
120 | if (full_path == NULL) { | 121 | if (full_path == NULL) { |
122 | rc = -ENOMEM; | ||
121 | FreeXid(xid); | 123 | FreeXid(xid); |
122 | return -ENOMEM; | 124 | return rc; |
123 | } | 125 | } |
124 | /* return dos attributes as pseudo xattr */ | 126 | /* return dos attributes as pseudo xattr */ |
125 | /* return alt name if available as pseudo attr */ | 127 | /* return alt name if available as pseudo attr */ |
@@ -225,8 +227,9 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
225 | 227 | ||
226 | full_path = build_path_from_dentry(direntry); | 228 | full_path = build_path_from_dentry(direntry); |
227 | if (full_path == NULL) { | 229 | if (full_path == NULL) { |
230 | rc = -ENOMEM; | ||
228 | FreeXid(xid); | 231 | FreeXid(xid); |
229 | return -ENOMEM; | 232 | return rc; |
230 | } | 233 | } |
231 | /* return dos attributes as pseudo xattr */ | 234 | /* return dos attributes as pseudo xattr */ |
232 | /* return alt name if available as pseudo attr */ | 235 | /* return alt name if available as pseudo attr */ |
@@ -351,8 +354,9 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size) | |||
351 | 354 | ||
352 | full_path = build_path_from_dentry(direntry); | 355 | full_path = build_path_from_dentry(direntry); |
353 | if (full_path == NULL) { | 356 | if (full_path == NULL) { |
357 | rc = -ENOMEM; | ||
354 | FreeXid(xid); | 358 | FreeXid(xid); |
355 | return -ENOMEM; | 359 | return rc; |
356 | } | 360 | } |
357 | /* return dos attributes as pseudo xattr */ | 361 | /* return dos attributes as pseudo xattr */ |
358 | /* return alt name if available as pseudo attr */ | 362 | /* return alt name if available as pseudo attr */ |
diff --git a/fs/namei.c b/fs/namei.c index 5b961eb71cbf..f3c5b278895a 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1761,6 +1761,10 @@ do_last: | |||
1761 | goto exit; | 1761 | goto exit; |
1762 | } | 1762 | } |
1763 | filp = nameidata_to_filp(&nd, open_flag); | 1763 | filp = nameidata_to_filp(&nd, open_flag); |
1764 | if (IS_ERR(filp)) | ||
1765 | ima_counts_put(&nd.path, | ||
1766 | acc_mode & (MAY_READ | MAY_WRITE | | ||
1767 | MAY_EXEC)); | ||
1764 | mnt_drop_write(nd.path.mnt); | 1768 | mnt_drop_write(nd.path.mnt); |
1765 | if (nd.root.mnt) | 1769 | if (nd.root.mnt) |
1766 | path_put(&nd.root); | 1770 | path_put(&nd.root); |
@@ -1817,6 +1821,9 @@ ok: | |||
1817 | goto exit; | 1821 | goto exit; |
1818 | } | 1822 | } |
1819 | filp = nameidata_to_filp(&nd, open_flag); | 1823 | filp = nameidata_to_filp(&nd, open_flag); |
1824 | if (IS_ERR(filp)) | ||
1825 | ima_counts_put(&nd.path, | ||
1826 | acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC)); | ||
1820 | /* | 1827 | /* |
1821 | * It is now safe to drop the mnt write | 1828 | * It is now safe to drop the mnt write |
1822 | * because the filp has had a write taken | 1829 | * because the filp has had a write taken |
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index c263e4d71754..7d6c9a2dfcbb 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h | |||
@@ -35,11 +35,11 @@ struct est_timings { | |||
35 | } __attribute__((packed)); | 35 | } __attribute__((packed)); |
36 | 36 | ||
37 | /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ | 37 | /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ |
38 | #define EDID_TIMING_ASPECT_SHIFT 0 | 38 | #define EDID_TIMING_ASPECT_SHIFT 6 |
39 | #define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT) | 39 | #define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT) |
40 | 40 | ||
41 | /* need to add 60 */ | 41 | /* need to add 60 */ |
42 | #define EDID_TIMING_VFREQ_SHIFT 2 | 42 | #define EDID_TIMING_VFREQ_SHIFT 0 |
43 | #define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT) | 43 | #define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT) |
44 | 44 | ||
45 | struct std_timing { | 45 | struct std_timing { |
@@ -47,11 +47,11 @@ struct std_timing { | |||
47 | u8 vfreq_aspect; | 47 | u8 vfreq_aspect; |
48 | } __attribute__((packed)); | 48 | } __attribute__((packed)); |
49 | 49 | ||
50 | #define DRM_EDID_PT_HSYNC_POSITIVE (1 << 6) | 50 | #define DRM_EDID_PT_HSYNC_POSITIVE (1 << 1) |
51 | #define DRM_EDID_PT_VSYNC_POSITIVE (1 << 5) | 51 | #define DRM_EDID_PT_VSYNC_POSITIVE (1 << 2) |
52 | #define DRM_EDID_PT_SEPARATE_SYNC (3 << 3) | 52 | #define DRM_EDID_PT_SEPARATE_SYNC (3 << 3) |
53 | #define DRM_EDID_PT_STEREO (1 << 2) | 53 | #define DRM_EDID_PT_STEREO (1 << 5) |
54 | #define DRM_EDID_PT_INTERLACED (1 << 1) | 54 | #define DRM_EDID_PT_INTERLACED (1 << 7) |
55 | 55 | ||
56 | /* If detailed data is pixel timing */ | 56 | /* If detailed data is pixel timing */ |
57 | struct detailed_pixel_timing { | 57 | struct detailed_pixel_timing { |
@@ -93,7 +93,7 @@ struct detailed_data_monitor_range { | |||
93 | } __attribute__((packed)); | 93 | } __attribute__((packed)); |
94 | 94 | ||
95 | struct detailed_data_wpindex { | 95 | struct detailed_data_wpindex { |
96 | u8 white_xy_lo; /* Upper 2 bits each */ | 96 | u8 white_yx_lo; /* Lower 2 bits each */ |
97 | u8 white_x_hi; | 97 | u8 white_x_hi; |
98 | u8 white_y_hi; | 98 | u8 white_y_hi; |
99 | u8 gamma; /* need to divide by 100 then add 1 */ | 99 | u8 gamma; /* need to divide by 100 then add 1 */ |
@@ -135,21 +135,21 @@ struct detailed_timing { | |||
135 | } data; | 135 | } data; |
136 | } __attribute__((packed)); | 136 | } __attribute__((packed)); |
137 | 137 | ||
138 | #define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 7) | 138 | #define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 0) |
139 | #define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 5) | 139 | #define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 1) |
140 | #define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 4) | 140 | #define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 2) |
141 | #define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3) | 141 | #define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3) |
142 | #define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 2) | 142 | #define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 4) |
143 | #define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 1) | 143 | #define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 5) |
144 | #define DRM_EDID_INPUT_DIGITAL (1 << 0) /* bits above must be zero if set */ | 144 | #define DRM_EDID_INPUT_DIGITAL (1 << 7) /* bits below must be zero if set */ |
145 | 145 | ||
146 | #define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 7) | 146 | #define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 0) |
147 | #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 6) | 147 | #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 1) |
148 | #define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 5) | 148 | #define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 2) |
149 | #define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ | 149 | #define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ |
150 | #define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 2) | 150 | #define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 5) |
151 | #define DRM_EDID_FEATURE_PM_SUSPEND (1 << 1) | 151 | #define DRM_EDID_FEATURE_PM_SUSPEND (1 << 6) |
152 | #define DRM_EDID_FEATURE_PM_STANDBY (1 << 0) | 152 | #define DRM_EDID_FEATURE_PM_STANDBY (1 << 7) |
153 | 153 | ||
154 | struct edid { | 154 | struct edid { |
155 | u8 header[8]; | 155 | u8 header[8]; |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 44848aa830dc..6c3de999fb34 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -280,7 +280,7 @@ static inline void __fsnotify_update_dcache_flags(struct dentry *dentry) | |||
280 | assert_spin_locked(&dentry->d_lock); | 280 | assert_spin_locked(&dentry->d_lock); |
281 | 281 | ||
282 | parent = dentry->d_parent; | 282 | parent = dentry->d_parent; |
283 | if (fsnotify_inode_watches_children(parent->d_inode)) | 283 | if (parent->d_inode && fsnotify_inode_watches_children(parent->d_inode)) |
284 | dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; | 284 | dentry->d_flags |= DCACHE_FSNOTIFY_PARENT_WATCHED; |
285 | else | 285 | else |
286 | dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; | 286 | dentry->d_flags &= ~DCACHE_FSNOTIFY_PARENT_WATCHED; |
diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 7400900de94a..54648e625efd 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
22 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
23 | #include <linux/percpu.h> | 23 | #include <linux/percpu.h> |
24 | #include <linux/timer.h> | ||
24 | 25 | ||
25 | 26 | ||
26 | struct hrtimer_clock_base; | 27 | struct hrtimer_clock_base; |
@@ -447,6 +448,8 @@ extern void timer_stats_update_stats(void *timer, pid_t pid, void *startf, | |||
447 | 448 | ||
448 | static inline void timer_stats_account_hrtimer(struct hrtimer *timer) | 449 | static inline void timer_stats_account_hrtimer(struct hrtimer *timer) |
449 | { | 450 | { |
451 | if (likely(!timer->start_pid)) | ||
452 | return; | ||
450 | timer_stats_update_stats(timer, timer->start_pid, timer->start_site, | 453 | timer_stats_update_stats(timer, timer->start_pid, timer->start_site, |
451 | timer->function, timer->start_comm, 0); | 454 | timer->function, timer->start_comm, 0); |
452 | } | 455 | } |
@@ -456,6 +459,8 @@ extern void __timer_stats_hrtimer_set_start_info(struct hrtimer *timer, | |||
456 | 459 | ||
457 | static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) | 460 | static inline void timer_stats_hrtimer_set_start_info(struct hrtimer *timer) |
458 | { | 461 | { |
462 | if (likely(!timer_stats_active)) | ||
463 | return; | ||
459 | __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0)); | 464 | __timer_stats_hrtimer_set_start_info(timer, __builtin_return_address(0)); |
460 | } | 465 | } |
461 | 466 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index 95c6e00a72e8..cf1f3888067c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -1361,7 +1361,6 @@ int ide_in_drive_list(u16 *, const struct drive_list_entry *); | |||
1361 | #ifdef CONFIG_BLK_DEV_IDEDMA | 1361 | #ifdef CONFIG_BLK_DEV_IDEDMA |
1362 | int ide_dma_good_drive(ide_drive_t *); | 1362 | int ide_dma_good_drive(ide_drive_t *); |
1363 | int __ide_dma_bad_drive(ide_drive_t *); | 1363 | int __ide_dma_bad_drive(ide_drive_t *); |
1364 | int ide_id_dma_bug(ide_drive_t *); | ||
1365 | 1364 | ||
1366 | u8 ide_find_dma_mode(ide_drive_t *, u8); | 1365 | u8 ide_find_dma_mode(ide_drive_t *, u8); |
1367 | 1366 | ||
@@ -1402,7 +1401,6 @@ void ide_dma_lost_irq(ide_drive_t *); | |||
1402 | ide_startstop_t ide_dma_timeout_retry(ide_drive_t *, int); | 1401 | ide_startstop_t ide_dma_timeout_retry(ide_drive_t *, int); |
1403 | 1402 | ||
1404 | #else | 1403 | #else |
1405 | static inline int ide_id_dma_bug(ide_drive_t *drive) { return 0; } | ||
1406 | static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; } | 1404 | static inline u8 ide_find_dma_mode(ide_drive_t *drive, u8 speed) { return 0; } |
1407 | static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } | 1405 | static inline u8 ide_max_dma_mode(ide_drive_t *drive) { return 0; } |
1408 | static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; } | 1406 | static inline void ide_dma_off_quietly(ide_drive_t *drive) { ; } |
diff --git a/include/linux/ima.h b/include/linux/ima.h index b1b827d091a9..0e3f2a4c25f6 100644 --- a/include/linux/ima.h +++ b/include/linux/ima.h | |||
@@ -24,6 +24,7 @@ extern int ima_path_check(struct path *path, int mask, int update_counts); | |||
24 | extern void ima_file_free(struct file *file); | 24 | extern void ima_file_free(struct file *file); |
25 | extern int ima_file_mmap(struct file *file, unsigned long prot); | 25 | extern int ima_file_mmap(struct file *file, unsigned long prot); |
26 | extern void ima_counts_get(struct file *file); | 26 | extern void ima_counts_get(struct file *file); |
27 | extern void ima_counts_put(struct path *path, int mask); | ||
27 | 28 | ||
28 | #else | 29 | #else |
29 | static inline int ima_bprm_check(struct linux_binprm *bprm) | 30 | static inline int ima_bprm_check(struct linux_binprm *bprm) |
@@ -60,5 +61,10 @@ static inline void ima_counts_get(struct file *file) | |||
60 | { | 61 | { |
61 | return; | 62 | return; |
62 | } | 63 | } |
64 | |||
65 | static inline void ima_counts_put(struct path *path, int mask) | ||
66 | { | ||
67 | return; | ||
68 | } | ||
63 | #endif /* CONFIG_IMA_H */ | 69 | #endif /* CONFIG_IMA_H */ |
64 | #endif /* _LINUX_IMA_H */ | 70 | #endif /* _LINUX_IMA_H */ |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index fac104e7186a..d6320a3e8def 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -303,6 +303,7 @@ extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in | |||
303 | extern int panic_timeout; | 303 | extern int panic_timeout; |
304 | extern int panic_on_oops; | 304 | extern int panic_on_oops; |
305 | extern int panic_on_unrecovered_nmi; | 305 | extern int panic_on_unrecovered_nmi; |
306 | extern int panic_on_io_nmi; | ||
306 | extern const char *print_tainted(void); | 307 | extern const char *print_tainted(void); |
307 | extern void add_taint(unsigned flag); | 308 | extern void add_taint(unsigned flag); |
308 | extern int test_taint(unsigned flag); | 309 | extern int test_taint(unsigned flag); |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index aacc5449f586..16713dc672e4 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -125,6 +125,7 @@ struct kvm_kernel_irq_routing_entry { | |||
125 | struct kvm { | 125 | struct kvm { |
126 | struct mutex lock; /* protects the vcpus array and APIC accesses */ | 126 | struct mutex lock; /* protects the vcpus array and APIC accesses */ |
127 | spinlock_t mmu_lock; | 127 | spinlock_t mmu_lock; |
128 | spinlock_t requests_lock; | ||
128 | struct rw_semaphore slots_lock; | 129 | struct rw_semaphore slots_lock; |
129 | struct mm_struct *mm; /* userspace tied to this vm */ | 130 | struct mm_struct *mm; /* userspace tied to this vm */ |
130 | int nmemslots; | 131 | int nmemslots; |
diff --git a/include/linux/leds-lp3944.h b/include/linux/leds-lp3944.h new file mode 100644 index 000000000000..afc9f9fd70f5 --- /dev/null +++ b/include/linux/leds-lp3944.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * leds-lp3944.h - platform data structure for lp3944 led controller | ||
3 | * | ||
4 | * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef __LINUX_LEDS_LP3944_H | ||
13 | #define __LINUX_LEDS_LP3944_H | ||
14 | |||
15 | #include <linux/leds.h> | ||
16 | #include <linux/workqueue.h> | ||
17 | |||
18 | #define LP3944_LED0 0 | ||
19 | #define LP3944_LED1 1 | ||
20 | #define LP3944_LED2 2 | ||
21 | #define LP3944_LED3 3 | ||
22 | #define LP3944_LED4 4 | ||
23 | #define LP3944_LED5 5 | ||
24 | #define LP3944_LED6 6 | ||
25 | #define LP3944_LED7 7 | ||
26 | #define LP3944_LEDS_MAX 8 | ||
27 | |||
28 | #define LP3944_LED_STATUS_MASK 0x03 | ||
29 | enum lp3944_status { | ||
30 | LP3944_LED_STATUS_OFF = 0x0, | ||
31 | LP3944_LED_STATUS_ON = 0x1, | ||
32 | LP3944_LED_STATUS_DIM0 = 0x2, | ||
33 | LP3944_LED_STATUS_DIM1 = 0x3 | ||
34 | }; | ||
35 | |||
36 | enum lp3944_type { | ||
37 | LP3944_LED_TYPE_NONE, | ||
38 | LP3944_LED_TYPE_LED, | ||
39 | LP3944_LED_TYPE_LED_INVERTED, | ||
40 | }; | ||
41 | |||
42 | struct lp3944_led { | ||
43 | char *name; | ||
44 | enum lp3944_type type; | ||
45 | enum lp3944_status status; | ||
46 | }; | ||
47 | |||
48 | struct lp3944_platform_data { | ||
49 | struct lp3944_led leds[LP3944_LEDS_MAX]; | ||
50 | u8 leds_size; | ||
51 | }; | ||
52 | |||
53 | #endif /* __LINUX_LEDS_LP3944_H */ | ||
diff --git a/include/linux/leds.h b/include/linux/leds.h index 376fe07732ea..d8bf9665e70c 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h | |||
@@ -45,7 +45,10 @@ struct led_classdev { | |||
45 | /* Get LED brightness level */ | 45 | /* Get LED brightness level */ |
46 | enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); | 46 | enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); |
47 | 47 | ||
48 | /* Activate hardware accelerated blink */ | 48 | /* Activate hardware accelerated blink, delays are in |
49 | * miliseconds and if none is provided then a sensible default | ||
50 | * should be chosen. The call can adjust the timings if it can't | ||
51 | * match the values specified exactly. */ | ||
49 | int (*blink_set)(struct led_classdev *led_cdev, | 52 | int (*blink_set)(struct led_classdev *led_cdev, |
50 | unsigned long *delay_on, | 53 | unsigned long *delay_on, |
51 | unsigned long *delay_off); | 54 | unsigned long *delay_off); |
@@ -141,9 +144,14 @@ struct gpio_led { | |||
141 | const char *name; | 144 | const char *name; |
142 | const char *default_trigger; | 145 | const char *default_trigger; |
143 | unsigned gpio; | 146 | unsigned gpio; |
144 | u8 active_low : 1; | 147 | unsigned active_low : 1; |
145 | u8 retain_state_suspended : 1; | 148 | unsigned retain_state_suspended : 1; |
149 | unsigned default_state : 2; | ||
150 | /* default_state should be one of LEDS_GPIO_DEFSTATE_(ON|OFF|KEEP) */ | ||
146 | }; | 151 | }; |
152 | #define LEDS_GPIO_DEFSTATE_OFF 0 | ||
153 | #define LEDS_GPIO_DEFSTATE_ON 1 | ||
154 | #define LEDS_GPIO_DEFSTATE_KEEP 2 | ||
147 | 155 | ||
148 | struct gpio_led_platform_data { | 156 | struct gpio_led_platform_data { |
149 | int num_leds; | 157 | int num_leds; |
diff --git a/include/linux/mm.h b/include/linux/mm.h index d006e93d5c93..ba3a7cb1eaa0 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -826,7 +826,7 @@ extern int make_pages_present(unsigned long addr, unsigned long end); | |||
826 | extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); | 826 | extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write); |
827 | 827 | ||
828 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | 828 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
829 | unsigned long start, int len, int write, int force, | 829 | unsigned long start, int nr_pages, int write, int force, |
830 | struct page **pages, struct vm_area_struct **vmas); | 830 | struct page **pages, struct vm_area_struct **vmas); |
831 | int get_user_pages_fast(unsigned long start, int nr_pages, int write, | 831 | int get_user_pages_fast(unsigned long start, int nr_pages, int write, |
832 | struct page **pages); | 832 | struct page **pages); |
diff --git a/include/linux/timer.h b/include/linux/timer.h index ccf882eed8f8..be62ec2ebea5 100644 --- a/include/linux/timer.h +++ b/include/linux/timer.h | |||
@@ -190,6 +190,8 @@ extern unsigned long get_next_timer_interrupt(unsigned long now); | |||
190 | */ | 190 | */ |
191 | #ifdef CONFIG_TIMER_STATS | 191 | #ifdef CONFIG_TIMER_STATS |
192 | 192 | ||
193 | extern int timer_stats_active; | ||
194 | |||
193 | #define TIMER_STATS_FLAG_DEFERRABLE 0x1 | 195 | #define TIMER_STATS_FLAG_DEFERRABLE 0x1 |
194 | 196 | ||
195 | extern void init_timer_stats(void); | 197 | extern void init_timer_stats(void); |
@@ -203,6 +205,8 @@ extern void __timer_stats_timer_set_start_info(struct timer_list *timer, | |||
203 | 205 | ||
204 | static inline void timer_stats_timer_set_start_info(struct timer_list *timer) | 206 | static inline void timer_stats_timer_set_start_info(struct timer_list *timer) |
205 | { | 207 | { |
208 | if (likely(!timer_stats_active)) | ||
209 | return; | ||
206 | __timer_stats_timer_set_start_info(timer, __builtin_return_address(0)); | 210 | __timer_stats_timer_set_start_info(timer, __builtin_return_address(0)); |
207 | } | 211 | } |
208 | 212 | ||
diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h index 5054dc5ea2c2..29d126736611 100644 --- a/include/net/phonet/pn_dev.h +++ b/include/net/phonet/pn_dev.h | |||
@@ -45,6 +45,7 @@ int phonet_address_add(struct net_device *dev, u8 addr); | |||
45 | int phonet_address_del(struct net_device *dev, u8 addr); | 45 | int phonet_address_del(struct net_device *dev, u8 addr); |
46 | u8 phonet_address_get(struct net_device *dev, u8 addr); | 46 | u8 phonet_address_get(struct net_device *dev, u8 addr); |
47 | int phonet_address_lookup(struct net *net, u8 addr); | 47 | int phonet_address_lookup(struct net *net, u8 addr); |
48 | void phonet_address_notify(int event, struct net_device *dev, u8 addr); | ||
48 | 49 | ||
49 | #define PN_NO_ADDR 0xff | 50 | #define PN_NO_ADDR 0xff |
50 | 51 | ||
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index e35ba2c3a8d7..c5e68adc6732 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/nsproxy.h> | 32 | #include <linux/nsproxy.h> |
33 | #include <linux/pid.h> | 33 | #include <linux/pid.h> |
34 | #include <linux/ipc_namespace.h> | 34 | #include <linux/ipc_namespace.h> |
35 | #include <linux/ima.h> | ||
35 | 36 | ||
36 | #include <net/sock.h> | 37 | #include <net/sock.h> |
37 | #include "util.h" | 38 | #include "util.h" |
@@ -733,6 +734,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, | |||
733 | error = PTR_ERR(filp); | 734 | error = PTR_ERR(filp); |
734 | goto out_putfd; | 735 | goto out_putfd; |
735 | } | 736 | } |
737 | ima_counts_get(filp); | ||
736 | 738 | ||
737 | fd_install(fd, filp); | 739 | fd_install(fd, filp); |
738 | goto out_upsem; | 740 | goto out_upsem; |
diff --git a/kernel/Makefile b/kernel/Makefile index 780c8dcf4516..2093a691f1c2 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -96,6 +96,7 @@ obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o | |||
96 | obj-$(CONFIG_FUNCTION_TRACER) += trace/ | 96 | obj-$(CONFIG_FUNCTION_TRACER) += trace/ |
97 | obj-$(CONFIG_TRACING) += trace/ | 97 | obj-$(CONFIG_TRACING) += trace/ |
98 | obj-$(CONFIG_X86_DS) += trace/ | 98 | obj-$(CONFIG_X86_DS) += trace/ |
99 | obj-$(CONFIG_RING_BUFFER) += trace/ | ||
99 | obj-$(CONFIG_SMP) += sched_cpupri.o | 100 | obj-$(CONFIG_SMP) += sched_cpupri.o |
100 | obj-$(CONFIG_SLOW_WORK) += slow-work.o | 101 | obj-$(CONFIG_SLOW_WORK) += slow-work.o |
101 | obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o | 102 | obj-$(CONFIG_PERF_COUNTERS) += perf_counter.o |
diff --git a/kernel/futex.c b/kernel/futex.c index 1c337112335c..794c862125fe 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -299,7 +299,7 @@ void put_futex_key(int fshared, union futex_key *key) | |||
299 | static int fault_in_user_writeable(u32 __user *uaddr) | 299 | static int fault_in_user_writeable(u32 __user *uaddr) |
300 | { | 300 | { |
301 | int ret = get_user_pages(current, current->mm, (unsigned long)uaddr, | 301 | int ret = get_user_pages(current, current->mm, (unsigned long)uaddr, |
302 | sizeof(*uaddr), 1, 0, NULL, NULL); | 302 | 1, 1, 0, NULL, NULL); |
303 | return ret < 0 ? ret : 0; | 303 | return ret < 0 ? ret : 0; |
304 | } | 304 | } |
305 | 305 | ||
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 62e4ff9968b5..98e02328c67d 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -335,7 +335,10 @@ static struct ctl_table kern_table[] = { | |||
335 | .data = &sysctl_timer_migration, | 335 | .data = &sysctl_timer_migration, |
336 | .maxlen = sizeof(unsigned int), | 336 | .maxlen = sizeof(unsigned int), |
337 | .mode = 0644, | 337 | .mode = 0644, |
338 | .proc_handler = &proc_dointvec, | 338 | .proc_handler = &proc_dointvec_minmax, |
339 | .strategy = &sysctl_intvec, | ||
340 | .extra1 = &zero, | ||
341 | .extra2 = &one, | ||
339 | }, | 342 | }, |
340 | #endif | 343 | #endif |
341 | { | 344 | { |
@@ -744,6 +747,14 @@ static struct ctl_table kern_table[] = { | |||
744 | .proc_handler = &proc_dointvec, | 747 | .proc_handler = &proc_dointvec, |
745 | }, | 748 | }, |
746 | { | 749 | { |
750 | .ctl_name = CTL_UNNUMBERED, | ||
751 | .procname = "panic_on_io_nmi", | ||
752 | .data = &panic_on_io_nmi, | ||
753 | .maxlen = sizeof(int), | ||
754 | .mode = 0644, | ||
755 | .proc_handler = &proc_dointvec, | ||
756 | }, | ||
757 | { | ||
747 | .ctl_name = KERN_BOOTLOADER_TYPE, | 758 | .ctl_name = KERN_BOOTLOADER_TYPE, |
748 | .procname = "bootloader_type", | 759 | .procname = "bootloader_type", |
749 | .data = &bootloader_type, | 760 | .data = &bootloader_type, |
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c index c994530d166d..4cde8b9c716f 100644 --- a/kernel/time/timer_stats.c +++ b/kernel/time/timer_stats.c | |||
@@ -96,7 +96,7 @@ static DEFINE_MUTEX(show_mutex); | |||
96 | /* | 96 | /* |
97 | * Collection status, active/inactive: | 97 | * Collection status, active/inactive: |
98 | */ | 98 | */ |
99 | static int __read_mostly active; | 99 | int __read_mostly timer_stats_active; |
100 | 100 | ||
101 | /* | 101 | /* |
102 | * Beginning/end timestamps of measurement: | 102 | * Beginning/end timestamps of measurement: |
@@ -242,7 +242,7 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf, | |||
242 | struct entry *entry, input; | 242 | struct entry *entry, input; |
243 | unsigned long flags; | 243 | unsigned long flags; |
244 | 244 | ||
245 | if (likely(!active)) | 245 | if (likely(!timer_stats_active)) |
246 | return; | 246 | return; |
247 | 247 | ||
248 | lock = &per_cpu(lookup_lock, raw_smp_processor_id()); | 248 | lock = &per_cpu(lookup_lock, raw_smp_processor_id()); |
@@ -254,7 +254,7 @@ void timer_stats_update_stats(void *timer, pid_t pid, void *startf, | |||
254 | input.timer_flag = timer_flag; | 254 | input.timer_flag = timer_flag; |
255 | 255 | ||
256 | spin_lock_irqsave(lock, flags); | 256 | spin_lock_irqsave(lock, flags); |
257 | if (!active) | 257 | if (!timer_stats_active) |
258 | goto out_unlock; | 258 | goto out_unlock; |
259 | 259 | ||
260 | entry = tstat_lookup(&input, comm); | 260 | entry = tstat_lookup(&input, comm); |
@@ -290,7 +290,7 @@ static int tstats_show(struct seq_file *m, void *v) | |||
290 | /* | 290 | /* |
291 | * If still active then calculate up to now: | 291 | * If still active then calculate up to now: |
292 | */ | 292 | */ |
293 | if (active) | 293 | if (timer_stats_active) |
294 | time_stop = ktime_get(); | 294 | time_stop = ktime_get(); |
295 | 295 | ||
296 | time = ktime_sub(time_stop, time_start); | 296 | time = ktime_sub(time_stop, time_start); |
@@ -368,18 +368,18 @@ static ssize_t tstats_write(struct file *file, const char __user *buf, | |||
368 | mutex_lock(&show_mutex); | 368 | mutex_lock(&show_mutex); |
369 | switch (ctl[0]) { | 369 | switch (ctl[0]) { |
370 | case '0': | 370 | case '0': |
371 | if (active) { | 371 | if (timer_stats_active) { |
372 | active = 0; | 372 | timer_stats_active = 0; |
373 | time_stop = ktime_get(); | 373 | time_stop = ktime_get(); |
374 | sync_access(); | 374 | sync_access(); |
375 | } | 375 | } |
376 | break; | 376 | break; |
377 | case '1': | 377 | case '1': |
378 | if (!active) { | 378 | if (!timer_stats_active) { |
379 | reset_entries(); | 379 | reset_entries(); |
380 | time_start = ktime_get(); | 380 | time_start = ktime_get(); |
381 | smp_mb(); | 381 | smp_mb(); |
382 | active = 1; | 382 | timer_stats_active = 1; |
383 | } | 383 | } |
384 | break; | 384 | break; |
385 | default: | 385 | default: |
diff --git a/kernel/timer.c b/kernel/timer.c index 54d3912f8cad..0b36b9e5cc8b 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -380,6 +380,8 @@ static void timer_stats_account_timer(struct timer_list *timer) | |||
380 | { | 380 | { |
381 | unsigned int flag = 0; | 381 | unsigned int flag = 0; |
382 | 382 | ||
383 | if (likely(!timer->start_site)) | ||
384 | return; | ||
383 | if (unlikely(tbase_get_deferrable(timer->base))) | 385 | if (unlikely(tbase_get_deferrable(timer->base))) |
384 | flag |= TIMER_STATS_FLAG_DEFERRABLE; | 386 | flag |= TIMER_STATS_FLAG_DEFERRABLE; |
385 | 387 | ||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index 3718d55fb4c3..f3716bf04df6 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c | |||
@@ -291,7 +291,9 @@ function_stat_next(void *v, int idx) | |||
291 | pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK); | 291 | pg = (struct ftrace_profile_page *)((unsigned long)rec & PAGE_MASK); |
292 | 292 | ||
293 | again: | 293 | again: |
294 | rec++; | 294 | if (idx != 0) |
295 | rec++; | ||
296 | |||
295 | if ((void *)rec >= (void *)&pg->records[pg->index]) { | 297 | if ((void *)rec >= (void *)&pg->records[pg->index]) { |
296 | pg = pg->next; | 298 | pg = pg->next; |
297 | if (!pg) | 299 | if (!pg) |
@@ -1417,10 +1419,20 @@ static void *t_hash_start(struct seq_file *m, loff_t *pos) | |||
1417 | { | 1419 | { |
1418 | struct ftrace_iterator *iter = m->private; | 1420 | struct ftrace_iterator *iter = m->private; |
1419 | void *p = NULL; | 1421 | void *p = NULL; |
1422 | loff_t l; | ||
1423 | |||
1424 | if (!(iter->flags & FTRACE_ITER_HASH)) | ||
1425 | *pos = 0; | ||
1420 | 1426 | ||
1421 | iter->flags |= FTRACE_ITER_HASH; | 1427 | iter->flags |= FTRACE_ITER_HASH; |
1422 | 1428 | ||
1423 | return t_hash_next(m, p, pos); | 1429 | iter->hidx = 0; |
1430 | for (l = 0; l <= *pos; ) { | ||
1431 | p = t_hash_next(m, p, &l); | ||
1432 | if (!p) | ||
1433 | break; | ||
1434 | } | ||
1435 | return p; | ||
1424 | } | 1436 | } |
1425 | 1437 | ||
1426 | static int t_hash_show(struct seq_file *m, void *v) | 1438 | static int t_hash_show(struct seq_file *m, void *v) |
@@ -1467,8 +1479,6 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
1467 | iter->pg = iter->pg->next; | 1479 | iter->pg = iter->pg->next; |
1468 | iter->idx = 0; | 1480 | iter->idx = 0; |
1469 | goto retry; | 1481 | goto retry; |
1470 | } else { | ||
1471 | iter->idx = -1; | ||
1472 | } | 1482 | } |
1473 | } else { | 1483 | } else { |
1474 | rec = &iter->pg->records[iter->idx++]; | 1484 | rec = &iter->pg->records[iter->idx++]; |
@@ -1497,6 +1507,7 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
1497 | { | 1507 | { |
1498 | struct ftrace_iterator *iter = m->private; | 1508 | struct ftrace_iterator *iter = m->private; |
1499 | void *p = NULL; | 1509 | void *p = NULL; |
1510 | loff_t l; | ||
1500 | 1511 | ||
1501 | mutex_lock(&ftrace_lock); | 1512 | mutex_lock(&ftrace_lock); |
1502 | /* | 1513 | /* |
@@ -1508,23 +1519,21 @@ static void *t_start(struct seq_file *m, loff_t *pos) | |||
1508 | if (*pos > 0) | 1519 | if (*pos > 0) |
1509 | return t_hash_start(m, pos); | 1520 | return t_hash_start(m, pos); |
1510 | iter->flags |= FTRACE_ITER_PRINTALL; | 1521 | iter->flags |= FTRACE_ITER_PRINTALL; |
1511 | (*pos)++; | ||
1512 | return iter; | 1522 | return iter; |
1513 | } | 1523 | } |
1514 | 1524 | ||
1515 | if (iter->flags & FTRACE_ITER_HASH) | 1525 | if (iter->flags & FTRACE_ITER_HASH) |
1516 | return t_hash_start(m, pos); | 1526 | return t_hash_start(m, pos); |
1517 | 1527 | ||
1518 | if (*pos > 0) { | 1528 | iter->pg = ftrace_pages_start; |
1519 | if (iter->idx < 0) | 1529 | iter->idx = 0; |
1520 | return p; | 1530 | for (l = 0; l <= *pos; ) { |
1521 | (*pos)--; | 1531 | p = t_next(m, p, &l); |
1522 | iter->idx--; | 1532 | if (!p) |
1533 | break; | ||
1523 | } | 1534 | } |
1524 | 1535 | ||
1525 | p = t_next(m, p, pos); | 1536 | if (!p && iter->flags & FTRACE_ITER_FILTER) |
1526 | |||
1527 | if (!p) | ||
1528 | return t_hash_start(m, pos); | 1537 | return t_hash_start(m, pos); |
1529 | 1538 | ||
1530 | return p; | 1539 | return p; |
@@ -2500,32 +2509,31 @@ int ftrace_graph_count; | |||
2500 | unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; | 2509 | unsigned long ftrace_graph_funcs[FTRACE_GRAPH_MAX_FUNCS] __read_mostly; |
2501 | 2510 | ||
2502 | static void * | 2511 | static void * |
2503 | g_next(struct seq_file *m, void *v, loff_t *pos) | 2512 | __g_next(struct seq_file *m, loff_t *pos) |
2504 | { | 2513 | { |
2505 | unsigned long *array = m->private; | 2514 | unsigned long *array = m->private; |
2506 | int index = *pos; | ||
2507 | 2515 | ||
2508 | (*pos)++; | 2516 | if (*pos >= ftrace_graph_count) |
2509 | |||
2510 | if (index >= ftrace_graph_count) | ||
2511 | return NULL; | 2517 | return NULL; |
2518 | return &array[*pos]; | ||
2519 | } | ||
2512 | 2520 | ||
2513 | return &array[index]; | 2521 | static void * |
2522 | g_next(struct seq_file *m, void *v, loff_t *pos) | ||
2523 | { | ||
2524 | (*pos)++; | ||
2525 | return __g_next(m, pos); | ||
2514 | } | 2526 | } |
2515 | 2527 | ||
2516 | static void *g_start(struct seq_file *m, loff_t *pos) | 2528 | static void *g_start(struct seq_file *m, loff_t *pos) |
2517 | { | 2529 | { |
2518 | void *p = NULL; | ||
2519 | |||
2520 | mutex_lock(&graph_lock); | 2530 | mutex_lock(&graph_lock); |
2521 | 2531 | ||
2522 | /* Nothing, tell g_show to print all functions are enabled */ | 2532 | /* Nothing, tell g_show to print all functions are enabled */ |
2523 | if (!ftrace_graph_count && !*pos) | 2533 | if (!ftrace_graph_count && !*pos) |
2524 | return (void *)1; | 2534 | return (void *)1; |
2525 | 2535 | ||
2526 | p = g_next(m, p, pos); | 2536 | return __g_next(m, pos); |
2527 | |||
2528 | return p; | ||
2529 | } | 2537 | } |
2530 | 2538 | ||
2531 | static void g_stop(struct seq_file *m, void *p) | 2539 | static void g_stop(struct seq_file *m, void *p) |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 04dac2638258..bf27bb7a63e2 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -1563,6 +1563,8 @@ rb_reserve_next_event(struct ring_buffer_per_cpu *cpu_buffer, | |||
1563 | return NULL; | 1563 | return NULL; |
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | #ifdef CONFIG_TRACING | ||
1567 | |||
1566 | #define TRACE_RECURSIVE_DEPTH 16 | 1568 | #define TRACE_RECURSIVE_DEPTH 16 |
1567 | 1569 | ||
1568 | static int trace_recursive_lock(void) | 1570 | static int trace_recursive_lock(void) |
@@ -1593,6 +1595,13 @@ static void trace_recursive_unlock(void) | |||
1593 | current->trace_recursion--; | 1595 | current->trace_recursion--; |
1594 | } | 1596 | } |
1595 | 1597 | ||
1598 | #else | ||
1599 | |||
1600 | #define trace_recursive_lock() (0) | ||
1601 | #define trace_recursive_unlock() do { } while (0) | ||
1602 | |||
1603 | #endif | ||
1604 | |||
1596 | static DEFINE_PER_CPU(int, rb_need_resched); | 1605 | static DEFINE_PER_CPU(int, rb_need_resched); |
1597 | 1606 | ||
1598 | /** | 1607 | /** |
@@ -3104,6 +3113,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer, | |||
3104 | } | 3113 | } |
3105 | EXPORT_SYMBOL_GPL(ring_buffer_read_page); | 3114 | EXPORT_SYMBOL_GPL(ring_buffer_read_page); |
3106 | 3115 | ||
3116 | #ifdef CONFIG_TRACING | ||
3107 | static ssize_t | 3117 | static ssize_t |
3108 | rb_simple_read(struct file *filp, char __user *ubuf, | 3118 | rb_simple_read(struct file *filp, char __user *ubuf, |
3109 | size_t cnt, loff_t *ppos) | 3119 | size_t cnt, loff_t *ppos) |
@@ -3171,6 +3181,7 @@ static __init int rb_init_debugfs(void) | |||
3171 | } | 3181 | } |
3172 | 3182 | ||
3173 | fs_initcall(rb_init_debugfs); | 3183 | fs_initcall(rb_init_debugfs); |
3184 | #endif | ||
3174 | 3185 | ||
3175 | #ifdef CONFIG_HOTPLUG_CPU | 3186 | #ifdef CONFIG_HOTPLUG_CPU |
3176 | static int rb_cpu_notify(struct notifier_block *self, | 3187 | static int rb_cpu_notify(struct notifier_block *self, |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 076fa6f0ee48..3aa0a0dfdfa8 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -284,13 +284,12 @@ void trace_wake_up(void) | |||
284 | static int __init set_buf_size(char *str) | 284 | static int __init set_buf_size(char *str) |
285 | { | 285 | { |
286 | unsigned long buf_size; | 286 | unsigned long buf_size; |
287 | int ret; | ||
288 | 287 | ||
289 | if (!str) | 288 | if (!str) |
290 | return 0; | 289 | return 0; |
291 | ret = strict_strtoul(str, 0, &buf_size); | 290 | buf_size = memparse(str, &str); |
292 | /* nr_entries can not be zero */ | 291 | /* nr_entries can not be zero */ |
293 | if (ret < 0 || buf_size == 0) | 292 | if (buf_size == 0) |
294 | return 0; | 293 | return 0; |
295 | trace_buf_size = buf_size; | 294 | trace_buf_size = buf_size; |
296 | return 1; | 295 | return 1; |
@@ -2053,25 +2052,23 @@ static int tracing_open(struct inode *inode, struct file *file) | |||
2053 | static void * | 2052 | static void * |
2054 | t_next(struct seq_file *m, void *v, loff_t *pos) | 2053 | t_next(struct seq_file *m, void *v, loff_t *pos) |
2055 | { | 2054 | { |
2056 | struct tracer *t = m->private; | 2055 | struct tracer *t = v; |
2057 | 2056 | ||
2058 | (*pos)++; | 2057 | (*pos)++; |
2059 | 2058 | ||
2060 | if (t) | 2059 | if (t) |
2061 | t = t->next; | 2060 | t = t->next; |
2062 | 2061 | ||
2063 | m->private = t; | ||
2064 | |||
2065 | return t; | 2062 | return t; |
2066 | } | 2063 | } |
2067 | 2064 | ||
2068 | static void *t_start(struct seq_file *m, loff_t *pos) | 2065 | static void *t_start(struct seq_file *m, loff_t *pos) |
2069 | { | 2066 | { |
2070 | struct tracer *t = m->private; | 2067 | struct tracer *t; |
2071 | loff_t l = 0; | 2068 | loff_t l = 0; |
2072 | 2069 | ||
2073 | mutex_lock(&trace_types_lock); | 2070 | mutex_lock(&trace_types_lock); |
2074 | for (; t && l < *pos; t = t_next(m, t, &l)) | 2071 | for (t = trace_types; t && l < *pos; t = t_next(m, t, &l)) |
2075 | ; | 2072 | ; |
2076 | 2073 | ||
2077 | return t; | 2074 | return t; |
@@ -2107,18 +2104,10 @@ static struct seq_operations show_traces_seq_ops = { | |||
2107 | 2104 | ||
2108 | static int show_traces_open(struct inode *inode, struct file *file) | 2105 | static int show_traces_open(struct inode *inode, struct file *file) |
2109 | { | 2106 | { |
2110 | int ret; | ||
2111 | |||
2112 | if (tracing_disabled) | 2107 | if (tracing_disabled) |
2113 | return -ENODEV; | 2108 | return -ENODEV; |
2114 | 2109 | ||
2115 | ret = seq_open(file, &show_traces_seq_ops); | 2110 | return seq_open(file, &show_traces_seq_ops); |
2116 | if (!ret) { | ||
2117 | struct seq_file *m = file->private_data; | ||
2118 | m->private = trace_types; | ||
2119 | } | ||
2120 | |||
2121 | return ret; | ||
2122 | } | 2111 | } |
2123 | 2112 | ||
2124 | static ssize_t | 2113 | static ssize_t |
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h index 6e735d4771f8..3548ae5cc780 100644 --- a/kernel/trace/trace.h +++ b/kernel/trace/trace.h | |||
@@ -597,6 +597,7 @@ print_graph_function(struct trace_iterator *iter) | |||
597 | 597 | ||
598 | extern struct pid *ftrace_pid_trace; | 598 | extern struct pid *ftrace_pid_trace; |
599 | 599 | ||
600 | #ifdef CONFIG_FUNCTION_TRACER | ||
600 | static inline int ftrace_trace_task(struct task_struct *task) | 601 | static inline int ftrace_trace_task(struct task_struct *task) |
601 | { | 602 | { |
602 | if (!ftrace_pid_trace) | 603 | if (!ftrace_pid_trace) |
@@ -604,6 +605,12 @@ static inline int ftrace_trace_task(struct task_struct *task) | |||
604 | 605 | ||
605 | return test_tsk_trace_trace(task); | 606 | return test_tsk_trace_trace(task); |
606 | } | 607 | } |
608 | #else | ||
609 | static inline int ftrace_trace_task(struct task_struct *task) | ||
610 | { | ||
611 | return 1; | ||
612 | } | ||
613 | #endif | ||
607 | 614 | ||
608 | /* | 615 | /* |
609 | * trace_iterator_flags is an enumeration that defines bit | 616 | * trace_iterator_flags is an enumeration that defines bit |
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index aa08be69a1b6..53c8fd376a88 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c | |||
@@ -300,10 +300,18 @@ t_next(struct seq_file *m, void *v, loff_t *pos) | |||
300 | 300 | ||
301 | static void *t_start(struct seq_file *m, loff_t *pos) | 301 | static void *t_start(struct seq_file *m, loff_t *pos) |
302 | { | 302 | { |
303 | struct ftrace_event_call *call = NULL; | ||
304 | loff_t l; | ||
305 | |||
303 | mutex_lock(&event_mutex); | 306 | mutex_lock(&event_mutex); |
304 | if (*pos == 0) | 307 | |
305 | m->private = ftrace_events.next; | 308 | m->private = ftrace_events.next; |
306 | return t_next(m, NULL, pos); | 309 | for (l = 0; l <= *pos; ) { |
310 | call = t_next(m, NULL, &l); | ||
311 | if (!call) | ||
312 | break; | ||
313 | } | ||
314 | return call; | ||
307 | } | 315 | } |
308 | 316 | ||
309 | static void * | 317 | static void * |
@@ -332,10 +340,18 @@ s_next(struct seq_file *m, void *v, loff_t *pos) | |||
332 | 340 | ||
333 | static void *s_start(struct seq_file *m, loff_t *pos) | 341 | static void *s_start(struct seq_file *m, loff_t *pos) |
334 | { | 342 | { |
343 | struct ftrace_event_call *call = NULL; | ||
344 | loff_t l; | ||
345 | |||
335 | mutex_lock(&event_mutex); | 346 | mutex_lock(&event_mutex); |
336 | if (*pos == 0) | 347 | |
337 | m->private = ftrace_events.next; | 348 | m->private = ftrace_events.next; |
338 | return s_next(m, NULL, pos); | 349 | for (l = 0; l <= *pos; ) { |
350 | call = s_next(m, NULL, &l); | ||
351 | if (!call) | ||
352 | break; | ||
353 | } | ||
354 | return call; | ||
339 | } | 355 | } |
340 | 356 | ||
341 | static int t_show(struct seq_file *m, void *v) | 357 | static int t_show(struct seq_file *m, void *v) |
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c index 90f134764837..7402144bff21 100644 --- a/kernel/trace/trace_functions.c +++ b/kernel/trace/trace_functions.c | |||
@@ -302,8 +302,7 @@ ftrace_trace_onoff_print(struct seq_file *m, unsigned long ip, | |||
302 | if (count == -1) | 302 | if (count == -1) |
303 | seq_printf(m, ":unlimited\n"); | 303 | seq_printf(m, ":unlimited\n"); |
304 | else | 304 | else |
305 | seq_printf(m, ":count=%ld", count); | 305 | seq_printf(m, ":count=%ld\n", count); |
306 | seq_putc(m, '\n'); | ||
307 | 306 | ||
308 | return 0; | 307 | return 0; |
309 | } | 308 | } |
diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c index 9bece9687b62..7b6278110827 100644 --- a/kernel/trace/trace_printk.c +++ b/kernel/trace/trace_printk.c | |||
@@ -155,25 +155,19 @@ int __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap) | |||
155 | EXPORT_SYMBOL_GPL(__ftrace_vprintk); | 155 | EXPORT_SYMBOL_GPL(__ftrace_vprintk); |
156 | 156 | ||
157 | static void * | 157 | static void * |
158 | t_next(struct seq_file *m, void *v, loff_t *pos) | 158 | t_start(struct seq_file *m, loff_t *pos) |
159 | { | 159 | { |
160 | const char **fmt = m->private; | 160 | const char **fmt = __start___trace_bprintk_fmt + *pos; |
161 | const char **next = fmt; | ||
162 | |||
163 | (*pos)++; | ||
164 | 161 | ||
165 | if ((unsigned long)fmt >= (unsigned long)__stop___trace_bprintk_fmt) | 162 | if ((unsigned long)fmt >= (unsigned long)__stop___trace_bprintk_fmt) |
166 | return NULL; | 163 | return NULL; |
167 | |||
168 | next = fmt; | ||
169 | m->private = ++next; | ||
170 | |||
171 | return fmt; | 164 | return fmt; |
172 | } | 165 | } |
173 | 166 | ||
174 | static void *t_start(struct seq_file *m, loff_t *pos) | 167 | static void *t_next(struct seq_file *m, void * v, loff_t *pos) |
175 | { | 168 | { |
176 | return t_next(m, NULL, pos); | 169 | (*pos)++; |
170 | return t_start(m, pos); | ||
177 | } | 171 | } |
178 | 172 | ||
179 | static int t_show(struct seq_file *m, void *v) | 173 | static int t_show(struct seq_file *m, void *v) |
@@ -224,15 +218,7 @@ static const struct seq_operations show_format_seq_ops = { | |||
224 | static int | 218 | static int |
225 | ftrace_formats_open(struct inode *inode, struct file *file) | 219 | ftrace_formats_open(struct inode *inode, struct file *file) |
226 | { | 220 | { |
227 | int ret; | 221 | return seq_open(file, &show_format_seq_ops); |
228 | |||
229 | ret = seq_open(file, &show_format_seq_ops); | ||
230 | if (!ret) { | ||
231 | struct seq_file *m = file->private_data; | ||
232 | |||
233 | m->private = __start___trace_bprintk_fmt; | ||
234 | } | ||
235 | return ret; | ||
236 | } | 222 | } |
237 | 223 | ||
238 | static const struct file_operations ftrace_formats_fops = { | 224 | static const struct file_operations ftrace_formats_fops = { |
diff --git a/kernel/trace/trace_stat.c b/kernel/trace/trace_stat.c index c00643733f4c..e66f5e493342 100644 --- a/kernel/trace/trace_stat.c +++ b/kernel/trace/trace_stat.c | |||
@@ -199,17 +199,13 @@ static void *stat_seq_start(struct seq_file *s, loff_t *pos) | |||
199 | mutex_lock(&session->stat_mutex); | 199 | mutex_lock(&session->stat_mutex); |
200 | 200 | ||
201 | /* If we are in the beginning of the file, print the headers */ | 201 | /* If we are in the beginning of the file, print the headers */ |
202 | if (!*pos && session->ts->stat_headers) { | 202 | if (!*pos && session->ts->stat_headers) |
203 | (*pos)++; | ||
204 | return SEQ_START_TOKEN; | 203 | return SEQ_START_TOKEN; |
205 | } | ||
206 | 204 | ||
207 | node = rb_first(&session->stat_root); | 205 | node = rb_first(&session->stat_root); |
208 | for (i = 0; node && i < *pos; i++) | 206 | for (i = 0; node && i < *pos; i++) |
209 | node = rb_next(node); | 207 | node = rb_next(node); |
210 | 208 | ||
211 | (*pos)++; | ||
212 | |||
213 | return node; | 209 | return node; |
214 | } | 210 | } |
215 | 211 | ||
diff --git a/mm/memory.c b/mm/memory.c index f46ac18ba231..65216194eb8d 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1207,8 +1207,8 @@ static inline int use_zero_page(struct vm_area_struct *vma) | |||
1207 | 1207 | ||
1208 | 1208 | ||
1209 | int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | 1209 | int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
1210 | unsigned long start, int len, int flags, | 1210 | unsigned long start, int nr_pages, int flags, |
1211 | struct page **pages, struct vm_area_struct **vmas) | 1211 | struct page **pages, struct vm_area_struct **vmas) |
1212 | { | 1212 | { |
1213 | int i; | 1213 | int i; |
1214 | unsigned int vm_flags = 0; | 1214 | unsigned int vm_flags = 0; |
@@ -1217,7 +1217,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1217 | int ignore = !!(flags & GUP_FLAGS_IGNORE_VMA_PERMISSIONS); | 1217 | int ignore = !!(flags & GUP_FLAGS_IGNORE_VMA_PERMISSIONS); |
1218 | int ignore_sigkill = !!(flags & GUP_FLAGS_IGNORE_SIGKILL); | 1218 | int ignore_sigkill = !!(flags & GUP_FLAGS_IGNORE_SIGKILL); |
1219 | 1219 | ||
1220 | if (len <= 0) | 1220 | if (nr_pages <= 0) |
1221 | return 0; | 1221 | return 0; |
1222 | /* | 1222 | /* |
1223 | * Require read or write permissions. | 1223 | * Require read or write permissions. |
@@ -1269,7 +1269,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1269 | vmas[i] = gate_vma; | 1269 | vmas[i] = gate_vma; |
1270 | i++; | 1270 | i++; |
1271 | start += PAGE_SIZE; | 1271 | start += PAGE_SIZE; |
1272 | len--; | 1272 | nr_pages--; |
1273 | continue; | 1273 | continue; |
1274 | } | 1274 | } |
1275 | 1275 | ||
@@ -1280,7 +1280,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1280 | 1280 | ||
1281 | if (is_vm_hugetlb_page(vma)) { | 1281 | if (is_vm_hugetlb_page(vma)) { |
1282 | i = follow_hugetlb_page(mm, vma, pages, vmas, | 1282 | i = follow_hugetlb_page(mm, vma, pages, vmas, |
1283 | &start, &len, i, write); | 1283 | &start, &nr_pages, i, write); |
1284 | continue; | 1284 | continue; |
1285 | } | 1285 | } |
1286 | 1286 | ||
@@ -1357,9 +1357,9 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1357 | vmas[i] = vma; | 1357 | vmas[i] = vma; |
1358 | i++; | 1358 | i++; |
1359 | start += PAGE_SIZE; | 1359 | start += PAGE_SIZE; |
1360 | len--; | 1360 | nr_pages--; |
1361 | } while (len && start < vma->vm_end); | 1361 | } while (nr_pages && start < vma->vm_end); |
1362 | } while (len); | 1362 | } while (nr_pages); |
1363 | return i; | 1363 | return i; |
1364 | } | 1364 | } |
1365 | 1365 | ||
@@ -1368,7 +1368,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1368 | * @tsk: task_struct of target task | 1368 | * @tsk: task_struct of target task |
1369 | * @mm: mm_struct of target mm | 1369 | * @mm: mm_struct of target mm |
1370 | * @start: starting user address | 1370 | * @start: starting user address |
1371 | * @len: number of pages from start to pin | 1371 | * @nr_pages: number of pages from start to pin |
1372 | * @write: whether pages will be written to by the caller | 1372 | * @write: whether pages will be written to by the caller |
1373 | * @force: whether to force write access even if user mapping is | 1373 | * @force: whether to force write access even if user mapping is |
1374 | * readonly. This will result in the page being COWed even | 1374 | * readonly. This will result in the page being COWed even |
@@ -1380,7 +1380,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1380 | * Or NULL if the caller does not require them. | 1380 | * Or NULL if the caller does not require them. |
1381 | * | 1381 | * |
1382 | * Returns number of pages pinned. This may be fewer than the number | 1382 | * Returns number of pages pinned. This may be fewer than the number |
1383 | * requested. If len is 0 or negative, returns 0. If no pages | 1383 | * requested. If nr_pages is 0 or negative, returns 0. If no pages |
1384 | * were pinned, returns -errno. Each page returned must be released | 1384 | * were pinned, returns -errno. Each page returned must be released |
1385 | * with a put_page() call when it is finished with. vmas will only | 1385 | * with a put_page() call when it is finished with. vmas will only |
1386 | * remain valid while mmap_sem is held. | 1386 | * remain valid while mmap_sem is held. |
@@ -1414,7 +1414,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1414 | * See also get_user_pages_fast, for performance critical applications. | 1414 | * See also get_user_pages_fast, for performance critical applications. |
1415 | */ | 1415 | */ |
1416 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | 1416 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
1417 | unsigned long start, int len, int write, int force, | 1417 | unsigned long start, int nr_pages, int write, int force, |
1418 | struct page **pages, struct vm_area_struct **vmas) | 1418 | struct page **pages, struct vm_area_struct **vmas) |
1419 | { | 1419 | { |
1420 | int flags = 0; | 1420 | int flags = 0; |
@@ -1424,9 +1424,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
1424 | if (force) | 1424 | if (force) |
1425 | flags |= GUP_FLAGS_FORCE; | 1425 | flags |= GUP_FLAGS_FORCE; |
1426 | 1426 | ||
1427 | return __get_user_pages(tsk, mm, | 1427 | return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas); |
1428 | start, len, flags, | ||
1429 | pages, vmas); | ||
1430 | } | 1428 | } |
1431 | 1429 | ||
1432 | EXPORT_SYMBOL(get_user_pages); | 1430 | EXPORT_SYMBOL(get_user_pages); |
diff --git a/mm/nommu.c b/mm/nommu.c index 2fd2ad5da98e..bf0cc762a7d2 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -173,8 +173,8 @@ unsigned int kobjsize(const void *objp) | |||
173 | } | 173 | } |
174 | 174 | ||
175 | int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | 175 | int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
176 | unsigned long start, int len, int flags, | 176 | unsigned long start, int nr_pages, int flags, |
177 | struct page **pages, struct vm_area_struct **vmas) | 177 | struct page **pages, struct vm_area_struct **vmas) |
178 | { | 178 | { |
179 | struct vm_area_struct *vma; | 179 | struct vm_area_struct *vma; |
180 | unsigned long vm_flags; | 180 | unsigned long vm_flags; |
@@ -189,7 +189,7 @@ int __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
189 | vm_flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD); | 189 | vm_flags = write ? (VM_WRITE | VM_MAYWRITE) : (VM_READ | VM_MAYREAD); |
190 | vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); | 190 | vm_flags &= force ? (VM_MAYREAD | VM_MAYWRITE) : (VM_READ | VM_WRITE); |
191 | 191 | ||
192 | for (i = 0; i < len; i++) { | 192 | for (i = 0; i < nr_pages; i++) { |
193 | vma = find_vma(mm, start); | 193 | vma = find_vma(mm, start); |
194 | if (!vma) | 194 | if (!vma) |
195 | goto finish_or_fault; | 195 | goto finish_or_fault; |
@@ -224,7 +224,7 @@ finish_or_fault: | |||
224 | * - don't permit access to VMAs that don't support it, such as I/O mappings | 224 | * - don't permit access to VMAs that don't support it, such as I/O mappings |
225 | */ | 225 | */ |
226 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | 226 | int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, |
227 | unsigned long start, int len, int write, int force, | 227 | unsigned long start, int nr_pages, int write, int force, |
228 | struct page **pages, struct vm_area_struct **vmas) | 228 | struct page **pages, struct vm_area_struct **vmas) |
229 | { | 229 | { |
230 | int flags = 0; | 230 | int flags = 0; |
@@ -234,9 +234,7 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, | |||
234 | if (force) | 234 | if (force) |
235 | flags |= GUP_FLAGS_FORCE; | 235 | flags |= GUP_FLAGS_FORCE; |
236 | 236 | ||
237 | return __get_user_pages(tsk, mm, | 237 | return __get_user_pages(tsk, mm, start, nr_pages, flags, pages, vmas); |
238 | start, len, flags, | ||
239 | pages, vmas); | ||
240 | } | 238 | } |
241 | EXPORT_SYMBOL(get_user_pages); | 239 | EXPORT_SYMBOL(get_user_pages); |
242 | 240 | ||
diff --git a/mm/percpu.c b/mm/percpu.c index c0b2c1a76e81..b70f2acd8853 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -549,14 +549,14 @@ static void pcpu_free_area(struct pcpu_chunk *chunk, int freeme) | |||
549 | * @chunk: chunk of interest | 549 | * @chunk: chunk of interest |
550 | * @page_start: page index of the first page to unmap | 550 | * @page_start: page index of the first page to unmap |
551 | * @page_end: page index of the last page to unmap + 1 | 551 | * @page_end: page index of the last page to unmap + 1 |
552 | * @flush: whether to flush cache and tlb or not | 552 | * @flush_tlb: whether to flush tlb or not |
553 | * | 553 | * |
554 | * For each cpu, unmap pages [@page_start,@page_end) out of @chunk. | 554 | * For each cpu, unmap pages [@page_start,@page_end) out of @chunk. |
555 | * If @flush is true, vcache is flushed before unmapping and tlb | 555 | * If @flush is true, vcache is flushed before unmapping and tlb |
556 | * after. | 556 | * after. |
557 | */ | 557 | */ |
558 | static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end, | 558 | static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end, |
559 | bool flush) | 559 | bool flush_tlb) |
560 | { | 560 | { |
561 | unsigned int last = num_possible_cpus() - 1; | 561 | unsigned int last = num_possible_cpus() - 1; |
562 | unsigned int cpu; | 562 | unsigned int cpu; |
@@ -569,9 +569,8 @@ static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end, | |||
569 | * the whole region at once rather than doing it for each cpu. | 569 | * the whole region at once rather than doing it for each cpu. |
570 | * This could be an overkill but is more scalable. | 570 | * This could be an overkill but is more scalable. |
571 | */ | 571 | */ |
572 | if (flush) | 572 | flush_cache_vunmap(pcpu_chunk_addr(chunk, 0, page_start), |
573 | flush_cache_vunmap(pcpu_chunk_addr(chunk, 0, page_start), | 573 | pcpu_chunk_addr(chunk, last, page_end)); |
574 | pcpu_chunk_addr(chunk, last, page_end)); | ||
575 | 574 | ||
576 | for_each_possible_cpu(cpu) | 575 | for_each_possible_cpu(cpu) |
577 | unmap_kernel_range_noflush( | 576 | unmap_kernel_range_noflush( |
@@ -579,7 +578,7 @@ static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end, | |||
579 | (page_end - page_start) << PAGE_SHIFT); | 578 | (page_end - page_start) << PAGE_SHIFT); |
580 | 579 | ||
581 | /* ditto as flush_cache_vunmap() */ | 580 | /* ditto as flush_cache_vunmap() */ |
582 | if (flush) | 581 | if (flush_tlb) |
583 | flush_tlb_kernel_range(pcpu_chunk_addr(chunk, 0, page_start), | 582 | flush_tlb_kernel_range(pcpu_chunk_addr(chunk, 0, page_start), |
584 | pcpu_chunk_addr(chunk, last, page_end)); | 583 | pcpu_chunk_addr(chunk, last, page_end)); |
585 | } | 584 | } |
@@ -1234,6 +1233,7 @@ static struct page * __init pcpue_get_page(unsigned int cpu, int pageno) | |||
1234 | ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size, | 1233 | ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size, |
1235 | ssize_t dyn_size, ssize_t unit_size) | 1234 | ssize_t dyn_size, ssize_t unit_size) |
1236 | { | 1235 | { |
1236 | size_t chunk_size; | ||
1237 | unsigned int cpu; | 1237 | unsigned int cpu; |
1238 | 1238 | ||
1239 | /* determine parameters and allocate */ | 1239 | /* determine parameters and allocate */ |
@@ -1248,11 +1248,15 @@ ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size, | |||
1248 | } else | 1248 | } else |
1249 | pcpue_unit_size = max_t(size_t, pcpue_size, PCPU_MIN_UNIT_SIZE); | 1249 | pcpue_unit_size = max_t(size_t, pcpue_size, PCPU_MIN_UNIT_SIZE); |
1250 | 1250 | ||
1251 | pcpue_ptr = __alloc_bootmem_nopanic( | 1251 | chunk_size = pcpue_unit_size * num_possible_cpus(); |
1252 | num_possible_cpus() * pcpue_unit_size, | 1252 | |
1253 | PAGE_SIZE, __pa(MAX_DMA_ADDRESS)); | 1253 | pcpue_ptr = __alloc_bootmem_nopanic(chunk_size, PAGE_SIZE, |
1254 | if (!pcpue_ptr) | 1254 | __pa(MAX_DMA_ADDRESS)); |
1255 | if (!pcpue_ptr) { | ||
1256 | pr_warning("PERCPU: failed to allocate %zu bytes for " | ||
1257 | "embedding\n", chunk_size); | ||
1255 | return -ENOMEM; | 1258 | return -ENOMEM; |
1259 | } | ||
1256 | 1260 | ||
1257 | /* return the leftover and copy */ | 1261 | /* return the leftover and copy */ |
1258 | for_each_possible_cpu(cpu) { | 1262 | for_each_possible_cpu(cpu) { |
diff --git a/net/bridge/br.c b/net/bridge/br.c index 9aac5213105a..e1241c76239a 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c | |||
@@ -93,7 +93,7 @@ static void __exit br_deinit(void) | |||
93 | 93 | ||
94 | unregister_pernet_subsys(&br_net_ops); | 94 | unregister_pernet_subsys(&br_net_ops); |
95 | 95 | ||
96 | synchronize_net(); | 96 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
97 | 97 | ||
98 | br_netfilter_fini(); | 98 | br_netfilter_fini(); |
99 | #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) | 99 | #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) |
diff --git a/net/core/dev.c b/net/core/dev.c index 60b572812278..70c27e0c7c32 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2823,9 +2823,11 @@ static void net_rx_action(struct softirq_action *h) | |||
2823 | * move the instance around on the list at-will. | 2823 | * move the instance around on the list at-will. |
2824 | */ | 2824 | */ |
2825 | if (unlikely(work == weight)) { | 2825 | if (unlikely(work == weight)) { |
2826 | if (unlikely(napi_disable_pending(n))) | 2826 | if (unlikely(napi_disable_pending(n))) { |
2827 | __napi_complete(n); | 2827 | local_irq_enable(); |
2828 | else | 2828 | napi_complete(n); |
2829 | local_irq_disable(); | ||
2830 | } else | ||
2829 | list_move_tail(&n->poll_list, list); | 2831 | list_move_tail(&n->poll_list, list); |
2830 | } | 2832 | } |
2831 | 2833 | ||
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index d351b8db0df5..77d40289653c 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -2413,6 +2413,8 @@ static void __exit decnet_exit(void) | |||
2413 | proc_net_remove(&init_net, "decnet"); | 2413 | proc_net_remove(&init_net, "decnet"); |
2414 | 2414 | ||
2415 | proto_unregister(&dn_proto); | 2415 | proto_unregister(&dn_proto); |
2416 | |||
2417 | rcu_barrier_bh(); /* Wait for completion of call_rcu_bh()'s */ | ||
2416 | } | 2418 | } |
2417 | module_exit(decnet_exit); | 2419 | module_exit(decnet_exit); |
2418 | #endif | 2420 | #endif |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 490ce20faf38..db46b4b5b2b9 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -440,6 +440,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
440 | /* Remove any debris in the socket control block */ | 440 | /* Remove any debris in the socket control block */ |
441 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | 441 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); |
442 | 442 | ||
443 | /* Must drop socket now because of tproxy. */ | ||
444 | skb_orphan(skb); | ||
445 | |||
443 | return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL, | 446 | return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL, |
444 | ip_rcv_finish); | 447 | ip_rcv_finish); |
445 | 448 | ||
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 43bbba7926ee..f8d67ccc64f3 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -128,7 +128,8 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, | |||
128 | goto kill_with_rst; | 128 | goto kill_with_rst; |
129 | 129 | ||
130 | /* Dup ACK? */ | 130 | /* Dup ACK? */ |
131 | if (!after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || | 131 | if (!th->ack || |
132 | !after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || | ||
132 | TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { | 133 | TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { |
133 | inet_twsk_put(tw); | 134 | inet_twsk_put(tw); |
134 | return TCP_TW_SUCCESS; | 135 | return TCP_TW_SUCCESS; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8c1e86afbbf5..3883b4036a74 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3362,7 +3362,10 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | |||
3362 | valid = ifa->valid_lft; | 3362 | valid = ifa->valid_lft; |
3363 | if (preferred != INFINITY_LIFE_TIME) { | 3363 | if (preferred != INFINITY_LIFE_TIME) { |
3364 | long tval = (jiffies - ifa->tstamp)/HZ; | 3364 | long tval = (jiffies - ifa->tstamp)/HZ; |
3365 | preferred -= tval; | 3365 | if (preferred > tval) |
3366 | preferred -= tval; | ||
3367 | else | ||
3368 | preferred = 0; | ||
3366 | if (valid != INFINITY_LIFE_TIME) | 3369 | if (valid != INFINITY_LIFE_TIME) |
3367 | valid -= tval; | 3370 | valid -= tval; |
3368 | } | 3371 | } |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 85b3d0036afd..caa0278d30a9 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -1284,6 +1284,8 @@ static void __exit inet6_exit(void) | |||
1284 | proto_unregister(&udplitev6_prot); | 1284 | proto_unregister(&udplitev6_prot); |
1285 | proto_unregister(&udpv6_prot); | 1285 | proto_unregister(&udpv6_prot); |
1286 | proto_unregister(&tcpv6_prot); | 1286 | proto_unregister(&tcpv6_prot); |
1287 | |||
1288 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | ||
1287 | } | 1289 | } |
1288 | module_exit(inet6_exit); | 1290 | module_exit(inet6_exit); |
1289 | 1291 | ||
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index c3a07d75b5f5..6d6a4277c677 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -139,6 +139,9 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
139 | 139 | ||
140 | rcu_read_unlock(); | 140 | rcu_read_unlock(); |
141 | 141 | ||
142 | /* Must drop socket now because of tproxy. */ | ||
143 | skb_orphan(skb); | ||
144 | |||
142 | return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, | 145 | return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, |
143 | ip6_rcv_finish); | 146 | ip6_rcv_finish); |
144 | err: | 147 | err: |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index fc712e60705d..11cf45bce38a 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -494,7 +494,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | |||
494 | * should it be using the interface and enqueuing | 494 | * should it be using the interface and enqueuing |
495 | * frames at this very time on another CPU. | 495 | * frames at this very time on another CPU. |
496 | */ | 496 | */ |
497 | synchronize_rcu(); | 497 | rcu_barrier(); /* Wait for RX path and call_rcu()'s */ |
498 | skb_queue_purge(&sdata->u.mesh.skb_queue); | 498 | skb_queue_purge(&sdata->u.mesh.skb_queue); |
499 | } | 499 | } |
500 | 500 | ||
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 80a322d77909..b0d6ddd82a9d 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c | |||
@@ -69,10 +69,27 @@ static struct phonet_device *__phonet_get(struct net_device *dev) | |||
69 | return NULL; | 69 | return NULL; |
70 | } | 70 | } |
71 | 71 | ||
72 | static void __phonet_device_free(struct phonet_device *pnd) | 72 | static void phonet_device_destroy(struct net_device *dev) |
73 | { | 73 | { |
74 | list_del(&pnd->list); | 74 | struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); |
75 | kfree(pnd); | 75 | struct phonet_device *pnd; |
76 | |||
77 | ASSERT_RTNL(); | ||
78 | |||
79 | spin_lock_bh(&pndevs->lock); | ||
80 | pnd = __phonet_get(dev); | ||
81 | if (pnd) | ||
82 | list_del(&pnd->list); | ||
83 | spin_unlock_bh(&pndevs->lock); | ||
84 | |||
85 | if (pnd) { | ||
86 | u8 addr; | ||
87 | |||
88 | for (addr = find_first_bit(pnd->addrs, 64); addr < 64; | ||
89 | addr = find_next_bit(pnd->addrs, 64, 1+addr)) | ||
90 | phonet_address_notify(RTM_DELADDR, dev, addr); | ||
91 | kfree(pnd); | ||
92 | } | ||
76 | } | 93 | } |
77 | 94 | ||
78 | struct net_device *phonet_device_get(struct net *net) | 95 | struct net_device *phonet_device_get(struct net *net) |
@@ -126,8 +143,10 @@ int phonet_address_del(struct net_device *dev, u8 addr) | |||
126 | pnd = __phonet_get(dev); | 143 | pnd = __phonet_get(dev); |
127 | if (!pnd || !test_and_clear_bit(addr >> 2, pnd->addrs)) | 144 | if (!pnd || !test_and_clear_bit(addr >> 2, pnd->addrs)) |
128 | err = -EADDRNOTAVAIL; | 145 | err = -EADDRNOTAVAIL; |
129 | else if (bitmap_empty(pnd->addrs, 64)) | 146 | else if (bitmap_empty(pnd->addrs, 64)) { |
130 | __phonet_device_free(pnd); | 147 | list_del(&pnd->list); |
148 | kfree(pnd); | ||
149 | } | ||
131 | spin_unlock_bh(&pndevs->lock); | 150 | spin_unlock_bh(&pndevs->lock); |
132 | return err; | 151 | return err; |
133 | } | 152 | } |
@@ -181,18 +200,8 @@ static int phonet_device_notify(struct notifier_block *me, unsigned long what, | |||
181 | { | 200 | { |
182 | struct net_device *dev = arg; | 201 | struct net_device *dev = arg; |
183 | 202 | ||
184 | if (what == NETDEV_UNREGISTER) { | 203 | if (what == NETDEV_UNREGISTER) |
185 | struct phonet_device_list *pndevs; | 204 | phonet_device_destroy(dev); |
186 | struct phonet_device *pnd; | ||
187 | |||
188 | /* Destroy phonet-specific device data */ | ||
189 | pndevs = phonet_device_list(dev_net(dev)); | ||
190 | spin_lock_bh(&pndevs->lock); | ||
191 | pnd = __phonet_get(dev); | ||
192 | if (pnd) | ||
193 | __phonet_device_free(pnd); | ||
194 | spin_unlock_bh(&pndevs->lock); | ||
195 | } | ||
196 | return 0; | 205 | return 0; |
197 | 206 | ||
198 | } | 207 | } |
@@ -218,11 +227,12 @@ static int phonet_init_net(struct net *net) | |||
218 | static void phonet_exit_net(struct net *net) | 227 | static void phonet_exit_net(struct net *net) |
219 | { | 228 | { |
220 | struct phonet_net *pnn = net_generic(net, phonet_net_id); | 229 | struct phonet_net *pnn = net_generic(net, phonet_net_id); |
221 | struct phonet_device *pnd, *n; | 230 | struct net_device *dev; |
222 | |||
223 | list_for_each_entry_safe(pnd, n, &pnn->pndevs.list, list) | ||
224 | __phonet_device_free(pnd); | ||
225 | 231 | ||
232 | rtnl_lock(); | ||
233 | for_each_netdev(net, dev) | ||
234 | phonet_device_destroy(dev); | ||
235 | rtnl_unlock(); | ||
226 | kfree(pnn); | 236 | kfree(pnn); |
227 | } | 237 | } |
228 | 238 | ||
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index cec4e5951681..f8b4cee434c2 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c | |||
@@ -32,7 +32,7 @@ | |||
32 | static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr, | 32 | static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr, |
33 | u32 pid, u32 seq, int event); | 33 | u32 pid, u32 seq, int event); |
34 | 34 | ||
35 | static void rtmsg_notify(int event, struct net_device *dev, u8 addr) | 35 | void phonet_address_notify(int event, struct net_device *dev, u8 addr) |
36 | { | 36 | { |
37 | struct sk_buff *skb; | 37 | struct sk_buff *skb; |
38 | int err = -ENOBUFS; | 38 | int err = -ENOBUFS; |
@@ -94,7 +94,7 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr) | |||
94 | else | 94 | else |
95 | err = phonet_address_del(dev, pnaddr); | 95 | err = phonet_address_del(dev, pnaddr); |
96 | if (!err) | 96 | if (!err) |
97 | rtmsg_notify(nlh->nlmsg_type, dev, pnaddr); | 97 | phonet_address_notify(nlh->nlmsg_type, dev, pnaddr); |
98 | return err; | 98 | return err; |
99 | } | 99 | } |
100 | 100 | ||
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 843629f55763..adaa81982f74 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
@@ -66,6 +66,7 @@ cleanup_sunrpc(void) | |||
66 | #ifdef CONFIG_PROC_FS | 66 | #ifdef CONFIG_PROC_FS |
67 | rpc_proc_exit(); | 67 | rpc_proc_exit(); |
68 | #endif | 68 | #endif |
69 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | ||
69 | } | 70 | } |
70 | MODULE_LICENSE("GPL"); | 71 | MODULE_LICENSE("GPL"); |
71 | module_init(init_sunrpc); | 72 | module_init(init_sunrpc); |
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index d31ccb487730..faf54c6bf96b 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -292,8 +292,8 @@ static struct xfrm_algo_desc ealg_list[] = { | |||
292 | } | 292 | } |
293 | }, | 293 | }, |
294 | { | 294 | { |
295 | .name = "cbc(cast128)", | 295 | .name = "cbc(cast5)", |
296 | .compat = "cast128", | 296 | .compat = "cast5", |
297 | 297 | ||
298 | .uinfo = { | 298 | .uinfo = { |
299 | .encr = { | 299 | .encr = { |
diff --git a/scripts/dtc/.gitignore b/scripts/dtc/.gitignore new file mode 100644 index 000000000000..095acb49a374 --- /dev/null +++ b/scripts/dtc/.gitignore | |||
@@ -0,0 +1,5 @@ | |||
1 | dtc | ||
2 | dtc-lexer.lex.c | ||
3 | dtc-parser.tab.c | ||
4 | dtc-parser.tab.h | ||
5 | |||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 6f611874d10e..101c512564ec 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -238,7 +238,34 @@ out: | |||
238 | } | 238 | } |
239 | 239 | ||
240 | /* | 240 | /* |
241 | * ima_opens_get - increment file counts | 241 | * ima_counts_put - decrement file counts |
242 | * | ||
243 | * File counts are incremented in ima_path_check. On file open | ||
244 | * error, such as ETXTBSY, decrement the counts to prevent | ||
245 | * unnecessary imbalance messages. | ||
246 | */ | ||
247 | void ima_counts_put(struct path *path, int mask) | ||
248 | { | ||
249 | struct inode *inode = path->dentry->d_inode; | ||
250 | struct ima_iint_cache *iint; | ||
251 | |||
252 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | ||
253 | return; | ||
254 | iint = ima_iint_find_insert_get(inode); | ||
255 | if (!iint) | ||
256 | return; | ||
257 | |||
258 | mutex_lock(&iint->mutex); | ||
259 | iint->opencount--; | ||
260 | if ((mask & MAY_WRITE) || (mask == 0)) | ||
261 | iint->writecount--; | ||
262 | else if (mask & (MAY_READ | MAY_EXEC)) | ||
263 | iint->readcount--; | ||
264 | mutex_unlock(&iint->mutex); | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * ima_counts_get - increment file counts | ||
242 | * | 269 | * |
243 | * - for IPC shm and shmat file. | 270 | * - for IPC shm and shmat file. |
244 | * - for nfsd exported files. | 271 | * - for nfsd exported files. |
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 7ec94314ac0c..a0880e9c8e05 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c | |||
@@ -134,7 +134,8 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, | |||
134 | } | 134 | } |
135 | out: | 135 | out: |
136 | mutex_unlock(&ima_extend_list_mutex); | 136 | mutex_unlock(&ima_extend_list_mutex); |
137 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, entry->template_name, | 137 | integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, |
138 | entry->template.file_name, | ||
138 | op, audit_cause, result, audit_info); | 139 | op, audit_cause, result, audit_info); |
139 | return result; | 140 | return result; |
140 | } | 141 | } |
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index de83608719ea..3ee0269e5bd0 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c | |||
@@ -338,7 +338,7 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard, | |||
338 | return -EBUSY; | 338 | return -EBUSY; |
339 | 339 | ||
340 | acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL); | 340 | acard->mpu = pnp_request_card_device(card, id->devs[2].id, NULL); |
341 | if (acard->play == NULL) | 341 | if (acard->mpu == NULL) |
342 | return -EBUSY; | 342 | return -EBUSY; |
343 | 343 | ||
344 | pdev = acard->cap; | 344 | pdev = acard->cap; |
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c index c180598f1710..89466b056be7 100644 --- a/sound/oss/kahlua.c +++ b/sound/oss/kahlua.c | |||
@@ -199,7 +199,7 @@ MODULE_LICENSE("GPL"); | |||
199 | */ | 199 | */ |
200 | 200 | ||
201 | static struct pci_device_id id_tbl[] = { | 201 | static struct pci_device_id id_tbl[] = { |
202 | { PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 202 | { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO), 0 }, |
203 | { } | 203 | { } |
204 | }; | 204 | }; |
205 | 205 | ||
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c index 6c0a770ed054..1b2316f35b1f 100644 --- a/sound/oss/mpu401.c +++ b/sound/oss/mpu401.c | |||
@@ -926,31 +926,21 @@ static struct midi_operations mpu401_midi_operations[MAX_MIDI_DEV]; | |||
926 | static void mpu401_chk_version(int n, struct mpu_config *devc) | 926 | static void mpu401_chk_version(int n, struct mpu_config *devc) |
927 | { | 927 | { |
928 | int tmp; | 928 | int tmp; |
929 | unsigned long flags; | ||
930 | 929 | ||
931 | devc->version = devc->revision = 0; | 930 | devc->version = devc->revision = 0; |
932 | 931 | ||
933 | spin_lock_irqsave(&devc->lock,flags); | 932 | tmp = mpu_cmd(n, 0xAC, 0); |
934 | if ((tmp = mpu_cmd(n, 0xAC, 0)) < 0) | 933 | if (tmp < 0) |
935 | { | ||
936 | spin_unlock_irqrestore(&devc->lock,flags); | ||
937 | return; | 934 | return; |
938 | } | ||
939 | if ((tmp & 0xf0) > 0x20) /* Why it's larger than 2.x ??? */ | 935 | if ((tmp & 0xf0) > 0x20) /* Why it's larger than 2.x ??? */ |
940 | { | ||
941 | spin_unlock_irqrestore(&devc->lock,flags); | ||
942 | return; | 936 | return; |
943 | } | ||
944 | devc->version = tmp; | 937 | devc->version = tmp; |
945 | 938 | ||
946 | if ((tmp = mpu_cmd(n, 0xAD, 0)) < 0) | 939 | if ((tmp = mpu_cmd(n, 0xAD, 0)) < 0) { |
947 | { | ||
948 | devc->version = 0; | 940 | devc->version = 0; |
949 | spin_unlock_irqrestore(&devc->lock,flags); | ||
950 | return; | 941 | return; |
951 | } | 942 | } |
952 | devc->revision = tmp; | 943 | devc->revision = tmp; |
953 | spin_unlock_irqrestore(&devc->lock,flags); | ||
954 | } | 944 | } |
955 | 945 | ||
956 | int attach_mpu401(struct address_info *hw_config, struct module *owner) | 946 | int attach_mpu401(struct address_info *hw_config, struct module *owner) |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 71515ddb4593..d6752dff2a44 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -287,10 +287,10 @@ struct atiixp { | |||
287 | /* | 287 | /* |
288 | */ | 288 | */ |
289 | static struct pci_device_id snd_atiixp_ids[] = { | 289 | static struct pci_device_id snd_atiixp_ids[] = { |
290 | { 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ | 290 | { PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */ |
291 | { 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */ | 291 | { PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */ |
292 | { 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */ | 292 | { PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */ |
293 | { 0x1002, 0x4382, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB600 */ | 293 | { PCI_VDEVICE(ATI, 0x4382), 0 }, /* SB600 */ |
294 | { 0, } | 294 | { 0, } |
295 | }; | 295 | }; |
296 | 296 | ||
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index c3136cccc559..e7e147bf8eb2 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c | |||
@@ -262,8 +262,8 @@ struct atiixp_modem { | |||
262 | /* | 262 | /* |
263 | */ | 263 | */ |
264 | static struct pci_device_id snd_atiixp_ids[] = { | 264 | static struct pci_device_id snd_atiixp_ids[] = { |
265 | { 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ | 265 | { PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */ |
266 | { 0x1002, 0x4378, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */ | 266 | { PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */ |
267 | { 0, } | 267 | { 0, } |
268 | }; | 268 | }; |
269 | 269 | ||
diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c index fce22c7af0ea..c0e8c6b295cb 100644 --- a/sound/pci/au88x0/au8810.c +++ b/sound/pci/au88x0/au8810.c | |||
@@ -1,8 +1,7 @@ | |||
1 | #include "au8810.h" | 1 | #include "au8810.h" |
2 | #include "au88x0.h" | 2 | #include "au88x0.h" |
3 | static struct pci_device_id snd_vortex_ids[] = { | 3 | static struct pci_device_id snd_vortex_ids[] = { |
4 | {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE, | 4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,}, |
5 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1,}, | ||
6 | {0,} | 5 | {0,} |
7 | }; | 6 | }; |
8 | 7 | ||
diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c index d1fbcce07257..a6527330df58 100644 --- a/sound/pci/au88x0/au8820.c +++ b/sound/pci/au88x0/au8820.c | |||
@@ -1,8 +1,7 @@ | |||
1 | #include "au8820.h" | 1 | #include "au8820.h" |
2 | #include "au88x0.h" | 2 | #include "au88x0.h" |
3 | static struct pci_device_id snd_vortex_ids[] = { | 3 | static struct pci_device_id snd_vortex_ids[] = { |
4 | {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1, | 4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,}, |
5 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, | ||
6 | {0,} | 5 | {0,} |
7 | }; | 6 | }; |
8 | 7 | ||
diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c index d4f2717c14fb..6c702ad4352a 100644 --- a/sound/pci/au88x0/au8830.c +++ b/sound/pci/au88x0/au8830.c | |||
@@ -1,8 +1,7 @@ | |||
1 | #include "au8830.h" | 1 | #include "au8830.h" |
2 | #include "au88x0.h" | 2 | #include "au88x0.h" |
3 | static struct pci_device_id snd_vortex_ids[] = { | 3 | static struct pci_device_id snd_vortex_ids[] = { |
4 | {PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2, | 4 | {PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,}, |
5 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, | ||
6 | {0,} | 5 | {0,} |
7 | }; | 6 | }; |
8 | 7 | ||
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 57b992a5c057..f24bf1ecb36d 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c | |||
@@ -1876,7 +1876,7 @@ static int snd_ca0106_resume(struct pci_dev *pci) | |||
1876 | 1876 | ||
1877 | // PCI IDs | 1877 | // PCI IDs |
1878 | static struct pci_device_id snd_ca0106_ids[] = { | 1878 | static struct pci_device_id snd_ca0106_ids[] = { |
1879 | { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */ | 1879 | { PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */ |
1880 | { 0, } | 1880 | { 0, } |
1881 | }; | 1881 | }; |
1882 | MODULE_DEVICE_TABLE(pci, snd_ca0106_ids); | 1882 | MODULE_DEVICE_TABLE(pci, snd_ca0106_ids); |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 449fe02f666e..ddcd4a9fd7e6 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
@@ -2797,11 +2797,11 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {} | |||
2797 | 2797 | ||
2798 | 2798 | ||
2799 | static struct pci_device_id snd_cmipci_ids[] = { | 2799 | static struct pci_device_id snd_cmipci_ids[] = { |
2800 | {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2800 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0}, |
2801 | {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2801 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0}, |
2802 | {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2802 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0}, |
2803 | {PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2803 | {PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738B), 0}, |
2804 | {PCI_VENDOR_ID_AL, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 2804 | {PCI_VDEVICE(AL, PCI_DEVICE_ID_CMEDIA_CM8738), 0}, |
2805 | {0,}, | 2805 | {0,}, |
2806 | }; | 2806 | }; |
2807 | 2807 | ||
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index f6286f84a221..e2e0359bb056 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c | |||
@@ -495,7 +495,7 @@ struct cs4281 { | |||
495 | static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id); | 495 | static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id); |
496 | 496 | ||
497 | static struct pci_device_id snd_cs4281_ids[] = { | 497 | static struct pci_device_id snd_cs4281_ids[] = { |
498 | { 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4281 */ | 498 | { PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */ |
499 | { 0, } | 499 | { 0, } |
500 | }; | 500 | }; |
501 | 501 | ||
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c index c9b3e3d48cbc..033aec430117 100644 --- a/sound/pci/cs46xx/cs46xx.c +++ b/sound/pci/cs46xx/cs46xx.c | |||
@@ -65,9 +65,9 @@ module_param_array(mmap_valid, bool, NULL, 0444); | |||
65 | MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); | 65 | MODULE_PARM_DESC(mmap_valid, "Support OSS mmap."); |
66 | 66 | ||
67 | static struct pci_device_id snd_cs46xx_ids[] = { | 67 | static struct pci_device_id snd_cs46xx_ids[] = { |
68 | { 0x1013, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4280 */ | 68 | { PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */ |
69 | { 0x1013, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4612 */ | 69 | { PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */ |
70 | { 0x1013, 0x6004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4615 */ | 70 | { PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */ |
71 | { 0, } | 71 | { 0, } |
72 | }; | 72 | }; |
73 | 73 | ||
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c index c7f3b994101c..168af67d938e 100644 --- a/sound/pci/emu10k1/emu10k1.c +++ b/sound/pci/emu10k1/emu10k1.c | |||
@@ -77,9 +77,9 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model."); | |||
77 | * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 | 77 | * Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400 |
78 | */ | 78 | */ |
79 | static struct pci_device_id snd_emu10k1_ids[] = { | 79 | static struct pci_device_id snd_emu10k1_ids[] = { |
80 | { 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* EMU10K1 */ | 80 | { PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */ |
81 | { 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy */ | 81 | { PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */ |
82 | { 0x1102, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy 2 Value SB0400 */ | 82 | { PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */ |
83 | { 0, } | 83 | { 0, } |
84 | }; | 84 | }; |
85 | 85 | ||
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 4d3ad793e98f..36e08bd2b3cc 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c | |||
@@ -1607,7 +1607,7 @@ static void __devexit snd_emu10k1x_remove(struct pci_dev *pci) | |||
1607 | 1607 | ||
1608 | // PCI IDs | 1608 | // PCI IDs |
1609 | static struct pci_device_id snd_emu10k1x_ids[] = { | 1609 | static struct pci_device_id snd_emu10k1x_ids[] = { |
1610 | { 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dell OEM version (EMU10K1) */ | 1610 | { PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */ |
1611 | { 0, } | 1611 | { 0, } |
1612 | }; | 1612 | }; |
1613 | MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids); | 1613 | MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids); |
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 18f4d1e98c46..2b82c5c723e1 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c | |||
@@ -445,12 +445,12 @@ static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id); | |||
445 | 445 | ||
446 | static struct pci_device_id snd_audiopci_ids[] = { | 446 | static struct pci_device_id snd_audiopci_ids[] = { |
447 | #ifdef CHIP1370 | 447 | #ifdef CHIP1370 |
448 | { 0x1274, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1370 */ | 448 | { PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */ |
449 | #endif | 449 | #endif |
450 | #ifdef CHIP1371 | 450 | #ifdef CHIP1371 |
451 | { 0x1274, 0x1371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1371 */ | 451 | { PCI_VDEVICE(ENSONIQ, 0x1371), 0, }, /* ES1371 */ |
452 | { 0x1274, 0x5880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1373 - CT5880 */ | 452 | { PCI_VDEVICE(ENSONIQ, 0x5880), 0, }, /* ES1373 - CT5880 */ |
453 | { 0x1102, 0x8938, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ectiva EV1938 */ | 453 | { PCI_VDEVICE(ECTIVA, 0x8938), 0, }, /* Ectiva EV1938 */ |
454 | #endif | 454 | #endif |
455 | { 0, } | 455 | { 0, } |
456 | }; | 456 | }; |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index fbd2ac09aa34..820318ee62c1 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -244,7 +244,7 @@ struct es1938 { | |||
244 | static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id); | 244 | static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id); |
245 | 245 | ||
246 | static struct pci_device_id snd_es1938_ids[] = { | 246 | static struct pci_device_id snd_es1938_ids[] = { |
247 | { 0x125d, 0x1969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Solo-1 */ | 247 | { PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */ |
248 | { 0, } | 248 | { 0, } |
249 | }; | 249 | }; |
250 | 250 | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 84cc49ca9148..1988582d1ab8 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -72,6 +72,7 @@ struct ad198x_spec { | |||
72 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 72 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
73 | 73 | ||
74 | unsigned int jack_present :1; | 74 | unsigned int jack_present :1; |
75 | unsigned int inv_jack_detect:1; | ||
75 | 76 | ||
76 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 77 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
77 | struct hda_loopback_check loopback; | 78 | struct hda_loopback_check loopback; |
@@ -669,39 +670,13 @@ static struct hda_input_mux ad1986a_automic_capture_source = { | |||
669 | }, | 670 | }, |
670 | }; | 671 | }; |
671 | 672 | ||
672 | static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { | 673 | static struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { |
673 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), | 674 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), |
674 | HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), | 675 | HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), |
675 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
676 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
677 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), | ||
678 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), | ||
679 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
680 | HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
681 | HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), | ||
682 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), | ||
683 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), | ||
684 | { | ||
685 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
686 | .name = "Capture Source", | ||
687 | .info = ad198x_mux_enum_info, | ||
688 | .get = ad198x_mux_enum_get, | ||
689 | .put = ad198x_mux_enum_put, | ||
690 | }, | ||
691 | { | ||
692 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
693 | .name = "External Amplifier", | ||
694 | .info = ad198x_eapd_info, | ||
695 | .get = ad198x_eapd_get, | ||
696 | .put = ad198x_eapd_put, | ||
697 | .private_value = 0x1b | (1 << 8), /* port-D, inversed */ | ||
698 | }, | ||
699 | { } /* end */ | 676 | { } /* end */ |
700 | }; | 677 | }; |
701 | 678 | ||
702 | static struct snd_kcontrol_new ad1986a_samsung_mixers[] = { | 679 | static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { |
703 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), | ||
704 | HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), | ||
705 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 680 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
706 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 681 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
707 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), | 682 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), |
@@ -727,6 +702,12 @@ static struct snd_kcontrol_new ad1986a_samsung_mixers[] = { | |||
727 | { } /* end */ | 702 | { } /* end */ |
728 | }; | 703 | }; |
729 | 704 | ||
705 | static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { | ||
706 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), | ||
707 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), | ||
708 | { } /* end */ | ||
709 | }; | ||
710 | |||
730 | /* re-connect the mic boost input according to the jack sensing */ | 711 | /* re-connect the mic boost input according to the jack sensing */ |
731 | static void ad1986a_automic(struct hda_codec *codec) | 712 | static void ad1986a_automic(struct hda_codec *codec) |
732 | { | 713 | { |
@@ -776,8 +757,9 @@ static void ad1986a_hp_automute(struct hda_codec *codec) | |||
776 | unsigned int present; | 757 | unsigned int present; |
777 | 758 | ||
778 | present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); | 759 | present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); |
779 | /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ | 760 | spec->jack_present = !!(present & 0x80000000); |
780 | spec->jack_present = !(present & 0x80000000); | 761 | if (spec->inv_jack_detect) |
762 | spec->jack_present = !spec->jack_present; | ||
781 | ad1986a_update_hp(codec); | 763 | ad1986a_update_hp(codec); |
782 | } | 764 | } |
783 | 765 | ||
@@ -816,7 +798,7 @@ static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
816 | return change; | 798 | return change; |
817 | } | 799 | } |
818 | 800 | ||
819 | static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = { | 801 | static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { |
820 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), | 802 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), |
821 | { | 803 | { |
822 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 804 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -826,33 +808,10 @@ static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = { | |||
826 | .put = ad1986a_hp_master_sw_put, | 808 | .put = ad1986a_hp_master_sw_put, |
827 | .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), | 809 | .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), |
828 | }, | 810 | }, |
829 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
830 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
831 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), | ||
832 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT), | ||
833 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), | ||
834 | HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), | ||
835 | HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), | ||
836 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), | ||
837 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), | ||
838 | { | ||
839 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
840 | .name = "Capture Source", | ||
841 | .info = ad198x_mux_enum_info, | ||
842 | .get = ad198x_mux_enum_get, | ||
843 | .put = ad198x_mux_enum_put, | ||
844 | }, | ||
845 | { | ||
846 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
847 | .name = "External Amplifier", | ||
848 | .info = ad198x_eapd_info, | ||
849 | .get = ad198x_eapd_get, | ||
850 | .put = ad198x_eapd_put, | ||
851 | .private_value = 0x1b | (1 << 8), /* port-D, inversed */ | ||
852 | }, | ||
853 | { } /* end */ | 811 | { } /* end */ |
854 | }; | 812 | }; |
855 | 813 | ||
814 | |||
856 | /* | 815 | /* |
857 | * initialization verbs | 816 | * initialization verbs |
858 | */ | 817 | */ |
@@ -981,6 +940,27 @@ static struct hda_verb ad1986a_hp_init_verbs[] = { | |||
981 | {} | 940 | {} |
982 | }; | 941 | }; |
983 | 942 | ||
943 | static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec, | ||
944 | unsigned int res) | ||
945 | { | ||
946 | switch (res >> 26) { | ||
947 | case AD1986A_HP_EVENT: | ||
948 | ad1986a_hp_automute(codec); | ||
949 | break; | ||
950 | case AD1986A_MIC_EVENT: | ||
951 | ad1986a_automic(codec); | ||
952 | break; | ||
953 | } | ||
954 | } | ||
955 | |||
956 | static int ad1986a_samsung_p50_init(struct hda_codec *codec) | ||
957 | { | ||
958 | ad198x_init(codec); | ||
959 | ad1986a_hp_automute(codec); | ||
960 | ad1986a_automic(codec); | ||
961 | return 0; | ||
962 | } | ||
963 | |||
984 | 964 | ||
985 | /* models */ | 965 | /* models */ |
986 | enum { | 966 | enum { |
@@ -991,6 +971,7 @@ enum { | |||
991 | AD1986A_LAPTOP_AUTOMUTE, | 971 | AD1986A_LAPTOP_AUTOMUTE, |
992 | AD1986A_ULTRA, | 972 | AD1986A_ULTRA, |
993 | AD1986A_SAMSUNG, | 973 | AD1986A_SAMSUNG, |
974 | AD1986A_SAMSUNG_P50, | ||
994 | AD1986A_MODELS | 975 | AD1986A_MODELS |
995 | }; | 976 | }; |
996 | 977 | ||
@@ -1002,6 +983,7 @@ static const char *ad1986a_models[AD1986A_MODELS] = { | |||
1002 | [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", | 983 | [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", |
1003 | [AD1986A_ULTRA] = "ultra", | 984 | [AD1986A_ULTRA] = "ultra", |
1004 | [AD1986A_SAMSUNG] = "samsung", | 985 | [AD1986A_SAMSUNG] = "samsung", |
986 | [AD1986A_SAMSUNG_P50] = "samsung-p50", | ||
1005 | }; | 987 | }; |
1006 | 988 | ||
1007 | static struct snd_pci_quirk ad1986a_cfg_tbl[] = { | 989 | static struct snd_pci_quirk ad1986a_cfg_tbl[] = { |
@@ -1024,6 +1006,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { | |||
1024 | SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), | 1006 | SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), |
1025 | SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), | 1007 | SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), |
1026 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), | 1008 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), |
1009 | SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), | ||
1027 | SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), | 1010 | SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), |
1028 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG), | 1011 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG), |
1029 | SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), | 1012 | SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), |
@@ -1111,7 +1094,10 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
1111 | spec->multiout.dac_nids = ad1986a_laptop_dac_nids; | 1094 | spec->multiout.dac_nids = ad1986a_laptop_dac_nids; |
1112 | break; | 1095 | break; |
1113 | case AD1986A_LAPTOP_EAPD: | 1096 | case AD1986A_LAPTOP_EAPD: |
1114 | spec->mixers[0] = ad1986a_laptop_eapd_mixers; | 1097 | spec->num_mixers = 3; |
1098 | spec->mixers[0] = ad1986a_laptop_master_mixers; | ||
1099 | spec->mixers[1] = ad1986a_laptop_eapd_mixers; | ||
1100 | spec->mixers[2] = ad1986a_laptop_intmic_mixers; | ||
1115 | spec->num_init_verbs = 2; | 1101 | spec->num_init_verbs = 2; |
1116 | spec->init_verbs[1] = ad1986a_eapd_init_verbs; | 1102 | spec->init_verbs[1] = ad1986a_eapd_init_verbs; |
1117 | spec->multiout.max_channels = 2; | 1103 | spec->multiout.max_channels = 2; |
@@ -1122,7 +1108,9 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
1122 | spec->input_mux = &ad1986a_laptop_eapd_capture_source; | 1108 | spec->input_mux = &ad1986a_laptop_eapd_capture_source; |
1123 | break; | 1109 | break; |
1124 | case AD1986A_SAMSUNG: | 1110 | case AD1986A_SAMSUNG: |
1125 | spec->mixers[0] = ad1986a_samsung_mixers; | 1111 | spec->num_mixers = 2; |
1112 | spec->mixers[0] = ad1986a_laptop_master_mixers; | ||
1113 | spec->mixers[1] = ad1986a_laptop_eapd_mixers; | ||
1126 | spec->num_init_verbs = 3; | 1114 | spec->num_init_verbs = 3; |
1127 | spec->init_verbs[1] = ad1986a_eapd_init_verbs; | 1115 | spec->init_verbs[1] = ad1986a_eapd_init_verbs; |
1128 | spec->init_verbs[2] = ad1986a_automic_verbs; | 1116 | spec->init_verbs[2] = ad1986a_automic_verbs; |
@@ -1135,8 +1123,28 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
1135 | codec->patch_ops.unsol_event = ad1986a_automic_unsol_event; | 1123 | codec->patch_ops.unsol_event = ad1986a_automic_unsol_event; |
1136 | codec->patch_ops.init = ad1986a_automic_init; | 1124 | codec->patch_ops.init = ad1986a_automic_init; |
1137 | break; | 1125 | break; |
1126 | case AD1986A_SAMSUNG_P50: | ||
1127 | spec->num_mixers = 2; | ||
1128 | spec->mixers[0] = ad1986a_automute_master_mixers; | ||
1129 | spec->mixers[1] = ad1986a_laptop_eapd_mixers; | ||
1130 | spec->num_init_verbs = 4; | ||
1131 | spec->init_verbs[1] = ad1986a_eapd_init_verbs; | ||
1132 | spec->init_verbs[2] = ad1986a_automic_verbs; | ||
1133 | spec->init_verbs[3] = ad1986a_hp_init_verbs; | ||
1134 | spec->multiout.max_channels = 2; | ||
1135 | spec->multiout.num_dacs = 1; | ||
1136 | spec->multiout.dac_nids = ad1986a_laptop_dac_nids; | ||
1137 | if (!is_jack_available(codec, 0x25)) | ||
1138 | spec->multiout.dig_out_nid = 0; | ||
1139 | spec->input_mux = &ad1986a_automic_capture_source; | ||
1140 | codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event; | ||
1141 | codec->patch_ops.init = ad1986a_samsung_p50_init; | ||
1142 | break; | ||
1138 | case AD1986A_LAPTOP_AUTOMUTE: | 1143 | case AD1986A_LAPTOP_AUTOMUTE: |
1139 | spec->mixers[0] = ad1986a_laptop_automute_mixers; | 1144 | spec->num_mixers = 3; |
1145 | spec->mixers[0] = ad1986a_automute_master_mixers; | ||
1146 | spec->mixers[1] = ad1986a_laptop_eapd_mixers; | ||
1147 | spec->mixers[2] = ad1986a_laptop_intmic_mixers; | ||
1140 | spec->num_init_verbs = 3; | 1148 | spec->num_init_verbs = 3; |
1141 | spec->init_verbs[1] = ad1986a_eapd_init_verbs; | 1149 | spec->init_verbs[1] = ad1986a_eapd_init_verbs; |
1142 | spec->init_verbs[2] = ad1986a_hp_init_verbs; | 1150 | spec->init_verbs[2] = ad1986a_hp_init_verbs; |
@@ -1148,6 +1156,10 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
1148 | spec->input_mux = &ad1986a_laptop_eapd_capture_source; | 1156 | spec->input_mux = &ad1986a_laptop_eapd_capture_source; |
1149 | codec->patch_ops.unsol_event = ad1986a_hp_unsol_event; | 1157 | codec->patch_ops.unsol_event = ad1986a_hp_unsol_event; |
1150 | codec->patch_ops.init = ad1986a_hp_init; | 1158 | codec->patch_ops.init = ad1986a_hp_init; |
1159 | /* Lenovo N100 seems to report the reversed bit | ||
1160 | * for HP jack-sensing | ||
1161 | */ | ||
1162 | spec->inv_jack_detect = 1; | ||
1151 | break; | 1163 | break; |
1152 | case AD1986A_ULTRA: | 1164 | case AD1986A_ULTRA: |
1153 | spec->mixers[0] = ad1986a_laptop_eapd_mixers; | 1165 | spec->mixers[0] = ad1986a_laptop_eapd_mixers; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 334533197425..3a8e58c483df 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -945,12 +945,13 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | |||
945 | static void alc_automute_pin(struct hda_codec *codec) | 945 | static void alc_automute_pin(struct hda_codec *codec) |
946 | { | 946 | { |
947 | struct alc_spec *spec = codec->spec; | 947 | struct alc_spec *spec = codec->spec; |
948 | unsigned int present; | 948 | unsigned int present, pincap; |
949 | unsigned int nid = spec->autocfg.hp_pins[0]; | 949 | unsigned int nid = spec->autocfg.hp_pins[0]; |
950 | int i; | 950 | int i; |
951 | 951 | ||
952 | /* need to execute and sync at first */ | 952 | pincap = snd_hda_query_pin_caps(codec, nid); |
953 | snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); | 953 | if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ |
954 | snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); | ||
954 | present = snd_hda_codec_read(codec, nid, 0, | 955 | present = snd_hda_codec_read(codec, nid, 0, |
955 | AC_VERB_GET_PIN_SENSE, 0); | 956 | AC_VERB_GET_PIN_SENSE, 0); |
956 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; | 957 | spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; |
@@ -1392,7 +1393,7 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { | |||
1392 | static void alc_automute_amp(struct hda_codec *codec) | 1393 | static void alc_automute_amp(struct hda_codec *codec) |
1393 | { | 1394 | { |
1394 | struct alc_spec *spec = codec->spec; | 1395 | struct alc_spec *spec = codec->spec; |
1395 | unsigned int val, mute; | 1396 | unsigned int val, mute, pincap; |
1396 | hda_nid_t nid; | 1397 | hda_nid_t nid; |
1397 | int i; | 1398 | int i; |
1398 | 1399 | ||
@@ -1401,6 +1402,10 @@ static void alc_automute_amp(struct hda_codec *codec) | |||
1401 | nid = spec->autocfg.hp_pins[i]; | 1402 | nid = spec->autocfg.hp_pins[i]; |
1402 | if (!nid) | 1403 | if (!nid) |
1403 | break; | 1404 | break; |
1405 | pincap = snd_hda_query_pin_caps(codec, nid); | ||
1406 | if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ | ||
1407 | snd_hda_codec_read(codec, nid, 0, | ||
1408 | AC_VERB_SET_PIN_SENSE, 0); | ||
1404 | val = snd_hda_codec_read(codec, nid, 0, | 1409 | val = snd_hda_codec_read(codec, nid, 0, |
1405 | AC_VERB_GET_PIN_SENSE, 0); | 1410 | AC_VERB_GET_PIN_SENSE, 0); |
1406 | if (val & AC_PINSENSE_PRESENCE) { | 1411 | if (val & AC_PINSENSE_PRESENCE) { |
@@ -1471,6 +1476,10 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { | |||
1471 | static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { | 1476 | static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { |
1472 | /* Bias voltage on for external mic port */ | 1477 | /* Bias voltage on for external mic port */ |
1473 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, | 1478 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, |
1479 | /* Front Mic: set to PIN_IN (empty by default) */ | ||
1480 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
1481 | /* Unselect Front Mic by default in input mixer 3 */ | ||
1482 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)}, | ||
1474 | /* Enable unsolicited event for HP jack */ | 1483 | /* Enable unsolicited event for HP jack */ |
1475 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 1484 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
1476 | /* Enable speaker output */ | 1485 | /* Enable speaker output */ |
@@ -1560,18 +1569,22 @@ static struct hda_input_mux alc888_2_capture_sources[2] = { | |||
1560 | static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { | 1569 | static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { |
1561 | /* Interal mic only available on one ADC */ | 1570 | /* Interal mic only available on one ADC */ |
1562 | { | 1571 | { |
1563 | .num_items = 3, | 1572 | .num_items = 5, |
1564 | .items = { | 1573 | .items = { |
1565 | { "Ext Mic", 0x0 }, | 1574 | { "Ext Mic", 0x0 }, |
1575 | { "Line In", 0x2 }, | ||
1566 | { "CD", 0x4 }, | 1576 | { "CD", 0x4 }, |
1577 | { "Input Mix", 0xa }, | ||
1567 | { "Int Mic", 0xb }, | 1578 | { "Int Mic", 0xb }, |
1568 | }, | 1579 | }, |
1569 | }, | 1580 | }, |
1570 | { | 1581 | { |
1571 | .num_items = 2, | 1582 | .num_items = 4, |
1572 | .items = { | 1583 | .items = { |
1573 | { "Ext Mic", 0x0 }, | 1584 | { "Ext Mic", 0x0 }, |
1585 | { "Line In", 0x2 }, | ||
1574 | { "CD", 0x4 }, | 1586 | { "CD", 0x4 }, |
1587 | { "Input Mix", 0xa }, | ||
1575 | }, | 1588 | }, |
1576 | } | 1589 | } |
1577 | }; | 1590 | }; |
@@ -1639,6 +1652,17 @@ static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec) | |||
1639 | alc_automute_amp(codec); | 1652 | alc_automute_amp(codec); |
1640 | } | 1653 | } |
1641 | 1654 | ||
1655 | static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec) | ||
1656 | { | ||
1657 | struct alc_spec *spec = codec->spec; | ||
1658 | |||
1659 | spec->autocfg.hp_pins[0] = 0x15; | ||
1660 | spec->autocfg.speaker_pins[0] = 0x14; | ||
1661 | spec->autocfg.speaker_pins[1] = 0x16; | ||
1662 | spec->autocfg.speaker_pins[2] = 0x17; | ||
1663 | alc_automute_amp(codec); | ||
1664 | } | ||
1665 | |||
1642 | static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec) | 1666 | static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec) |
1643 | { | 1667 | { |
1644 | struct alc_spec *spec = codec->spec; | 1668 | struct alc_spec *spec = codec->spec; |
@@ -8189,6 +8213,8 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { | |||
8189 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 8213 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8190 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 8214 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
8191 | HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT), | 8215 | HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT), |
8216 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
8217 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
8192 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 8218 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
8193 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 8219 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
8194 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 8220 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -9064,7 +9090,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { | |||
9064 | SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), | 9090 | SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), |
9065 | SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), | 9091 | SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), |
9066 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", | 9092 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", |
9067 | ALC888_ACER_ASPIRE_4930G), | 9093 | ALC888_ACER_ASPIRE_6530G), |
9068 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", | 9094 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", |
9069 | ALC888_ACER_ASPIRE_6530G), | 9095 | ALC888_ACER_ASPIRE_6530G), |
9070 | /* default Acer -- disabled as it causes more problems. | 9096 | /* default Acer -- disabled as it causes more problems. |
@@ -9317,7 +9343,7 @@ static struct alc_config_preset alc883_presets[] = { | |||
9317 | ARRAY_SIZE(alc888_2_capture_sources), | 9343 | ARRAY_SIZE(alc888_2_capture_sources), |
9318 | .input_mux = alc888_acer_aspire_6530_sources, | 9344 | .input_mux = alc888_acer_aspire_6530_sources, |
9319 | .unsol_event = alc_automute_amp_unsol_event, | 9345 | .unsol_event = alc_automute_amp_unsol_event, |
9320 | .init_hook = alc888_acer_aspire_4930g_init_hook, | 9346 | .init_hook = alc888_acer_aspire_6530g_init_hook, |
9321 | }, | 9347 | }, |
9322 | [ALC888_ACER_ASPIRE_8930G] = { | 9348 | [ALC888_ACER_ASPIRE_8930G] = { |
9323 | .mixers = { alc888_base_mixer, | 9349 | .mixers = { alc888_base_mixer, |
@@ -12437,6 +12463,8 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
12437 | if (err < 0) | 12463 | if (err < 0) |
12438 | return err; | 12464 | return err; |
12439 | 12465 | ||
12466 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | ||
12467 | |||
12440 | return 1; | 12468 | return 1; |
12441 | } | 12469 | } |
12442 | 12470 | ||
@@ -13345,6 +13373,8 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13345 | if (!spec->cap_mixer && !spec->no_analog) | 13373 | if (!spec->cap_mixer && !spec->no_analog) |
13346 | set_capture_mixer(spec); | 13374 | set_capture_mixer(spec); |
13347 | 13375 | ||
13376 | alc_ssid_check(codec, 0x15, 0x1b, 0x14); | ||
13377 | |||
13348 | return 1; | 13378 | return 1; |
13349 | } | 13379 | } |
13350 | 13380 | ||
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 0d0cdbdb4486..cecf1ffeeaaa 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
@@ -107,7 +107,7 @@ MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); | |||
107 | 107 | ||
108 | 108 | ||
109 | static const struct pci_device_id snd_ice1712_ids[] = { | 109 | static const struct pci_device_id snd_ice1712_ids[] = { |
110 | { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */ | 110 | { PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */ |
111 | { 0, } | 111 | { 0, } |
112 | }; | 112 | }; |
113 | 113 | ||
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 36ade77cf371..cc84a831eb21 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -93,7 +93,7 @@ MODULE_PARM_DESC(model, "Use the given board model."); | |||
93 | 93 | ||
94 | /* Both VT1720 and VT1724 have the same PCI IDs */ | 94 | /* Both VT1720 and VT1724 have the same PCI IDs */ |
95 | static const struct pci_device_id snd_vt1724_ids[] = { | 95 | static const struct pci_device_id snd_vt1724_ids[] = { |
96 | { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 96 | { PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 }, |
97 | { 0, } | 97 | { 0, } |
98 | }; | 98 | }; |
99 | 99 | ||
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 8aa5687f392a..171ada535209 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -421,29 +421,29 @@ struct intel8x0 { | |||
421 | }; | 421 | }; |
422 | 422 | ||
423 | static struct pci_device_id snd_intel8x0_ids[] = { | 423 | static struct pci_device_id snd_intel8x0_ids[] = { |
424 | { 0x8086, 0x2415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */ | 424 | { PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */ |
425 | { 0x8086, 0x2425, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */ | 425 | { PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */ |
426 | { 0x8086, 0x2445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */ | 426 | { PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */ |
427 | { 0x8086, 0x2485, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */ | 427 | { PCI_VDEVICE(INTEL, 0x2485), DEVICE_INTEL }, /* ICH3 */ |
428 | { 0x8086, 0x24c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH4 */ | 428 | { PCI_VDEVICE(INTEL, 0x24c5), DEVICE_INTEL_ICH4 }, /* ICH4 */ |
429 | { 0x8086, 0x24d5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH5 */ | 429 | { PCI_VDEVICE(INTEL, 0x24d5), DEVICE_INTEL_ICH4 }, /* ICH5 */ |
430 | { 0x8086, 0x25a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ESB */ | 430 | { PCI_VDEVICE(INTEL, 0x25a6), DEVICE_INTEL_ICH4 }, /* ESB */ |
431 | { 0x8086, 0x266e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH6 */ | 431 | { PCI_VDEVICE(INTEL, 0x266e), DEVICE_INTEL_ICH4 }, /* ICH6 */ |
432 | { 0x8086, 0x27de, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ICH7 */ | 432 | { PCI_VDEVICE(INTEL, 0x27de), DEVICE_INTEL_ICH4 }, /* ICH7 */ |
433 | { 0x8086, 0x2698, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL_ICH4 }, /* ESB2 */ | 433 | { PCI_VDEVICE(INTEL, 0x2698), DEVICE_INTEL_ICH4 }, /* ESB2 */ |
434 | { 0x8086, 0x7195, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */ | 434 | { PCI_VDEVICE(INTEL, 0x7195), DEVICE_INTEL }, /* 440MX */ |
435 | { 0x1039, 0x7012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7012 */ | 435 | { PCI_VDEVICE(SI, 0x7012), DEVICE_SIS }, /* SI7012 */ |
436 | { 0x10de, 0x01b1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */ | 436 | { PCI_VDEVICE(NVIDIA, 0x01b1), DEVICE_NFORCE }, /* NFORCE */ |
437 | { 0x10de, 0x003a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* MCP04 */ | 437 | { PCI_VDEVICE(NVIDIA, 0x003a), DEVICE_NFORCE }, /* MCP04 */ |
438 | { 0x10de, 0x006a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2 */ | 438 | { PCI_VDEVICE(NVIDIA, 0x006a), DEVICE_NFORCE }, /* NFORCE2 */ |
439 | { 0x10de, 0x0059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK804 */ | 439 | { PCI_VDEVICE(NVIDIA, 0x0059), DEVICE_NFORCE }, /* CK804 */ |
440 | { 0x10de, 0x008a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8 */ | 440 | { PCI_VDEVICE(NVIDIA, 0x008a), DEVICE_NFORCE }, /* CK8 */ |
441 | { 0x10de, 0x00da, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */ | 441 | { PCI_VDEVICE(NVIDIA, 0x00da), DEVICE_NFORCE }, /* NFORCE3 */ |
442 | { 0x10de, 0x00ea, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* CK8S */ | 442 | { PCI_VDEVICE(NVIDIA, 0x00ea), DEVICE_NFORCE }, /* CK8S */ |
443 | { 0x10de, 0x026b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* MCP51 */ | 443 | { PCI_VDEVICE(NVIDIA, 0x026b), DEVICE_NFORCE }, /* MCP51 */ |
444 | { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ | 444 | { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */ |
445 | { 0x1022, 0x7445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ | 445 | { PCI_VDEVICE(AMD, 0x7445), DEVICE_INTEL }, /* AMD768 */ |
446 | { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ | 446 | { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ |
447 | { 0, } | 447 | { 0, } |
448 | }; | 448 | }; |
449 | 449 | ||
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 6ec0fc50d6be..9e7d12e7673f 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c | |||
@@ -220,24 +220,24 @@ struct intel8x0m { | |||
220 | }; | 220 | }; |
221 | 221 | ||
222 | static struct pci_device_id snd_intel8x0m_ids[] = { | 222 | static struct pci_device_id snd_intel8x0m_ids[] = { |
223 | { 0x8086, 0x2416, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */ | 223 | { PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */ |
224 | { 0x8086, 0x2426, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */ | 224 | { PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */ |
225 | { 0x8086, 0x2446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */ | 225 | { PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */ |
226 | { 0x8086, 0x2486, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */ | 226 | { PCI_VDEVICE(INTEL, 0x2486), DEVICE_INTEL }, /* ICH3 */ |
227 | { 0x8086, 0x24c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH4 */ | 227 | { PCI_VDEVICE(INTEL, 0x24c6), DEVICE_INTEL }, /* ICH4 */ |
228 | { 0x8086, 0x24d6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH5 */ | 228 | { PCI_VDEVICE(INTEL, 0x24d6), DEVICE_INTEL }, /* ICH5 */ |
229 | { 0x8086, 0x266d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH6 */ | 229 | { PCI_VDEVICE(INTEL, 0x266d), DEVICE_INTEL }, /* ICH6 */ |
230 | { 0x8086, 0x27dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH7 */ | 230 | { PCI_VDEVICE(INTEL, 0x27dd), DEVICE_INTEL }, /* ICH7 */ |
231 | { 0x8086, 0x7196, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */ | 231 | { PCI_VDEVICE(INTEL, 0x7196), DEVICE_INTEL }, /* 440MX */ |
232 | { 0x1022, 0x7446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */ | 232 | { PCI_VDEVICE(AMD, 0x7446), DEVICE_INTEL }, /* AMD768 */ |
233 | { 0x1039, 0x7013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7013 */ | 233 | { PCI_VDEVICE(SI, 0x7013), DEVICE_SIS }, /* SI7013 */ |
234 | { 0x10de, 0x01c1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE */ | 234 | { PCI_VDEVICE(NVIDIA, 0x01c1), DEVICE_NFORCE }, /* NFORCE */ |
235 | { 0x10de, 0x0069, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2 */ | 235 | { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */ |
236 | { 0x10de, 0x0089, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE2s */ | 236 | { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */ |
237 | { 0x10de, 0x00d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_NFORCE }, /* NFORCE3 */ | 237 | { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */ |
238 | #if 0 | 238 | #if 0 |
239 | { 0x1022, 0x746d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD8111 */ | 239 | { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */ |
240 | { 0x10b9, 0x5455, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALI }, /* Ali5455 */ | 240 | { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ |
241 | #endif | 241 | #endif |
242 | { 0, } | 242 | { 0, } |
243 | }; | 243 | }; |
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index 18da2ef04d09..11b8c6514b3d 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c | |||
@@ -654,13 +654,12 @@ static int __devinit lx_init_ethersound_config(struct lx6464es *chip) | |||
654 | int i; | 654 | int i; |
655 | u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES); | 655 | u32 orig_conf_es = lx_dsp_reg_read(chip, eReg_CONFES); |
656 | 656 | ||
657 | u32 default_conf_es = (64 << IOCR_OUTPUTS_OFFSET) | | 657 | /* configure 64 io channels */ |
658 | u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK) | | ||
658 | (64 << IOCR_INPUTS_OFFSET) | | 659 | (64 << IOCR_INPUTS_OFFSET) | |
660 | (64 << IOCR_OUTPUTS_OFFSET) | | ||
659 | (FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET); | 661 | (FREQ_RATIO_SINGLE_MODE << FREQ_RATIO_OFFSET); |
660 | 662 | ||
661 | u32 conf_es = (orig_conf_es & CONFES_READ_PART_MASK) | ||
662 | | (default_conf_es & CONFES_WRITE_PART_MASK); | ||
663 | |||
664 | snd_printdd("->lx_init_ethersound\n"); | 663 | snd_printdd("->lx_init_ethersound\n"); |
665 | 664 | ||
666 | chip->freq_ratio = FREQ_RATIO_SINGLE_MODE; | 665 | chip->freq_ratio = FREQ_RATIO_SINGLE_MODE; |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 82bc5b9e7629..a83d1968a845 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -61,7 +61,7 @@ MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard."); | |||
61 | */ | 61 | */ |
62 | 62 | ||
63 | static struct pci_device_id snd_mixart_ids[] = { | 63 | static struct pci_device_id snd_mixart_ids[] = { |
64 | { 0x1057, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* MC8240 */ | 64 | { PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */ |
65 | { 0, } | 65 | { 0, } |
66 | }; | 66 | }; |
67 | 67 | ||
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 522a040855d4..97a0731331a1 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c | |||
@@ -263,9 +263,9 @@ struct nm256 { | |||
263 | * PCI ids | 263 | * PCI ids |
264 | */ | 264 | */ |
265 | static struct pci_device_id snd_nm256_ids[] = { | 265 | static struct pci_device_id snd_nm256_ids[] = { |
266 | {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 266 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0}, |
267 | {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 267 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0}, |
268 | {PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 268 | {PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0}, |
269 | {0,}, | 269 | {0,}, |
270 | }; | 270 | }; |
271 | 271 | ||
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 304da169bfdc..5401c547c4e3 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c | |||
@@ -575,8 +575,10 @@ static int ac97_switch_put(struct snd_kcontrol *ctl, | |||
575 | static int ac97_volume_info(struct snd_kcontrol *ctl, | 575 | static int ac97_volume_info(struct snd_kcontrol *ctl, |
576 | struct snd_ctl_elem_info *info) | 576 | struct snd_ctl_elem_info *info) |
577 | { | 577 | { |
578 | int stereo = (ctl->private_value >> 16) & 1; | ||
579 | |||
578 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 580 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
579 | info->count = 2; | 581 | info->count = stereo ? 2 : 1; |
580 | info->value.integer.min = 0; | 582 | info->value.integer.min = 0; |
581 | info->value.integer.max = 0x1f; | 583 | info->value.integer.max = 0x1f; |
582 | return 0; | 584 | return 0; |
@@ -587,6 +589,7 @@ static int ac97_volume_get(struct snd_kcontrol *ctl, | |||
587 | { | 589 | { |
588 | struct oxygen *chip = ctl->private_data; | 590 | struct oxygen *chip = ctl->private_data; |
589 | unsigned int codec = (ctl->private_value >> 24) & 1; | 591 | unsigned int codec = (ctl->private_value >> 24) & 1; |
592 | int stereo = (ctl->private_value >> 16) & 1; | ||
590 | unsigned int index = ctl->private_value & 0xff; | 593 | unsigned int index = ctl->private_value & 0xff; |
591 | u16 reg; | 594 | u16 reg; |
592 | 595 | ||
@@ -594,7 +597,8 @@ static int ac97_volume_get(struct snd_kcontrol *ctl, | |||
594 | reg = oxygen_read_ac97(chip, codec, index); | 597 | reg = oxygen_read_ac97(chip, codec, index); |
595 | mutex_unlock(&chip->mutex); | 598 | mutex_unlock(&chip->mutex); |
596 | value->value.integer.value[0] = 31 - (reg & 0x1f); | 599 | value->value.integer.value[0] = 31 - (reg & 0x1f); |
597 | value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); | 600 | if (stereo) |
601 | value->value.integer.value[1] = 31 - ((reg >> 8) & 0x1f); | ||
598 | return 0; | 602 | return 0; |
599 | } | 603 | } |
600 | 604 | ||
@@ -603,6 +607,7 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, | |||
603 | { | 607 | { |
604 | struct oxygen *chip = ctl->private_data; | 608 | struct oxygen *chip = ctl->private_data; |
605 | unsigned int codec = (ctl->private_value >> 24) & 1; | 609 | unsigned int codec = (ctl->private_value >> 24) & 1; |
610 | int stereo = (ctl->private_value >> 16) & 1; | ||
606 | unsigned int index = ctl->private_value & 0xff; | 611 | unsigned int index = ctl->private_value & 0xff; |
607 | u16 oldreg, newreg; | 612 | u16 oldreg, newreg; |
608 | int change; | 613 | int change; |
@@ -612,8 +617,11 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, | |||
612 | newreg = oldreg; | 617 | newreg = oldreg; |
613 | newreg = (newreg & ~0x1f) | | 618 | newreg = (newreg & ~0x1f) | |
614 | (31 - (value->value.integer.value[0] & 0x1f)); | 619 | (31 - (value->value.integer.value[0] & 0x1f)); |
615 | newreg = (newreg & ~0x1f00) | | 620 | if (stereo) |
616 | ((31 - (value->value.integer.value[0] & 0x1f)) << 8); | 621 | newreg = (newreg & ~0x1f00) | |
622 | ((31 - (value->value.integer.value[1] & 0x1f)) << 8); | ||
623 | else | ||
624 | newreg = (newreg & ~0x1f00) | ((newreg & 0x1f) << 8); | ||
617 | change = newreg != oldreg; | 625 | change = newreg != oldreg; |
618 | if (change) | 626 | if (change) |
619 | oxygen_write_ac97(chip, codec, index, newreg); | 627 | oxygen_write_ac97(chip, codec, index, newreg); |
@@ -673,7 +681,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl, | |||
673 | .private_value = ((codec) << 24) | ((invert) << 16) | \ | 681 | .private_value = ((codec) << 24) | ((invert) << 16) | \ |
674 | ((bitnr) << 8) | (index), \ | 682 | ((bitnr) << 8) | (index), \ |
675 | } | 683 | } |
676 | #define AC97_VOLUME(xname, codec, index) { \ | 684 | #define AC97_VOLUME(xname, codec, index, stereo) { \ |
677 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 685 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
678 | .name = xname, \ | 686 | .name = xname, \ |
679 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | 687 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ |
@@ -682,7 +690,7 @@ static int ac97_fp_rec_volume_put(struct snd_kcontrol *ctl, | |||
682 | .get = ac97_volume_get, \ | 690 | .get = ac97_volume_get, \ |
683 | .put = ac97_volume_put, \ | 691 | .put = ac97_volume_put, \ |
684 | .tlv = { .p = ac97_db_scale, }, \ | 692 | .tlv = { .p = ac97_db_scale, }, \ |
685 | .private_value = ((codec) << 24) | (index), \ | 693 | .private_value = ((codec) << 24) | ((stereo) << 16) | (index), \ |
686 | } | 694 | } |
687 | 695 | ||
688 | static DECLARE_TLV_DB_SCALE(monitor_db_scale, -1000, 1000, 0); | 696 | static DECLARE_TLV_DB_SCALE(monitor_db_scale, -1000, 1000, 0); |
@@ -882,18 +890,18 @@ static const struct { | |||
882 | }; | 890 | }; |
883 | 891 | ||
884 | static const struct snd_kcontrol_new ac97_controls[] = { | 892 | static const struct snd_kcontrol_new ac97_controls[] = { |
885 | AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC), | 893 | AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), |
886 | AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), | 894 | AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), |
887 | AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), | 895 | AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), |
888 | AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), | 896 | AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), |
889 | AC97_VOLUME("CD Capture Volume", 0, AC97_CD), | 897 | AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), |
890 | AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), | 898 | AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), |
891 | AC97_VOLUME("Aux Capture Volume", 0, AC97_AUX), | 899 | AC97_VOLUME("Aux Capture Volume", 0, AC97_AUX, 1), |
892 | AC97_SWITCH("Aux Capture Switch", 0, AC97_AUX, 15, 1), | 900 | AC97_SWITCH("Aux Capture Switch", 0, AC97_AUX, 15, 1), |
893 | }; | 901 | }; |
894 | 902 | ||
895 | static const struct snd_kcontrol_new ac97_fp_controls[] = { | 903 | static const struct snd_kcontrol_new ac97_fp_controls[] = { |
896 | AC97_VOLUME("Front Panel Playback Volume", 1, AC97_HEADPHONE), | 904 | AC97_VOLUME("Front Panel Playback Volume", 1, AC97_HEADPHONE, 1), |
897 | AC97_SWITCH("Front Panel Playback Switch", 1, AC97_HEADPHONE, 15, 1), | 905 | AC97_SWITCH("Front Panel Playback Switch", 1, AC97_HEADPHONE, 15, 1), |
898 | { | 906 | { |
899 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 907 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index d7b966e7c4cf..f977dba7cbd0 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c | |||
@@ -227,12 +227,9 @@ struct rme32 { | |||
227 | }; | 227 | }; |
228 | 228 | ||
229 | static struct pci_device_id snd_rme32_ids[] = { | 229 | static struct pci_device_id snd_rme32_ids[] = { |
230 | {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32, | 230 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32), 0,}, |
231 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, | 231 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8), 0,}, |
232 | {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8, | 232 | {PCI_VDEVICE(XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO), 0,}, |
233 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, | ||
234 | {PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_PRO, | ||
235 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,}, | ||
236 | {0,} | 233 | {0,} |
237 | }; | 234 | }; |
238 | 235 | ||
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c index 55fb1c131f58..2ba5c0fd55db 100644 --- a/sound/pci/rme96.c +++ b/sound/pci/rme96.c | |||
@@ -232,14 +232,10 @@ struct rme96 { | |||
232 | }; | 232 | }; |
233 | 233 | ||
234 | static struct pci_device_id snd_rme96_ids[] = { | 234 | static struct pci_device_id snd_rme96_ids[] = { |
235 | { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96, | 235 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96), 0, }, |
236 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, | 236 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8), 0, }, |
237 | { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8, | 237 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO), 0, }, |
238 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, | 238 | { PCI_VDEVICE(XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST), 0, }, |
239 | { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PRO, | ||
240 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, | ||
241 | { PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST, | ||
242 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, | ||
243 | { 0, } | 239 | { 0, } |
244 | }; | 240 | }; |
245 | 241 | ||
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 7dc60ad4772e..1f6406c4534d 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
@@ -243,7 +243,7 @@ struct sonicvibes { | |||
243 | }; | 243 | }; |
244 | 244 | ||
245 | static struct pci_device_id snd_sonic_ids[] = { | 245 | static struct pci_device_id snd_sonic_ids[] = { |
246 | { 0x5333, 0xca00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, | 246 | { PCI_VDEVICE(S3, 0xca00), 0, }, |
247 | { 0, } | 247 | { 0, } |
248 | }; | 248 | }; |
249 | 249 | ||
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 949fcaf6b70e..acfa4760da49 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -402,9 +402,9 @@ struct via82xx { | |||
402 | 402 | ||
403 | static struct pci_device_id snd_via82xx_ids[] = { | 403 | static struct pci_device_id snd_via82xx_ids[] = { |
404 | /* 0x1106, 0x3058 */ | 404 | /* 0x1106, 0x3058 */ |
405 | { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */ | 405 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686_5), TYPE_CARD_VIA686, }, /* 686A */ |
406 | /* 0x1106, 0x3059 */ | 406 | /* 0x1106, 0x3059 */ |
407 | { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, }, /* VT8233 */ | 407 | { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_5), TYPE_CARD_VIA8233, }, /* VT8233 */ |
408 | { 0, } | 408 | { 0, } |
409 | }; | 409 | }; |
410 | 410 | ||
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 0d54e3503c1e..47eb61561dfc 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c | |||
@@ -261,7 +261,7 @@ struct via82xx_modem { | |||
261 | }; | 261 | }; |
262 | 262 | ||
263 | static struct pci_device_id snd_via82xx_modem_ids[] = { | 263 | static struct pci_device_id snd_via82xx_modem_ids[] = { |
264 | { 0x1106, 0x3068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA82XX_MODEM, }, | 264 | { PCI_VDEVICE(VIA, 0x3068), TYPE_CARD_VIA82XX_MODEM, }, |
265 | { 0, } | 265 | { 0, } |
266 | }; | 266 | }; |
267 | 267 | ||
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 4af66661f9b0..e6b18b90d451 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c | |||
@@ -67,12 +67,12 @@ module_param_array(rear_switch, bool, NULL, 0444); | |||
67 | MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); | 67 | MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch"); |
68 | 68 | ||
69 | static struct pci_device_id snd_ymfpci_ids[] = { | 69 | static struct pci_device_id snd_ymfpci_ids[] = { |
70 | { 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */ | 70 | { PCI_VDEVICE(YAMAHA, 0x0004), 0, }, /* YMF724 */ |
71 | { 0x1073, 0x000d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724F */ | 71 | { PCI_VDEVICE(YAMAHA, 0x000d), 0, }, /* YMF724F */ |
72 | { 0x1073, 0x000a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF740 */ | 72 | { PCI_VDEVICE(YAMAHA, 0x000a), 0, }, /* YMF740 */ |
73 | { 0x1073, 0x000c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF740C */ | 73 | { PCI_VDEVICE(YAMAHA, 0x000c), 0, }, /* YMF740C */ |
74 | { 0x1073, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF744 */ | 74 | { PCI_VDEVICE(YAMAHA, 0x0010), 0, }, /* YMF744 */ |
75 | { 0x1073, 0x0012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF754 */ | 75 | { PCI_VDEVICE(YAMAHA, 0x0012), 0, }, /* YMF754 */ |
76 | { 0, } | 76 | { 0, } |
77 | }; | 77 | }; |
78 | 78 | ||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 764554350ed8..2884baf1d5f9 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -746,6 +746,7 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req) | |||
746 | cpumask_clear(cpus); | 746 | cpumask_clear(cpus); |
747 | 747 | ||
748 | me = get_cpu(); | 748 | me = get_cpu(); |
749 | spin_lock(&kvm->requests_lock); | ||
749 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { | 750 | for (i = 0; i < KVM_MAX_VCPUS; ++i) { |
750 | vcpu = kvm->vcpus[i]; | 751 | vcpu = kvm->vcpus[i]; |
751 | if (!vcpu) | 752 | if (!vcpu) |
@@ -762,6 +763,7 @@ static bool make_all_cpus_request(struct kvm *kvm, unsigned int req) | |||
762 | smp_call_function_many(cpus, ack_flush, NULL, 1); | 763 | smp_call_function_many(cpus, ack_flush, NULL, 1); |
763 | else | 764 | else |
764 | called = false; | 765 | called = false; |
766 | spin_unlock(&kvm->requests_lock); | ||
765 | put_cpu(); | 767 | put_cpu(); |
766 | free_cpumask_var(cpus); | 768 | free_cpumask_var(cpus); |
767 | return called; | 769 | return called; |
@@ -982,6 +984,7 @@ static struct kvm *kvm_create_vm(void) | |||
982 | kvm->mm = current->mm; | 984 | kvm->mm = current->mm; |
983 | atomic_inc(&kvm->mm->mm_count); | 985 | atomic_inc(&kvm->mm->mm_count); |
984 | spin_lock_init(&kvm->mmu_lock); | 986 | spin_lock_init(&kvm->mmu_lock); |
987 | spin_lock_init(&kvm->requests_lock); | ||
985 | kvm_io_bus_init(&kvm->pio_bus); | 988 | kvm_io_bus_init(&kvm->pio_bus); |
986 | mutex_init(&kvm->lock); | 989 | mutex_init(&kvm->lock); |
987 | kvm_io_bus_init(&kvm->mmio_bus); | 990 | kvm_io_bus_init(&kvm->mmio_bus); |
@@ -1194,6 +1197,8 @@ int __kvm_set_memory_region(struct kvm *kvm, | |||
1194 | if (!new.dirty_bitmap) | 1197 | if (!new.dirty_bitmap) |
1195 | goto out_free; | 1198 | goto out_free; |
1196 | memset(new.dirty_bitmap, 0, dirty_bytes); | 1199 | memset(new.dirty_bitmap, 0, dirty_bytes); |
1200 | if (old.npages) | ||
1201 | kvm_arch_flush_shadow(kvm); | ||
1197 | } | 1202 | } |
1198 | #endif /* not defined CONFIG_S390 */ | 1203 | #endif /* not defined CONFIG_S390 */ |
1199 | 1204 | ||