diff options
Diffstat (limited to 'drivers')
257 files changed, 6405 insertions, 8301 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 65e3e2708371..11ec911016c6 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -828,6 +828,7 @@ config PATA_SAMSUNG_CF | |||
828 | config PATA_WINBOND_VLB | 828 | config PATA_WINBOND_VLB |
829 | tristate "Winbond W83759A VLB PATA support (Experimental)" | 829 | tristate "Winbond W83759A VLB PATA support (Experimental)" |
830 | depends on ISA && EXPERIMENTAL | 830 | depends on ISA && EXPERIMENTAL |
831 | select PATA_LEGACY | ||
831 | help | 832 | help |
832 | Support for the Winbond W83759A controller on Vesa Local Bus | 833 | Support for the Winbond W83759A controller on Vesa Local Bus |
833 | systems. | 834 | systems. |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 158eaa961b1e..d5df04a395ca 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -89,7 +89,6 @@ obj-$(CONFIG_PATA_QDI) += pata_qdi.o | |||
89 | obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o | 89 | obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o |
90 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o | 90 | obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o |
91 | obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o | 91 | obj-$(CONFIG_PATA_SAMSUNG_CF) += pata_samsung_cf.o |
92 | obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o | ||
93 | 92 | ||
94 | obj-$(CONFIG_PATA_PXA) += pata_pxa.o | 93 | obj-$(CONFIG_PATA_PXA) += pata_pxa.o |
95 | 94 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index fe75d8befc3a..013727b20417 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -60,6 +60,7 @@ enum board_ids { | |||
60 | board_ahci, | 60 | board_ahci, |
61 | board_ahci_ign_iferr, | 61 | board_ahci_ign_iferr, |
62 | board_ahci_nosntf, | 62 | board_ahci_nosntf, |
63 | board_ahci_yes_fbs, | ||
63 | 64 | ||
64 | /* board IDs for specific chipsets in alphabetical order */ | 65 | /* board IDs for specific chipsets in alphabetical order */ |
65 | board_ahci_mcp65, | 66 | board_ahci_mcp65, |
@@ -132,6 +133,14 @@ static const struct ata_port_info ahci_port_info[] = { | |||
132 | .udma_mask = ATA_UDMA6, | 133 | .udma_mask = ATA_UDMA6, |
133 | .port_ops = &ahci_ops, | 134 | .port_ops = &ahci_ops, |
134 | }, | 135 | }, |
136 | [board_ahci_yes_fbs] = | ||
137 | { | ||
138 | AHCI_HFLAGS (AHCI_HFLAG_YES_FBS), | ||
139 | .flags = AHCI_FLAG_COMMON, | ||
140 | .pio_mask = ATA_PIO4, | ||
141 | .udma_mask = ATA_UDMA6, | ||
142 | .port_ops = &ahci_ops, | ||
143 | }, | ||
135 | /* by chipsets */ | 144 | /* by chipsets */ |
136 | [board_ahci_mcp65] = | 145 | [board_ahci_mcp65] = |
137 | { | 146 | { |
@@ -362,6 +371,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
362 | /* Marvell */ | 371 | /* Marvell */ |
363 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ | 372 | { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */ |
364 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ | 373 | { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */ |
374 | { PCI_DEVICE(0x1b4b, 0x9123), | ||
375 | .driver_data = board_ahci_yes_fbs }, /* 88se9128 */ | ||
365 | 376 | ||
366 | /* Promise */ | 377 | /* Promise */ |
367 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ | 378 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 7113c5724471..474427b6f99f 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -209,6 +209,7 @@ enum { | |||
209 | link offline */ | 209 | link offline */ |
210 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ | 210 | AHCI_HFLAG_NO_SNTF = (1 << 12), /* no sntf */ |
211 | AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ | 211 | AHCI_HFLAG_NO_FPDMA_AA = (1 << 13), /* no FPDMA AA */ |
212 | AHCI_HFLAG_YES_FBS = (1 << 14), /* force FBS cap on */ | ||
212 | 213 | ||
213 | /* ap->flags bits */ | 214 | /* ap->flags bits */ |
214 | 215 | ||
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 81e772a94d59..666850d31df2 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -430,6 +430,12 @@ void ahci_save_initial_config(struct device *dev, | |||
430 | cap &= ~HOST_CAP_SNTF; | 430 | cap &= ~HOST_CAP_SNTF; |
431 | } | 431 | } |
432 | 432 | ||
433 | if (!(cap & HOST_CAP_FBS) && (hpriv->flags & AHCI_HFLAG_YES_FBS)) { | ||
434 | dev_printk(KERN_INFO, dev, | ||
435 | "controller can do FBS, turning on CAP_FBS\n"); | ||
436 | cap |= HOST_CAP_FBS; | ||
437 | } | ||
438 | |||
433 | if (force_port_map && port_map != force_port_map) { | 439 | if (force_port_map && port_map != force_port_map) { |
434 | dev_printk(KERN_INFO, dev, "forcing port_map 0x%x -> 0x%x\n", | 440 | dev_printk(KERN_INFO, dev, "forcing port_map 0x%x -> 0x%x\n", |
435 | port_map, force_port_map); | 441 | port_map, force_port_map); |
@@ -2036,9 +2042,15 @@ static int ahci_port_start(struct ata_port *ap) | |||
2036 | u32 cmd = readl(port_mmio + PORT_CMD); | 2042 | u32 cmd = readl(port_mmio + PORT_CMD); |
2037 | if (cmd & PORT_CMD_FBSCP) | 2043 | if (cmd & PORT_CMD_FBSCP) |
2038 | pp->fbs_supported = true; | 2044 | pp->fbs_supported = true; |
2039 | else | 2045 | else if (hpriv->flags & AHCI_HFLAG_YES_FBS) { |
2046 | dev_printk(KERN_INFO, dev, | ||
2047 | "port %d can do FBS, forcing FBSCP\n", | ||
2048 | ap->port_no); | ||
2049 | pp->fbs_supported = true; | ||
2050 | } else | ||
2040 | dev_printk(KERN_WARNING, dev, | 2051 | dev_printk(KERN_WARNING, dev, |
2041 | "The port is not capable of FBS\n"); | 2052 | "port %d is not capable of FBS\n", |
2053 | ap->port_no); | ||
2042 | } | 2054 | } |
2043 | 2055 | ||
2044 | if (pp->fbs_supported) { | 2056 | if (pp->fbs_supported) { |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7ef7c4f216fa..c035b3d041ee 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5111,15 +5111,18 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5111 | qc->flags |= ATA_QCFLAG_ACTIVE; | 5111 | qc->flags |= ATA_QCFLAG_ACTIVE; |
5112 | ap->qc_active |= 1 << qc->tag; | 5112 | ap->qc_active |= 1 << qc->tag; |
5113 | 5113 | ||
5114 | /* We guarantee to LLDs that they will have at least one | 5114 | /* |
5115 | * We guarantee to LLDs that they will have at least one | ||
5115 | * non-zero sg if the command is a data command. | 5116 | * non-zero sg if the command is a data command. |
5116 | */ | 5117 | */ |
5117 | BUG_ON(ata_is_data(prot) && (!qc->sg || !qc->n_elem || !qc->nbytes)); | 5118 | if (WARN_ON_ONCE(ata_is_data(prot) && |
5119 | (!qc->sg || !qc->n_elem || !qc->nbytes))) | ||
5120 | goto sys_err; | ||
5118 | 5121 | ||
5119 | if (ata_is_dma(prot) || (ata_is_pio(prot) && | 5122 | if (ata_is_dma(prot) || (ata_is_pio(prot) && |
5120 | (ap->flags & ATA_FLAG_PIO_DMA))) | 5123 | (ap->flags & ATA_FLAG_PIO_DMA))) |
5121 | if (ata_sg_setup(qc)) | 5124 | if (ata_sg_setup(qc)) |
5122 | goto sg_err; | 5125 | goto sys_err; |
5123 | 5126 | ||
5124 | /* if device is sleeping, schedule reset and abort the link */ | 5127 | /* if device is sleeping, schedule reset and abort the link */ |
5125 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { | 5128 | if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) { |
@@ -5136,7 +5139,7 @@ void ata_qc_issue(struct ata_queued_cmd *qc) | |||
5136 | goto err; | 5139 | goto err; |
5137 | return; | 5140 | return; |
5138 | 5141 | ||
5139 | sg_err: | 5142 | sys_err: |
5140 | qc->err_mask |= AC_ERR_SYSTEM; | 5143 | qc->err_mask |= AC_ERR_SYSTEM; |
5141 | err: | 5144 | err: |
5142 | ata_qc_complete(qc); | 5145 | ata_qc_complete(qc); |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index 674c1436491f..3b82d8ef76f0 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -2735,10 +2735,6 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc) | |||
2735 | { | 2735 | { |
2736 | struct ata_port *ap = qc->ap; | 2736 | struct ata_port *ap = qc->ap; |
2737 | 2737 | ||
2738 | /* see ata_dma_blacklisted() */ | ||
2739 | BUG_ON((ap->flags & ATA_FLAG_PIO_POLLING) && | ||
2740 | qc->tf.protocol == ATAPI_PROT_DMA); | ||
2741 | |||
2742 | /* defer PIO handling to sff_qc_issue */ | 2738 | /* defer PIO handling to sff_qc_issue */ |
2743 | if (!ata_is_dma(qc->tf.protocol)) | 2739 | if (!ata_is_dma(qc->tf.protocol)) |
2744 | return ata_sff_qc_issue(qc); | 2740 | return ata_sff_qc_issue(qc); |
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c index 9f5da1c7454b..905ff76d3cbb 100644 --- a/drivers/ata/pata_cmd64x.c +++ b/drivers/ata/pata_cmd64x.c | |||
@@ -121,14 +121,8 @@ static void cmd64x_set_timing(struct ata_port *ap, struct ata_device *adev, u8 m | |||
121 | 121 | ||
122 | if (pair) { | 122 | if (pair) { |
123 | struct ata_timing tp; | 123 | struct ata_timing tp; |
124 | |||
125 | ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); | 124 | ata_timing_compute(pair, pair->pio_mode, &tp, T, 0); |
126 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); | 125 | ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP); |
127 | if (pair->dma_mode) { | ||
128 | ata_timing_compute(pair, pair->dma_mode, | ||
129 | &tp, T, 0); | ||
130 | ata_timing_merge(&tp, &t, &t, ATA_TIMING_SETUP); | ||
131 | } | ||
132 | } | 126 | } |
133 | } | 127 | } |
134 | 128 | ||
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 9df1ff7e1eaa..eaf194138f21 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
@@ -44,6 +44,9 @@ | |||
44 | * Specific support is included for the ht6560a/ht6560b/opti82c611a/ | 44 | * Specific support is included for the ht6560a/ht6560b/opti82c611a/ |
45 | * opti82c465mv/promise 20230c/20630/qdi65x0/winbond83759A | 45 | * opti82c465mv/promise 20230c/20630/qdi65x0/winbond83759A |
46 | * | 46 | * |
47 | * Support for the Winbond 83759A when operating in advanced mode. | ||
48 | * Multichip mode is not currently supported. | ||
49 | * | ||
47 | * Use the autospeed and pio_mask options with: | 50 | * Use the autospeed and pio_mask options with: |
48 | * Appian ADI/2 aka CLPD7220 or AIC25VL01. | 51 | * Appian ADI/2 aka CLPD7220 or AIC25VL01. |
49 | * Use the jumpers, autospeed and set pio_mask to the mode on the jumpers with | 52 | * Use the jumpers, autospeed and set pio_mask to the mode on the jumpers with |
@@ -135,12 +138,18 @@ static int ht6560b; /* HT 6560A on primary 1, second 2, both 3 */ | |||
135 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ | 138 | static int opti82c611a; /* Opti82c611A on primary 1, sec 2, both 3 */ |
136 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ | 139 | static int opti82c46x; /* Opti 82c465MV present(pri/sec autodetect) */ |
137 | static int qdi; /* Set to probe QDI controllers */ | 140 | static int qdi; /* Set to probe QDI controllers */ |
138 | static int winbond; /* Set to probe Winbond controllers, | ||
139 | give I/O port if non standard */ | ||
140 | static int autospeed; /* Chip present which snoops speed changes */ | 141 | static int autospeed; /* Chip present which snoops speed changes */ |
141 | static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ | 142 | static int pio_mask = ATA_PIO4; /* PIO range for autospeed devices */ |
142 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ | 143 | static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */ |
143 | 144 | ||
145 | #ifdef PATA_WINBOND_VLB_MODULE | ||
146 | static int winbond = 1; /* Set to probe Winbond controllers, | ||
147 | give I/O port if non standard */ | ||
148 | #else | ||
149 | static int winbond; /* Set to probe Winbond controllers, | ||
150 | give I/O port if non standard */ | ||
151 | #endif | ||
152 | |||
144 | /** | 153 | /** |
145 | * legacy_probe_add - Add interface to probe list | 154 | * legacy_probe_add - Add interface to probe list |
146 | * @port: Controller port | 155 | * @port: Controller port |
@@ -1297,6 +1306,7 @@ MODULE_AUTHOR("Alan Cox"); | |||
1297 | MODULE_DESCRIPTION("low-level driver for legacy ATA"); | 1306 | MODULE_DESCRIPTION("low-level driver for legacy ATA"); |
1298 | MODULE_LICENSE("GPL"); | 1307 | MODULE_LICENSE("GPL"); |
1299 | MODULE_VERSION(DRV_VERSION); | 1308 | MODULE_VERSION(DRV_VERSION); |
1309 | MODULE_ALIAS("pata_winbond"); | ||
1300 | 1310 | ||
1301 | module_param(probe_all, int, 0); | 1311 | module_param(probe_all, int, 0); |
1302 | module_param(autospeed, int, 0); | 1312 | module_param(autospeed, int, 0); |
@@ -1305,6 +1315,7 @@ module_param(ht6560b, int, 0); | |||
1305 | module_param(opti82c611a, int, 0); | 1315 | module_param(opti82c611a, int, 0); |
1306 | module_param(opti82c46x, int, 0); | 1316 | module_param(opti82c46x, int, 0); |
1307 | module_param(qdi, int, 0); | 1317 | module_param(qdi, int, 0); |
1318 | module_param(winbond, int, 0); | ||
1308 | module_param(pio_mask, int, 0); | 1319 | module_param(pio_mask, int, 0); |
1309 | module_param(iordy_mask, int, 0); | 1320 | module_param(iordy_mask, int, 0); |
1310 | 1321 | ||
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c deleted file mode 100644 index 6d8619b6f670..000000000000 --- a/drivers/ata/pata_winbond.c +++ /dev/null | |||
@@ -1,282 +0,0 @@ | |||
1 | /* | ||
2 | * pata_winbond.c - Winbond VLB ATA controllers | ||
3 | * (C) 2006 Red Hat | ||
4 | * | ||
5 | * Support for the Winbond 83759A when operating in advanced mode. | ||
6 | * Multichip mode is not currently supported. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/blkdev.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <scsi/scsi_host.h> | ||
15 | #include <linux/libata.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #define DRV_NAME "pata_winbond" | ||
19 | #define DRV_VERSION "0.0.3" | ||
20 | |||
21 | #define NR_HOST 4 /* Two winbond controllers, two channels each */ | ||
22 | |||
23 | struct winbond_data { | ||
24 | unsigned long config; | ||
25 | struct platform_device *platform_dev; | ||
26 | }; | ||
27 | |||
28 | static struct ata_host *winbond_host[NR_HOST]; | ||
29 | static struct winbond_data winbond_data[NR_HOST]; | ||
30 | static int nr_winbond_host; | ||
31 | |||
32 | #ifdef MODULE | ||
33 | static int probe_winbond = 1; | ||
34 | #else | ||
35 | static int probe_winbond; | ||
36 | #endif | ||
37 | |||
38 | static DEFINE_SPINLOCK(winbond_lock); | ||
39 | |||
40 | static void winbond_writecfg(unsigned long port, u8 reg, u8 val) | ||
41 | { | ||
42 | unsigned long flags; | ||
43 | spin_lock_irqsave(&winbond_lock, flags); | ||
44 | outb(reg, port + 0x01); | ||
45 | outb(val, port + 0x02); | ||
46 | spin_unlock_irqrestore(&winbond_lock, flags); | ||
47 | } | ||
48 | |||
49 | static u8 winbond_readcfg(unsigned long port, u8 reg) | ||
50 | { | ||
51 | u8 val; | ||
52 | |||
53 | unsigned long flags; | ||
54 | spin_lock_irqsave(&winbond_lock, flags); | ||
55 | outb(reg, port + 0x01); | ||
56 | val = inb(port + 0x02); | ||
57 | spin_unlock_irqrestore(&winbond_lock, flags); | ||
58 | |||
59 | return val; | ||
60 | } | ||
61 | |||
62 | static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev) | ||
63 | { | ||
64 | struct ata_timing t; | ||
65 | struct winbond_data *winbond = ap->host->private_data; | ||
66 | int active, recovery; | ||
67 | u8 reg; | ||
68 | int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2); | ||
69 | |||
70 | reg = winbond_readcfg(winbond->config, 0x81); | ||
71 | |||
72 | /* Get the timing data in cycles */ | ||
73 | if (reg & 0x40) /* Fast VLB bus, assume 50MHz */ | ||
74 | ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000); | ||
75 | else | ||
76 | ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000); | ||
77 | |||
78 | active = (clamp_val(t.active, 3, 17) - 1) & 0x0F; | ||
79 | recovery = (clamp_val(t.recover, 1, 15) + 1) & 0x0F; | ||
80 | timing = (active << 4) | recovery; | ||
81 | winbond_writecfg(winbond->config, timing, reg); | ||
82 | |||
83 | /* Load the setup timing */ | ||
84 | |||
85 | reg = 0x35; | ||
86 | if (adev->class != ATA_DEV_ATA) | ||
87 | reg |= 0x08; /* FIFO off */ | ||
88 | if (!ata_pio_need_iordy(adev)) | ||
89 | reg |= 0x02; /* IORDY off */ | ||
90 | reg |= (clamp_val(t.setup, 0, 3) << 6); | ||
91 | winbond_writecfg(winbond->config, timing + 1, reg); | ||
92 | } | ||
93 | |||
94 | |||
95 | static unsigned int winbond_data_xfer(struct ata_device *dev, | ||
96 | unsigned char *buf, unsigned int buflen, int rw) | ||
97 | { | ||
98 | struct ata_port *ap = dev->link->ap; | ||
99 | int slop = buflen & 3; | ||
100 | |||
101 | if (ata_id_has_dword_io(dev->id)) { | ||
102 | if (rw == READ) | ||
103 | ioread32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
104 | else | ||
105 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | ||
106 | |||
107 | if (unlikely(slop)) { | ||
108 | __le32 pad; | ||
109 | if (rw == READ) { | ||
110 | pad = cpu_to_le32(ioread32(ap->ioaddr.data_addr)); | ||
111 | memcpy(buf + buflen - slop, &pad, slop); | ||
112 | } else { | ||
113 | memcpy(&pad, buf + buflen - slop, slop); | ||
114 | iowrite32(le32_to_cpu(pad), ap->ioaddr.data_addr); | ||
115 | } | ||
116 | buflen += 4 - slop; | ||
117 | } | ||
118 | } else | ||
119 | buflen = ata_sff_data_xfer(dev, buf, buflen, rw); | ||
120 | |||
121 | return buflen; | ||
122 | } | ||
123 | |||
124 | static struct scsi_host_template winbond_sht = { | ||
125 | ATA_PIO_SHT(DRV_NAME), | ||
126 | }; | ||
127 | |||
128 | static struct ata_port_operations winbond_port_ops = { | ||
129 | .inherits = &ata_sff_port_ops, | ||
130 | .sff_data_xfer = winbond_data_xfer, | ||
131 | .cable_detect = ata_cable_40wire, | ||
132 | .set_piomode = winbond_set_piomode, | ||
133 | }; | ||
134 | |||
135 | /** | ||
136 | * winbond_init_one - attach a winbond interface | ||
137 | * @type: Type to display | ||
138 | * @io: I/O port start | ||
139 | * @irq: interrupt line | ||
140 | * @fast: True if on a > 33Mhz VLB | ||
141 | * | ||
142 | * Register a VLB bus IDE interface. Such interfaces are PIO and we | ||
143 | * assume do not support IRQ sharing. | ||
144 | */ | ||
145 | |||
146 | static __init int winbond_init_one(unsigned long port) | ||
147 | { | ||
148 | struct platform_device *pdev; | ||
149 | u8 reg; | ||
150 | int i, rc; | ||
151 | |||
152 | reg = winbond_readcfg(port, 0x81); | ||
153 | reg |= 0x80; /* jumpered mode off */ | ||
154 | winbond_writecfg(port, 0x81, reg); | ||
155 | reg = winbond_readcfg(port, 0x83); | ||
156 | reg |= 0xF0; /* local control */ | ||
157 | winbond_writecfg(port, 0x83, reg); | ||
158 | reg = winbond_readcfg(port, 0x85); | ||
159 | reg |= 0xF0; /* programmable timing */ | ||
160 | winbond_writecfg(port, 0x85, reg); | ||
161 | |||
162 | reg = winbond_readcfg(port, 0x81); | ||
163 | |||
164 | if (!(reg & 0x03)) /* Disabled */ | ||
165 | return -ENODEV; | ||
166 | |||
167 | for (i = 0; i < 2 ; i ++) { | ||
168 | unsigned long cmd_port = 0x1F0 - (0x80 * i); | ||
169 | unsigned long ctl_port = cmd_port + 0x206; | ||
170 | struct ata_host *host; | ||
171 | struct ata_port *ap; | ||
172 | void __iomem *cmd_addr, *ctl_addr; | ||
173 | |||
174 | if (!(reg & (1 << i))) | ||
175 | continue; | ||
176 | |||
177 | pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0); | ||
178 | if (IS_ERR(pdev)) | ||
179 | return PTR_ERR(pdev); | ||
180 | |||
181 | rc = -ENOMEM; | ||
182 | host = ata_host_alloc(&pdev->dev, 1); | ||
183 | if (!host) | ||
184 | goto err_unregister; | ||
185 | ap = host->ports[0]; | ||
186 | |||
187 | rc = -ENOMEM; | ||
188 | cmd_addr = devm_ioport_map(&pdev->dev, cmd_port, 8); | ||
189 | ctl_addr = devm_ioport_map(&pdev->dev, ctl_port, 1); | ||
190 | if (!cmd_addr || !ctl_addr) | ||
191 | goto err_unregister; | ||
192 | |||
193 | ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", cmd_port, ctl_port); | ||
194 | |||
195 | ap->ops = &winbond_port_ops; | ||
196 | ap->pio_mask = ATA_PIO4; | ||
197 | ap->flags |= ATA_FLAG_SLAVE_POSS; | ||
198 | ap->ioaddr.cmd_addr = cmd_addr; | ||
199 | ap->ioaddr.altstatus_addr = ctl_addr; | ||
200 | ap->ioaddr.ctl_addr = ctl_addr; | ||
201 | ata_sff_std_ports(&ap->ioaddr); | ||
202 | |||
203 | /* hook in a private data structure per channel */ | ||
204 | host->private_data = &winbond_data[nr_winbond_host]; | ||
205 | winbond_data[nr_winbond_host].config = port; | ||
206 | winbond_data[nr_winbond_host].platform_dev = pdev; | ||
207 | |||
208 | /* activate */ | ||
209 | rc = ata_host_activate(host, 14 + i, ata_sff_interrupt, 0, | ||
210 | &winbond_sht); | ||
211 | if (rc) | ||
212 | goto err_unregister; | ||
213 | |||
214 | winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev); | ||
215 | } | ||
216 | |||
217 | return 0; | ||
218 | |||
219 | err_unregister: | ||
220 | platform_device_unregister(pdev); | ||
221 | return rc; | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * winbond_init - attach winbond interfaces | ||
226 | * | ||
227 | * Attach winbond IDE interfaces by scanning the ports it may occupy. | ||
228 | */ | ||
229 | |||
230 | static __init int winbond_init(void) | ||
231 | { | ||
232 | static const unsigned long config[2] = { 0x130, 0x1B0 }; | ||
233 | |||
234 | int ct = 0; | ||
235 | int i; | ||
236 | |||
237 | if (probe_winbond == 0) | ||
238 | return -ENODEV; | ||
239 | |||
240 | /* | ||
241 | * Check both base addresses | ||
242 | */ | ||
243 | |||
244 | for (i = 0; i < 2; i++) { | ||
245 | if (probe_winbond & (1<<i)) { | ||
246 | int ret = 0; | ||
247 | unsigned long port = config[i]; | ||
248 | |||
249 | if (request_region(port, 2, "pata_winbond")) { | ||
250 | ret = winbond_init_one(port); | ||
251 | if (ret <= 0) | ||
252 | release_region(port, 2); | ||
253 | else ct+= ret; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | if (ct != 0) | ||
258 | return 0; | ||
259 | return -ENODEV; | ||
260 | } | ||
261 | |||
262 | static __exit void winbond_exit(void) | ||
263 | { | ||
264 | int i; | ||
265 | |||
266 | for (i = 0; i < nr_winbond_host; i++) { | ||
267 | ata_host_detach(winbond_host[i]); | ||
268 | release_region(winbond_data[i].config, 2); | ||
269 | platform_device_unregister(winbond_data[i].platform_dev); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | MODULE_AUTHOR("Alan Cox"); | ||
274 | MODULE_DESCRIPTION("low-level driver for Winbond VL ATA"); | ||
275 | MODULE_LICENSE("GPL"); | ||
276 | MODULE_VERSION(DRV_VERSION); | ||
277 | |||
278 | module_init(winbond_init); | ||
279 | module_exit(winbond_exit); | ||
280 | |||
281 | module_param(probe_winbond, int, 0); | ||
282 | |||
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index ea24c1e51be2..6cf57c5c2b5f 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c | |||
@@ -1459,7 +1459,7 @@ static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag) | |||
1459 | { | 1459 | { |
1460 | struct scatterlist *sg = qc->sg; | 1460 | struct scatterlist *sg = qc->sg; |
1461 | struct ata_port *ap = qc->ap; | 1461 | struct ata_port *ap = qc->ap; |
1462 | u32 dma_chan; | 1462 | int dma_chan; |
1463 | struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); | 1463 | struct sata_dwc_device *hsdev = HSDEV_FROM_AP(ap); |
1464 | struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); | 1464 | struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); |
1465 | int err; | 1465 | int err; |
@@ -1588,7 +1588,7 @@ static const struct ata_port_info sata_dwc_port_info[] = { | |||
1588 | }, | 1588 | }, |
1589 | }; | 1589 | }; |
1590 | 1590 | ||
1591 | static int sata_dwc_probe(struct of_device *ofdev, | 1591 | static int sata_dwc_probe(struct platform_device *ofdev, |
1592 | const struct of_device_id *match) | 1592 | const struct of_device_id *match) |
1593 | { | 1593 | { |
1594 | struct sata_dwc_device *hsdev; | 1594 | struct sata_dwc_device *hsdev; |
@@ -1702,7 +1702,7 @@ error_out: | |||
1702 | return err; | 1702 | return err; |
1703 | } | 1703 | } |
1704 | 1704 | ||
1705 | static int sata_dwc_remove(struct of_device *ofdev) | 1705 | static int sata_dwc_remove(struct platform_device *ofdev) |
1706 | { | 1706 | { |
1707 | struct device *dev = &ofdev->dev; | 1707 | struct device *dev = &ofdev->dev; |
1708 | struct ata_host *host = dev_get_drvdata(dev); | 1708 | struct ata_host *host = dev_get_drvdata(dev); |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 9463c71dd38e..81982594a014 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1898,19 +1898,25 @@ static void mv_bmdma_start(struct ata_queued_cmd *qc) | |||
1898 | * LOCKING: | 1898 | * LOCKING: |
1899 | * Inherited from caller. | 1899 | * Inherited from caller. |
1900 | */ | 1900 | */ |
1901 | static void mv_bmdma_stop(struct ata_queued_cmd *qc) | 1901 | static void mv_bmdma_stop_ap(struct ata_port *ap) |
1902 | { | 1902 | { |
1903 | struct ata_port *ap = qc->ap; | ||
1904 | void __iomem *port_mmio = mv_ap_base(ap); | 1903 | void __iomem *port_mmio = mv_ap_base(ap); |
1905 | u32 cmd; | 1904 | u32 cmd; |
1906 | 1905 | ||
1907 | /* clear start/stop bit */ | 1906 | /* clear start/stop bit */ |
1908 | cmd = readl(port_mmio + BMDMA_CMD); | 1907 | cmd = readl(port_mmio + BMDMA_CMD); |
1909 | cmd &= ~ATA_DMA_START; | 1908 | if (cmd & ATA_DMA_START) { |
1910 | writelfl(cmd, port_mmio + BMDMA_CMD); | 1909 | cmd &= ~ATA_DMA_START; |
1910 | writelfl(cmd, port_mmio + BMDMA_CMD); | ||
1911 | |||
1912 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | ||
1913 | ata_sff_dma_pause(ap); | ||
1914 | } | ||
1915 | } | ||
1911 | 1916 | ||
1912 | /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */ | 1917 | static void mv_bmdma_stop(struct ata_queued_cmd *qc) |
1913 | ata_sff_dma_pause(ap); | 1918 | { |
1919 | mv_bmdma_stop_ap(qc->ap); | ||
1914 | } | 1920 | } |
1915 | 1921 | ||
1916 | /** | 1922 | /** |
@@ -1934,8 +1940,21 @@ static u8 mv_bmdma_status(struct ata_port *ap) | |||
1934 | reg = readl(port_mmio + BMDMA_STATUS); | 1940 | reg = readl(port_mmio + BMDMA_STATUS); |
1935 | if (reg & ATA_DMA_ACTIVE) | 1941 | if (reg & ATA_DMA_ACTIVE) |
1936 | status = ATA_DMA_ACTIVE; | 1942 | status = ATA_DMA_ACTIVE; |
1937 | else | 1943 | else if (reg & ATA_DMA_ERR) |
1938 | status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; | 1944 | status = (reg & ATA_DMA_ERR) | ATA_DMA_INTR; |
1945 | else { | ||
1946 | /* | ||
1947 | * Just because DMA_ACTIVE is 0 (DMA completed), | ||
1948 | * this does _not_ mean the device is "done". | ||
1949 | * So we should not yet be signalling ATA_DMA_INTR | ||
1950 | * in some cases. Eg. DSM/TRIM, and perhaps others. | ||
1951 | */ | ||
1952 | mv_bmdma_stop_ap(ap); | ||
1953 | if (ioread8(ap->ioaddr.altstatus_addr) & ATA_BUSY) | ||
1954 | status = 0; | ||
1955 | else | ||
1956 | status = ATA_DMA_INTR; | ||
1957 | } | ||
1939 | return status; | 1958 | return status; |
1940 | } | 1959 | } |
1941 | 1960 | ||
@@ -1995,6 +2014,9 @@ static void mv_qc_prep(struct ata_queued_cmd *qc) | |||
1995 | 2014 | ||
1996 | switch (tf->protocol) { | 2015 | switch (tf->protocol) { |
1997 | case ATA_PROT_DMA: | 2016 | case ATA_PROT_DMA: |
2017 | if (tf->command == ATA_CMD_DSM) | ||
2018 | return; | ||
2019 | /* fall-thru */ | ||
1998 | case ATA_PROT_NCQ: | 2020 | case ATA_PROT_NCQ: |
1999 | break; /* continue below */ | 2021 | break; /* continue below */ |
2000 | case ATA_PROT_PIO: | 2022 | case ATA_PROT_PIO: |
@@ -2094,6 +2116,8 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc) | |||
2094 | if ((tf->protocol != ATA_PROT_DMA) && | 2116 | if ((tf->protocol != ATA_PROT_DMA) && |
2095 | (tf->protocol != ATA_PROT_NCQ)) | 2117 | (tf->protocol != ATA_PROT_NCQ)) |
2096 | return; | 2118 | return; |
2119 | if (tf->command == ATA_CMD_DSM) | ||
2120 | return; /* use bmdma for this */ | ||
2097 | 2121 | ||
2098 | /* Fill in Gen IIE command request block */ | 2122 | /* Fill in Gen IIE command request block */ |
2099 | if (!(tf->flags & ATA_TFLAG_WRITE)) | 2123 | if (!(tf->flags & ATA_TFLAG_WRITE)) |
@@ -2289,6 +2313,12 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc) | |||
2289 | 2313 | ||
2290 | switch (qc->tf.protocol) { | 2314 | switch (qc->tf.protocol) { |
2291 | case ATA_PROT_DMA: | 2315 | case ATA_PROT_DMA: |
2316 | if (qc->tf.command == ATA_CMD_DSM) { | ||
2317 | if (!ap->ops->bmdma_setup) /* no bmdma on GEN_I */ | ||
2318 | return AC_ERR_OTHER; | ||
2319 | break; /* use bmdma for this */ | ||
2320 | } | ||
2321 | /* fall thru */ | ||
2292 | case ATA_PROT_NCQ: | 2322 | case ATA_PROT_NCQ: |
2293 | mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); | 2323 | mv_start_edma(ap, port_mmio, pp, qc->tf.protocol); |
2294 | pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; | 2324 | pp->req_idx = (pp->req_idx + 1) & MV_MAX_Q_DEPTH_MASK; |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index c8a44f5e0584..40af43ebd92d 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -568,7 +568,7 @@ static int _request_firmware(const struct firmware **firmware_p, | |||
568 | out: | 568 | out: |
569 | if (retval) { | 569 | if (retval) { |
570 | release_firmware(firmware); | 570 | release_firmware(firmware); |
571 | firmware_p = NULL; | 571 | *firmware_p = NULL; |
572 | } | 572 | } |
573 | 573 | ||
574 | return retval; | 574 | return retval; |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index ac1b682edecb..ab735a605cf3 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -834,7 +834,7 @@ static int blkfront_probe(struct xenbus_device *dev, | |||
834 | char *type; | 834 | char *type; |
835 | int len; | 835 | int len; |
836 | /* no unplug has been done: do not hook devices != xen vbds */ | 836 | /* no unplug has been done: do not hook devices != xen vbds */ |
837 | if (xen_platform_pci_unplug & XEN_UNPLUG_IGNORE) { | 837 | if (xen_platform_pci_unplug & XEN_UNPLUG_UNNECESSARY) { |
838 | int major; | 838 | int major; |
839 | 839 | ||
840 | if (!VDEV_IS_EXTENDED(vdevice)) | 840 | if (!VDEV_IS_EXTENDED(vdevice)) |
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c index 2982b3ee9465..057413bb16e2 100644 --- a/drivers/block/xsysace.c +++ b/drivers/block/xsysace.c | |||
@@ -94,6 +94,7 @@ | |||
94 | #include <linux/hdreg.h> | 94 | #include <linux/hdreg.h> |
95 | #include <linux/platform_device.h> | 95 | #include <linux/platform_device.h> |
96 | #if defined(CONFIG_OF) | 96 | #if defined(CONFIG_OF) |
97 | #include <linux/of_address.h> | ||
97 | #include <linux/of_device.h> | 98 | #include <linux/of_device.h> |
98 | #include <linux/of_platform.h> | 99 | #include <linux/of_platform.h> |
99 | #endif | 100 | #endif |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index ddf5def1b0da..710af89b176d 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -819,13 +819,16 @@ static const struct intel_driver_description { | |||
819 | "Sandybridge", NULL, &intel_gen6_driver }, | 819 | "Sandybridge", NULL, &intel_gen6_driver }, |
820 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG, | 820 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG, |
821 | "Sandybridge", NULL, &intel_gen6_driver }, | 821 | "Sandybridge", NULL, &intel_gen6_driver }, |
822 | { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB, PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG, | ||
823 | "Sandybridge", NULL, &intel_gen6_driver }, | ||
822 | { 0, 0, NULL, NULL, NULL } | 824 | { 0, 0, NULL, NULL, NULL } |
823 | }; | 825 | }; |
824 | 826 | ||
825 | static int __devinit intel_gmch_probe(struct pci_dev *pdev, | 827 | static int __devinit intel_gmch_probe(struct pci_dev *pdev, |
826 | struct agp_bridge_data *bridge) | 828 | struct agp_bridge_data *bridge) |
827 | { | 829 | { |
828 | int i; | 830 | int i, mask; |
831 | |||
829 | bridge->driver = NULL; | 832 | bridge->driver = NULL; |
830 | 833 | ||
831 | for (i = 0; intel_agp_chipsets[i].name != NULL; i++) { | 834 | for (i = 0; intel_agp_chipsets[i].name != NULL; i++) { |
@@ -845,14 +848,19 @@ static int __devinit intel_gmch_probe(struct pci_dev *pdev, | |||
845 | 848 | ||
846 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); | 849 | dev_info(&pdev->dev, "Intel %s Chipset\n", intel_agp_chipsets[i].name); |
847 | 850 | ||
848 | if (bridge->driver->mask_memory == intel_i965_mask_memory) { | 851 | if (bridge->driver->mask_memory == intel_gen6_mask_memory) |
849 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(36))) | 852 | mask = 40; |
850 | dev_err(&intel_private.pcidev->dev, | 853 | else if (bridge->driver->mask_memory == intel_i965_mask_memory) |
851 | "set gfx device dma mask 36bit failed!\n"); | 854 | mask = 36; |
852 | else | 855 | else |
853 | pci_set_consistent_dma_mask(intel_private.pcidev, | 856 | mask = 32; |
854 | DMA_BIT_MASK(36)); | 857 | |
855 | } | 858 | if (pci_set_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask))) |
859 | dev_err(&intel_private.pcidev->dev, | ||
860 | "set gfx device dma mask %d-bit failed!\n", mask); | ||
861 | else | ||
862 | pci_set_consistent_dma_mask(intel_private.pcidev, | ||
863 | DMA_BIT_MASK(mask)); | ||
856 | 864 | ||
857 | return 1; | 865 | return 1; |
858 | } | 866 | } |
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index c05e3e518268..08d47532e605 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -204,6 +204,7 @@ | |||
204 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102 | 204 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_IG 0x0102 |
205 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 | 205 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB 0x0104 |
206 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106 | 206 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_IG 0x0106 |
207 | #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_D0_IG 0x0126 | ||
207 | 208 | ||
208 | /* cover 915 and 945 variants */ | 209 | /* cover 915 and 945 variants */ |
209 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ | 210 | #define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ |
diff --git a/drivers/char/hangcheck-timer.c b/drivers/char/hangcheck-timer.c index e0249722d25f..f953c96efc86 100644 --- a/drivers/char/hangcheck-timer.c +++ b/drivers/char/hangcheck-timer.c | |||
@@ -159,7 +159,7 @@ static void hangcheck_fire(unsigned long data) | |||
159 | if (hangcheck_dump_tasks) { | 159 | if (hangcheck_dump_tasks) { |
160 | printk(KERN_CRIT "Hangcheck: Task state:\n"); | 160 | printk(KERN_CRIT "Hangcheck: Task state:\n"); |
161 | #ifdef CONFIG_MAGIC_SYSRQ | 161 | #ifdef CONFIG_MAGIC_SYSRQ |
162 | handle_sysrq('t', NULL); | 162 | handle_sysrq('t'); |
163 | #endif /* CONFIG_MAGIC_SYSRQ */ | 163 | #endif /* CONFIG_MAGIC_SYSRQ */ |
164 | } | 164 | } |
165 | if (hangcheck_reboot) { | 165 | if (hangcheck_reboot) { |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index fa27d1676ee5..3afd62e856eb 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -651,7 +651,7 @@ int hvc_poll(struct hvc_struct *hp) | |||
651 | if (sysrq_pressed) | 651 | if (sysrq_pressed) |
652 | continue; | 652 | continue; |
653 | } else if (sysrq_pressed) { | 653 | } else if (sysrq_pressed) { |
654 | handle_sysrq(buf[i], tty); | 654 | handle_sysrq(buf[i]); |
655 | sysrq_pressed = 0; | 655 | sysrq_pressed = 0; |
656 | continue; | 656 | continue; |
657 | } | 657 | } |
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c index 1f4b6de65a2d..a2bc885ce60a 100644 --- a/drivers/char/hvsi.c +++ b/drivers/char/hvsi.c | |||
@@ -403,7 +403,7 @@ static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) | |||
403 | hp->sysrq = 1; | 403 | hp->sysrq = 1; |
404 | continue; | 404 | continue; |
405 | } else if (hp->sysrq) { | 405 | } else if (hp->sysrq) { |
406 | handle_sysrq(c, hp->tty); | 406 | handle_sysrq(c); |
407 | hp->sysrq = 0; | 407 | hp->sysrq = 0; |
408 | continue; | 408 | continue; |
409 | } | 409 | } |
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 07f3ea38b582..d4b71e8d0d23 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -1650,7 +1650,7 @@ ip2_close( PTTY tty, struct file *pFile ) | |||
1650 | /* disable DSS reporting */ | 1650 | /* disable DSS reporting */ |
1651 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, | 1651 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 4, |
1652 | CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); | 1652 | CMD_DCD_NREP, CMD_CTS_NREP, CMD_DSR_NREP, CMD_RI_NREP); |
1653 | if ( !tty || (tty->termios->c_cflag & HUPCL) ) { | 1653 | if (tty->termios->c_cflag & HUPCL) { |
1654 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); | 1654 | i2QueueCommands(PTYPE_INLINE, pCh, 100, 2, CMD_RTSDN, CMD_DTRDN); |
1655 | pCh->dataSetOut &= ~(I2_DTR | I2_RTS); | 1655 | pCh->dataSetOut &= ~(I2_DTR | I2_RTS); |
1656 | i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); | 1656 | i2QueueCommands( PTYPE_INLINE, pCh, 100, 1, CMD_PAUSE(25)); |
@@ -2930,6 +2930,8 @@ ip2_ipl_ioctl (struct file *pFile, UINT cmd, ULONG arg ) | |||
2930 | if ( pCh ) | 2930 | if ( pCh ) |
2931 | { | 2931 | { |
2932 | rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); | 2932 | rc = copy_to_user(argp, pCh, sizeof(i2ChanStr)); |
2933 | if (rc) | ||
2934 | rc = -EFAULT; | ||
2933 | } else { | 2935 | } else { |
2934 | rc = -ENODEV; | 2936 | rc = -ENODEV; |
2935 | } | 2937 | } |
diff --git a/drivers/char/pty.c b/drivers/char/pty.c index ad46eae1f9bb..c350d01716bd 100644 --- a/drivers/char/pty.c +++ b/drivers/char/pty.c | |||
@@ -675,8 +675,8 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
675 | } | 675 | } |
676 | 676 | ||
677 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 677 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
678 | filp->private_data = tty; | 678 | |
679 | file_move(filp, &tty->tty_files); | 679 | tty_add_file(tty, filp); |
680 | 680 | ||
681 | retval = devpts_pty_new(inode, tty->link); | 681 | retval = devpts_pty_new(inode, tty->link); |
682 | if (retval) | 682 | if (retval) |
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index 79c3bc69165a..7c79d243acc9 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c | |||
@@ -1244,6 +1244,7 @@ static int set_config(struct tty_struct *tty, struct r_port *info, | |||
1244 | } | 1244 | } |
1245 | info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); | 1245 | info->flags = ((info->flags & ~ROCKET_USR_MASK) | (new_serial.flags & ROCKET_USR_MASK)); |
1246 | configure_r_port(tty, info, NULL); | 1246 | configure_r_port(tty, info, NULL); |
1247 | mutex_unlock(&info->port.mutex); | ||
1247 | return 0; | 1248 | return 0; |
1248 | } | 1249 | } |
1249 | 1250 | ||
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index fef80cfcab5c..e63b830c86cc 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -691,8 +691,10 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
691 | if (info->port.count == 1) { | 691 | if (info->port.count == 1) { |
692 | /* 1st open on this device, init hardware */ | 692 | /* 1st open on this device, init hardware */ |
693 | retval = startup(info); | 693 | retval = startup(info); |
694 | if (retval < 0) | 694 | if (retval < 0) { |
695 | mutex_unlock(&info->port.mutex); | ||
695 | goto cleanup; | 696 | goto cleanup; |
697 | } | ||
696 | } | 698 | } |
697 | mutex_unlock(&info->port.mutex); | 699 | mutex_unlock(&info->port.mutex); |
698 | retval = block_til_ready(tty, filp, info); | 700 | retval = block_til_ready(tty, filp, info); |
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 878ac0c2cc68..ef31bb81e843 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/fs.h> | 20 | #include <linux/fs.h> |
21 | #include <linux/tty.h> | ||
22 | #include <linux/mount.h> | 21 | #include <linux/mount.h> |
23 | #include <linux/kdev_t.h> | 22 | #include <linux/kdev_t.h> |
24 | #include <linux/major.h> | 23 | #include <linux/major.h> |
@@ -76,7 +75,7 @@ static int __init sysrq_always_enabled_setup(char *str) | |||
76 | __setup("sysrq_always_enabled", sysrq_always_enabled_setup); | 75 | __setup("sysrq_always_enabled", sysrq_always_enabled_setup); |
77 | 76 | ||
78 | 77 | ||
79 | static void sysrq_handle_loglevel(int key, struct tty_struct *tty) | 78 | static void sysrq_handle_loglevel(int key) |
80 | { | 79 | { |
81 | int i; | 80 | int i; |
82 | 81 | ||
@@ -93,7 +92,7 @@ static struct sysrq_key_op sysrq_loglevel_op = { | |||
93 | }; | 92 | }; |
94 | 93 | ||
95 | #ifdef CONFIG_VT | 94 | #ifdef CONFIG_VT |
96 | static void sysrq_handle_SAK(int key, struct tty_struct *tty) | 95 | static void sysrq_handle_SAK(int key) |
97 | { | 96 | { |
98 | struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; | 97 | struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work; |
99 | schedule_work(SAK_work); | 98 | schedule_work(SAK_work); |
@@ -109,7 +108,7 @@ static struct sysrq_key_op sysrq_SAK_op = { | |||
109 | #endif | 108 | #endif |
110 | 109 | ||
111 | #ifdef CONFIG_VT | 110 | #ifdef CONFIG_VT |
112 | static void sysrq_handle_unraw(int key, struct tty_struct *tty) | 111 | static void sysrq_handle_unraw(int key) |
113 | { | 112 | { |
114 | struct kbd_struct *kbd = &kbd_table[fg_console]; | 113 | struct kbd_struct *kbd = &kbd_table[fg_console]; |
115 | 114 | ||
@@ -126,7 +125,7 @@ static struct sysrq_key_op sysrq_unraw_op = { | |||
126 | #define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) | 125 | #define sysrq_unraw_op (*(struct sysrq_key_op *)NULL) |
127 | #endif /* CONFIG_VT */ | 126 | #endif /* CONFIG_VT */ |
128 | 127 | ||
129 | static void sysrq_handle_crash(int key, struct tty_struct *tty) | 128 | static void sysrq_handle_crash(int key) |
130 | { | 129 | { |
131 | char *killer = NULL; | 130 | char *killer = NULL; |
132 | 131 | ||
@@ -141,7 +140,7 @@ static struct sysrq_key_op sysrq_crash_op = { | |||
141 | .enable_mask = SYSRQ_ENABLE_DUMP, | 140 | .enable_mask = SYSRQ_ENABLE_DUMP, |
142 | }; | 141 | }; |
143 | 142 | ||
144 | static void sysrq_handle_reboot(int key, struct tty_struct *tty) | 143 | static void sysrq_handle_reboot(int key) |
145 | { | 144 | { |
146 | lockdep_off(); | 145 | lockdep_off(); |
147 | local_irq_enable(); | 146 | local_irq_enable(); |
@@ -154,7 +153,7 @@ static struct sysrq_key_op sysrq_reboot_op = { | |||
154 | .enable_mask = SYSRQ_ENABLE_BOOT, | 153 | .enable_mask = SYSRQ_ENABLE_BOOT, |
155 | }; | 154 | }; |
156 | 155 | ||
157 | static void sysrq_handle_sync(int key, struct tty_struct *tty) | 156 | static void sysrq_handle_sync(int key) |
158 | { | 157 | { |
159 | emergency_sync(); | 158 | emergency_sync(); |
160 | } | 159 | } |
@@ -165,7 +164,7 @@ static struct sysrq_key_op sysrq_sync_op = { | |||
165 | .enable_mask = SYSRQ_ENABLE_SYNC, | 164 | .enable_mask = SYSRQ_ENABLE_SYNC, |
166 | }; | 165 | }; |
167 | 166 | ||
168 | static void sysrq_handle_show_timers(int key, struct tty_struct *tty) | 167 | static void sysrq_handle_show_timers(int key) |
169 | { | 168 | { |
170 | sysrq_timer_list_show(); | 169 | sysrq_timer_list_show(); |
171 | } | 170 | } |
@@ -176,7 +175,7 @@ static struct sysrq_key_op sysrq_show_timers_op = { | |||
176 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", | 175 | .action_msg = "Show clockevent devices & pending hrtimers (no others)", |
177 | }; | 176 | }; |
178 | 177 | ||
179 | static void sysrq_handle_mountro(int key, struct tty_struct *tty) | 178 | static void sysrq_handle_mountro(int key) |
180 | { | 179 | { |
181 | emergency_remount(); | 180 | emergency_remount(); |
182 | } | 181 | } |
@@ -188,7 +187,7 @@ static struct sysrq_key_op sysrq_mountro_op = { | |||
188 | }; | 187 | }; |
189 | 188 | ||
190 | #ifdef CONFIG_LOCKDEP | 189 | #ifdef CONFIG_LOCKDEP |
191 | static void sysrq_handle_showlocks(int key, struct tty_struct *tty) | 190 | static void sysrq_handle_showlocks(int key) |
192 | { | 191 | { |
193 | debug_show_all_locks(); | 192 | debug_show_all_locks(); |
194 | } | 193 | } |
@@ -226,7 +225,7 @@ static void sysrq_showregs_othercpus(struct work_struct *dummy) | |||
226 | 225 | ||
227 | static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); | 226 | static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); |
228 | 227 | ||
229 | static void sysrq_handle_showallcpus(int key, struct tty_struct *tty) | 228 | static void sysrq_handle_showallcpus(int key) |
230 | { | 229 | { |
231 | /* | 230 | /* |
232 | * Fall back to the workqueue based printing if the | 231 | * Fall back to the workqueue based printing if the |
@@ -252,7 +251,7 @@ static struct sysrq_key_op sysrq_showallcpus_op = { | |||
252 | }; | 251 | }; |
253 | #endif | 252 | #endif |
254 | 253 | ||
255 | static void sysrq_handle_showregs(int key, struct tty_struct *tty) | 254 | static void sysrq_handle_showregs(int key) |
256 | { | 255 | { |
257 | struct pt_regs *regs = get_irq_regs(); | 256 | struct pt_regs *regs = get_irq_regs(); |
258 | if (regs) | 257 | if (regs) |
@@ -266,7 +265,7 @@ static struct sysrq_key_op sysrq_showregs_op = { | |||
266 | .enable_mask = SYSRQ_ENABLE_DUMP, | 265 | .enable_mask = SYSRQ_ENABLE_DUMP, |
267 | }; | 266 | }; |
268 | 267 | ||
269 | static void sysrq_handle_showstate(int key, struct tty_struct *tty) | 268 | static void sysrq_handle_showstate(int key) |
270 | { | 269 | { |
271 | show_state(); | 270 | show_state(); |
272 | } | 271 | } |
@@ -277,7 +276,7 @@ static struct sysrq_key_op sysrq_showstate_op = { | |||
277 | .enable_mask = SYSRQ_ENABLE_DUMP, | 276 | .enable_mask = SYSRQ_ENABLE_DUMP, |
278 | }; | 277 | }; |
279 | 278 | ||
280 | static void sysrq_handle_showstate_blocked(int key, struct tty_struct *tty) | 279 | static void sysrq_handle_showstate_blocked(int key) |
281 | { | 280 | { |
282 | show_state_filter(TASK_UNINTERRUPTIBLE); | 281 | show_state_filter(TASK_UNINTERRUPTIBLE); |
283 | } | 282 | } |
@@ -291,7 +290,7 @@ static struct sysrq_key_op sysrq_showstate_blocked_op = { | |||
291 | #ifdef CONFIG_TRACING | 290 | #ifdef CONFIG_TRACING |
292 | #include <linux/ftrace.h> | 291 | #include <linux/ftrace.h> |
293 | 292 | ||
294 | static void sysrq_ftrace_dump(int key, struct tty_struct *tty) | 293 | static void sysrq_ftrace_dump(int key) |
295 | { | 294 | { |
296 | ftrace_dump(DUMP_ALL); | 295 | ftrace_dump(DUMP_ALL); |
297 | } | 296 | } |
@@ -305,7 +304,7 @@ static struct sysrq_key_op sysrq_ftrace_dump_op = { | |||
305 | #define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) | 304 | #define sysrq_ftrace_dump_op (*(struct sysrq_key_op *)NULL) |
306 | #endif | 305 | #endif |
307 | 306 | ||
308 | static void sysrq_handle_showmem(int key, struct tty_struct *tty) | 307 | static void sysrq_handle_showmem(int key) |
309 | { | 308 | { |
310 | show_mem(); | 309 | show_mem(); |
311 | } | 310 | } |
@@ -330,7 +329,7 @@ static void send_sig_all(int sig) | |||
330 | } | 329 | } |
331 | } | 330 | } |
332 | 331 | ||
333 | static void sysrq_handle_term(int key, struct tty_struct *tty) | 332 | static void sysrq_handle_term(int key) |
334 | { | 333 | { |
335 | send_sig_all(SIGTERM); | 334 | send_sig_all(SIGTERM); |
336 | console_loglevel = 8; | 335 | console_loglevel = 8; |
@@ -349,7 +348,7 @@ static void moom_callback(struct work_struct *ignored) | |||
349 | 348 | ||
350 | static DECLARE_WORK(moom_work, moom_callback); | 349 | static DECLARE_WORK(moom_work, moom_callback); |
351 | 350 | ||
352 | static void sysrq_handle_moom(int key, struct tty_struct *tty) | 351 | static void sysrq_handle_moom(int key) |
353 | { | 352 | { |
354 | schedule_work(&moom_work); | 353 | schedule_work(&moom_work); |
355 | } | 354 | } |
@@ -361,7 +360,7 @@ static struct sysrq_key_op sysrq_moom_op = { | |||
361 | }; | 360 | }; |
362 | 361 | ||
363 | #ifdef CONFIG_BLOCK | 362 | #ifdef CONFIG_BLOCK |
364 | static void sysrq_handle_thaw(int key, struct tty_struct *tty) | 363 | static void sysrq_handle_thaw(int key) |
365 | { | 364 | { |
366 | emergency_thaw_all(); | 365 | emergency_thaw_all(); |
367 | } | 366 | } |
@@ -373,7 +372,7 @@ static struct sysrq_key_op sysrq_thaw_op = { | |||
373 | }; | 372 | }; |
374 | #endif | 373 | #endif |
375 | 374 | ||
376 | static void sysrq_handle_kill(int key, struct tty_struct *tty) | 375 | static void sysrq_handle_kill(int key) |
377 | { | 376 | { |
378 | send_sig_all(SIGKILL); | 377 | send_sig_all(SIGKILL); |
379 | console_loglevel = 8; | 378 | console_loglevel = 8; |
@@ -385,7 +384,7 @@ static struct sysrq_key_op sysrq_kill_op = { | |||
385 | .enable_mask = SYSRQ_ENABLE_SIGNAL, | 384 | .enable_mask = SYSRQ_ENABLE_SIGNAL, |
386 | }; | 385 | }; |
387 | 386 | ||
388 | static void sysrq_handle_unrt(int key, struct tty_struct *tty) | 387 | static void sysrq_handle_unrt(int key) |
389 | { | 388 | { |
390 | normalize_rt_tasks(); | 389 | normalize_rt_tasks(); |
391 | } | 390 | } |
@@ -493,7 +492,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) | |||
493 | sysrq_key_table[i] = op_p; | 492 | sysrq_key_table[i] = op_p; |
494 | } | 493 | } |
495 | 494 | ||
496 | void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | 495 | void __handle_sysrq(int key, bool check_mask) |
497 | { | 496 | { |
498 | struct sysrq_key_op *op_p; | 497 | struct sysrq_key_op *op_p; |
499 | int orig_log_level; | 498 | int orig_log_level; |
@@ -520,7 +519,7 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | |||
520 | if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { | 519 | if (!check_mask || sysrq_on_mask(op_p->enable_mask)) { |
521 | printk("%s\n", op_p->action_msg); | 520 | printk("%s\n", op_p->action_msg); |
522 | console_loglevel = orig_log_level; | 521 | console_loglevel = orig_log_level; |
523 | op_p->handler(key, tty); | 522 | op_p->handler(key); |
524 | } else { | 523 | } else { |
525 | printk("This sysrq operation is disabled.\n"); | 524 | printk("This sysrq operation is disabled.\n"); |
526 | } | 525 | } |
@@ -545,10 +544,10 @@ void __handle_sysrq(int key, struct tty_struct *tty, int check_mask) | |||
545 | spin_unlock_irqrestore(&sysrq_key_table_lock, flags); | 544 | spin_unlock_irqrestore(&sysrq_key_table_lock, flags); |
546 | } | 545 | } |
547 | 546 | ||
548 | void handle_sysrq(int key, struct tty_struct *tty) | 547 | void handle_sysrq(int key) |
549 | { | 548 | { |
550 | if (sysrq_on()) | 549 | if (sysrq_on()) |
551 | __handle_sysrq(key, tty, 1); | 550 | __handle_sysrq(key, true); |
552 | } | 551 | } |
553 | EXPORT_SYMBOL(handle_sysrq); | 552 | EXPORT_SYMBOL(handle_sysrq); |
554 | 553 | ||
@@ -597,7 +596,7 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type, | |||
597 | 596 | ||
598 | default: | 597 | default: |
599 | if (sysrq_down && value && value != 2) | 598 | if (sysrq_down && value && value != 2) |
600 | __handle_sysrq(sysrq_xlate[code], NULL, 1); | 599 | __handle_sysrq(sysrq_xlate[code], true); |
601 | break; | 600 | break; |
602 | } | 601 | } |
603 | 602 | ||
@@ -765,7 +764,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, | |||
765 | 764 | ||
766 | if (get_user(c, buf)) | 765 | if (get_user(c, buf)) |
767 | return -EFAULT; | 766 | return -EFAULT; |
768 | __handle_sysrq(c, NULL, 0); | 767 | __handle_sysrq(c, false); |
769 | } | 768 | } |
770 | 769 | ||
771 | return count; | 770 | return count; |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 0350c42375a2..949067a0bd47 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -136,6 +136,9 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | |||
136 | DEFINE_MUTEX(tty_mutex); | 136 | DEFINE_MUTEX(tty_mutex); |
137 | EXPORT_SYMBOL(tty_mutex); | 137 | EXPORT_SYMBOL(tty_mutex); |
138 | 138 | ||
139 | /* Spinlock to protect the tty->tty_files list */ | ||
140 | DEFINE_SPINLOCK(tty_files_lock); | ||
141 | |||
139 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); | 142 | static ssize_t tty_read(struct file *, char __user *, size_t, loff_t *); |
140 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); | 143 | static ssize_t tty_write(struct file *, const char __user *, size_t, loff_t *); |
141 | ssize_t redirected_tty_write(struct file *, const char __user *, | 144 | ssize_t redirected_tty_write(struct file *, const char __user *, |
@@ -185,6 +188,41 @@ void free_tty_struct(struct tty_struct *tty) | |||
185 | kfree(tty); | 188 | kfree(tty); |
186 | } | 189 | } |
187 | 190 | ||
191 | static inline struct tty_struct *file_tty(struct file *file) | ||
192 | { | ||
193 | return ((struct tty_file_private *)file->private_data)->tty; | ||
194 | } | ||
195 | |||
196 | /* Associate a new file with the tty structure */ | ||
197 | void tty_add_file(struct tty_struct *tty, struct file *file) | ||
198 | { | ||
199 | struct tty_file_private *priv; | ||
200 | |||
201 | /* XXX: must implement proper error handling in callers */ | ||
202 | priv = kmalloc(sizeof(*priv), GFP_KERNEL|__GFP_NOFAIL); | ||
203 | |||
204 | priv->tty = tty; | ||
205 | priv->file = file; | ||
206 | file->private_data = priv; | ||
207 | |||
208 | spin_lock(&tty_files_lock); | ||
209 | list_add(&priv->list, &tty->tty_files); | ||
210 | spin_unlock(&tty_files_lock); | ||
211 | } | ||
212 | |||
213 | /* Delete file from its tty */ | ||
214 | void tty_del_file(struct file *file) | ||
215 | { | ||
216 | struct tty_file_private *priv = file->private_data; | ||
217 | |||
218 | spin_lock(&tty_files_lock); | ||
219 | list_del(&priv->list); | ||
220 | spin_unlock(&tty_files_lock); | ||
221 | file->private_data = NULL; | ||
222 | kfree(priv); | ||
223 | } | ||
224 | |||
225 | |||
188 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) | 226 | #define TTY_NUMBER(tty) ((tty)->index + (tty)->driver->name_base) |
189 | 227 | ||
190 | /** | 228 | /** |
@@ -235,11 +273,11 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
235 | struct list_head *p; | 273 | struct list_head *p; |
236 | int count = 0; | 274 | int count = 0; |
237 | 275 | ||
238 | file_list_lock(); | 276 | spin_lock(&tty_files_lock); |
239 | list_for_each(p, &tty->tty_files) { | 277 | list_for_each(p, &tty->tty_files) { |
240 | count++; | 278 | count++; |
241 | } | 279 | } |
242 | file_list_unlock(); | 280 | spin_unlock(&tty_files_lock); |
243 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 281 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
244 | tty->driver->subtype == PTY_TYPE_SLAVE && | 282 | tty->driver->subtype == PTY_TYPE_SLAVE && |
245 | tty->link && tty->link->count) | 283 | tty->link && tty->link->count) |
@@ -497,6 +535,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
497 | struct file *cons_filp = NULL; | 535 | struct file *cons_filp = NULL; |
498 | struct file *filp, *f = NULL; | 536 | struct file *filp, *f = NULL; |
499 | struct task_struct *p; | 537 | struct task_struct *p; |
538 | struct tty_file_private *priv; | ||
500 | int closecount = 0, n; | 539 | int closecount = 0, n; |
501 | unsigned long flags; | 540 | unsigned long flags; |
502 | int refs = 0; | 541 | int refs = 0; |
@@ -506,7 +545,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
506 | 545 | ||
507 | 546 | ||
508 | spin_lock(&redirect_lock); | 547 | spin_lock(&redirect_lock); |
509 | if (redirect && redirect->private_data == tty) { | 548 | if (redirect && file_tty(redirect) == tty) { |
510 | f = redirect; | 549 | f = redirect; |
511 | redirect = NULL; | 550 | redirect = NULL; |
512 | } | 551 | } |
@@ -519,9 +558,10 @@ void __tty_hangup(struct tty_struct *tty) | |||
519 | workqueue with the lock held */ | 558 | workqueue with the lock held */ |
520 | check_tty_count(tty, "tty_hangup"); | 559 | check_tty_count(tty, "tty_hangup"); |
521 | 560 | ||
522 | file_list_lock(); | 561 | spin_lock(&tty_files_lock); |
523 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ | 562 | /* This breaks for file handles being sent over AF_UNIX sockets ? */ |
524 | list_for_each_entry(filp, &tty->tty_files, f_u.fu_list) { | 563 | list_for_each_entry(priv, &tty->tty_files, list) { |
564 | filp = priv->file; | ||
525 | if (filp->f_op->write == redirected_tty_write) | 565 | if (filp->f_op->write == redirected_tty_write) |
526 | cons_filp = filp; | 566 | cons_filp = filp; |
527 | if (filp->f_op->write != tty_write) | 567 | if (filp->f_op->write != tty_write) |
@@ -530,7 +570,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
530 | __tty_fasync(-1, filp, 0); /* can't block */ | 570 | __tty_fasync(-1, filp, 0); /* can't block */ |
531 | filp->f_op = &hung_up_tty_fops; | 571 | filp->f_op = &hung_up_tty_fops; |
532 | } | 572 | } |
533 | file_list_unlock(); | 573 | spin_unlock(&tty_files_lock); |
534 | 574 | ||
535 | tty_ldisc_hangup(tty); | 575 | tty_ldisc_hangup(tty); |
536 | 576 | ||
@@ -889,12 +929,10 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count, | |||
889 | loff_t *ppos) | 929 | loff_t *ppos) |
890 | { | 930 | { |
891 | int i; | 931 | int i; |
892 | struct tty_struct *tty; | 932 | struct inode *inode = file->f_path.dentry->d_inode; |
893 | struct inode *inode; | 933 | struct tty_struct *tty = file_tty(file); |
894 | struct tty_ldisc *ld; | 934 | struct tty_ldisc *ld; |
895 | 935 | ||
896 | tty = file->private_data; | ||
897 | inode = file->f_path.dentry->d_inode; | ||
898 | if (tty_paranoia_check(tty, inode, "tty_read")) | 936 | if (tty_paranoia_check(tty, inode, "tty_read")) |
899 | return -EIO; | 937 | return -EIO; |
900 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) | 938 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) |
@@ -1065,12 +1103,11 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1065 | static ssize_t tty_write(struct file *file, const char __user *buf, | 1103 | static ssize_t tty_write(struct file *file, const char __user *buf, |
1066 | size_t count, loff_t *ppos) | 1104 | size_t count, loff_t *ppos) |
1067 | { | 1105 | { |
1068 | struct tty_struct *tty; | ||
1069 | struct inode *inode = file->f_path.dentry->d_inode; | 1106 | struct inode *inode = file->f_path.dentry->d_inode; |
1107 | struct tty_struct *tty = file_tty(file); | ||
1108 | struct tty_ldisc *ld; | ||
1070 | ssize_t ret; | 1109 | ssize_t ret; |
1071 | struct tty_ldisc *ld; | ||
1072 | 1110 | ||
1073 | tty = file->private_data; | ||
1074 | if (tty_paranoia_check(tty, inode, "tty_write")) | 1111 | if (tty_paranoia_check(tty, inode, "tty_write")) |
1075 | return -EIO; | 1112 | return -EIO; |
1076 | if (!tty || !tty->ops->write || | 1113 | if (!tty || !tty->ops->write || |
@@ -1424,9 +1461,9 @@ static void release_one_tty(struct work_struct *work) | |||
1424 | tty_driver_kref_put(driver); | 1461 | tty_driver_kref_put(driver); |
1425 | module_put(driver->owner); | 1462 | module_put(driver->owner); |
1426 | 1463 | ||
1427 | file_list_lock(); | 1464 | spin_lock(&tty_files_lock); |
1428 | list_del_init(&tty->tty_files); | 1465 | list_del_init(&tty->tty_files); |
1429 | file_list_unlock(); | 1466 | spin_unlock(&tty_files_lock); |
1430 | 1467 | ||
1431 | put_pid(tty->pgrp); | 1468 | put_pid(tty->pgrp); |
1432 | put_pid(tty->session); | 1469 | put_pid(tty->session); |
@@ -1507,13 +1544,13 @@ static void release_tty(struct tty_struct *tty, int idx) | |||
1507 | 1544 | ||
1508 | int tty_release(struct inode *inode, struct file *filp) | 1545 | int tty_release(struct inode *inode, struct file *filp) |
1509 | { | 1546 | { |
1510 | struct tty_struct *tty, *o_tty; | 1547 | struct tty_struct *tty = file_tty(filp); |
1548 | struct tty_struct *o_tty; | ||
1511 | int pty_master, tty_closing, o_tty_closing, do_sleep; | 1549 | int pty_master, tty_closing, o_tty_closing, do_sleep; |
1512 | int devpts; | 1550 | int devpts; |
1513 | int idx; | 1551 | int idx; |
1514 | char buf[64]; | 1552 | char buf[64]; |
1515 | 1553 | ||
1516 | tty = filp->private_data; | ||
1517 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) | 1554 | if (tty_paranoia_check(tty, inode, "tty_release_dev")) |
1518 | return 0; | 1555 | return 0; |
1519 | 1556 | ||
@@ -1671,8 +1708,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1671 | * - do_tty_hangup no longer sees this file descriptor as | 1708 | * - do_tty_hangup no longer sees this file descriptor as |
1672 | * something that needs to be handled for hangups. | 1709 | * something that needs to be handled for hangups. |
1673 | */ | 1710 | */ |
1674 | file_kill(filp); | 1711 | tty_del_file(filp); |
1675 | filp->private_data = NULL; | ||
1676 | 1712 | ||
1677 | /* | 1713 | /* |
1678 | * Perform some housekeeping before deciding whether to return. | 1714 | * Perform some housekeeping before deciding whether to return. |
@@ -1839,8 +1875,8 @@ got_driver: | |||
1839 | return PTR_ERR(tty); | 1875 | return PTR_ERR(tty); |
1840 | } | 1876 | } |
1841 | 1877 | ||
1842 | filp->private_data = tty; | 1878 | tty_add_file(tty, filp); |
1843 | file_move(filp, &tty->tty_files); | 1879 | |
1844 | check_tty_count(tty, "tty_open"); | 1880 | check_tty_count(tty, "tty_open"); |
1845 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1881 | if (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1846 | tty->driver->subtype == PTY_TYPE_MASTER) | 1882 | tty->driver->subtype == PTY_TYPE_MASTER) |
@@ -1916,11 +1952,10 @@ got_driver: | |||
1916 | 1952 | ||
1917 | static unsigned int tty_poll(struct file *filp, poll_table *wait) | 1953 | static unsigned int tty_poll(struct file *filp, poll_table *wait) |
1918 | { | 1954 | { |
1919 | struct tty_struct *tty; | 1955 | struct tty_struct *tty = file_tty(filp); |
1920 | struct tty_ldisc *ld; | 1956 | struct tty_ldisc *ld; |
1921 | int ret = 0; | 1957 | int ret = 0; |
1922 | 1958 | ||
1923 | tty = filp->private_data; | ||
1924 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) | 1959 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) |
1925 | return 0; | 1960 | return 0; |
1926 | 1961 | ||
@@ -1933,11 +1968,10 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait) | |||
1933 | 1968 | ||
1934 | static int __tty_fasync(int fd, struct file *filp, int on) | 1969 | static int __tty_fasync(int fd, struct file *filp, int on) |
1935 | { | 1970 | { |
1936 | struct tty_struct *tty; | 1971 | struct tty_struct *tty = file_tty(filp); |
1937 | unsigned long flags; | 1972 | unsigned long flags; |
1938 | int retval = 0; | 1973 | int retval = 0; |
1939 | 1974 | ||
1940 | tty = filp->private_data; | ||
1941 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) | 1975 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
1942 | goto out; | 1976 | goto out; |
1943 | 1977 | ||
@@ -2491,13 +2525,13 @@ EXPORT_SYMBOL(tty_pair_get_pty); | |||
2491 | */ | 2525 | */ |
2492 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 2526 | long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
2493 | { | 2527 | { |
2494 | struct tty_struct *tty, *real_tty; | 2528 | struct tty_struct *tty = file_tty(file); |
2529 | struct tty_struct *real_tty; | ||
2495 | void __user *p = (void __user *)arg; | 2530 | void __user *p = (void __user *)arg; |
2496 | int retval; | 2531 | int retval; |
2497 | struct tty_ldisc *ld; | 2532 | struct tty_ldisc *ld; |
2498 | struct inode *inode = file->f_dentry->d_inode; | 2533 | struct inode *inode = file->f_dentry->d_inode; |
2499 | 2534 | ||
2500 | tty = file->private_data; | ||
2501 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) | 2535 | if (tty_paranoia_check(tty, inode, "tty_ioctl")) |
2502 | return -EINVAL; | 2536 | return -EINVAL; |
2503 | 2537 | ||
@@ -2619,7 +2653,7 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd, | |||
2619 | unsigned long arg) | 2653 | unsigned long arg) |
2620 | { | 2654 | { |
2621 | struct inode *inode = file->f_dentry->d_inode; | 2655 | struct inode *inode = file->f_dentry->d_inode; |
2622 | struct tty_struct *tty = file->private_data; | 2656 | struct tty_struct *tty = file_tty(file); |
2623 | struct tty_ldisc *ld; | 2657 | struct tty_ldisc *ld; |
2624 | int retval = -ENOIOCTLCMD; | 2658 | int retval = -ENOIOCTLCMD; |
2625 | 2659 | ||
@@ -2711,7 +2745,7 @@ void __do_SAK(struct tty_struct *tty) | |||
2711 | if (!filp) | 2745 | if (!filp) |
2712 | continue; | 2746 | continue; |
2713 | if (filp->f_op->read == tty_read && | 2747 | if (filp->f_op->read == tty_read && |
2714 | filp->private_data == tty) { | 2748 | file_tty(filp) == tty) { |
2715 | printk(KERN_NOTICE "SAK: killed process %d" | 2749 | printk(KERN_NOTICE "SAK: killed process %d" |
2716 | " (%s): fd#%d opened to the tty\n", | 2750 | " (%s): fd#%d opened to the tty\n", |
2717 | task_pid_nr(p), p->comm, i); | 2751 | task_pid_nr(p), p->comm, i); |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index c734f9b1263a..50590c7f2c01 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -194,10 +194,11 @@ static DECLARE_WORK(console_work, console_callback); | |||
194 | int fg_console; | 194 | int fg_console; |
195 | int last_console; | 195 | int last_console; |
196 | int want_console = -1; | 196 | int want_console = -1; |
197 | int saved_fg_console; | 197 | static int saved_fg_console; |
198 | int saved_last_console; | 198 | static int saved_last_console; |
199 | int saved_want_console; | 199 | static int saved_want_console; |
200 | int saved_vc_mode; | 200 | static int saved_vc_mode; |
201 | static int saved_console_blanked; | ||
201 | 202 | ||
202 | /* | 203 | /* |
203 | * For each existing display, we have a pointer to console currently visible | 204 | * For each existing display, we have a pointer to console currently visible |
@@ -3449,6 +3450,7 @@ int con_debug_enter(struct vc_data *vc) | |||
3449 | saved_last_console = last_console; | 3450 | saved_last_console = last_console; |
3450 | saved_want_console = want_console; | 3451 | saved_want_console = want_console; |
3451 | saved_vc_mode = vc->vc_mode; | 3452 | saved_vc_mode = vc->vc_mode; |
3453 | saved_console_blanked = console_blanked; | ||
3452 | vc->vc_mode = KD_TEXT; | 3454 | vc->vc_mode = KD_TEXT; |
3453 | console_blanked = 0; | 3455 | console_blanked = 0; |
3454 | if (vc->vc_sw->con_debug_enter) | 3456 | if (vc->vc_sw->con_debug_enter) |
@@ -3492,6 +3494,7 @@ int con_debug_leave(void) | |||
3492 | fg_console = saved_fg_console; | 3494 | fg_console = saved_fg_console; |
3493 | last_console = saved_last_console; | 3495 | last_console = saved_last_console; |
3494 | want_console = saved_want_console; | 3496 | want_console = saved_want_console; |
3497 | console_blanked = saved_console_blanked; | ||
3495 | vc_cons[fg_console].d->vc_mode = saved_vc_mode; | 3498 | vc_cons[fg_console].d->vc_mode = saved_vc_mode; |
3496 | 3499 | ||
3497 | vc = vc_cons[fg_console].d; | 3500 | vc = vc_cons[fg_console].d; |
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 0ed763cd2e77..b663d573aad9 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c | |||
@@ -94,6 +94,7 @@ | |||
94 | 94 | ||
95 | #ifdef CONFIG_OF | 95 | #ifdef CONFIG_OF |
96 | /* For open firmware. */ | 96 | /* For open firmware. */ |
97 | #include <linux/of_address.h> | ||
97 | #include <linux/of_device.h> | 98 | #include <linux/of_device.h> |
98 | #include <linux/of_platform.h> | 99 | #include <linux/of_platform.h> |
99 | #endif | 100 | #endif |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 670239ab7511..e7d5d6b5dcf6 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -2071,16 +2071,6 @@ static inline void __amd64_decode_bus_error(struct mem_ctl_info *mci, | |||
2071 | amd64_handle_ce(mci, info); | 2071 | amd64_handle_ce(mci, info); |
2072 | else if (ecc_type == 1) | 2072 | else if (ecc_type == 1) |
2073 | amd64_handle_ue(mci, info); | 2073 | amd64_handle_ue(mci, info); |
2074 | |||
2075 | /* | ||
2076 | * If main error is CE then overflow must be CE. If main error is UE | ||
2077 | * then overflow is unknown. We'll call the overflow a CE - if | ||
2078 | * panic_on_ue is set then we're already panic'ed and won't arrive | ||
2079 | * here. Else, then apparently someone doesn't think that UE's are | ||
2080 | * catastrophic. | ||
2081 | */ | ||
2082 | if (info->nbsh & K8_NBSH_OVERFLOW) | ||
2083 | edac_mc_handle_ce_no_info(mci, EDAC_MOD_STR " Error Overflow"); | ||
2084 | } | 2074 | } |
2085 | 2075 | ||
2086 | void amd64_decode_bus_error(int node_id, struct err_regs *regs) | 2076 | void amd64_decode_bus_error(int node_id, struct err_regs *regs) |
diff --git a/drivers/edac/edac_mce_amd.c b/drivers/edac/edac_mce_amd.c index bae9351e9473..9014df6f605d 100644 --- a/drivers/edac/edac_mce_amd.c +++ b/drivers/edac/edac_mce_amd.c | |||
@@ -365,11 +365,10 @@ static int amd_decode_mce(struct notifier_block *nb, unsigned long val, | |||
365 | 365 | ||
366 | pr_emerg("MC%d_STATUS: ", m->bank); | 366 | pr_emerg("MC%d_STATUS: ", m->bank); |
367 | 367 | ||
368 | pr_cont("%sorrected error, report: %s, MiscV: %svalid, " | 368 | pr_cont("%sorrected error, other errors lost: %s, " |
369 | "CPU context corrupt: %s", | 369 | "CPU context corrupt: %s", |
370 | ((m->status & MCI_STATUS_UC) ? "Unc" : "C"), | 370 | ((m->status & MCI_STATUS_UC) ? "Unc" : "C"), |
371 | ((m->status & MCI_STATUS_EN) ? "yes" : "no"), | 371 | ((m->status & MCI_STATUS_OVER) ? "yes" : "no"), |
372 | ((m->status & MCI_STATUS_MISCV) ? "" : "in"), | ||
373 | ((m->status & MCI_STATUS_PCC) ? "yes" : "no")); | 372 | ((m->status & MCI_STATUS_PCC) ? "yes" : "no")); |
374 | 373 | ||
375 | /* do the two bits[14:13] together */ | 374 | /* do the two bits[14:13] together */ |
@@ -426,11 +425,15 @@ static struct notifier_block amd_mce_dec_nb = { | |||
426 | static int __init mce_amd_init(void) | 425 | static int __init mce_amd_init(void) |
427 | { | 426 | { |
428 | /* | 427 | /* |
429 | * We can decode MCEs for Opteron and later CPUs: | 428 | * We can decode MCEs for K8, F10h and F11h CPUs: |
430 | */ | 429 | */ |
431 | if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && | 430 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
432 | (boot_cpu_data.x86 >= 0xf)) | 431 | return 0; |
433 | atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb); | 432 | |
433 | if (boot_cpu_data.x86 < 0xf || boot_cpu_data.x86 > 0x11) | ||
434 | return 0; | ||
435 | |||
436 | atomic_notifier_chain_register(&x86_mce_decoder_chain, &amd_mce_dec_nb); | ||
434 | 437 | ||
435 | return 0; | 438 | return 0; |
436 | } | 439 | } |
diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index ca7ca56661e0..b42a0bde8494 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c | |||
@@ -81,6 +81,10 @@ static int close_transaction(struct fw_transaction *transaction, | |||
81 | spin_lock_irqsave(&card->lock, flags); | 81 | spin_lock_irqsave(&card->lock, flags); |
82 | list_for_each_entry(t, &card->transaction_list, link) { | 82 | list_for_each_entry(t, &card->transaction_list, link) { |
83 | if (t == transaction) { | 83 | if (t == transaction) { |
84 | if (!del_timer(&t->split_timeout_timer)) { | ||
85 | spin_unlock_irqrestore(&card->lock, flags); | ||
86 | goto timed_out; | ||
87 | } | ||
84 | list_del_init(&t->link); | 88 | list_del_init(&t->link); |
85 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 89 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
86 | break; | 90 | break; |
@@ -89,11 +93,11 @@ static int close_transaction(struct fw_transaction *transaction, | |||
89 | spin_unlock_irqrestore(&card->lock, flags); | 93 | spin_unlock_irqrestore(&card->lock, flags); |
90 | 94 | ||
91 | if (&t->link != &card->transaction_list) { | 95 | if (&t->link != &card->transaction_list) { |
92 | del_timer_sync(&t->split_timeout_timer); | ||
93 | t->callback(card, rcode, NULL, 0, t->callback_data); | 96 | t->callback(card, rcode, NULL, 0, t->callback_data); |
94 | return 0; | 97 | return 0; |
95 | } | 98 | } |
96 | 99 | ||
100 | timed_out: | ||
97 | return -ENOENT; | 101 | return -ENOENT; |
98 | } | 102 | } |
99 | 103 | ||
@@ -921,6 +925,10 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
921 | spin_lock_irqsave(&card->lock, flags); | 925 | spin_lock_irqsave(&card->lock, flags); |
922 | list_for_each_entry(t, &card->transaction_list, link) { | 926 | list_for_each_entry(t, &card->transaction_list, link) { |
923 | if (t->node_id == source && t->tlabel == tlabel) { | 927 | if (t->node_id == source && t->tlabel == tlabel) { |
928 | if (!del_timer(&t->split_timeout_timer)) { | ||
929 | spin_unlock_irqrestore(&card->lock, flags); | ||
930 | goto timed_out; | ||
931 | } | ||
924 | list_del_init(&t->link); | 932 | list_del_init(&t->link); |
925 | card->tlabel_mask &= ~(1ULL << t->tlabel); | 933 | card->tlabel_mask &= ~(1ULL << t->tlabel); |
926 | break; | 934 | break; |
@@ -929,6 +937,7 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
929 | spin_unlock_irqrestore(&card->lock, flags); | 937 | spin_unlock_irqrestore(&card->lock, flags); |
930 | 938 | ||
931 | if (&t->link == &card->transaction_list) { | 939 | if (&t->link == &card->transaction_list) { |
940 | timed_out: | ||
932 | fw_notify("Unsolicited response (source %x, tlabel %x)\n", | 941 | fw_notify("Unsolicited response (source %x, tlabel %x)\n", |
933 | source, tlabel); | 942 | source, tlabel); |
934 | return; | 943 | return; |
@@ -963,8 +972,6 @@ void fw_core_handle_response(struct fw_card *card, struct fw_packet *p) | |||
963 | break; | 972 | break; |
964 | } | 973 | } |
965 | 974 | ||
966 | del_timer_sync(&t->split_timeout_timer); | ||
967 | |||
968 | /* | 975 | /* |
969 | * The response handler may be executed while the request handler | 976 | * The response handler may be executed while the request handler |
970 | * is still pending. Cancel the request handler. | 977 | * is still pending. Cancel the request handler. |
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index da17d409a244..33f8421c71cc 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c | |||
@@ -579,7 +579,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
579 | if (!peer) { | 579 | if (!peer) { |
580 | fw_notify("No peer for ARP packet from %016llx\n", | 580 | fw_notify("No peer for ARP packet from %016llx\n", |
581 | (unsigned long long)peer_guid); | 581 | (unsigned long long)peer_guid); |
582 | goto failed_proto; | 582 | goto no_peer; |
583 | } | 583 | } |
584 | 584 | ||
585 | /* | 585 | /* |
@@ -656,7 +656,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
656 | 656 | ||
657 | return 0; | 657 | return 0; |
658 | 658 | ||
659 | failed_proto: | 659 | no_peer: |
660 | net->stats.rx_errors++; | 660 | net->stats.rx_errors++; |
661 | net->stats.rx_dropped++; | 661 | net->stats.rx_dropped++; |
662 | 662 | ||
@@ -664,7 +664,7 @@ static int fwnet_finish_incoming_packet(struct net_device *net, | |||
664 | if (netif_queue_stopped(net)) | 664 | if (netif_queue_stopped(net)) |
665 | netif_wake_queue(net); | 665 | netif_wake_queue(net); |
666 | 666 | ||
667 | return 0; | 667 | return -ENOENT; |
668 | } | 668 | } |
669 | 669 | ||
670 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | 670 | static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, |
@@ -701,7 +701,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
701 | fw_error("out of memory\n"); | 701 | fw_error("out of memory\n"); |
702 | net->stats.rx_dropped++; | 702 | net->stats.rx_dropped++; |
703 | 703 | ||
704 | return -1; | 704 | return -ENOMEM; |
705 | } | 705 | } |
706 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); | 706 | skb_reserve(skb, (net->hard_header_len + 15) & ~15); |
707 | memcpy(skb_put(skb, len), buf, len); | 707 | memcpy(skb_put(skb, len), buf, len); |
@@ -726,8 +726,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
726 | spin_lock_irqsave(&dev->lock, flags); | 726 | spin_lock_irqsave(&dev->lock, flags); |
727 | 727 | ||
728 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); | 728 | peer = fwnet_peer_find_by_node_id(dev, source_node_id, generation); |
729 | if (!peer) | 729 | if (!peer) { |
730 | goto bad_proto; | 730 | retval = -ENOENT; |
731 | goto fail; | ||
732 | } | ||
731 | 733 | ||
732 | pd = fwnet_pd_find(peer, datagram_label); | 734 | pd = fwnet_pd_find(peer, datagram_label); |
733 | if (pd == NULL) { | 735 | if (pd == NULL) { |
@@ -741,7 +743,7 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
741 | dg_size, buf, fg_off, len); | 743 | dg_size, buf, fg_off, len); |
742 | if (pd == NULL) { | 744 | if (pd == NULL) { |
743 | retval = -ENOMEM; | 745 | retval = -ENOMEM; |
744 | goto bad_proto; | 746 | goto fail; |
745 | } | 747 | } |
746 | peer->pdg_size++; | 748 | peer->pdg_size++; |
747 | } else { | 749 | } else { |
@@ -755,9 +757,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
755 | pd = fwnet_pd_new(net, peer, datagram_label, | 757 | pd = fwnet_pd_new(net, peer, datagram_label, |
756 | dg_size, buf, fg_off, len); | 758 | dg_size, buf, fg_off, len); |
757 | if (pd == NULL) { | 759 | if (pd == NULL) { |
758 | retval = -ENOMEM; | ||
759 | peer->pdg_size--; | 760 | peer->pdg_size--; |
760 | goto bad_proto; | 761 | retval = -ENOMEM; |
762 | goto fail; | ||
761 | } | 763 | } |
762 | } else { | 764 | } else { |
763 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { | 765 | if (!fwnet_pd_update(peer, pd, buf, fg_off, len)) { |
@@ -768,7 +770,8 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
768 | */ | 770 | */ |
769 | fwnet_pd_delete(pd); | 771 | fwnet_pd_delete(pd); |
770 | peer->pdg_size--; | 772 | peer->pdg_size--; |
771 | goto bad_proto; | 773 | retval = -ENOMEM; |
774 | goto fail; | ||
772 | } | 775 | } |
773 | } | 776 | } |
774 | } /* new datagram or add to existing one */ | 777 | } /* new datagram or add to existing one */ |
@@ -794,14 +797,13 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len, | |||
794 | spin_unlock_irqrestore(&dev->lock, flags); | 797 | spin_unlock_irqrestore(&dev->lock, flags); |
795 | 798 | ||
796 | return 0; | 799 | return 0; |
797 | 800 | fail: | |
798 | bad_proto: | ||
799 | spin_unlock_irqrestore(&dev->lock, flags); | 801 | spin_unlock_irqrestore(&dev->lock, flags); |
800 | 802 | ||
801 | if (netif_queue_stopped(net)) | 803 | if (netif_queue_stopped(net)) |
802 | netif_wake_queue(net); | 804 | netif_wake_queue(net); |
803 | 805 | ||
804 | return 0; | 806 | return retval; |
805 | } | 807 | } |
806 | 808 | ||
807 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, | 809 | static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 7f03540cabe8..be29b0bb2471 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -694,7 +694,15 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) | |||
694 | log_ar_at_event('R', p.speed, p.header, evt); | 694 | log_ar_at_event('R', p.speed, p.header, evt); |
695 | 695 | ||
696 | /* | 696 | /* |
697 | * The OHCI bus reset handler synthesizes a phy packet with | 697 | * Several controllers, notably from NEC and VIA, forget to |
698 | * write ack_complete status at PHY packet reception. | ||
699 | */ | ||
700 | if (evt == OHCI1394_evt_no_status && | ||
701 | (p.header[0] & 0xff) == (OHCI1394_phy_tcode << 4)) | ||
702 | p.ack = ACK_COMPLETE; | ||
703 | |||
704 | /* | ||
705 | * The OHCI bus reset handler synthesizes a PHY packet with | ||
698 | * the new generation number when a bus reset happens (see | 706 | * the new generation number when a bus reset happens (see |
699 | * section 8.4.2.3). This helps us determine when a request | 707 | * section 8.4.2.3). This helps us determine when a request |
700 | * was received and make sure we send the response in the same | 708 | * was received and make sure we send the response in the same |
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 9f76171717e5..bfae4b309791 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c | |||
@@ -450,7 +450,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, | |||
450 | 450 | ||
451 | if (&orb->link != &lu->orb_list) { | 451 | if (&orb->link != &lu->orb_list) { |
452 | orb->callback(orb, &status); | 452 | orb->callback(orb, &status); |
453 | kref_put(&orb->kref, free_orb); | 453 | kref_put(&orb->kref, free_orb); /* orb callback reference */ |
454 | } else { | 454 | } else { |
455 | fw_error("status write for unknown orb\n"); | 455 | fw_error("status write for unknown orb\n"); |
456 | } | 456 | } |
@@ -472,20 +472,28 @@ static void complete_transaction(struct fw_card *card, int rcode, | |||
472 | * So this callback only sets the rcode if it hasn't already | 472 | * So this callback only sets the rcode if it hasn't already |
473 | * been set and only does the cleanup if the transaction | 473 | * been set and only does the cleanup if the transaction |
474 | * failed and we didn't already get a status write. | 474 | * failed and we didn't already get a status write. |
475 | * | ||
476 | * Here we treat RCODE_CANCELLED like RCODE_COMPLETE because some | ||
477 | * OXUF936QSE firmwares occasionally respond after Split_Timeout and | ||
478 | * complete the ORB just fine. Note, we also get RCODE_CANCELLED | ||
479 | * from sbp2_cancel_orbs() if fw_cancel_transaction() == 0. | ||
475 | */ | 480 | */ |
476 | spin_lock_irqsave(&card->lock, flags); | 481 | spin_lock_irqsave(&card->lock, flags); |
477 | 482 | ||
478 | if (orb->rcode == -1) | 483 | if (orb->rcode == -1) |
479 | orb->rcode = rcode; | 484 | orb->rcode = rcode; |
480 | if (orb->rcode != RCODE_COMPLETE) { | 485 | |
486 | if (orb->rcode != RCODE_COMPLETE && orb->rcode != RCODE_CANCELLED) { | ||
481 | list_del(&orb->link); | 487 | list_del(&orb->link); |
482 | spin_unlock_irqrestore(&card->lock, flags); | 488 | spin_unlock_irqrestore(&card->lock, flags); |
489 | |||
483 | orb->callback(orb, NULL); | 490 | orb->callback(orb, NULL); |
491 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | ||
484 | } else { | 492 | } else { |
485 | spin_unlock_irqrestore(&card->lock, flags); | 493 | spin_unlock_irqrestore(&card->lock, flags); |
486 | } | 494 | } |
487 | 495 | ||
488 | kref_put(&orb->kref, free_orb); | 496 | kref_put(&orb->kref, free_orb); /* transaction callback reference */ |
489 | } | 497 | } |
490 | 498 | ||
491 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | 499 | static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, |
@@ -501,9 +509,8 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | |||
501 | list_add_tail(&orb->link, &lu->orb_list); | 509 | list_add_tail(&orb->link, &lu->orb_list); |
502 | spin_unlock_irqrestore(&device->card->lock, flags); | 510 | spin_unlock_irqrestore(&device->card->lock, flags); |
503 | 511 | ||
504 | /* Take a ref for the orb list and for the transaction callback. */ | 512 | kref_get(&orb->kref); /* transaction callback reference */ |
505 | kref_get(&orb->kref); | 513 | kref_get(&orb->kref); /* orb callback reference */ |
506 | kref_get(&orb->kref); | ||
507 | 514 | ||
508 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, | 515 | fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, |
509 | node_id, generation, device->max_speed, offset, | 516 | node_id, generation, device->max_speed, offset, |
@@ -525,11 +532,11 @@ static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) | |||
525 | 532 | ||
526 | list_for_each_entry_safe(orb, next, &list, link) { | 533 | list_for_each_entry_safe(orb, next, &list, link) { |
527 | retval = 0; | 534 | retval = 0; |
528 | if (fw_cancel_transaction(device->card, &orb->t) == 0) | 535 | fw_cancel_transaction(device->card, &orb->t); |
529 | continue; | ||
530 | 536 | ||
531 | orb->rcode = RCODE_CANCELLED; | 537 | orb->rcode = RCODE_CANCELLED; |
532 | orb->callback(orb, NULL); | 538 | orb->callback(orb, NULL); |
539 | kref_put(&orb->kref, free_orb); /* orb callback reference */ | ||
533 | } | 540 | } |
534 | 541 | ||
535 | return retval; | 542 | return retval; |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 90288ec7c284..84da748555bc 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -55,6 +55,9 @@ | |||
55 | static int drm_version(struct drm_device *dev, void *data, | 55 | static int drm_version(struct drm_device *dev, void *data, |
56 | struct drm_file *file_priv); | 56 | struct drm_file *file_priv); |
57 | 57 | ||
58 | #define DRM_IOCTL_DEF(ioctl, _func, _flags) \ | ||
59 | [DRM_IOCTL_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0} | ||
60 | |||
58 | /** Ioctl table */ | 61 | /** Ioctl table */ |
59 | static struct drm_ioctl_desc drm_ioctls[] = { | 62 | static struct drm_ioctl_desc drm_ioctls[] = { |
60 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), | 63 | DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0), |
@@ -421,6 +424,7 @@ long drm_ioctl(struct file *filp, | |||
421 | int retcode = -EINVAL; | 424 | int retcode = -EINVAL; |
422 | char stack_kdata[128]; | 425 | char stack_kdata[128]; |
423 | char *kdata = NULL; | 426 | char *kdata = NULL; |
427 | unsigned int usize, asize; | ||
424 | 428 | ||
425 | dev = file_priv->minor->dev; | 429 | dev = file_priv->minor->dev; |
426 | atomic_inc(&dev->ioctl_count); | 430 | atomic_inc(&dev->ioctl_count); |
@@ -436,11 +440,18 @@ long drm_ioctl(struct file *filp, | |||
436 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) | 440 | ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END))) |
437 | goto err_i1; | 441 | goto err_i1; |
438 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && | 442 | if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) && |
439 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) | 443 | (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { |
444 | u32 drv_size; | ||
440 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; | 445 | ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE]; |
446 | drv_size = _IOC_SIZE(ioctl->cmd_drv); | ||
447 | usize = asize = _IOC_SIZE(cmd); | ||
448 | if (drv_size > asize) | ||
449 | asize = drv_size; | ||
450 | } | ||
441 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { | 451 | else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE)) { |
442 | ioctl = &drm_ioctls[nr]; | 452 | ioctl = &drm_ioctls[nr]; |
443 | cmd = ioctl->cmd; | 453 | cmd = ioctl->cmd; |
454 | usize = asize = _IOC_SIZE(cmd); | ||
444 | } else | 455 | } else |
445 | goto err_i1; | 456 | goto err_i1; |
446 | 457 | ||
@@ -460,10 +471,10 @@ long drm_ioctl(struct file *filp, | |||
460 | retcode = -EACCES; | 471 | retcode = -EACCES; |
461 | } else { | 472 | } else { |
462 | if (cmd & (IOC_IN | IOC_OUT)) { | 473 | if (cmd & (IOC_IN | IOC_OUT)) { |
463 | if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) { | 474 | if (asize <= sizeof(stack_kdata)) { |
464 | kdata = stack_kdata; | 475 | kdata = stack_kdata; |
465 | } else { | 476 | } else { |
466 | kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL); | 477 | kdata = kmalloc(asize, GFP_KERNEL); |
467 | if (!kdata) { | 478 | if (!kdata) { |
468 | retcode = -ENOMEM; | 479 | retcode = -ENOMEM; |
469 | goto err_i1; | 480 | goto err_i1; |
@@ -473,11 +484,13 @@ long drm_ioctl(struct file *filp, | |||
473 | 484 | ||
474 | if (cmd & IOC_IN) { | 485 | if (cmd & IOC_IN) { |
475 | if (copy_from_user(kdata, (void __user *)arg, | 486 | if (copy_from_user(kdata, (void __user *)arg, |
476 | _IOC_SIZE(cmd)) != 0) { | 487 | usize) != 0) { |
477 | retcode = -EFAULT; | 488 | retcode = -EFAULT; |
478 | goto err_i1; | 489 | goto err_i1; |
479 | } | 490 | } |
480 | } | 491 | } else |
492 | memset(kdata, 0, usize); | ||
493 | |||
481 | if (ioctl->flags & DRM_UNLOCKED) | 494 | if (ioctl->flags & DRM_UNLOCKED) |
482 | retcode = func(dev, kdata, file_priv); | 495 | retcode = func(dev, kdata, file_priv); |
483 | else { | 496 | else { |
@@ -488,7 +501,7 @@ long drm_ioctl(struct file *filp, | |||
488 | 501 | ||
489 | if (cmd & IOC_OUT) { | 502 | if (cmd & IOC_OUT) { |
490 | if (copy_to_user((void __user *)arg, kdata, | 503 | if (copy_to_user((void __user *)arg, kdata, |
491 | _IOC_SIZE(cmd)) != 0) | 504 | usize) != 0) |
492 | retcode = -EFAULT; | 505 | retcode = -EFAULT; |
493 | } | 506 | } |
494 | } | 507 | } |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index de82e201d682..6a5e403f9aa1 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -94,10 +94,11 @@ static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_conn | |||
94 | int i; | 94 | int i; |
95 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; | 95 | enum drm_connector_force force = DRM_FORCE_UNSPECIFIED; |
96 | struct drm_fb_helper_cmdline_mode *cmdline_mode; | 96 | struct drm_fb_helper_cmdline_mode *cmdline_mode; |
97 | struct drm_connector *connector = fb_helper_conn->connector; | 97 | struct drm_connector *connector; |
98 | 98 | ||
99 | if (!fb_helper_conn) | 99 | if (!fb_helper_conn) |
100 | return false; | 100 | return false; |
101 | connector = fb_helper_conn->connector; | ||
101 | 102 | ||
102 | cmdline_mode = &fb_helper_conn->cmdline_mode; | 103 | cmdline_mode = &fb_helper_conn->cmdline_mode; |
103 | if (!mode_option) | 104 | if (!mode_option) |
@@ -369,7 +370,7 @@ static void drm_fb_helper_restore_work_fn(struct work_struct *ignored) | |||
369 | } | 370 | } |
370 | static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); | 371 | static DECLARE_WORK(drm_fb_helper_restore_work, drm_fb_helper_restore_work_fn); |
371 | 372 | ||
372 | static void drm_fb_helper_sysrq(int dummy1, struct tty_struct *dummy3) | 373 | static void drm_fb_helper_sysrq(int dummy1) |
373 | { | 374 | { |
374 | schedule_work(&drm_fb_helper_restore_work); | 375 | schedule_work(&drm_fb_helper_restore_work); |
375 | } | 376 | } |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 3a652a65546f..b744dad5c237 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
@@ -41,6 +41,7 @@ | |||
41 | 41 | ||
42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ | 42 | /* from BKL pushdown: note that nothing else serializes idr_find() */ |
43 | DEFINE_MUTEX(drm_global_mutex); | 43 | DEFINE_MUTEX(drm_global_mutex); |
44 | EXPORT_SYMBOL(drm_global_mutex); | ||
44 | 45 | ||
45 | static int drm_open_helper(struct inode *inode, struct file *filp, | 46 | static int drm_open_helper(struct inode *inode, struct file *filp, |
46 | struct drm_device * dev); | 47 | struct drm_device * dev); |
diff --git a/drivers/gpu/drm/drm_lock.c b/drivers/gpu/drm/drm_lock.c index e2f70a516c34..9bf93bc9a32c 100644 --- a/drivers/gpu/drm/drm_lock.c +++ b/drivers/gpu/drm/drm_lock.c | |||
@@ -92,7 +92,9 @@ int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /* Contention */ | 94 | /* Contention */ |
95 | mutex_unlock(&drm_global_mutex); | ||
95 | schedule(); | 96 | schedule(); |
97 | mutex_lock(&drm_global_mutex); | ||
96 | if (signal_pending(current)) { | 98 | if (signal_pending(current)) { |
97 | ret = -EINTR; | 99 | ret = -EINTR; |
98 | break; | 100 | break; |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index da99edc50888..a6bfc302ed90 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -285,21 +285,21 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
285 | 285 | ||
286 | EXPORT_SYMBOL(drm_mm_put_block); | 286 | EXPORT_SYMBOL(drm_mm_put_block); |
287 | 287 | ||
288 | static int check_free_mm_node(struct drm_mm_node *entry, unsigned long size, | 288 | static int check_free_hole(unsigned long start, unsigned long end, |
289 | unsigned alignment) | 289 | unsigned long size, unsigned alignment) |
290 | { | 290 | { |
291 | unsigned wasted = 0; | 291 | unsigned wasted = 0; |
292 | 292 | ||
293 | if (entry->size < size) | 293 | if (end - start < size) |
294 | return 0; | 294 | return 0; |
295 | 295 | ||
296 | if (alignment) { | 296 | if (alignment) { |
297 | register unsigned tmp = entry->start % alignment; | 297 | unsigned tmp = start % alignment; |
298 | if (tmp) | 298 | if (tmp) |
299 | wasted = alignment - tmp; | 299 | wasted = alignment - tmp; |
300 | } | 300 | } |
301 | 301 | ||
302 | if (entry->size >= size + wasted) { | 302 | if (end >= start + size + wasted) { |
303 | return 1; | 303 | return 1; |
304 | } | 304 | } |
305 | 305 | ||
@@ -320,7 +320,8 @@ struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | |||
320 | best_size = ~0UL; | 320 | best_size = ~0UL; |
321 | 321 | ||
322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { | 322 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
323 | if (!check_free_mm_node(entry, size, alignment)) | 323 | if (!check_free_hole(entry->start, entry->start + entry->size, |
324 | size, alignment)) | ||
324 | continue; | 325 | continue; |
325 | 326 | ||
326 | if (!best_match) | 327 | if (!best_match) |
@@ -353,10 +354,12 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm, | |||
353 | best_size = ~0UL; | 354 | best_size = ~0UL; |
354 | 355 | ||
355 | list_for_each_entry(entry, &mm->free_stack, free_stack) { | 356 | list_for_each_entry(entry, &mm->free_stack, free_stack) { |
356 | if (entry->start > end || (entry->start+entry->size) < start) | 357 | unsigned long adj_start = entry->start < start ? |
357 | continue; | 358 | start : entry->start; |
359 | unsigned long adj_end = entry->start + entry->size > end ? | ||
360 | end : entry->start + entry->size; | ||
358 | 361 | ||
359 | if (!check_free_mm_node(entry, size, alignment)) | 362 | if (!check_free_hole(adj_start, adj_end, size, alignment)) |
360 | continue; | 363 | continue; |
361 | 364 | ||
362 | if (!best_match) | 365 | if (!best_match) |
@@ -449,7 +452,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) | |||
449 | node->free_stack.prev = prev_free; | 452 | node->free_stack.prev = prev_free; |
450 | node->free_stack.next = next_free; | 453 | node->free_stack.next = next_free; |
451 | 454 | ||
452 | if (check_free_mm_node(node, mm->scan_size, mm->scan_alignment)) { | 455 | if (check_free_hole(node->start, node->start + node->size, |
456 | mm->scan_size, mm->scan_alignment)) { | ||
453 | mm->scan_hit_start = node->start; | 457 | mm->scan_hit_start = node->start; |
454 | mm->scan_hit_size = node->size; | 458 | mm->scan_hit_size = node->size; |
455 | 459 | ||
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index f1f473ea97d3..949326d2a8e5 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -251,7 +251,10 @@ struct drm_display_mode *drm_cvt_mode(struct drm_device *dev, int hdisplay, | |||
251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; | 251 | drm_mode->htotal = drm_mode->hdisplay + CVT_RB_H_BLANK; |
252 | /* Fill in HSync values */ | 252 | /* Fill in HSync values */ |
253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; | 253 | drm_mode->hsync_end = drm_mode->hdisplay + CVT_RB_H_BLANK / 2; |
254 | drm_mode->hsync_start = drm_mode->hsync_end = CVT_RB_H_SYNC; | 254 | drm_mode->hsync_start = drm_mode->hsync_end - CVT_RB_H_SYNC; |
255 | /* Fill in VSync values */ | ||
256 | drm_mode->vsync_start = drm_mode->vdisplay + CVT_RB_VFPORCH; | ||
257 | drm_mode->vsync_end = drm_mode->vsync_start + vsync; | ||
255 | } | 258 | } |
256 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ | 259 | /* 15/13. Find pixel clock frequency (kHz for xf86) */ |
257 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; | 260 | drm_mode->clock = drm_mode->htotal * HV_FACTOR * 1000 / hperiod; |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 3778360eceea..fda67468e603 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
@@ -138,7 +138,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
138 | break; | 138 | break; |
139 | } | 139 | } |
140 | 140 | ||
141 | if (!agpmem) | 141 | if (&agpmem->head == &dev->agp->memory) |
142 | goto vm_fault_error; | 142 | goto vm_fault_error; |
143 | 143 | ||
144 | /* | 144 | /* |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 0e6c131313d9..61b4caf220fa 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -1255,21 +1255,21 @@ long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | struct drm_ioctl_desc i810_ioctls[] = { | 1257 | struct drm_ioctl_desc i810_ioctls[] = { |
1258 | DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1258 | DRM_IOCTL_DEF_DRV(I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1259 | DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), | 1259 | DRM_IOCTL_DEF_DRV(I810_VERTEX, i810_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
1260 | DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), | 1260 | DRM_IOCTL_DEF_DRV(I810_CLEAR, i810_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
1261 | DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), | 1261 | DRM_IOCTL_DEF_DRV(I810_FLUSH, i810_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
1262 | DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), | 1262 | DRM_IOCTL_DEF_DRV(I810_GETAGE, i810_getage, DRM_AUTH|DRM_UNLOCKED), |
1263 | DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), | 1263 | DRM_IOCTL_DEF_DRV(I810_GETBUF, i810_getbuf, DRM_AUTH|DRM_UNLOCKED), |
1264 | DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), | 1264 | DRM_IOCTL_DEF_DRV(I810_SWAP, i810_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
1265 | DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), | 1265 | DRM_IOCTL_DEF_DRV(I810_COPY, i810_copybuf, DRM_AUTH|DRM_UNLOCKED), |
1266 | DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), | 1266 | DRM_IOCTL_DEF_DRV(I810_DOCOPY, i810_docopy, DRM_AUTH|DRM_UNLOCKED), |
1267 | DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), | 1267 | DRM_IOCTL_DEF_DRV(I810_OV0INFO, i810_ov0_info, DRM_AUTH|DRM_UNLOCKED), |
1268 | DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), | 1268 | DRM_IOCTL_DEF_DRV(I810_FSTATUS, i810_fstatus, DRM_AUTH|DRM_UNLOCKED), |
1269 | DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), | 1269 | DRM_IOCTL_DEF_DRV(I810_OV0FLIP, i810_ov0_flip, DRM_AUTH|DRM_UNLOCKED), |
1270 | DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1270 | DRM_IOCTL_DEF_DRV(I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1271 | DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), | 1271 | DRM_IOCTL_DEF_DRV(I810_RSTATUS, i810_rstatus, DRM_AUTH|DRM_UNLOCKED), |
1272 | DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), | 1272 | DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
1273 | }; | 1273 | }; |
1274 | 1274 | ||
1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); | 1275 | int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls); |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index 5168862c9227..671aa18415ac 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
@@ -1524,20 +1524,20 @@ long i830_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | struct drm_ioctl_desc i830_ioctls[] = { | 1526 | struct drm_ioctl_desc i830_ioctls[] = { |
1527 | DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 1527 | DRM_IOCTL_DEF_DRV(I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
1528 | DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), | 1528 | DRM_IOCTL_DEF_DRV(I830_VERTEX, i830_dma_vertex, DRM_AUTH|DRM_UNLOCKED), |
1529 | DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), | 1529 | DRM_IOCTL_DEF_DRV(I830_CLEAR, i830_clear_bufs, DRM_AUTH|DRM_UNLOCKED), |
1530 | DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), | 1530 | DRM_IOCTL_DEF_DRV(I830_FLUSH, i830_flush_ioctl, DRM_AUTH|DRM_UNLOCKED), |
1531 | DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), | 1531 | DRM_IOCTL_DEF_DRV(I830_GETAGE, i830_getage, DRM_AUTH|DRM_UNLOCKED), |
1532 | DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), | 1532 | DRM_IOCTL_DEF_DRV(I830_GETBUF, i830_getbuf, DRM_AUTH|DRM_UNLOCKED), |
1533 | DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), | 1533 | DRM_IOCTL_DEF_DRV(I830_SWAP, i830_swap_bufs, DRM_AUTH|DRM_UNLOCKED), |
1534 | DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), | 1534 | DRM_IOCTL_DEF_DRV(I830_COPY, i830_copybuf, DRM_AUTH|DRM_UNLOCKED), |
1535 | DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), | 1535 | DRM_IOCTL_DEF_DRV(I830_DOCOPY, i830_docopy, DRM_AUTH|DRM_UNLOCKED), |
1536 | DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), | 1536 | DRM_IOCTL_DEF_DRV(I830_FLIP, i830_flip_bufs, DRM_AUTH|DRM_UNLOCKED), |
1537 | DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), | 1537 | DRM_IOCTL_DEF_DRV(I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH|DRM_UNLOCKED), |
1538 | DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), | 1538 | DRM_IOCTL_DEF_DRV(I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH|DRM_UNLOCKED), |
1539 | DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), | 1539 | DRM_IOCTL_DEF_DRV(I830_GETPARAM, i830_getparam, DRM_AUTH|DRM_UNLOCKED), |
1540 | DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), | 1540 | DRM_IOCTL_DEF_DRV(I830_SETPARAM, i830_setparam, DRM_AUTH|DRM_UNLOCKED), |
1541 | }; | 1541 | }; |
1542 | 1542 | ||
1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); | 1543 | int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls); |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index da78f2c0d909..5c8e53458edb 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -8,6 +8,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
8 | i915_suspend.o \ | 8 | i915_suspend.o \ |
9 | i915_gem.o \ | 9 | i915_gem.o \ |
10 | i915_gem_debug.o \ | 10 | i915_gem_debug.o \ |
11 | i915_gem_evict.o \ | ||
11 | i915_gem_tiling.o \ | 12 | i915_gem_tiling.o \ |
12 | i915_trace_points.o \ | 13 | i915_trace_points.o \ |
13 | intel_display.o \ | 14 | intel_display.o \ |
@@ -18,6 +19,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ | |||
18 | intel_hdmi.o \ | 19 | intel_hdmi.o \ |
19 | intel_sdvo.o \ | 20 | intel_sdvo.o \ |
20 | intel_modes.o \ | 21 | intel_modes.o \ |
22 | intel_panel.o \ | ||
21 | intel_i2c.o \ | 23 | intel_i2c.o \ |
22 | intel_fb.o \ | 24 | intel_fb.o \ |
23 | intel_tv.o \ | 25 | intel_tv.o \ |
diff --git a/drivers/gpu/drm/i915/dvo.h b/drivers/gpu/drm/i915/dvo.h index 0d6ff640e1c6..8c2ad014c47f 100644 --- a/drivers/gpu/drm/i915/dvo.h +++ b/drivers/gpu/drm/i915/dvo.h | |||
@@ -30,20 +30,17 @@ | |||
30 | #include "intel_drv.h" | 30 | #include "intel_drv.h" |
31 | 31 | ||
32 | struct intel_dvo_device { | 32 | struct intel_dvo_device { |
33 | char *name; | 33 | const char *name; |
34 | int type; | 34 | int type; |
35 | /* DVOA/B/C output register */ | 35 | /* DVOA/B/C output register */ |
36 | u32 dvo_reg; | 36 | u32 dvo_reg; |
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 i2c_adapter *i2c_bus; | ||
41 | 40 | ||
42 | const struct intel_dvo_dev_ops *dev_ops; | 41 | const struct intel_dvo_dev_ops *dev_ops; |
43 | void *dev_priv; | 42 | void *dev_priv; |
44 | 43 | struct i2c_adapter *i2c_bus; | |
45 | struct drm_display_mode *panel_fixed_mode; | ||
46 | bool panel_wants_dither; | ||
47 | }; | 44 | }; |
48 | 45 | ||
49 | struct intel_dvo_dev_ops { | 46 | struct intel_dvo_dev_ops { |
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9214119c0154..92d5605a34d1 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -467,6 +467,9 @@ static int i915_error_state(struct seq_file *m, void *unused) | |||
467 | } | 467 | } |
468 | } | 468 | } |
469 | 469 | ||
470 | if (error->overlay) | ||
471 | intel_overlay_print_error_state(m, error->overlay); | ||
472 | |||
470 | out: | 473 | out: |
471 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); | 474 | spin_unlock_irqrestore(&dev_priv->error_lock, flags); |
472 | 475 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f19ffe87af3c..a7ec93e62f81 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -499,6 +499,13 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, | |||
499 | } | 499 | } |
500 | } | 500 | } |
501 | 501 | ||
502 | |||
503 | if (IS_G4X(dev) || IS_IRONLAKE(dev)) { | ||
504 | BEGIN_LP_RING(2); | ||
505 | OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); | ||
506 | OUT_RING(MI_NOOP); | ||
507 | ADVANCE_LP_RING(); | ||
508 | } | ||
502 | i915_emit_breadcrumb(dev); | 509 | i915_emit_breadcrumb(dev); |
503 | 510 | ||
504 | return 0; | 511 | return 0; |
@@ -2360,46 +2367,46 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
2360 | } | 2367 | } |
2361 | 2368 | ||
2362 | struct drm_ioctl_desc i915_ioctls[] = { | 2369 | struct drm_ioctl_desc i915_ioctls[] = { |
2363 | DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2370 | DRM_IOCTL_DEF_DRV(I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2364 | DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH), | 2371 | DRM_IOCTL_DEF_DRV(I915_FLUSH, i915_flush_ioctl, DRM_AUTH), |
2365 | DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH), | 2372 | DRM_IOCTL_DEF_DRV(I915_FLIP, i915_flip_bufs, DRM_AUTH), |
2366 | DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), | 2373 | DRM_IOCTL_DEF_DRV(I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH), |
2367 | DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), | 2374 | DRM_IOCTL_DEF_DRV(I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH), |
2368 | DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), | 2375 | DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), |
2369 | DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH), | 2376 | DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), |
2370 | DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2377 | DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2371 | DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH), | 2378 | DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH), |
2372 | DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH), | 2379 | DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH), |
2373 | DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2380 | DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2374 | DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), | 2381 | DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), |
2375 | DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 2382 | DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2376 | DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ), | 2383 | DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2377 | DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ), | 2384 | DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), |
2378 | DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), | 2385 | DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), |
2379 | DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 2386 | DRM_IOCTL_DEF_DRV(I915_HWS_ADDR, i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
2380 | DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2387 | DRM_IOCTL_DEF_DRV(I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2381 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), | 2388 | DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH|DRM_UNLOCKED), |
2382 | DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), | 2389 | DRM_IOCTL_DEF_DRV(I915_GEM_EXECBUFFER2, i915_gem_execbuffer2, DRM_AUTH|DRM_UNLOCKED), |
2383 | DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2390 | DRM_IOCTL_DEF_DRV(I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2384 | DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2391 | DRM_IOCTL_DEF_DRV(I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2385 | DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), | 2392 | DRM_IOCTL_DEF_DRV(I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), |
2386 | DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 2393 | DRM_IOCTL_DEF_DRV(I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH|DRM_UNLOCKED), |
2387 | DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2394 | DRM_IOCTL_DEF_DRV(I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2388 | DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), | 2395 | DRM_IOCTL_DEF_DRV(I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY|DRM_UNLOCKED), |
2389 | DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), | 2396 | DRM_IOCTL_DEF_DRV(I915_GEM_CREATE, i915_gem_create_ioctl, DRM_UNLOCKED), |
2390 | DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), | 2397 | DRM_IOCTL_DEF_DRV(I915_GEM_PREAD, i915_gem_pread_ioctl, DRM_UNLOCKED), |
2391 | DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), | 2398 | DRM_IOCTL_DEF_DRV(I915_GEM_PWRITE, i915_gem_pwrite_ioctl, DRM_UNLOCKED), |
2392 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), | 2399 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP, i915_gem_mmap_ioctl, DRM_UNLOCKED), |
2393 | DRM_IOCTL_DEF(DRM_I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), | 2400 | DRM_IOCTL_DEF_DRV(I915_GEM_MMAP_GTT, i915_gem_mmap_gtt_ioctl, DRM_UNLOCKED), |
2394 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), | 2401 | DRM_IOCTL_DEF_DRV(I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, DRM_UNLOCKED), |
2395 | DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), | 2402 | DRM_IOCTL_DEF_DRV(I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, DRM_UNLOCKED), |
2396 | DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), | 2403 | DRM_IOCTL_DEF_DRV(I915_GEM_SET_TILING, i915_gem_set_tiling, DRM_UNLOCKED), |
2397 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), | 2404 | DRM_IOCTL_DEF_DRV(I915_GEM_GET_TILING, i915_gem_get_tiling, DRM_UNLOCKED), |
2398 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), | 2405 | DRM_IOCTL_DEF_DRV(I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, DRM_UNLOCKED), |
2399 | DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), | 2406 | DRM_IOCTL_DEF_DRV(I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, DRM_UNLOCKED), |
2400 | DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), | 2407 | DRM_IOCTL_DEF_DRV(I915_GEM_MADVISE, i915_gem_madvise_ioctl, DRM_UNLOCKED), |
2401 | DRM_IOCTL_DEF(DRM_I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 2408 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_PUT_IMAGE, intel_overlay_put_image, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
2402 | DRM_IOCTL_DEF(DRM_I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 2409 | DRM_IOCTL_DEF_DRV(I915_OVERLAY_ATTRS, intel_overlay_attrs, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
2403 | }; | 2410 | }; |
2404 | 2411 | ||
2405 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 2412 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5044f653e8ea..00befce8fbb7 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -181,6 +181,7 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
181 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), | 181 | INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info), |
182 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), | 182 | INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info), |
183 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), | 183 | INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info), |
184 | INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info), | ||
184 | {0, 0, 0} | 185 | {0, 0, 0} |
185 | }; | 186 | }; |
186 | 187 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 906663b9929e..047cd7ce7e1b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -113,6 +113,9 @@ struct intel_opregion { | |||
113 | int enabled; | 113 | int enabled; |
114 | }; | 114 | }; |
115 | 115 | ||
116 | struct intel_overlay; | ||
117 | struct intel_overlay_error_state; | ||
118 | |||
116 | struct drm_i915_master_private { | 119 | struct drm_i915_master_private { |
117 | drm_local_map_t *sarea; | 120 | drm_local_map_t *sarea; |
118 | struct _drm_i915_sarea *sarea_priv; | 121 | struct _drm_i915_sarea *sarea_priv; |
@@ -166,6 +169,7 @@ struct drm_i915_error_state { | |||
166 | u32 purgeable:1; | 169 | u32 purgeable:1; |
167 | } *active_bo; | 170 | } *active_bo; |
168 | u32 active_bo_count; | 171 | u32 active_bo_count; |
172 | struct intel_overlay_error_state *overlay; | ||
169 | }; | 173 | }; |
170 | 174 | ||
171 | struct drm_i915_display_funcs { | 175 | struct drm_i915_display_funcs { |
@@ -186,8 +190,6 @@ struct drm_i915_display_funcs { | |||
186 | /* clock gating init */ | 190 | /* clock gating init */ |
187 | }; | 191 | }; |
188 | 192 | ||
189 | struct intel_overlay; | ||
190 | |||
191 | struct intel_device_info { | 193 | struct intel_device_info { |
192 | u8 is_mobile : 1; | 194 | u8 is_mobile : 1; |
193 | u8 is_i8xx : 1; | 195 | u8 is_i8xx : 1; |
@@ -242,6 +244,7 @@ typedef struct drm_i915_private { | |||
242 | struct pci_dev *bridge_dev; | 244 | struct pci_dev *bridge_dev; |
243 | struct intel_ring_buffer render_ring; | 245 | struct intel_ring_buffer render_ring; |
244 | struct intel_ring_buffer bsd_ring; | 246 | struct intel_ring_buffer bsd_ring; |
247 | uint32_t next_seqno; | ||
245 | 248 | ||
246 | drm_dma_handle_t *status_page_dmah; | 249 | drm_dma_handle_t *status_page_dmah; |
247 | void *seqno_page; | 250 | void *seqno_page; |
@@ -251,6 +254,7 @@ typedef struct drm_i915_private { | |||
251 | drm_local_map_t hws_map; | 254 | drm_local_map_t hws_map; |
252 | struct drm_gem_object *seqno_obj; | 255 | struct drm_gem_object *seqno_obj; |
253 | struct drm_gem_object *pwrctx; | 256 | struct drm_gem_object *pwrctx; |
257 | struct drm_gem_object *renderctx; | ||
254 | 258 | ||
255 | struct resource mch_res; | 259 | struct resource mch_res; |
256 | 260 | ||
@@ -285,6 +289,9 @@ typedef struct drm_i915_private { | |||
285 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; | 289 | unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; |
286 | int vblank_pipe; | 290 | int vblank_pipe; |
287 | int num_pipe; | 291 | int num_pipe; |
292 | u32 flush_rings; | ||
293 | #define FLUSH_RENDER_RING 0x1 | ||
294 | #define FLUSH_BSD_RING 0x2 | ||
288 | 295 | ||
289 | /* For hangcheck timer */ | 296 | /* For hangcheck timer */ |
290 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ | 297 | #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */ |
@@ -568,8 +575,6 @@ typedef struct drm_i915_private { | |||
568 | */ | 575 | */ |
569 | struct delayed_work retire_work; | 576 | struct delayed_work retire_work; |
570 | 577 | ||
571 | uint32_t next_gem_seqno; | ||
572 | |||
573 | /** | 578 | /** |
574 | * Waiting sequence number, if any | 579 | * Waiting sequence number, if any |
575 | */ | 580 | */ |
@@ -610,6 +615,8 @@ typedef struct drm_i915_private { | |||
610 | struct sdvo_device_mapping sdvo_mappings[2]; | 615 | struct sdvo_device_mapping sdvo_mappings[2]; |
611 | /* indicate whether the LVDS_BORDER should be enabled or not */ | 616 | /* indicate whether the LVDS_BORDER should be enabled or not */ |
612 | unsigned int lvds_border_bits; | 617 | unsigned int lvds_border_bits; |
618 | /* Panel fitter placement and size for Ironlake+ */ | ||
619 | u32 pch_pf_pos, pch_pf_size; | ||
613 | 620 | ||
614 | struct drm_crtc *plane_to_crtc_mapping[2]; | 621 | struct drm_crtc *plane_to_crtc_mapping[2]; |
615 | struct drm_crtc *pipe_to_crtc_mapping[2]; | 622 | struct drm_crtc *pipe_to_crtc_mapping[2]; |
@@ -669,6 +676,8 @@ struct drm_i915_gem_object { | |||
669 | struct list_head list; | 676 | struct list_head list; |
670 | /** This object's place on GPU write list */ | 677 | /** This object's place on GPU write list */ |
671 | struct list_head gpu_write_list; | 678 | struct list_head gpu_write_list; |
679 | /** This object's place on eviction list */ | ||
680 | struct list_head evict_list; | ||
672 | 681 | ||
673 | /** | 682 | /** |
674 | * This is set if the object is on the active or flushing lists | 683 | * This is set if the object is on the active or flushing lists |
@@ -978,6 +987,7 @@ int i915_gem_init_ringbuffer(struct drm_device *dev); | |||
978 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 987 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
979 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 988 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
980 | unsigned long end); | 989 | unsigned long end); |
990 | int i915_gpu_idle(struct drm_device *dev); | ||
981 | int i915_gem_idle(struct drm_device *dev); | 991 | int i915_gem_idle(struct drm_device *dev); |
982 | uint32_t i915_add_request(struct drm_device *dev, | 992 | uint32_t i915_add_request(struct drm_device *dev, |
983 | struct drm_file *file_priv, | 993 | struct drm_file *file_priv, |
@@ -991,7 +1001,9 @@ int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, | |||
991 | int write); | 1001 | int write); |
992 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); | 1002 | int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj); |
993 | int i915_gem_attach_phys_object(struct drm_device *dev, | 1003 | int i915_gem_attach_phys_object(struct drm_device *dev, |
994 | struct drm_gem_object *obj, int id); | 1004 | struct drm_gem_object *obj, |
1005 | int id, | ||
1006 | int align); | ||
995 | void i915_gem_detach_phys_object(struct drm_device *dev, | 1007 | void i915_gem_detach_phys_object(struct drm_device *dev, |
996 | struct drm_gem_object *obj); | 1008 | struct drm_gem_object *obj); |
997 | void i915_gem_free_all_phys_object(struct drm_device *dev); | 1009 | void i915_gem_free_all_phys_object(struct drm_device *dev); |
@@ -1003,6 +1015,11 @@ int i915_gem_object_flush_write_domain(struct drm_gem_object *obj); | |||
1003 | void i915_gem_shrinker_init(void); | 1015 | void i915_gem_shrinker_init(void); |
1004 | void i915_gem_shrinker_exit(void); | 1016 | void i915_gem_shrinker_exit(void); |
1005 | 1017 | ||
1018 | /* i915_gem_evict.c */ | ||
1019 | int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); | ||
1020 | int i915_gem_evict_everything(struct drm_device *dev); | ||
1021 | int i915_gem_evict_inactive(struct drm_device *dev); | ||
1022 | |||
1006 | /* i915_gem_tiling.c */ | 1023 | /* i915_gem_tiling.c */ |
1007 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); | 1024 | void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); |
1008 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); | 1025 | void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); |
@@ -1066,6 +1083,10 @@ extern bool ironlake_set_drps(struct drm_device *dev, u8 val); | |||
1066 | extern void intel_detect_pch (struct drm_device *dev); | 1083 | extern void intel_detect_pch (struct drm_device *dev); |
1067 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | 1084 | extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); |
1068 | 1085 | ||
1086 | /* overlay */ | ||
1087 | extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); | ||
1088 | extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); | ||
1089 | |||
1069 | /** | 1090 | /** |
1070 | * Lock test for when it's just for synchronization of ring access. | 1091 | * Lock test for when it's just for synchronization of ring access. |
1071 | * | 1092 | * |
@@ -1092,26 +1113,26 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); | |||
1092 | #define I915_VERBOSE 0 | 1113 | #define I915_VERBOSE 0 |
1093 | 1114 | ||
1094 | #define BEGIN_LP_RING(n) do { \ | 1115 | #define BEGIN_LP_RING(n) do { \ |
1095 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1116 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
1096 | if (I915_VERBOSE) \ | 1117 | if (I915_VERBOSE) \ |
1097 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ | 1118 | DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ |
1098 | intel_ring_begin(dev, &dev_priv->render_ring, (n)); \ | 1119 | intel_ring_begin(dev, &dev_priv__->render_ring, (n)); \ |
1099 | } while (0) | 1120 | } while (0) |
1100 | 1121 | ||
1101 | 1122 | ||
1102 | #define OUT_RING(x) do { \ | 1123 | #define OUT_RING(x) do { \ |
1103 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1124 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
1104 | if (I915_VERBOSE) \ | 1125 | if (I915_VERBOSE) \ |
1105 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ | 1126 | DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ |
1106 | intel_ring_emit(dev, &dev_priv->render_ring, x); \ | 1127 | intel_ring_emit(dev, &dev_priv__->render_ring, x); \ |
1107 | } while (0) | 1128 | } while (0) |
1108 | 1129 | ||
1109 | #define ADVANCE_LP_RING() do { \ | 1130 | #define ADVANCE_LP_RING() do { \ |
1110 | drm_i915_private_t *dev_priv = dev->dev_private; \ | 1131 | drm_i915_private_t *dev_priv__ = dev->dev_private; \ |
1111 | if (I915_VERBOSE) \ | 1132 | if (I915_VERBOSE) \ |
1112 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ | 1133 | DRM_DEBUG("ADVANCE_LP_RING %x\n", \ |
1113 | dev_priv->render_ring.tail); \ | 1134 | dev_priv__->render_ring.tail); \ |
1114 | intel_ring_advance(dev, &dev_priv->render_ring); \ | 1135 | intel_ring_advance(dev, &dev_priv__->render_ring); \ |
1115 | } while(0) | 1136 | } while(0) |
1116 | 1137 | ||
1117 | /** | 1138 | /** |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 0758c7802e6b..df5a7135c261 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/swap.h> | 35 | #include <linux/swap.h> |
36 | #include <linux/pci.h> | 36 | #include <linux/pci.h> |
37 | 37 | ||
38 | static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); | ||
38 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); | 39 | static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); |
39 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); | 40 | static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); |
40 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); | 41 | static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); |
@@ -48,8 +49,6 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | |||
48 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 49 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, |
49 | unsigned alignment); | 50 | unsigned alignment); |
50 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 51 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); |
51 | static int i915_gem_evict_something(struct drm_device *dev, int min_size); | ||
52 | static int i915_gem_evict_from_inactive_list(struct drm_device *dev); | ||
53 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 52 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, |
54 | struct drm_i915_gem_pwrite *args, | 53 | struct drm_i915_gem_pwrite *args, |
55 | struct drm_file *file_priv); | 54 | struct drm_file *file_priv); |
@@ -58,6 +57,14 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj); | |||
58 | static LIST_HEAD(shrink_list); | 57 | static LIST_HEAD(shrink_list); |
59 | static DEFINE_SPINLOCK(shrink_list_lock); | 58 | static DEFINE_SPINLOCK(shrink_list_lock); |
60 | 59 | ||
60 | static inline bool | ||
61 | i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) | ||
62 | { | ||
63 | return obj_priv->gtt_space && | ||
64 | !obj_priv->active && | ||
65 | obj_priv->pin_count == 0; | ||
66 | } | ||
67 | |||
61 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, | 68 | int i915_gem_do_init(struct drm_device *dev, unsigned long start, |
62 | unsigned long end) | 69 | unsigned long end) |
63 | { | 70 | { |
@@ -313,7 +320,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) | |||
313 | if (ret == -ENOMEM) { | 320 | if (ret == -ENOMEM) { |
314 | struct drm_device *dev = obj->dev; | 321 | struct drm_device *dev = obj->dev; |
315 | 322 | ||
316 | ret = i915_gem_evict_something(dev, obj->size); | 323 | ret = i915_gem_evict_something(dev, obj->size, |
324 | i915_gem_get_gtt_alignment(obj)); | ||
317 | if (ret) | 325 | if (ret) |
318 | return ret; | 326 | return ret; |
319 | 327 | ||
@@ -1036,6 +1044,11 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, | |||
1036 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); | 1044 | ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); |
1037 | } | 1045 | } |
1038 | 1046 | ||
1047 | |||
1048 | /* Maintain LRU order of "inactive" objects */ | ||
1049 | if (ret == 0 && i915_gem_object_is_inactive(obj_priv)) | ||
1050 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1051 | |||
1039 | drm_gem_object_unreference(obj); | 1052 | drm_gem_object_unreference(obj); |
1040 | mutex_unlock(&dev->struct_mutex); | 1053 | mutex_unlock(&dev->struct_mutex); |
1041 | return ret; | 1054 | return ret; |
@@ -1137,7 +1150,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1137 | { | 1150 | { |
1138 | struct drm_gem_object *obj = vma->vm_private_data; | 1151 | struct drm_gem_object *obj = vma->vm_private_data; |
1139 | struct drm_device *dev = obj->dev; | 1152 | struct drm_device *dev = obj->dev; |
1140 | struct drm_i915_private *dev_priv = dev->dev_private; | 1153 | drm_i915_private_t *dev_priv = dev->dev_private; |
1141 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1154 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1142 | pgoff_t page_offset; | 1155 | pgoff_t page_offset; |
1143 | unsigned long pfn; | 1156 | unsigned long pfn; |
@@ -1155,8 +1168,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1155 | if (ret) | 1168 | if (ret) |
1156 | goto unlock; | 1169 | goto unlock; |
1157 | 1170 | ||
1158 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1159 | |||
1160 | ret = i915_gem_object_set_to_gtt_domain(obj, write); | 1171 | ret = i915_gem_object_set_to_gtt_domain(obj, write); |
1161 | if (ret) | 1172 | if (ret) |
1162 | goto unlock; | 1173 | goto unlock; |
@@ -1169,6 +1180,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
1169 | goto unlock; | 1180 | goto unlock; |
1170 | } | 1181 | } |
1171 | 1182 | ||
1183 | if (i915_gem_object_is_inactive(obj_priv)) | ||
1184 | list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1185 | |||
1172 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + | 1186 | pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + |
1173 | page_offset; | 1187 | page_offset; |
1174 | 1188 | ||
@@ -1363,7 +1377,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1363 | struct drm_file *file_priv) | 1377 | struct drm_file *file_priv) |
1364 | { | 1378 | { |
1365 | struct drm_i915_gem_mmap_gtt *args = data; | 1379 | struct drm_i915_gem_mmap_gtt *args = data; |
1366 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1367 | struct drm_gem_object *obj; | 1380 | struct drm_gem_object *obj; |
1368 | struct drm_i915_gem_object *obj_priv; | 1381 | struct drm_i915_gem_object *obj_priv; |
1369 | int ret; | 1382 | int ret; |
@@ -1409,7 +1422,6 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, | |||
1409 | mutex_unlock(&dev->struct_mutex); | 1422 | mutex_unlock(&dev->struct_mutex); |
1410 | return ret; | 1423 | return ret; |
1411 | } | 1424 | } |
1412 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
1413 | } | 1425 | } |
1414 | 1426 | ||
1415 | drm_gem_object_unreference(obj); | 1427 | drm_gem_object_unreference(obj); |
@@ -1493,9 +1505,16 @@ i915_gem_object_truncate(struct drm_gem_object *obj) | |||
1493 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 1505 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
1494 | struct inode *inode; | 1506 | struct inode *inode; |
1495 | 1507 | ||
1508 | /* Our goal here is to return as much of the memory as | ||
1509 | * is possible back to the system as we are called from OOM. | ||
1510 | * To do this we must instruct the shmfs to drop all of its | ||
1511 | * backing pages, *now*. Here we mirror the actions taken | ||
1512 | * when by shmem_delete_inode() to release the backing store. | ||
1513 | */ | ||
1496 | inode = obj->filp->f_path.dentry->d_inode; | 1514 | inode = obj->filp->f_path.dentry->d_inode; |
1497 | if (inode->i_op->truncate) | 1515 | truncate_inode_pages(inode->i_mapping, 0); |
1498 | inode->i_op->truncate (inode); | 1516 | if (inode->i_op->truncate_range) |
1517 | inode->i_op->truncate_range(inode, 0, (loff_t)-1); | ||
1499 | 1518 | ||
1500 | obj_priv->madv = __I915_MADV_PURGED; | 1519 | obj_priv->madv = __I915_MADV_PURGED; |
1501 | } | 1520 | } |
@@ -1887,19 +1906,6 @@ i915_gem_flush(struct drm_device *dev, | |||
1887 | flush_domains); | 1906 | flush_domains); |
1888 | } | 1907 | } |
1889 | 1908 | ||
1890 | static void | ||
1891 | i915_gem_flush_ring(struct drm_device *dev, | ||
1892 | uint32_t invalidate_domains, | ||
1893 | uint32_t flush_domains, | ||
1894 | struct intel_ring_buffer *ring) | ||
1895 | { | ||
1896 | if (flush_domains & I915_GEM_DOMAIN_CPU) | ||
1897 | drm_agp_chipset_flush(dev); | ||
1898 | ring->flush(dev, ring, | ||
1899 | invalidate_domains, | ||
1900 | flush_domains); | ||
1901 | } | ||
1902 | |||
1903 | /** | 1909 | /** |
1904 | * Ensures that all rendering to the object has completed and the object is | 1910 | * Ensures that all rendering to the object has completed and the object is |
1905 | * safe to unbind from the GTT or access from the CPU. | 1911 | * safe to unbind from the GTT or access from the CPU. |
@@ -1973,8 +1979,6 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
1973 | * cause memory corruption through use-after-free. | 1979 | * cause memory corruption through use-after-free. |
1974 | */ | 1980 | */ |
1975 | 1981 | ||
1976 | BUG_ON(obj_priv->active); | ||
1977 | |||
1978 | /* release the fence reg _after_ flushing */ | 1982 | /* release the fence reg _after_ flushing */ |
1979 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 1983 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
1980 | i915_gem_clear_fence_reg(obj); | 1984 | i915_gem_clear_fence_reg(obj); |
@@ -2010,34 +2014,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) | |||
2010 | return ret; | 2014 | return ret; |
2011 | } | 2015 | } |
2012 | 2016 | ||
2013 | static struct drm_gem_object * | 2017 | int |
2014 | i915_gem_find_inactive_object(struct drm_device *dev, int min_size) | ||
2015 | { | ||
2016 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2017 | struct drm_i915_gem_object *obj_priv; | ||
2018 | struct drm_gem_object *best = NULL; | ||
2019 | struct drm_gem_object *first = NULL; | ||
2020 | |||
2021 | /* Try to find the smallest clean object */ | ||
2022 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
2023 | struct drm_gem_object *obj = &obj_priv->base; | ||
2024 | if (obj->size >= min_size) { | ||
2025 | if ((!obj_priv->dirty || | ||
2026 | i915_gem_object_is_purgeable(obj_priv)) && | ||
2027 | (!best || obj->size < best->size)) { | ||
2028 | best = obj; | ||
2029 | if (best->size == min_size) | ||
2030 | return best; | ||
2031 | } | ||
2032 | if (!first) | ||
2033 | first = obj; | ||
2034 | } | ||
2035 | } | ||
2036 | |||
2037 | return best ? best : first; | ||
2038 | } | ||
2039 | |||
2040 | static int | ||
2041 | i915_gpu_idle(struct drm_device *dev) | 2018 | i915_gpu_idle(struct drm_device *dev) |
2042 | { | 2019 | { |
2043 | drm_i915_private_t *dev_priv = dev->dev_private; | 2020 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -2078,155 +2055,6 @@ i915_gpu_idle(struct drm_device *dev) | |||
2078 | return ret; | 2055 | return ret; |
2079 | } | 2056 | } |
2080 | 2057 | ||
2081 | static int | ||
2082 | i915_gem_evict_everything(struct drm_device *dev) | ||
2083 | { | ||
2084 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2085 | int ret; | ||
2086 | bool lists_empty; | ||
2087 | |||
2088 | spin_lock(&dev_priv->mm.active_list_lock); | ||
2089 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
2090 | list_empty(&dev_priv->mm.flushing_list) && | ||
2091 | list_empty(&dev_priv->render_ring.active_list) && | ||
2092 | (!HAS_BSD(dev) | ||
2093 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
2094 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
2095 | |||
2096 | if (lists_empty) | ||
2097 | return -ENOSPC; | ||
2098 | |||
2099 | /* Flush everything (on to the inactive lists) and evict */ | ||
2100 | ret = i915_gpu_idle(dev); | ||
2101 | if (ret) | ||
2102 | return ret; | ||
2103 | |||
2104 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
2105 | |||
2106 | ret = i915_gem_evict_from_inactive_list(dev); | ||
2107 | if (ret) | ||
2108 | return ret; | ||
2109 | |||
2110 | spin_lock(&dev_priv->mm.active_list_lock); | ||
2111 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
2112 | list_empty(&dev_priv->mm.flushing_list) && | ||
2113 | list_empty(&dev_priv->render_ring.active_list) && | ||
2114 | (!HAS_BSD(dev) | ||
2115 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
2116 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
2117 | BUG_ON(!lists_empty); | ||
2118 | |||
2119 | return 0; | ||
2120 | } | ||
2121 | |||
2122 | static int | ||
2123 | i915_gem_evict_something(struct drm_device *dev, int min_size) | ||
2124 | { | ||
2125 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
2126 | struct drm_gem_object *obj; | ||
2127 | int ret; | ||
2128 | |||
2129 | struct intel_ring_buffer *render_ring = &dev_priv->render_ring; | ||
2130 | struct intel_ring_buffer *bsd_ring = &dev_priv->bsd_ring; | ||
2131 | for (;;) { | ||
2132 | i915_gem_retire_requests(dev); | ||
2133 | |||
2134 | /* If there's an inactive buffer available now, grab it | ||
2135 | * and be done. | ||
2136 | */ | ||
2137 | obj = i915_gem_find_inactive_object(dev, min_size); | ||
2138 | if (obj) { | ||
2139 | struct drm_i915_gem_object *obj_priv; | ||
2140 | |||
2141 | #if WATCH_LRU | ||
2142 | DRM_INFO("%s: evicting %p\n", __func__, obj); | ||
2143 | #endif | ||
2144 | obj_priv = to_intel_bo(obj); | ||
2145 | BUG_ON(obj_priv->pin_count != 0); | ||
2146 | BUG_ON(obj_priv->active); | ||
2147 | |||
2148 | /* Wait on the rendering and unbind the buffer. */ | ||
2149 | return i915_gem_object_unbind(obj); | ||
2150 | } | ||
2151 | |||
2152 | /* If we didn't get anything, but the ring is still processing | ||
2153 | * things, wait for the next to finish and hopefully leave us | ||
2154 | * a buffer to evict. | ||
2155 | */ | ||
2156 | if (!list_empty(&render_ring->request_list)) { | ||
2157 | struct drm_i915_gem_request *request; | ||
2158 | |||
2159 | request = list_first_entry(&render_ring->request_list, | ||
2160 | struct drm_i915_gem_request, | ||
2161 | list); | ||
2162 | |||
2163 | ret = i915_wait_request(dev, | ||
2164 | request->seqno, request->ring); | ||
2165 | if (ret) | ||
2166 | return ret; | ||
2167 | |||
2168 | continue; | ||
2169 | } | ||
2170 | |||
2171 | if (HAS_BSD(dev) && !list_empty(&bsd_ring->request_list)) { | ||
2172 | struct drm_i915_gem_request *request; | ||
2173 | |||
2174 | request = list_first_entry(&bsd_ring->request_list, | ||
2175 | struct drm_i915_gem_request, | ||
2176 | list); | ||
2177 | |||
2178 | ret = i915_wait_request(dev, | ||
2179 | request->seqno, request->ring); | ||
2180 | if (ret) | ||
2181 | return ret; | ||
2182 | |||
2183 | continue; | ||
2184 | } | ||
2185 | |||
2186 | /* If we didn't have anything on the request list but there | ||
2187 | * are buffers awaiting a flush, emit one and try again. | ||
2188 | * When we wait on it, those buffers waiting for that flush | ||
2189 | * will get moved to inactive. | ||
2190 | */ | ||
2191 | if (!list_empty(&dev_priv->mm.flushing_list)) { | ||
2192 | struct drm_i915_gem_object *obj_priv; | ||
2193 | |||
2194 | /* Find an object that we can immediately reuse */ | ||
2195 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
2196 | obj = &obj_priv->base; | ||
2197 | if (obj->size >= min_size) | ||
2198 | break; | ||
2199 | |||
2200 | obj = NULL; | ||
2201 | } | ||
2202 | |||
2203 | if (obj != NULL) { | ||
2204 | uint32_t seqno; | ||
2205 | |||
2206 | i915_gem_flush_ring(dev, | ||
2207 | obj->write_domain, | ||
2208 | obj->write_domain, | ||
2209 | obj_priv->ring); | ||
2210 | seqno = i915_add_request(dev, NULL, | ||
2211 | obj->write_domain, | ||
2212 | obj_priv->ring); | ||
2213 | if (seqno == 0) | ||
2214 | return -ENOMEM; | ||
2215 | continue; | ||
2216 | } | ||
2217 | } | ||
2218 | |||
2219 | /* If we didn't do any of the above, there's no single buffer | ||
2220 | * large enough to swap out for the new one, so just evict | ||
2221 | * everything and start again. (This should be rare.) | ||
2222 | */ | ||
2223 | if (!list_empty (&dev_priv->mm.inactive_list)) | ||
2224 | return i915_gem_evict_from_inactive_list(dev); | ||
2225 | else | ||
2226 | return i915_gem_evict_everything(dev); | ||
2227 | } | ||
2228 | } | ||
2229 | |||
2230 | int | 2058 | int |
2231 | i915_gem_object_get_pages(struct drm_gem_object *obj, | 2059 | i915_gem_object_get_pages(struct drm_gem_object *obj, |
2232 | gfp_t gfpmask) | 2060 | gfp_t gfpmask) |
@@ -2666,7 +2494,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2666 | #if WATCH_LRU | 2494 | #if WATCH_LRU |
2667 | DRM_INFO("%s: GTT full, evicting something\n", __func__); | 2495 | DRM_INFO("%s: GTT full, evicting something\n", __func__); |
2668 | #endif | 2496 | #endif |
2669 | ret = i915_gem_evict_something(dev, obj->size); | 2497 | ret = i915_gem_evict_something(dev, obj->size, alignment); |
2670 | if (ret) | 2498 | if (ret) |
2671 | return ret; | 2499 | return ret; |
2672 | 2500 | ||
@@ -2684,7 +2512,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2684 | 2512 | ||
2685 | if (ret == -ENOMEM) { | 2513 | if (ret == -ENOMEM) { |
2686 | /* first try to clear up some space from the GTT */ | 2514 | /* first try to clear up some space from the GTT */ |
2687 | ret = i915_gem_evict_something(dev, obj->size); | 2515 | ret = i915_gem_evict_something(dev, obj->size, |
2516 | alignment); | ||
2688 | if (ret) { | 2517 | if (ret) { |
2689 | /* now try to shrink everyone else */ | 2518 | /* now try to shrink everyone else */ |
2690 | if (gfpmask) { | 2519 | if (gfpmask) { |
@@ -2714,7 +2543,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2714 | drm_mm_put_block(obj_priv->gtt_space); | 2543 | drm_mm_put_block(obj_priv->gtt_space); |
2715 | obj_priv->gtt_space = NULL; | 2544 | obj_priv->gtt_space = NULL; |
2716 | 2545 | ||
2717 | ret = i915_gem_evict_something(dev, obj->size); | 2546 | ret = i915_gem_evict_something(dev, obj->size, alignment); |
2718 | if (ret) | 2547 | if (ret) |
2719 | return ret; | 2548 | return ret; |
2720 | 2549 | ||
@@ -2723,6 +2552,9 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2723 | atomic_inc(&dev->gtt_count); | 2552 | atomic_inc(&dev->gtt_count); |
2724 | atomic_add(obj->size, &dev->gtt_memory); | 2553 | atomic_add(obj->size, &dev->gtt_memory); |
2725 | 2554 | ||
2555 | /* keep track of bounds object by adding it to the inactive list */ | ||
2556 | list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); | ||
2557 | |||
2726 | /* Assert that the object is not currently in any GPU domain. As it | 2558 | /* Assert that the object is not currently in any GPU domain. As it |
2727 | * wasn't in the GTT, there shouldn't be any way it could have been in | 2559 | * wasn't in the GTT, there shouldn't be any way it could have been in |
2728 | * a GPU cache | 2560 | * a GPU cache |
@@ -3117,6 +2949,7 @@ static void | |||
3117 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | 2949 | i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) |
3118 | { | 2950 | { |
3119 | struct drm_device *dev = obj->dev; | 2951 | struct drm_device *dev = obj->dev; |
2952 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
3120 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); | 2953 | struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); |
3121 | uint32_t invalidate_domains = 0; | 2954 | uint32_t invalidate_domains = 0; |
3122 | uint32_t flush_domains = 0; | 2955 | uint32_t flush_domains = 0; |
@@ -3179,6 +3012,13 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj) | |||
3179 | obj->pending_write_domain = obj->write_domain; | 3012 | obj->pending_write_domain = obj->write_domain; |
3180 | obj->read_domains = obj->pending_read_domains; | 3013 | obj->read_domains = obj->pending_read_domains; |
3181 | 3014 | ||
3015 | if (flush_domains & I915_GEM_GPU_DOMAINS) { | ||
3016 | if (obj_priv->ring == &dev_priv->render_ring) | ||
3017 | dev_priv->flush_rings |= FLUSH_RENDER_RING; | ||
3018 | else if (obj_priv->ring == &dev_priv->bsd_ring) | ||
3019 | dev_priv->flush_rings |= FLUSH_BSD_RING; | ||
3020 | } | ||
3021 | |||
3182 | dev->invalidate_domains |= invalidate_domains; | 3022 | dev->invalidate_domains |= invalidate_domains; |
3183 | dev->flush_domains |= flush_domains; | 3023 | dev->flush_domains |= flush_domains; |
3184 | #if WATCH_BUF | 3024 | #if WATCH_BUF |
@@ -3718,7 +3558,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3718 | ring = &dev_priv->render_ring; | 3558 | ring = &dev_priv->render_ring; |
3719 | } | 3559 | } |
3720 | 3560 | ||
3721 | |||
3722 | if (args->buffer_count < 1) { | 3561 | if (args->buffer_count < 1) { |
3723 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); | 3562 | DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); |
3724 | return -EINVAL; | 3563 | return -EINVAL; |
@@ -3892,6 +3731,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3892 | */ | 3731 | */ |
3893 | dev->invalidate_domains = 0; | 3732 | dev->invalidate_domains = 0; |
3894 | dev->flush_domains = 0; | 3733 | dev->flush_domains = 0; |
3734 | dev_priv->flush_rings = 0; | ||
3895 | 3735 | ||
3896 | for (i = 0; i < args->buffer_count; i++) { | 3736 | for (i = 0; i < args->buffer_count; i++) { |
3897 | struct drm_gem_object *obj = object_list[i]; | 3737 | struct drm_gem_object *obj = object_list[i]; |
@@ -3912,16 +3752,14 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
3912 | i915_gem_flush(dev, | 3752 | i915_gem_flush(dev, |
3913 | dev->invalidate_domains, | 3753 | dev->invalidate_domains, |
3914 | dev->flush_domains); | 3754 | dev->flush_domains); |
3915 | if (dev->flush_domains & I915_GEM_GPU_DOMAINS) { | 3755 | if (dev_priv->flush_rings & FLUSH_RENDER_RING) |
3916 | (void)i915_add_request(dev, file_priv, | 3756 | (void)i915_add_request(dev, file_priv, |
3917 | dev->flush_domains, | 3757 | dev->flush_domains, |
3918 | &dev_priv->render_ring); | 3758 | &dev_priv->render_ring); |
3919 | 3759 | if (dev_priv->flush_rings & FLUSH_BSD_RING) | |
3920 | if (HAS_BSD(dev)) | 3760 | (void)i915_add_request(dev, file_priv, |
3921 | (void)i915_add_request(dev, file_priv, | 3761 | dev->flush_domains, |
3922 | dev->flush_domains, | 3762 | &dev_priv->bsd_ring); |
3923 | &dev_priv->bsd_ring); | ||
3924 | } | ||
3925 | } | 3763 | } |
3926 | 3764 | ||
3927 | for (i = 0; i < args->buffer_count; i++) { | 3765 | for (i = 0; i < args->buffer_count; i++) { |
@@ -4192,6 +4030,10 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
4192 | if (alignment == 0) | 4030 | if (alignment == 0) |
4193 | alignment = i915_gem_get_gtt_alignment(obj); | 4031 | alignment = i915_gem_get_gtt_alignment(obj); |
4194 | if (obj_priv->gtt_offset & (alignment - 1)) { | 4032 | if (obj_priv->gtt_offset & (alignment - 1)) { |
4033 | WARN(obj_priv->pin_count, | ||
4034 | "bo is already pinned with incorrect alignment:" | ||
4035 | " offset=%x, req.alignment=%x\n", | ||
4036 | obj_priv->gtt_offset, alignment); | ||
4195 | ret = i915_gem_object_unbind(obj); | 4037 | ret = i915_gem_object_unbind(obj); |
4196 | if (ret) | 4038 | if (ret) |
4197 | return ret; | 4039 | return ret; |
@@ -4213,8 +4055,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
4213 | atomic_inc(&dev->pin_count); | 4055 | atomic_inc(&dev->pin_count); |
4214 | atomic_add(obj->size, &dev->pin_memory); | 4056 | atomic_add(obj->size, &dev->pin_memory); |
4215 | if (!obj_priv->active && | 4057 | if (!obj_priv->active && |
4216 | (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0 && | 4058 | (obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) |
4217 | !list_empty(&obj_priv->list)) | ||
4218 | list_del_init(&obj_priv->list); | 4059 | list_del_init(&obj_priv->list); |
4219 | } | 4060 | } |
4220 | i915_verify_inactive(dev, __FILE__, __LINE__); | 4061 | i915_verify_inactive(dev, __FILE__, __LINE__); |
@@ -4359,22 +4200,34 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4359 | } | 4200 | } |
4360 | 4201 | ||
4361 | mutex_lock(&dev->struct_mutex); | 4202 | mutex_lock(&dev->struct_mutex); |
4362 | /* Update the active list for the hardware's current position. | ||
4363 | * Otherwise this only updates on a delayed timer or when irqs are | ||
4364 | * actually unmasked, and our working set ends up being larger than | ||
4365 | * required. | ||
4366 | */ | ||
4367 | i915_gem_retire_requests(dev); | ||
4368 | 4203 | ||
4369 | obj_priv = to_intel_bo(obj); | 4204 | /* Count all active objects as busy, even if they are currently not used |
4370 | /* Don't count being on the flushing list against the object being | 4205 | * by the gpu. Users of this interface expect objects to eventually |
4371 | * done. Otherwise, a buffer left on the flushing list but not getting | 4206 | * become non-busy without any further actions, therefore emit any |
4372 | * flushed (because nobody's flushing that domain) won't ever return | 4207 | * necessary flushes here. |
4373 | * unbusy and get reused by libdrm's bo cache. The other expected | ||
4374 | * consumer of this interface, OpenGL's occlusion queries, also specs | ||
4375 | * that the objects get unbusy "eventually" without any interference. | ||
4376 | */ | 4208 | */ |
4377 | args->busy = obj_priv->active && obj_priv->last_rendering_seqno != 0; | 4209 | obj_priv = to_intel_bo(obj); |
4210 | args->busy = obj_priv->active; | ||
4211 | if (args->busy) { | ||
4212 | /* Unconditionally flush objects, even when the gpu still uses this | ||
4213 | * object. Userspace calling this function indicates that it wants to | ||
4214 | * use this buffer rather sooner than later, so issuing the required | ||
4215 | * flush earlier is beneficial. | ||
4216 | */ | ||
4217 | if (obj->write_domain) { | ||
4218 | i915_gem_flush(dev, 0, obj->write_domain); | ||
4219 | (void)i915_add_request(dev, file_priv, obj->write_domain, obj_priv->ring); | ||
4220 | } | ||
4221 | |||
4222 | /* Update the active list for the hardware's current position. | ||
4223 | * Otherwise this only updates on a delayed timer or when irqs | ||
4224 | * are actually unmasked, and our working set ends up being | ||
4225 | * larger than required. | ||
4226 | */ | ||
4227 | i915_gem_retire_requests_ring(dev, obj_priv->ring); | ||
4228 | |||
4229 | args->busy = obj_priv->active; | ||
4230 | } | ||
4378 | 4231 | ||
4379 | drm_gem_object_unreference(obj); | 4232 | drm_gem_object_unreference(obj); |
4380 | mutex_unlock(&dev->struct_mutex); | 4233 | mutex_unlock(&dev->struct_mutex); |
@@ -4514,30 +4367,6 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
4514 | i915_gem_free_object_tail(obj); | 4367 | i915_gem_free_object_tail(obj); |
4515 | } | 4368 | } |
4516 | 4369 | ||
4517 | /** Unbinds all inactive objects. */ | ||
4518 | static int | ||
4519 | i915_gem_evict_from_inactive_list(struct drm_device *dev) | ||
4520 | { | ||
4521 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
4522 | |||
4523 | while (!list_empty(&dev_priv->mm.inactive_list)) { | ||
4524 | struct drm_gem_object *obj; | ||
4525 | int ret; | ||
4526 | |||
4527 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | ||
4528 | struct drm_i915_gem_object, | ||
4529 | list)->base; | ||
4530 | |||
4531 | ret = i915_gem_object_unbind(obj); | ||
4532 | if (ret != 0) { | ||
4533 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
4534 | return ret; | ||
4535 | } | ||
4536 | } | ||
4537 | |||
4538 | return 0; | ||
4539 | } | ||
4540 | |||
4541 | int | 4370 | int |
4542 | i915_gem_idle(struct drm_device *dev) | 4371 | i915_gem_idle(struct drm_device *dev) |
4543 | { | 4372 | { |
@@ -4562,7 +4391,7 @@ i915_gem_idle(struct drm_device *dev) | |||
4562 | 4391 | ||
4563 | /* Under UMS, be paranoid and evict. */ | 4392 | /* Under UMS, be paranoid and evict. */ |
4564 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { | 4393 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) { |
4565 | ret = i915_gem_evict_from_inactive_list(dev); | 4394 | ret = i915_gem_evict_inactive(dev); |
4566 | if (ret) { | 4395 | if (ret) { |
4567 | mutex_unlock(&dev->struct_mutex); | 4396 | mutex_unlock(&dev->struct_mutex); |
4568 | return ret; | 4397 | return ret; |
@@ -4680,6 +4509,8 @@ i915_gem_init_ringbuffer(struct drm_device *dev) | |||
4680 | goto cleanup_render_ring; | 4509 | goto cleanup_render_ring; |
4681 | } | 4510 | } |
4682 | 4511 | ||
4512 | dev_priv->next_seqno = 1; | ||
4513 | |||
4683 | return 0; | 4514 | return 0; |
4684 | 4515 | ||
4685 | cleanup_render_ring: | 4516 | cleanup_render_ring: |
@@ -4841,7 +4672,7 @@ i915_gem_load(struct drm_device *dev) | |||
4841 | * e.g. for cursor + overlay regs | 4672 | * e.g. for cursor + overlay regs |
4842 | */ | 4673 | */ |
4843 | int i915_gem_init_phys_object(struct drm_device *dev, | 4674 | int i915_gem_init_phys_object(struct drm_device *dev, |
4844 | int id, int size) | 4675 | int id, int size, int align) |
4845 | { | 4676 | { |
4846 | drm_i915_private_t *dev_priv = dev->dev_private; | 4677 | drm_i915_private_t *dev_priv = dev->dev_private; |
4847 | struct drm_i915_gem_phys_object *phys_obj; | 4678 | struct drm_i915_gem_phys_object *phys_obj; |
@@ -4856,7 +4687,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
4856 | 4687 | ||
4857 | phys_obj->id = id; | 4688 | phys_obj->id = id; |
4858 | 4689 | ||
4859 | phys_obj->handle = drm_pci_alloc(dev, size, 0); | 4690 | phys_obj->handle = drm_pci_alloc(dev, size, align); |
4860 | if (!phys_obj->handle) { | 4691 | if (!phys_obj->handle) { |
4861 | ret = -ENOMEM; | 4692 | ret = -ENOMEM; |
4862 | goto kfree_obj; | 4693 | goto kfree_obj; |
@@ -4938,7 +4769,9 @@ out: | |||
4938 | 4769 | ||
4939 | int | 4770 | int |
4940 | i915_gem_attach_phys_object(struct drm_device *dev, | 4771 | i915_gem_attach_phys_object(struct drm_device *dev, |
4941 | struct drm_gem_object *obj, int id) | 4772 | struct drm_gem_object *obj, |
4773 | int id, | ||
4774 | int align) | ||
4942 | { | 4775 | { |
4943 | drm_i915_private_t *dev_priv = dev->dev_private; | 4776 | drm_i915_private_t *dev_priv = dev->dev_private; |
4944 | struct drm_i915_gem_object *obj_priv; | 4777 | struct drm_i915_gem_object *obj_priv; |
@@ -4957,11 +4790,10 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
4957 | i915_gem_detach_phys_object(dev, obj); | 4790 | i915_gem_detach_phys_object(dev, obj); |
4958 | } | 4791 | } |
4959 | 4792 | ||
4960 | |||
4961 | /* create a new object */ | 4793 | /* create a new object */ |
4962 | if (!dev_priv->mm.phys_objs[id - 1]) { | 4794 | if (!dev_priv->mm.phys_objs[id - 1]) { |
4963 | ret = i915_gem_init_phys_object(dev, id, | 4795 | ret = i915_gem_init_phys_object(dev, id, |
4964 | obj->size); | 4796 | obj->size, align); |
4965 | if (ret) { | 4797 | if (ret) { |
4966 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); | 4798 | DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); |
4967 | goto out; | 4799 | goto out; |
diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c new file mode 100644 index 000000000000..72cae3cccad8 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_evict.c | |||
@@ -0,0 +1,271 @@ | |||
1 | /* | ||
2 | * Copyright © 2008-2010 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 | * Eric Anholt <eric@anholt.net> | ||
25 | * Chris Wilson <chris@chris-wilson.co.uuk> | ||
26 | * | ||
27 | */ | ||
28 | |||
29 | #include "drmP.h" | ||
30 | #include "drm.h" | ||
31 | #include "i915_drv.h" | ||
32 | #include "i915_drm.h" | ||
33 | |||
34 | static struct drm_i915_gem_object * | ||
35 | i915_gem_next_active_object(struct drm_device *dev, | ||
36 | struct list_head **render_iter, | ||
37 | struct list_head **bsd_iter) | ||
38 | { | ||
39 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
40 | struct drm_i915_gem_object *render_obj = NULL, *bsd_obj = NULL; | ||
41 | |||
42 | if (*render_iter != &dev_priv->render_ring.active_list) | ||
43 | render_obj = list_entry(*render_iter, | ||
44 | struct drm_i915_gem_object, | ||
45 | list); | ||
46 | |||
47 | if (HAS_BSD(dev)) { | ||
48 | if (*bsd_iter != &dev_priv->bsd_ring.active_list) | ||
49 | bsd_obj = list_entry(*bsd_iter, | ||
50 | struct drm_i915_gem_object, | ||
51 | list); | ||
52 | |||
53 | if (render_obj == NULL) { | ||
54 | *bsd_iter = (*bsd_iter)->next; | ||
55 | return bsd_obj; | ||
56 | } | ||
57 | |||
58 | if (bsd_obj == NULL) { | ||
59 | *render_iter = (*render_iter)->next; | ||
60 | return render_obj; | ||
61 | } | ||
62 | |||
63 | /* XXX can we handle seqno wrapping? */ | ||
64 | if (render_obj->last_rendering_seqno < bsd_obj->last_rendering_seqno) { | ||
65 | *render_iter = (*render_iter)->next; | ||
66 | return render_obj; | ||
67 | } else { | ||
68 | *bsd_iter = (*bsd_iter)->next; | ||
69 | return bsd_obj; | ||
70 | } | ||
71 | } else { | ||
72 | *render_iter = (*render_iter)->next; | ||
73 | return render_obj; | ||
74 | } | ||
75 | } | ||
76 | |||
77 | static bool | ||
78 | mark_free(struct drm_i915_gem_object *obj_priv, | ||
79 | struct list_head *unwind) | ||
80 | { | ||
81 | list_add(&obj_priv->evict_list, unwind); | ||
82 | return drm_mm_scan_add_block(obj_priv->gtt_space); | ||
83 | } | ||
84 | |||
85 | #define i915_for_each_active_object(OBJ, R, B) \ | ||
86 | *(R) = dev_priv->render_ring.active_list.next; \ | ||
87 | *(B) = dev_priv->bsd_ring.active_list.next; \ | ||
88 | while (((OBJ) = i915_gem_next_active_object(dev, (R), (B))) != NULL) | ||
89 | |||
90 | int | ||
91 | i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment) | ||
92 | { | ||
93 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
94 | struct list_head eviction_list, unwind_list; | ||
95 | struct drm_i915_gem_object *obj_priv, *tmp_obj_priv; | ||
96 | struct list_head *render_iter, *bsd_iter; | ||
97 | int ret = 0; | ||
98 | |||
99 | i915_gem_retire_requests(dev); | ||
100 | |||
101 | /* Re-check for free space after retiring requests */ | ||
102 | if (drm_mm_search_free(&dev_priv->mm.gtt_space, | ||
103 | min_size, alignment, 0)) | ||
104 | return 0; | ||
105 | |||
106 | /* | ||
107 | * The goal is to evict objects and amalgamate space in LRU order. | ||
108 | * The oldest idle objects reside on the inactive list, which is in | ||
109 | * retirement order. The next objects to retire are those on the (per | ||
110 | * ring) active list that do not have an outstanding flush. Once the | ||
111 | * hardware reports completion (the seqno is updated after the | ||
112 | * batchbuffer has been finished) the clean buffer objects would | ||
113 | * be retired to the inactive list. Any dirty objects would be added | ||
114 | * to the tail of the flushing list. So after processing the clean | ||
115 | * active objects we need to emit a MI_FLUSH to retire the flushing | ||
116 | * list, hence the retirement order of the flushing list is in | ||
117 | * advance of the dirty objects on the active lists. | ||
118 | * | ||
119 | * The retirement sequence is thus: | ||
120 | * 1. Inactive objects (already retired) | ||
121 | * 2. Clean active objects | ||
122 | * 3. Flushing list | ||
123 | * 4. Dirty active objects. | ||
124 | * | ||
125 | * On each list, the oldest objects lie at the HEAD with the freshest | ||
126 | * object on the TAIL. | ||
127 | */ | ||
128 | |||
129 | INIT_LIST_HEAD(&unwind_list); | ||
130 | drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); | ||
131 | |||
132 | /* First see if there is a large enough contiguous idle region... */ | ||
133 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
134 | if (mark_free(obj_priv, &unwind_list)) | ||
135 | goto found; | ||
136 | } | ||
137 | |||
138 | /* Now merge in the soon-to-be-expired objects... */ | ||
139 | i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) { | ||
140 | /* Does the object require an outstanding flush? */ | ||
141 | if (obj_priv->base.write_domain || obj_priv->pin_count) | ||
142 | continue; | ||
143 | |||
144 | if (mark_free(obj_priv, &unwind_list)) | ||
145 | goto found; | ||
146 | } | ||
147 | |||
148 | /* Finally add anything with a pending flush (in order of retirement) */ | ||
149 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
150 | if (obj_priv->pin_count) | ||
151 | continue; | ||
152 | |||
153 | if (mark_free(obj_priv, &unwind_list)) | ||
154 | goto found; | ||
155 | } | ||
156 | i915_for_each_active_object(obj_priv, &render_iter, &bsd_iter) { | ||
157 | if (! obj_priv->base.write_domain || obj_priv->pin_count) | ||
158 | continue; | ||
159 | |||
160 | if (mark_free(obj_priv, &unwind_list)) | ||
161 | goto found; | ||
162 | } | ||
163 | |||
164 | /* Nothing found, clean up and bail out! */ | ||
165 | list_for_each_entry(obj_priv, &unwind_list, evict_list) { | ||
166 | ret = drm_mm_scan_remove_block(obj_priv->gtt_space); | ||
167 | BUG_ON(ret); | ||
168 | } | ||
169 | |||
170 | /* We expect the caller to unpin, evict all and try again, or give up. | ||
171 | * So calling i915_gem_evict_everything() is unnecessary. | ||
172 | */ | ||
173 | return -ENOSPC; | ||
174 | |||
175 | found: | ||
176 | INIT_LIST_HEAD(&eviction_list); | ||
177 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | ||
178 | &unwind_list, evict_list) { | ||
179 | if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { | ||
180 | /* drm_mm doesn't allow any other other operations while | ||
181 | * scanning, therefore store to be evicted objects on a | ||
182 | * temporary list. */ | ||
183 | list_move(&obj_priv->evict_list, &eviction_list); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | /* Unbinding will emit any required flushes */ | ||
188 | list_for_each_entry_safe(obj_priv, tmp_obj_priv, | ||
189 | &eviction_list, evict_list) { | ||
190 | #if WATCH_LRU | ||
191 | DRM_INFO("%s: evicting %p\n", __func__, obj); | ||
192 | #endif | ||
193 | ret = i915_gem_object_unbind(&obj_priv->base); | ||
194 | if (ret) | ||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | /* The just created free hole should be on the top of the free stack | ||
199 | * maintained by drm_mm, so this BUG_ON actually executes in O(1). | ||
200 | * Furthermore all accessed data has just recently been used, so it | ||
201 | * should be really fast, too. */ | ||
202 | BUG_ON(!drm_mm_search_free(&dev_priv->mm.gtt_space, min_size, | ||
203 | alignment, 0)); | ||
204 | |||
205 | return 0; | ||
206 | } | ||
207 | |||
208 | int | ||
209 | i915_gem_evict_everything(struct drm_device *dev) | ||
210 | { | ||
211 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
212 | int ret; | ||
213 | bool lists_empty; | ||
214 | |||
215 | spin_lock(&dev_priv->mm.active_list_lock); | ||
216 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
217 | list_empty(&dev_priv->mm.flushing_list) && | ||
218 | list_empty(&dev_priv->render_ring.active_list) && | ||
219 | (!HAS_BSD(dev) | ||
220 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
221 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
222 | |||
223 | if (lists_empty) | ||
224 | return -ENOSPC; | ||
225 | |||
226 | /* Flush everything (on to the inactive lists) and evict */ | ||
227 | ret = i915_gpu_idle(dev); | ||
228 | if (ret) | ||
229 | return ret; | ||
230 | |||
231 | BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); | ||
232 | |||
233 | ret = i915_gem_evict_inactive(dev); | ||
234 | if (ret) | ||
235 | return ret; | ||
236 | |||
237 | spin_lock(&dev_priv->mm.active_list_lock); | ||
238 | lists_empty = (list_empty(&dev_priv->mm.inactive_list) && | ||
239 | list_empty(&dev_priv->mm.flushing_list) && | ||
240 | list_empty(&dev_priv->render_ring.active_list) && | ||
241 | (!HAS_BSD(dev) | ||
242 | || list_empty(&dev_priv->bsd_ring.active_list))); | ||
243 | spin_unlock(&dev_priv->mm.active_list_lock); | ||
244 | BUG_ON(!lists_empty); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | /** Unbinds all inactive objects. */ | ||
250 | int | ||
251 | i915_gem_evict_inactive(struct drm_device *dev) | ||
252 | { | ||
253 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
254 | |||
255 | while (!list_empty(&dev_priv->mm.inactive_list)) { | ||
256 | struct drm_gem_object *obj; | ||
257 | int ret; | ||
258 | |||
259 | obj = &list_first_entry(&dev_priv->mm.inactive_list, | ||
260 | struct drm_i915_gem_object, | ||
261 | list)->base; | ||
262 | |||
263 | ret = i915_gem_object_unbind(obj); | ||
264 | if (ret != 0) { | ||
265 | DRM_ERROR("Error unbinding object: %d\n", ret); | ||
266 | return ret; | ||
267 | } | ||
268 | } | ||
269 | |||
270 | return 0; | ||
271 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 85785a8844ed..16861b800fee 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -425,9 +425,11 @@ static struct drm_i915_error_object * | |||
425 | i915_error_object_create(struct drm_device *dev, | 425 | i915_error_object_create(struct drm_device *dev, |
426 | struct drm_gem_object *src) | 426 | struct drm_gem_object *src) |
427 | { | 427 | { |
428 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
428 | struct drm_i915_error_object *dst; | 429 | struct drm_i915_error_object *dst; |
429 | struct drm_i915_gem_object *src_priv; | 430 | struct drm_i915_gem_object *src_priv; |
430 | int page, page_count; | 431 | int page, page_count; |
432 | u32 reloc_offset; | ||
431 | 433 | ||
432 | if (src == NULL) | 434 | if (src == NULL) |
433 | return NULL; | 435 | return NULL; |
@@ -442,18 +444,27 @@ i915_error_object_create(struct drm_device *dev, | |||
442 | if (dst == NULL) | 444 | if (dst == NULL) |
443 | return NULL; | 445 | return NULL; |
444 | 446 | ||
447 | reloc_offset = src_priv->gtt_offset; | ||
445 | for (page = 0; page < page_count; page++) { | 448 | for (page = 0; page < page_count; page++) { |
446 | void *s, *d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | ||
447 | unsigned long flags; | 449 | unsigned long flags; |
450 | void __iomem *s; | ||
451 | void *d; | ||
448 | 452 | ||
453 | d = kmalloc(PAGE_SIZE, GFP_ATOMIC); | ||
449 | if (d == NULL) | 454 | if (d == NULL) |
450 | goto unwind; | 455 | goto unwind; |
456 | |||
451 | local_irq_save(flags); | 457 | local_irq_save(flags); |
452 | s = kmap_atomic(src_priv->pages[page], KM_IRQ0); | 458 | s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, |
453 | memcpy(d, s, PAGE_SIZE); | 459 | reloc_offset, |
454 | kunmap_atomic(s, KM_IRQ0); | 460 | KM_IRQ0); |
461 | memcpy_fromio(d, s, PAGE_SIZE); | ||
462 | io_mapping_unmap_atomic(s, KM_IRQ0); | ||
455 | local_irq_restore(flags); | 463 | local_irq_restore(flags); |
464 | |||
456 | dst->pages[page] = d; | 465 | dst->pages[page] = d; |
466 | |||
467 | reloc_offset += PAGE_SIZE; | ||
457 | } | 468 | } |
458 | dst->page_count = page_count; | 469 | dst->page_count = page_count; |
459 | dst->gtt_offset = src_priv->gtt_offset; | 470 | dst->gtt_offset = src_priv->gtt_offset; |
@@ -489,6 +500,7 @@ i915_error_state_free(struct drm_device *dev, | |||
489 | i915_error_object_free(error->batchbuffer[1]); | 500 | i915_error_object_free(error->batchbuffer[1]); |
490 | i915_error_object_free(error->ringbuffer); | 501 | i915_error_object_free(error->ringbuffer); |
491 | kfree(error->active_bo); | 502 | kfree(error->active_bo); |
503 | kfree(error->overlay); | ||
492 | kfree(error); | 504 | kfree(error); |
493 | } | 505 | } |
494 | 506 | ||
@@ -612,18 +624,57 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
612 | 624 | ||
613 | if (batchbuffer[1] == NULL && | 625 | if (batchbuffer[1] == NULL && |
614 | error->acthd >= obj_priv->gtt_offset && | 626 | error->acthd >= obj_priv->gtt_offset && |
615 | error->acthd < obj_priv->gtt_offset + obj->size && | 627 | error->acthd < obj_priv->gtt_offset + obj->size) |
616 | batchbuffer[0] != obj) | ||
617 | batchbuffer[1] = obj; | 628 | batchbuffer[1] = obj; |
618 | 629 | ||
619 | count++; | 630 | count++; |
620 | } | 631 | } |
632 | /* Scan the other lists for completeness for those bizarre errors. */ | ||
633 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
634 | list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, list) { | ||
635 | struct drm_gem_object *obj = &obj_priv->base; | ||
636 | |||
637 | if (batchbuffer[0] == NULL && | ||
638 | bbaddr >= obj_priv->gtt_offset && | ||
639 | bbaddr < obj_priv->gtt_offset + obj->size) | ||
640 | batchbuffer[0] = obj; | ||
641 | |||
642 | if (batchbuffer[1] == NULL && | ||
643 | error->acthd >= obj_priv->gtt_offset && | ||
644 | error->acthd < obj_priv->gtt_offset + obj->size) | ||
645 | batchbuffer[1] = obj; | ||
646 | |||
647 | if (batchbuffer[0] && batchbuffer[1]) | ||
648 | break; | ||
649 | } | ||
650 | } | ||
651 | if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { | ||
652 | list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) { | ||
653 | struct drm_gem_object *obj = &obj_priv->base; | ||
654 | |||
655 | if (batchbuffer[0] == NULL && | ||
656 | bbaddr >= obj_priv->gtt_offset && | ||
657 | bbaddr < obj_priv->gtt_offset + obj->size) | ||
658 | batchbuffer[0] = obj; | ||
659 | |||
660 | if (batchbuffer[1] == NULL && | ||
661 | error->acthd >= obj_priv->gtt_offset && | ||
662 | error->acthd < obj_priv->gtt_offset + obj->size) | ||
663 | batchbuffer[1] = obj; | ||
664 | |||
665 | if (batchbuffer[0] && batchbuffer[1]) | ||
666 | break; | ||
667 | } | ||
668 | } | ||
621 | 669 | ||
622 | /* We need to copy these to an anonymous buffer as the simplest | 670 | /* We need to copy these to an anonymous buffer as the simplest |
623 | * method to avoid being overwritten by userpace. | 671 | * method to avoid being overwritten by userpace. |
624 | */ | 672 | */ |
625 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); | 673 | error->batchbuffer[0] = i915_error_object_create(dev, batchbuffer[0]); |
626 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | 674 | if (batchbuffer[1] != batchbuffer[0]) |
675 | error->batchbuffer[1] = i915_error_object_create(dev, batchbuffer[1]); | ||
676 | else | ||
677 | error->batchbuffer[1] = NULL; | ||
627 | 678 | ||
628 | /* Record the ringbuffer */ | 679 | /* Record the ringbuffer */ |
629 | error->ringbuffer = i915_error_object_create(dev, | 680 | error->ringbuffer = i915_error_object_create(dev, |
@@ -667,6 +718,8 @@ static void i915_capture_error_state(struct drm_device *dev) | |||
667 | 718 | ||
668 | do_gettimeofday(&error->time); | 719 | do_gettimeofday(&error->time); |
669 | 720 | ||
721 | error->overlay = intel_overlay_capture_error_state(dev); | ||
722 | |||
670 | spin_lock_irqsave(&dev_priv->error_lock, flags); | 723 | spin_lock_irqsave(&dev_priv->error_lock, flags); |
671 | if (dev_priv->first_error == NULL) { | 724 | if (dev_priv->first_error == NULL) { |
672 | dev_priv->first_error = error; | 725 | dev_priv->first_error = error; |
@@ -1251,6 +1304,16 @@ void i915_hangcheck_elapsed(unsigned long data) | |||
1251 | &dev_priv->render_ring), | 1304 | &dev_priv->render_ring), |
1252 | i915_get_tail_request(dev)->seqno)) { | 1305 | i915_get_tail_request(dev)->seqno)) { |
1253 | dev_priv->hangcheck_count = 0; | 1306 | dev_priv->hangcheck_count = 0; |
1307 | |||
1308 | /* Issue a wake-up to catch stuck h/w. */ | ||
1309 | if (dev_priv->render_ring.waiting_gem_seqno | | ||
1310 | dev_priv->bsd_ring.waiting_gem_seqno) { | ||
1311 | DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); | ||
1312 | if (dev_priv->render_ring.waiting_gem_seqno) | ||
1313 | DRM_WAKEUP(&dev_priv->render_ring.irq_queue); | ||
1314 | if (dev_priv->bsd_ring.waiting_gem_seqno) | ||
1315 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | ||
1316 | } | ||
1254 | return; | 1317 | return; |
1255 | } | 1318 | } |
1256 | 1319 | ||
@@ -1318,12 +1381,17 @@ static int ironlake_irq_postinstall(struct drm_device *dev) | |||
1318 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); | 1381 | I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); |
1319 | (void) I915_READ(DEIER); | 1382 | (void) I915_READ(DEIER); |
1320 | 1383 | ||
1321 | /* user interrupt should be enabled, but masked initial */ | 1384 | /* Gen6 only needs render pipe_control now */ |
1385 | if (IS_GEN6(dev)) | ||
1386 | render_mask = GT_PIPE_NOTIFY; | ||
1387 | |||
1322 | dev_priv->gt_irq_mask_reg = ~render_mask; | 1388 | dev_priv->gt_irq_mask_reg = ~render_mask; |
1323 | dev_priv->gt_irq_enable_reg = render_mask; | 1389 | dev_priv->gt_irq_enable_reg = render_mask; |
1324 | 1390 | ||
1325 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 1391 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
1326 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); | 1392 | I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); |
1393 | if (IS_GEN6(dev)) | ||
1394 | I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT); | ||
1327 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); | 1395 | I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); |
1328 | (void) I915_READ(GTIER); | 1396 | (void) I915_READ(GTIER); |
1329 | 1397 | ||
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index d1bf92b99788..ea5d3fea4b61 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
@@ -114,10 +114,6 @@ struct opregion_asle { | |||
114 | #define ASLE_REQ_MSK 0xf | 114 | #define ASLE_REQ_MSK 0xf |
115 | 115 | ||
116 | /* response bits of ASLE irq request */ | 116 | /* response bits of ASLE irq request */ |
117 | #define ASLE_ALS_ILLUM_FAIL (2<<10) | ||
118 | #define ASLE_BACKLIGHT_FAIL (2<<12) | ||
119 | #define ASLE_PFIT_FAIL (2<<14) | ||
120 | #define ASLE_PWM_FREQ_FAIL (2<<16) | ||
121 | #define ASLE_ALS_ILLUM_FAILED (1<<10) | 117 | #define ASLE_ALS_ILLUM_FAILED (1<<10) |
122 | #define ASLE_BACKLIGHT_FAILED (1<<12) | 118 | #define ASLE_BACKLIGHT_FAILED (1<<12) |
123 | #define ASLE_PFIT_FAILED (1<<14) | 119 | #define ASLE_PFIT_FAILED (1<<14) |
@@ -155,11 +151,11 @@ static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) | |||
155 | u32 max_backlight, level, shift; | 151 | u32 max_backlight, level, shift; |
156 | 152 | ||
157 | if (!(bclp & ASLE_BCLP_VALID)) | 153 | if (!(bclp & ASLE_BCLP_VALID)) |
158 | return ASLE_BACKLIGHT_FAIL; | 154 | return ASLE_BACKLIGHT_FAILED; |
159 | 155 | ||
160 | bclp &= ASLE_BCLP_MSK; | 156 | bclp &= ASLE_BCLP_MSK; |
161 | if (bclp < 0 || bclp > 255) | 157 | if (bclp < 0 || bclp > 255) |
162 | return ASLE_BACKLIGHT_FAIL; | 158 | return ASLE_BACKLIGHT_FAILED; |
163 | 159 | ||
164 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); | 160 | blc_pwm_ctl = I915_READ(BLC_PWM_CTL); |
165 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); | 161 | blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2); |
@@ -211,7 +207,7 @@ static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) | |||
211 | /* Panel fitting is currently controlled by the X code, so this is a | 207 | /* Panel fitting is currently controlled by the X code, so this is a |
212 | noop until modesetting support works fully */ | 208 | noop until modesetting support works fully */ |
213 | if (!(pfit & ASLE_PFIT_VALID)) | 209 | if (!(pfit & ASLE_PFIT_VALID)) |
214 | return ASLE_PFIT_FAIL; | 210 | return ASLE_PFIT_FAILED; |
215 | return 0; | 211 | return 0; |
216 | } | 212 | } |
217 | 213 | ||
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 281db6e5403a..67e3ec1a6af9 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -170,6 +170,7 @@ | |||
170 | #define MI_NO_WRITE_FLUSH (1 << 2) | 170 | #define MI_NO_WRITE_FLUSH (1 << 2) |
171 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ | 171 | #define MI_SCENE_COUNT (1 << 3) /* just increment scene count */ |
172 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ | 172 | #define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */ |
173 | #define MI_INVALIDATE_ISP (1 << 5) /* invalidate indirect state pointers */ | ||
173 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) | 174 | #define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0) |
174 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) | 175 | #define MI_REPORT_HEAD MI_INSTR(0x07, 0) |
175 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) | 176 | #define MI_OVERLAY_FLIP MI_INSTR(0x11,0) |
@@ -180,6 +181,12 @@ | |||
180 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) | 181 | #define MI_DISPLAY_FLIP MI_INSTR(0x14, 2) |
181 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) | 182 | #define MI_DISPLAY_FLIP_I915 MI_INSTR(0x14, 1) |
182 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) | 183 | #define MI_DISPLAY_FLIP_PLANE(n) ((n) << 20) |
184 | #define MI_SET_CONTEXT MI_INSTR(0x18, 0) | ||
185 | #define MI_MM_SPACE_GTT (1<<8) | ||
186 | #define MI_MM_SPACE_PHYSICAL (0<<8) | ||
187 | #define MI_SAVE_EXT_STATE_EN (1<<3) | ||
188 | #define MI_RESTORE_EXT_STATE_EN (1<<2) | ||
189 | #define MI_RESTORE_INHIBIT (1<<0) | ||
183 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) | 190 | #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) |
184 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ | 191 | #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ |
185 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) | 192 | #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) |
@@ -1100,6 +1107,11 @@ | |||
1100 | #define PEG_BAND_GAP_DATA 0x14d68 | 1107 | #define PEG_BAND_GAP_DATA 0x14d68 |
1101 | 1108 | ||
1102 | /* | 1109 | /* |
1110 | * Logical Context regs | ||
1111 | */ | ||
1112 | #define CCID 0x2180 | ||
1113 | #define CCID_EN (1<<0) | ||
1114 | /* | ||
1103 | * Overlay regs | 1115 | * Overlay regs |
1104 | */ | 1116 | */ |
1105 | 1117 | ||
@@ -2069,6 +2081,7 @@ | |||
2069 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) | 2081 | #define PIPE_DITHER_TYPE_ST01 (1 << 2) |
2070 | /* Pipe A */ | 2082 | /* Pipe A */ |
2071 | #define PIPEADSL 0x70000 | 2083 | #define PIPEADSL 0x70000 |
2084 | #define DSL_LINEMASK 0x00000fff | ||
2072 | #define PIPEACONF 0x70008 | 2085 | #define PIPEACONF 0x70008 |
2073 | #define PIPEACONF_ENABLE (1<<31) | 2086 | #define PIPEACONF_ENABLE (1<<31) |
2074 | #define PIPEACONF_DISABLE 0 | 2087 | #define PIPEACONF_DISABLE 0 |
@@ -2928,6 +2941,7 @@ | |||
2928 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | 2941 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 |
2929 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | 2942 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) |
2930 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 | 2943 | #define TRANS_DP_HSYNC_ACTIVE_LOW 0 |
2944 | #define TRANS_DP_SYNC_MASK (3<<3) | ||
2931 | 2945 | ||
2932 | /* SNB eDP training params */ | 2946 | /* SNB eDP training params */ |
2933 | /* SNB A-stepping */ | 2947 | /* SNB A-stepping */ |
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 6e2025274db5..2c6b98f2440e 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -34,7 +34,7 @@ static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe) | |||
34 | struct drm_i915_private *dev_priv = dev->dev_private; | 34 | struct drm_i915_private *dev_priv = dev->dev_private; |
35 | u32 dpll_reg; | 35 | u32 dpll_reg; |
36 | 36 | ||
37 | if (IS_IRONLAKE(dev)) { | 37 | if (HAS_PCH_SPLIT(dev)) { |
38 | dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; | 38 | dpll_reg = (pipe == PIPE_A) ? PCH_DPLL_A: PCH_DPLL_B; |
39 | } else { | 39 | } else { |
40 | dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; | 40 | dpll_reg = (pipe == PIPE_A) ? DPLL_A: DPLL_B; |
@@ -53,7 +53,7 @@ static void i915_save_palette(struct drm_device *dev, enum pipe pipe) | |||
53 | if (!i915_pipe_enabled(dev, pipe)) | 53 | if (!i915_pipe_enabled(dev, pipe)) |
54 | return; | 54 | return; |
55 | 55 | ||
56 | if (IS_IRONLAKE(dev)) | 56 | if (HAS_PCH_SPLIT(dev)) |
57 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; | 57 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; |
58 | 58 | ||
59 | if (pipe == PIPE_A) | 59 | if (pipe == PIPE_A) |
@@ -75,7 +75,7 @@ static void i915_restore_palette(struct drm_device *dev, enum pipe pipe) | |||
75 | if (!i915_pipe_enabled(dev, pipe)) | 75 | if (!i915_pipe_enabled(dev, pipe)) |
76 | return; | 76 | return; |
77 | 77 | ||
78 | if (IS_IRONLAKE(dev)) | 78 | if (HAS_PCH_SPLIT(dev)) |
79 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; | 79 | reg = (pipe == PIPE_A) ? LGC_PALETTE_A : LGC_PALETTE_B; |
80 | 80 | ||
81 | if (pipe == PIPE_A) | 81 | if (pipe == PIPE_A) |
@@ -239,7 +239,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
240 | return; | 240 | return; |
241 | 241 | ||
242 | if (IS_IRONLAKE(dev)) { | 242 | if (HAS_PCH_SPLIT(dev)) { |
243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); | 243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); |
244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); | 244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); |
245 | } | 245 | } |
@@ -247,7 +247,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
247 | /* Pipe & plane A info */ | 247 | /* Pipe & plane A info */ |
248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
250 | if (IS_IRONLAKE(dev)) { | 250 | if (HAS_PCH_SPLIT(dev)) { |
251 | dev_priv->saveFPA0 = I915_READ(PCH_FPA0); | 251 | dev_priv->saveFPA0 = I915_READ(PCH_FPA0); |
252 | dev_priv->saveFPA1 = I915_READ(PCH_FPA1); | 252 | dev_priv->saveFPA1 = I915_READ(PCH_FPA1); |
253 | dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); | 253 | dev_priv->saveDPLL_A = I915_READ(PCH_DPLL_A); |
@@ -256,7 +256,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
256 | dev_priv->saveFPA1 = I915_READ(FPA1); | 256 | dev_priv->saveFPA1 = I915_READ(FPA1); |
257 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); | 257 | dev_priv->saveDPLL_A = I915_READ(DPLL_A); |
258 | } | 258 | } |
259 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 259 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
260 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); | 260 | dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD); |
261 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); | 261 | dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A); |
262 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); | 262 | dev_priv->saveHBLANK_A = I915_READ(HBLANK_A); |
@@ -264,10 +264,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
264 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); | 264 | dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A); |
265 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); | 265 | dev_priv->saveVBLANK_A = I915_READ(VBLANK_A); |
266 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); | 266 | dev_priv->saveVSYNC_A = I915_READ(VSYNC_A); |
267 | if (!IS_IRONLAKE(dev)) | 267 | if (!HAS_PCH_SPLIT(dev)) |
268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | 268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); |
269 | 269 | ||
270 | if (IS_IRONLAKE(dev)) { | 270 | if (HAS_PCH_SPLIT(dev)) { |
271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); | 271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); |
272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); | 272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); |
273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); | 273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); |
@@ -304,7 +304,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
304 | /* Pipe & plane B info */ | 304 | /* Pipe & plane B info */ |
305 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); | 305 | dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF); |
306 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); | 306 | dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC); |
307 | if (IS_IRONLAKE(dev)) { | 307 | if (HAS_PCH_SPLIT(dev)) { |
308 | dev_priv->saveFPB0 = I915_READ(PCH_FPB0); | 308 | dev_priv->saveFPB0 = I915_READ(PCH_FPB0); |
309 | dev_priv->saveFPB1 = I915_READ(PCH_FPB1); | 309 | dev_priv->saveFPB1 = I915_READ(PCH_FPB1); |
310 | dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); | 310 | dev_priv->saveDPLL_B = I915_READ(PCH_DPLL_B); |
@@ -313,7 +313,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
313 | dev_priv->saveFPB1 = I915_READ(FPB1); | 313 | dev_priv->saveFPB1 = I915_READ(FPB1); |
314 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); | 314 | dev_priv->saveDPLL_B = I915_READ(DPLL_B); |
315 | } | 315 | } |
316 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 316 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
317 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); | 317 | dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD); |
318 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); | 318 | dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B); |
319 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); | 319 | dev_priv->saveHBLANK_B = I915_READ(HBLANK_B); |
@@ -321,10 +321,10 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
321 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); | 321 | dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B); |
322 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); | 322 | dev_priv->saveVBLANK_B = I915_READ(VBLANK_B); |
323 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); | 323 | dev_priv->saveVSYNC_B = I915_READ(VSYNC_B); |
324 | if (!IS_IRONLAKE(dev)) | 324 | if (!HAS_PCH_SPLIT(dev)) |
325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); | 325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); |
326 | 326 | ||
327 | if (IS_IRONLAKE(dev)) { | 327 | if (HAS_PCH_SPLIT(dev)) { |
328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); | 328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); |
329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); | 329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); |
330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); | 330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); |
@@ -369,7 +369,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 369 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
370 | return; | 370 | return; |
371 | 371 | ||
372 | if (IS_IRONLAKE(dev)) { | 372 | if (HAS_PCH_SPLIT(dev)) { |
373 | dpll_a_reg = PCH_DPLL_A; | 373 | dpll_a_reg = PCH_DPLL_A; |
374 | dpll_b_reg = PCH_DPLL_B; | 374 | dpll_b_reg = PCH_DPLL_B; |
375 | fpa0_reg = PCH_FPA0; | 375 | fpa0_reg = PCH_FPA0; |
@@ -385,7 +385,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
385 | fpb1_reg = FPB1; | 385 | fpb1_reg = FPB1; |
386 | } | 386 | } |
387 | 387 | ||
388 | if (IS_IRONLAKE(dev)) { | 388 | if (HAS_PCH_SPLIT(dev)) { |
389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); | 389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); |
390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); | 390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); |
391 | } | 391 | } |
@@ -395,16 +395,20 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { |
396 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & | 396 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A & |
397 | ~DPLL_VCO_ENABLE); | 397 | ~DPLL_VCO_ENABLE); |
398 | DRM_UDELAY(150); | 398 | POSTING_READ(dpll_a_reg); |
399 | udelay(150); | ||
399 | } | 400 | } |
400 | I915_WRITE(fpa0_reg, dev_priv->saveFPA0); | 401 | I915_WRITE(fpa0_reg, dev_priv->saveFPA0); |
401 | I915_WRITE(fpa1_reg, dev_priv->saveFPA1); | 402 | I915_WRITE(fpa1_reg, dev_priv->saveFPA1); |
402 | /* Actually enable it */ | 403 | /* Actually enable it */ |
403 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); | 404 | I915_WRITE(dpll_a_reg, dev_priv->saveDPLL_A); |
404 | DRM_UDELAY(150); | 405 | POSTING_READ(dpll_a_reg); |
405 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 406 | udelay(150); |
407 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | ||
406 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); | 408 | I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD); |
407 | DRM_UDELAY(150); | 409 | POSTING_READ(DPLL_A_MD); |
410 | } | ||
411 | udelay(150); | ||
408 | 412 | ||
409 | /* Restore mode */ | 413 | /* Restore mode */ |
410 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); | 414 | I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A); |
@@ -413,10 +417,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
413 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); | 417 | I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A); |
414 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); | 418 | I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A); |
415 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); | 419 | I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A); |
416 | if (!IS_IRONLAKE(dev)) | 420 | if (!HAS_PCH_SPLIT(dev)) |
417 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | 421 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); |
418 | 422 | ||
419 | if (IS_IRONLAKE(dev)) { | 423 | if (HAS_PCH_SPLIT(dev)) { |
420 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); | 424 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); |
421 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); | 425 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); |
422 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); | 426 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); |
@@ -460,16 +464,20 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
460 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { | 464 | if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) { |
461 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & | 465 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B & |
462 | ~DPLL_VCO_ENABLE); | 466 | ~DPLL_VCO_ENABLE); |
463 | DRM_UDELAY(150); | 467 | POSTING_READ(dpll_b_reg); |
468 | udelay(150); | ||
464 | } | 469 | } |
465 | I915_WRITE(fpb0_reg, dev_priv->saveFPB0); | 470 | I915_WRITE(fpb0_reg, dev_priv->saveFPB0); |
466 | I915_WRITE(fpb1_reg, dev_priv->saveFPB1); | 471 | I915_WRITE(fpb1_reg, dev_priv->saveFPB1); |
467 | /* Actually enable it */ | 472 | /* Actually enable it */ |
468 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); | 473 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); |
469 | DRM_UDELAY(150); | 474 | POSTING_READ(dpll_b_reg); |
470 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 475 | udelay(150); |
476 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) { | ||
471 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | 477 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); |
472 | DRM_UDELAY(150); | 478 | POSTING_READ(DPLL_B_MD); |
479 | } | ||
480 | udelay(150); | ||
473 | 481 | ||
474 | /* Restore mode */ | 482 | /* Restore mode */ |
475 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); | 483 | I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B); |
@@ -478,10 +486,10 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
478 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); | 486 | I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B); |
479 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); | 487 | I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B); |
480 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); | 488 | I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B); |
481 | if (!IS_IRONLAKE(dev)) | 489 | if (!HAS_PCH_SPLIT(dev)) |
482 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | 490 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); |
483 | 491 | ||
484 | if (IS_IRONLAKE(dev)) { | 492 | if (HAS_PCH_SPLIT(dev)) { |
485 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); | 493 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); |
486 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); | 494 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); |
487 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); | 495 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); |
@@ -546,14 +554,14 @@ void i915_save_display(struct drm_device *dev) | |||
546 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); | 554 | dev_priv->saveCURSIZE = I915_READ(CURSIZE); |
547 | 555 | ||
548 | /* CRT state */ | 556 | /* CRT state */ |
549 | if (IS_IRONLAKE(dev)) { | 557 | if (HAS_PCH_SPLIT(dev)) { |
550 | dev_priv->saveADPA = I915_READ(PCH_ADPA); | 558 | dev_priv->saveADPA = I915_READ(PCH_ADPA); |
551 | } else { | 559 | } else { |
552 | dev_priv->saveADPA = I915_READ(ADPA); | 560 | dev_priv->saveADPA = I915_READ(ADPA); |
553 | } | 561 | } |
554 | 562 | ||
555 | /* LVDS state */ | 563 | /* LVDS state */ |
556 | if (IS_IRONLAKE(dev)) { | 564 | if (HAS_PCH_SPLIT(dev)) { |
557 | dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); | 565 | dev_priv->savePP_CONTROL = I915_READ(PCH_PP_CONTROL); |
558 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); | 566 | dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_PCH_CTL1); |
559 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); | 567 | dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_PCH_CTL2); |
@@ -571,10 +579,10 @@ void i915_save_display(struct drm_device *dev) | |||
571 | dev_priv->saveLVDS = I915_READ(LVDS); | 579 | dev_priv->saveLVDS = I915_READ(LVDS); |
572 | } | 580 | } |
573 | 581 | ||
574 | if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev)) | 582 | if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) |
575 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); | 583 | dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL); |
576 | 584 | ||
577 | if (IS_IRONLAKE(dev)) { | 585 | if (HAS_PCH_SPLIT(dev)) { |
578 | dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); | 586 | dev_priv->savePP_ON_DELAYS = I915_READ(PCH_PP_ON_DELAYS); |
579 | dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); | 587 | dev_priv->savePP_OFF_DELAYS = I915_READ(PCH_PP_OFF_DELAYS); |
580 | dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); | 588 | dev_priv->savePP_DIVISOR = I915_READ(PCH_PP_DIVISOR); |
@@ -602,7 +610,7 @@ void i915_save_display(struct drm_device *dev) | |||
602 | 610 | ||
603 | /* Only save FBC state on the platform that supports FBC */ | 611 | /* Only save FBC state on the platform that supports FBC */ |
604 | if (I915_HAS_FBC(dev)) { | 612 | if (I915_HAS_FBC(dev)) { |
605 | if (IS_IRONLAKE_M(dev)) { | 613 | if (HAS_PCH_SPLIT(dev)) { |
606 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); | 614 | dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE); |
607 | } else if (IS_GM45(dev)) { | 615 | } else if (IS_GM45(dev)) { |
608 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); | 616 | dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE); |
@@ -618,7 +626,7 @@ void i915_save_display(struct drm_device *dev) | |||
618 | dev_priv->saveVGA0 = I915_READ(VGA0); | 626 | dev_priv->saveVGA0 = I915_READ(VGA0); |
619 | dev_priv->saveVGA1 = I915_READ(VGA1); | 627 | dev_priv->saveVGA1 = I915_READ(VGA1); |
620 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); | 628 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); |
621 | if (IS_IRONLAKE(dev)) | 629 | if (HAS_PCH_SPLIT(dev)) |
622 | dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); | 630 | dev_priv->saveVGACNTRL = I915_READ(CPU_VGACNTRL); |
623 | else | 631 | else |
624 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | 632 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); |
@@ -660,24 +668,24 @@ void i915_restore_display(struct drm_device *dev) | |||
660 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); | 668 | I915_WRITE(CURSIZE, dev_priv->saveCURSIZE); |
661 | 669 | ||
662 | /* CRT state */ | 670 | /* CRT state */ |
663 | if (IS_IRONLAKE(dev)) | 671 | if (HAS_PCH_SPLIT(dev)) |
664 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); | 672 | I915_WRITE(PCH_ADPA, dev_priv->saveADPA); |
665 | else | 673 | else |
666 | I915_WRITE(ADPA, dev_priv->saveADPA); | 674 | I915_WRITE(ADPA, dev_priv->saveADPA); |
667 | 675 | ||
668 | /* LVDS state */ | 676 | /* LVDS state */ |
669 | if (IS_I965G(dev) && !IS_IRONLAKE(dev)) | 677 | if (IS_I965G(dev) && !HAS_PCH_SPLIT(dev)) |
670 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); | 678 | I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2); |
671 | 679 | ||
672 | if (IS_IRONLAKE(dev)) { | 680 | if (HAS_PCH_SPLIT(dev)) { |
673 | I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); | 681 | I915_WRITE(PCH_LVDS, dev_priv->saveLVDS); |
674 | } else if (IS_MOBILE(dev) && !IS_I830(dev)) | 682 | } else if (IS_MOBILE(dev) && !IS_I830(dev)) |
675 | I915_WRITE(LVDS, dev_priv->saveLVDS); | 683 | I915_WRITE(LVDS, dev_priv->saveLVDS); |
676 | 684 | ||
677 | if (!IS_I830(dev) && !IS_845G(dev) && !IS_IRONLAKE(dev)) | 685 | if (!IS_I830(dev) && !IS_845G(dev) && !HAS_PCH_SPLIT(dev)) |
678 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); | 686 | I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL); |
679 | 687 | ||
680 | if (IS_IRONLAKE(dev)) { | 688 | if (HAS_PCH_SPLIT(dev)) { |
681 | I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); | 689 | I915_WRITE(BLC_PWM_PCH_CTL1, dev_priv->saveBLC_PWM_CTL); |
682 | I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); | 690 | I915_WRITE(BLC_PWM_PCH_CTL2, dev_priv->saveBLC_PWM_CTL2); |
683 | I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); | 691 | I915_WRITE(BLC_PWM_CPU_CTL, dev_priv->saveBLC_CPU_PWM_CTL); |
@@ -708,7 +716,7 @@ void i915_restore_display(struct drm_device *dev) | |||
708 | 716 | ||
709 | /* only restore FBC info on the platform that supports FBC*/ | 717 | /* only restore FBC info on the platform that supports FBC*/ |
710 | if (I915_HAS_FBC(dev)) { | 718 | if (I915_HAS_FBC(dev)) { |
711 | if (IS_IRONLAKE_M(dev)) { | 719 | if (HAS_PCH_SPLIT(dev)) { |
712 | ironlake_disable_fbc(dev); | 720 | ironlake_disable_fbc(dev); |
713 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); | 721 | I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE); |
714 | } else if (IS_GM45(dev)) { | 722 | } else if (IS_GM45(dev)) { |
@@ -723,14 +731,15 @@ void i915_restore_display(struct drm_device *dev) | |||
723 | } | 731 | } |
724 | } | 732 | } |
725 | /* VGA state */ | 733 | /* VGA state */ |
726 | if (IS_IRONLAKE(dev)) | 734 | if (HAS_PCH_SPLIT(dev)) |
727 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); | 735 | I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL); |
728 | else | 736 | else |
729 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | 737 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); |
730 | I915_WRITE(VGA0, dev_priv->saveVGA0); | 738 | I915_WRITE(VGA0, dev_priv->saveVGA0); |
731 | I915_WRITE(VGA1, dev_priv->saveVGA1); | 739 | I915_WRITE(VGA1, dev_priv->saveVGA1); |
732 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | 740 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); |
733 | DRM_UDELAY(150); | 741 | POSTING_READ(VGA_PD); |
742 | udelay(150); | ||
734 | 743 | ||
735 | i915_restore_vga(dev); | 744 | i915_restore_vga(dev); |
736 | } | 745 | } |
@@ -748,7 +757,7 @@ int i915_save_state(struct drm_device *dev) | |||
748 | i915_save_display(dev); | 757 | i915_save_display(dev); |
749 | 758 | ||
750 | /* Interrupt state */ | 759 | /* Interrupt state */ |
751 | if (IS_IRONLAKE(dev)) { | 760 | if (HAS_PCH_SPLIT(dev)) { |
752 | dev_priv->saveDEIER = I915_READ(DEIER); | 761 | dev_priv->saveDEIER = I915_READ(DEIER); |
753 | dev_priv->saveDEIMR = I915_READ(DEIMR); | 762 | dev_priv->saveDEIMR = I915_READ(DEIMR); |
754 | dev_priv->saveGTIER = I915_READ(GTIER); | 763 | dev_priv->saveGTIER = I915_READ(GTIER); |
@@ -762,7 +771,7 @@ int i915_save_state(struct drm_device *dev) | |||
762 | dev_priv->saveIMR = I915_READ(IMR); | 771 | dev_priv->saveIMR = I915_READ(IMR); |
763 | } | 772 | } |
764 | 773 | ||
765 | if (IS_IRONLAKE_M(dev)) | 774 | if (HAS_PCH_SPLIT(dev)) |
766 | ironlake_disable_drps(dev); | 775 | ironlake_disable_drps(dev); |
767 | 776 | ||
768 | /* Cache mode state */ | 777 | /* Cache mode state */ |
@@ -820,7 +829,7 @@ int i915_restore_state(struct drm_device *dev) | |||
820 | i915_restore_display(dev); | 829 | i915_restore_display(dev); |
821 | 830 | ||
822 | /* Interrupt state */ | 831 | /* Interrupt state */ |
823 | if (IS_IRONLAKE(dev)) { | 832 | if (HAS_PCH_SPLIT(dev)) { |
824 | I915_WRITE(DEIER, dev_priv->saveDEIER); | 833 | I915_WRITE(DEIER, dev_priv->saveDEIER); |
825 | I915_WRITE(DEIMR, dev_priv->saveDEIMR); | 834 | I915_WRITE(DEIMR, dev_priv->saveDEIMR); |
826 | I915_WRITE(GTIER, dev_priv->saveGTIER); | 835 | I915_WRITE(GTIER, dev_priv->saveGTIER); |
@@ -835,7 +844,7 @@ int i915_restore_state(struct drm_device *dev) | |||
835 | /* Clock gating state */ | 844 | /* Clock gating state */ |
836 | intel_init_clock_gating(dev); | 845 | intel_init_clock_gating(dev); |
837 | 846 | ||
838 | if (IS_IRONLAKE_M(dev)) | 847 | if (HAS_PCH_SPLIT(dev)) |
839 | ironlake_enable_drps(dev); | 848 | ironlake_enable_drps(dev); |
840 | 849 | ||
841 | /* Cache mode state */ | 850 | /* Cache mode state */ |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index ee0732b222a1..4b7735196cd5 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -160,19 +160,20 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
160 | struct drm_i915_private *dev_priv = dev->dev_private; | 160 | struct drm_i915_private *dev_priv = dev->dev_private; |
161 | u32 adpa, temp; | 161 | u32 adpa, temp; |
162 | bool ret; | 162 | bool ret; |
163 | bool turn_off_dac = false; | ||
163 | 164 | ||
164 | temp = adpa = I915_READ(PCH_ADPA); | 165 | temp = adpa = I915_READ(PCH_ADPA); |
165 | 166 | ||
166 | if (HAS_PCH_CPT(dev)) { | 167 | if (HAS_PCH_SPLIT(dev)) |
167 | /* Disable DAC before force detect */ | 168 | turn_off_dac = true; |
168 | I915_WRITE(PCH_ADPA, adpa & ~ADPA_DAC_ENABLE); | 169 | |
169 | (void)I915_READ(PCH_ADPA); | 170 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; |
170 | } else { | 171 | if (turn_off_dac) |
171 | adpa &= ~ADPA_CRT_HOTPLUG_MASK; | 172 | adpa &= ~ADPA_DAC_ENABLE; |
172 | /* disable HPD first */ | 173 | |
173 | I915_WRITE(PCH_ADPA, adpa); | 174 | /* disable HPD first */ |
174 | (void)I915_READ(PCH_ADPA); | 175 | I915_WRITE(PCH_ADPA, adpa); |
175 | } | 176 | (void)I915_READ(PCH_ADPA); |
176 | 177 | ||
177 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | | 178 | adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | |
178 | ADPA_CRT_HOTPLUG_WARMUP_10MS | | 179 | ADPA_CRT_HOTPLUG_WARMUP_10MS | |
@@ -185,10 +186,11 @@ static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) | |||
185 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); | 186 | DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); |
186 | I915_WRITE(PCH_ADPA, adpa); | 187 | I915_WRITE(PCH_ADPA, adpa); |
187 | 188 | ||
188 | while ((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) != 0) | 189 | if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, |
189 | ; | 190 | 1000, 1)) |
191 | DRM_ERROR("timed out waiting for FORCE_TRIGGER"); | ||
190 | 192 | ||
191 | if (HAS_PCH_CPT(dev)) { | 193 | if (turn_off_dac) { |
192 | I915_WRITE(PCH_ADPA, temp); | 194 | I915_WRITE(PCH_ADPA, temp); |
193 | (void)I915_READ(PCH_ADPA); | 195 | (void)I915_READ(PCH_ADPA); |
194 | } | 196 | } |
@@ -237,17 +239,13 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
237 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; | 239 | hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; |
238 | 240 | ||
239 | for (i = 0; i < tries ; i++) { | 241 | for (i = 0; i < tries ; i++) { |
240 | unsigned long timeout; | ||
241 | /* turn on the FORCE_DETECT */ | 242 | /* turn on the FORCE_DETECT */ |
242 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 243 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
243 | timeout = jiffies + msecs_to_jiffies(1000); | ||
244 | /* wait for FORCE_DETECT to go off */ | 244 | /* wait for FORCE_DETECT to go off */ |
245 | do { | 245 | if (wait_for((I915_READ(PORT_HOTPLUG_EN) & |
246 | if (!(I915_READ(PORT_HOTPLUG_EN) & | 246 | CRT_HOTPLUG_FORCE_DETECT) == 0, |
247 | CRT_HOTPLUG_FORCE_DETECT)) | 247 | 1000, 1)) |
248 | break; | 248 | DRM_ERROR("timed out waiting for FORCE_DETECT to go off"); |
249 | msleep(1); | ||
250 | } while (time_after(timeout, jiffies)); | ||
251 | } | 249 | } |
252 | 250 | ||
253 | stat = I915_READ(PORT_HOTPLUG_STAT); | 251 | stat = I915_READ(PORT_HOTPLUG_STAT); |
@@ -331,7 +329,7 @@ intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
331 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); | 329 | I915_WRITE(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); |
332 | /* Wait for next Vblank to substitue | 330 | /* Wait for next Vblank to substitue |
333 | * border color for Color info */ | 331 | * border color for Color info */ |
334 | intel_wait_for_vblank(dev); | 332 | intel_wait_for_vblank(dev, pipe); |
335 | st00 = I915_READ8(VGA_MSR_WRITE); | 333 | st00 = I915_READ8(VGA_MSR_WRITE); |
336 | status = ((st00 & (1 << 4)) != 0) ? | 334 | status = ((st00 & (1 << 4)) != 0) ? |
337 | connector_status_connected : | 335 | connector_status_connected : |
@@ -508,17 +506,8 @@ static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs | |||
508 | .best_encoder = intel_attached_encoder, | 506 | .best_encoder = intel_attached_encoder, |
509 | }; | 507 | }; |
510 | 508 | ||
511 | static void intel_crt_enc_destroy(struct drm_encoder *encoder) | ||
512 | { | ||
513 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
514 | |||
515 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
516 | drm_encoder_cleanup(encoder); | ||
517 | kfree(intel_encoder); | ||
518 | } | ||
519 | |||
520 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { | 509 | static const struct drm_encoder_funcs intel_crt_enc_funcs = { |
521 | .destroy = intel_crt_enc_destroy, | 510 | .destroy = intel_encoder_destroy, |
522 | }; | 511 | }; |
523 | 512 | ||
524 | void intel_crt_init(struct drm_device *dev) | 513 | void intel_crt_init(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5ec10e02341b..11a3394f5fe1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/vgaarb.h> | ||
32 | #include "drmP.h" | 33 | #include "drmP.h" |
33 | #include "intel_drv.h" | 34 | #include "intel_drv.h" |
34 | #include "i915_drm.h" | 35 | #include "i915_drm.h" |
@@ -976,14 +977,54 @@ intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
976 | return true; | 977 | return true; |
977 | } | 978 | } |
978 | 979 | ||
979 | void | 980 | /** |
980 | intel_wait_for_vblank(struct drm_device *dev) | 981 | * intel_wait_for_vblank - wait for vblank on a given pipe |
982 | * @dev: drm device | ||
983 | * @pipe: pipe to wait for | ||
984 | * | ||
985 | * Wait for vblank to occur on a given pipe. Needed for various bits of | ||
986 | * mode setting code. | ||
987 | */ | ||
988 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) | ||
981 | { | 989 | { |
982 | /* Wait for 20ms, i.e. one cycle at 50hz. */ | 990 | struct drm_i915_private *dev_priv = dev->dev_private; |
983 | if (in_dbg_master()) | 991 | int pipestat_reg = (pipe == 0 ? PIPEASTAT : PIPEBSTAT); |
984 | mdelay(20); /* The kernel debugger cannot call msleep() */ | 992 | |
985 | else | 993 | /* Wait for vblank interrupt bit to set */ |
986 | msleep(20); | 994 | if (wait_for((I915_READ(pipestat_reg) & |
995 | PIPE_VBLANK_INTERRUPT_STATUS), | ||
996 | 50, 0)) | ||
997 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
998 | } | ||
999 | |||
1000 | /** | ||
1001 | * intel_wait_for_vblank_off - wait for vblank after disabling a pipe | ||
1002 | * @dev: drm device | ||
1003 | * @pipe: pipe to wait for | ||
1004 | * | ||
1005 | * After disabling a pipe, we can't wait for vblank in the usual way, | ||
1006 | * spinning on the vblank interrupt status bit, since we won't actually | ||
1007 | * see an interrupt when the pipe is disabled. | ||
1008 | * | ||
1009 | * So this function waits for the display line value to settle (it | ||
1010 | * usually ends up stopping at the start of the next frame). | ||
1011 | */ | ||
1012 | void intel_wait_for_vblank_off(struct drm_device *dev, int pipe) | ||
1013 | { | ||
1014 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1015 | int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL); | ||
1016 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | ||
1017 | u32 last_line; | ||
1018 | |||
1019 | /* Wait for the display line to settle */ | ||
1020 | do { | ||
1021 | last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK; | ||
1022 | mdelay(5); | ||
1023 | } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) && | ||
1024 | time_after(timeout, jiffies)); | ||
1025 | |||
1026 | if (time_after(jiffies, timeout)) | ||
1027 | DRM_DEBUG_KMS("vblank wait timed out\n"); | ||
987 | } | 1028 | } |
988 | 1029 | ||
989 | /* Parameters have changed, update FBC info */ | 1030 | /* Parameters have changed, update FBC info */ |
@@ -1037,7 +1078,6 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) | |||
1037 | void i8xx_disable_fbc(struct drm_device *dev) | 1078 | void i8xx_disable_fbc(struct drm_device *dev) |
1038 | { | 1079 | { |
1039 | struct drm_i915_private *dev_priv = dev->dev_private; | 1080 | struct drm_i915_private *dev_priv = dev->dev_private; |
1040 | unsigned long timeout = jiffies + msecs_to_jiffies(1); | ||
1041 | u32 fbc_ctl; | 1081 | u32 fbc_ctl; |
1042 | 1082 | ||
1043 | if (!I915_HAS_FBC(dev)) | 1083 | if (!I915_HAS_FBC(dev)) |
@@ -1052,16 +1092,11 @@ void i8xx_disable_fbc(struct drm_device *dev) | |||
1052 | I915_WRITE(FBC_CONTROL, fbc_ctl); | 1092 | I915_WRITE(FBC_CONTROL, fbc_ctl); |
1053 | 1093 | ||
1054 | /* Wait for compressing bit to clear */ | 1094 | /* Wait for compressing bit to clear */ |
1055 | while (I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) { | 1095 | if (wait_for((I915_READ(FBC_STATUS) & FBC_STAT_COMPRESSING) == 0, 10, 0)) { |
1056 | if (time_after(jiffies, timeout)) { | 1096 | DRM_DEBUG_KMS("FBC idle timed out\n"); |
1057 | DRM_DEBUG_DRIVER("FBC idle timed out\n"); | 1097 | return; |
1058 | break; | ||
1059 | } | ||
1060 | ; /* do nothing */ | ||
1061 | } | 1098 | } |
1062 | 1099 | ||
1063 | intel_wait_for_vblank(dev); | ||
1064 | |||
1065 | DRM_DEBUG_KMS("disabled FBC\n"); | 1100 | DRM_DEBUG_KMS("disabled FBC\n"); |
1066 | } | 1101 | } |
1067 | 1102 | ||
@@ -1118,7 +1153,6 @@ void g4x_disable_fbc(struct drm_device *dev) | |||
1118 | dpfc_ctl = I915_READ(DPFC_CONTROL); | 1153 | dpfc_ctl = I915_READ(DPFC_CONTROL); |
1119 | dpfc_ctl &= ~DPFC_CTL_EN; | 1154 | dpfc_ctl &= ~DPFC_CTL_EN; |
1120 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); | 1155 | I915_WRITE(DPFC_CONTROL, dpfc_ctl); |
1121 | intel_wait_for_vblank(dev); | ||
1122 | 1156 | ||
1123 | DRM_DEBUG_KMS("disabled FBC\n"); | 1157 | DRM_DEBUG_KMS("disabled FBC\n"); |
1124 | } | 1158 | } |
@@ -1179,7 +1213,6 @@ void ironlake_disable_fbc(struct drm_device *dev) | |||
1179 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); | 1213 | dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); |
1180 | dpfc_ctl &= ~DPFC_CTL_EN; | 1214 | dpfc_ctl &= ~DPFC_CTL_EN; |
1181 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); | 1215 | I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl); |
1182 | intel_wait_for_vblank(dev); | ||
1183 | 1216 | ||
1184 | DRM_DEBUG_KMS("disabled FBC\n"); | 1217 | DRM_DEBUG_KMS("disabled FBC\n"); |
1185 | } | 1218 | } |
@@ -1478,7 +1511,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
1478 | if ((IS_I965G(dev) || plane == 0)) | 1511 | if ((IS_I965G(dev) || plane == 0)) |
1479 | intel_update_fbc(crtc, &crtc->mode); | 1512 | intel_update_fbc(crtc, &crtc->mode); |
1480 | 1513 | ||
1481 | intel_wait_for_vblank(dev); | 1514 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1482 | intel_increase_pllclock(crtc, true); | 1515 | intel_increase_pllclock(crtc, true); |
1483 | 1516 | ||
1484 | return 0; | 1517 | return 0; |
@@ -1585,20 +1618,18 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1585 | Start, Offset, x, y, crtc->fb->pitch); | 1618 | Start, Offset, x, y, crtc->fb->pitch); |
1586 | I915_WRITE(dspstride, crtc->fb->pitch); | 1619 | I915_WRITE(dspstride, crtc->fb->pitch); |
1587 | if (IS_I965G(dev)) { | 1620 | if (IS_I965G(dev)) { |
1588 | I915_WRITE(dspbase, Offset); | ||
1589 | I915_READ(dspbase); | ||
1590 | I915_WRITE(dspsurf, Start); | 1621 | I915_WRITE(dspsurf, Start); |
1591 | I915_READ(dspsurf); | ||
1592 | I915_WRITE(dsptileoff, (y << 16) | x); | 1622 | I915_WRITE(dsptileoff, (y << 16) | x); |
1623 | I915_WRITE(dspbase, Offset); | ||
1593 | } else { | 1624 | } else { |
1594 | I915_WRITE(dspbase, Start + Offset); | 1625 | I915_WRITE(dspbase, Start + Offset); |
1595 | I915_READ(dspbase); | ||
1596 | } | 1626 | } |
1627 | POSTING_READ(dspbase); | ||
1597 | 1628 | ||
1598 | if ((IS_I965G(dev) || plane == 0)) | 1629 | if ((IS_I965G(dev) || plane == 0)) |
1599 | intel_update_fbc(crtc, &crtc->mode); | 1630 | intel_update_fbc(crtc, &crtc->mode); |
1600 | 1631 | ||
1601 | intel_wait_for_vblank(dev); | 1632 | intel_wait_for_vblank(dev, pipe); |
1602 | 1633 | ||
1603 | if (old_fb) { | 1634 | if (old_fb) { |
1604 | intel_fb = to_intel_framebuffer(old_fb); | 1635 | intel_fb = to_intel_framebuffer(old_fb); |
@@ -1627,54 +1658,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
1627 | return 0; | 1658 | return 0; |
1628 | } | 1659 | } |
1629 | 1660 | ||
1630 | /* Disable the VGA plane that we never use */ | ||
1631 | static void i915_disable_vga (struct drm_device *dev) | ||
1632 | { | ||
1633 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1634 | u8 sr1; | ||
1635 | u32 vga_reg; | ||
1636 | |||
1637 | if (HAS_PCH_SPLIT(dev)) | ||
1638 | vga_reg = CPU_VGACNTRL; | ||
1639 | else | ||
1640 | vga_reg = VGACNTRL; | ||
1641 | |||
1642 | if (I915_READ(vga_reg) & VGA_DISP_DISABLE) | ||
1643 | return; | ||
1644 | |||
1645 | I915_WRITE8(VGA_SR_INDEX, 1); | ||
1646 | sr1 = I915_READ8(VGA_SR_DATA); | ||
1647 | I915_WRITE8(VGA_SR_DATA, sr1 | (1 << 5)); | ||
1648 | udelay(100); | ||
1649 | |||
1650 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
1651 | } | ||
1652 | |||
1653 | static void ironlake_disable_pll_edp (struct drm_crtc *crtc) | ||
1654 | { | ||
1655 | struct drm_device *dev = crtc->dev; | ||
1656 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1657 | u32 dpa_ctl; | ||
1658 | |||
1659 | DRM_DEBUG_KMS("\n"); | ||
1660 | dpa_ctl = I915_READ(DP_A); | ||
1661 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
1662 | I915_WRITE(DP_A, dpa_ctl); | ||
1663 | } | ||
1664 | |||
1665 | static void ironlake_enable_pll_edp (struct drm_crtc *crtc) | ||
1666 | { | ||
1667 | struct drm_device *dev = crtc->dev; | ||
1668 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1669 | u32 dpa_ctl; | ||
1670 | |||
1671 | dpa_ctl = I915_READ(DP_A); | ||
1672 | dpa_ctl |= DP_PLL_ENABLE; | ||
1673 | I915_WRITE(DP_A, dpa_ctl); | ||
1674 | udelay(200); | ||
1675 | } | ||
1676 | |||
1677 | |||
1678 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) | 1661 | static void ironlake_set_pll_edp (struct drm_crtc *crtc, int clock) |
1679 | { | 1662 | { |
1680 | struct drm_device *dev = crtc->dev; | 1663 | struct drm_device *dev = crtc->dev; |
@@ -1945,7 +1928,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1945 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; | 1928 | int trans_vsync_reg = (pipe == 0) ? TRANS_VSYNC_A : TRANS_VSYNC_B; |
1946 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; | 1929 | int trans_dpll_sel = (pipe == 0) ? 0 : 1; |
1947 | u32 temp; | 1930 | u32 temp; |
1948 | int n; | ||
1949 | u32 pipe_bpc; | 1931 | u32 pipe_bpc; |
1950 | 1932 | ||
1951 | temp = I915_READ(pipeconf_reg); | 1933 | temp = I915_READ(pipeconf_reg); |
@@ -1958,7 +1940,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1958 | case DRM_MODE_DPMS_ON: | 1940 | case DRM_MODE_DPMS_ON: |
1959 | case DRM_MODE_DPMS_STANDBY: | 1941 | case DRM_MODE_DPMS_STANDBY: |
1960 | case DRM_MODE_DPMS_SUSPEND: | 1942 | case DRM_MODE_DPMS_SUSPEND: |
1961 | DRM_DEBUG_KMS("crtc %d dpms on\n", pipe); | 1943 | DRM_DEBUG_KMS("crtc %d/%d dpms on\n", pipe, plane); |
1962 | 1944 | ||
1963 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | 1945 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
1964 | temp = I915_READ(PCH_LVDS); | 1946 | temp = I915_READ(PCH_LVDS); |
@@ -1968,10 +1950,7 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
1968 | } | 1950 | } |
1969 | } | 1951 | } |
1970 | 1952 | ||
1971 | if (HAS_eDP) { | 1953 | if (!HAS_eDP) { |
1972 | /* enable eDP PLL */ | ||
1973 | ironlake_enable_pll_edp(crtc); | ||
1974 | } else { | ||
1975 | 1954 | ||
1976 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ | 1955 | /* enable PCH FDI RX PLL, wait warmup plus DMI latency */ |
1977 | temp = I915_READ(fdi_rx_reg); | 1956 | temp = I915_READ(fdi_rx_reg); |
@@ -2005,15 +1984,13 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2005 | /* Enable panel fitting for LVDS */ | 1984 | /* Enable panel fitting for LVDS */ |
2006 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) | 1985 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) |
2007 | || HAS_eDP || intel_pch_has_edp(crtc)) { | 1986 | || HAS_eDP || intel_pch_has_edp(crtc)) { |
2008 | temp = I915_READ(pf_ctl_reg); | 1987 | if (dev_priv->pch_pf_size) { |
2009 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | 1988 | temp = I915_READ(pf_ctl_reg); |
2010 | 1989 | I915_WRITE(pf_ctl_reg, temp | PF_ENABLE | PF_FILTER_MED_3x3); | |
2011 | /* currently full aspect */ | 1990 | I915_WRITE(pf_win_pos, dev_priv->pch_pf_pos); |
2012 | I915_WRITE(pf_win_pos, 0); | 1991 | I915_WRITE(pf_win_size, dev_priv->pch_pf_size); |
2013 | 1992 | } else | |
2014 | I915_WRITE(pf_win_size, | 1993 | I915_WRITE(pf_ctl_reg, temp & ~PF_ENABLE); |
2015 | (dev_priv->panel_fixed_mode->hdisplay << 16) | | ||
2016 | (dev_priv->panel_fixed_mode->vdisplay)); | ||
2017 | } | 1994 | } |
2018 | 1995 | ||
2019 | /* Enable CPU pipe */ | 1996 | /* Enable CPU pipe */ |
@@ -2097,9 +2074,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2097 | int reg; | 2074 | int reg; |
2098 | 2075 | ||
2099 | reg = I915_READ(trans_dp_ctl); | 2076 | reg = I915_READ(trans_dp_ctl); |
2100 | reg &= ~TRANS_DP_PORT_SEL_MASK; | 2077 | reg &= ~(TRANS_DP_PORT_SEL_MASK | |
2101 | reg = TRANS_DP_OUTPUT_ENABLE | | 2078 | TRANS_DP_SYNC_MASK); |
2102 | TRANS_DP_ENH_FRAMING; | 2079 | reg |= (TRANS_DP_OUTPUT_ENABLE | |
2080 | TRANS_DP_ENH_FRAMING); | ||
2103 | 2081 | ||
2104 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2082 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
2105 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2083 | reg |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
@@ -2137,18 +2115,17 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2137 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); | 2115 | I915_WRITE(transconf_reg, temp | TRANS_ENABLE); |
2138 | I915_READ(transconf_reg); | 2116 | I915_READ(transconf_reg); |
2139 | 2117 | ||
2140 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0) | 2118 | if (wait_for(I915_READ(transconf_reg) & TRANS_STATE_ENABLE, 10, 0)) |
2141 | ; | 2119 | DRM_ERROR("failed to enable transcoder\n"); |
2142 | |||
2143 | } | 2120 | } |
2144 | 2121 | ||
2145 | intel_crtc_load_lut(crtc); | 2122 | intel_crtc_load_lut(crtc); |
2146 | 2123 | ||
2147 | intel_update_fbc(crtc, &crtc->mode); | 2124 | intel_update_fbc(crtc, &crtc->mode); |
2125 | break; | ||
2148 | 2126 | ||
2149 | break; | ||
2150 | case DRM_MODE_DPMS_OFF: | 2127 | case DRM_MODE_DPMS_OFF: |
2151 | DRM_DEBUG_KMS("crtc %d dpms off\n", pipe); | 2128 | DRM_DEBUG_KMS("crtc %d/%d dpms off\n", pipe, plane); |
2152 | 2129 | ||
2153 | drm_vblank_off(dev, pipe); | 2130 | drm_vblank_off(dev, pipe); |
2154 | /* Disable display plane */ | 2131 | /* Disable display plane */ |
@@ -2164,26 +2141,14 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2164 | dev_priv->display.disable_fbc) | 2141 | dev_priv->display.disable_fbc) |
2165 | dev_priv->display.disable_fbc(dev); | 2142 | dev_priv->display.disable_fbc(dev); |
2166 | 2143 | ||
2167 | i915_disable_vga(dev); | ||
2168 | |||
2169 | /* disable cpu pipe, disable after all planes disabled */ | 2144 | /* disable cpu pipe, disable after all planes disabled */ |
2170 | temp = I915_READ(pipeconf_reg); | 2145 | temp = I915_READ(pipeconf_reg); |
2171 | if ((temp & PIPEACONF_ENABLE) != 0) { | 2146 | if ((temp & PIPEACONF_ENABLE) != 0) { |
2172 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); | 2147 | I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); |
2173 | I915_READ(pipeconf_reg); | 2148 | |
2174 | n = 0; | ||
2175 | /* wait for cpu pipe off, pipe state */ | 2149 | /* wait for cpu pipe off, pipe state */ |
2176 | while ((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) != 0) { | 2150 | if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0, 50, 1)) |
2177 | n++; | 2151 | DRM_ERROR("failed to turn off cpu pipe\n"); |
2178 | if (n < 60) { | ||
2179 | udelay(500); | ||
2180 | continue; | ||
2181 | } else { | ||
2182 | DRM_DEBUG_KMS("pipe %d off delay\n", | ||
2183 | pipe); | ||
2184 | break; | ||
2185 | } | ||
2186 | } | ||
2187 | } else | 2152 | } else |
2188 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); | 2153 | DRM_DEBUG_KMS("crtc %d is disabled\n", pipe); |
2189 | 2154 | ||
@@ -2244,20 +2209,10 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2244 | temp = I915_READ(transconf_reg); | 2209 | temp = I915_READ(transconf_reg); |
2245 | if ((temp & TRANS_ENABLE) != 0) { | 2210 | if ((temp & TRANS_ENABLE) != 0) { |
2246 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); | 2211 | I915_WRITE(transconf_reg, temp & ~TRANS_ENABLE); |
2247 | I915_READ(transconf_reg); | 2212 | |
2248 | n = 0; | ||
2249 | /* wait for PCH transcoder off, transcoder state */ | 2213 | /* wait for PCH transcoder off, transcoder state */ |
2250 | while ((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) != 0) { | 2214 | if (wait_for((I915_READ(transconf_reg) & TRANS_STATE_ENABLE) == 0, 50, 1)) |
2251 | n++; | 2215 | DRM_ERROR("failed to disable transcoder\n"); |
2252 | if (n < 60) { | ||
2253 | udelay(500); | ||
2254 | continue; | ||
2255 | } else { | ||
2256 | DRM_DEBUG_KMS("transcoder %d off " | ||
2257 | "delay\n", pipe); | ||
2258 | break; | ||
2259 | } | ||
2260 | } | ||
2261 | } | 2216 | } |
2262 | 2217 | ||
2263 | temp = I915_READ(transconf_reg); | 2218 | temp = I915_READ(transconf_reg); |
@@ -2294,10 +2249,6 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2294 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); | 2249 | I915_WRITE(pch_dpll_reg, temp & ~DPLL_VCO_ENABLE); |
2295 | I915_READ(pch_dpll_reg); | 2250 | I915_READ(pch_dpll_reg); |
2296 | 2251 | ||
2297 | if (HAS_eDP) { | ||
2298 | ironlake_disable_pll_edp(crtc); | ||
2299 | } | ||
2300 | |||
2301 | /* Switch from PCDclk to Rawclk */ | 2252 | /* Switch from PCDclk to Rawclk */ |
2302 | temp = I915_READ(fdi_rx_reg); | 2253 | temp = I915_READ(fdi_rx_reg); |
2303 | temp &= ~FDI_SEL_PCDCLK; | 2254 | temp &= ~FDI_SEL_PCDCLK; |
@@ -2372,8 +2323,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2372 | case DRM_MODE_DPMS_ON: | 2323 | case DRM_MODE_DPMS_ON: |
2373 | case DRM_MODE_DPMS_STANDBY: | 2324 | case DRM_MODE_DPMS_STANDBY: |
2374 | case DRM_MODE_DPMS_SUSPEND: | 2325 | case DRM_MODE_DPMS_SUSPEND: |
2375 | intel_update_watermarks(dev); | ||
2376 | |||
2377 | /* Enable the DPLL */ | 2326 | /* Enable the DPLL */ |
2378 | temp = I915_READ(dpll_reg); | 2327 | temp = I915_READ(dpll_reg); |
2379 | if ((temp & DPLL_VCO_ENABLE) == 0) { | 2328 | if ((temp & DPLL_VCO_ENABLE) == 0) { |
@@ -2413,8 +2362,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2413 | intel_crtc_dpms_overlay(intel_crtc, true); | 2362 | intel_crtc_dpms_overlay(intel_crtc, true); |
2414 | break; | 2363 | break; |
2415 | case DRM_MODE_DPMS_OFF: | 2364 | case DRM_MODE_DPMS_OFF: |
2416 | intel_update_watermarks(dev); | ||
2417 | |||
2418 | /* Give the overlay scaler a chance to disable if it's on this pipe */ | 2365 | /* Give the overlay scaler a chance to disable if it's on this pipe */ |
2419 | intel_crtc_dpms_overlay(intel_crtc, false); | 2366 | intel_crtc_dpms_overlay(intel_crtc, false); |
2420 | drm_vblank_off(dev, pipe); | 2367 | drm_vblank_off(dev, pipe); |
@@ -2423,9 +2370,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2423 | dev_priv->display.disable_fbc) | 2370 | dev_priv->display.disable_fbc) |
2424 | dev_priv->display.disable_fbc(dev); | 2371 | dev_priv->display.disable_fbc(dev); |
2425 | 2372 | ||
2426 | /* Disable the VGA plane that we never use */ | ||
2427 | i915_disable_vga(dev); | ||
2428 | |||
2429 | /* Disable display plane */ | 2373 | /* Disable display plane */ |
2430 | temp = I915_READ(dspcntr_reg); | 2374 | temp = I915_READ(dspcntr_reg); |
2431 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { | 2375 | if ((temp & DISPLAY_PLANE_ENABLE) != 0) { |
@@ -2435,10 +2379,8 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2435 | I915_READ(dspbase_reg); | 2379 | I915_READ(dspbase_reg); |
2436 | } | 2380 | } |
2437 | 2381 | ||
2438 | if (!IS_I9XX(dev)) { | 2382 | /* Wait for vblank for the disable to take effect */ |
2439 | /* Wait for vblank for the disable to take effect */ | 2383 | intel_wait_for_vblank_off(dev, pipe); |
2440 | intel_wait_for_vblank(dev); | ||
2441 | } | ||
2442 | 2384 | ||
2443 | /* Don't disable pipe A or pipe A PLLs if needed */ | 2385 | /* Don't disable pipe A or pipe A PLLs if needed */ |
2444 | if (pipeconf_reg == PIPEACONF && | 2386 | if (pipeconf_reg == PIPEACONF && |
@@ -2453,7 +2395,7 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2453 | } | 2395 | } |
2454 | 2396 | ||
2455 | /* Wait for vblank for the disable to take effect. */ | 2397 | /* Wait for vblank for the disable to take effect. */ |
2456 | intel_wait_for_vblank(dev); | 2398 | intel_wait_for_vblank_off(dev, pipe); |
2457 | 2399 | ||
2458 | temp = I915_READ(dpll_reg); | 2400 | temp = I915_READ(dpll_reg); |
2459 | if ((temp & DPLL_VCO_ENABLE) != 0) { | 2401 | if ((temp & DPLL_VCO_ENABLE) != 0) { |
@@ -2469,9 +2411,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2469 | 2411 | ||
2470 | /** | 2412 | /** |
2471 | * Sets the power management mode of the pipe and plane. | 2413 | * Sets the power management mode of the pipe and plane. |
2472 | * | ||
2473 | * This code should probably grow support for turning the cursor off and back | ||
2474 | * on appropriately at the same time as we're turning the pipe off/on. | ||
2475 | */ | 2414 | */ |
2476 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | 2415 | static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) |
2477 | { | 2416 | { |
@@ -2482,9 +2421,26 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
2482 | int pipe = intel_crtc->pipe; | 2421 | int pipe = intel_crtc->pipe; |
2483 | bool enabled; | 2422 | bool enabled; |
2484 | 2423 | ||
2424 | intel_crtc->dpms_mode = mode; | ||
2425 | intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; | ||
2426 | |||
2427 | /* When switching on the display, ensure that SR is disabled | ||
2428 | * with multiple pipes prior to enabling to new pipe. | ||
2429 | * | ||
2430 | * When switching off the display, make sure the cursor is | ||
2431 | * properly hidden prior to disabling the pipe. | ||
2432 | */ | ||
2433 | if (mode == DRM_MODE_DPMS_ON) | ||
2434 | intel_update_watermarks(dev); | ||
2435 | else | ||
2436 | intel_crtc_update_cursor(crtc); | ||
2437 | |||
2485 | dev_priv->display.dpms(crtc, mode); | 2438 | dev_priv->display.dpms(crtc, mode); |
2486 | 2439 | ||
2487 | intel_crtc->dpms_mode = mode; | 2440 | if (mode == DRM_MODE_DPMS_ON) |
2441 | intel_crtc_update_cursor(crtc); | ||
2442 | else | ||
2443 | intel_update_watermarks(dev); | ||
2488 | 2444 | ||
2489 | if (!dev->primary->master) | 2445 | if (!dev->primary->master) |
2490 | return; | 2446 | return; |
@@ -2536,6 +2492,20 @@ void intel_encoder_commit (struct drm_encoder *encoder) | |||
2536 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); | 2492 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); |
2537 | } | 2493 | } |
2538 | 2494 | ||
2495 | void intel_encoder_destroy(struct drm_encoder *encoder) | ||
2496 | { | ||
2497 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2498 | |||
2499 | if (intel_encoder->ddc_bus) | ||
2500 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2501 | |||
2502 | if (intel_encoder->i2c_bus) | ||
2503 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
2504 | |||
2505 | drm_encoder_cleanup(encoder); | ||
2506 | kfree(intel_encoder); | ||
2507 | } | ||
2508 | |||
2539 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, | 2509 | static bool intel_crtc_mode_fixup(struct drm_crtc *crtc, |
2540 | struct drm_display_mode *mode, | 2510 | struct drm_display_mode *mode, |
2541 | struct drm_display_mode *adjusted_mode) | 2511 | struct drm_display_mode *adjusted_mode) |
@@ -2867,7 +2837,7 @@ struct cxsr_latency { | |||
2867 | unsigned long cursor_hpll_disable; | 2837 | unsigned long cursor_hpll_disable; |
2868 | }; | 2838 | }; |
2869 | 2839 | ||
2870 | static struct cxsr_latency cxsr_latency_table[] = { | 2840 | static const struct cxsr_latency cxsr_latency_table[] = { |
2871 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ | 2841 | {1, 0, 800, 400, 3382, 33382, 3983, 33983}, /* DDR2-400 SC */ |
2872 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ | 2842 | {1, 0, 800, 667, 3354, 33354, 3807, 33807}, /* DDR2-667 SC */ |
2873 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ | 2843 | {1, 0, 800, 800, 3347, 33347, 3763, 33763}, /* DDR2-800 SC */ |
@@ -2905,11 +2875,13 @@ static struct cxsr_latency cxsr_latency_table[] = { | |||
2905 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ | 2875 | {0, 1, 400, 800, 6042, 36042, 6584, 36584}, /* DDR3-800 SC */ |
2906 | }; | 2876 | }; |
2907 | 2877 | ||
2908 | static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | 2878 | static const struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, |
2909 | int fsb, int mem) | 2879 | int is_ddr3, |
2880 | int fsb, | ||
2881 | int mem) | ||
2910 | { | 2882 | { |
2883 | const struct cxsr_latency *latency; | ||
2911 | int i; | 2884 | int i; |
2912 | struct cxsr_latency *latency; | ||
2913 | 2885 | ||
2914 | if (fsb == 0 || mem == 0) | 2886 | if (fsb == 0 || mem == 0) |
2915 | return NULL; | 2887 | return NULL; |
@@ -2930,13 +2902,9 @@ static struct cxsr_latency *intel_get_cxsr_latency(int is_desktop, int is_ddr3, | |||
2930 | static void pineview_disable_cxsr(struct drm_device *dev) | 2902 | static void pineview_disable_cxsr(struct drm_device *dev) |
2931 | { | 2903 | { |
2932 | struct drm_i915_private *dev_priv = dev->dev_private; | 2904 | struct drm_i915_private *dev_priv = dev->dev_private; |
2933 | u32 reg; | ||
2934 | 2905 | ||
2935 | /* deactivate cxsr */ | 2906 | /* deactivate cxsr */ |
2936 | reg = I915_READ(DSPFW3); | 2907 | I915_WRITE(DSPFW3, I915_READ(DSPFW3) & ~PINEVIEW_SELF_REFRESH_EN); |
2937 | reg &= ~(PINEVIEW_SELF_REFRESH_EN); | ||
2938 | I915_WRITE(DSPFW3, reg); | ||
2939 | DRM_INFO("Big FIFO is disabled\n"); | ||
2940 | } | 2908 | } |
2941 | 2909 | ||
2942 | /* | 2910 | /* |
@@ -3024,12 +2992,12 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3024 | int pixel_size) | 2992 | int pixel_size) |
3025 | { | 2993 | { |
3026 | struct drm_i915_private *dev_priv = dev->dev_private; | 2994 | struct drm_i915_private *dev_priv = dev->dev_private; |
2995 | const struct cxsr_latency *latency; | ||
3027 | u32 reg; | 2996 | u32 reg; |
3028 | unsigned long wm; | 2997 | unsigned long wm; |
3029 | struct cxsr_latency *latency; | ||
3030 | int sr_clock; | 2998 | int sr_clock; |
3031 | 2999 | ||
3032 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, | 3000 | latency = intel_get_cxsr_latency(IS_PINEVIEW_G(dev), dev_priv->is_ddr3, |
3033 | dev_priv->fsb_freq, dev_priv->mem_freq); | 3001 | dev_priv->fsb_freq, dev_priv->mem_freq); |
3034 | if (!latency) { | 3002 | if (!latency) { |
3035 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); | 3003 | DRM_DEBUG_KMS("Unknown FSB/MEM found, disable CxSR\n"); |
@@ -3075,9 +3043,8 @@ static void pineview_update_wm(struct drm_device *dev, int planea_clock, | |||
3075 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); | 3043 | DRM_DEBUG_KMS("DSPFW3 register is %x\n", reg); |
3076 | 3044 | ||
3077 | /* activate cxsr */ | 3045 | /* activate cxsr */ |
3078 | reg = I915_READ(DSPFW3); | 3046 | I915_WRITE(DSPFW3, |
3079 | reg |= PINEVIEW_SELF_REFRESH_EN; | 3047 | I915_READ(DSPFW3) | PINEVIEW_SELF_REFRESH_EN); |
3080 | I915_WRITE(DSPFW3, reg); | ||
3081 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); | 3048 | DRM_DEBUG_KMS("Self-refresh is enabled\n"); |
3082 | } else { | 3049 | } else { |
3083 | pineview_disable_cxsr(dev); | 3050 | pineview_disable_cxsr(dev); |
@@ -3354,12 +3321,11 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, | |||
3354 | int line_count; | 3321 | int line_count; |
3355 | int planea_htotal = 0, planeb_htotal = 0; | 3322 | int planea_htotal = 0, planeb_htotal = 0; |
3356 | struct drm_crtc *crtc; | 3323 | struct drm_crtc *crtc; |
3357 | struct intel_crtc *intel_crtc; | ||
3358 | 3324 | ||
3359 | /* Need htotal for all active display plane */ | 3325 | /* Need htotal for all active display plane */ |
3360 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3326 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
3361 | intel_crtc = to_intel_crtc(crtc); | 3327 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3362 | if (crtc->enabled) { | 3328 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
3363 | if (intel_crtc->plane == 0) | 3329 | if (intel_crtc->plane == 0) |
3364 | planea_htotal = crtc->mode.htotal; | 3330 | planea_htotal = crtc->mode.htotal; |
3365 | else | 3331 | else |
@@ -3519,7 +3485,6 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3519 | { | 3485 | { |
3520 | struct drm_i915_private *dev_priv = dev->dev_private; | 3486 | struct drm_i915_private *dev_priv = dev->dev_private; |
3521 | struct drm_crtc *crtc; | 3487 | struct drm_crtc *crtc; |
3522 | struct intel_crtc *intel_crtc; | ||
3523 | int sr_hdisplay = 0; | 3488 | int sr_hdisplay = 0; |
3524 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; | 3489 | unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; |
3525 | int enabled = 0, pixel_size = 0; | 3490 | int enabled = 0, pixel_size = 0; |
@@ -3530,8 +3495,8 @@ static void intel_update_watermarks(struct drm_device *dev) | |||
3530 | 3495 | ||
3531 | /* Get the clock config from both planes */ | 3496 | /* Get the clock config from both planes */ |
3532 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 3497 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
3533 | intel_crtc = to_intel_crtc(crtc); | 3498 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
3534 | if (crtc->enabled) { | 3499 | if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { |
3535 | enabled++; | 3500 | enabled++; |
3536 | if (intel_crtc->plane == 0) { | 3501 | if (intel_crtc->plane == 0) { |
3537 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", | 3502 | DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", |
@@ -3966,9 +3931,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3966 | dpll_reg = pch_dpll_reg; | 3931 | dpll_reg = pch_dpll_reg; |
3967 | } | 3932 | } |
3968 | 3933 | ||
3969 | if (is_edp) { | 3934 | if (!is_edp) { |
3970 | ironlake_disable_pll_edp(crtc); | ||
3971 | } else if ((dpll & DPLL_VCO_ENABLE)) { | ||
3972 | I915_WRITE(fp_reg, fp); | 3935 | I915_WRITE(fp_reg, fp); |
3973 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); | 3936 | I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE); |
3974 | I915_READ(dpll_reg); | 3937 | I915_READ(dpll_reg); |
@@ -4167,7 +4130,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4167 | I915_WRITE(pipeconf_reg, pipeconf); | 4130 | I915_WRITE(pipeconf_reg, pipeconf); |
4168 | I915_READ(pipeconf_reg); | 4131 | I915_READ(pipeconf_reg); |
4169 | 4132 | ||
4170 | intel_wait_for_vblank(dev); | 4133 | intel_wait_for_vblank(dev, pipe); |
4171 | 4134 | ||
4172 | if (IS_IRONLAKE(dev)) { | 4135 | if (IS_IRONLAKE(dev)) { |
4173 | /* enable address swizzle for tiling buffer */ | 4136 | /* enable address swizzle for tiling buffer */ |
@@ -4180,9 +4143,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
4180 | /* Flush the plane changes */ | 4143 | /* Flush the plane changes */ |
4181 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 4144 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
4182 | 4145 | ||
4183 | if ((IS_I965G(dev) || plane == 0)) | ||
4184 | intel_update_fbc(crtc, &crtc->mode); | ||
4185 | |||
4186 | intel_update_watermarks(dev); | 4146 | intel_update_watermarks(dev); |
4187 | 4147 | ||
4188 | drm_vblank_post_modeset(dev, pipe); | 4148 | drm_vblank_post_modeset(dev, pipe); |
@@ -4216,6 +4176,62 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
4216 | } | 4176 | } |
4217 | } | 4177 | } |
4218 | 4178 | ||
4179 | static void i845_update_cursor(struct drm_crtc *crtc, u32 base) | ||
4180 | { | ||
4181 | struct drm_device *dev = crtc->dev; | ||
4182 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4183 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4184 | bool visible = base != 0; | ||
4185 | u32 cntl; | ||
4186 | |||
4187 | if (intel_crtc->cursor_visible == visible) | ||
4188 | return; | ||
4189 | |||
4190 | cntl = I915_READ(CURACNTR); | ||
4191 | if (visible) { | ||
4192 | /* On these chipsets we can only modify the base whilst | ||
4193 | * the cursor is disabled. | ||
4194 | */ | ||
4195 | I915_WRITE(CURABASE, base); | ||
4196 | |||
4197 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
4198 | /* XXX width must be 64, stride 256 => 0x00 << 28 */ | ||
4199 | cntl |= CURSOR_ENABLE | | ||
4200 | CURSOR_GAMMA_ENABLE | | ||
4201 | CURSOR_FORMAT_ARGB; | ||
4202 | } else | ||
4203 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
4204 | I915_WRITE(CURACNTR, cntl); | ||
4205 | |||
4206 | intel_crtc->cursor_visible = visible; | ||
4207 | } | ||
4208 | |||
4209 | static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) | ||
4210 | { | ||
4211 | struct drm_device *dev = crtc->dev; | ||
4212 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
4213 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
4214 | int pipe = intel_crtc->pipe; | ||
4215 | bool visible = base != 0; | ||
4216 | |||
4217 | if (intel_crtc->cursor_visible != visible) { | ||
4218 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | ||
4219 | if (base) { | ||
4220 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
4221 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
4222 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
4223 | } else { | ||
4224 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
4225 | cntl |= CURSOR_MODE_DISABLE; | ||
4226 | } | ||
4227 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
4228 | |||
4229 | intel_crtc->cursor_visible = visible; | ||
4230 | } | ||
4231 | /* and commit changes on next vblank */ | ||
4232 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
4233 | } | ||
4234 | |||
4219 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ | 4235 | /* If no-part of the cursor is visible on the framebuffer, then the GPU may hang... */ |
4220 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) | 4236 | static void intel_crtc_update_cursor(struct drm_crtc *crtc) |
4221 | { | 4237 | { |
@@ -4225,12 +4241,12 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
4225 | int pipe = intel_crtc->pipe; | 4241 | int pipe = intel_crtc->pipe; |
4226 | int x = intel_crtc->cursor_x; | 4242 | int x = intel_crtc->cursor_x; |
4227 | int y = intel_crtc->cursor_y; | 4243 | int y = intel_crtc->cursor_y; |
4228 | uint32_t base, pos; | 4244 | u32 base, pos; |
4229 | bool visible; | 4245 | bool visible; |
4230 | 4246 | ||
4231 | pos = 0; | 4247 | pos = 0; |
4232 | 4248 | ||
4233 | if (crtc->fb) { | 4249 | if (intel_crtc->cursor_on && crtc->fb) { |
4234 | base = intel_crtc->cursor_addr; | 4250 | base = intel_crtc->cursor_addr; |
4235 | if (x > (int) crtc->fb->width) | 4251 | if (x > (int) crtc->fb->width) |
4236 | base = 0; | 4252 | base = 0; |
@@ -4259,37 +4275,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc) | |||
4259 | pos |= y << CURSOR_Y_SHIFT; | 4275 | pos |= y << CURSOR_Y_SHIFT; |
4260 | 4276 | ||
4261 | visible = base != 0; | 4277 | visible = base != 0; |
4262 | if (!visible && !intel_crtc->cursor_visble) | 4278 | if (!visible && !intel_crtc->cursor_visible) |
4263 | return; | 4279 | return; |
4264 | 4280 | ||
4265 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); | 4281 | I915_WRITE(pipe == 0 ? CURAPOS : CURBPOS, pos); |
4266 | if (intel_crtc->cursor_visble != visible) { | 4282 | if (IS_845G(dev) || IS_I865G(dev)) |
4267 | uint32_t cntl = I915_READ(pipe == 0 ? CURACNTR : CURBCNTR); | 4283 | i845_update_cursor(crtc, base); |
4268 | if (base) { | 4284 | else |
4269 | /* Hooray for CUR*CNTR differences */ | 4285 | i9xx_update_cursor(crtc, base); |
4270 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4271 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); | ||
4272 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; | ||
4273 | cntl |= pipe << 28; /* Connect to correct pipe */ | ||
4274 | } else { | ||
4275 | cntl &= ~(CURSOR_FORMAT_MASK); | ||
4276 | cntl |= CURSOR_ENABLE; | ||
4277 | cntl |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; | ||
4278 | } | ||
4279 | } else { | ||
4280 | if (IS_MOBILE(dev) || IS_I9XX(dev)) { | ||
4281 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); | ||
4282 | cntl |= CURSOR_MODE_DISABLE; | ||
4283 | } else { | ||
4284 | cntl &= ~(CURSOR_ENABLE | CURSOR_GAMMA_ENABLE); | ||
4285 | } | ||
4286 | } | ||
4287 | I915_WRITE(pipe == 0 ? CURACNTR : CURBCNTR, cntl); | ||
4288 | |||
4289 | intel_crtc->cursor_visble = visible; | ||
4290 | } | ||
4291 | /* and commit changes on next vblank */ | ||
4292 | I915_WRITE(pipe == 0 ? CURABASE : CURBBASE, base); | ||
4293 | 4286 | ||
4294 | if (visible) | 4287 | if (visible) |
4295 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); | 4288 | intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); |
@@ -4354,8 +4347,10 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, | |||
4354 | 4347 | ||
4355 | addr = obj_priv->gtt_offset; | 4348 | addr = obj_priv->gtt_offset; |
4356 | } else { | 4349 | } else { |
4350 | int align = IS_I830(dev) ? 16 * 1024 : 256; | ||
4357 | ret = i915_gem_attach_phys_object(dev, bo, | 4351 | ret = i915_gem_attach_phys_object(dev, bo, |
4358 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1); | 4352 | (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, |
4353 | align); | ||
4359 | if (ret) { | 4354 | if (ret) { |
4360 | DRM_ERROR("failed to attach phys object\n"); | 4355 | DRM_ERROR("failed to attach phys object\n"); |
4361 | goto fail_locked; | 4356 | goto fail_locked; |
@@ -4544,7 +4539,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | |||
4544 | encoder_funcs->commit(encoder); | 4539 | encoder_funcs->commit(encoder); |
4545 | } | 4540 | } |
4546 | /* let the connector get through one full cycle before testing */ | 4541 | /* let the connector get through one full cycle before testing */ |
4547 | intel_wait_for_vblank(dev); | 4542 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
4548 | 4543 | ||
4549 | return crtc; | 4544 | return crtc; |
4550 | } | 4545 | } |
@@ -4749,7 +4744,7 @@ static void intel_increase_pllclock(struct drm_crtc *crtc, bool schedule) | |||
4749 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; | 4744 | dpll &= ~DISPLAY_RATE_SELECT_FPA1; |
4750 | I915_WRITE(dpll_reg, dpll); | 4745 | I915_WRITE(dpll_reg, dpll); |
4751 | dpll = I915_READ(dpll_reg); | 4746 | dpll = I915_READ(dpll_reg); |
4752 | intel_wait_for_vblank(dev); | 4747 | intel_wait_for_vblank(dev, pipe); |
4753 | dpll = I915_READ(dpll_reg); | 4748 | dpll = I915_READ(dpll_reg); |
4754 | if (dpll & DISPLAY_RATE_SELECT_FPA1) | 4749 | if (dpll & DISPLAY_RATE_SELECT_FPA1) |
4755 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); | 4750 | DRM_DEBUG_DRIVER("failed to upclock LVDS!\n"); |
@@ -4793,7 +4788,7 @@ static void intel_decrease_pllclock(struct drm_crtc *crtc) | |||
4793 | dpll |= DISPLAY_RATE_SELECT_FPA1; | 4788 | dpll |= DISPLAY_RATE_SELECT_FPA1; |
4794 | I915_WRITE(dpll_reg, dpll); | 4789 | I915_WRITE(dpll_reg, dpll); |
4795 | dpll = I915_READ(dpll_reg); | 4790 | dpll = I915_READ(dpll_reg); |
4796 | intel_wait_for_vblank(dev); | 4791 | intel_wait_for_vblank(dev, pipe); |
4797 | dpll = I915_READ(dpll_reg); | 4792 | dpll = I915_READ(dpll_reg); |
4798 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) | 4793 | if (!(dpll & DISPLAY_RATE_SELECT_FPA1)) |
4799 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); | 4794 | DRM_DEBUG_DRIVER("failed to downclock LVDS!\n"); |
@@ -5083,14 +5078,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5083 | work->pending_flip_obj = obj; | 5078 | work->pending_flip_obj = obj; |
5084 | 5079 | ||
5085 | if (intel_crtc->plane) | 5080 | if (intel_crtc->plane) |
5086 | flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT; | 5081 | flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; |
5087 | else | 5082 | else |
5088 | flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT; | 5083 | flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; |
5089 | 5084 | ||
5090 | /* Wait for any previous flip to finish */ | 5085 | if (IS_GEN3(dev) || IS_GEN2(dev)) { |
5091 | if (IS_GEN3(dev)) | 5086 | BEGIN_LP_RING(2); |
5092 | while (I915_READ(ISR) & flip_mask) | 5087 | OUT_RING(MI_WAIT_FOR_EVENT | flip_mask); |
5093 | ; | 5088 | OUT_RING(0); |
5089 | ADVANCE_LP_RING(); | ||
5090 | } | ||
5094 | 5091 | ||
5095 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ | 5092 | /* Offset into the new buffer for cases of shared fbs between CRTCs */ |
5096 | offset = obj_priv->gtt_offset; | 5093 | offset = obj_priv->gtt_offset; |
@@ -5104,12 +5101,18 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, | |||
5104 | OUT_RING(offset | obj_priv->tiling_mode); | 5101 | OUT_RING(offset | obj_priv->tiling_mode); |
5105 | pipesrc = I915_READ(pipesrc_reg); | 5102 | pipesrc = I915_READ(pipesrc_reg); |
5106 | OUT_RING(pipesrc & 0x0fff0fff); | 5103 | OUT_RING(pipesrc & 0x0fff0fff); |
5107 | } else { | 5104 | } else if (IS_GEN3(dev)) { |
5108 | OUT_RING(MI_DISPLAY_FLIP_I915 | | 5105 | OUT_RING(MI_DISPLAY_FLIP_I915 | |
5109 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | 5106 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); |
5110 | OUT_RING(fb->pitch); | 5107 | OUT_RING(fb->pitch); |
5111 | OUT_RING(offset); | 5108 | OUT_RING(offset); |
5112 | OUT_RING(MI_NOOP); | 5109 | OUT_RING(MI_NOOP); |
5110 | } else { | ||
5111 | OUT_RING(MI_DISPLAY_FLIP | | ||
5112 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); | ||
5113 | OUT_RING(fb->pitch); | ||
5114 | OUT_RING(offset); | ||
5115 | OUT_RING(MI_NOOP); | ||
5113 | } | 5116 | } |
5114 | ADVANCE_LP_RING(); | 5117 | ADVANCE_LP_RING(); |
5115 | 5118 | ||
@@ -5432,37 +5435,37 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { | |||
5432 | }; | 5435 | }; |
5433 | 5436 | ||
5434 | static struct drm_gem_object * | 5437 | static struct drm_gem_object * |
5435 | intel_alloc_power_context(struct drm_device *dev) | 5438 | intel_alloc_context_page(struct drm_device *dev) |
5436 | { | 5439 | { |
5437 | struct drm_gem_object *pwrctx; | 5440 | struct drm_gem_object *ctx; |
5438 | int ret; | 5441 | int ret; |
5439 | 5442 | ||
5440 | pwrctx = i915_gem_alloc_object(dev, 4096); | 5443 | ctx = i915_gem_alloc_object(dev, 4096); |
5441 | if (!pwrctx) { | 5444 | if (!ctx) { |
5442 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); | 5445 | DRM_DEBUG("failed to alloc power context, RC6 disabled\n"); |
5443 | return NULL; | 5446 | return NULL; |
5444 | } | 5447 | } |
5445 | 5448 | ||
5446 | mutex_lock(&dev->struct_mutex); | 5449 | mutex_lock(&dev->struct_mutex); |
5447 | ret = i915_gem_object_pin(pwrctx, 4096); | 5450 | ret = i915_gem_object_pin(ctx, 4096); |
5448 | if (ret) { | 5451 | if (ret) { |
5449 | DRM_ERROR("failed to pin power context: %d\n", ret); | 5452 | DRM_ERROR("failed to pin power context: %d\n", ret); |
5450 | goto err_unref; | 5453 | goto err_unref; |
5451 | } | 5454 | } |
5452 | 5455 | ||
5453 | ret = i915_gem_object_set_to_gtt_domain(pwrctx, 1); | 5456 | ret = i915_gem_object_set_to_gtt_domain(ctx, 1); |
5454 | if (ret) { | 5457 | if (ret) { |
5455 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); | 5458 | DRM_ERROR("failed to set-domain on power context: %d\n", ret); |
5456 | goto err_unpin; | 5459 | goto err_unpin; |
5457 | } | 5460 | } |
5458 | mutex_unlock(&dev->struct_mutex); | 5461 | mutex_unlock(&dev->struct_mutex); |
5459 | 5462 | ||
5460 | return pwrctx; | 5463 | return ctx; |
5461 | 5464 | ||
5462 | err_unpin: | 5465 | err_unpin: |
5463 | i915_gem_object_unpin(pwrctx); | 5466 | i915_gem_object_unpin(ctx); |
5464 | err_unref: | 5467 | err_unref: |
5465 | drm_gem_object_unreference(pwrctx); | 5468 | drm_gem_object_unreference(ctx); |
5466 | mutex_unlock(&dev->struct_mutex); | 5469 | mutex_unlock(&dev->struct_mutex); |
5467 | return NULL; | 5470 | return NULL; |
5468 | } | 5471 | } |
@@ -5494,7 +5497,6 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5494 | struct drm_i915_private *dev_priv = dev->dev_private; | 5497 | struct drm_i915_private *dev_priv = dev->dev_private; |
5495 | u32 rgvmodectl = I915_READ(MEMMODECTL); | 5498 | u32 rgvmodectl = I915_READ(MEMMODECTL); |
5496 | u8 fmax, fmin, fstart, vstart; | 5499 | u8 fmax, fmin, fstart, vstart; |
5497 | int i = 0; | ||
5498 | 5500 | ||
5499 | /* 100ms RC evaluation intervals */ | 5501 | /* 100ms RC evaluation intervals */ |
5500 | I915_WRITE(RCUPEI, 100000); | 5502 | I915_WRITE(RCUPEI, 100000); |
@@ -5538,13 +5540,8 @@ void ironlake_enable_drps(struct drm_device *dev) | |||
5538 | rgvmodectl |= MEMMODE_SWMODE_EN; | 5540 | rgvmodectl |= MEMMODE_SWMODE_EN; |
5539 | I915_WRITE(MEMMODECTL, rgvmodectl); | 5541 | I915_WRITE(MEMMODECTL, rgvmodectl); |
5540 | 5542 | ||
5541 | while (I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) { | 5543 | if (wait_for((I915_READ(MEMSWCTL) & MEMCTL_CMD_STS) == 0, 1, 0)) |
5542 | if (i++ > 100) { | 5544 | DRM_ERROR("stuck trying to change perf mode\n"); |
5543 | DRM_ERROR("stuck trying to change perf mode\n"); | ||
5544 | break; | ||
5545 | } | ||
5546 | msleep(1); | ||
5547 | } | ||
5548 | msleep(1); | 5545 | msleep(1); |
5549 | 5546 | ||
5550 | ironlake_set_drps(dev, fstart); | 5547 | ironlake_set_drps(dev, fstart); |
@@ -5725,7 +5722,8 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5725 | ILK_DPFC_DIS2 | | 5722 | ILK_DPFC_DIS2 | |
5726 | ILK_CLK_FBC); | 5723 | ILK_CLK_FBC); |
5727 | } | 5724 | } |
5728 | return; | 5725 | if (IS_GEN6(dev)) |
5726 | return; | ||
5729 | } else if (IS_G4X(dev)) { | 5727 | } else if (IS_G4X(dev)) { |
5730 | uint32_t dspclk_gate; | 5728 | uint32_t dspclk_gate; |
5731 | I915_WRITE(RENCLK_GATE_D1, 0); | 5729 | I915_WRITE(RENCLK_GATE_D1, 0); |
@@ -5768,6 +5766,31 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5768 | * GPU can automatically power down the render unit if given a page | 5766 | * GPU can automatically power down the render unit if given a page |
5769 | * to save state. | 5767 | * to save state. |
5770 | */ | 5768 | */ |
5769 | if (IS_IRONLAKE_M(dev)) { | ||
5770 | if (dev_priv->renderctx == NULL) | ||
5771 | dev_priv->renderctx = intel_alloc_context_page(dev); | ||
5772 | if (dev_priv->renderctx) { | ||
5773 | struct drm_i915_gem_object *obj_priv; | ||
5774 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
5775 | if (obj_priv) { | ||
5776 | BEGIN_LP_RING(4); | ||
5777 | OUT_RING(MI_SET_CONTEXT); | ||
5778 | OUT_RING(obj_priv->gtt_offset | | ||
5779 | MI_MM_SPACE_GTT | | ||
5780 | MI_SAVE_EXT_STATE_EN | | ||
5781 | MI_RESTORE_EXT_STATE_EN | | ||
5782 | MI_RESTORE_INHIBIT); | ||
5783 | OUT_RING(MI_NOOP); | ||
5784 | OUT_RING(MI_FLUSH); | ||
5785 | ADVANCE_LP_RING(); | ||
5786 | } | ||
5787 | } else { | ||
5788 | DRM_DEBUG_KMS("Failed to allocate render context." | ||
5789 | "Disable RC6\n"); | ||
5790 | return; | ||
5791 | } | ||
5792 | } | ||
5793 | |||
5771 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { | 5794 | if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { |
5772 | struct drm_i915_gem_object *obj_priv = NULL; | 5795 | struct drm_i915_gem_object *obj_priv = NULL; |
5773 | 5796 | ||
@@ -5776,7 +5799,7 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5776 | } else { | 5799 | } else { |
5777 | struct drm_gem_object *pwrctx; | 5800 | struct drm_gem_object *pwrctx; |
5778 | 5801 | ||
5779 | pwrctx = intel_alloc_power_context(dev); | 5802 | pwrctx = intel_alloc_context_page(dev); |
5780 | if (pwrctx) { | 5803 | if (pwrctx) { |
5781 | dev_priv->pwrctx = pwrctx; | 5804 | dev_priv->pwrctx = pwrctx; |
5782 | obj_priv = to_intel_bo(pwrctx); | 5805 | obj_priv = to_intel_bo(pwrctx); |
@@ -5948,6 +5971,29 @@ static void intel_init_quirks(struct drm_device *dev) | |||
5948 | } | 5971 | } |
5949 | } | 5972 | } |
5950 | 5973 | ||
5974 | /* Disable the VGA plane that we never use */ | ||
5975 | static void i915_disable_vga(struct drm_device *dev) | ||
5976 | { | ||
5977 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5978 | u8 sr1; | ||
5979 | u32 vga_reg; | ||
5980 | |||
5981 | if (HAS_PCH_SPLIT(dev)) | ||
5982 | vga_reg = CPU_VGACNTRL; | ||
5983 | else | ||
5984 | vga_reg = VGACNTRL; | ||
5985 | |||
5986 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
5987 | outb(1, VGA_SR_INDEX); | ||
5988 | sr1 = inb(VGA_SR_DATA); | ||
5989 | outb(sr1 | 1<<5, VGA_SR_DATA); | ||
5990 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | ||
5991 | udelay(300); | ||
5992 | |||
5993 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | ||
5994 | POSTING_READ(vga_reg); | ||
5995 | } | ||
5996 | |||
5951 | void intel_modeset_init(struct drm_device *dev) | 5997 | void intel_modeset_init(struct drm_device *dev) |
5952 | { | 5998 | { |
5953 | struct drm_i915_private *dev_priv = dev->dev_private; | 5999 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -5996,6 +6042,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
5996 | 6042 | ||
5997 | intel_init_clock_gating(dev); | 6043 | intel_init_clock_gating(dev); |
5998 | 6044 | ||
6045 | /* Just disable it once at startup */ | ||
6046 | i915_disable_vga(dev); | ||
6047 | |||
5999 | if (IS_IRONLAKE_M(dev)) { | 6048 | if (IS_IRONLAKE_M(dev)) { |
6000 | ironlake_enable_drps(dev); | 6049 | ironlake_enable_drps(dev); |
6001 | intel_init_emon(dev); | 6050 | intel_init_emon(dev); |
@@ -6034,6 +6083,16 @@ void intel_modeset_cleanup(struct drm_device *dev) | |||
6034 | if (dev_priv->display.disable_fbc) | 6083 | if (dev_priv->display.disable_fbc) |
6035 | dev_priv->display.disable_fbc(dev); | 6084 | dev_priv->display.disable_fbc(dev); |
6036 | 6085 | ||
6086 | if (dev_priv->renderctx) { | ||
6087 | struct drm_i915_gem_object *obj_priv; | ||
6088 | |||
6089 | obj_priv = to_intel_bo(dev_priv->renderctx); | ||
6090 | I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN); | ||
6091 | I915_READ(CCID); | ||
6092 | i915_gem_object_unpin(dev_priv->renderctx); | ||
6093 | drm_gem_object_unreference(dev_priv->renderctx); | ||
6094 | } | ||
6095 | |||
6037 | if (dev_priv->pwrctx) { | 6096 | if (dev_priv->pwrctx) { |
6038 | struct drm_i915_gem_object *obj_priv; | 6097 | struct drm_i915_gem_object *obj_priv; |
6039 | 6098 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 40be1fa65be1..9caccd03dccb 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -42,10 +42,11 @@ | |||
42 | 42 | ||
43 | #define DP_LINK_CONFIGURATION_SIZE 9 | 43 | #define DP_LINK_CONFIGURATION_SIZE 9 |
44 | 44 | ||
45 | #define IS_eDP(i) ((i)->type == INTEL_OUTPUT_EDP) | 45 | #define IS_eDP(i) ((i)->base.type == INTEL_OUTPUT_EDP) |
46 | #define IS_PCH_eDP(dp_priv) ((dp_priv)->is_pch_edp) | 46 | #define IS_PCH_eDP(i) ((i)->is_pch_edp) |
47 | 47 | ||
48 | struct intel_dp_priv { | 48 | struct intel_dp { |
49 | struct intel_encoder base; | ||
49 | uint32_t output_reg; | 50 | uint32_t output_reg; |
50 | uint32_t DP; | 51 | uint32_t DP; |
51 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; | 52 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]; |
@@ -54,40 +55,39 @@ struct intel_dp_priv { | |||
54 | uint8_t link_bw; | 55 | uint8_t link_bw; |
55 | uint8_t lane_count; | 56 | uint8_t lane_count; |
56 | uint8_t dpcd[4]; | 57 | uint8_t dpcd[4]; |
57 | struct intel_encoder *intel_encoder; | ||
58 | struct i2c_adapter adapter; | 58 | struct i2c_adapter adapter; |
59 | struct i2c_algo_dp_aux_data algo; | 59 | struct i2c_algo_dp_aux_data algo; |
60 | bool is_pch_edp; | 60 | bool is_pch_edp; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static void | 63 | static struct intel_dp *enc_to_intel_dp(struct drm_encoder *encoder) |
64 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 64 | { |
65 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]); | 65 | return container_of(enc_to_intel_encoder(encoder), struct intel_dp, base); |
66 | } | ||
66 | 67 | ||
67 | static void | 68 | static void intel_dp_link_train(struct intel_dp *intel_dp); |
68 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP); | 69 | static void intel_dp_link_down(struct intel_dp *intel_dp); |
69 | 70 | ||
70 | void | 71 | void |
71 | intel_edp_link_config (struct intel_encoder *intel_encoder, | 72 | intel_edp_link_config (struct intel_encoder *intel_encoder, |
72 | int *lane_num, int *link_bw) | 73 | int *lane_num, int *link_bw) |
73 | { | 74 | { |
74 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 75 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
75 | 76 | ||
76 | *lane_num = dp_priv->lane_count; | 77 | *lane_num = intel_dp->lane_count; |
77 | if (dp_priv->link_bw == DP_LINK_BW_1_62) | 78 | if (intel_dp->link_bw == DP_LINK_BW_1_62) |
78 | *link_bw = 162000; | 79 | *link_bw = 162000; |
79 | else if (dp_priv->link_bw == DP_LINK_BW_2_7) | 80 | else if (intel_dp->link_bw == DP_LINK_BW_2_7) |
80 | *link_bw = 270000; | 81 | *link_bw = 270000; |
81 | } | 82 | } |
82 | 83 | ||
83 | static int | 84 | static int |
84 | intel_dp_max_lane_count(struct intel_encoder *intel_encoder) | 85 | intel_dp_max_lane_count(struct intel_dp *intel_dp) |
85 | { | 86 | { |
86 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
87 | int max_lane_count = 4; | 87 | int max_lane_count = 4; |
88 | 88 | ||
89 | if (dp_priv->dpcd[0] >= 0x11) { | 89 | if (intel_dp->dpcd[0] >= 0x11) { |
90 | max_lane_count = dp_priv->dpcd[2] & 0x1f; | 90 | max_lane_count = intel_dp->dpcd[2] & 0x1f; |
91 | switch (max_lane_count) { | 91 | switch (max_lane_count) { |
92 | case 1: case 2: case 4: | 92 | case 1: case 2: case 4: |
93 | break; | 93 | break; |
@@ -99,10 +99,9 @@ intel_dp_max_lane_count(struct intel_encoder *intel_encoder) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | static int | 101 | static int |
102 | intel_dp_max_link_bw(struct intel_encoder *intel_encoder) | 102 | intel_dp_max_link_bw(struct intel_dp *intel_dp) |
103 | { | 103 | { |
104 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 104 | int max_link_bw = intel_dp->dpcd[1]; |
105 | int max_link_bw = dp_priv->dpcd[1]; | ||
106 | 105 | ||
107 | switch (max_link_bw) { | 106 | switch (max_link_bw) { |
108 | case DP_LINK_BW_1_62: | 107 | case DP_LINK_BW_1_62: |
@@ -126,13 +125,11 @@ intel_dp_link_clock(uint8_t link_bw) | |||
126 | 125 | ||
127 | /* I think this is a fiction */ | 126 | /* I think this is a fiction */ |
128 | static int | 127 | static int |
129 | intel_dp_link_required(struct drm_device *dev, | 128 | intel_dp_link_required(struct drm_device *dev, struct intel_dp *intel_dp, int pixel_clock) |
130 | struct intel_encoder *intel_encoder, int pixel_clock) | ||
131 | { | 129 | { |
132 | struct drm_i915_private *dev_priv = dev->dev_private; | 130 | struct drm_i915_private *dev_priv = dev->dev_private; |
133 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
134 | 131 | ||
135 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) | 132 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
136 | return (pixel_clock * dev_priv->edp_bpp) / 8; | 133 | return (pixel_clock * dev_priv->edp_bpp) / 8; |
137 | else | 134 | else |
138 | return pixel_clock * 3; | 135 | return pixel_clock * 3; |
@@ -149,14 +146,13 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
149 | struct drm_display_mode *mode) | 146 | struct drm_display_mode *mode) |
150 | { | 147 | { |
151 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 148 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 149 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
153 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
154 | struct drm_device *dev = connector->dev; | 150 | struct drm_device *dev = connector->dev; |
155 | struct drm_i915_private *dev_priv = dev->dev_private; | 151 | struct drm_i915_private *dev_priv = dev->dev_private; |
156 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_encoder)); | 152 | int max_link_clock = intel_dp_link_clock(intel_dp_max_link_bw(intel_dp)); |
157 | int max_lanes = intel_dp_max_lane_count(intel_encoder); | 153 | int max_lanes = intel_dp_max_lane_count(intel_dp); |
158 | 154 | ||
159 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 155 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
160 | dev_priv->panel_fixed_mode) { | 156 | dev_priv->panel_fixed_mode) { |
161 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) | 157 | if (mode->hdisplay > dev_priv->panel_fixed_mode->hdisplay) |
162 | return MODE_PANEL; | 158 | return MODE_PANEL; |
@@ -167,8 +163,8 @@ intel_dp_mode_valid(struct drm_connector *connector, | |||
167 | 163 | ||
168 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels | 164 | /* only refuse the mode on non eDP since we have seen some wierd eDP panels |
169 | which are outside spec tolerances but somehow work by magic */ | 165 | which are outside spec tolerances but somehow work by magic */ |
170 | if (!IS_eDP(intel_encoder) && | 166 | if (!IS_eDP(intel_dp) && |
171 | (intel_dp_link_required(connector->dev, intel_encoder, mode->clock) | 167 | (intel_dp_link_required(connector->dev, intel_dp, mode->clock) |
172 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) | 168 | > intel_dp_max_data_rate(max_link_clock, max_lanes))) |
173 | return MODE_CLOCK_HIGH; | 169 | return MODE_CLOCK_HIGH; |
174 | 170 | ||
@@ -232,13 +228,12 @@ intel_hrawclk(struct drm_device *dev) | |||
232 | } | 228 | } |
233 | 229 | ||
234 | static int | 230 | static int |
235 | intel_dp_aux_ch(struct intel_encoder *intel_encoder, | 231 | intel_dp_aux_ch(struct intel_dp *intel_dp, |
236 | uint8_t *send, int send_bytes, | 232 | uint8_t *send, int send_bytes, |
237 | uint8_t *recv, int recv_size) | 233 | uint8_t *recv, int recv_size) |
238 | { | 234 | { |
239 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 235 | uint32_t output_reg = intel_dp->output_reg; |
240 | uint32_t output_reg = dp_priv->output_reg; | 236 | struct drm_device *dev = intel_dp->base.enc.dev; |
241 | struct drm_device *dev = intel_encoder->enc.dev; | ||
242 | struct drm_i915_private *dev_priv = dev->dev_private; | 237 | struct drm_i915_private *dev_priv = dev->dev_private; |
243 | uint32_t ch_ctl = output_reg + 0x10; | 238 | uint32_t ch_ctl = output_reg + 0x10; |
244 | uint32_t ch_data = ch_ctl + 4; | 239 | uint32_t ch_data = ch_ctl + 4; |
@@ -253,7 +248,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
253 | * and would like to run at 2MHz. So, take the | 248 | * and would like to run at 2MHz. So, take the |
254 | * hrawclk value and divide by 2 and use that | 249 | * hrawclk value and divide by 2 and use that |
255 | */ | 250 | */ |
256 | if (IS_eDP(intel_encoder)) { | 251 | if (IS_eDP(intel_dp)) { |
257 | if (IS_GEN6(dev)) | 252 | if (IS_GEN6(dev)) |
258 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ | 253 | aux_clock_divider = 200; /* SNB eDP input clock at 400Mhz */ |
259 | else | 254 | else |
@@ -344,7 +339,7 @@ intel_dp_aux_ch(struct intel_encoder *intel_encoder, | |||
344 | 339 | ||
345 | /* Write data to the aux channel in native mode */ | 340 | /* Write data to the aux channel in native mode */ |
346 | static int | 341 | static int |
347 | intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | 342 | intel_dp_aux_native_write(struct intel_dp *intel_dp, |
348 | uint16_t address, uint8_t *send, int send_bytes) | 343 | uint16_t address, uint8_t *send, int send_bytes) |
349 | { | 344 | { |
350 | int ret; | 345 | int ret; |
@@ -361,7 +356,7 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | |||
361 | memcpy(&msg[4], send, send_bytes); | 356 | memcpy(&msg[4], send, send_bytes); |
362 | msg_bytes = send_bytes + 4; | 357 | msg_bytes = send_bytes + 4; |
363 | for (;;) { | 358 | for (;;) { |
364 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, &ack, 1); | 359 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, &ack, 1); |
365 | if (ret < 0) | 360 | if (ret < 0) |
366 | return ret; | 361 | return ret; |
367 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) | 362 | if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK) |
@@ -376,15 +371,15 @@ intel_dp_aux_native_write(struct intel_encoder *intel_encoder, | |||
376 | 371 | ||
377 | /* Write a single byte to the aux channel in native mode */ | 372 | /* Write a single byte to the aux channel in native mode */ |
378 | static int | 373 | static int |
379 | intel_dp_aux_native_write_1(struct intel_encoder *intel_encoder, | 374 | intel_dp_aux_native_write_1(struct intel_dp *intel_dp, |
380 | uint16_t address, uint8_t byte) | 375 | uint16_t address, uint8_t byte) |
381 | { | 376 | { |
382 | return intel_dp_aux_native_write(intel_encoder, address, &byte, 1); | 377 | return intel_dp_aux_native_write(intel_dp, address, &byte, 1); |
383 | } | 378 | } |
384 | 379 | ||
385 | /* read bytes from a native aux channel */ | 380 | /* read bytes from a native aux channel */ |
386 | static int | 381 | static int |
387 | intel_dp_aux_native_read(struct intel_encoder *intel_encoder, | 382 | intel_dp_aux_native_read(struct intel_dp *intel_dp, |
388 | uint16_t address, uint8_t *recv, int recv_bytes) | 383 | uint16_t address, uint8_t *recv, int recv_bytes) |
389 | { | 384 | { |
390 | uint8_t msg[4]; | 385 | uint8_t msg[4]; |
@@ -403,7 +398,7 @@ intel_dp_aux_native_read(struct intel_encoder *intel_encoder, | |||
403 | reply_bytes = recv_bytes + 1; | 398 | reply_bytes = recv_bytes + 1; |
404 | 399 | ||
405 | for (;;) { | 400 | for (;;) { |
406 | ret = intel_dp_aux_ch(intel_encoder, msg, msg_bytes, | 401 | ret = intel_dp_aux_ch(intel_dp, msg, msg_bytes, |
407 | reply, reply_bytes); | 402 | reply, reply_bytes); |
408 | if (ret == 0) | 403 | if (ret == 0) |
409 | return -EPROTO; | 404 | return -EPROTO; |
@@ -426,10 +421,9 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
426 | uint8_t write_byte, uint8_t *read_byte) | 421 | uint8_t write_byte, uint8_t *read_byte) |
427 | { | 422 | { |
428 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; | 423 | struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data; |
429 | struct intel_dp_priv *dp_priv = container_of(adapter, | 424 | struct intel_dp *intel_dp = container_of(adapter, |
430 | struct intel_dp_priv, | 425 | struct intel_dp, |
431 | adapter); | 426 | adapter); |
432 | struct intel_encoder *intel_encoder = dp_priv->intel_encoder; | ||
433 | uint16_t address = algo_data->address; | 427 | uint16_t address = algo_data->address; |
434 | uint8_t msg[5]; | 428 | uint8_t msg[5]; |
435 | uint8_t reply[2]; | 429 | uint8_t reply[2]; |
@@ -468,7 +462,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
468 | } | 462 | } |
469 | 463 | ||
470 | for (;;) { | 464 | for (;;) { |
471 | ret = intel_dp_aux_ch(intel_encoder, | 465 | ret = intel_dp_aux_ch(intel_dp, |
472 | msg, msg_bytes, | 466 | msg, msg_bytes, |
473 | reply, reply_bytes); | 467 | reply, reply_bytes); |
474 | if (ret < 0) { | 468 | if (ret < 0) { |
@@ -496,57 +490,42 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
496 | } | 490 | } |
497 | 491 | ||
498 | static int | 492 | static int |
499 | intel_dp_i2c_init(struct intel_encoder *intel_encoder, | 493 | intel_dp_i2c_init(struct intel_dp *intel_dp, |
500 | struct intel_connector *intel_connector, const char *name) | 494 | struct intel_connector *intel_connector, const char *name) |
501 | { | 495 | { |
502 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
503 | |||
504 | DRM_DEBUG_KMS("i2c_init %s\n", name); | 496 | DRM_DEBUG_KMS("i2c_init %s\n", name); |
505 | dp_priv->algo.running = false; | 497 | intel_dp->algo.running = false; |
506 | dp_priv->algo.address = 0; | 498 | intel_dp->algo.address = 0; |
507 | dp_priv->algo.aux_ch = intel_dp_i2c_aux_ch; | 499 | intel_dp->algo.aux_ch = intel_dp_i2c_aux_ch; |
508 | 500 | ||
509 | memset(&dp_priv->adapter, '\0', sizeof (dp_priv->adapter)); | 501 | memset(&intel_dp->adapter, '\0', sizeof (intel_dp->adapter)); |
510 | dp_priv->adapter.owner = THIS_MODULE; | 502 | intel_dp->adapter.owner = THIS_MODULE; |
511 | dp_priv->adapter.class = I2C_CLASS_DDC; | 503 | intel_dp->adapter.class = I2C_CLASS_DDC; |
512 | strncpy (dp_priv->adapter.name, name, sizeof(dp_priv->adapter.name) - 1); | 504 | strncpy (intel_dp->adapter.name, name, sizeof(intel_dp->adapter.name) - 1); |
513 | dp_priv->adapter.name[sizeof(dp_priv->adapter.name) - 1] = '\0'; | 505 | intel_dp->adapter.name[sizeof(intel_dp->adapter.name) - 1] = '\0'; |
514 | dp_priv->adapter.algo_data = &dp_priv->algo; | 506 | intel_dp->adapter.algo_data = &intel_dp->algo; |
515 | dp_priv->adapter.dev.parent = &intel_connector->base.kdev; | 507 | intel_dp->adapter.dev.parent = &intel_connector->base.kdev; |
516 | 508 | ||
517 | return i2c_dp_aux_add_bus(&dp_priv->adapter); | 509 | return i2c_dp_aux_add_bus(&intel_dp->adapter); |
518 | } | 510 | } |
519 | 511 | ||
520 | static bool | 512 | static bool |
521 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | 513 | intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, |
522 | struct drm_display_mode *adjusted_mode) | 514 | struct drm_display_mode *adjusted_mode) |
523 | { | 515 | { |
524 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
525 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
526 | struct drm_device *dev = encoder->dev; | 516 | struct drm_device *dev = encoder->dev; |
527 | struct drm_i915_private *dev_priv = dev->dev_private; | 517 | struct drm_i915_private *dev_priv = dev->dev_private; |
518 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
528 | int lane_count, clock; | 519 | int lane_count, clock; |
529 | int max_lane_count = intel_dp_max_lane_count(intel_encoder); | 520 | int max_lane_count = intel_dp_max_lane_count(intel_dp); |
530 | int max_clock = intel_dp_max_link_bw(intel_encoder) == DP_LINK_BW_2_7 ? 1 : 0; | 521 | int max_clock = intel_dp_max_link_bw(intel_dp) == DP_LINK_BW_2_7 ? 1 : 0; |
531 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; | 522 | static int bws[2] = { DP_LINK_BW_1_62, DP_LINK_BW_2_7 }; |
532 | 523 | ||
533 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 524 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
534 | dev_priv->panel_fixed_mode) { | 525 | dev_priv->panel_fixed_mode) { |
535 | struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode; | 526 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); |
536 | 527 | intel_pch_panel_fitting(dev, DRM_MODE_SCALE_FULLSCREEN, | |
537 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | 528 | mode, adjusted_mode); |
538 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
539 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
540 | adjusted_mode->htotal = fixed_mode->htotal; | ||
541 | |||
542 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
543 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
544 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
545 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
546 | |||
547 | adjusted_mode->clock = fixed_mode->clock; | ||
548 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
549 | |||
550 | /* | 529 | /* |
551 | * the mode->clock is used to calculate the Data&Link M/N | 530 | * the mode->clock is used to calculate the Data&Link M/N |
552 | * of the pipe. For the eDP the fixed clock should be used. | 531 | * of the pipe. For the eDP the fixed clock should be used. |
@@ -558,31 +537,33 @@ intel_dp_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
558 | for (clock = 0; clock <= max_clock; clock++) { | 537 | for (clock = 0; clock <= max_clock; clock++) { |
559 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); | 538 | int link_avail = intel_dp_max_data_rate(intel_dp_link_clock(bws[clock]), lane_count); |
560 | 539 | ||
561 | if (intel_dp_link_required(encoder->dev, intel_encoder, mode->clock) | 540 | if (intel_dp_link_required(encoder->dev, intel_dp, mode->clock) |
562 | <= link_avail) { | 541 | <= link_avail) { |
563 | dp_priv->link_bw = bws[clock]; | 542 | intel_dp->link_bw = bws[clock]; |
564 | dp_priv->lane_count = lane_count; | 543 | intel_dp->lane_count = lane_count; |
565 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 544 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
566 | DRM_DEBUG_KMS("Display port link bw %02x lane " | 545 | DRM_DEBUG_KMS("Display port link bw %02x lane " |
567 | "count %d clock %d\n", | 546 | "count %d clock %d\n", |
568 | dp_priv->link_bw, dp_priv->lane_count, | 547 | intel_dp->link_bw, intel_dp->lane_count, |
569 | adjusted_mode->clock); | 548 | adjusted_mode->clock); |
570 | return true; | 549 | return true; |
571 | } | 550 | } |
572 | } | 551 | } |
573 | } | 552 | } |
574 | 553 | ||
575 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 554 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
576 | /* okay we failed just pick the highest */ | 555 | /* okay we failed just pick the highest */ |
577 | dp_priv->lane_count = max_lane_count; | 556 | intel_dp->lane_count = max_lane_count; |
578 | dp_priv->link_bw = bws[max_clock]; | 557 | intel_dp->link_bw = bws[max_clock]; |
579 | adjusted_mode->clock = intel_dp_link_clock(dp_priv->link_bw); | 558 | adjusted_mode->clock = intel_dp_link_clock(intel_dp->link_bw); |
580 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " | 559 | DRM_DEBUG_KMS("Force picking display port link bw %02x lane " |
581 | "count %d clock %d\n", | 560 | "count %d clock %d\n", |
582 | dp_priv->link_bw, dp_priv->lane_count, | 561 | intel_dp->link_bw, intel_dp->lane_count, |
583 | adjusted_mode->clock); | 562 | adjusted_mode->clock); |
563 | |||
584 | return true; | 564 | return true; |
585 | } | 565 | } |
566 | |||
586 | return false; | 567 | return false; |
587 | } | 568 | } |
588 | 569 | ||
@@ -626,17 +607,14 @@ bool intel_pch_has_edp(struct drm_crtc *crtc) | |||
626 | struct drm_encoder *encoder; | 607 | struct drm_encoder *encoder; |
627 | 608 | ||
628 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 609 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
629 | struct intel_encoder *intel_encoder; | 610 | struct intel_dp *intel_dp; |
630 | struct intel_dp_priv *dp_priv; | ||
631 | 611 | ||
632 | if (!encoder || encoder->crtc != crtc) | 612 | if (encoder->crtc != crtc) |
633 | continue; | 613 | continue; |
634 | 614 | ||
635 | intel_encoder = enc_to_intel_encoder(encoder); | 615 | intel_dp = enc_to_intel_dp(encoder); |
636 | dp_priv = intel_encoder->dev_priv; | 616 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) |
637 | 617 | return intel_dp->is_pch_edp; | |
638 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) | ||
639 | return dp_priv->is_pch_edp; | ||
640 | } | 618 | } |
641 | return false; | 619 | return false; |
642 | } | 620 | } |
@@ -657,18 +635,15 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, | |||
657 | * Find the lane count in the intel_encoder private | 635 | * Find the lane count in the intel_encoder private |
658 | */ | 636 | */ |
659 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 637 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
660 | struct intel_encoder *intel_encoder; | 638 | struct intel_dp *intel_dp; |
661 | struct intel_dp_priv *dp_priv; | ||
662 | 639 | ||
663 | if (encoder->crtc != crtc) | 640 | if (encoder->crtc != crtc) |
664 | continue; | 641 | continue; |
665 | 642 | ||
666 | intel_encoder = enc_to_intel_encoder(encoder); | 643 | intel_dp = enc_to_intel_dp(encoder); |
667 | dp_priv = intel_encoder->dev_priv; | 644 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) { |
668 | 645 | lane_count = intel_dp->lane_count; | |
669 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 646 | if (IS_PCH_eDP(intel_dp)) |
670 | lane_count = dp_priv->lane_count; | ||
671 | if (IS_PCH_eDP(dp_priv)) | ||
672 | bpp = dev_priv->edp_bpp; | 647 | bpp = dev_priv->edp_bpp; |
673 | break; | 648 | break; |
674 | } | 649 | } |
@@ -724,107 +699,114 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
724 | struct drm_display_mode *adjusted_mode) | 699 | struct drm_display_mode *adjusted_mode) |
725 | { | 700 | { |
726 | struct drm_device *dev = encoder->dev; | 701 | struct drm_device *dev = encoder->dev; |
727 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 702 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
728 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 703 | struct drm_crtc *crtc = intel_dp->base.enc.crtc; |
729 | struct drm_crtc *crtc = intel_encoder->enc.crtc; | ||
730 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 704 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
731 | 705 | ||
732 | dp_priv->DP = (DP_VOLTAGE_0_4 | | 706 | intel_dp->DP = (DP_VOLTAGE_0_4 | |
733 | DP_PRE_EMPHASIS_0); | 707 | DP_PRE_EMPHASIS_0); |
734 | 708 | ||
735 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 709 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
736 | dp_priv->DP |= DP_SYNC_HS_HIGH; | 710 | intel_dp->DP |= DP_SYNC_HS_HIGH; |
737 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) | 711 | if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) |
738 | dp_priv->DP |= DP_SYNC_VS_HIGH; | 712 | intel_dp->DP |= DP_SYNC_VS_HIGH; |
739 | 713 | ||
740 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 714 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
741 | dp_priv->DP |= DP_LINK_TRAIN_OFF_CPT; | 715 | intel_dp->DP |= DP_LINK_TRAIN_OFF_CPT; |
742 | else | 716 | else |
743 | dp_priv->DP |= DP_LINK_TRAIN_OFF; | 717 | intel_dp->DP |= DP_LINK_TRAIN_OFF; |
744 | 718 | ||
745 | switch (dp_priv->lane_count) { | 719 | switch (intel_dp->lane_count) { |
746 | case 1: | 720 | case 1: |
747 | dp_priv->DP |= DP_PORT_WIDTH_1; | 721 | intel_dp->DP |= DP_PORT_WIDTH_1; |
748 | break; | 722 | break; |
749 | case 2: | 723 | case 2: |
750 | dp_priv->DP |= DP_PORT_WIDTH_2; | 724 | intel_dp->DP |= DP_PORT_WIDTH_2; |
751 | break; | 725 | break; |
752 | case 4: | 726 | case 4: |
753 | dp_priv->DP |= DP_PORT_WIDTH_4; | 727 | intel_dp->DP |= DP_PORT_WIDTH_4; |
754 | break; | 728 | break; |
755 | } | 729 | } |
756 | if (dp_priv->has_audio) | 730 | if (intel_dp->has_audio) |
757 | dp_priv->DP |= DP_AUDIO_OUTPUT_ENABLE; | 731 | intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; |
758 | 732 | ||
759 | memset(dp_priv->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); | 733 | memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); |
760 | dp_priv->link_configuration[0] = dp_priv->link_bw; | 734 | intel_dp->link_configuration[0] = intel_dp->link_bw; |
761 | dp_priv->link_configuration[1] = dp_priv->lane_count; | 735 | intel_dp->link_configuration[1] = intel_dp->lane_count; |
762 | 736 | ||
763 | /* | 737 | /* |
764 | * Check for DPCD version > 1.1 and enhanced framing support | 738 | * Check for DPCD version > 1.1 and enhanced framing support |
765 | */ | 739 | */ |
766 | if (dp_priv->dpcd[0] >= 0x11 && (dp_priv->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { | 740 | if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { |
767 | dp_priv->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 741 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
768 | dp_priv->DP |= DP_ENHANCED_FRAMING; | 742 | intel_dp->DP |= DP_ENHANCED_FRAMING; |
769 | } | 743 | } |
770 | 744 | ||
771 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ | 745 | /* CPT DP's pipe select is decided in TRANS_DP_CTL */ |
772 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) | 746 | if (intel_crtc->pipe == 1 && !HAS_PCH_CPT(dev)) |
773 | dp_priv->DP |= DP_PIPEB_SELECT; | 747 | intel_dp->DP |= DP_PIPEB_SELECT; |
774 | 748 | ||
775 | if (IS_eDP(intel_encoder)) { | 749 | if (IS_eDP(intel_dp)) { |
776 | /* don't miss out required setting for eDP */ | 750 | /* don't miss out required setting for eDP */ |
777 | dp_priv->DP |= DP_PLL_ENABLE; | 751 | intel_dp->DP |= DP_PLL_ENABLE; |
778 | if (adjusted_mode->clock < 200000) | 752 | if (adjusted_mode->clock < 200000) |
779 | dp_priv->DP |= DP_PLL_FREQ_160MHZ; | 753 | intel_dp->DP |= DP_PLL_FREQ_160MHZ; |
780 | else | 754 | else |
781 | dp_priv->DP |= DP_PLL_FREQ_270MHZ; | 755 | intel_dp->DP |= DP_PLL_FREQ_270MHZ; |
782 | } | 756 | } |
783 | } | 757 | } |
784 | 758 | ||
785 | static void ironlake_edp_panel_on (struct drm_device *dev) | 759 | static void ironlake_edp_panel_on (struct drm_device *dev) |
786 | { | 760 | { |
787 | struct drm_i915_private *dev_priv = dev->dev_private; | 761 | struct drm_i915_private *dev_priv = dev->dev_private; |
788 | unsigned long timeout = jiffies + msecs_to_jiffies(5000); | 762 | u32 pp; |
789 | u32 pp, pp_status; | ||
790 | 763 | ||
791 | pp_status = I915_READ(PCH_PP_STATUS); | 764 | if (I915_READ(PCH_PP_STATUS) & PP_ON) |
792 | if (pp_status & PP_ON) | ||
793 | return; | 765 | return; |
794 | 766 | ||
795 | pp = I915_READ(PCH_PP_CONTROL); | 767 | pp = I915_READ(PCH_PP_CONTROL); |
768 | |||
769 | /* ILK workaround: disable reset around power sequence */ | ||
770 | pp &= ~PANEL_POWER_RESET; | ||
771 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
772 | POSTING_READ(PCH_PP_CONTROL); | ||
773 | |||
796 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; | 774 | pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON; |
797 | I915_WRITE(PCH_PP_CONTROL, pp); | 775 | I915_WRITE(PCH_PP_CONTROL, pp); |
798 | do { | ||
799 | pp_status = I915_READ(PCH_PP_STATUS); | ||
800 | } while (((pp_status & PP_ON) == 0) && !time_after(jiffies, timeout)); | ||
801 | 776 | ||
802 | if (time_after(jiffies, timeout)) | 777 | if (wait_for(I915_READ(PCH_PP_STATUS) & PP_ON, 5000, 10)) |
803 | DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status); | 778 | DRM_ERROR("panel on wait timed out: 0x%08x\n", |
779 | I915_READ(PCH_PP_STATUS)); | ||
804 | 780 | ||
805 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); | 781 | pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD); |
782 | pp |= PANEL_POWER_RESET; /* restore panel reset bit */ | ||
806 | I915_WRITE(PCH_PP_CONTROL, pp); | 783 | I915_WRITE(PCH_PP_CONTROL, pp); |
784 | POSTING_READ(PCH_PP_CONTROL); | ||
807 | } | 785 | } |
808 | 786 | ||
809 | static void ironlake_edp_panel_off (struct drm_device *dev) | 787 | static void ironlake_edp_panel_off (struct drm_device *dev) |
810 | { | 788 | { |
811 | struct drm_i915_private *dev_priv = dev->dev_private; | 789 | struct drm_i915_private *dev_priv = dev->dev_private; |
812 | unsigned long timeout = jiffies + msecs_to_jiffies(5000); | 790 | u32 pp; |
813 | u32 pp, pp_status; | ||
814 | 791 | ||
815 | pp = I915_READ(PCH_PP_CONTROL); | 792 | pp = I915_READ(PCH_PP_CONTROL); |
793 | |||
794 | /* ILK workaround: disable reset around power sequence */ | ||
795 | pp &= ~PANEL_POWER_RESET; | ||
796 | I915_WRITE(PCH_PP_CONTROL, pp); | ||
797 | POSTING_READ(PCH_PP_CONTROL); | ||
798 | |||
816 | pp &= ~POWER_TARGET_ON; | 799 | pp &= ~POWER_TARGET_ON; |
817 | I915_WRITE(PCH_PP_CONTROL, pp); | 800 | I915_WRITE(PCH_PP_CONTROL, pp); |
818 | do { | ||
819 | pp_status = I915_READ(PCH_PP_STATUS); | ||
820 | } while ((pp_status & PP_ON) && !time_after(jiffies, timeout)); | ||
821 | 801 | ||
822 | if (time_after(jiffies, timeout)) | 802 | if (wait_for((I915_READ(PCH_PP_STATUS) & PP_ON) == 0, 5000, 10)) |
823 | DRM_DEBUG_KMS("panel off wait timed out\n"); | 803 | DRM_ERROR("panel off wait timed out: 0x%08x\n", |
804 | I915_READ(PCH_PP_STATUS)); | ||
824 | 805 | ||
825 | /* Make sure VDD is enabled so DP AUX will work */ | 806 | /* Make sure VDD is enabled so DP AUX will work */ |
826 | pp |= EDP_FORCE_VDD; | 807 | pp |= EDP_FORCE_VDD | PANEL_POWER_RESET; /* restore panel reset bit */ |
827 | I915_WRITE(PCH_PP_CONTROL, pp); | 808 | I915_WRITE(PCH_PP_CONTROL, pp); |
809 | POSTING_READ(PCH_PP_CONTROL); | ||
828 | } | 810 | } |
829 | 811 | ||
830 | static void ironlake_edp_backlight_on (struct drm_device *dev) | 812 | static void ironlake_edp_backlight_on (struct drm_device *dev) |
@@ -849,33 +831,87 @@ static void ironlake_edp_backlight_off (struct drm_device *dev) | |||
849 | I915_WRITE(PCH_PP_CONTROL, pp); | 831 | I915_WRITE(PCH_PP_CONTROL, pp); |
850 | } | 832 | } |
851 | 833 | ||
834 | static void ironlake_edp_pll_on(struct drm_encoder *encoder) | ||
835 | { | ||
836 | struct drm_device *dev = encoder->dev; | ||
837 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
838 | u32 dpa_ctl; | ||
839 | |||
840 | DRM_DEBUG_KMS("\n"); | ||
841 | dpa_ctl = I915_READ(DP_A); | ||
842 | dpa_ctl &= ~DP_PLL_ENABLE; | ||
843 | I915_WRITE(DP_A, dpa_ctl); | ||
844 | } | ||
845 | |||
846 | static void ironlake_edp_pll_off(struct drm_encoder *encoder) | ||
847 | { | ||
848 | struct drm_device *dev = encoder->dev; | ||
849 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
850 | u32 dpa_ctl; | ||
851 | |||
852 | dpa_ctl = I915_READ(DP_A); | ||
853 | dpa_ctl |= DP_PLL_ENABLE; | ||
854 | I915_WRITE(DP_A, dpa_ctl); | ||
855 | udelay(200); | ||
856 | } | ||
857 | |||
858 | static void intel_dp_prepare(struct drm_encoder *encoder) | ||
859 | { | ||
860 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
861 | struct drm_device *dev = encoder->dev; | ||
862 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
863 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
864 | |||
865 | if (IS_eDP(intel_dp)) { | ||
866 | ironlake_edp_backlight_off(dev); | ||
867 | ironlake_edp_panel_on(dev); | ||
868 | ironlake_edp_pll_on(encoder); | ||
869 | } | ||
870 | if (dp_reg & DP_PORT_EN) | ||
871 | intel_dp_link_down(intel_dp); | ||
872 | } | ||
873 | |||
874 | static void intel_dp_commit(struct drm_encoder *encoder) | ||
875 | { | ||
876 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | ||
877 | struct drm_device *dev = encoder->dev; | ||
878 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
879 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); | ||
880 | |||
881 | if (!(dp_reg & DP_PORT_EN)) { | ||
882 | intel_dp_link_train(intel_dp); | ||
883 | } | ||
884 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
885 | ironlake_edp_backlight_on(dev); | ||
886 | } | ||
887 | |||
852 | static void | 888 | static void |
853 | intel_dp_dpms(struct drm_encoder *encoder, int mode) | 889 | intel_dp_dpms(struct drm_encoder *encoder, int mode) |
854 | { | 890 | { |
855 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 891 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
856 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
857 | struct drm_device *dev = encoder->dev; | 892 | struct drm_device *dev = encoder->dev; |
858 | struct drm_i915_private *dev_priv = dev->dev_private; | 893 | struct drm_i915_private *dev_priv = dev->dev_private; |
859 | uint32_t dp_reg = I915_READ(dp_priv->output_reg); | 894 | uint32_t dp_reg = I915_READ(intel_dp->output_reg); |
860 | 895 | ||
861 | if (mode != DRM_MODE_DPMS_ON) { | 896 | if (mode != DRM_MODE_DPMS_ON) { |
862 | if (dp_reg & DP_PORT_EN) { | 897 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
863 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 898 | ironlake_edp_backlight_off(dev); |
864 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 899 | ironlake_edp_panel_off(dev); |
865 | ironlake_edp_backlight_off(dev); | ||
866 | ironlake_edp_panel_off(dev); | ||
867 | } | ||
868 | } | 900 | } |
901 | if (dp_reg & DP_PORT_EN) | ||
902 | intel_dp_link_down(intel_dp); | ||
903 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
904 | ironlake_edp_pll_off(encoder); | ||
869 | } else { | 905 | } else { |
870 | if (!(dp_reg & DP_PORT_EN)) { | 906 | if (!(dp_reg & DP_PORT_EN)) { |
871 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 907 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) |
872 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | ||
873 | ironlake_edp_panel_on(dev); | 908 | ironlake_edp_panel_on(dev); |
909 | intel_dp_link_train(intel_dp); | ||
910 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) | ||
874 | ironlake_edp_backlight_on(dev); | 911 | ironlake_edp_backlight_on(dev); |
875 | } | ||
876 | } | 912 | } |
877 | } | 913 | } |
878 | dp_priv->dpms_mode = mode; | 914 | intel_dp->dpms_mode = mode; |
879 | } | 915 | } |
880 | 916 | ||
881 | /* | 917 | /* |
@@ -883,12 +919,12 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
883 | * link status information | 919 | * link status information |
884 | */ | 920 | */ |
885 | static bool | 921 | static bool |
886 | intel_dp_get_link_status(struct intel_encoder *intel_encoder, | 922 | intel_dp_get_link_status(struct intel_dp *intel_dp, |
887 | uint8_t link_status[DP_LINK_STATUS_SIZE]) | 923 | uint8_t link_status[DP_LINK_STATUS_SIZE]) |
888 | { | 924 | { |
889 | int ret; | 925 | int ret; |
890 | 926 | ||
891 | ret = intel_dp_aux_native_read(intel_encoder, | 927 | ret = intel_dp_aux_native_read(intel_dp, |
892 | DP_LANE0_1_STATUS, | 928 | DP_LANE0_1_STATUS, |
893 | link_status, DP_LINK_STATUS_SIZE); | 929 | link_status, DP_LINK_STATUS_SIZE); |
894 | if (ret != DP_LINK_STATUS_SIZE) | 930 | if (ret != DP_LINK_STATUS_SIZE) |
@@ -965,7 +1001,7 @@ intel_dp_pre_emphasis_max(uint8_t voltage_swing) | |||
965 | } | 1001 | } |
966 | 1002 | ||
967 | static void | 1003 | static void |
968 | intel_get_adjust_train(struct intel_encoder *intel_encoder, | 1004 | intel_get_adjust_train(struct intel_dp *intel_dp, |
969 | uint8_t link_status[DP_LINK_STATUS_SIZE], | 1005 | uint8_t link_status[DP_LINK_STATUS_SIZE], |
970 | int lane_count, | 1006 | int lane_count, |
971 | uint8_t train_set[4]) | 1007 | uint8_t train_set[4]) |
@@ -1101,27 +1137,27 @@ intel_channel_eq_ok(uint8_t link_status[DP_LINK_STATUS_SIZE], int lane_count) | |||
1101 | } | 1137 | } |
1102 | 1138 | ||
1103 | static bool | 1139 | static bool |
1104 | intel_dp_set_link_train(struct intel_encoder *intel_encoder, | 1140 | intel_dp_set_link_train(struct intel_dp *intel_dp, |
1105 | uint32_t dp_reg_value, | 1141 | uint32_t dp_reg_value, |
1106 | uint8_t dp_train_pat, | 1142 | uint8_t dp_train_pat, |
1107 | uint8_t train_set[4], | 1143 | uint8_t train_set[4], |
1108 | bool first) | 1144 | bool first) |
1109 | { | 1145 | { |
1110 | struct drm_device *dev = intel_encoder->enc.dev; | 1146 | struct drm_device *dev = intel_dp->base.enc.dev; |
1111 | struct drm_i915_private *dev_priv = dev->dev_private; | 1147 | struct drm_i915_private *dev_priv = dev->dev_private; |
1112 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1148 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc); |
1113 | int ret; | 1149 | int ret; |
1114 | 1150 | ||
1115 | I915_WRITE(dp_priv->output_reg, dp_reg_value); | 1151 | I915_WRITE(intel_dp->output_reg, dp_reg_value); |
1116 | POSTING_READ(dp_priv->output_reg); | 1152 | POSTING_READ(intel_dp->output_reg); |
1117 | if (first) | 1153 | if (first) |
1118 | intel_wait_for_vblank(dev); | 1154 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1119 | 1155 | ||
1120 | intel_dp_aux_native_write_1(intel_encoder, | 1156 | intel_dp_aux_native_write_1(intel_dp, |
1121 | DP_TRAINING_PATTERN_SET, | 1157 | DP_TRAINING_PATTERN_SET, |
1122 | dp_train_pat); | 1158 | dp_train_pat); |
1123 | 1159 | ||
1124 | ret = intel_dp_aux_native_write(intel_encoder, | 1160 | ret = intel_dp_aux_native_write(intel_dp, |
1125 | DP_TRAINING_LANE0_SET, train_set, 4); | 1161 | DP_TRAINING_LANE0_SET, train_set, 4); |
1126 | if (ret != 4) | 1162 | if (ret != 4) |
1127 | return false; | 1163 | return false; |
@@ -1130,12 +1166,10 @@ intel_dp_set_link_train(struct intel_encoder *intel_encoder, | |||
1130 | } | 1166 | } |
1131 | 1167 | ||
1132 | static void | 1168 | static void |
1133 | intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | 1169 | intel_dp_link_train(struct intel_dp *intel_dp) |
1134 | uint8_t link_configuration[DP_LINK_CONFIGURATION_SIZE]) | ||
1135 | { | 1170 | { |
1136 | struct drm_device *dev = intel_encoder->enc.dev; | 1171 | struct drm_device *dev = intel_dp->base.enc.dev; |
1137 | struct drm_i915_private *dev_priv = dev->dev_private; | 1172 | struct drm_i915_private *dev_priv = dev->dev_private; |
1138 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1139 | uint8_t train_set[4]; | 1173 | uint8_t train_set[4]; |
1140 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1174 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
1141 | int i; | 1175 | int i; |
@@ -1145,13 +1179,15 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1145 | bool first = true; | 1179 | bool first = true; |
1146 | int tries; | 1180 | int tries; |
1147 | u32 reg; | 1181 | u32 reg; |
1182 | uint32_t DP = intel_dp->DP; | ||
1148 | 1183 | ||
1149 | /* Write the link configuration data */ | 1184 | /* Write the link configuration data */ |
1150 | intel_dp_aux_native_write(intel_encoder, DP_LINK_BW_SET, | 1185 | intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, |
1151 | link_configuration, DP_LINK_CONFIGURATION_SIZE); | 1186 | intel_dp->link_configuration, |
1187 | DP_LINK_CONFIGURATION_SIZE); | ||
1152 | 1188 | ||
1153 | DP |= DP_PORT_EN; | 1189 | DP |= DP_PORT_EN; |
1154 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1190 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
1155 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1191 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1156 | else | 1192 | else |
1157 | DP &= ~DP_LINK_TRAIN_MASK; | 1193 | DP &= ~DP_LINK_TRAIN_MASK; |
@@ -1162,39 +1198,39 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1162 | for (;;) { | 1198 | for (;;) { |
1163 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1199 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
1164 | uint32_t signal_levels; | 1200 | uint32_t signal_levels; |
1165 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | 1201 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
1166 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1202 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); |
1167 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1203 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1168 | } else { | 1204 | } else { |
1169 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1205 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); |
1170 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1206 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1171 | } | 1207 | } |
1172 | 1208 | ||
1173 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1209 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
1174 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; | 1210 | reg = DP | DP_LINK_TRAIN_PAT_1_CPT; |
1175 | else | 1211 | else |
1176 | reg = DP | DP_LINK_TRAIN_PAT_1; | 1212 | reg = DP | DP_LINK_TRAIN_PAT_1; |
1177 | 1213 | ||
1178 | if (!intel_dp_set_link_train(intel_encoder, reg, | 1214 | if (!intel_dp_set_link_train(intel_dp, reg, |
1179 | DP_TRAINING_PATTERN_1, train_set, first)) | 1215 | DP_TRAINING_PATTERN_1, train_set, first)) |
1180 | break; | 1216 | break; |
1181 | first = false; | 1217 | first = false; |
1182 | /* Set training pattern 1 */ | 1218 | /* Set training pattern 1 */ |
1183 | 1219 | ||
1184 | udelay(100); | 1220 | udelay(100); |
1185 | if (!intel_dp_get_link_status(intel_encoder, link_status)) | 1221 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
1186 | break; | 1222 | break; |
1187 | 1223 | ||
1188 | if (intel_clock_recovery_ok(link_status, dp_priv->lane_count)) { | 1224 | if (intel_clock_recovery_ok(link_status, intel_dp->lane_count)) { |
1189 | clock_recovery = true; | 1225 | clock_recovery = true; |
1190 | break; | 1226 | break; |
1191 | } | 1227 | } |
1192 | 1228 | ||
1193 | /* Check to see if we've tried the max voltage */ | 1229 | /* Check to see if we've tried the max voltage */ |
1194 | for (i = 0; i < dp_priv->lane_count; i++) | 1230 | for (i = 0; i < intel_dp->lane_count; i++) |
1195 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) | 1231 | if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) |
1196 | break; | 1232 | break; |
1197 | if (i == dp_priv->lane_count) | 1233 | if (i == intel_dp->lane_count) |
1198 | break; | 1234 | break; |
1199 | 1235 | ||
1200 | /* Check to see if we've tried the same voltage 5 times */ | 1236 | /* Check to see if we've tried the same voltage 5 times */ |
@@ -1207,7 +1243,7 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1207 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; | 1243 | voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK; |
1208 | 1244 | ||
1209 | /* Compute new train_set as requested by target */ | 1245 | /* Compute new train_set as requested by target */ |
1210 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); | 1246 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); |
1211 | } | 1247 | } |
1212 | 1248 | ||
1213 | /* channel equalization */ | 1249 | /* channel equalization */ |
@@ -1217,30 +1253,30 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1217 | /* Use train_set[0] to set the voltage and pre emphasis values */ | 1253 | /* Use train_set[0] to set the voltage and pre emphasis values */ |
1218 | uint32_t signal_levels; | 1254 | uint32_t signal_levels; |
1219 | 1255 | ||
1220 | if (IS_GEN6(dev) && IS_eDP(intel_encoder)) { | 1256 | if (IS_GEN6(dev) && IS_eDP(intel_dp)) { |
1221 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); | 1257 | signal_levels = intel_gen6_edp_signal_levels(train_set[0]); |
1222 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; | 1258 | DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels; |
1223 | } else { | 1259 | } else { |
1224 | signal_levels = intel_dp_signal_levels(train_set[0], dp_priv->lane_count); | 1260 | signal_levels = intel_dp_signal_levels(train_set[0], intel_dp->lane_count); |
1225 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; | 1261 | DP = (DP & ~(DP_VOLTAGE_MASK|DP_PRE_EMPHASIS_MASK)) | signal_levels; |
1226 | } | 1262 | } |
1227 | 1263 | ||
1228 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1264 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
1229 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; | 1265 | reg = DP | DP_LINK_TRAIN_PAT_2_CPT; |
1230 | else | 1266 | else |
1231 | reg = DP | DP_LINK_TRAIN_PAT_2; | 1267 | reg = DP | DP_LINK_TRAIN_PAT_2; |
1232 | 1268 | ||
1233 | /* channel eq pattern */ | 1269 | /* channel eq pattern */ |
1234 | if (!intel_dp_set_link_train(intel_encoder, reg, | 1270 | if (!intel_dp_set_link_train(intel_dp, reg, |
1235 | DP_TRAINING_PATTERN_2, train_set, | 1271 | DP_TRAINING_PATTERN_2, train_set, |
1236 | false)) | 1272 | false)) |
1237 | break; | 1273 | break; |
1238 | 1274 | ||
1239 | udelay(400); | 1275 | udelay(400); |
1240 | if (!intel_dp_get_link_status(intel_encoder, link_status)) | 1276 | if (!intel_dp_get_link_status(intel_dp, link_status)) |
1241 | break; | 1277 | break; |
1242 | 1278 | ||
1243 | if (intel_channel_eq_ok(link_status, dp_priv->lane_count)) { | 1279 | if (intel_channel_eq_ok(link_status, intel_dp->lane_count)) { |
1244 | channel_eq = true; | 1280 | channel_eq = true; |
1245 | break; | 1281 | break; |
1246 | } | 1282 | } |
@@ -1250,53 +1286,53 @@ intel_dp_link_train(struct intel_encoder *intel_encoder, uint32_t DP, | |||
1250 | break; | 1286 | break; |
1251 | 1287 | ||
1252 | /* Compute new train_set as requested by target */ | 1288 | /* Compute new train_set as requested by target */ |
1253 | intel_get_adjust_train(intel_encoder, link_status, dp_priv->lane_count, train_set); | 1289 | intel_get_adjust_train(intel_dp, link_status, intel_dp->lane_count, train_set); |
1254 | ++tries; | 1290 | ++tries; |
1255 | } | 1291 | } |
1256 | 1292 | ||
1257 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) | 1293 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) |
1258 | reg = DP | DP_LINK_TRAIN_OFF_CPT; | 1294 | reg = DP | DP_LINK_TRAIN_OFF_CPT; |
1259 | else | 1295 | else |
1260 | reg = DP | DP_LINK_TRAIN_OFF; | 1296 | reg = DP | DP_LINK_TRAIN_OFF; |
1261 | 1297 | ||
1262 | I915_WRITE(dp_priv->output_reg, reg); | 1298 | I915_WRITE(intel_dp->output_reg, reg); |
1263 | POSTING_READ(dp_priv->output_reg); | 1299 | POSTING_READ(intel_dp->output_reg); |
1264 | intel_dp_aux_native_write_1(intel_encoder, | 1300 | intel_dp_aux_native_write_1(intel_dp, |
1265 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); | 1301 | DP_TRAINING_PATTERN_SET, DP_TRAINING_PATTERN_DISABLE); |
1266 | } | 1302 | } |
1267 | 1303 | ||
1268 | static void | 1304 | static void |
1269 | intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | 1305 | intel_dp_link_down(struct intel_dp *intel_dp) |
1270 | { | 1306 | { |
1271 | struct drm_device *dev = intel_encoder->enc.dev; | 1307 | struct drm_device *dev = intel_dp->base.enc.dev; |
1272 | struct drm_i915_private *dev_priv = dev->dev_private; | 1308 | struct drm_i915_private *dev_priv = dev->dev_private; |
1273 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1309 | uint32_t DP = intel_dp->DP; |
1274 | 1310 | ||
1275 | DRM_DEBUG_KMS("\n"); | 1311 | DRM_DEBUG_KMS("\n"); |
1276 | 1312 | ||
1277 | if (IS_eDP(intel_encoder)) { | 1313 | if (IS_eDP(intel_dp)) { |
1278 | DP &= ~DP_PLL_ENABLE; | 1314 | DP &= ~DP_PLL_ENABLE; |
1279 | I915_WRITE(dp_priv->output_reg, DP); | 1315 | I915_WRITE(intel_dp->output_reg, DP); |
1280 | POSTING_READ(dp_priv->output_reg); | 1316 | POSTING_READ(intel_dp->output_reg); |
1281 | udelay(100); | 1317 | udelay(100); |
1282 | } | 1318 | } |
1283 | 1319 | ||
1284 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_encoder)) { | 1320 | if (HAS_PCH_CPT(dev) && !IS_eDP(intel_dp)) { |
1285 | DP &= ~DP_LINK_TRAIN_MASK_CPT; | 1321 | DP &= ~DP_LINK_TRAIN_MASK_CPT; |
1286 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); | 1322 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE_CPT); |
1287 | POSTING_READ(dp_priv->output_reg); | 1323 | POSTING_READ(intel_dp->output_reg); |
1288 | } else { | 1324 | } else { |
1289 | DP &= ~DP_LINK_TRAIN_MASK; | 1325 | DP &= ~DP_LINK_TRAIN_MASK; |
1290 | I915_WRITE(dp_priv->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); | 1326 | I915_WRITE(intel_dp->output_reg, DP | DP_LINK_TRAIN_PAT_IDLE); |
1291 | POSTING_READ(dp_priv->output_reg); | 1327 | POSTING_READ(intel_dp->output_reg); |
1292 | } | 1328 | } |
1293 | 1329 | ||
1294 | udelay(17000); | 1330 | udelay(17000); |
1295 | 1331 | ||
1296 | if (IS_eDP(intel_encoder)) | 1332 | if (IS_eDP(intel_dp)) |
1297 | DP |= DP_LINK_TRAIN_OFF; | 1333 | DP |= DP_LINK_TRAIN_OFF; |
1298 | I915_WRITE(dp_priv->output_reg, DP & ~DP_PORT_EN); | 1334 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
1299 | POSTING_READ(dp_priv->output_reg); | 1335 | POSTING_READ(intel_dp->output_reg); |
1300 | } | 1336 | } |
1301 | 1337 | ||
1302 | /* | 1338 | /* |
@@ -1309,41 +1345,39 @@ intel_dp_link_down(struct intel_encoder *intel_encoder, uint32_t DP) | |||
1309 | */ | 1345 | */ |
1310 | 1346 | ||
1311 | static void | 1347 | static void |
1312 | intel_dp_check_link_status(struct intel_encoder *intel_encoder) | 1348 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1313 | { | 1349 | { |
1314 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1315 | uint8_t link_status[DP_LINK_STATUS_SIZE]; | 1350 | uint8_t link_status[DP_LINK_STATUS_SIZE]; |
1316 | 1351 | ||
1317 | if (!intel_encoder->enc.crtc) | 1352 | if (!intel_dp->base.enc.crtc) |
1318 | return; | 1353 | return; |
1319 | 1354 | ||
1320 | if (!intel_dp_get_link_status(intel_encoder, link_status)) { | 1355 | if (!intel_dp_get_link_status(intel_dp, link_status)) { |
1321 | intel_dp_link_down(intel_encoder, dp_priv->DP); | 1356 | intel_dp_link_down(intel_dp); |
1322 | return; | 1357 | return; |
1323 | } | 1358 | } |
1324 | 1359 | ||
1325 | if (!intel_channel_eq_ok(link_status, dp_priv->lane_count)) | 1360 | if (!intel_channel_eq_ok(link_status, intel_dp->lane_count)) |
1326 | intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration); | 1361 | intel_dp_link_train(intel_dp); |
1327 | } | 1362 | } |
1328 | 1363 | ||
1329 | static enum drm_connector_status | 1364 | static enum drm_connector_status |
1330 | ironlake_dp_detect(struct drm_connector *connector) | 1365 | ironlake_dp_detect(struct drm_connector *connector) |
1331 | { | 1366 | { |
1332 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1367 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1333 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1368 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1334 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1335 | enum drm_connector_status status; | 1369 | enum drm_connector_status status; |
1336 | 1370 | ||
1337 | status = connector_status_disconnected; | 1371 | status = connector_status_disconnected; |
1338 | if (intel_dp_aux_native_read(intel_encoder, | 1372 | if (intel_dp_aux_native_read(intel_dp, |
1339 | 0x000, dp_priv->dpcd, | 1373 | 0x000, intel_dp->dpcd, |
1340 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1374 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
1341 | { | 1375 | { |
1342 | if (dp_priv->dpcd[0] != 0) | 1376 | if (intel_dp->dpcd[0] != 0) |
1343 | status = connector_status_connected; | 1377 | status = connector_status_connected; |
1344 | } | 1378 | } |
1345 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", dp_priv->dpcd[0], | 1379 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
1346 | dp_priv->dpcd[1], dp_priv->dpcd[2], dp_priv->dpcd[3]); | 1380 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
1347 | return status; | 1381 | return status; |
1348 | } | 1382 | } |
1349 | 1383 | ||
@@ -1357,19 +1391,18 @@ static enum drm_connector_status | |||
1357 | intel_dp_detect(struct drm_connector *connector) | 1391 | intel_dp_detect(struct drm_connector *connector) |
1358 | { | 1392 | { |
1359 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1393 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1360 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1394 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1361 | struct drm_device *dev = intel_encoder->enc.dev; | 1395 | struct drm_device *dev = intel_dp->base.enc.dev; |
1362 | struct drm_i915_private *dev_priv = dev->dev_private; | 1396 | struct drm_i915_private *dev_priv = dev->dev_private; |
1363 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1364 | uint32_t temp, bit; | 1397 | uint32_t temp, bit; |
1365 | enum drm_connector_status status; | 1398 | enum drm_connector_status status; |
1366 | 1399 | ||
1367 | dp_priv->has_audio = false; | 1400 | intel_dp->has_audio = false; |
1368 | 1401 | ||
1369 | if (HAS_PCH_SPLIT(dev)) | 1402 | if (HAS_PCH_SPLIT(dev)) |
1370 | return ironlake_dp_detect(connector); | 1403 | return ironlake_dp_detect(connector); |
1371 | 1404 | ||
1372 | switch (dp_priv->output_reg) { | 1405 | switch (intel_dp->output_reg) { |
1373 | case DP_B: | 1406 | case DP_B: |
1374 | bit = DPB_HOTPLUG_INT_STATUS; | 1407 | bit = DPB_HOTPLUG_INT_STATUS; |
1375 | break; | 1408 | break; |
@@ -1389,11 +1422,11 @@ intel_dp_detect(struct drm_connector *connector) | |||
1389 | return connector_status_disconnected; | 1422 | return connector_status_disconnected; |
1390 | 1423 | ||
1391 | status = connector_status_disconnected; | 1424 | status = connector_status_disconnected; |
1392 | if (intel_dp_aux_native_read(intel_encoder, | 1425 | if (intel_dp_aux_native_read(intel_dp, |
1393 | 0x000, dp_priv->dpcd, | 1426 | 0x000, intel_dp->dpcd, |
1394 | sizeof (dp_priv->dpcd)) == sizeof (dp_priv->dpcd)) | 1427 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
1395 | { | 1428 | { |
1396 | if (dp_priv->dpcd[0] != 0) | 1429 | if (intel_dp->dpcd[0] != 0) |
1397 | status = connector_status_connected; | 1430 | status = connector_status_connected; |
1398 | } | 1431 | } |
1399 | return status; | 1432 | return status; |
@@ -1402,18 +1435,17 @@ intel_dp_detect(struct drm_connector *connector) | |||
1402 | static int intel_dp_get_modes(struct drm_connector *connector) | 1435 | static int intel_dp_get_modes(struct drm_connector *connector) |
1403 | { | 1436 | { |
1404 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1437 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1405 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1438 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1406 | struct drm_device *dev = intel_encoder->enc.dev; | 1439 | struct drm_device *dev = intel_dp->base.enc.dev; |
1407 | struct drm_i915_private *dev_priv = dev->dev_private; | 1440 | struct drm_i915_private *dev_priv = dev->dev_private; |
1408 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | ||
1409 | int ret; | 1441 | int ret; |
1410 | 1442 | ||
1411 | /* We should parse the EDID data and find out if it has an audio sink | 1443 | /* We should parse the EDID data and find out if it has an audio sink |
1412 | */ | 1444 | */ |
1413 | 1445 | ||
1414 | ret = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1446 | ret = intel_ddc_get_modes(connector, intel_dp->base.ddc_bus); |
1415 | if (ret) { | 1447 | if (ret) { |
1416 | if ((IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) && | 1448 | if ((IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) && |
1417 | !dev_priv->panel_fixed_mode) { | 1449 | !dev_priv->panel_fixed_mode) { |
1418 | struct drm_display_mode *newmode; | 1450 | struct drm_display_mode *newmode; |
1419 | list_for_each_entry(newmode, &connector->probed_modes, | 1451 | list_for_each_entry(newmode, &connector->probed_modes, |
@@ -1430,7 +1462,7 @@ static int intel_dp_get_modes(struct drm_connector *connector) | |||
1430 | } | 1462 | } |
1431 | 1463 | ||
1432 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ | 1464 | /* if eDP has no EDID, try to use fixed panel mode from VBT */ |
1433 | if (IS_eDP(intel_encoder) || IS_PCH_eDP(dp_priv)) { | 1465 | if (IS_eDP(intel_dp) || IS_PCH_eDP(intel_dp)) { |
1434 | if (dev_priv->panel_fixed_mode != NULL) { | 1466 | if (dev_priv->panel_fixed_mode != NULL) { |
1435 | struct drm_display_mode *mode; | 1467 | struct drm_display_mode *mode; |
1436 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); | 1468 | mode = drm_mode_duplicate(dev, dev_priv->panel_fixed_mode); |
@@ -1452,9 +1484,9 @@ intel_dp_destroy (struct drm_connector *connector) | |||
1452 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { | 1484 | static const struct drm_encoder_helper_funcs intel_dp_helper_funcs = { |
1453 | .dpms = intel_dp_dpms, | 1485 | .dpms = intel_dp_dpms, |
1454 | .mode_fixup = intel_dp_mode_fixup, | 1486 | .mode_fixup = intel_dp_mode_fixup, |
1455 | .prepare = intel_encoder_prepare, | 1487 | .prepare = intel_dp_prepare, |
1456 | .mode_set = intel_dp_mode_set, | 1488 | .mode_set = intel_dp_mode_set, |
1457 | .commit = intel_encoder_commit, | 1489 | .commit = intel_dp_commit, |
1458 | }; | 1490 | }; |
1459 | 1491 | ||
1460 | static const struct drm_connector_funcs intel_dp_connector_funcs = { | 1492 | static const struct drm_connector_funcs intel_dp_connector_funcs = { |
@@ -1470,27 +1502,17 @@ static const struct drm_connector_helper_funcs intel_dp_connector_helper_funcs = | |||
1470 | .best_encoder = intel_attached_encoder, | 1502 | .best_encoder = intel_attached_encoder, |
1471 | }; | 1503 | }; |
1472 | 1504 | ||
1473 | static void intel_dp_enc_destroy(struct drm_encoder *encoder) | ||
1474 | { | ||
1475 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1476 | |||
1477 | if (intel_encoder->i2c_bus) | ||
1478 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
1479 | drm_encoder_cleanup(encoder); | ||
1480 | kfree(intel_encoder); | ||
1481 | } | ||
1482 | |||
1483 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { | 1505 | static const struct drm_encoder_funcs intel_dp_enc_funcs = { |
1484 | .destroy = intel_dp_enc_destroy, | 1506 | .destroy = intel_encoder_destroy, |
1485 | }; | 1507 | }; |
1486 | 1508 | ||
1487 | void | 1509 | void |
1488 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) | 1510 | intel_dp_hot_plug(struct intel_encoder *intel_encoder) |
1489 | { | 1511 | { |
1490 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1512 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
1491 | 1513 | ||
1492 | if (dp_priv->dpms_mode == DRM_MODE_DPMS_ON) | 1514 | if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON) |
1493 | intel_dp_check_link_status(intel_encoder); | 1515 | intel_dp_check_link_status(intel_dp); |
1494 | } | 1516 | } |
1495 | 1517 | ||
1496 | /* Return which DP Port should be selected for Transcoder DP control */ | 1518 | /* Return which DP Port should be selected for Transcoder DP control */ |
@@ -1500,18 +1522,18 @@ intel_trans_dp_port_sel (struct drm_crtc *crtc) | |||
1500 | struct drm_device *dev = crtc->dev; | 1522 | struct drm_device *dev = crtc->dev; |
1501 | struct drm_mode_config *mode_config = &dev->mode_config; | 1523 | struct drm_mode_config *mode_config = &dev->mode_config; |
1502 | struct drm_encoder *encoder; | 1524 | struct drm_encoder *encoder; |
1503 | struct intel_encoder *intel_encoder = NULL; | ||
1504 | 1525 | ||
1505 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { | 1526 | list_for_each_entry(encoder, &mode_config->encoder_list, head) { |
1527 | struct intel_dp *intel_dp; | ||
1528 | |||
1506 | if (encoder->crtc != crtc) | 1529 | if (encoder->crtc != crtc) |
1507 | continue; | 1530 | continue; |
1508 | 1531 | ||
1509 | intel_encoder = enc_to_intel_encoder(encoder); | 1532 | intel_dp = enc_to_intel_dp(encoder); |
1510 | if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) { | 1533 | if (intel_dp->base.type == INTEL_OUTPUT_DISPLAYPORT) |
1511 | struct intel_dp_priv *dp_priv = intel_encoder->dev_priv; | 1534 | return intel_dp->output_reg; |
1512 | return dp_priv->output_reg; | ||
1513 | } | ||
1514 | } | 1535 | } |
1536 | |||
1515 | return -1; | 1537 | return -1; |
1516 | } | 1538 | } |
1517 | 1539 | ||
@@ -1540,30 +1562,28 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1540 | { | 1562 | { |
1541 | struct drm_i915_private *dev_priv = dev->dev_private; | 1563 | struct drm_i915_private *dev_priv = dev->dev_private; |
1542 | struct drm_connector *connector; | 1564 | struct drm_connector *connector; |
1565 | struct intel_dp *intel_dp; | ||
1543 | struct intel_encoder *intel_encoder; | 1566 | struct intel_encoder *intel_encoder; |
1544 | struct intel_connector *intel_connector; | 1567 | struct intel_connector *intel_connector; |
1545 | struct intel_dp_priv *dp_priv; | ||
1546 | const char *name = NULL; | 1568 | const char *name = NULL; |
1547 | int type; | 1569 | int type; |
1548 | 1570 | ||
1549 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 1571 | intel_dp = kzalloc(sizeof(struct intel_dp), GFP_KERNEL); |
1550 | sizeof(struct intel_dp_priv), 1, GFP_KERNEL); | 1572 | if (!intel_dp) |
1551 | if (!intel_encoder) | ||
1552 | return; | 1573 | return; |
1553 | 1574 | ||
1554 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1575 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1555 | if (!intel_connector) { | 1576 | if (!intel_connector) { |
1556 | kfree(intel_encoder); | 1577 | kfree(intel_dp); |
1557 | return; | 1578 | return; |
1558 | } | 1579 | } |
1580 | intel_encoder = &intel_dp->base; | ||
1559 | 1581 | ||
1560 | dp_priv = (struct intel_dp_priv *)(intel_encoder + 1); | 1582 | if (HAS_PCH_SPLIT(dev) && output_reg == PCH_DP_D) |
1561 | |||
1562 | if (HAS_PCH_SPLIT(dev) && (output_reg == PCH_DP_D)) | ||
1563 | if (intel_dpd_is_edp(dev)) | 1583 | if (intel_dpd_is_edp(dev)) |
1564 | dp_priv->is_pch_edp = true; | 1584 | intel_dp->is_pch_edp = true; |
1565 | 1585 | ||
1566 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | 1586 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
1567 | type = DRM_MODE_CONNECTOR_eDP; | 1587 | type = DRM_MODE_CONNECTOR_eDP; |
1568 | intel_encoder->type = INTEL_OUTPUT_EDP; | 1588 | intel_encoder->type = INTEL_OUTPUT_EDP; |
1569 | } else { | 1589 | } else { |
@@ -1584,18 +1604,16 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1584 | else if (output_reg == DP_D || output_reg == PCH_DP_D) | 1604 | else if (output_reg == DP_D || output_reg == PCH_DP_D) |
1585 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); | 1605 | intel_encoder->clone_mask = (1 << INTEL_DP_D_CLONE_BIT); |
1586 | 1606 | ||
1587 | if (IS_eDP(intel_encoder)) | 1607 | if (IS_eDP(intel_dp)) |
1588 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); | 1608 | intel_encoder->clone_mask = (1 << INTEL_EDP_CLONE_BIT); |
1589 | 1609 | ||
1590 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1610 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1591 | connector->interlace_allowed = true; | 1611 | connector->interlace_allowed = true; |
1592 | connector->doublescan_allowed = 0; | 1612 | connector->doublescan_allowed = 0; |
1593 | 1613 | ||
1594 | dp_priv->intel_encoder = intel_encoder; | 1614 | intel_dp->output_reg = output_reg; |
1595 | dp_priv->output_reg = output_reg; | 1615 | intel_dp->has_audio = false; |
1596 | dp_priv->has_audio = false; | 1616 | intel_dp->dpms_mode = DRM_MODE_DPMS_ON; |
1597 | dp_priv->dpms_mode = DRM_MODE_DPMS_ON; | ||
1598 | intel_encoder->dev_priv = dp_priv; | ||
1599 | 1617 | ||
1600 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, | 1618 | drm_encoder_init(dev, &intel_encoder->enc, &intel_dp_enc_funcs, |
1601 | DRM_MODE_ENCODER_TMDS); | 1619 | DRM_MODE_ENCODER_TMDS); |
@@ -1630,12 +1648,12 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1630 | break; | 1648 | break; |
1631 | } | 1649 | } |
1632 | 1650 | ||
1633 | intel_dp_i2c_init(intel_encoder, intel_connector, name); | 1651 | intel_dp_i2c_init(intel_dp, intel_connector, name); |
1634 | 1652 | ||
1635 | intel_encoder->ddc_bus = &dp_priv->adapter; | 1653 | intel_encoder->ddc_bus = &intel_dp->adapter; |
1636 | intel_encoder->hot_plug = intel_dp_hot_plug; | 1654 | intel_encoder->hot_plug = intel_dp_hot_plug; |
1637 | 1655 | ||
1638 | if (output_reg == DP_A || IS_PCH_eDP(dp_priv)) { | 1656 | if (output_reg == DP_A || IS_PCH_eDP(intel_dp)) { |
1639 | /* initialize panel mode from VBT if available for eDP */ | 1657 | /* initialize panel mode from VBT if available for eDP */ |
1640 | if (dev_priv->lfp_lvds_vbt_mode) { | 1658 | if (dev_priv->lfp_lvds_vbt_mode) { |
1641 | dev_priv->panel_fixed_mode = | 1659 | dev_priv->panel_fixed_mode = |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index b2190148703a..0e92aa07b382 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -32,6 +32,20 @@ | |||
32 | #include "drm_crtc.h" | 32 | #include "drm_crtc.h" |
33 | 33 | ||
34 | #include "drm_crtc_helper.h" | 34 | #include "drm_crtc_helper.h" |
35 | |||
36 | #define wait_for(COND, MS, W) ({ \ | ||
37 | unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \ | ||
38 | int ret__ = 0; \ | ||
39 | while (! (COND)) { \ | ||
40 | if (time_after(jiffies, timeout__)) { \ | ||
41 | ret__ = -ETIMEDOUT; \ | ||
42 | break; \ | ||
43 | } \ | ||
44 | if (W) msleep(W); \ | ||
45 | } \ | ||
46 | ret__; \ | ||
47 | }) | ||
48 | |||
35 | /* | 49 | /* |
36 | * Display related stuff | 50 | * Display related stuff |
37 | */ | 51 | */ |
@@ -102,7 +116,6 @@ struct intel_encoder { | |||
102 | struct i2c_adapter *ddc_bus; | 116 | struct i2c_adapter *ddc_bus; |
103 | bool load_detect_temp; | 117 | bool load_detect_temp; |
104 | bool needs_tv_clock; | 118 | bool needs_tv_clock; |
105 | void *dev_priv; | ||
106 | void (*hot_plug)(struct intel_encoder *); | 119 | void (*hot_plug)(struct intel_encoder *); |
107 | int crtc_mask; | 120 | int crtc_mask; |
108 | int clone_mask; | 121 | int clone_mask; |
@@ -110,7 +123,6 @@ struct intel_encoder { | |||
110 | 123 | ||
111 | struct intel_connector { | 124 | struct intel_connector { |
112 | struct drm_connector base; | 125 | struct drm_connector base; |
113 | void *dev_priv; | ||
114 | }; | 126 | }; |
115 | 127 | ||
116 | struct intel_crtc; | 128 | struct intel_crtc; |
@@ -156,7 +168,7 @@ struct intel_crtc { | |||
156 | uint32_t cursor_addr; | 168 | uint32_t cursor_addr; |
157 | int16_t cursor_x, cursor_y; | 169 | int16_t cursor_x, cursor_y; |
158 | int16_t cursor_width, cursor_height; | 170 | int16_t cursor_width, cursor_height; |
159 | bool cursor_visble; | 171 | bool cursor_visible, cursor_on; |
160 | }; | 172 | }; |
161 | 173 | ||
162 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) | 174 | #define to_intel_crtc(x) container_of(x, struct intel_crtc, base) |
@@ -188,10 +200,18 @@ extern bool intel_dpd_is_edp(struct drm_device *dev); | |||
188 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); | 200 | extern void intel_edp_link_config (struct intel_encoder *, int *, int *); |
189 | 201 | ||
190 | 202 | ||
203 | extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
204 | struct drm_display_mode *adjusted_mode); | ||
205 | extern void intel_pch_panel_fitting(struct drm_device *dev, | ||
206 | int fitting_mode, | ||
207 | struct drm_display_mode *mode, | ||
208 | struct drm_display_mode *adjusted_mode); | ||
209 | |||
191 | extern int intel_panel_fitter_pipe (struct drm_device *dev); | 210 | extern int intel_panel_fitter_pipe (struct drm_device *dev); |
192 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); | 211 | extern void intel_crtc_load_lut(struct drm_crtc *crtc); |
193 | extern void intel_encoder_prepare (struct drm_encoder *encoder); | 212 | extern void intel_encoder_prepare (struct drm_encoder *encoder); |
194 | extern void intel_encoder_commit (struct drm_encoder *encoder); | 213 | extern void intel_encoder_commit (struct drm_encoder *encoder); |
214 | extern void intel_encoder_destroy(struct drm_encoder *encoder); | ||
195 | 215 | ||
196 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); | 216 | extern struct drm_encoder *intel_attached_encoder(struct drm_connector *connector); |
197 | 217 | ||
@@ -199,7 +219,8 @@ extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev, | |||
199 | struct drm_crtc *crtc); | 219 | struct drm_crtc *crtc); |
200 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 220 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
201 | struct drm_file *file_priv); | 221 | struct drm_file *file_priv); |
202 | extern void intel_wait_for_vblank(struct drm_device *dev); | 222 | extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe); |
223 | extern void intel_wait_for_vblank(struct drm_device *dev, int pipe); | ||
203 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); | 224 | extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe); |
204 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, | 225 | extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder, |
205 | struct drm_connector *connector, | 226 | struct drm_connector *connector, |
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index 227feca7cf8d..a399f4b2c1c5 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #define CH7xxx_ADDR 0x76 | 38 | #define CH7xxx_ADDR 0x76 |
39 | #define TFP410_ADDR 0x38 | 39 | #define TFP410_ADDR 0x38 |
40 | 40 | ||
41 | static struct intel_dvo_device intel_dvo_devices[] = { | 41 | static const struct intel_dvo_device intel_dvo_devices[] = { |
42 | { | 42 | { |
43 | .type = INTEL_DVO_CHIP_TMDS, | 43 | .type = INTEL_DVO_CHIP_TMDS, |
44 | .name = "sil164", | 44 | .name = "sil164", |
@@ -77,20 +77,33 @@ static struct intel_dvo_device intel_dvo_devices[] = { | |||
77 | } | 77 | } |
78 | }; | 78 | }; |
79 | 79 | ||
80 | struct intel_dvo { | ||
81 | struct intel_encoder base; | ||
82 | |||
83 | struct intel_dvo_device dev; | ||
84 | |||
85 | struct drm_display_mode *panel_fixed_mode; | ||
86 | bool panel_wants_dither; | ||
87 | }; | ||
88 | |||
89 | static struct intel_dvo *enc_to_intel_dvo(struct drm_encoder *encoder) | ||
90 | { | ||
91 | return container_of(enc_to_intel_encoder(encoder), struct intel_dvo, base); | ||
92 | } | ||
93 | |||
80 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) | 94 | static void intel_dvo_dpms(struct drm_encoder *encoder, int mode) |
81 | { | 95 | { |
82 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; | 96 | struct drm_i915_private *dev_priv = encoder->dev->dev_private; |
83 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 97 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
84 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 98 | u32 dvo_reg = intel_dvo->dev.dvo_reg; |
85 | u32 dvo_reg = dvo->dvo_reg; | ||
86 | u32 temp = I915_READ(dvo_reg); | 99 | u32 temp = I915_READ(dvo_reg); |
87 | 100 | ||
88 | if (mode == DRM_MODE_DPMS_ON) { | 101 | if (mode == DRM_MODE_DPMS_ON) { |
89 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); | 102 | I915_WRITE(dvo_reg, temp | DVO_ENABLE); |
90 | I915_READ(dvo_reg); | 103 | I915_READ(dvo_reg); |
91 | dvo->dev_ops->dpms(dvo, mode); | 104 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); |
92 | } else { | 105 | } else { |
93 | dvo->dev_ops->dpms(dvo, mode); | 106 | intel_dvo->dev.dev_ops->dpms(&intel_dvo->dev, mode); |
94 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); | 107 | I915_WRITE(dvo_reg, temp & ~DVO_ENABLE); |
95 | I915_READ(dvo_reg); | 108 | I915_READ(dvo_reg); |
96 | } | 109 | } |
@@ -100,38 +113,36 @@ static int intel_dvo_mode_valid(struct drm_connector *connector, | |||
100 | struct drm_display_mode *mode) | 113 | struct drm_display_mode *mode) |
101 | { | 114 | { |
102 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 115 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
103 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 116 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
104 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
105 | 117 | ||
106 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 118 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
107 | return MODE_NO_DBLESCAN; | 119 | return MODE_NO_DBLESCAN; |
108 | 120 | ||
109 | /* XXX: Validate clock range */ | 121 | /* XXX: Validate clock range */ |
110 | 122 | ||
111 | if (dvo->panel_fixed_mode) { | 123 | if (intel_dvo->panel_fixed_mode) { |
112 | if (mode->hdisplay > dvo->panel_fixed_mode->hdisplay) | 124 | if (mode->hdisplay > intel_dvo->panel_fixed_mode->hdisplay) |
113 | return MODE_PANEL; | 125 | return MODE_PANEL; |
114 | if (mode->vdisplay > dvo->panel_fixed_mode->vdisplay) | 126 | if (mode->vdisplay > intel_dvo->panel_fixed_mode->vdisplay) |
115 | return MODE_PANEL; | 127 | return MODE_PANEL; |
116 | } | 128 | } |
117 | 129 | ||
118 | return dvo->dev_ops->mode_valid(dvo, mode); | 130 | return intel_dvo->dev.dev_ops->mode_valid(&intel_dvo->dev, mode); |
119 | } | 131 | } |
120 | 132 | ||
121 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | 133 | static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, |
122 | struct drm_display_mode *mode, | 134 | struct drm_display_mode *mode, |
123 | struct drm_display_mode *adjusted_mode) | 135 | struct drm_display_mode *adjusted_mode) |
124 | { | 136 | { |
125 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 137 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
126 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
127 | 138 | ||
128 | /* If we have timings from the BIOS for the panel, put them in | 139 | /* If we have timings from the BIOS for the panel, put them in |
129 | * to the adjusted mode. The CRTC will be set up for this mode, | 140 | * to the adjusted mode. The CRTC will be set up for this mode, |
130 | * with the panel scaling set up to source from the H/VDisplay | 141 | * with the panel scaling set up to source from the H/VDisplay |
131 | * of the original mode. | 142 | * of the original mode. |
132 | */ | 143 | */ |
133 | if (dvo->panel_fixed_mode != NULL) { | 144 | if (intel_dvo->panel_fixed_mode != NULL) { |
134 | #define C(x) adjusted_mode->x = dvo->panel_fixed_mode->x | 145 | #define C(x) adjusted_mode->x = intel_dvo->panel_fixed_mode->x |
135 | C(hdisplay); | 146 | C(hdisplay); |
136 | C(hsync_start); | 147 | C(hsync_start); |
137 | C(hsync_end); | 148 | C(hsync_end); |
@@ -145,8 +156,8 @@ static bool intel_dvo_mode_fixup(struct drm_encoder *encoder, | |||
145 | #undef C | 156 | #undef C |
146 | } | 157 | } |
147 | 158 | ||
148 | if (dvo->dev_ops->mode_fixup) | 159 | if (intel_dvo->dev.dev_ops->mode_fixup) |
149 | return dvo->dev_ops->mode_fixup(dvo, mode, adjusted_mode); | 160 | return intel_dvo->dev.dev_ops->mode_fixup(&intel_dvo->dev, mode, adjusted_mode); |
150 | 161 | ||
151 | return true; | 162 | return true; |
152 | } | 163 | } |
@@ -158,11 +169,10 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
158 | struct drm_device *dev = encoder->dev; | 169 | struct drm_device *dev = encoder->dev; |
159 | struct drm_i915_private *dev_priv = dev->dev_private; | 170 | struct drm_i915_private *dev_priv = dev->dev_private; |
160 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 171 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
161 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 172 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
162 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
163 | int pipe = intel_crtc->pipe; | 173 | int pipe = intel_crtc->pipe; |
164 | u32 dvo_val; | 174 | u32 dvo_val; |
165 | u32 dvo_reg = dvo->dvo_reg, dvo_srcdim_reg; | 175 | u32 dvo_reg = intel_dvo->dev.dvo_reg, dvo_srcdim_reg; |
166 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; | 176 | int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; |
167 | 177 | ||
168 | switch (dvo_reg) { | 178 | switch (dvo_reg) { |
@@ -178,7 +188,7 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
178 | break; | 188 | break; |
179 | } | 189 | } |
180 | 190 | ||
181 | dvo->dev_ops->mode_set(dvo, mode, adjusted_mode); | 191 | intel_dvo->dev.dev_ops->mode_set(&intel_dvo->dev, mode, adjusted_mode); |
182 | 192 | ||
183 | /* Save the data order, since I don't know what it should be set to. */ | 193 | /* Save the data order, since I don't know what it should be set to. */ |
184 | dvo_val = I915_READ(dvo_reg) & | 194 | dvo_val = I915_READ(dvo_reg) & |
@@ -214,40 +224,38 @@ static void intel_dvo_mode_set(struct drm_encoder *encoder, | |||
214 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) | 224 | static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector) |
215 | { | 225 | { |
216 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 226 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
217 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 227 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
218 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
219 | 228 | ||
220 | return dvo->dev_ops->detect(dvo); | 229 | return intel_dvo->dev.dev_ops->detect(&intel_dvo->dev); |
221 | } | 230 | } |
222 | 231 | ||
223 | static int intel_dvo_get_modes(struct drm_connector *connector) | 232 | static int intel_dvo_get_modes(struct drm_connector *connector) |
224 | { | 233 | { |
225 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 234 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
226 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 235 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
227 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | ||
228 | 236 | ||
229 | /* We should probably have an i2c driver get_modes function for those | 237 | /* We should probably have an i2c driver get_modes function for those |
230 | * devices which will have a fixed set of modes determined by the chip | 238 | * devices which will have a fixed set of modes determined by the chip |
231 | * (TV-out, for example), but for now with just TMDS and LVDS, | 239 | * (TV-out, for example), but for now with just TMDS and LVDS, |
232 | * that's not the case. | 240 | * that's not the case. |
233 | */ | 241 | */ |
234 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 242 | intel_ddc_get_modes(connector, intel_dvo->base.ddc_bus); |
235 | if (!list_empty(&connector->probed_modes)) | 243 | if (!list_empty(&connector->probed_modes)) |
236 | return 1; | 244 | return 1; |
237 | 245 | ||
238 | 246 | if (intel_dvo->panel_fixed_mode != NULL) { | |
239 | if (dvo->panel_fixed_mode != NULL) { | ||
240 | struct drm_display_mode *mode; | 247 | struct drm_display_mode *mode; |
241 | mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode); | 248 | mode = drm_mode_duplicate(connector->dev, intel_dvo->panel_fixed_mode); |
242 | if (mode) { | 249 | if (mode) { |
243 | drm_mode_probed_add(connector, mode); | 250 | drm_mode_probed_add(connector, mode); |
244 | return 1; | 251 | return 1; |
245 | } | 252 | } |
246 | } | 253 | } |
254 | |||
247 | return 0; | 255 | return 0; |
248 | } | 256 | } |
249 | 257 | ||
250 | static void intel_dvo_destroy (struct drm_connector *connector) | 258 | static void intel_dvo_destroy(struct drm_connector *connector) |
251 | { | 259 | { |
252 | drm_sysfs_connector_remove(connector); | 260 | drm_sysfs_connector_remove(connector); |
253 | drm_connector_cleanup(connector); | 261 | drm_connector_cleanup(connector); |
@@ -277,28 +285,20 @@ static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs | |||
277 | 285 | ||
278 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) | 286 | static void intel_dvo_enc_destroy(struct drm_encoder *encoder) |
279 | { | 287 | { |
280 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 288 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
281 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 289 | |
282 | 290 | if (intel_dvo->dev.dev_ops->destroy) | |
283 | if (dvo) { | 291 | intel_dvo->dev.dev_ops->destroy(&intel_dvo->dev); |
284 | if (dvo->dev_ops->destroy) | 292 | |
285 | dvo->dev_ops->destroy(dvo); | 293 | kfree(intel_dvo->panel_fixed_mode); |
286 | if (dvo->panel_fixed_mode) | 294 | |
287 | kfree(dvo->panel_fixed_mode); | 295 | intel_encoder_destroy(encoder); |
288 | } | ||
289 | if (intel_encoder->i2c_bus) | ||
290 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
291 | if (intel_encoder->ddc_bus) | ||
292 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
293 | drm_encoder_cleanup(encoder); | ||
294 | kfree(intel_encoder); | ||
295 | } | 296 | } |
296 | 297 | ||
297 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | 298 | static const struct drm_encoder_funcs intel_dvo_enc_funcs = { |
298 | .destroy = intel_dvo_enc_destroy, | 299 | .destroy = intel_dvo_enc_destroy, |
299 | }; | 300 | }; |
300 | 301 | ||
301 | |||
302 | /** | 302 | /** |
303 | * Attempts to get a fixed panel timing for LVDS (currently only the i830). | 303 | * Attempts to get a fixed panel timing for LVDS (currently only the i830). |
304 | * | 304 | * |
@@ -306,15 +306,13 @@ static const struct drm_encoder_funcs intel_dvo_enc_funcs = { | |||
306 | * chip being on DVOB/C and having multiple pipes. | 306 | * chip being on DVOB/C and having multiple pipes. |
307 | */ | 307 | */ |
308 | static struct drm_display_mode * | 308 | static struct drm_display_mode * |
309 | intel_dvo_get_current_mode (struct drm_connector *connector) | 309 | intel_dvo_get_current_mode(struct drm_connector *connector) |
310 | { | 310 | { |
311 | struct drm_device *dev = connector->dev; | 311 | struct drm_device *dev = connector->dev; |
312 | struct drm_i915_private *dev_priv = dev->dev_private; | 312 | struct drm_i915_private *dev_priv = dev->dev_private; |
313 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 313 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
314 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 314 | struct intel_dvo *intel_dvo = enc_to_intel_dvo(encoder); |
315 | struct intel_dvo_device *dvo = intel_encoder->dev_priv; | 315 | uint32_t dvo_val = I915_READ(intel_dvo->dev.dvo_reg); |
316 | uint32_t dvo_reg = dvo->dvo_reg; | ||
317 | uint32_t dvo_val = I915_READ(dvo_reg); | ||
318 | struct drm_display_mode *mode = NULL; | 316 | struct drm_display_mode *mode = NULL; |
319 | 317 | ||
320 | /* If the DVO port is active, that'll be the LVDS, so we can pull out | 318 | /* If the DVO port is active, that'll be the LVDS, so we can pull out |
@@ -327,7 +325,6 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
327 | crtc = intel_get_crtc_from_pipe(dev, pipe); | 325 | crtc = intel_get_crtc_from_pipe(dev, pipe); |
328 | if (crtc) { | 326 | if (crtc) { |
329 | mode = intel_crtc_mode_get(dev, crtc); | 327 | mode = intel_crtc_mode_get(dev, crtc); |
330 | |||
331 | if (mode) { | 328 | if (mode) { |
332 | mode->type |= DRM_MODE_TYPE_PREFERRED; | 329 | mode->type |= DRM_MODE_TYPE_PREFERRED; |
333 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) | 330 | if (dvo_val & DVO_HSYNC_ACTIVE_HIGH) |
@@ -337,28 +334,32 @@ intel_dvo_get_current_mode (struct drm_connector *connector) | |||
337 | } | 334 | } |
338 | } | 335 | } |
339 | } | 336 | } |
337 | |||
340 | return mode; | 338 | return mode; |
341 | } | 339 | } |
342 | 340 | ||
343 | void intel_dvo_init(struct drm_device *dev) | 341 | void intel_dvo_init(struct drm_device *dev) |
344 | { | 342 | { |
345 | struct intel_encoder *intel_encoder; | 343 | struct intel_encoder *intel_encoder; |
344 | struct intel_dvo *intel_dvo; | ||
346 | struct intel_connector *intel_connector; | 345 | struct intel_connector *intel_connector; |
347 | struct intel_dvo_device *dvo; | ||
348 | struct i2c_adapter *i2cbus = NULL; | 346 | struct i2c_adapter *i2cbus = NULL; |
349 | int ret = 0; | 347 | int ret = 0; |
350 | int i; | 348 | int i; |
351 | int encoder_type = DRM_MODE_ENCODER_NONE; | 349 | int encoder_type = DRM_MODE_ENCODER_NONE; |
352 | intel_encoder = kzalloc (sizeof(struct intel_encoder), GFP_KERNEL); | 350 | |
353 | if (!intel_encoder) | 351 | intel_dvo = kzalloc(sizeof(struct intel_dvo), GFP_KERNEL); |
352 | if (!intel_dvo) | ||
354 | return; | 353 | return; |
355 | 354 | ||
356 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 355 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
357 | if (!intel_connector) { | 356 | if (!intel_connector) { |
358 | kfree(intel_encoder); | 357 | kfree(intel_dvo); |
359 | return; | 358 | return; |
360 | } | 359 | } |
361 | 360 | ||
361 | intel_encoder = &intel_dvo->base; | ||
362 | |||
362 | /* Set up the DDC bus */ | 363 | /* Set up the DDC bus */ |
363 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); | 364 | intel_encoder->ddc_bus = intel_i2c_create(dev, GPIOD, "DVODDC_D"); |
364 | if (!intel_encoder->ddc_bus) | 365 | if (!intel_encoder->ddc_bus) |
@@ -367,10 +368,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
367 | /* Now, try to find a controller */ | 368 | /* Now, try to find a controller */ |
368 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { | 369 | for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) { |
369 | struct drm_connector *connector = &intel_connector->base; | 370 | struct drm_connector *connector = &intel_connector->base; |
371 | const struct intel_dvo_device *dvo = &intel_dvo_devices[i]; | ||
370 | int gpio; | 372 | int gpio; |
371 | 373 | ||
372 | dvo = &intel_dvo_devices[i]; | ||
373 | |||
374 | /* Allow the I2C driver info to specify the GPIO to be used in | 374 | /* Allow the I2C driver info to specify the GPIO to be used in |
375 | * special cases, but otherwise default to what's defined | 375 | * special cases, but otherwise default to what's defined |
376 | * in the spec. | 376 | * in the spec. |
@@ -393,11 +393,8 @@ void intel_dvo_init(struct drm_device *dev) | |||
393 | continue; | 393 | continue; |
394 | } | 394 | } |
395 | 395 | ||
396 | if (dvo->dev_ops!= NULL) | 396 | intel_dvo->dev = *dvo; |
397 | ret = dvo->dev_ops->init(dvo, i2cbus); | 397 | ret = dvo->dev_ops->init(&intel_dvo->dev, i2cbus); |
398 | else | ||
399 | ret = false; | ||
400 | |||
401 | if (!ret) | 398 | if (!ret) |
402 | continue; | 399 | continue; |
403 | 400 | ||
@@ -429,9 +426,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
429 | connector->interlace_allowed = false; | 426 | connector->interlace_allowed = false; |
430 | connector->doublescan_allowed = false; | 427 | connector->doublescan_allowed = false; |
431 | 428 | ||
432 | intel_encoder->dev_priv = dvo; | ||
433 | intel_encoder->i2c_bus = i2cbus; | ||
434 | |||
435 | drm_encoder_init(dev, &intel_encoder->enc, | 429 | drm_encoder_init(dev, &intel_encoder->enc, |
436 | &intel_dvo_enc_funcs, encoder_type); | 430 | &intel_dvo_enc_funcs, encoder_type); |
437 | drm_encoder_helper_add(&intel_encoder->enc, | 431 | drm_encoder_helper_add(&intel_encoder->enc, |
@@ -447,9 +441,9 @@ void intel_dvo_init(struct drm_device *dev) | |||
447 | * headers, likely), so for now, just get the current | 441 | * headers, likely), so for now, just get the current |
448 | * mode being output through DVO. | 442 | * mode being output through DVO. |
449 | */ | 443 | */ |
450 | dvo->panel_fixed_mode = | 444 | intel_dvo->panel_fixed_mode = |
451 | intel_dvo_get_current_mode(connector); | 445 | intel_dvo_get_current_mode(connector); |
452 | dvo->panel_wants_dither = true; | 446 | intel_dvo->panel_wants_dither = true; |
453 | } | 447 | } |
454 | 448 | ||
455 | drm_sysfs_connector_add(connector); | 449 | drm_sysfs_connector_add(connector); |
@@ -461,6 +455,6 @@ void intel_dvo_init(struct drm_device *dev) | |||
461 | if (i2cbus != NULL) | 455 | if (i2cbus != NULL) |
462 | intel_i2c_destroy(i2cbus); | 456 | intel_i2c_destroy(i2cbus); |
463 | free_intel: | 457 | free_intel: |
464 | kfree(intel_encoder); | 458 | kfree(intel_dvo); |
465 | kfree(intel_connector); | 459 | kfree(intel_connector); |
466 | } | 460 | } |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 197887ed1823..ccd4c97e6524 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -37,11 +37,17 @@ | |||
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | 39 | ||
40 | struct intel_hdmi_priv { | 40 | struct intel_hdmi { |
41 | struct intel_encoder base; | ||
41 | u32 sdvox_reg; | 42 | u32 sdvox_reg; |
42 | bool has_hdmi_sink; | 43 | bool has_hdmi_sink; |
43 | }; | 44 | }; |
44 | 45 | ||
46 | static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) | ||
47 | { | ||
48 | return container_of(enc_to_intel_encoder(encoder), struct intel_hdmi, base); | ||
49 | } | ||
50 | |||
45 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, | 51 | static void intel_hdmi_mode_set(struct drm_encoder *encoder, |
46 | struct drm_display_mode *mode, | 52 | struct drm_display_mode *mode, |
47 | struct drm_display_mode *adjusted_mode) | 53 | struct drm_display_mode *adjusted_mode) |
@@ -50,8 +56,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
50 | struct drm_i915_private *dev_priv = dev->dev_private; | 56 | struct drm_i915_private *dev_priv = dev->dev_private; |
51 | struct drm_crtc *crtc = encoder->crtc; | 57 | struct drm_crtc *crtc = encoder->crtc; |
52 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 58 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
53 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 59 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
54 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
55 | u32 sdvox; | 60 | u32 sdvox; |
56 | 61 | ||
57 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; | 62 | sdvox = SDVO_ENCODING_HDMI | SDVO_BORDER_ENABLE; |
@@ -60,7 +65,7 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
60 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 65 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
61 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 66 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
62 | 67 | ||
63 | if (hdmi_priv->has_hdmi_sink) { | 68 | if (intel_hdmi->has_hdmi_sink) { |
64 | sdvox |= SDVO_AUDIO_ENABLE; | 69 | sdvox |= SDVO_AUDIO_ENABLE; |
65 | if (HAS_PCH_CPT(dev)) | 70 | if (HAS_PCH_CPT(dev)) |
66 | sdvox |= HDMI_MODE_SELECT; | 71 | sdvox |= HDMI_MODE_SELECT; |
@@ -73,26 +78,25 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, | |||
73 | sdvox |= SDVO_PIPE_B_SELECT; | 78 | sdvox |= SDVO_PIPE_B_SELECT; |
74 | } | 79 | } |
75 | 80 | ||
76 | I915_WRITE(hdmi_priv->sdvox_reg, sdvox); | 81 | I915_WRITE(intel_hdmi->sdvox_reg, sdvox); |
77 | POSTING_READ(hdmi_priv->sdvox_reg); | 82 | POSTING_READ(intel_hdmi->sdvox_reg); |
78 | } | 83 | } |
79 | 84 | ||
80 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | 85 | static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) |
81 | { | 86 | { |
82 | struct drm_device *dev = encoder->dev; | 87 | struct drm_device *dev = encoder->dev; |
83 | struct drm_i915_private *dev_priv = dev->dev_private; | 88 | struct drm_i915_private *dev_priv = dev->dev_private; |
84 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 89 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
85 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
86 | u32 temp; | 90 | u32 temp; |
87 | 91 | ||
88 | temp = I915_READ(hdmi_priv->sdvox_reg); | 92 | temp = I915_READ(intel_hdmi->sdvox_reg); |
89 | 93 | ||
90 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | 94 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but |
91 | * we do this anyway which shows more stable in testing. | 95 | * we do this anyway which shows more stable in testing. |
92 | */ | 96 | */ |
93 | if (HAS_PCH_SPLIT(dev)) { | 97 | if (HAS_PCH_SPLIT(dev)) { |
94 | I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); | 98 | I915_WRITE(intel_hdmi->sdvox_reg, temp & ~SDVO_ENABLE); |
95 | POSTING_READ(hdmi_priv->sdvox_reg); | 99 | POSTING_READ(intel_hdmi->sdvox_reg); |
96 | } | 100 | } |
97 | 101 | ||
98 | if (mode != DRM_MODE_DPMS_ON) { | 102 | if (mode != DRM_MODE_DPMS_ON) { |
@@ -101,15 +105,15 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
101 | temp |= SDVO_ENABLE; | 105 | temp |= SDVO_ENABLE; |
102 | } | 106 | } |
103 | 107 | ||
104 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | 108 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
105 | POSTING_READ(hdmi_priv->sdvox_reg); | 109 | POSTING_READ(intel_hdmi->sdvox_reg); |
106 | 110 | ||
107 | /* HW workaround, need to write this twice for issue that may result | 111 | /* HW workaround, need to write this twice for issue that may result |
108 | * in first write getting masked. | 112 | * in first write getting masked. |
109 | */ | 113 | */ |
110 | if (HAS_PCH_SPLIT(dev)) { | 114 | if (HAS_PCH_SPLIT(dev)) { |
111 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | 115 | I915_WRITE(intel_hdmi->sdvox_reg, temp); |
112 | POSTING_READ(hdmi_priv->sdvox_reg); | 116 | POSTING_READ(intel_hdmi->sdvox_reg); |
113 | } | 117 | } |
114 | } | 118 | } |
115 | 119 | ||
@@ -138,19 +142,17 @@ static enum drm_connector_status | |||
138 | intel_hdmi_detect(struct drm_connector *connector) | 142 | intel_hdmi_detect(struct drm_connector *connector) |
139 | { | 143 | { |
140 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 144 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
141 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 145 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
142 | struct intel_hdmi_priv *hdmi_priv = intel_encoder->dev_priv; | ||
143 | struct edid *edid = NULL; | 146 | struct edid *edid = NULL; |
144 | enum drm_connector_status status = connector_status_disconnected; | 147 | enum drm_connector_status status = connector_status_disconnected; |
145 | 148 | ||
146 | hdmi_priv->has_hdmi_sink = false; | 149 | intel_hdmi->has_hdmi_sink = false; |
147 | edid = drm_get_edid(connector, | 150 | edid = drm_get_edid(connector, intel_hdmi->base.ddc_bus); |
148 | intel_encoder->ddc_bus); | ||
149 | 151 | ||
150 | if (edid) { | 152 | if (edid) { |
151 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { | 153 | if (edid->input & DRM_EDID_INPUT_DIGITAL) { |
152 | status = connector_status_connected; | 154 | status = connector_status_connected; |
153 | hdmi_priv->has_hdmi_sink = drm_detect_hdmi_monitor(edid); | 155 | intel_hdmi->has_hdmi_sink = drm_detect_hdmi_monitor(edid); |
154 | } | 156 | } |
155 | connector->display_info.raw_edid = NULL; | 157 | connector->display_info.raw_edid = NULL; |
156 | kfree(edid); | 158 | kfree(edid); |
@@ -162,13 +164,13 @@ intel_hdmi_detect(struct drm_connector *connector) | |||
162 | static int intel_hdmi_get_modes(struct drm_connector *connector) | 164 | static int intel_hdmi_get_modes(struct drm_connector *connector) |
163 | { | 165 | { |
164 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 166 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
165 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 167 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
166 | 168 | ||
167 | /* We should parse the EDID data and find out if it's an HDMI sink so | 169 | /* We should parse the EDID data and find out if it's an HDMI sink so |
168 | * we can send audio to it. | 170 | * we can send audio to it. |
169 | */ | 171 | */ |
170 | 172 | ||
171 | return intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 173 | return intel_ddc_get_modes(connector, intel_hdmi->base.ddc_bus); |
172 | } | 174 | } |
173 | 175 | ||
174 | static void intel_hdmi_destroy(struct drm_connector *connector) | 176 | static void intel_hdmi_destroy(struct drm_connector *connector) |
@@ -199,18 +201,8 @@ static const struct drm_connector_helper_funcs intel_hdmi_connector_helper_funcs | |||
199 | .best_encoder = intel_attached_encoder, | 201 | .best_encoder = intel_attached_encoder, |
200 | }; | 202 | }; |
201 | 203 | ||
202 | static void intel_hdmi_enc_destroy(struct drm_encoder *encoder) | ||
203 | { | ||
204 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
205 | |||
206 | if (intel_encoder->i2c_bus) | ||
207 | intel_i2c_destroy(intel_encoder->i2c_bus); | ||
208 | drm_encoder_cleanup(encoder); | ||
209 | kfree(intel_encoder); | ||
210 | } | ||
211 | |||
212 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { | 204 | static const struct drm_encoder_funcs intel_hdmi_enc_funcs = { |
213 | .destroy = intel_hdmi_enc_destroy, | 205 | .destroy = intel_encoder_destroy, |
214 | }; | 206 | }; |
215 | 207 | ||
216 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | 208 | void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) |
@@ -219,21 +211,19 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
219 | struct drm_connector *connector; | 211 | struct drm_connector *connector; |
220 | struct intel_encoder *intel_encoder; | 212 | struct intel_encoder *intel_encoder; |
221 | struct intel_connector *intel_connector; | 213 | struct intel_connector *intel_connector; |
222 | struct intel_hdmi_priv *hdmi_priv; | 214 | struct intel_hdmi *intel_hdmi; |
223 | 215 | ||
224 | intel_encoder = kcalloc(sizeof(struct intel_encoder) + | 216 | intel_hdmi = kzalloc(sizeof(struct intel_hdmi), GFP_KERNEL); |
225 | sizeof(struct intel_hdmi_priv), 1, GFP_KERNEL); | 217 | if (!intel_hdmi) |
226 | if (!intel_encoder) | ||
227 | return; | 218 | return; |
228 | 219 | ||
229 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 220 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
230 | if (!intel_connector) { | 221 | if (!intel_connector) { |
231 | kfree(intel_encoder); | 222 | kfree(intel_hdmi); |
232 | return; | 223 | return; |
233 | } | 224 | } |
234 | 225 | ||
235 | hdmi_priv = (struct intel_hdmi_priv *)(intel_encoder + 1); | 226 | intel_encoder = &intel_hdmi->base; |
236 | |||
237 | connector = &intel_connector->base; | 227 | connector = &intel_connector->base; |
238 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, | 228 | drm_connector_init(dev, connector, &intel_hdmi_connector_funcs, |
239 | DRM_MODE_CONNECTOR_HDMIA); | 229 | DRM_MODE_CONNECTOR_HDMIA); |
@@ -274,8 +264,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
274 | if (!intel_encoder->ddc_bus) | 264 | if (!intel_encoder->ddc_bus) |
275 | goto err_connector; | 265 | goto err_connector; |
276 | 266 | ||
277 | hdmi_priv->sdvox_reg = sdvox_reg; | 267 | intel_hdmi->sdvox_reg = sdvox_reg; |
278 | intel_encoder->dev_priv = hdmi_priv; | ||
279 | 268 | ||
280 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, | 269 | drm_encoder_init(dev, &intel_encoder->enc, &intel_hdmi_enc_funcs, |
281 | DRM_MODE_ENCODER_TMDS); | 270 | DRM_MODE_ENCODER_TMDS); |
@@ -298,7 +287,7 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) | |||
298 | 287 | ||
299 | err_connector: | 288 | err_connector: |
300 | drm_connector_cleanup(connector); | 289 | drm_connector_cleanup(connector); |
301 | kfree(intel_encoder); | 290 | kfree(intel_hdmi); |
302 | kfree(intel_connector); | 291 | kfree(intel_connector); |
303 | 292 | ||
304 | return; | 293 | return; |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 0a2e60059fb3..b819c1081147 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -41,12 +41,18 @@ | |||
41 | #include <linux/acpi.h> | 41 | #include <linux/acpi.h> |
42 | 42 | ||
43 | /* Private structure for the integrated LVDS support */ | 43 | /* Private structure for the integrated LVDS support */ |
44 | struct intel_lvds_priv { | 44 | struct intel_lvds { |
45 | struct intel_encoder base; | ||
45 | int fitting_mode; | 46 | int fitting_mode; |
46 | u32 pfit_control; | 47 | u32 pfit_control; |
47 | u32 pfit_pgm_ratios; | 48 | u32 pfit_pgm_ratios; |
48 | }; | 49 | }; |
49 | 50 | ||
51 | static struct intel_lvds *enc_to_intel_lvds(struct drm_encoder *encoder) | ||
52 | { | ||
53 | return container_of(enc_to_intel_encoder(encoder), struct intel_lvds, base); | ||
54 | } | ||
55 | |||
50 | /** | 56 | /** |
51 | * Sets the backlight level. | 57 | * Sets the backlight level. |
52 | * | 58 | * |
@@ -90,7 +96,7 @@ static u32 intel_lvds_get_max_backlight(struct drm_device *dev) | |||
90 | static void intel_lvds_set_power(struct drm_device *dev, bool on) | 96 | static void intel_lvds_set_power(struct drm_device *dev, bool on) |
91 | { | 97 | { |
92 | struct drm_i915_private *dev_priv = dev->dev_private; | 98 | struct drm_i915_private *dev_priv = dev->dev_private; |
93 | u32 pp_status, ctl_reg, status_reg, lvds_reg; | 99 | u32 ctl_reg, status_reg, lvds_reg; |
94 | 100 | ||
95 | if (HAS_PCH_SPLIT(dev)) { | 101 | if (HAS_PCH_SPLIT(dev)) { |
96 | ctl_reg = PCH_PP_CONTROL; | 102 | ctl_reg = PCH_PP_CONTROL; |
@@ -108,9 +114,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) | |||
108 | 114 | ||
109 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | | 115 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | |
110 | POWER_TARGET_ON); | 116 | POWER_TARGET_ON); |
111 | do { | 117 | if (wait_for(I915_READ(status_reg) & PP_ON, 1000, 0)) |
112 | pp_status = I915_READ(status_reg); | 118 | DRM_ERROR("timed out waiting to enable LVDS pipe"); |
113 | } while ((pp_status & PP_ON) == 0); | ||
114 | 119 | ||
115 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); | 120 | intel_lvds_set_backlight(dev, dev_priv->backlight_duty_cycle); |
116 | } else { | 121 | } else { |
@@ -118,9 +123,8 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on) | |||
118 | 123 | ||
119 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & | 124 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & |
120 | ~POWER_TARGET_ON); | 125 | ~POWER_TARGET_ON); |
121 | do { | 126 | if (wait_for((I915_READ(status_reg) & PP_ON) == 0, 1000, 0)) |
122 | pp_status = I915_READ(status_reg); | 127 | DRM_ERROR("timed out waiting for LVDS pipe to turn off"); |
123 | } while (pp_status & PP_ON); | ||
124 | 128 | ||
125 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 129 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); |
126 | POSTING_READ(lvds_reg); | 130 | POSTING_READ(lvds_reg); |
@@ -219,9 +223,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
219 | struct drm_device *dev = encoder->dev; | 223 | struct drm_device *dev = encoder->dev; |
220 | struct drm_i915_private *dev_priv = dev->dev_private; | 224 | struct drm_i915_private *dev_priv = dev->dev_private; |
221 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | 225 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
226 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); | ||
222 | struct drm_encoder *tmp_encoder; | 227 | struct drm_encoder *tmp_encoder; |
223 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
224 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
225 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; | 228 | u32 pfit_control = 0, pfit_pgm_ratios = 0, border = 0; |
226 | 229 | ||
227 | /* Should never happen!! */ | 230 | /* Should never happen!! */ |
@@ -241,26 +244,20 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
241 | /* If we don't have a panel mode, there is nothing we can do */ | 244 | /* If we don't have a panel mode, there is nothing we can do */ |
242 | if (dev_priv->panel_fixed_mode == NULL) | 245 | if (dev_priv->panel_fixed_mode == NULL) |
243 | return true; | 246 | return true; |
247 | |||
244 | /* | 248 | /* |
245 | * We have timings from the BIOS for the panel, put them in | 249 | * We have timings from the BIOS for the panel, put them in |
246 | * to the adjusted mode. The CRTC will be set up for this mode, | 250 | * to the adjusted mode. The CRTC will be set up for this mode, |
247 | * with the panel scaling set up to source from the H/VDisplay | 251 | * with the panel scaling set up to source from the H/VDisplay |
248 | * of the original mode. | 252 | * of the original mode. |
249 | */ | 253 | */ |
250 | adjusted_mode->hdisplay = dev_priv->panel_fixed_mode->hdisplay; | 254 | intel_fixed_panel_mode(dev_priv->panel_fixed_mode, adjusted_mode); |
251 | adjusted_mode->hsync_start = | 255 | |
252 | dev_priv->panel_fixed_mode->hsync_start; | 256 | if (HAS_PCH_SPLIT(dev)) { |
253 | adjusted_mode->hsync_end = | 257 | intel_pch_panel_fitting(dev, intel_lvds->fitting_mode, |
254 | dev_priv->panel_fixed_mode->hsync_end; | 258 | mode, adjusted_mode); |
255 | adjusted_mode->htotal = dev_priv->panel_fixed_mode->htotal; | 259 | return true; |
256 | adjusted_mode->vdisplay = dev_priv->panel_fixed_mode->vdisplay; | 260 | } |
257 | adjusted_mode->vsync_start = | ||
258 | dev_priv->panel_fixed_mode->vsync_start; | ||
259 | adjusted_mode->vsync_end = | ||
260 | dev_priv->panel_fixed_mode->vsync_end; | ||
261 | adjusted_mode->vtotal = dev_priv->panel_fixed_mode->vtotal; | ||
262 | adjusted_mode->clock = dev_priv->panel_fixed_mode->clock; | ||
263 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
264 | 261 | ||
265 | /* Make sure pre-965s set dither correctly */ | 262 | /* Make sure pre-965s set dither correctly */ |
266 | if (!IS_I965G(dev)) { | 263 | if (!IS_I965G(dev)) { |
@@ -273,10 +270,6 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
273 | adjusted_mode->vdisplay == mode->vdisplay) | 270 | adjusted_mode->vdisplay == mode->vdisplay) |
274 | goto out; | 271 | goto out; |
275 | 272 | ||
276 | /* full screen scale for now */ | ||
277 | if (HAS_PCH_SPLIT(dev)) | ||
278 | goto out; | ||
279 | |||
280 | /* 965+ wants fuzzy fitting */ | 273 | /* 965+ wants fuzzy fitting */ |
281 | if (IS_I965G(dev)) | 274 | if (IS_I965G(dev)) |
282 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | | 275 | pfit_control |= ((intel_crtc->pipe << PFIT_PIPE_SHIFT) | |
@@ -288,12 +281,10 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
288 | * to register description and PRM. | 281 | * to register description and PRM. |
289 | * Change the value here to see the borders for debugging | 282 | * Change the value here to see the borders for debugging |
290 | */ | 283 | */ |
291 | if (!HAS_PCH_SPLIT(dev)) { | 284 | I915_WRITE(BCLRPAT_A, 0); |
292 | I915_WRITE(BCLRPAT_A, 0); | 285 | I915_WRITE(BCLRPAT_B, 0); |
293 | I915_WRITE(BCLRPAT_B, 0); | ||
294 | } | ||
295 | 286 | ||
296 | switch (lvds_priv->fitting_mode) { | 287 | switch (intel_lvds->fitting_mode) { |
297 | case DRM_MODE_SCALE_CENTER: | 288 | case DRM_MODE_SCALE_CENTER: |
298 | /* | 289 | /* |
299 | * For centered modes, we have to calculate border widths & | 290 | * For centered modes, we have to calculate border widths & |
@@ -378,8 +369,8 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
378 | } | 369 | } |
379 | 370 | ||
380 | out: | 371 | out: |
381 | lvds_priv->pfit_control = pfit_control; | 372 | intel_lvds->pfit_control = pfit_control; |
382 | lvds_priv->pfit_pgm_ratios = pfit_pgm_ratios; | 373 | intel_lvds->pfit_pgm_ratios = pfit_pgm_ratios; |
383 | dev_priv->lvds_border_bits = border; | 374 | dev_priv->lvds_border_bits = border; |
384 | 375 | ||
385 | /* | 376 | /* |
@@ -427,8 +418,7 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
427 | { | 418 | { |
428 | struct drm_device *dev = encoder->dev; | 419 | struct drm_device *dev = encoder->dev; |
429 | struct drm_i915_private *dev_priv = dev->dev_private; | 420 | struct drm_i915_private *dev_priv = dev->dev_private; |
430 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 421 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); |
431 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
432 | 422 | ||
433 | /* | 423 | /* |
434 | * The LVDS pin pair will already have been turned on in the | 424 | * The LVDS pin pair will already have been turned on in the |
@@ -444,8 +434,8 @@ static void intel_lvds_mode_set(struct drm_encoder *encoder, | |||
444 | * screen. Should be enabled before the pipe is enabled, according to | 434 | * screen. Should be enabled before the pipe is enabled, according to |
445 | * register description and PRM. | 435 | * register description and PRM. |
446 | */ | 436 | */ |
447 | I915_WRITE(PFIT_PGM_RATIOS, lvds_priv->pfit_pgm_ratios); | 437 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); |
448 | I915_WRITE(PFIT_CONTROL, lvds_priv->pfit_control); | 438 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); |
449 | } | 439 | } |
450 | 440 | ||
451 | /** | 441 | /** |
@@ -600,18 +590,17 @@ static int intel_lvds_set_property(struct drm_connector *connector, | |||
600 | connector->encoder) { | 590 | connector->encoder) { |
601 | struct drm_crtc *crtc = connector->encoder->crtc; | 591 | struct drm_crtc *crtc = connector->encoder->crtc; |
602 | struct drm_encoder *encoder = connector->encoder; | 592 | struct drm_encoder *encoder = connector->encoder; |
603 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 593 | struct intel_lvds *intel_lvds = enc_to_intel_lvds(encoder); |
604 | struct intel_lvds_priv *lvds_priv = intel_encoder->dev_priv; | ||
605 | 594 | ||
606 | if (value == DRM_MODE_SCALE_NONE) { | 595 | if (value == DRM_MODE_SCALE_NONE) { |
607 | DRM_DEBUG_KMS("no scaling not supported\n"); | 596 | DRM_DEBUG_KMS("no scaling not supported\n"); |
608 | return 0; | 597 | return 0; |
609 | } | 598 | } |
610 | if (lvds_priv->fitting_mode == value) { | 599 | if (intel_lvds->fitting_mode == value) { |
611 | /* the LVDS scaling property is not changed */ | 600 | /* the LVDS scaling property is not changed */ |
612 | return 0; | 601 | return 0; |
613 | } | 602 | } |
614 | lvds_priv->fitting_mode = value; | 603 | intel_lvds->fitting_mode = value; |
615 | if (crtc && crtc->enabled) { | 604 | if (crtc && crtc->enabled) { |
616 | /* | 605 | /* |
617 | * If the CRTC is enabled, the display will be changed | 606 | * If the CRTC is enabled, the display will be changed |
@@ -647,19 +636,8 @@ static const struct drm_connector_funcs intel_lvds_connector_funcs = { | |||
647 | .destroy = intel_lvds_destroy, | 636 | .destroy = intel_lvds_destroy, |
648 | }; | 637 | }; |
649 | 638 | ||
650 | |||
651 | static void intel_lvds_enc_destroy(struct drm_encoder *encoder) | ||
652 | { | ||
653 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
654 | |||
655 | if (intel_encoder->ddc_bus) | ||
656 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
657 | drm_encoder_cleanup(encoder); | ||
658 | kfree(intel_encoder); | ||
659 | } | ||
660 | |||
661 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { | 639 | static const struct drm_encoder_funcs intel_lvds_enc_funcs = { |
662 | .destroy = intel_lvds_enc_destroy, | 640 | .destroy = intel_encoder_destroy, |
663 | }; | 641 | }; |
664 | 642 | ||
665 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) | 643 | static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) |
@@ -843,13 +821,13 @@ static int lvds_is_present_in_vbt(struct drm_device *dev) | |||
843 | void intel_lvds_init(struct drm_device *dev) | 821 | void intel_lvds_init(struct drm_device *dev) |
844 | { | 822 | { |
845 | struct drm_i915_private *dev_priv = dev->dev_private; | 823 | struct drm_i915_private *dev_priv = dev->dev_private; |
824 | struct intel_lvds *intel_lvds; | ||
846 | struct intel_encoder *intel_encoder; | 825 | struct intel_encoder *intel_encoder; |
847 | struct intel_connector *intel_connector; | 826 | struct intel_connector *intel_connector; |
848 | struct drm_connector *connector; | 827 | struct drm_connector *connector; |
849 | struct drm_encoder *encoder; | 828 | struct drm_encoder *encoder; |
850 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 829 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
851 | struct drm_crtc *crtc; | 830 | struct drm_crtc *crtc; |
852 | struct intel_lvds_priv *lvds_priv; | ||
853 | u32 lvds; | 831 | u32 lvds; |
854 | int pipe, gpio = GPIOC; | 832 | int pipe, gpio = GPIOC; |
855 | 833 | ||
@@ -872,20 +850,20 @@ void intel_lvds_init(struct drm_device *dev) | |||
872 | gpio = PCH_GPIOC; | 850 | gpio = PCH_GPIOC; |
873 | } | 851 | } |
874 | 852 | ||
875 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 853 | intel_lvds = kzalloc(sizeof(struct intel_lvds), GFP_KERNEL); |
876 | sizeof(struct intel_lvds_priv), GFP_KERNEL); | 854 | if (!intel_lvds) { |
877 | if (!intel_encoder) { | ||
878 | return; | 855 | return; |
879 | } | 856 | } |
880 | 857 | ||
881 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 858 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
882 | if (!intel_connector) { | 859 | if (!intel_connector) { |
883 | kfree(intel_encoder); | 860 | kfree(intel_lvds); |
884 | return; | 861 | return; |
885 | } | 862 | } |
886 | 863 | ||
887 | connector = &intel_connector->base; | 864 | intel_encoder = &intel_lvds->base; |
888 | encoder = &intel_encoder->enc; | 865 | encoder = &intel_encoder->enc; |
866 | connector = &intel_connector->base; | ||
889 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, | 867 | drm_connector_init(dev, &intel_connector->base, &intel_lvds_connector_funcs, |
890 | DRM_MODE_CONNECTOR_LVDS); | 868 | DRM_MODE_CONNECTOR_LVDS); |
891 | 869 | ||
@@ -905,8 +883,6 @@ void intel_lvds_init(struct drm_device *dev) | |||
905 | connector->interlace_allowed = false; | 883 | connector->interlace_allowed = false; |
906 | connector->doublescan_allowed = false; | 884 | connector->doublescan_allowed = false; |
907 | 885 | ||
908 | lvds_priv = (struct intel_lvds_priv *)(intel_encoder + 1); | ||
909 | intel_encoder->dev_priv = lvds_priv; | ||
910 | /* create the scaling mode property */ | 886 | /* create the scaling mode property */ |
911 | drm_mode_create_scaling_mode_property(dev); | 887 | drm_mode_create_scaling_mode_property(dev); |
912 | /* | 888 | /* |
@@ -916,7 +892,7 @@ void intel_lvds_init(struct drm_device *dev) | |||
916 | drm_connector_attach_property(&intel_connector->base, | 892 | drm_connector_attach_property(&intel_connector->base, |
917 | dev->mode_config.scaling_mode_property, | 893 | dev->mode_config.scaling_mode_property, |
918 | DRM_MODE_SCALE_ASPECT); | 894 | DRM_MODE_SCALE_ASPECT); |
919 | lvds_priv->fitting_mode = DRM_MODE_SCALE_ASPECT; | 895 | intel_lvds->fitting_mode = DRM_MODE_SCALE_ASPECT; |
920 | /* | 896 | /* |
921 | * LVDS discovery: | 897 | * LVDS discovery: |
922 | * 1) check for EDID on DDC | 898 | * 1) check for EDID on DDC |
@@ -1024,6 +1000,6 @@ failed: | |||
1024 | intel_i2c_destroy(intel_encoder->ddc_bus); | 1000 | intel_i2c_destroy(intel_encoder->ddc_bus); |
1025 | drm_connector_cleanup(connector); | 1001 | drm_connector_cleanup(connector); |
1026 | drm_encoder_cleanup(encoder); | 1002 | drm_encoder_cleanup(encoder); |
1027 | kfree(intel_encoder); | 1003 | kfree(intel_lvds); |
1028 | kfree(intel_connector); | 1004 | kfree(intel_connector); |
1029 | } | 1005 | } |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d39aea24eabe..4f00390d7c61 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -1367,7 +1367,8 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1367 | overlay->flip_addr = overlay->reg_bo->gtt_offset; | 1367 | overlay->flip_addr = overlay->reg_bo->gtt_offset; |
1368 | } else { | 1368 | } else { |
1369 | ret = i915_gem_attach_phys_object(dev, reg_bo, | 1369 | ret = i915_gem_attach_phys_object(dev, reg_bo, |
1370 | I915_GEM_PHYS_OVERLAY_REGS); | 1370 | I915_GEM_PHYS_OVERLAY_REGS, |
1371 | 0); | ||
1371 | if (ret) { | 1372 | if (ret) { |
1372 | DRM_ERROR("failed to attach phys overlay regs\n"); | 1373 | DRM_ERROR("failed to attach phys overlay regs\n"); |
1373 | goto out_free_bo; | 1374 | goto out_free_bo; |
@@ -1416,3 +1417,99 @@ void intel_cleanup_overlay(struct drm_device *dev) | |||
1416 | kfree(dev_priv->overlay); | 1417 | kfree(dev_priv->overlay); |
1417 | } | 1418 | } |
1418 | } | 1419 | } |
1420 | |||
1421 | struct intel_overlay_error_state { | ||
1422 | struct overlay_registers regs; | ||
1423 | unsigned long base; | ||
1424 | u32 dovsta; | ||
1425 | u32 isr; | ||
1426 | }; | ||
1427 | |||
1428 | struct intel_overlay_error_state * | ||
1429 | intel_overlay_capture_error_state(struct drm_device *dev) | ||
1430 | { | ||
1431 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
1432 | struct intel_overlay *overlay = dev_priv->overlay; | ||
1433 | struct intel_overlay_error_state *error; | ||
1434 | struct overlay_registers __iomem *regs; | ||
1435 | |||
1436 | if (!overlay || !overlay->active) | ||
1437 | return NULL; | ||
1438 | |||
1439 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | ||
1440 | if (error == NULL) | ||
1441 | return NULL; | ||
1442 | |||
1443 | error->dovsta = I915_READ(DOVSTA); | ||
1444 | error->isr = I915_READ(ISR); | ||
1445 | if (OVERLAY_NONPHYSICAL(overlay->dev)) | ||
1446 | error->base = (long) overlay->reg_bo->gtt_offset; | ||
1447 | else | ||
1448 | error->base = (long) overlay->reg_bo->phys_obj->handle->vaddr; | ||
1449 | |||
1450 | regs = intel_overlay_map_regs_atomic(overlay); | ||
1451 | if (!regs) | ||
1452 | goto err; | ||
1453 | |||
1454 | memcpy_fromio(&error->regs, regs, sizeof(struct overlay_registers)); | ||
1455 | intel_overlay_unmap_regs_atomic(overlay); | ||
1456 | |||
1457 | return error; | ||
1458 | |||
1459 | err: | ||
1460 | kfree(error); | ||
1461 | return NULL; | ||
1462 | } | ||
1463 | |||
1464 | void | ||
1465 | intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error) | ||
1466 | { | ||
1467 | seq_printf(m, "Overlay, status: 0x%08x, interrupt: 0x%08x\n", | ||
1468 | error->dovsta, error->isr); | ||
1469 | seq_printf(m, " Register file at 0x%08lx:\n", | ||
1470 | error->base); | ||
1471 | |||
1472 | #define P(x) seq_printf(m, " " #x ": 0x%08x\n", error->regs.x) | ||
1473 | P(OBUF_0Y); | ||
1474 | P(OBUF_1Y); | ||
1475 | P(OBUF_0U); | ||
1476 | P(OBUF_0V); | ||
1477 | P(OBUF_1U); | ||
1478 | P(OBUF_1V); | ||
1479 | P(OSTRIDE); | ||
1480 | P(YRGB_VPH); | ||
1481 | P(UV_VPH); | ||
1482 | P(HORZ_PH); | ||
1483 | P(INIT_PHS); | ||
1484 | P(DWINPOS); | ||
1485 | P(DWINSZ); | ||
1486 | P(SWIDTH); | ||
1487 | P(SWIDTHSW); | ||
1488 | P(SHEIGHT); | ||
1489 | P(YRGBSCALE); | ||
1490 | P(UVSCALE); | ||
1491 | P(OCLRC0); | ||
1492 | P(OCLRC1); | ||
1493 | P(DCLRKV); | ||
1494 | P(DCLRKM); | ||
1495 | P(SCLRKVH); | ||
1496 | P(SCLRKVL); | ||
1497 | P(SCLRKEN); | ||
1498 | P(OCONFIG); | ||
1499 | P(OCMD); | ||
1500 | P(OSTART_0Y); | ||
1501 | P(OSTART_1Y); | ||
1502 | P(OSTART_0U); | ||
1503 | P(OSTART_0V); | ||
1504 | P(OSTART_1U); | ||
1505 | P(OSTART_1V); | ||
1506 | P(OTILEOFF_0Y); | ||
1507 | P(OTILEOFF_1Y); | ||
1508 | P(OTILEOFF_0U); | ||
1509 | P(OTILEOFF_0V); | ||
1510 | P(OTILEOFF_1U); | ||
1511 | P(OTILEOFF_1V); | ||
1512 | P(FASTHSCALE); | ||
1513 | P(UVSCALEV); | ||
1514 | #undef P | ||
1515 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c new file mode 100644 index 000000000000..e7f5299d9d57 --- /dev/null +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * Copyright © 2006-2010 Intel Corporation | ||
3 | * Copyright (c) 2006 Dave Airlie <airlied@linux.ie> | ||
4 | * | ||
5 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
6 | * copy of this software and associated documentation files (the "Software"), | ||
7 | * to deal in the Software without restriction, including without limitation | ||
8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
9 | * and/or sell copies of the Software, and to permit persons to whom the | ||
10 | * Software is furnished to do so, subject to the following conditions: | ||
11 | * | ||
12 | * The above copyright notice and this permission notice (including the next | ||
13 | * paragraph) shall be included in all copies or substantial portions of the | ||
14 | * Software. | ||
15 | * | ||
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
22 | * DEALINGS IN THE SOFTWARE. | ||
23 | * | ||
24 | * Authors: | ||
25 | * Eric Anholt <eric@anholt.net> | ||
26 | * Dave Airlie <airlied@linux.ie> | ||
27 | * Jesse Barnes <jesse.barnes@intel.com> | ||
28 | * Chris Wilson <chris@chris-wilson.co.uk> | ||
29 | */ | ||
30 | |||
31 | #include "intel_drv.h" | ||
32 | |||
33 | void | ||
34 | intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, | ||
35 | struct drm_display_mode *adjusted_mode) | ||
36 | { | ||
37 | adjusted_mode->hdisplay = fixed_mode->hdisplay; | ||
38 | adjusted_mode->hsync_start = fixed_mode->hsync_start; | ||
39 | adjusted_mode->hsync_end = fixed_mode->hsync_end; | ||
40 | adjusted_mode->htotal = fixed_mode->htotal; | ||
41 | |||
42 | adjusted_mode->vdisplay = fixed_mode->vdisplay; | ||
43 | adjusted_mode->vsync_start = fixed_mode->vsync_start; | ||
44 | adjusted_mode->vsync_end = fixed_mode->vsync_end; | ||
45 | adjusted_mode->vtotal = fixed_mode->vtotal; | ||
46 | |||
47 | adjusted_mode->clock = fixed_mode->clock; | ||
48 | |||
49 | drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); | ||
50 | } | ||
51 | |||
52 | /* adjusted_mode has been preset to be the panel's fixed mode */ | ||
53 | void | ||
54 | intel_pch_panel_fitting(struct drm_device *dev, | ||
55 | int fitting_mode, | ||
56 | struct drm_display_mode *mode, | ||
57 | struct drm_display_mode *adjusted_mode) | ||
58 | { | ||
59 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
60 | int x, y, width, height; | ||
61 | |||
62 | x = y = width = height = 0; | ||
63 | |||
64 | /* Native modes don't need fitting */ | ||
65 | if (adjusted_mode->hdisplay == mode->hdisplay && | ||
66 | adjusted_mode->vdisplay == mode->vdisplay) | ||
67 | goto done; | ||
68 | |||
69 | switch (fitting_mode) { | ||
70 | case DRM_MODE_SCALE_CENTER: | ||
71 | width = mode->hdisplay; | ||
72 | height = mode->vdisplay; | ||
73 | x = (adjusted_mode->hdisplay - width + 1)/2; | ||
74 | y = (adjusted_mode->vdisplay - height + 1)/2; | ||
75 | break; | ||
76 | |||
77 | case DRM_MODE_SCALE_ASPECT: | ||
78 | /* Scale but preserve the aspect ratio */ | ||
79 | { | ||
80 | u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; | ||
81 | u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; | ||
82 | if (scaled_width > scaled_height) { /* pillar */ | ||
83 | width = scaled_height / mode->vdisplay; | ||
84 | x = (adjusted_mode->hdisplay - width + 1) / 2; | ||
85 | y = 0; | ||
86 | height = adjusted_mode->vdisplay; | ||
87 | } else if (scaled_width < scaled_height) { /* letter */ | ||
88 | height = scaled_width / mode->hdisplay; | ||
89 | y = (adjusted_mode->vdisplay - height + 1) / 2; | ||
90 | x = 0; | ||
91 | width = adjusted_mode->hdisplay; | ||
92 | } else { | ||
93 | x = y = 0; | ||
94 | width = adjusted_mode->hdisplay; | ||
95 | height = adjusted_mode->vdisplay; | ||
96 | } | ||
97 | } | ||
98 | break; | ||
99 | |||
100 | default: | ||
101 | case DRM_MODE_SCALE_FULLSCREEN: | ||
102 | x = y = 0; | ||
103 | width = adjusted_mode->hdisplay; | ||
104 | height = adjusted_mode->vdisplay; | ||
105 | break; | ||
106 | } | ||
107 | |||
108 | done: | ||
109 | dev_priv->pch_pf_pos = (x << 16) | y; | ||
110 | dev_priv->pch_pf_size = (width << 16) | height; | ||
111 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 26362f8495a8..51e9c9e718c4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -33,18 +33,35 @@ | |||
33 | #include "i915_drm.h" | 33 | #include "i915_drm.h" |
34 | #include "i915_trace.h" | 34 | #include "i915_trace.h" |
35 | 35 | ||
36 | static u32 i915_gem_get_seqno(struct drm_device *dev) | ||
37 | { | ||
38 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
39 | u32 seqno; | ||
40 | |||
41 | seqno = dev_priv->next_seqno; | ||
42 | |||
43 | /* reserve 0 for non-seqno */ | ||
44 | if (++dev_priv->next_seqno == 0) | ||
45 | dev_priv->next_seqno = 1; | ||
46 | |||
47 | return seqno; | ||
48 | } | ||
49 | |||
36 | static void | 50 | static void |
37 | render_ring_flush(struct drm_device *dev, | 51 | render_ring_flush(struct drm_device *dev, |
38 | struct intel_ring_buffer *ring, | 52 | struct intel_ring_buffer *ring, |
39 | u32 invalidate_domains, | 53 | u32 invalidate_domains, |
40 | u32 flush_domains) | 54 | u32 flush_domains) |
41 | { | 55 | { |
56 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
57 | u32 cmd; | ||
58 | |||
42 | #if WATCH_EXEC | 59 | #if WATCH_EXEC |
43 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, | 60 | DRM_INFO("%s: invalidate %08x flush %08x\n", __func__, |
44 | invalidate_domains, flush_domains); | 61 | invalidate_domains, flush_domains); |
45 | #endif | 62 | #endif |
46 | u32 cmd; | 63 | |
47 | trace_i915_gem_request_flush(dev, ring->next_seqno, | 64 | trace_i915_gem_request_flush(dev, dev_priv->next_seqno, |
48 | invalidate_domains, flush_domains); | 65 | invalidate_domains, flush_domains); |
49 | 66 | ||
50 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { | 67 | if ((invalidate_domains | flush_domains) & I915_GEM_GPU_DOMAINS) { |
@@ -233,9 +250,10 @@ render_ring_add_request(struct drm_device *dev, | |||
233 | struct drm_file *file_priv, | 250 | struct drm_file *file_priv, |
234 | u32 flush_domains) | 251 | u32 flush_domains) |
235 | { | 252 | { |
236 | u32 seqno; | ||
237 | drm_i915_private_t *dev_priv = dev->dev_private; | 253 | drm_i915_private_t *dev_priv = dev->dev_private; |
238 | seqno = intel_ring_get_seqno(dev, ring); | 254 | u32 seqno; |
255 | |||
256 | seqno = i915_gem_get_seqno(dev); | ||
239 | 257 | ||
240 | if (IS_GEN6(dev)) { | 258 | if (IS_GEN6(dev)) { |
241 | BEGIN_LP_RING(6); | 259 | BEGIN_LP_RING(6); |
@@ -405,7 +423,9 @@ bsd_ring_add_request(struct drm_device *dev, | |||
405 | u32 flush_domains) | 423 | u32 flush_domains) |
406 | { | 424 | { |
407 | u32 seqno; | 425 | u32 seqno; |
408 | seqno = intel_ring_get_seqno(dev, ring); | 426 | |
427 | seqno = i915_gem_get_seqno(dev); | ||
428 | |||
409 | intel_ring_begin(dev, ring, 4); | 429 | intel_ring_begin(dev, ring, 4); |
410 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); | 430 | intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); |
411 | intel_ring_emit(dev, ring, | 431 | intel_ring_emit(dev, ring, |
@@ -479,7 +499,7 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |||
479 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; | 499 | exec_start = (uint32_t) exec_offset + exec->batch_start_offset; |
480 | exec_len = (uint32_t) exec->batch_len; | 500 | exec_len = (uint32_t) exec->batch_len; |
481 | 501 | ||
482 | trace_i915_gem_request_submit(dev, dev_priv->mm.next_gem_seqno + 1); | 502 | trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1); |
483 | 503 | ||
484 | count = nbox ? nbox : 1; | 504 | count = nbox ? nbox : 1; |
485 | 505 | ||
@@ -515,7 +535,16 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, | |||
515 | intel_ring_advance(dev, ring); | 535 | intel_ring_advance(dev, ring); |
516 | } | 536 | } |
517 | 537 | ||
538 | if (IS_G4X(dev) || IS_IRONLAKE(dev)) { | ||
539 | intel_ring_begin(dev, ring, 2); | ||
540 | intel_ring_emit(dev, ring, MI_FLUSH | | ||
541 | MI_NO_WRITE_FLUSH | | ||
542 | MI_INVALIDATE_ISP ); | ||
543 | intel_ring_emit(dev, ring, MI_NOOP); | ||
544 | intel_ring_advance(dev, ring); | ||
545 | } | ||
518 | /* XXX breadcrumb */ | 546 | /* XXX breadcrumb */ |
547 | |||
519 | return 0; | 548 | return 0; |
520 | } | 549 | } |
521 | 550 | ||
@@ -588,9 +617,10 @@ err: | |||
588 | int intel_init_ring_buffer(struct drm_device *dev, | 617 | int intel_init_ring_buffer(struct drm_device *dev, |
589 | struct intel_ring_buffer *ring) | 618 | struct intel_ring_buffer *ring) |
590 | { | 619 | { |
591 | int ret; | ||
592 | struct drm_i915_gem_object *obj_priv; | 620 | struct drm_i915_gem_object *obj_priv; |
593 | struct drm_gem_object *obj; | 621 | struct drm_gem_object *obj; |
622 | int ret; | ||
623 | |||
594 | ring->dev = dev; | 624 | ring->dev = dev; |
595 | 625 | ||
596 | if (I915_NEED_GFX_HWS(dev)) { | 626 | if (I915_NEED_GFX_HWS(dev)) { |
@@ -603,16 +633,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
603 | if (obj == NULL) { | 633 | if (obj == NULL) { |
604 | DRM_ERROR("Failed to allocate ringbuffer\n"); | 634 | DRM_ERROR("Failed to allocate ringbuffer\n"); |
605 | ret = -ENOMEM; | 635 | ret = -ENOMEM; |
606 | goto cleanup; | 636 | goto err_hws; |
607 | } | 637 | } |
608 | 638 | ||
609 | ring->gem_object = obj; | 639 | ring->gem_object = obj; |
610 | 640 | ||
611 | ret = i915_gem_object_pin(obj, ring->alignment); | 641 | ret = i915_gem_object_pin(obj, ring->alignment); |
612 | if (ret != 0) { | 642 | if (ret) |
613 | drm_gem_object_unreference(obj); | 643 | goto err_unref; |
614 | goto cleanup; | ||
615 | } | ||
616 | 644 | ||
617 | obj_priv = to_intel_bo(obj); | 645 | obj_priv = to_intel_bo(obj); |
618 | ring->map.size = ring->size; | 646 | ring->map.size = ring->size; |
@@ -624,18 +652,14 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
624 | drm_core_ioremap_wc(&ring->map, dev); | 652 | drm_core_ioremap_wc(&ring->map, dev); |
625 | if (ring->map.handle == NULL) { | 653 | if (ring->map.handle == NULL) { |
626 | DRM_ERROR("Failed to map ringbuffer.\n"); | 654 | DRM_ERROR("Failed to map ringbuffer.\n"); |
627 | i915_gem_object_unpin(obj); | ||
628 | drm_gem_object_unreference(obj); | ||
629 | ret = -EINVAL; | 655 | ret = -EINVAL; |
630 | goto cleanup; | 656 | goto err_unpin; |
631 | } | 657 | } |
632 | 658 | ||
633 | ring->virtual_start = ring->map.handle; | 659 | ring->virtual_start = ring->map.handle; |
634 | ret = ring->init(dev, ring); | 660 | ret = ring->init(dev, ring); |
635 | if (ret != 0) { | 661 | if (ret) |
636 | intel_cleanup_ring_buffer(dev, ring); | 662 | goto err_unmap; |
637 | return ret; | ||
638 | } | ||
639 | 663 | ||
640 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | 664 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
641 | i915_kernel_lost_context(dev); | 665 | i915_kernel_lost_context(dev); |
@@ -649,7 +673,15 @@ int intel_init_ring_buffer(struct drm_device *dev, | |||
649 | INIT_LIST_HEAD(&ring->active_list); | 673 | INIT_LIST_HEAD(&ring->active_list); |
650 | INIT_LIST_HEAD(&ring->request_list); | 674 | INIT_LIST_HEAD(&ring->request_list); |
651 | return ret; | 675 | return ret; |
652 | cleanup: | 676 | |
677 | err_unmap: | ||
678 | drm_core_ioremapfree(&ring->map, dev); | ||
679 | err_unpin: | ||
680 | i915_gem_object_unpin(obj); | ||
681 | err_unref: | ||
682 | drm_gem_object_unreference(obj); | ||
683 | ring->gem_object = NULL; | ||
684 | err_hws: | ||
653 | cleanup_status_page(dev, ring); | 685 | cleanup_status_page(dev, ring); |
654 | return ret; | 686 | return ret; |
655 | } | 687 | } |
@@ -682,9 +714,11 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
682 | } | 714 | } |
683 | 715 | ||
684 | virt = (unsigned int *)(ring->virtual_start + ring->tail); | 716 | virt = (unsigned int *)(ring->virtual_start + ring->tail); |
685 | rem /= 4; | 717 | rem /= 8; |
686 | while (rem--) | 718 | while (rem--) { |
719 | *virt++ = MI_NOOP; | ||
687 | *virt++ = MI_NOOP; | 720 | *virt++ = MI_NOOP; |
721 | } | ||
688 | 722 | ||
689 | ring->tail = 0; | 723 | ring->tail = 0; |
690 | ring->space = ring->head - 8; | 724 | ring->space = ring->head - 8; |
@@ -729,21 +763,14 @@ void intel_ring_begin(struct drm_device *dev, | |||
729 | intel_wrap_ring_buffer(dev, ring); | 763 | intel_wrap_ring_buffer(dev, ring); |
730 | if (unlikely(ring->space < n)) | 764 | if (unlikely(ring->space < n)) |
731 | intel_wait_ring_buffer(dev, ring, n); | 765 | intel_wait_ring_buffer(dev, ring, n); |
732 | } | ||
733 | 766 | ||
734 | void intel_ring_emit(struct drm_device *dev, | 767 | ring->space -= n; |
735 | struct intel_ring_buffer *ring, unsigned int data) | ||
736 | { | ||
737 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
738 | *virt = data; | ||
739 | ring->tail += 4; | ||
740 | ring->tail &= ring->size - 1; | ||
741 | ring->space -= 4; | ||
742 | } | 768 | } |
743 | 769 | ||
744 | void intel_ring_advance(struct drm_device *dev, | 770 | void intel_ring_advance(struct drm_device *dev, |
745 | struct intel_ring_buffer *ring) | 771 | struct intel_ring_buffer *ring) |
746 | { | 772 | { |
773 | ring->tail &= ring->size - 1; | ||
747 | ring->advance_ring(dev, ring); | 774 | ring->advance_ring(dev, ring); |
748 | } | 775 | } |
749 | 776 | ||
@@ -762,18 +789,6 @@ void intel_fill_struct(struct drm_device *dev, | |||
762 | intel_ring_advance(dev, ring); | 789 | intel_ring_advance(dev, ring); |
763 | } | 790 | } |
764 | 791 | ||
765 | u32 intel_ring_get_seqno(struct drm_device *dev, | ||
766 | struct intel_ring_buffer *ring) | ||
767 | { | ||
768 | u32 seqno; | ||
769 | seqno = ring->next_seqno; | ||
770 | |||
771 | /* reserve 0 for non-seqno */ | ||
772 | if (++ring->next_seqno == 0) | ||
773 | ring->next_seqno = 1; | ||
774 | return seqno; | ||
775 | } | ||
776 | |||
777 | struct intel_ring_buffer render_ring = { | 792 | struct intel_ring_buffer render_ring = { |
778 | .name = "render ring", | 793 | .name = "render ring", |
779 | .regs = { | 794 | .regs = { |
@@ -791,7 +806,6 @@ struct intel_ring_buffer render_ring = { | |||
791 | .head = 0, | 806 | .head = 0, |
792 | .tail = 0, | 807 | .tail = 0, |
793 | .space = 0, | 808 | .space = 0, |
794 | .next_seqno = 1, | ||
795 | .user_irq_refcount = 0, | 809 | .user_irq_refcount = 0, |
796 | .irq_gem_seqno = 0, | 810 | .irq_gem_seqno = 0, |
797 | .waiting_gem_seqno = 0, | 811 | .waiting_gem_seqno = 0, |
@@ -830,7 +844,6 @@ struct intel_ring_buffer bsd_ring = { | |||
830 | .head = 0, | 844 | .head = 0, |
831 | .tail = 0, | 845 | .tail = 0, |
832 | .space = 0, | 846 | .space = 0, |
833 | .next_seqno = 1, | ||
834 | .user_irq_refcount = 0, | 847 | .user_irq_refcount = 0, |
835 | .irq_gem_seqno = 0, | 848 | .irq_gem_seqno = 0, |
836 | .waiting_gem_seqno = 0, | 849 | .waiting_gem_seqno = 0, |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d5568d3766de..525e7d3edda8 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -26,7 +26,6 @@ struct intel_ring_buffer { | |||
26 | unsigned int head; | 26 | unsigned int head; |
27 | unsigned int tail; | 27 | unsigned int tail; |
28 | unsigned int space; | 28 | unsigned int space; |
29 | u32 next_seqno; | ||
30 | struct intel_hw_status_page status_page; | 29 | struct intel_hw_status_page status_page; |
31 | 30 | ||
32 | u32 irq_gem_seqno; /* last seq seem at irq time */ | 31 | u32 irq_gem_seqno; /* last seq seem at irq time */ |
@@ -106,8 +105,16 @@ int intel_wrap_ring_buffer(struct drm_device *dev, | |||
106 | struct intel_ring_buffer *ring); | 105 | struct intel_ring_buffer *ring); |
107 | void intel_ring_begin(struct drm_device *dev, | 106 | void intel_ring_begin(struct drm_device *dev, |
108 | struct intel_ring_buffer *ring, int n); | 107 | struct intel_ring_buffer *ring, int n); |
109 | void intel_ring_emit(struct drm_device *dev, | 108 | |
110 | struct intel_ring_buffer *ring, u32 data); | 109 | static inline void intel_ring_emit(struct drm_device *dev, |
110 | struct intel_ring_buffer *ring, | ||
111 | unsigned int data) | ||
112 | { | ||
113 | unsigned int *virt = ring->virtual_start + ring->tail; | ||
114 | *virt = data; | ||
115 | ring->tail += 4; | ||
116 | } | ||
117 | |||
111 | void intel_fill_struct(struct drm_device *dev, | 118 | void intel_fill_struct(struct drm_device *dev, |
112 | struct intel_ring_buffer *ring, | 119 | struct intel_ring_buffer *ring, |
113 | void *data, | 120 | void *data, |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d9d4d51aa89e..093e914e8a41 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -31,8 +31,8 @@ | |||
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 "intel_drv.h" | ||
35 | #include "drm_edid.h" | 34 | #include "drm_edid.h" |
35 | #include "intel_drv.h" | ||
36 | #include "i915_drm.h" | 36 | #include "i915_drm.h" |
37 | #include "i915_drv.h" | 37 | #include "i915_drv.h" |
38 | #include "intel_sdvo_regs.h" | 38 | #include "intel_sdvo_regs.h" |
@@ -47,9 +47,10 @@ | |||
47 | 47 | ||
48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) | 48 | #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) |
49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) | 49 | #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) |
50 | #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) | ||
50 | 51 | ||
51 | 52 | ||
52 | static char *tv_format_names[] = { | 53 | static const char *tv_format_names[] = { |
53 | "NTSC_M" , "NTSC_J" , "NTSC_443", | 54 | "NTSC_M" , "NTSC_J" , "NTSC_443", |
54 | "PAL_B" , "PAL_D" , "PAL_G" , | 55 | "PAL_B" , "PAL_D" , "PAL_G" , |
55 | "PAL_H" , "PAL_I" , "PAL_M" , | 56 | "PAL_H" , "PAL_I" , "PAL_M" , |
@@ -61,7 +62,9 @@ static char *tv_format_names[] = { | |||
61 | 62 | ||
62 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) | 63 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) |
63 | 64 | ||
64 | struct intel_sdvo_priv { | 65 | struct intel_sdvo { |
66 | struct intel_encoder base; | ||
67 | |||
65 | u8 slave_addr; | 68 | u8 slave_addr; |
66 | 69 | ||
67 | /* Register for the SDVO device: SDVOB or SDVOC */ | 70 | /* Register for the SDVO device: SDVOB or SDVOC */ |
@@ -95,7 +98,7 @@ struct intel_sdvo_priv { | |||
95 | bool is_tv; | 98 | bool is_tv; |
96 | 99 | ||
97 | /* This is for current tv format name */ | 100 | /* This is for current tv format name */ |
98 | char *tv_format_name; | 101 | int tv_format_index; |
99 | 102 | ||
100 | /** | 103 | /** |
101 | * This is set if we treat the device as HDMI, instead of DVI. | 104 | * This is set if we treat the device as HDMI, instead of DVI. |
@@ -132,37 +135,40 @@ struct intel_sdvo_priv { | |||
132 | }; | 135 | }; |
133 | 136 | ||
134 | struct intel_sdvo_connector { | 137 | struct intel_sdvo_connector { |
138 | struct intel_connector base; | ||
139 | |||
135 | /* Mark the type of connector */ | 140 | /* Mark the type of connector */ |
136 | uint16_t output_flag; | 141 | uint16_t output_flag; |
137 | 142 | ||
138 | /* This contains all current supported TV format */ | 143 | /* This contains all current supported TV format */ |
139 | char *tv_format_supported[TV_FORMAT_NUM]; | 144 | u8 tv_format_supported[TV_FORMAT_NUM]; |
140 | int format_supported_num; | 145 | int format_supported_num; |
141 | struct drm_property *tv_format_property; | 146 | struct drm_property *tv_format; |
142 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
143 | |||
144 | /** | ||
145 | * Returned SDTV resolutions allowed for the current format, if the | ||
146 | * device reported it. | ||
147 | */ | ||
148 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | ||
149 | 147 | ||
150 | /* add the property for the SDVO-TV */ | 148 | /* add the property for the SDVO-TV */ |
151 | struct drm_property *left_property; | 149 | struct drm_property *left; |
152 | struct drm_property *right_property; | 150 | struct drm_property *right; |
153 | struct drm_property *top_property; | 151 | struct drm_property *top; |
154 | struct drm_property *bottom_property; | 152 | struct drm_property *bottom; |
155 | struct drm_property *hpos_property; | 153 | struct drm_property *hpos; |
156 | struct drm_property *vpos_property; | 154 | struct drm_property *vpos; |
155 | struct drm_property *contrast; | ||
156 | struct drm_property *saturation; | ||
157 | struct drm_property *hue; | ||
158 | struct drm_property *sharpness; | ||
159 | struct drm_property *flicker_filter; | ||
160 | struct drm_property *flicker_filter_adaptive; | ||
161 | struct drm_property *flicker_filter_2d; | ||
162 | struct drm_property *tv_chroma_filter; | ||
163 | struct drm_property *tv_luma_filter; | ||
164 | struct drm_property *dot_crawl; | ||
157 | 165 | ||
158 | /* add the property for the SDVO-TV/LVDS */ | 166 | /* add the property for the SDVO-TV/LVDS */ |
159 | struct drm_property *brightness_property; | 167 | struct drm_property *brightness; |
160 | struct drm_property *contrast_property; | ||
161 | struct drm_property *saturation_property; | ||
162 | struct drm_property *hue_property; | ||
163 | 168 | ||
164 | /* Add variable to record current setting for the above property */ | 169 | /* Add variable to record current setting for the above property */ |
165 | u32 left_margin, right_margin, top_margin, bottom_margin; | 170 | u32 left_margin, right_margin, top_margin, bottom_margin; |
171 | |||
166 | /* this is to get the range of margin.*/ | 172 | /* this is to get the range of margin.*/ |
167 | u32 max_hscan, max_vscan; | 173 | u32 max_hscan, max_vscan; |
168 | u32 max_hpos, cur_hpos; | 174 | u32 max_hpos, cur_hpos; |
@@ -171,36 +177,54 @@ struct intel_sdvo_connector { | |||
171 | u32 cur_contrast, max_contrast; | 177 | u32 cur_contrast, max_contrast; |
172 | u32 cur_saturation, max_saturation; | 178 | u32 cur_saturation, max_saturation; |
173 | u32 cur_hue, max_hue; | 179 | u32 cur_hue, max_hue; |
180 | u32 cur_sharpness, max_sharpness; | ||
181 | u32 cur_flicker_filter, max_flicker_filter; | ||
182 | u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive; | ||
183 | u32 cur_flicker_filter_2d, max_flicker_filter_2d; | ||
184 | u32 cur_tv_chroma_filter, max_tv_chroma_filter; | ||
185 | u32 cur_tv_luma_filter, max_tv_luma_filter; | ||
186 | u32 cur_dot_crawl, max_dot_crawl; | ||
174 | }; | 187 | }; |
175 | 188 | ||
189 | static struct intel_sdvo *enc_to_intel_sdvo(struct drm_encoder *encoder) | ||
190 | { | ||
191 | return container_of(enc_to_intel_encoder(encoder), struct intel_sdvo, base); | ||
192 | } | ||
193 | |||
194 | static struct intel_sdvo_connector *to_intel_sdvo_connector(struct drm_connector *connector) | ||
195 | { | ||
196 | return container_of(to_intel_connector(connector), struct intel_sdvo_connector, base); | ||
197 | } | ||
198 | |||
176 | static bool | 199 | static bool |
177 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, | 200 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags); |
178 | uint16_t flags); | 201 | static bool |
179 | static void | 202 | intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
180 | intel_sdvo_tv_create_property(struct drm_connector *connector, int type); | 203 | struct intel_sdvo_connector *intel_sdvo_connector, |
181 | static void | 204 | int type); |
182 | intel_sdvo_create_enhance_property(struct drm_connector *connector); | 205 | static bool |
206 | intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, | ||
207 | struct intel_sdvo_connector *intel_sdvo_connector); | ||
183 | 208 | ||
184 | /** | 209 | /** |
185 | * Writes the SDVOB or SDVOC with the given value, but always writes both | 210 | * Writes the SDVOB or SDVOC with the given value, but always writes both |
186 | * SDVOB and SDVOC to work around apparent hardware issues (according to | 211 | * SDVOB and SDVOC to work around apparent hardware issues (according to |
187 | * comments in the BIOS). | 212 | * comments in the BIOS). |
188 | */ | 213 | */ |
189 | static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | 214 | static void intel_sdvo_write_sdvox(struct intel_sdvo *intel_sdvo, u32 val) |
190 | { | 215 | { |
191 | struct drm_device *dev = intel_encoder->enc.dev; | 216 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
192 | struct drm_i915_private *dev_priv = dev->dev_private; | 217 | struct drm_i915_private *dev_priv = dev->dev_private; |
193 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
194 | u32 bval = val, cval = val; | 218 | u32 bval = val, cval = val; |
195 | int i; | 219 | int i; |
196 | 220 | ||
197 | if (sdvo_priv->sdvo_reg == PCH_SDVOB) { | 221 | if (intel_sdvo->sdvo_reg == PCH_SDVOB) { |
198 | I915_WRITE(sdvo_priv->sdvo_reg, val); | 222 | I915_WRITE(intel_sdvo->sdvo_reg, val); |
199 | I915_READ(sdvo_priv->sdvo_reg); | 223 | I915_READ(intel_sdvo->sdvo_reg); |
200 | return; | 224 | return; |
201 | } | 225 | } |
202 | 226 | ||
203 | if (sdvo_priv->sdvo_reg == SDVOB) { | 227 | if (intel_sdvo->sdvo_reg == SDVOB) { |
204 | cval = I915_READ(SDVOC); | 228 | cval = I915_READ(SDVOC); |
205 | } else { | 229 | } else { |
206 | bval = I915_READ(SDVOB); | 230 | bval = I915_READ(SDVOB); |
@@ -219,33 +243,27 @@ static void intel_sdvo_write_sdvox(struct intel_encoder *intel_encoder, u32 val) | |||
219 | } | 243 | } |
220 | } | 244 | } |
221 | 245 | ||
222 | static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, | 246 | static bool intel_sdvo_read_byte(struct intel_sdvo *intel_sdvo, u8 addr, u8 *ch) |
223 | u8 *ch) | ||
224 | { | 247 | { |
225 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 248 | u8 out_buf[2] = { addr, 0 }; |
226 | u8 out_buf[2]; | ||
227 | u8 buf[2]; | 249 | u8 buf[2]; |
228 | int ret; | ||
229 | |||
230 | struct i2c_msg msgs[] = { | 250 | struct i2c_msg msgs[] = { |
231 | { | 251 | { |
232 | .addr = sdvo_priv->slave_addr >> 1, | 252 | .addr = intel_sdvo->slave_addr >> 1, |
233 | .flags = 0, | 253 | .flags = 0, |
234 | .len = 1, | 254 | .len = 1, |
235 | .buf = out_buf, | 255 | .buf = out_buf, |
236 | }, | 256 | }, |
237 | { | 257 | { |
238 | .addr = sdvo_priv->slave_addr >> 1, | 258 | .addr = intel_sdvo->slave_addr >> 1, |
239 | .flags = I2C_M_RD, | 259 | .flags = I2C_M_RD, |
240 | .len = 1, | 260 | .len = 1, |
241 | .buf = buf, | 261 | .buf = buf, |
242 | } | 262 | } |
243 | }; | 263 | }; |
264 | int ret; | ||
244 | 265 | ||
245 | out_buf[0] = addr; | 266 | if ((ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 2)) == 2) |
246 | out_buf[1] = 0; | ||
247 | |||
248 | if ((ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 2)) == 2) | ||
249 | { | 267 | { |
250 | *ch = buf[0]; | 268 | *ch = buf[0]; |
251 | return true; | 269 | return true; |
@@ -255,35 +273,26 @@ static bool intel_sdvo_read_byte(struct intel_encoder *intel_encoder, u8 addr, | |||
255 | return false; | 273 | return false; |
256 | } | 274 | } |
257 | 275 | ||
258 | static bool intel_sdvo_write_byte(struct intel_encoder *intel_encoder, int addr, | 276 | static bool intel_sdvo_write_byte(struct intel_sdvo *intel_sdvo, int addr, u8 ch) |
259 | u8 ch) | ||
260 | { | 277 | { |
261 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 278 | u8 out_buf[2] = { addr, ch }; |
262 | u8 out_buf[2]; | ||
263 | struct i2c_msg msgs[] = { | 279 | struct i2c_msg msgs[] = { |
264 | { | 280 | { |
265 | .addr = sdvo_priv->slave_addr >> 1, | 281 | .addr = intel_sdvo->slave_addr >> 1, |
266 | .flags = 0, | 282 | .flags = 0, |
267 | .len = 2, | 283 | .len = 2, |
268 | .buf = out_buf, | 284 | .buf = out_buf, |
269 | } | 285 | } |
270 | }; | 286 | }; |
271 | 287 | ||
272 | out_buf[0] = addr; | 288 | return i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 1) == 1; |
273 | out_buf[1] = ch; | ||
274 | |||
275 | if (i2c_transfer(intel_encoder->i2c_bus, msgs, 1) == 1) | ||
276 | { | ||
277 | return true; | ||
278 | } | ||
279 | return false; | ||
280 | } | 289 | } |
281 | 290 | ||
282 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} | 291 | #define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} |
283 | /** Mapping of command numbers to names, for debug output */ | 292 | /** Mapping of command numbers to names, for debug output */ |
284 | static const struct _sdvo_cmd_name { | 293 | static const struct _sdvo_cmd_name { |
285 | u8 cmd; | 294 | u8 cmd; |
286 | char *name; | 295 | const char *name; |
287 | } sdvo_cmd_names[] = { | 296 | } sdvo_cmd_names[] = { |
288 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), | 297 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), |
289 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), | 298 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), |
@@ -328,13 +337,14 @@ static const struct _sdvo_cmd_name { | |||
328 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), | 337 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), |
329 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), | 338 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), |
330 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), | 339 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), |
340 | |||
331 | /* Add the op code for SDVO enhancements */ | 341 | /* Add the op code for SDVO enhancements */ |
332 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_H), | 342 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS), |
333 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_H), | 343 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS), |
334 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_H), | 344 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS), |
335 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_POSITION_V), | 345 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS), |
336 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POSITION_V), | 346 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS), |
337 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_POSITION_V), | 347 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS), |
338 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), | 348 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), |
339 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), | 349 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), |
340 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), | 350 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), |
@@ -353,6 +363,27 @@ static const struct _sdvo_cmd_name { | |||
353 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), | 363 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), |
354 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), | 364 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), |
355 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), | 365 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), |
366 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER), | ||
367 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER), | ||
368 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER), | ||
369 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE), | ||
370 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE), | ||
371 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE), | ||
372 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D), | ||
373 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D), | ||
374 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D), | ||
375 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS), | ||
376 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS), | ||
377 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS), | ||
378 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL), | ||
379 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL), | ||
380 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER), | ||
381 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER), | ||
382 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER), | ||
383 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER), | ||
384 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER), | ||
385 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER), | ||
386 | |||
356 | /* HDMI op code */ | 387 | /* HDMI op code */ |
357 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), | 388 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), |
358 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), | 389 | SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), |
@@ -377,17 +408,15 @@ static const struct _sdvo_cmd_name { | |||
377 | }; | 408 | }; |
378 | 409 | ||
379 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) | 410 | #define IS_SDVOB(reg) (reg == SDVOB || reg == PCH_SDVOB) |
380 | #define SDVO_NAME(dev_priv) (IS_SDVOB((dev_priv)->sdvo_reg) ? "SDVOB" : "SDVOC") | 411 | #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") |
381 | #define SDVO_PRIV(encoder) ((struct intel_sdvo_priv *) (encoder)->dev_priv) | ||
382 | 412 | ||
383 | static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | 413 | static void intel_sdvo_debug_write(struct intel_sdvo *intel_sdvo, u8 cmd, |
384 | void *args, int args_len) | 414 | const void *args, int args_len) |
385 | { | 415 | { |
386 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
387 | int i; | 416 | int i; |
388 | 417 | ||
389 | DRM_DEBUG_KMS("%s: W: %02X ", | 418 | DRM_DEBUG_KMS("%s: W: %02X ", |
390 | SDVO_NAME(sdvo_priv), cmd); | 419 | SDVO_NAME(intel_sdvo), cmd); |
391 | for (i = 0; i < args_len; i++) | 420 | for (i = 0; i < args_len; i++) |
392 | DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); | 421 | DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); |
393 | for (; i < 8; i++) | 422 | for (; i < 8; i++) |
@@ -403,19 +432,20 @@ static void intel_sdvo_debug_write(struct intel_encoder *intel_encoder, u8 cmd, | |||
403 | DRM_LOG_KMS("\n"); | 432 | DRM_LOG_KMS("\n"); |
404 | } | 433 | } |
405 | 434 | ||
406 | static void intel_sdvo_write_cmd(struct intel_encoder *intel_encoder, u8 cmd, | 435 | static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, |
407 | void *args, int args_len) | 436 | const void *args, int args_len) |
408 | { | 437 | { |
409 | int i; | 438 | int i; |
410 | 439 | ||
411 | intel_sdvo_debug_write(intel_encoder, cmd, args, args_len); | 440 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
412 | 441 | ||
413 | for (i = 0; i < args_len; i++) { | 442 | for (i = 0; i < args_len; i++) { |
414 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0 - i, | 443 | if (!intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0 - i, |
415 | ((u8*)args)[i]); | 444 | ((u8*)args)[i])) |
445 | return false; | ||
416 | } | 446 | } |
417 | 447 | ||
418 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_OPCODE, cmd); | 448 | return intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_OPCODE, cmd); |
419 | } | 449 | } |
420 | 450 | ||
421 | static const char *cmd_status_names[] = { | 451 | static const char *cmd_status_names[] = { |
@@ -428,14 +458,13 @@ static const char *cmd_status_names[] = { | |||
428 | "Scaling not supported" | 458 | "Scaling not supported" |
429 | }; | 459 | }; |
430 | 460 | ||
431 | static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, | 461 | static void intel_sdvo_debug_response(struct intel_sdvo *intel_sdvo, |
432 | void *response, int response_len, | 462 | void *response, int response_len, |
433 | u8 status) | 463 | u8 status) |
434 | { | 464 | { |
435 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
436 | int i; | 465 | int i; |
437 | 466 | ||
438 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(sdvo_priv)); | 467 | DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(intel_sdvo)); |
439 | for (i = 0; i < response_len; i++) | 468 | for (i = 0; i < response_len; i++) |
440 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); | 469 | DRM_LOG_KMS("%02X ", ((u8 *)response)[i]); |
441 | for (; i < 8; i++) | 470 | for (; i < 8; i++) |
@@ -447,8 +476,8 @@ static void intel_sdvo_debug_response(struct intel_encoder *intel_encoder, | |||
447 | DRM_LOG_KMS("\n"); | 476 | DRM_LOG_KMS("\n"); |
448 | } | 477 | } |
449 | 478 | ||
450 | static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, | 479 | static bool intel_sdvo_read_response(struct intel_sdvo *intel_sdvo, |
451 | void *response, int response_len) | 480 | void *response, int response_len) |
452 | { | 481 | { |
453 | int i; | 482 | int i; |
454 | u8 status; | 483 | u8 status; |
@@ -457,24 +486,26 @@ static u8 intel_sdvo_read_response(struct intel_encoder *intel_encoder, | |||
457 | while (retry--) { | 486 | while (retry--) { |
458 | /* Read the command response */ | 487 | /* Read the command response */ |
459 | for (i = 0; i < response_len; i++) { | 488 | for (i = 0; i < response_len; i++) { |
460 | intel_sdvo_read_byte(intel_encoder, | 489 | if (!intel_sdvo_read_byte(intel_sdvo, |
461 | SDVO_I2C_RETURN_0 + i, | 490 | SDVO_I2C_RETURN_0 + i, |
462 | &((u8 *)response)[i]); | 491 | &((u8 *)response)[i])) |
492 | return false; | ||
463 | } | 493 | } |
464 | 494 | ||
465 | /* read the return status */ | 495 | /* read the return status */ |
466 | intel_sdvo_read_byte(intel_encoder, SDVO_I2C_CMD_STATUS, | 496 | if (!intel_sdvo_read_byte(intel_sdvo, SDVO_I2C_CMD_STATUS, |
467 | &status); | 497 | &status)) |
498 | return false; | ||
468 | 499 | ||
469 | intel_sdvo_debug_response(intel_encoder, response, response_len, | 500 | intel_sdvo_debug_response(intel_sdvo, response, response_len, |
470 | status); | 501 | status); |
471 | if (status != SDVO_CMD_STATUS_PENDING) | 502 | if (status != SDVO_CMD_STATUS_PENDING) |
472 | return status; | 503 | break; |
473 | 504 | ||
474 | mdelay(50); | 505 | mdelay(50); |
475 | } | 506 | } |
476 | 507 | ||
477 | return status; | 508 | return status == SDVO_CMD_STATUS_SUCCESS; |
478 | } | 509 | } |
479 | 510 | ||
480 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | 511 | static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) |
@@ -494,37 +525,36 @@ static int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) | |||
494 | * another I2C transaction after issuing the DDC bus switch, it will be | 525 | * another I2C transaction after issuing the DDC bus switch, it will be |
495 | * switched to the internal SDVO register. | 526 | * switched to the internal SDVO register. |
496 | */ | 527 | */ |
497 | static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encoder, | 528 | static void intel_sdvo_set_control_bus_switch(struct intel_sdvo *intel_sdvo, |
498 | u8 target) | 529 | u8 target) |
499 | { | 530 | { |
500 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
501 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; | 531 | u8 out_buf[2], cmd_buf[2], ret_value[2], ret; |
502 | struct i2c_msg msgs[] = { | 532 | struct i2c_msg msgs[] = { |
503 | { | 533 | { |
504 | .addr = sdvo_priv->slave_addr >> 1, | 534 | .addr = intel_sdvo->slave_addr >> 1, |
505 | .flags = 0, | 535 | .flags = 0, |
506 | .len = 2, | 536 | .len = 2, |
507 | .buf = out_buf, | 537 | .buf = out_buf, |
508 | }, | 538 | }, |
509 | /* the following two are to read the response */ | 539 | /* the following two are to read the response */ |
510 | { | 540 | { |
511 | .addr = sdvo_priv->slave_addr >> 1, | 541 | .addr = intel_sdvo->slave_addr >> 1, |
512 | .flags = 0, | 542 | .flags = 0, |
513 | .len = 1, | 543 | .len = 1, |
514 | .buf = cmd_buf, | 544 | .buf = cmd_buf, |
515 | }, | 545 | }, |
516 | { | 546 | { |
517 | .addr = sdvo_priv->slave_addr >> 1, | 547 | .addr = intel_sdvo->slave_addr >> 1, |
518 | .flags = I2C_M_RD, | 548 | .flags = I2C_M_RD, |
519 | .len = 1, | 549 | .len = 1, |
520 | .buf = ret_value, | 550 | .buf = ret_value, |
521 | }, | 551 | }, |
522 | }; | 552 | }; |
523 | 553 | ||
524 | intel_sdvo_debug_write(intel_encoder, SDVO_CMD_SET_CONTROL_BUS_SWITCH, | 554 | intel_sdvo_debug_write(intel_sdvo, SDVO_CMD_SET_CONTROL_BUS_SWITCH, |
525 | &target, 1); | 555 | &target, 1); |
526 | /* write the DDC switch command argument */ | 556 | /* write the DDC switch command argument */ |
527 | intel_sdvo_write_byte(intel_encoder, SDVO_I2C_ARG_0, target); | 557 | intel_sdvo_write_byte(intel_sdvo, SDVO_I2C_ARG_0, target); |
528 | 558 | ||
529 | out_buf[0] = SDVO_I2C_OPCODE; | 559 | out_buf[0] = SDVO_I2C_OPCODE; |
530 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; | 560 | out_buf[1] = SDVO_CMD_SET_CONTROL_BUS_SWITCH; |
@@ -533,7 +563,7 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode | |||
533 | ret_value[0] = 0; | 563 | ret_value[0] = 0; |
534 | ret_value[1] = 0; | 564 | ret_value[1] = 0; |
535 | 565 | ||
536 | ret = i2c_transfer(intel_encoder->i2c_bus, msgs, 3); | 566 | ret = i2c_transfer(intel_sdvo->base.i2c_bus, msgs, 3); |
537 | if (ret != 3) { | 567 | if (ret != 3) { |
538 | /* failure in I2C transfer */ | 568 | /* failure in I2C transfer */ |
539 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); | 569 | DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); |
@@ -547,23 +577,29 @@ static void intel_sdvo_set_control_bus_switch(struct intel_encoder *intel_encode | |||
547 | return; | 577 | return; |
548 | } | 578 | } |
549 | 579 | ||
550 | static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, bool target_0, bool target_1) | 580 | static bool intel_sdvo_set_value(struct intel_sdvo *intel_sdvo, u8 cmd, const void *data, int len) |
551 | { | 581 | { |
552 | struct intel_sdvo_set_target_input_args targets = {0}; | 582 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, data, len)) |
553 | u8 status; | 583 | return false; |
554 | |||
555 | if (target_0 && target_1) | ||
556 | return SDVO_CMD_STATUS_NOTSUPP; | ||
557 | 584 | ||
558 | if (target_1) | 585 | return intel_sdvo_read_response(intel_sdvo, NULL, 0); |
559 | targets.target_1 = 1; | 586 | } |
560 | 587 | ||
561 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_INPUT, &targets, | 588 | static bool |
562 | sizeof(targets)); | 589 | intel_sdvo_get_value(struct intel_sdvo *intel_sdvo, u8 cmd, void *value, int len) |
590 | { | ||
591 | if (!intel_sdvo_write_cmd(intel_sdvo, cmd, NULL, 0)) | ||
592 | return false; | ||
563 | 593 | ||
564 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 594 | return intel_sdvo_read_response(intel_sdvo, value, len); |
595 | } | ||
565 | 596 | ||
566 | return (status == SDVO_CMD_STATUS_SUCCESS); | 597 | static bool intel_sdvo_set_target_input(struct intel_sdvo *intel_sdvo) |
598 | { | ||
599 | struct intel_sdvo_set_target_input_args targets = {0}; | ||
600 | return intel_sdvo_set_value(intel_sdvo, | ||
601 | SDVO_CMD_SET_TARGET_INPUT, | ||
602 | &targets, sizeof(targets)); | ||
567 | } | 603 | } |
568 | 604 | ||
569 | /** | 605 | /** |
@@ -572,14 +608,12 @@ static bool intel_sdvo_set_target_input(struct intel_encoder *intel_encoder, boo | |||
572 | * This function is making an assumption about the layout of the response, | 608 | * This function is making an assumption about the layout of the response, |
573 | * which should be checked against the docs. | 609 | * which should be checked against the docs. |
574 | */ | 610 | */ |
575 | static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, bool *input_1, bool *input_2) | 611 | static bool intel_sdvo_get_trained_inputs(struct intel_sdvo *intel_sdvo, bool *input_1, bool *input_2) |
576 | { | 612 | { |
577 | struct intel_sdvo_get_trained_inputs_response response; | 613 | struct intel_sdvo_get_trained_inputs_response response; |
578 | u8 status; | ||
579 | 614 | ||
580 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); | 615 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, |
581 | status = intel_sdvo_read_response(intel_encoder, &response, sizeof(response)); | 616 | &response, sizeof(response))) |
582 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
583 | return false; | 617 | return false; |
584 | 618 | ||
585 | *input_1 = response.input0_trained; | 619 | *input_1 = response.input0_trained; |
@@ -587,21 +621,18 @@ static bool intel_sdvo_get_trained_inputs(struct intel_encoder *intel_encoder, b | |||
587 | return true; | 621 | return true; |
588 | } | 622 | } |
589 | 623 | ||
590 | static bool intel_sdvo_set_active_outputs(struct intel_encoder *intel_encoder, | 624 | static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, |
591 | u16 outputs) | 625 | u16 outputs) |
592 | { | 626 | { |
593 | u8 status; | 627 | return intel_sdvo_set_value(intel_sdvo, |
594 | 628 | SDVO_CMD_SET_ACTIVE_OUTPUTS, | |
595 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, | 629 | &outputs, sizeof(outputs)); |
596 | sizeof(outputs)); | ||
597 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
598 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
599 | } | 630 | } |
600 | 631 | ||
601 | static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encoder, | 632 | static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, |
602 | int mode) | 633 | int mode) |
603 | { | 634 | { |
604 | u8 status, state = SDVO_ENCODER_STATE_ON; | 635 | u8 state = SDVO_ENCODER_STATE_ON; |
605 | 636 | ||
606 | switch (mode) { | 637 | switch (mode) { |
607 | case DRM_MODE_DPMS_ON: | 638 | case DRM_MODE_DPMS_ON: |
@@ -618,88 +649,63 @@ static bool intel_sdvo_set_encoder_power_state(struct intel_encoder *intel_encod | |||
618 | break; | 649 | break; |
619 | } | 650 | } |
620 | 651 | ||
621 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, | 652 | return intel_sdvo_set_value(intel_sdvo, |
622 | sizeof(state)); | 653 | SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); |
623 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
624 | |||
625 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
626 | } | 654 | } |
627 | 655 | ||
628 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_encoder *intel_encoder, | 656 | static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo, |
629 | int *clock_min, | 657 | int *clock_min, |
630 | int *clock_max) | 658 | int *clock_max) |
631 | { | 659 | { |
632 | struct intel_sdvo_pixel_clock_range clocks; | 660 | struct intel_sdvo_pixel_clock_range clocks; |
633 | u8 status; | ||
634 | |||
635 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
636 | NULL, 0); | ||
637 | |||
638 | status = intel_sdvo_read_response(intel_encoder, &clocks, sizeof(clocks)); | ||
639 | 661 | ||
640 | if (status != SDVO_CMD_STATUS_SUCCESS) | 662 | if (!intel_sdvo_get_value(intel_sdvo, |
663 | SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, | ||
664 | &clocks, sizeof(clocks))) | ||
641 | return false; | 665 | return false; |
642 | 666 | ||
643 | /* Convert the values from units of 10 kHz to kHz. */ | 667 | /* Convert the values from units of 10 kHz to kHz. */ |
644 | *clock_min = clocks.min * 10; | 668 | *clock_min = clocks.min * 10; |
645 | *clock_max = clocks.max * 10; | 669 | *clock_max = clocks.max * 10; |
646 | |||
647 | return true; | 670 | return true; |
648 | } | 671 | } |
649 | 672 | ||
650 | static bool intel_sdvo_set_target_output(struct intel_encoder *intel_encoder, | 673 | static bool intel_sdvo_set_target_output(struct intel_sdvo *intel_sdvo, |
651 | u16 outputs) | 674 | u16 outputs) |
652 | { | 675 | { |
653 | u8 status; | 676 | return intel_sdvo_set_value(intel_sdvo, |
654 | 677 | SDVO_CMD_SET_TARGET_OUTPUT, | |
655 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, | 678 | &outputs, sizeof(outputs)); |
656 | sizeof(outputs)); | ||
657 | |||
658 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
659 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
660 | } | 679 | } |
661 | 680 | ||
662 | static bool intel_sdvo_set_timing(struct intel_encoder *intel_encoder, u8 cmd, | 681 | static bool intel_sdvo_set_timing(struct intel_sdvo *intel_sdvo, u8 cmd, |
663 | struct intel_sdvo_dtd *dtd) | 682 | struct intel_sdvo_dtd *dtd) |
664 | { | 683 | { |
665 | u8 status; | 684 | return intel_sdvo_set_value(intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && |
666 | 685 | intel_sdvo_set_value(intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | |
667 | intel_sdvo_write_cmd(intel_encoder, cmd, &dtd->part1, sizeof(dtd->part1)); | ||
668 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
669 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
670 | return false; | ||
671 | |||
672 | intel_sdvo_write_cmd(intel_encoder, cmd + 1, &dtd->part2, sizeof(dtd->part2)); | ||
673 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
674 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
675 | return false; | ||
676 | |||
677 | return true; | ||
678 | } | 686 | } |
679 | 687 | ||
680 | static bool intel_sdvo_set_input_timing(struct intel_encoder *intel_encoder, | 688 | static bool intel_sdvo_set_input_timing(struct intel_sdvo *intel_sdvo, |
681 | struct intel_sdvo_dtd *dtd) | 689 | struct intel_sdvo_dtd *dtd) |
682 | { | 690 | { |
683 | return intel_sdvo_set_timing(intel_encoder, | 691 | return intel_sdvo_set_timing(intel_sdvo, |
684 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); | 692 | SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); |
685 | } | 693 | } |
686 | 694 | ||
687 | static bool intel_sdvo_set_output_timing(struct intel_encoder *intel_encoder, | 695 | static bool intel_sdvo_set_output_timing(struct intel_sdvo *intel_sdvo, |
688 | struct intel_sdvo_dtd *dtd) | 696 | struct intel_sdvo_dtd *dtd) |
689 | { | 697 | { |
690 | return intel_sdvo_set_timing(intel_encoder, | 698 | return intel_sdvo_set_timing(intel_sdvo, |
691 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); | 699 | SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); |
692 | } | 700 | } |
693 | 701 | ||
694 | static bool | 702 | static bool |
695 | intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, | 703 | intel_sdvo_create_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
696 | uint16_t clock, | 704 | uint16_t clock, |
697 | uint16_t width, | 705 | uint16_t width, |
698 | uint16_t height) | 706 | uint16_t height) |
699 | { | 707 | { |
700 | struct intel_sdvo_preferred_input_timing_args args; | 708 | struct intel_sdvo_preferred_input_timing_args args; |
701 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
702 | uint8_t status; | ||
703 | 709 | ||
704 | memset(&args, 0, sizeof(args)); | 710 | memset(&args, 0, sizeof(args)); |
705 | args.clock = clock; | 711 | args.clock = clock; |
@@ -707,59 +713,32 @@ intel_sdvo_create_preferred_input_timing(struct intel_encoder *intel_encoder, | |||
707 | args.height = height; | 713 | args.height = height; |
708 | args.interlace = 0; | 714 | args.interlace = 0; |
709 | 715 | ||
710 | if (sdvo_priv->is_lvds && | 716 | if (intel_sdvo->is_lvds && |
711 | (sdvo_priv->sdvo_lvds_fixed_mode->hdisplay != width || | 717 | (intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || |
712 | sdvo_priv->sdvo_lvds_fixed_mode->vdisplay != height)) | 718 | intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) |
713 | args.scaled = 1; | 719 | args.scaled = 1; |
714 | 720 | ||
715 | intel_sdvo_write_cmd(intel_encoder, | 721 | return intel_sdvo_set_value(intel_sdvo, |
716 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, | 722 | SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, |
717 | &args, sizeof(args)); | 723 | &args, sizeof(args)); |
718 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
719 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
720 | return false; | ||
721 | |||
722 | return true; | ||
723 | } | 724 | } |
724 | 725 | ||
725 | static bool intel_sdvo_get_preferred_input_timing(struct intel_encoder *intel_encoder, | 726 | static bool intel_sdvo_get_preferred_input_timing(struct intel_sdvo *intel_sdvo, |
726 | struct intel_sdvo_dtd *dtd) | 727 | struct intel_sdvo_dtd *dtd) |
727 | { | 728 | { |
728 | bool status; | 729 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, |
729 | 730 | &dtd->part1, sizeof(dtd->part1)) && | |
730 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, | 731 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, |
731 | NULL, 0); | 732 | &dtd->part2, sizeof(dtd->part2)); |
732 | |||
733 | status = intel_sdvo_read_response(intel_encoder, &dtd->part1, | ||
734 | sizeof(dtd->part1)); | ||
735 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
736 | return false; | ||
737 | |||
738 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, | ||
739 | NULL, 0); | ||
740 | |||
741 | status = intel_sdvo_read_response(intel_encoder, &dtd->part2, | ||
742 | sizeof(dtd->part2)); | ||
743 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
744 | return false; | ||
745 | |||
746 | return false; | ||
747 | } | 733 | } |
748 | 734 | ||
749 | static bool intel_sdvo_set_clock_rate_mult(struct intel_encoder *intel_encoder, u8 val) | 735 | static bool intel_sdvo_set_clock_rate_mult(struct intel_sdvo *intel_sdvo, u8 val) |
750 | { | 736 | { |
751 | u8 status; | 737 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); |
752 | |||
753 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); | ||
754 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
755 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
756 | return false; | ||
757 | |||
758 | return true; | ||
759 | } | 738 | } |
760 | 739 | ||
761 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | 740 | static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, |
762 | struct drm_display_mode *mode) | 741 | const struct drm_display_mode *mode) |
763 | { | 742 | { |
764 | uint16_t width, height; | 743 | uint16_t width, height; |
765 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; | 744 | uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; |
@@ -808,7 +787,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd, | |||
808 | } | 787 | } |
809 | 788 | ||
810 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | 789 | static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, |
811 | struct intel_sdvo_dtd *dtd) | 790 | const struct intel_sdvo_dtd *dtd) |
812 | { | 791 | { |
813 | mode->hdisplay = dtd->part1.h_active; | 792 | mode->hdisplay = dtd->part1.h_active; |
814 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; | 793 | mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; |
@@ -840,45 +819,33 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, | |||
840 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | 819 | mode->flags |= DRM_MODE_FLAG_PVSYNC; |
841 | } | 820 | } |
842 | 821 | ||
843 | static bool intel_sdvo_get_supp_encode(struct intel_encoder *intel_encoder, | 822 | static bool intel_sdvo_get_supp_encode(struct intel_sdvo *intel_sdvo, |
844 | struct intel_sdvo_encode *encode) | 823 | struct intel_sdvo_encode *encode) |
845 | { | 824 | { |
846 | uint8_t status; | 825 | if (intel_sdvo_get_value(intel_sdvo, |
847 | 826 | SDVO_CMD_GET_SUPP_ENCODE, | |
848 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); | 827 | encode, sizeof(*encode))) |
849 | status = intel_sdvo_read_response(intel_encoder, encode, sizeof(*encode)); | 828 | return true; |
850 | if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ | ||
851 | memset(encode, 0, sizeof(*encode)); | ||
852 | return false; | ||
853 | } | ||
854 | 829 | ||
855 | return true; | 830 | /* non-support means DVI */ |
831 | memset(encode, 0, sizeof(*encode)); | ||
832 | return false; | ||
856 | } | 833 | } |
857 | 834 | ||
858 | static bool intel_sdvo_set_encode(struct intel_encoder *intel_encoder, | 835 | static bool intel_sdvo_set_encode(struct intel_sdvo *intel_sdvo, |
859 | uint8_t mode) | 836 | uint8_t mode) |
860 | { | 837 | { |
861 | uint8_t status; | 838 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); |
862 | |||
863 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ENCODE, &mode, 1); | ||
864 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
865 | |||
866 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
867 | } | 839 | } |
868 | 840 | ||
869 | static bool intel_sdvo_set_colorimetry(struct intel_encoder *intel_encoder, | 841 | static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo, |
870 | uint8_t mode) | 842 | uint8_t mode) |
871 | { | 843 | { |
872 | uint8_t status; | 844 | return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); |
873 | |||
874 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_COLORIMETRY, &mode, 1); | ||
875 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | ||
876 | |||
877 | return (status == SDVO_CMD_STATUS_SUCCESS); | ||
878 | } | 845 | } |
879 | 846 | ||
880 | #if 0 | 847 | #if 0 |
881 | static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | 848 | static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) |
882 | { | 849 | { |
883 | int i, j; | 850 | int i, j; |
884 | uint8_t set_buf_index[2]; | 851 | uint8_t set_buf_index[2]; |
@@ -887,8 +854,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | |||
887 | uint8_t buf[48]; | 854 | uint8_t buf[48]; |
888 | uint8_t *pos; | 855 | uint8_t *pos; |
889 | 856 | ||
890 | intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); | 857 | intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1); |
891 | intel_sdvo_read_response(encoder, &av_split, 1); | ||
892 | 858 | ||
893 | for (i = 0; i <= av_split; i++) { | 859 | for (i = 0; i <= av_split; i++) { |
894 | set_buf_index[0] = i; set_buf_index[1] = 0; | 860 | set_buf_index[0] = i; set_buf_index[1] = 0; |
@@ -908,7 +874,7 @@ static void intel_sdvo_dump_hdmi_buf(struct intel_encoder *intel_encoder) | |||
908 | } | 874 | } |
909 | #endif | 875 | #endif |
910 | 876 | ||
911 | static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, | 877 | static bool intel_sdvo_set_hdmi_buf(struct intel_sdvo *intel_sdvo, |
912 | int index, | 878 | int index, |
913 | uint8_t *data, int8_t size, uint8_t tx_rate) | 879 | uint8_t *data, int8_t size, uint8_t tx_rate) |
914 | { | 880 | { |
@@ -917,15 +883,18 @@ static void intel_sdvo_set_hdmi_buf(struct intel_encoder *intel_encoder, | |||
917 | set_buf_index[0] = index; | 883 | set_buf_index[0] = index; |
918 | set_buf_index[1] = 0; | 884 | set_buf_index[1] = 0; |
919 | 885 | ||
920 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_INDEX, | 886 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_INDEX, |
921 | set_buf_index, 2); | 887 | set_buf_index, 2)) |
888 | return false; | ||
922 | 889 | ||
923 | for (; size > 0; size -= 8) { | 890 | for (; size > 0; size -= 8) { |
924 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_DATA, data, 8); | 891 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_DATA, data, 8)) |
892 | return false; | ||
893 | |||
925 | data += 8; | 894 | data += 8; |
926 | } | 895 | } |
927 | 896 | ||
928 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); | 897 | return intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); |
929 | } | 898 | } |
930 | 899 | ||
931 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) | 900 | static uint8_t intel_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) |
@@ -1000,7 +969,7 @@ struct dip_infoframe { | |||
1000 | } __attribute__ ((packed)) u; | 969 | } __attribute__ ((packed)) u; |
1001 | } __attribute__((packed)); | 970 | } __attribute__((packed)); |
1002 | 971 | ||
1003 | static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, | 972 | static bool intel_sdvo_set_avi_infoframe(struct intel_sdvo *intel_sdvo, |
1004 | struct drm_display_mode * mode) | 973 | struct drm_display_mode * mode) |
1005 | { | 974 | { |
1006 | struct dip_infoframe avi_if = { | 975 | struct dip_infoframe avi_if = { |
@@ -1011,133 +980,105 @@ static void intel_sdvo_set_avi_infoframe(struct intel_encoder *intel_encoder, | |||
1011 | 980 | ||
1012 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, | 981 | avi_if.checksum = intel_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, |
1013 | 4 + avi_if.len); | 982 | 4 + avi_if.len); |
1014 | intel_sdvo_set_hdmi_buf(intel_encoder, 1, (uint8_t *)&avi_if, | 983 | return intel_sdvo_set_hdmi_buf(intel_sdvo, 1, (uint8_t *)&avi_if, |
1015 | 4 + avi_if.len, | 984 | 4 + avi_if.len, |
1016 | SDVO_HBUF_TX_VSYNC); | 985 | SDVO_HBUF_TX_VSYNC); |
1017 | } | 986 | } |
1018 | 987 | ||
1019 | static void intel_sdvo_set_tv_format(struct intel_encoder *intel_encoder) | 988 | static bool intel_sdvo_set_tv_format(struct intel_sdvo *intel_sdvo) |
1020 | { | 989 | { |
1021 | |||
1022 | struct intel_sdvo_tv_format format; | 990 | struct intel_sdvo_tv_format format; |
1023 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 991 | uint32_t format_map; |
1024 | uint32_t format_map, i; | ||
1025 | uint8_t status; | ||
1026 | 992 | ||
1027 | for (i = 0; i < TV_FORMAT_NUM; i++) | 993 | format_map = 1 << intel_sdvo->tv_format_index; |
1028 | if (tv_format_names[i] == sdvo_priv->tv_format_name) | ||
1029 | break; | ||
1030 | |||
1031 | format_map = 1 << i; | ||
1032 | memset(&format, 0, sizeof(format)); | 994 | memset(&format, 0, sizeof(format)); |
1033 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? | 995 | memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); |
1034 | sizeof(format) : sizeof(format_map)); | ||
1035 | |||
1036 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_TV_FORMAT, &format, | ||
1037 | sizeof(format)); | ||
1038 | 996 | ||
1039 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 997 | BUILD_BUG_ON(sizeof(format) != 6); |
1040 | if (status != SDVO_CMD_STATUS_SUCCESS) | 998 | return intel_sdvo_set_value(intel_sdvo, |
1041 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", | 999 | SDVO_CMD_SET_TV_FORMAT, |
1042 | SDVO_NAME(sdvo_priv)); | 1000 | &format, sizeof(format)); |
1043 | } | 1001 | } |
1044 | 1002 | ||
1045 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 1003 | static bool |
1046 | struct drm_display_mode *mode, | 1004 | intel_sdvo_set_output_timings_from_mode(struct intel_sdvo *intel_sdvo, |
1047 | struct drm_display_mode *adjusted_mode) | 1005 | struct drm_display_mode *mode) |
1048 | { | 1006 | { |
1049 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1007 | struct intel_sdvo_dtd output_dtd; |
1050 | struct intel_sdvo_priv *dev_priv = intel_encoder->dev_priv; | ||
1051 | 1008 | ||
1052 | if (dev_priv->is_tv) { | 1009 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1053 | struct intel_sdvo_dtd output_dtd; | 1010 | intel_sdvo->attached_output)) |
1054 | bool success; | 1011 | return false; |
1055 | 1012 | ||
1056 | /* We need to construct preferred input timings based on our | 1013 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); |
1057 | * output timings. To do that, we have to set the output | 1014 | if (!intel_sdvo_set_output_timing(intel_sdvo, &output_dtd)) |
1058 | * timings, even though this isn't really the right place in | 1015 | return false; |
1059 | * the sequence to do it. Oh well. | ||
1060 | */ | ||
1061 | 1016 | ||
1017 | return true; | ||
1018 | } | ||
1062 | 1019 | ||
1063 | /* Set output timings */ | 1020 | static bool |
1064 | intel_sdvo_get_dtd_from_mode(&output_dtd, mode); | 1021 | intel_sdvo_set_input_timings_for_mode(struct intel_sdvo *intel_sdvo, |
1065 | intel_sdvo_set_target_output(intel_encoder, | 1022 | struct drm_display_mode *mode, |
1066 | dev_priv->attached_output); | 1023 | struct drm_display_mode *adjusted_mode) |
1067 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | 1024 | { |
1025 | struct intel_sdvo_dtd input_dtd; | ||
1068 | 1026 | ||
1069 | /* Set the input timing to the screen. Assume always input 0. */ | 1027 | /* Reset the input timing to the screen. Assume always input 0. */ |
1070 | intel_sdvo_set_target_input(intel_encoder, true, false); | 1028 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1029 | return false; | ||
1071 | 1030 | ||
1031 | if (!intel_sdvo_create_preferred_input_timing(intel_sdvo, | ||
1032 | mode->clock / 10, | ||
1033 | mode->hdisplay, | ||
1034 | mode->vdisplay)) | ||
1035 | return false; | ||
1072 | 1036 | ||
1073 | success = intel_sdvo_create_preferred_input_timing(intel_encoder, | 1037 | if (!intel_sdvo_get_preferred_input_timing(intel_sdvo, |
1074 | mode->clock / 10, | 1038 | &input_dtd)) |
1075 | mode->hdisplay, | 1039 | return false; |
1076 | mode->vdisplay); | ||
1077 | if (success) { | ||
1078 | struct intel_sdvo_dtd input_dtd; | ||
1079 | 1040 | ||
1080 | intel_sdvo_get_preferred_input_timing(intel_encoder, | 1041 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); |
1081 | &input_dtd); | 1042 | intel_sdvo->sdvo_flags = input_dtd.part2.sdvo_flags; |
1082 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1083 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1084 | 1043 | ||
1085 | drm_mode_set_crtcinfo(adjusted_mode, 0); | 1044 | drm_mode_set_crtcinfo(adjusted_mode, 0); |
1045 | mode->clock = adjusted_mode->clock; | ||
1046 | return true; | ||
1047 | } | ||
1086 | 1048 | ||
1087 | mode->clock = adjusted_mode->clock; | 1049 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
1050 | struct drm_display_mode *mode, | ||
1051 | struct drm_display_mode *adjusted_mode) | ||
1052 | { | ||
1053 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); | ||
1088 | 1054 | ||
1089 | adjusted_mode->clock *= | 1055 | /* We need to construct preferred input timings based on our |
1090 | intel_sdvo_get_pixel_multiplier(mode); | 1056 | * output timings. To do that, we have to set the output |
1091 | } else { | 1057 | * timings, even though this isn't really the right place in |
1058 | * the sequence to do it. Oh well. | ||
1059 | */ | ||
1060 | if (intel_sdvo->is_tv) { | ||
1061 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, mode)) | ||
1092 | return false; | 1062 | return false; |
1093 | } | ||
1094 | } else if (dev_priv->is_lvds) { | ||
1095 | struct intel_sdvo_dtd output_dtd; | ||
1096 | bool success; | ||
1097 | |||
1098 | drm_mode_set_crtcinfo(dev_priv->sdvo_lvds_fixed_mode, 0); | ||
1099 | /* Set output timings */ | ||
1100 | intel_sdvo_get_dtd_from_mode(&output_dtd, | ||
1101 | dev_priv->sdvo_lvds_fixed_mode); | ||
1102 | |||
1103 | intel_sdvo_set_target_output(intel_encoder, | ||
1104 | dev_priv->attached_output); | ||
1105 | intel_sdvo_set_output_timing(intel_encoder, &output_dtd); | ||
1106 | |||
1107 | /* Set the input timing to the screen. Assume always input 0. */ | ||
1108 | intel_sdvo_set_target_input(intel_encoder, true, false); | ||
1109 | |||
1110 | |||
1111 | success = intel_sdvo_create_preferred_input_timing( | ||
1112 | intel_encoder, | ||
1113 | mode->clock / 10, | ||
1114 | mode->hdisplay, | ||
1115 | mode->vdisplay); | ||
1116 | 1063 | ||
1117 | if (success) { | 1064 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) |
1118 | struct intel_sdvo_dtd input_dtd; | 1065 | return false; |
1119 | 1066 | } else if (intel_sdvo->is_lvds) { | |
1120 | intel_sdvo_get_preferred_input_timing(intel_encoder, | 1067 | drm_mode_set_crtcinfo(intel_sdvo->sdvo_lvds_fixed_mode, 0); |
1121 | &input_dtd); | ||
1122 | intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); | ||
1123 | dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; | ||
1124 | |||
1125 | drm_mode_set_crtcinfo(adjusted_mode, 0); | ||
1126 | |||
1127 | mode->clock = adjusted_mode->clock; | ||
1128 | 1068 | ||
1129 | adjusted_mode->clock *= | 1069 | if (!intel_sdvo_set_output_timings_from_mode(intel_sdvo, |
1130 | intel_sdvo_get_pixel_multiplier(mode); | 1070 | intel_sdvo->sdvo_lvds_fixed_mode)) |
1131 | } else { | ||
1132 | return false; | 1071 | return false; |
1133 | } | ||
1134 | 1072 | ||
1135 | } else { | 1073 | if (!intel_sdvo_set_input_timings_for_mode(intel_sdvo, mode, adjusted_mode)) |
1136 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | 1074 | return false; |
1137 | * SDVO device will be told of the multiplier during mode_set. | ||
1138 | */ | ||
1139 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
1140 | } | 1075 | } |
1076 | |||
1077 | /* Make the CRTC code factor in the SDVO pixel multiplier. The | ||
1078 | * SDVO device will be told of the multiplier during mode_set. | ||
1079 | */ | ||
1080 | adjusted_mode->clock *= intel_sdvo_get_pixel_multiplier(mode); | ||
1081 | |||
1141 | return true; | 1082 | return true; |
1142 | } | 1083 | } |
1143 | 1084 | ||
@@ -1149,13 +1090,11 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1149 | struct drm_i915_private *dev_priv = dev->dev_private; | 1090 | struct drm_i915_private *dev_priv = dev->dev_private; |
1150 | struct drm_crtc *crtc = encoder->crtc; | 1091 | struct drm_crtc *crtc = encoder->crtc; |
1151 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1092 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
1152 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1093 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1153 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1154 | u32 sdvox = 0; | 1094 | u32 sdvox = 0; |
1155 | int sdvo_pixel_multiply; | 1095 | int sdvo_pixel_multiply, rate; |
1156 | struct intel_sdvo_in_out_map in_out; | 1096 | struct intel_sdvo_in_out_map in_out; |
1157 | struct intel_sdvo_dtd input_dtd; | 1097 | struct intel_sdvo_dtd input_dtd; |
1158 | u8 status; | ||
1159 | 1098 | ||
1160 | if (!mode) | 1099 | if (!mode) |
1161 | return; | 1100 | return; |
@@ -1166,41 +1105,50 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1166 | * channel on the motherboard. In a two-input device, the first input | 1105 | * channel on the motherboard. In a two-input device, the first input |
1167 | * will be SDVOB and the second SDVOC. | 1106 | * will be SDVOB and the second SDVOC. |
1168 | */ | 1107 | */ |
1169 | in_out.in0 = sdvo_priv->attached_output; | 1108 | in_out.in0 = intel_sdvo->attached_output; |
1170 | in_out.in1 = 0; | 1109 | in_out.in1 = 0; |
1171 | 1110 | ||
1172 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_IN_OUT_MAP, | 1111 | if (!intel_sdvo_set_value(intel_sdvo, |
1173 | &in_out, sizeof(in_out)); | 1112 | SDVO_CMD_SET_IN_OUT_MAP, |
1174 | status = intel_sdvo_read_response(intel_encoder, NULL, 0); | 1113 | &in_out, sizeof(in_out))) |
1114 | return; | ||
1115 | |||
1116 | if (intel_sdvo->is_hdmi) { | ||
1117 | if (!intel_sdvo_set_avi_infoframe(intel_sdvo, mode)) | ||
1118 | return; | ||
1175 | 1119 | ||
1176 | if (sdvo_priv->is_hdmi) { | ||
1177 | intel_sdvo_set_avi_infoframe(intel_encoder, mode); | ||
1178 | sdvox |= SDVO_AUDIO_ENABLE; | 1120 | sdvox |= SDVO_AUDIO_ENABLE; |
1179 | } | 1121 | } |
1180 | 1122 | ||
1181 | /* We have tried to get input timing in mode_fixup, and filled into | 1123 | /* We have tried to get input timing in mode_fixup, and filled into |
1182 | adjusted_mode */ | 1124 | adjusted_mode */ |
1183 | if (sdvo_priv->is_tv || sdvo_priv->is_lvds) { | 1125 | if (intel_sdvo->is_tv || intel_sdvo->is_lvds) { |
1184 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); | 1126 | intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); |
1185 | input_dtd.part2.sdvo_flags = sdvo_priv->sdvo_flags; | 1127 | input_dtd.part2.sdvo_flags = intel_sdvo->sdvo_flags; |
1186 | } else | 1128 | } else |
1187 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); | 1129 | intel_sdvo_get_dtd_from_mode(&input_dtd, mode); |
1188 | 1130 | ||
1189 | /* If it's a TV, we already set the output timing in mode_fixup. | 1131 | /* If it's a TV, we already set the output timing in mode_fixup. |
1190 | * Otherwise, the output timing is equal to the input timing. | 1132 | * Otherwise, the output timing is equal to the input timing. |
1191 | */ | 1133 | */ |
1192 | if (!sdvo_priv->is_tv && !sdvo_priv->is_lvds) { | 1134 | if (!intel_sdvo->is_tv && !intel_sdvo->is_lvds) { |
1193 | /* Set the output timing to the screen */ | 1135 | /* Set the output timing to the screen */ |
1194 | intel_sdvo_set_target_output(intel_encoder, | 1136 | if (!intel_sdvo_set_target_output(intel_sdvo, |
1195 | sdvo_priv->attached_output); | 1137 | intel_sdvo->attached_output)) |
1196 | intel_sdvo_set_output_timing(intel_encoder, &input_dtd); | 1138 | return; |
1139 | |||
1140 | if (!intel_sdvo_set_output_timing(intel_sdvo, &input_dtd)) | ||
1141 | return; | ||
1197 | } | 1142 | } |
1198 | 1143 | ||
1199 | /* Set the input timing to the screen. Assume always input 0. */ | 1144 | /* Set the input timing to the screen. Assume always input 0. */ |
1200 | intel_sdvo_set_target_input(intel_encoder, true, false); | 1145 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
1146 | return; | ||
1201 | 1147 | ||
1202 | if (sdvo_priv->is_tv) | 1148 | if (intel_sdvo->is_tv) { |
1203 | intel_sdvo_set_tv_format(intel_encoder); | 1149 | if (!intel_sdvo_set_tv_format(intel_sdvo)) |
1150 | return; | ||
1151 | } | ||
1204 | 1152 | ||
1205 | /* We would like to use intel_sdvo_create_preferred_input_timing() to | 1153 | /* We would like to use intel_sdvo_create_preferred_input_timing() to |
1206 | * provide the device with a timing it can support, if it supports that | 1154 | * provide the device with a timing it can support, if it supports that |
@@ -1217,23 +1165,18 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1217 | intel_sdvo_set_input_timing(encoder, &input_dtd); | 1165 | intel_sdvo_set_input_timing(encoder, &input_dtd); |
1218 | } | 1166 | } |
1219 | #else | 1167 | #else |
1220 | intel_sdvo_set_input_timing(intel_encoder, &input_dtd); | 1168 | if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) |
1169 | return; | ||
1221 | #endif | 1170 | #endif |
1222 | 1171 | ||
1223 | switch (intel_sdvo_get_pixel_multiplier(mode)) { | 1172 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); |
1224 | case 1: | 1173 | switch (sdvo_pixel_multiply) { |
1225 | intel_sdvo_set_clock_rate_mult(intel_encoder, | 1174 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
1226 | SDVO_CLOCK_RATE_MULT_1X); | 1175 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
1227 | break; | 1176 | case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; |
1228 | case 2: | ||
1229 | intel_sdvo_set_clock_rate_mult(intel_encoder, | ||
1230 | SDVO_CLOCK_RATE_MULT_2X); | ||
1231 | break; | ||
1232 | case 4: | ||
1233 | intel_sdvo_set_clock_rate_mult(intel_encoder, | ||
1234 | SDVO_CLOCK_RATE_MULT_4X); | ||
1235 | break; | ||
1236 | } | 1177 | } |
1178 | if (!intel_sdvo_set_clock_rate_mult(intel_sdvo, rate)) | ||
1179 | return; | ||
1237 | 1180 | ||
1238 | /* Set the SDVO control regs. */ | 1181 | /* Set the SDVO control regs. */ |
1239 | if (IS_I965G(dev)) { | 1182 | if (IS_I965G(dev)) { |
@@ -1243,8 +1186,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1243 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) | 1186 | if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) |
1244 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; | 1187 | sdvox |= SDVO_HSYNC_ACTIVE_HIGH; |
1245 | } else { | 1188 | } else { |
1246 | sdvox |= I915_READ(sdvo_priv->sdvo_reg); | 1189 | sdvox |= I915_READ(intel_sdvo->sdvo_reg); |
1247 | switch (sdvo_priv->sdvo_reg) { | 1190 | switch (intel_sdvo->sdvo_reg) { |
1248 | case SDVOB: | 1191 | case SDVOB: |
1249 | sdvox &= SDVOB_PRESERVE_MASK; | 1192 | sdvox &= SDVOB_PRESERVE_MASK; |
1250 | break; | 1193 | break; |
@@ -1257,7 +1200,6 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1257 | if (intel_crtc->pipe == 1) | 1200 | if (intel_crtc->pipe == 1) |
1258 | sdvox |= SDVO_PIPE_B_SELECT; | 1201 | sdvox |= SDVO_PIPE_B_SELECT; |
1259 | 1202 | ||
1260 | sdvo_pixel_multiply = intel_sdvo_get_pixel_multiplier(mode); | ||
1261 | if (IS_I965G(dev)) { | 1203 | if (IS_I965G(dev)) { |
1262 | /* done in crtc_mode_set as the dpll_md reg must be written early */ | 1204 | /* done in crtc_mode_set as the dpll_md reg must be written early */ |
1263 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { | 1205 | } else if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) { |
@@ -1266,28 +1208,28 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, | |||
1266 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; | 1208 | sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; |
1267 | } | 1209 | } |
1268 | 1210 | ||
1269 | if (sdvo_priv->sdvo_flags & SDVO_NEED_TO_STALL) | 1211 | if (intel_sdvo->sdvo_flags & SDVO_NEED_TO_STALL) |
1270 | sdvox |= SDVO_STALL_SELECT; | 1212 | sdvox |= SDVO_STALL_SELECT; |
1271 | intel_sdvo_write_sdvox(intel_encoder, sdvox); | 1213 | intel_sdvo_write_sdvox(intel_sdvo, sdvox); |
1272 | } | 1214 | } |
1273 | 1215 | ||
1274 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | 1216 | static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) |
1275 | { | 1217 | { |
1276 | struct drm_device *dev = encoder->dev; | 1218 | struct drm_device *dev = encoder->dev; |
1277 | struct drm_i915_private *dev_priv = dev->dev_private; | 1219 | struct drm_i915_private *dev_priv = dev->dev_private; |
1278 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1220 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1279 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1221 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); |
1280 | u32 temp; | 1222 | u32 temp; |
1281 | 1223 | ||
1282 | if (mode != DRM_MODE_DPMS_ON) { | 1224 | if (mode != DRM_MODE_DPMS_ON) { |
1283 | intel_sdvo_set_active_outputs(intel_encoder, 0); | 1225 | intel_sdvo_set_active_outputs(intel_sdvo, 0); |
1284 | if (0) | 1226 | if (0) |
1285 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1227 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
1286 | 1228 | ||
1287 | if (mode == DRM_MODE_DPMS_OFF) { | 1229 | if (mode == DRM_MODE_DPMS_OFF) { |
1288 | temp = I915_READ(sdvo_priv->sdvo_reg); | 1230 | temp = I915_READ(intel_sdvo->sdvo_reg); |
1289 | if ((temp & SDVO_ENABLE) != 0) { | 1231 | if ((temp & SDVO_ENABLE) != 0) { |
1290 | intel_sdvo_write_sdvox(intel_encoder, temp & ~SDVO_ENABLE); | 1232 | intel_sdvo_write_sdvox(intel_sdvo, temp & ~SDVO_ENABLE); |
1291 | } | 1233 | } |
1292 | } | 1234 | } |
1293 | } else { | 1235 | } else { |
@@ -1295,28 +1237,25 @@ static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1295 | int i; | 1237 | int i; |
1296 | u8 status; | 1238 | u8 status; |
1297 | 1239 | ||
1298 | temp = I915_READ(sdvo_priv->sdvo_reg); | 1240 | temp = I915_READ(intel_sdvo->sdvo_reg); |
1299 | if ((temp & SDVO_ENABLE) == 0) | 1241 | if ((temp & SDVO_ENABLE) == 0) |
1300 | intel_sdvo_write_sdvox(intel_encoder, temp | SDVO_ENABLE); | 1242 | intel_sdvo_write_sdvox(intel_sdvo, temp | SDVO_ENABLE); |
1301 | for (i = 0; i < 2; i++) | 1243 | for (i = 0; i < 2; i++) |
1302 | intel_wait_for_vblank(dev); | 1244 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1303 | |||
1304 | status = intel_sdvo_get_trained_inputs(intel_encoder, &input1, | ||
1305 | &input2); | ||
1306 | |||
1307 | 1245 | ||
1246 | status = intel_sdvo_get_trained_inputs(intel_sdvo, &input1, &input2); | ||
1308 | /* Warn if the device reported failure to sync. | 1247 | /* Warn if the device reported failure to sync. |
1309 | * A lot of SDVO devices fail to notify of sync, but it's | 1248 | * A lot of SDVO devices fail to notify of sync, but it's |
1310 | * a given it the status is a success, we succeeded. | 1249 | * a given it the status is a success, we succeeded. |
1311 | */ | 1250 | */ |
1312 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { | 1251 | if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { |
1313 | DRM_DEBUG_KMS("First %s output reported failure to " | 1252 | DRM_DEBUG_KMS("First %s output reported failure to " |
1314 | "sync\n", SDVO_NAME(sdvo_priv)); | 1253 | "sync\n", SDVO_NAME(intel_sdvo)); |
1315 | } | 1254 | } |
1316 | 1255 | ||
1317 | if (0) | 1256 | if (0) |
1318 | intel_sdvo_set_encoder_power_state(intel_encoder, mode); | 1257 | intel_sdvo_set_encoder_power_state(intel_sdvo, mode); |
1319 | intel_sdvo_set_active_outputs(intel_encoder, sdvo_priv->attached_output); | 1258 | intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); |
1320 | } | 1259 | } |
1321 | return; | 1260 | return; |
1322 | } | 1261 | } |
@@ -1325,42 +1264,31 @@ static int intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1325 | struct drm_display_mode *mode) | 1264 | struct drm_display_mode *mode) |
1326 | { | 1265 | { |
1327 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1266 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1328 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1267 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1329 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1330 | 1268 | ||
1331 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1269 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
1332 | return MODE_NO_DBLESCAN; | 1270 | return MODE_NO_DBLESCAN; |
1333 | 1271 | ||
1334 | if (sdvo_priv->pixel_clock_min > mode->clock) | 1272 | if (intel_sdvo->pixel_clock_min > mode->clock) |
1335 | return MODE_CLOCK_LOW; | 1273 | return MODE_CLOCK_LOW; |
1336 | 1274 | ||
1337 | if (sdvo_priv->pixel_clock_max < mode->clock) | 1275 | if (intel_sdvo->pixel_clock_max < mode->clock) |
1338 | return MODE_CLOCK_HIGH; | 1276 | return MODE_CLOCK_HIGH; |
1339 | 1277 | ||
1340 | if (sdvo_priv->is_lvds == true) { | 1278 | if (intel_sdvo->is_lvds) { |
1341 | if (sdvo_priv->sdvo_lvds_fixed_mode == NULL) | 1279 | if (mode->hdisplay > intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) |
1342 | return MODE_PANEL; | 1280 | return MODE_PANEL; |
1343 | 1281 | ||
1344 | if (mode->hdisplay > sdvo_priv->sdvo_lvds_fixed_mode->hdisplay) | 1282 | if (mode->vdisplay > intel_sdvo->sdvo_lvds_fixed_mode->vdisplay) |
1345 | return MODE_PANEL; | ||
1346 | |||
1347 | if (mode->vdisplay > sdvo_priv->sdvo_lvds_fixed_mode->vdisplay) | ||
1348 | return MODE_PANEL; | 1283 | return MODE_PANEL; |
1349 | } | 1284 | } |
1350 | 1285 | ||
1351 | return MODE_OK; | 1286 | return MODE_OK; |
1352 | } | 1287 | } |
1353 | 1288 | ||
1354 | static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, struct intel_sdvo_caps *caps) | 1289 | static bool intel_sdvo_get_capabilities(struct intel_sdvo *intel_sdvo, struct intel_sdvo_caps *caps) |
1355 | { | 1290 | { |
1356 | u8 status; | 1291 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DEVICE_CAPS, caps, sizeof(*caps)); |
1357 | |||
1358 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); | ||
1359 | status = intel_sdvo_read_response(intel_encoder, caps, sizeof(*caps)); | ||
1360 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1361 | return false; | ||
1362 | |||
1363 | return true; | ||
1364 | } | 1292 | } |
1365 | 1293 | ||
1366 | /* No use! */ | 1294 | /* No use! */ |
@@ -1368,12 +1296,12 @@ static bool intel_sdvo_get_capabilities(struct intel_encoder *intel_encoder, str | |||
1368 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) | 1296 | struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB) |
1369 | { | 1297 | { |
1370 | struct drm_connector *connector = NULL; | 1298 | struct drm_connector *connector = NULL; |
1371 | struct intel_encoder *iout = NULL; | 1299 | struct intel_sdvo *iout = NULL; |
1372 | struct intel_sdvo_priv *sdvo; | 1300 | struct intel_sdvo *sdvo; |
1373 | 1301 | ||
1374 | /* find the sdvo connector */ | 1302 | /* find the sdvo connector */ |
1375 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1303 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1376 | iout = to_intel_encoder(connector); | 1304 | iout = to_intel_sdvo(connector); |
1377 | 1305 | ||
1378 | if (iout->type != INTEL_OUTPUT_SDVO) | 1306 | if (iout->type != INTEL_OUTPUT_SDVO) |
1379 | continue; | 1307 | continue; |
@@ -1395,75 +1323,69 @@ int intel_sdvo_supports_hotplug(struct drm_connector *connector) | |||
1395 | { | 1323 | { |
1396 | u8 response[2]; | 1324 | u8 response[2]; |
1397 | u8 status; | 1325 | u8 status; |
1398 | struct intel_encoder *intel_encoder; | 1326 | struct intel_sdvo *intel_sdvo; |
1399 | DRM_DEBUG_KMS("\n"); | 1327 | DRM_DEBUG_KMS("\n"); |
1400 | 1328 | ||
1401 | if (!connector) | 1329 | if (!connector) |
1402 | return 0; | 1330 | return 0; |
1403 | 1331 | ||
1404 | intel_encoder = to_intel_encoder(connector); | 1332 | intel_sdvo = to_intel_sdvo(connector); |
1405 | |||
1406 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | ||
1407 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | ||
1408 | |||
1409 | if (response[0] !=0) | ||
1410 | return 1; | ||
1411 | 1333 | ||
1412 | return 0; | 1334 | return intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
1335 | &response, 2) && response[0]; | ||
1413 | } | 1336 | } |
1414 | 1337 | ||
1415 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) | 1338 | void intel_sdvo_set_hotplug(struct drm_connector *connector, int on) |
1416 | { | 1339 | { |
1417 | u8 response[2]; | 1340 | u8 response[2]; |
1418 | u8 status; | 1341 | u8 status; |
1419 | struct intel_encoder *intel_encoder = to_intel_encoder(connector); | 1342 | struct intel_sdvo *intel_sdvo = to_intel_sdvo(connector); |
1420 | 1343 | ||
1421 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1344 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
1422 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1345 | intel_sdvo_read_response(intel_sdvo, &response, 2); |
1423 | 1346 | ||
1424 | if (on) { | 1347 | if (on) { |
1425 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); | 1348 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); |
1426 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | 1349 | status = intel_sdvo_read_response(intel_sdvo, &response, 2); |
1427 | 1350 | ||
1428 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1351 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
1429 | } else { | 1352 | } else { |
1430 | response[0] = 0; | 1353 | response[0] = 0; |
1431 | response[1] = 0; | 1354 | response[1] = 0; |
1432 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); | 1355 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
1433 | } | 1356 | } |
1434 | 1357 | ||
1435 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); | 1358 | intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
1436 | intel_sdvo_read_response(intel_encoder, &response, 2); | 1359 | intel_sdvo_read_response(intel_sdvo, &response, 2); |
1437 | } | 1360 | } |
1438 | #endif | 1361 | #endif |
1439 | 1362 | ||
1440 | static bool | 1363 | static bool |
1441 | intel_sdvo_multifunc_encoder(struct intel_encoder *intel_encoder) | 1364 | intel_sdvo_multifunc_encoder(struct intel_sdvo *intel_sdvo) |
1442 | { | 1365 | { |
1443 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1444 | int caps = 0; | 1366 | int caps = 0; |
1445 | 1367 | ||
1446 | if (sdvo_priv->caps.output_flags & | 1368 | if (intel_sdvo->caps.output_flags & |
1447 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) | 1369 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) |
1448 | caps++; | 1370 | caps++; |
1449 | if (sdvo_priv->caps.output_flags & | 1371 | if (intel_sdvo->caps.output_flags & |
1450 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | 1372 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) |
1451 | caps++; | 1373 | caps++; |
1452 | if (sdvo_priv->caps.output_flags & | 1374 | if (intel_sdvo->caps.output_flags & |
1453 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) | 1375 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) |
1454 | caps++; | 1376 | caps++; |
1455 | if (sdvo_priv->caps.output_flags & | 1377 | if (intel_sdvo->caps.output_flags & |
1456 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | 1378 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) |
1457 | caps++; | 1379 | caps++; |
1458 | if (sdvo_priv->caps.output_flags & | 1380 | if (intel_sdvo->caps.output_flags & |
1459 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) | 1381 | (SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_YPRPB1)) |
1460 | caps++; | 1382 | caps++; |
1461 | 1383 | ||
1462 | if (sdvo_priv->caps.output_flags & | 1384 | if (intel_sdvo->caps.output_flags & |
1463 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) | 1385 | (SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1)) |
1464 | caps++; | 1386 | caps++; |
1465 | 1387 | ||
1466 | if (sdvo_priv->caps.output_flags & | 1388 | if (intel_sdvo->caps.output_flags & |
1467 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) | 1389 | (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) |
1468 | caps++; | 1390 | caps++; |
1469 | 1391 | ||
@@ -1475,11 +1397,11 @@ intel_find_analog_connector(struct drm_device *dev) | |||
1475 | { | 1397 | { |
1476 | struct drm_connector *connector; | 1398 | struct drm_connector *connector; |
1477 | struct drm_encoder *encoder; | 1399 | struct drm_encoder *encoder; |
1478 | struct intel_encoder *intel_encoder; | 1400 | struct intel_sdvo *intel_sdvo; |
1479 | 1401 | ||
1480 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1402 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1481 | intel_encoder = enc_to_intel_encoder(encoder); | 1403 | intel_sdvo = enc_to_intel_sdvo(encoder); |
1482 | if (intel_encoder->type == INTEL_OUTPUT_ANALOG) { | 1404 | if (intel_sdvo->base.type == INTEL_OUTPUT_ANALOG) { |
1483 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 1405 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
1484 | if (encoder == intel_attached_encoder(connector)) | 1406 | if (encoder == intel_attached_encoder(connector)) |
1485 | return connector; | 1407 | return connector; |
@@ -1493,8 +1415,8 @@ static int | |||
1493 | intel_analog_is_connected(struct drm_device *dev) | 1415 | intel_analog_is_connected(struct drm_device *dev) |
1494 | { | 1416 | { |
1495 | struct drm_connector *analog_connector; | 1417 | struct drm_connector *analog_connector; |
1496 | analog_connector = intel_find_analog_connector(dev); | ||
1497 | 1418 | ||
1419 | analog_connector = intel_find_analog_connector(dev); | ||
1498 | if (!analog_connector) | 1420 | if (!analog_connector) |
1499 | return false; | 1421 | return false; |
1500 | 1422 | ||
@@ -1509,54 +1431,52 @@ enum drm_connector_status | |||
1509 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | 1431 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) |
1510 | { | 1432 | { |
1511 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1433 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1512 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1434 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1513 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1435 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1514 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1515 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1516 | enum drm_connector_status status = connector_status_connected; | 1436 | enum drm_connector_status status = connector_status_connected; |
1517 | struct edid *edid = NULL; | 1437 | struct edid *edid = NULL; |
1518 | 1438 | ||
1519 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); | 1439 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); |
1520 | 1440 | ||
1521 | /* This is only applied to SDVO cards with multiple outputs */ | 1441 | /* This is only applied to SDVO cards with multiple outputs */ |
1522 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_encoder)) { | 1442 | if (edid == NULL && intel_sdvo_multifunc_encoder(intel_sdvo)) { |
1523 | uint8_t saved_ddc, temp_ddc; | 1443 | uint8_t saved_ddc, temp_ddc; |
1524 | saved_ddc = sdvo_priv->ddc_bus; | 1444 | saved_ddc = intel_sdvo->ddc_bus; |
1525 | temp_ddc = sdvo_priv->ddc_bus >> 1; | 1445 | temp_ddc = intel_sdvo->ddc_bus >> 1; |
1526 | /* | 1446 | /* |
1527 | * Don't use the 1 as the argument of DDC bus switch to get | 1447 | * Don't use the 1 as the argument of DDC bus switch to get |
1528 | * the EDID. It is used for SDVO SPD ROM. | 1448 | * the EDID. It is used for SDVO SPD ROM. |
1529 | */ | 1449 | */ |
1530 | while(temp_ddc > 1) { | 1450 | while(temp_ddc > 1) { |
1531 | sdvo_priv->ddc_bus = temp_ddc; | 1451 | intel_sdvo->ddc_bus = temp_ddc; |
1532 | edid = drm_get_edid(connector, intel_encoder->ddc_bus); | 1452 | edid = drm_get_edid(connector, intel_sdvo->base.ddc_bus); |
1533 | if (edid) { | 1453 | if (edid) { |
1534 | /* | 1454 | /* |
1535 | * When we can get the EDID, maybe it is the | 1455 | * When we can get the EDID, maybe it is the |
1536 | * correct DDC bus. Update it. | 1456 | * correct DDC bus. Update it. |
1537 | */ | 1457 | */ |
1538 | sdvo_priv->ddc_bus = temp_ddc; | 1458 | intel_sdvo->ddc_bus = temp_ddc; |
1539 | break; | 1459 | break; |
1540 | } | 1460 | } |
1541 | temp_ddc >>= 1; | 1461 | temp_ddc >>= 1; |
1542 | } | 1462 | } |
1543 | if (edid == NULL) | 1463 | if (edid == NULL) |
1544 | sdvo_priv->ddc_bus = saved_ddc; | 1464 | intel_sdvo->ddc_bus = saved_ddc; |
1545 | } | 1465 | } |
1546 | /* when there is no edid and no monitor is connected with VGA | 1466 | /* when there is no edid and no monitor is connected with VGA |
1547 | * port, try to use the CRT ddc to read the EDID for DVI-connector | 1467 | * port, try to use the CRT ddc to read the EDID for DVI-connector |
1548 | */ | 1468 | */ |
1549 | if (edid == NULL && sdvo_priv->analog_ddc_bus && | 1469 | if (edid == NULL && intel_sdvo->analog_ddc_bus && |
1550 | !intel_analog_is_connected(connector->dev)) | 1470 | !intel_analog_is_connected(connector->dev)) |
1551 | edid = drm_get_edid(connector, sdvo_priv->analog_ddc_bus); | 1471 | edid = drm_get_edid(connector, intel_sdvo->analog_ddc_bus); |
1552 | 1472 | ||
1553 | if (edid != NULL) { | 1473 | if (edid != NULL) { |
1554 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); | 1474 | bool is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); |
1555 | bool need_digital = !!(sdvo_connector->output_flag & SDVO_TMDS_MASK); | 1475 | bool need_digital = !!(intel_sdvo_connector->output_flag & SDVO_TMDS_MASK); |
1556 | 1476 | ||
1557 | /* DDC bus is shared, match EDID to connector type */ | 1477 | /* DDC bus is shared, match EDID to connector type */ |
1558 | if (is_digital && need_digital) | 1478 | if (is_digital && need_digital) |
1559 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1479 | intel_sdvo->is_hdmi = drm_detect_hdmi_monitor(edid); |
1560 | else if (is_digital != need_digital) | 1480 | else if (is_digital != need_digital) |
1561 | status = connector_status_disconnected; | 1481 | status = connector_status_disconnected; |
1562 | 1482 | ||
@@ -1572,33 +1492,29 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1572 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) | 1492 | static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector) |
1573 | { | 1493 | { |
1574 | uint16_t response; | 1494 | uint16_t response; |
1575 | u8 status; | ||
1576 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1495 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1577 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1496 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1578 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1497 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1579 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1580 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1581 | enum drm_connector_status ret; | 1498 | enum drm_connector_status ret; |
1582 | 1499 | ||
1583 | intel_sdvo_write_cmd(intel_encoder, | 1500 | if (!intel_sdvo_write_cmd(intel_sdvo, |
1584 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1501 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) |
1585 | if (sdvo_priv->is_tv) { | 1502 | return connector_status_unknown; |
1503 | if (intel_sdvo->is_tv) { | ||
1586 | /* add 30ms delay when the output type is SDVO-TV */ | 1504 | /* add 30ms delay when the output type is SDVO-TV */ |
1587 | mdelay(30); | 1505 | mdelay(30); |
1588 | } | 1506 | } |
1589 | status = intel_sdvo_read_response(intel_encoder, &response, 2); | 1507 | if (!intel_sdvo_read_response(intel_sdvo, &response, 2)) |
1508 | return connector_status_unknown; | ||
1590 | 1509 | ||
1591 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1510 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); |
1592 | 1511 | ||
1593 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1594 | return connector_status_unknown; | ||
1595 | |||
1596 | if (response == 0) | 1512 | if (response == 0) |
1597 | return connector_status_disconnected; | 1513 | return connector_status_disconnected; |
1598 | 1514 | ||
1599 | sdvo_priv->attached_output = response; | 1515 | intel_sdvo->attached_output = response; |
1600 | 1516 | ||
1601 | if ((sdvo_connector->output_flag & response) == 0) | 1517 | if ((intel_sdvo_connector->output_flag & response) == 0) |
1602 | ret = connector_status_disconnected; | 1518 | ret = connector_status_disconnected; |
1603 | else if (response & SDVO_TMDS_MASK) | 1519 | else if (response & SDVO_TMDS_MASK) |
1604 | ret = intel_sdvo_hdmi_sink_detect(connector); | 1520 | ret = intel_sdvo_hdmi_sink_detect(connector); |
@@ -1607,16 +1523,16 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1607 | 1523 | ||
1608 | /* May update encoder flag for like clock for SDVO TV, etc.*/ | 1524 | /* May update encoder flag for like clock for SDVO TV, etc.*/ |
1609 | if (ret == connector_status_connected) { | 1525 | if (ret == connector_status_connected) { |
1610 | sdvo_priv->is_tv = false; | 1526 | intel_sdvo->is_tv = false; |
1611 | sdvo_priv->is_lvds = false; | 1527 | intel_sdvo->is_lvds = false; |
1612 | intel_encoder->needs_tv_clock = false; | 1528 | intel_sdvo->base.needs_tv_clock = false; |
1613 | 1529 | ||
1614 | if (response & SDVO_TV_MASK) { | 1530 | if (response & SDVO_TV_MASK) { |
1615 | sdvo_priv->is_tv = true; | 1531 | intel_sdvo->is_tv = true; |
1616 | intel_encoder->needs_tv_clock = true; | 1532 | intel_sdvo->base.needs_tv_clock = true; |
1617 | } | 1533 | } |
1618 | if (response & SDVO_LVDS_MASK) | 1534 | if (response & SDVO_LVDS_MASK) |
1619 | sdvo_priv->is_lvds = true; | 1535 | intel_sdvo->is_lvds = intel_sdvo->sdvo_lvds_fixed_mode != NULL; |
1620 | } | 1536 | } |
1621 | 1537 | ||
1622 | return ret; | 1538 | return ret; |
@@ -1625,12 +1541,11 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1625 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1541 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1626 | { | 1542 | { |
1627 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1543 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1628 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1544 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1629 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1630 | int num_modes; | 1545 | int num_modes; |
1631 | 1546 | ||
1632 | /* set the bus switch and get the modes */ | 1547 | /* set the bus switch and get the modes */ |
1633 | num_modes = intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1548 | num_modes = intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); |
1634 | 1549 | ||
1635 | /* | 1550 | /* |
1636 | * Mac mini hack. On this device, the DVI-I connector shares one DDC | 1551 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
@@ -1639,11 +1554,11 @@ static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | |||
1639 | * which case we'll look there for the digital DDC data. | 1554 | * which case we'll look there for the digital DDC data. |
1640 | */ | 1555 | */ |
1641 | if (num_modes == 0 && | 1556 | if (num_modes == 0 && |
1642 | sdvo_priv->analog_ddc_bus && | 1557 | intel_sdvo->analog_ddc_bus && |
1643 | !intel_analog_is_connected(connector->dev)) { | 1558 | !intel_analog_is_connected(connector->dev)) { |
1644 | /* Switch to the analog ddc bus and try that | 1559 | /* Switch to the analog ddc bus and try that |
1645 | */ | 1560 | */ |
1646 | (void) intel_ddc_get_modes(connector, sdvo_priv->analog_ddc_bus); | 1561 | (void) intel_ddc_get_modes(connector, intel_sdvo->analog_ddc_bus); |
1647 | } | 1562 | } |
1648 | } | 1563 | } |
1649 | 1564 | ||
@@ -1715,52 +1630,43 @@ struct drm_display_mode sdvo_tv_modes[] = { | |||
1715 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | 1630 | static void intel_sdvo_get_tv_modes(struct drm_connector *connector) |
1716 | { | 1631 | { |
1717 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1632 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1718 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1633 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1719 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1720 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1634 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1721 | uint32_t reply = 0, format_map = 0; | 1635 | uint32_t reply = 0, format_map = 0; |
1722 | int i; | 1636 | int i; |
1723 | uint8_t status; | ||
1724 | |||
1725 | 1637 | ||
1726 | /* Read the list of supported input resolutions for the selected TV | 1638 | /* Read the list of supported input resolutions for the selected TV |
1727 | * format. | 1639 | * format. |
1728 | */ | 1640 | */ |
1729 | for (i = 0; i < TV_FORMAT_NUM; i++) | 1641 | format_map = 1 << intel_sdvo->tv_format_index; |
1730 | if (tv_format_names[i] == sdvo_priv->tv_format_name) | ||
1731 | break; | ||
1732 | |||
1733 | format_map = (1 << i); | ||
1734 | memcpy(&tv_res, &format_map, | 1642 | memcpy(&tv_res, &format_map, |
1735 | sizeof(struct intel_sdvo_sdtv_resolution_request) > | 1643 | min(sizeof(format_map), sizeof(struct intel_sdvo_sdtv_resolution_request))); |
1736 | sizeof(format_map) ? sizeof(format_map) : | ||
1737 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | ||
1738 | 1644 | ||
1739 | intel_sdvo_set_target_output(intel_encoder, sdvo_priv->attached_output); | 1645 | if (!intel_sdvo_set_target_output(intel_sdvo, intel_sdvo->attached_output)) |
1646 | return; | ||
1740 | 1647 | ||
1741 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1648 | BUILD_BUG_ON(sizeof(tv_res) != 3); |
1742 | &tv_res, sizeof(tv_res)); | 1649 | if (!intel_sdvo_write_cmd(intel_sdvo, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
1743 | status = intel_sdvo_read_response(intel_encoder, &reply, 3); | 1650 | &tv_res, sizeof(tv_res))) |
1744 | if (status != SDVO_CMD_STATUS_SUCCESS) | 1651 | return; |
1652 | if (!intel_sdvo_read_response(intel_sdvo, &reply, 3)) | ||
1745 | return; | 1653 | return; |
1746 | 1654 | ||
1747 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) | 1655 | for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) |
1748 | if (reply & (1 << i)) { | 1656 | if (reply & (1 << i)) { |
1749 | struct drm_display_mode *nmode; | 1657 | struct drm_display_mode *nmode; |
1750 | nmode = drm_mode_duplicate(connector->dev, | 1658 | nmode = drm_mode_duplicate(connector->dev, |
1751 | &sdvo_tv_modes[i]); | 1659 | &sdvo_tv_modes[i]); |
1752 | if (nmode) | 1660 | if (nmode) |
1753 | drm_mode_probed_add(connector, nmode); | 1661 | drm_mode_probed_add(connector, nmode); |
1754 | } | 1662 | } |
1755 | |||
1756 | } | 1663 | } |
1757 | 1664 | ||
1758 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1665 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1759 | { | 1666 | { |
1760 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1667 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1761 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1668 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1762 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1669 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1763 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
1764 | struct drm_display_mode *newmode; | 1670 | struct drm_display_mode *newmode; |
1765 | 1671 | ||
1766 | /* | 1672 | /* |
@@ -1768,7 +1674,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1768 | * Assume that the preferred modes are | 1674 | * Assume that the preferred modes are |
1769 | * arranged in priority order. | 1675 | * arranged in priority order. |
1770 | */ | 1676 | */ |
1771 | intel_ddc_get_modes(connector, intel_encoder->ddc_bus); | 1677 | intel_ddc_get_modes(connector, intel_sdvo->base.ddc_bus); |
1772 | if (list_empty(&connector->probed_modes) == false) | 1678 | if (list_empty(&connector->probed_modes) == false) |
1773 | goto end; | 1679 | goto end; |
1774 | 1680 | ||
@@ -1787,8 +1693,9 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1787 | end: | 1693 | end: |
1788 | list_for_each_entry(newmode, &connector->probed_modes, head) { | 1694 | list_for_each_entry(newmode, &connector->probed_modes, head) { |
1789 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { | 1695 | if (newmode->type & DRM_MODE_TYPE_PREFERRED) { |
1790 | sdvo_priv->sdvo_lvds_fixed_mode = | 1696 | intel_sdvo->sdvo_lvds_fixed_mode = |
1791 | drm_mode_duplicate(connector->dev, newmode); | 1697 | drm_mode_duplicate(connector->dev, newmode); |
1698 | intel_sdvo->is_lvds = true; | ||
1792 | break; | 1699 | break; |
1793 | } | 1700 | } |
1794 | } | 1701 | } |
@@ -1797,66 +1704,67 @@ end: | |||
1797 | 1704 | ||
1798 | static int intel_sdvo_get_modes(struct drm_connector *connector) | 1705 | static int intel_sdvo_get_modes(struct drm_connector *connector) |
1799 | { | 1706 | { |
1800 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1707 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1801 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1802 | 1708 | ||
1803 | if (IS_TV(sdvo_connector)) | 1709 | if (IS_TV(intel_sdvo_connector)) |
1804 | intel_sdvo_get_tv_modes(connector); | 1710 | intel_sdvo_get_tv_modes(connector); |
1805 | else if (IS_LVDS(sdvo_connector)) | 1711 | else if (IS_LVDS(intel_sdvo_connector)) |
1806 | intel_sdvo_get_lvds_modes(connector); | 1712 | intel_sdvo_get_lvds_modes(connector); |
1807 | else | 1713 | else |
1808 | intel_sdvo_get_ddc_modes(connector); | 1714 | intel_sdvo_get_ddc_modes(connector); |
1809 | 1715 | ||
1810 | if (list_empty(&connector->probed_modes)) | 1716 | return !list_empty(&connector->probed_modes); |
1811 | return 0; | ||
1812 | return 1; | ||
1813 | } | 1717 | } |
1814 | 1718 | ||
1815 | static | 1719 | static void |
1816 | void intel_sdvo_destroy_enhance_property(struct drm_connector *connector) | 1720 | intel_sdvo_destroy_enhance_property(struct drm_connector *connector) |
1817 | { | 1721 | { |
1818 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1722 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1819 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
1820 | struct drm_device *dev = connector->dev; | 1723 | struct drm_device *dev = connector->dev; |
1821 | 1724 | ||
1822 | if (IS_TV(sdvo_priv)) { | 1725 | if (intel_sdvo_connector->left) |
1823 | if (sdvo_priv->left_property) | 1726 | drm_property_destroy(dev, intel_sdvo_connector->left); |
1824 | drm_property_destroy(dev, sdvo_priv->left_property); | 1727 | if (intel_sdvo_connector->right) |
1825 | if (sdvo_priv->right_property) | 1728 | drm_property_destroy(dev, intel_sdvo_connector->right); |
1826 | drm_property_destroy(dev, sdvo_priv->right_property); | 1729 | if (intel_sdvo_connector->top) |
1827 | if (sdvo_priv->top_property) | 1730 | drm_property_destroy(dev, intel_sdvo_connector->top); |
1828 | drm_property_destroy(dev, sdvo_priv->top_property); | 1731 | if (intel_sdvo_connector->bottom) |
1829 | if (sdvo_priv->bottom_property) | 1732 | drm_property_destroy(dev, intel_sdvo_connector->bottom); |
1830 | drm_property_destroy(dev, sdvo_priv->bottom_property); | 1733 | if (intel_sdvo_connector->hpos) |
1831 | if (sdvo_priv->hpos_property) | 1734 | drm_property_destroy(dev, intel_sdvo_connector->hpos); |
1832 | drm_property_destroy(dev, sdvo_priv->hpos_property); | 1735 | if (intel_sdvo_connector->vpos) |
1833 | if (sdvo_priv->vpos_property) | 1736 | drm_property_destroy(dev, intel_sdvo_connector->vpos); |
1834 | drm_property_destroy(dev, sdvo_priv->vpos_property); | 1737 | if (intel_sdvo_connector->saturation) |
1835 | if (sdvo_priv->saturation_property) | 1738 | drm_property_destroy(dev, intel_sdvo_connector->saturation); |
1836 | drm_property_destroy(dev, | 1739 | if (intel_sdvo_connector->contrast) |
1837 | sdvo_priv->saturation_property); | 1740 | drm_property_destroy(dev, intel_sdvo_connector->contrast); |
1838 | if (sdvo_priv->contrast_property) | 1741 | if (intel_sdvo_connector->hue) |
1839 | drm_property_destroy(dev, | 1742 | drm_property_destroy(dev, intel_sdvo_connector->hue); |
1840 | sdvo_priv->contrast_property); | 1743 | if (intel_sdvo_connector->sharpness) |
1841 | if (sdvo_priv->hue_property) | 1744 | drm_property_destroy(dev, intel_sdvo_connector->sharpness); |
1842 | drm_property_destroy(dev, sdvo_priv->hue_property); | 1745 | if (intel_sdvo_connector->flicker_filter) |
1843 | } | 1746 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter); |
1844 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { | 1747 | if (intel_sdvo_connector->flicker_filter_2d) |
1845 | if (sdvo_priv->brightness_property) | 1748 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_2d); |
1846 | drm_property_destroy(dev, | 1749 | if (intel_sdvo_connector->flicker_filter_adaptive) |
1847 | sdvo_priv->brightness_property); | 1750 | drm_property_destroy(dev, intel_sdvo_connector->flicker_filter_adaptive); |
1848 | } | 1751 | if (intel_sdvo_connector->tv_luma_filter) |
1849 | return; | 1752 | drm_property_destroy(dev, intel_sdvo_connector->tv_luma_filter); |
1753 | if (intel_sdvo_connector->tv_chroma_filter) | ||
1754 | drm_property_destroy(dev, intel_sdvo_connector->tv_chroma_filter); | ||
1755 | if (intel_sdvo_connector->dot_crawl) | ||
1756 | drm_property_destroy(dev, intel_sdvo_connector->dot_crawl); | ||
1757 | if (intel_sdvo_connector->brightness) | ||
1758 | drm_property_destroy(dev, intel_sdvo_connector->brightness); | ||
1850 | } | 1759 | } |
1851 | 1760 | ||
1852 | static void intel_sdvo_destroy(struct drm_connector *connector) | 1761 | static void intel_sdvo_destroy(struct drm_connector *connector) |
1853 | { | 1762 | { |
1854 | struct intel_connector *intel_connector = to_intel_connector(connector); | 1763 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1855 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1856 | 1764 | ||
1857 | if (sdvo_connector->tv_format_property) | 1765 | if (intel_sdvo_connector->tv_format) |
1858 | drm_property_destroy(connector->dev, | 1766 | drm_property_destroy(connector->dev, |
1859 | sdvo_connector->tv_format_property); | 1767 | intel_sdvo_connector->tv_format); |
1860 | 1768 | ||
1861 | intel_sdvo_destroy_enhance_property(connector); | 1769 | intel_sdvo_destroy_enhance_property(connector); |
1862 | drm_sysfs_connector_remove(connector); | 1770 | drm_sysfs_connector_remove(connector); |
@@ -1870,132 +1778,118 @@ intel_sdvo_set_property(struct drm_connector *connector, | |||
1870 | uint64_t val) | 1778 | uint64_t val) |
1871 | { | 1779 | { |
1872 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1780 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1873 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1781 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
1874 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 1782 | struct intel_sdvo_connector *intel_sdvo_connector = to_intel_sdvo_connector(connector); |
1875 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
1876 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
1877 | struct drm_crtc *crtc = encoder->crtc; | ||
1878 | int ret = 0; | ||
1879 | bool changed = false; | ||
1880 | uint8_t cmd, status; | ||
1881 | uint16_t temp_value; | 1783 | uint16_t temp_value; |
1784 | uint8_t cmd; | ||
1785 | int ret; | ||
1882 | 1786 | ||
1883 | ret = drm_connector_property_set_value(connector, property, val); | 1787 | ret = drm_connector_property_set_value(connector, property, val); |
1884 | if (ret < 0) | 1788 | if (ret) |
1885 | goto out; | 1789 | return ret; |
1790 | |||
1791 | #define CHECK_PROPERTY(name, NAME) \ | ||
1792 | if (intel_sdvo_connector->name == property) { \ | ||
1793 | if (intel_sdvo_connector->cur_##name == temp_value) return 0; \ | ||
1794 | if (intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \ | ||
1795 | cmd = SDVO_CMD_SET_##NAME; \ | ||
1796 | intel_sdvo_connector->cur_##name = temp_value; \ | ||
1797 | goto set_value; \ | ||
1798 | } | ||
1886 | 1799 | ||
1887 | if (property == sdvo_connector->tv_format_property) { | 1800 | if (property == intel_sdvo_connector->tv_format) { |
1888 | if (val >= TV_FORMAT_NUM) { | 1801 | if (val >= TV_FORMAT_NUM) |
1889 | ret = -EINVAL; | 1802 | return -EINVAL; |
1890 | goto out; | ||
1891 | } | ||
1892 | if (sdvo_priv->tv_format_name == | ||
1893 | sdvo_connector->tv_format_supported[val]) | ||
1894 | goto out; | ||
1895 | 1803 | ||
1896 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[val]; | 1804 | if (intel_sdvo->tv_format_index == |
1897 | changed = true; | 1805 | intel_sdvo_connector->tv_format_supported[val]) |
1898 | } | 1806 | return 0; |
1899 | 1807 | ||
1900 | if (IS_TV(sdvo_connector) || IS_LVDS(sdvo_connector)) { | 1808 | intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[val]; |
1901 | cmd = 0; | 1809 | goto done; |
1810 | } else if (IS_TV_OR_LVDS(intel_sdvo_connector)) { | ||
1902 | temp_value = val; | 1811 | temp_value = val; |
1903 | if (sdvo_connector->left_property == property) { | 1812 | if (intel_sdvo_connector->left == property) { |
1904 | drm_connector_property_set_value(connector, | 1813 | drm_connector_property_set_value(connector, |
1905 | sdvo_connector->right_property, val); | 1814 | intel_sdvo_connector->right, val); |
1906 | if (sdvo_connector->left_margin == temp_value) | 1815 | if (intel_sdvo_connector->left_margin == temp_value) |
1907 | goto out; | 1816 | return 0; |
1908 | 1817 | ||
1909 | sdvo_connector->left_margin = temp_value; | 1818 | intel_sdvo_connector->left_margin = temp_value; |
1910 | sdvo_connector->right_margin = temp_value; | 1819 | intel_sdvo_connector->right_margin = temp_value; |
1911 | temp_value = sdvo_connector->max_hscan - | 1820 | temp_value = intel_sdvo_connector->max_hscan - |
1912 | sdvo_connector->left_margin; | 1821 | intel_sdvo_connector->left_margin; |
1913 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1822 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
1914 | } else if (sdvo_connector->right_property == property) { | 1823 | goto set_value; |
1824 | } else if (intel_sdvo_connector->right == property) { | ||
1915 | drm_connector_property_set_value(connector, | 1825 | drm_connector_property_set_value(connector, |
1916 | sdvo_connector->left_property, val); | 1826 | intel_sdvo_connector->left, val); |
1917 | if (sdvo_connector->right_margin == temp_value) | 1827 | if (intel_sdvo_connector->right_margin == temp_value) |
1918 | goto out; | 1828 | return 0; |
1919 | 1829 | ||
1920 | sdvo_connector->left_margin = temp_value; | 1830 | intel_sdvo_connector->left_margin = temp_value; |
1921 | sdvo_connector->right_margin = temp_value; | 1831 | intel_sdvo_connector->right_margin = temp_value; |
1922 | temp_value = sdvo_connector->max_hscan - | 1832 | temp_value = intel_sdvo_connector->max_hscan - |
1923 | sdvo_connector->left_margin; | 1833 | intel_sdvo_connector->left_margin; |
1924 | cmd = SDVO_CMD_SET_OVERSCAN_H; | 1834 | cmd = SDVO_CMD_SET_OVERSCAN_H; |
1925 | } else if (sdvo_connector->top_property == property) { | 1835 | goto set_value; |
1836 | } else if (intel_sdvo_connector->top == property) { | ||
1926 | drm_connector_property_set_value(connector, | 1837 | drm_connector_property_set_value(connector, |
1927 | sdvo_connector->bottom_property, val); | 1838 | intel_sdvo_connector->bottom, val); |
1928 | if (sdvo_connector->top_margin == temp_value) | 1839 | if (intel_sdvo_connector->top_margin == temp_value) |
1929 | goto out; | 1840 | return 0; |
1930 | 1841 | ||
1931 | sdvo_connector->top_margin = temp_value; | 1842 | intel_sdvo_connector->top_margin = temp_value; |
1932 | sdvo_connector->bottom_margin = temp_value; | 1843 | intel_sdvo_connector->bottom_margin = temp_value; |
1933 | temp_value = sdvo_connector->max_vscan - | 1844 | temp_value = intel_sdvo_connector->max_vscan - |
1934 | sdvo_connector->top_margin; | 1845 | intel_sdvo_connector->top_margin; |
1935 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1846 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
1936 | } else if (sdvo_connector->bottom_property == property) { | 1847 | goto set_value; |
1848 | } else if (intel_sdvo_connector->bottom == property) { | ||
1937 | drm_connector_property_set_value(connector, | 1849 | drm_connector_property_set_value(connector, |
1938 | sdvo_connector->top_property, val); | 1850 | intel_sdvo_connector->top, val); |
1939 | if (sdvo_connector->bottom_margin == temp_value) | 1851 | if (intel_sdvo_connector->bottom_margin == temp_value) |
1940 | goto out; | 1852 | return 0; |
1941 | sdvo_connector->top_margin = temp_value; | 1853 | |
1942 | sdvo_connector->bottom_margin = temp_value; | 1854 | intel_sdvo_connector->top_margin = temp_value; |
1943 | temp_value = sdvo_connector->max_vscan - | 1855 | intel_sdvo_connector->bottom_margin = temp_value; |
1944 | sdvo_connector->top_margin; | 1856 | temp_value = intel_sdvo_connector->max_vscan - |
1857 | intel_sdvo_connector->top_margin; | ||
1945 | cmd = SDVO_CMD_SET_OVERSCAN_V; | 1858 | cmd = SDVO_CMD_SET_OVERSCAN_V; |
1946 | } else if (sdvo_connector->hpos_property == property) { | 1859 | goto set_value; |
1947 | if (sdvo_connector->cur_hpos == temp_value) | ||
1948 | goto out; | ||
1949 | |||
1950 | cmd = SDVO_CMD_SET_POSITION_H; | ||
1951 | sdvo_connector->cur_hpos = temp_value; | ||
1952 | } else if (sdvo_connector->vpos_property == property) { | ||
1953 | if (sdvo_connector->cur_vpos == temp_value) | ||
1954 | goto out; | ||
1955 | |||
1956 | cmd = SDVO_CMD_SET_POSITION_V; | ||
1957 | sdvo_connector->cur_vpos = temp_value; | ||
1958 | } else if (sdvo_connector->saturation_property == property) { | ||
1959 | if (sdvo_connector->cur_saturation == temp_value) | ||
1960 | goto out; | ||
1961 | |||
1962 | cmd = SDVO_CMD_SET_SATURATION; | ||
1963 | sdvo_connector->cur_saturation = temp_value; | ||
1964 | } else if (sdvo_connector->contrast_property == property) { | ||
1965 | if (sdvo_connector->cur_contrast == temp_value) | ||
1966 | goto out; | ||
1967 | |||
1968 | cmd = SDVO_CMD_SET_CONTRAST; | ||
1969 | sdvo_connector->cur_contrast = temp_value; | ||
1970 | } else if (sdvo_connector->hue_property == property) { | ||
1971 | if (sdvo_connector->cur_hue == temp_value) | ||
1972 | goto out; | ||
1973 | |||
1974 | cmd = SDVO_CMD_SET_HUE; | ||
1975 | sdvo_connector->cur_hue = temp_value; | ||
1976 | } else if (sdvo_connector->brightness_property == property) { | ||
1977 | if (sdvo_connector->cur_brightness == temp_value) | ||
1978 | goto out; | ||
1979 | |||
1980 | cmd = SDVO_CMD_SET_BRIGHTNESS; | ||
1981 | sdvo_connector->cur_brightness = temp_value; | ||
1982 | } | ||
1983 | if (cmd) { | ||
1984 | intel_sdvo_write_cmd(intel_encoder, cmd, &temp_value, 2); | ||
1985 | status = intel_sdvo_read_response(intel_encoder, | ||
1986 | NULL, 0); | ||
1987 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
1988 | DRM_DEBUG_KMS("Incorrect SDVO command \n"); | ||
1989 | return -EINVAL; | ||
1990 | } | ||
1991 | changed = true; | ||
1992 | } | 1860 | } |
1861 | CHECK_PROPERTY(hpos, HPOS) | ||
1862 | CHECK_PROPERTY(vpos, VPOS) | ||
1863 | CHECK_PROPERTY(saturation, SATURATION) | ||
1864 | CHECK_PROPERTY(contrast, CONTRAST) | ||
1865 | CHECK_PROPERTY(hue, HUE) | ||
1866 | CHECK_PROPERTY(brightness, BRIGHTNESS) | ||
1867 | CHECK_PROPERTY(sharpness, SHARPNESS) | ||
1868 | CHECK_PROPERTY(flicker_filter, FLICKER_FILTER) | ||
1869 | CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D) | ||
1870 | CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) | ||
1871 | CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) | ||
1872 | CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) | ||
1873 | CHECK_PROPERTY(dot_crawl, DOT_CRAWL) | ||
1993 | } | 1874 | } |
1994 | if (changed && crtc) | 1875 | |
1876 | return -EINVAL; /* unknown property */ | ||
1877 | |||
1878 | set_value: | ||
1879 | if (!intel_sdvo_set_value(intel_sdvo, cmd, &temp_value, 2)) | ||
1880 | return -EIO; | ||
1881 | |||
1882 | |||
1883 | done: | ||
1884 | if (encoder->crtc) { | ||
1885 | struct drm_crtc *crtc = encoder->crtc; | ||
1886 | |||
1995 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | 1887 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, |
1996 | crtc->y, crtc->fb); | 1888 | crtc->y, crtc->fb); |
1997 | out: | 1889 | } |
1998 | return ret; | 1890 | |
1891 | return 0; | ||
1892 | #undef CHECK_PROPERTY | ||
1999 | } | 1893 | } |
2000 | 1894 | ||
2001 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 1895 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
@@ -2022,22 +1916,16 @@ static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs | |||
2022 | 1916 | ||
2023 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) | 1917 | static void intel_sdvo_enc_destroy(struct drm_encoder *encoder) |
2024 | { | 1918 | { |
2025 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1919 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
2026 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2027 | 1920 | ||
2028 | if (intel_encoder->i2c_bus) | 1921 | if (intel_sdvo->analog_ddc_bus) |
2029 | intel_i2c_destroy(intel_encoder->i2c_bus); | 1922 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |
2030 | if (intel_encoder->ddc_bus) | ||
2031 | intel_i2c_destroy(intel_encoder->ddc_bus); | ||
2032 | if (sdvo_priv->analog_ddc_bus) | ||
2033 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
2034 | 1923 | ||
2035 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | 1924 | if (intel_sdvo->sdvo_lvds_fixed_mode != NULL) |
2036 | drm_mode_destroy(encoder->dev, | 1925 | drm_mode_destroy(encoder->dev, |
2037 | sdvo_priv->sdvo_lvds_fixed_mode); | 1926 | intel_sdvo->sdvo_lvds_fixed_mode); |
2038 | 1927 | ||
2039 | drm_encoder_cleanup(encoder); | 1928 | intel_encoder_destroy(encoder); |
2040 | kfree(intel_encoder); | ||
2041 | } | 1929 | } |
2042 | 1930 | ||
2043 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | 1931 | static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { |
@@ -2054,7 +1942,7 @@ static const struct drm_encoder_funcs intel_sdvo_enc_funcs = { | |||
2054 | */ | 1942 | */ |
2055 | static void | 1943 | static void |
2056 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | 1944 | intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, |
2057 | struct intel_sdvo_priv *sdvo, u32 reg) | 1945 | struct intel_sdvo *sdvo, u32 reg) |
2058 | { | 1946 | { |
2059 | struct sdvo_device_mapping *mapping; | 1947 | struct sdvo_device_mapping *mapping; |
2060 | 1948 | ||
@@ -2067,57 +1955,46 @@ intel_sdvo_select_ddc_bus(struct drm_i915_private *dev_priv, | |||
2067 | } | 1955 | } |
2068 | 1956 | ||
2069 | static bool | 1957 | static bool |
2070 | intel_sdvo_get_digital_encoding_mode(struct intel_encoder *output, int device) | 1958 | intel_sdvo_get_digital_encoding_mode(struct intel_sdvo *intel_sdvo, int device) |
2071 | { | 1959 | { |
2072 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1960 | return intel_sdvo_set_target_output(intel_sdvo, |
2073 | uint8_t status; | 1961 | device == 0 ? SDVO_OUTPUT_TMDS0 : SDVO_OUTPUT_TMDS1) && |
2074 | 1962 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, | |
2075 | if (device == 0) | 1963 | &intel_sdvo->is_hdmi, 1); |
2076 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS0); | ||
2077 | else | ||
2078 | intel_sdvo_set_target_output(output, SDVO_OUTPUT_TMDS1); | ||
2079 | |||
2080 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); | ||
2081 | status = intel_sdvo_read_response(output, &sdvo_priv->is_hdmi, 1); | ||
2082 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
2083 | return false; | ||
2084 | return true; | ||
2085 | } | 1964 | } |
2086 | 1965 | ||
2087 | static struct intel_encoder * | 1966 | static struct intel_sdvo * |
2088 | intel_sdvo_chan_to_intel_encoder(struct intel_i2c_chan *chan) | 1967 | intel_sdvo_chan_to_intel_sdvo(struct intel_i2c_chan *chan) |
2089 | { | 1968 | { |
2090 | struct drm_device *dev = chan->drm_dev; | 1969 | struct drm_device *dev = chan->drm_dev; |
2091 | struct drm_encoder *encoder; | 1970 | struct drm_encoder *encoder; |
2092 | struct intel_encoder *intel_encoder = NULL; | ||
2093 | 1971 | ||
2094 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1972 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
2095 | intel_encoder = enc_to_intel_encoder(encoder); | 1973 | struct intel_sdvo *intel_sdvo = enc_to_intel_sdvo(encoder); |
2096 | if (intel_encoder->ddc_bus == &chan->adapter) | 1974 | if (intel_sdvo->base.ddc_bus == &chan->adapter) |
2097 | break; | 1975 | return intel_sdvo; |
2098 | } | 1976 | } |
2099 | return intel_encoder; | 1977 | |
1978 | return NULL; | ||
2100 | } | 1979 | } |
2101 | 1980 | ||
2102 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | 1981 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, |
2103 | struct i2c_msg msgs[], int num) | 1982 | struct i2c_msg msgs[], int num) |
2104 | { | 1983 | { |
2105 | struct intel_encoder *intel_encoder; | 1984 | struct intel_sdvo *intel_sdvo; |
2106 | struct intel_sdvo_priv *sdvo_priv; | ||
2107 | struct i2c_algo_bit_data *algo_data; | 1985 | struct i2c_algo_bit_data *algo_data; |
2108 | const struct i2c_algorithm *algo; | 1986 | const struct i2c_algorithm *algo; |
2109 | 1987 | ||
2110 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 1988 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
2111 | intel_encoder = | 1989 | intel_sdvo = |
2112 | intel_sdvo_chan_to_intel_encoder( | 1990 | intel_sdvo_chan_to_intel_sdvo((struct intel_i2c_chan *) |
2113 | (struct intel_i2c_chan *)(algo_data->data)); | 1991 | (algo_data->data)); |
2114 | if (intel_encoder == NULL) | 1992 | if (intel_sdvo == NULL) |
2115 | return -EINVAL; | 1993 | return -EINVAL; |
2116 | 1994 | ||
2117 | sdvo_priv = intel_encoder->dev_priv; | 1995 | algo = intel_sdvo->base.i2c_bus->algo; |
2118 | algo = intel_encoder->i2c_bus->algo; | ||
2119 | 1996 | ||
2120 | intel_sdvo_set_control_bus_switch(intel_encoder, sdvo_priv->ddc_bus); | 1997 | intel_sdvo_set_control_bus_switch(intel_sdvo, intel_sdvo->ddc_bus); |
2121 | return algo->master_xfer(i2c_adap, msgs, num); | 1998 | return algo->master_xfer(i2c_adap, msgs, num); |
2122 | } | 1999 | } |
2123 | 2000 | ||
@@ -2162,27 +2039,9 @@ intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) | |||
2162 | return 0x72; | 2039 | return 0x72; |
2163 | } | 2040 | } |
2164 | 2041 | ||
2165 | static bool | ||
2166 | intel_sdvo_connector_alloc (struct intel_connector **ret) | ||
2167 | { | ||
2168 | struct intel_connector *intel_connector; | ||
2169 | struct intel_sdvo_connector *sdvo_connector; | ||
2170 | |||
2171 | *ret = kzalloc(sizeof(*intel_connector) + | ||
2172 | sizeof(*sdvo_connector), GFP_KERNEL); | ||
2173 | if (!*ret) | ||
2174 | return false; | ||
2175 | |||
2176 | intel_connector = *ret; | ||
2177 | sdvo_connector = (struct intel_sdvo_connector *)(intel_connector + 1); | ||
2178 | intel_connector->dev_priv = sdvo_connector; | ||
2179 | |||
2180 | return true; | ||
2181 | } | ||
2182 | |||
2183 | static void | 2042 | static void |
2184 | intel_sdvo_connector_create (struct drm_encoder *encoder, | 2043 | intel_sdvo_connector_init(struct drm_encoder *encoder, |
2185 | struct drm_connector *connector) | 2044 | struct drm_connector *connector) |
2186 | { | 2045 | { |
2187 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, | 2046 | drm_connector_init(encoder->dev, connector, &intel_sdvo_connector_funcs, |
2188 | connector->connector_type); | 2047 | connector->connector_type); |
@@ -2198,582 +2057,470 @@ intel_sdvo_connector_create (struct drm_encoder *encoder, | |||
2198 | } | 2057 | } |
2199 | 2058 | ||
2200 | static bool | 2059 | static bool |
2201 | intel_sdvo_dvi_init(struct intel_encoder *intel_encoder, int device) | 2060 | intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) |
2202 | { | 2061 | { |
2203 | struct drm_encoder *encoder = &intel_encoder->enc; | 2062 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
2204 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2205 | struct drm_connector *connector; | 2063 | struct drm_connector *connector; |
2206 | struct intel_connector *intel_connector; | 2064 | struct intel_connector *intel_connector; |
2207 | struct intel_sdvo_connector *sdvo_connector; | 2065 | struct intel_sdvo_connector *intel_sdvo_connector; |
2208 | 2066 | ||
2209 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2067 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2068 | if (!intel_sdvo_connector) | ||
2210 | return false; | 2069 | return false; |
2211 | 2070 | ||
2212 | sdvo_connector = intel_connector->dev_priv; | ||
2213 | |||
2214 | if (device == 0) { | 2071 | if (device == 0) { |
2215 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS0; | 2072 | intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; |
2216 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; | 2073 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; |
2217 | } else if (device == 1) { | 2074 | } else if (device == 1) { |
2218 | sdvo_priv->controlled_output |= SDVO_OUTPUT_TMDS1; | 2075 | intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; |
2219 | sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; | 2076 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; |
2220 | } | 2077 | } |
2221 | 2078 | ||
2079 | intel_connector = &intel_sdvo_connector->base; | ||
2222 | connector = &intel_connector->base; | 2080 | connector = &intel_connector->base; |
2223 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | 2081 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; |
2224 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; | 2082 | encoder->encoder_type = DRM_MODE_ENCODER_TMDS; |
2225 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; | 2083 | connector->connector_type = DRM_MODE_CONNECTOR_DVID; |
2226 | 2084 | ||
2227 | if (intel_sdvo_get_supp_encode(intel_encoder, &sdvo_priv->encode) | 2085 | if (intel_sdvo_get_supp_encode(intel_sdvo, &intel_sdvo->encode) |
2228 | && intel_sdvo_get_digital_encoding_mode(intel_encoder, device) | 2086 | && intel_sdvo_get_digital_encoding_mode(intel_sdvo, device) |
2229 | && sdvo_priv->is_hdmi) { | 2087 | && intel_sdvo->is_hdmi) { |
2230 | /* enable hdmi encoding mode if supported */ | 2088 | /* enable hdmi encoding mode if supported */ |
2231 | intel_sdvo_set_encode(intel_encoder, SDVO_ENCODE_HDMI); | 2089 | intel_sdvo_set_encode(intel_sdvo, SDVO_ENCODE_HDMI); |
2232 | intel_sdvo_set_colorimetry(intel_encoder, | 2090 | intel_sdvo_set_colorimetry(intel_sdvo, |
2233 | SDVO_COLORIMETRY_RGB256); | 2091 | SDVO_COLORIMETRY_RGB256); |
2234 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2092 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2235 | } | 2093 | } |
2236 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2094 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2237 | (1 << INTEL_ANALOG_CLONE_BIT); | 2095 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2238 | 2096 | ||
2239 | intel_sdvo_connector_create(encoder, connector); | 2097 | intel_sdvo_connector_init(encoder, connector); |
2240 | 2098 | ||
2241 | return true; | 2099 | return true; |
2242 | } | 2100 | } |
2243 | 2101 | ||
2244 | static bool | 2102 | static bool |
2245 | intel_sdvo_tv_init(struct intel_encoder *intel_encoder, int type) | 2103 | intel_sdvo_tv_init(struct intel_sdvo *intel_sdvo, int type) |
2246 | { | 2104 | { |
2247 | struct drm_encoder *encoder = &intel_encoder->enc; | 2105 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
2248 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2249 | struct drm_connector *connector; | 2106 | struct drm_connector *connector; |
2250 | struct intel_connector *intel_connector; | 2107 | struct intel_connector *intel_connector; |
2251 | struct intel_sdvo_connector *sdvo_connector; | 2108 | struct intel_sdvo_connector *intel_sdvo_connector; |
2252 | 2109 | ||
2253 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2110 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2254 | return false; | 2111 | if (!intel_sdvo_connector) |
2112 | return false; | ||
2255 | 2113 | ||
2114 | intel_connector = &intel_sdvo_connector->base; | ||
2256 | connector = &intel_connector->base; | 2115 | connector = &intel_connector->base; |
2257 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; | 2116 | encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; |
2258 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2117 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
2259 | sdvo_connector = intel_connector->dev_priv; | ||
2260 | 2118 | ||
2261 | sdvo_priv->controlled_output |= type; | 2119 | intel_sdvo->controlled_output |= type; |
2262 | sdvo_connector->output_flag = type; | 2120 | intel_sdvo_connector->output_flag = type; |
2263 | 2121 | ||
2264 | sdvo_priv->is_tv = true; | 2122 | intel_sdvo->is_tv = true; |
2265 | intel_encoder->needs_tv_clock = true; | 2123 | intel_sdvo->base.needs_tv_clock = true; |
2266 | intel_encoder->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | 2124 | intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; |
2267 | 2125 | ||
2268 | intel_sdvo_connector_create(encoder, connector); | 2126 | intel_sdvo_connector_init(encoder, connector); |
2269 | 2127 | ||
2270 | intel_sdvo_tv_create_property(connector, type); | 2128 | if (!intel_sdvo_tv_create_property(intel_sdvo, intel_sdvo_connector, type)) |
2129 | goto err; | ||
2271 | 2130 | ||
2272 | intel_sdvo_create_enhance_property(connector); | 2131 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2132 | goto err; | ||
2273 | 2133 | ||
2274 | return true; | 2134 | return true; |
2135 | |||
2136 | err: | ||
2137 | intel_sdvo_destroy_enhance_property(connector); | ||
2138 | kfree(intel_sdvo_connector); | ||
2139 | return false; | ||
2275 | } | 2140 | } |
2276 | 2141 | ||
2277 | static bool | 2142 | static bool |
2278 | intel_sdvo_analog_init(struct intel_encoder *intel_encoder, int device) | 2143 | intel_sdvo_analog_init(struct intel_sdvo *intel_sdvo, int device) |
2279 | { | 2144 | { |
2280 | struct drm_encoder *encoder = &intel_encoder->enc; | 2145 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
2281 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2282 | struct drm_connector *connector; | 2146 | struct drm_connector *connector; |
2283 | struct intel_connector *intel_connector; | 2147 | struct intel_connector *intel_connector; |
2284 | struct intel_sdvo_connector *sdvo_connector; | 2148 | struct intel_sdvo_connector *intel_sdvo_connector; |
2285 | 2149 | ||
2286 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2150 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2287 | return false; | 2151 | if (!intel_sdvo_connector) |
2152 | return false; | ||
2288 | 2153 | ||
2154 | intel_connector = &intel_sdvo_connector->base; | ||
2289 | connector = &intel_connector->base; | 2155 | connector = &intel_connector->base; |
2290 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | 2156 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
2291 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2157 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
2292 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2158 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2293 | sdvo_connector = intel_connector->dev_priv; | ||
2294 | 2159 | ||
2295 | if (device == 0) { | 2160 | if (device == 0) { |
2296 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB0; | 2161 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; |
2297 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; | 2162 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; |
2298 | } else if (device == 1) { | 2163 | } else if (device == 1) { |
2299 | sdvo_priv->controlled_output |= SDVO_OUTPUT_RGB1; | 2164 | intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; |
2300 | sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; | 2165 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; |
2301 | } | 2166 | } |
2302 | 2167 | ||
2303 | intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2168 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2304 | (1 << INTEL_ANALOG_CLONE_BIT); | 2169 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2305 | 2170 | ||
2306 | intel_sdvo_connector_create(encoder, connector); | 2171 | intel_sdvo_connector_init(encoder, connector); |
2307 | return true; | 2172 | return true; |
2308 | } | 2173 | } |
2309 | 2174 | ||
2310 | static bool | 2175 | static bool |
2311 | intel_sdvo_lvds_init(struct intel_encoder *intel_encoder, int device) | 2176 | intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) |
2312 | { | 2177 | { |
2313 | struct drm_encoder *encoder = &intel_encoder->enc; | 2178 | struct drm_encoder *encoder = &intel_sdvo->base.enc; |
2314 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2315 | struct drm_connector *connector; | 2179 | struct drm_connector *connector; |
2316 | struct intel_connector *intel_connector; | 2180 | struct intel_connector *intel_connector; |
2317 | struct intel_sdvo_connector *sdvo_connector; | 2181 | struct intel_sdvo_connector *intel_sdvo_connector; |
2318 | 2182 | ||
2319 | if (!intel_sdvo_connector_alloc(&intel_connector)) | 2183 | intel_sdvo_connector = kzalloc(sizeof(struct intel_sdvo_connector), GFP_KERNEL); |
2320 | return false; | 2184 | if (!intel_sdvo_connector) |
2185 | return false; | ||
2321 | 2186 | ||
2322 | connector = &intel_connector->base; | 2187 | intel_connector = &intel_sdvo_connector->base; |
2188 | connector = &intel_connector->base; | ||
2323 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2189 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
2324 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2190 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
2325 | sdvo_connector = intel_connector->dev_priv; | ||
2326 | |||
2327 | sdvo_priv->is_lvds = true; | ||
2328 | 2191 | ||
2329 | if (device == 0) { | 2192 | if (device == 0) { |
2330 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS0; | 2193 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; |
2331 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; | 2194 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; |
2332 | } else if (device == 1) { | 2195 | } else if (device == 1) { |
2333 | sdvo_priv->controlled_output |= SDVO_OUTPUT_LVDS1; | 2196 | intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; |
2334 | sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; | 2197 | intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; |
2335 | } | 2198 | } |
2336 | 2199 | ||
2337 | intel_encoder->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | 2200 | intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | |
2338 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | 2201 | (1 << INTEL_SDVO_LVDS_CLONE_BIT)); |
2339 | 2202 | ||
2340 | intel_sdvo_connector_create(encoder, connector); | 2203 | intel_sdvo_connector_init(encoder, connector); |
2341 | intel_sdvo_create_enhance_property(connector); | 2204 | if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) |
2342 | return true; | 2205 | goto err; |
2206 | |||
2207 | return true; | ||
2208 | |||
2209 | err: | ||
2210 | intel_sdvo_destroy_enhance_property(connector); | ||
2211 | kfree(intel_sdvo_connector); | ||
2212 | return false; | ||
2343 | } | 2213 | } |
2344 | 2214 | ||
2345 | static bool | 2215 | static bool |
2346 | intel_sdvo_output_setup(struct intel_encoder *intel_encoder, uint16_t flags) | 2216 | intel_sdvo_output_setup(struct intel_sdvo *intel_sdvo, uint16_t flags) |
2347 | { | 2217 | { |
2348 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | 2218 | intel_sdvo->is_tv = false; |
2349 | 2219 | intel_sdvo->base.needs_tv_clock = false; | |
2350 | sdvo_priv->is_tv = false; | 2220 | intel_sdvo->is_lvds = false; |
2351 | intel_encoder->needs_tv_clock = false; | ||
2352 | sdvo_priv->is_lvds = false; | ||
2353 | 2221 | ||
2354 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ | 2222 | /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ |
2355 | 2223 | ||
2356 | if (flags & SDVO_OUTPUT_TMDS0) | 2224 | if (flags & SDVO_OUTPUT_TMDS0) |
2357 | if (!intel_sdvo_dvi_init(intel_encoder, 0)) | 2225 | if (!intel_sdvo_dvi_init(intel_sdvo, 0)) |
2358 | return false; | 2226 | return false; |
2359 | 2227 | ||
2360 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) | 2228 | if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) |
2361 | if (!intel_sdvo_dvi_init(intel_encoder, 1)) | 2229 | if (!intel_sdvo_dvi_init(intel_sdvo, 1)) |
2362 | return false; | 2230 | return false; |
2363 | 2231 | ||
2364 | /* TV has no XXX1 function block */ | 2232 | /* TV has no XXX1 function block */ |
2365 | if (flags & SDVO_OUTPUT_SVID0) | 2233 | if (flags & SDVO_OUTPUT_SVID0) |
2366 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_SVID0)) | 2234 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_SVID0)) |
2367 | return false; | 2235 | return false; |
2368 | 2236 | ||
2369 | if (flags & SDVO_OUTPUT_CVBS0) | 2237 | if (flags & SDVO_OUTPUT_CVBS0) |
2370 | if (!intel_sdvo_tv_init(intel_encoder, SDVO_OUTPUT_CVBS0)) | 2238 | if (!intel_sdvo_tv_init(intel_sdvo, SDVO_OUTPUT_CVBS0)) |
2371 | return false; | 2239 | return false; |
2372 | 2240 | ||
2373 | if (flags & SDVO_OUTPUT_RGB0) | 2241 | if (flags & SDVO_OUTPUT_RGB0) |
2374 | if (!intel_sdvo_analog_init(intel_encoder, 0)) | 2242 | if (!intel_sdvo_analog_init(intel_sdvo, 0)) |
2375 | return false; | 2243 | return false; |
2376 | 2244 | ||
2377 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) | 2245 | if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) |
2378 | if (!intel_sdvo_analog_init(intel_encoder, 1)) | 2246 | if (!intel_sdvo_analog_init(intel_sdvo, 1)) |
2379 | return false; | 2247 | return false; |
2380 | 2248 | ||
2381 | if (flags & SDVO_OUTPUT_LVDS0) | 2249 | if (flags & SDVO_OUTPUT_LVDS0) |
2382 | if (!intel_sdvo_lvds_init(intel_encoder, 0)) | 2250 | if (!intel_sdvo_lvds_init(intel_sdvo, 0)) |
2383 | return false; | 2251 | return false; |
2384 | 2252 | ||
2385 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) | 2253 | if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) |
2386 | if (!intel_sdvo_lvds_init(intel_encoder, 1)) | 2254 | if (!intel_sdvo_lvds_init(intel_sdvo, 1)) |
2387 | return false; | 2255 | return false; |
2388 | 2256 | ||
2389 | if ((flags & SDVO_OUTPUT_MASK) == 0) { | 2257 | if ((flags & SDVO_OUTPUT_MASK) == 0) { |
2390 | unsigned char bytes[2]; | 2258 | unsigned char bytes[2]; |
2391 | 2259 | ||
2392 | sdvo_priv->controlled_output = 0; | 2260 | intel_sdvo->controlled_output = 0; |
2393 | memcpy(bytes, &sdvo_priv->caps.output_flags, 2); | 2261 | memcpy(bytes, &intel_sdvo->caps.output_flags, 2); |
2394 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", | 2262 | DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", |
2395 | SDVO_NAME(sdvo_priv), | 2263 | SDVO_NAME(intel_sdvo), |
2396 | bytes[0], bytes[1]); | 2264 | bytes[0], bytes[1]); |
2397 | return false; | 2265 | return false; |
2398 | } | 2266 | } |
2399 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 2267 | intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1); |
2400 | 2268 | ||
2401 | return true; | 2269 | return true; |
2402 | } | 2270 | } |
2403 | 2271 | ||
2404 | static void intel_sdvo_tv_create_property(struct drm_connector *connector, int type) | 2272 | static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, |
2273 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
2274 | int type) | ||
2405 | { | 2275 | { |
2406 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2276 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
2407 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
2408 | struct intel_sdvo_priv *sdvo_priv = intel_encoder->dev_priv; | ||
2409 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
2410 | struct intel_sdvo_connector *sdvo_connector = intel_connector->dev_priv; | ||
2411 | struct intel_sdvo_tv_format format; | 2277 | struct intel_sdvo_tv_format format; |
2412 | uint32_t format_map, i; | 2278 | uint32_t format_map, i; |
2413 | uint8_t status; | ||
2414 | 2279 | ||
2415 | intel_sdvo_set_target_output(intel_encoder, type); | 2280 | if (!intel_sdvo_set_target_output(intel_sdvo, type)) |
2281 | return false; | ||
2416 | 2282 | ||
2417 | intel_sdvo_write_cmd(intel_encoder, | 2283 | if (!intel_sdvo_get_value(intel_sdvo, |
2418 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | 2284 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, |
2419 | status = intel_sdvo_read_response(intel_encoder, | 2285 | &format, sizeof(format))) |
2420 | &format, sizeof(format)); | 2286 | return false; |
2421 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
2422 | return; | ||
2423 | 2287 | ||
2424 | memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ? | 2288 | memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format))); |
2425 | sizeof(format_map) : sizeof(format)); | ||
2426 | 2289 | ||
2427 | if (format_map == 0) | 2290 | if (format_map == 0) |
2428 | return; | 2291 | return false; |
2429 | 2292 | ||
2430 | sdvo_connector->format_supported_num = 0; | 2293 | intel_sdvo_connector->format_supported_num = 0; |
2431 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | 2294 | for (i = 0 ; i < TV_FORMAT_NUM; i++) |
2432 | if (format_map & (1 << i)) { | 2295 | if (format_map & (1 << i)) |
2433 | sdvo_connector->tv_format_supported | 2296 | intel_sdvo_connector->tv_format_supported[intel_sdvo_connector->format_supported_num++] = i; |
2434 | [sdvo_connector->format_supported_num++] = | ||
2435 | tv_format_names[i]; | ||
2436 | } | ||
2437 | 2297 | ||
2438 | 2298 | ||
2439 | sdvo_connector->tv_format_property = | 2299 | intel_sdvo_connector->tv_format = |
2440 | drm_property_create( | 2300 | drm_property_create(dev, DRM_MODE_PROP_ENUM, |
2441 | connector->dev, DRM_MODE_PROP_ENUM, | 2301 | "mode", intel_sdvo_connector->format_supported_num); |
2442 | "mode", sdvo_connector->format_supported_num); | 2302 | if (!intel_sdvo_connector->tv_format) |
2303 | return false; | ||
2443 | 2304 | ||
2444 | for (i = 0; i < sdvo_connector->format_supported_num; i++) | 2305 | for (i = 0; i < intel_sdvo_connector->format_supported_num; i++) |
2445 | drm_property_add_enum( | 2306 | drm_property_add_enum( |
2446 | sdvo_connector->tv_format_property, i, | 2307 | intel_sdvo_connector->tv_format, i, |
2447 | i, sdvo_connector->tv_format_supported[i]); | 2308 | i, tv_format_names[intel_sdvo_connector->tv_format_supported[i]]); |
2448 | 2309 | ||
2449 | sdvo_priv->tv_format_name = sdvo_connector->tv_format_supported[0]; | 2310 | intel_sdvo->tv_format_index = intel_sdvo_connector->tv_format_supported[0]; |
2450 | drm_connector_attach_property( | 2311 | drm_connector_attach_property(&intel_sdvo_connector->base.base, |
2451 | connector, sdvo_connector->tv_format_property, 0); | 2312 | intel_sdvo_connector->tv_format, 0); |
2313 | return true; | ||
2452 | 2314 | ||
2453 | } | 2315 | } |
2454 | 2316 | ||
2455 | static void intel_sdvo_create_enhance_property(struct drm_connector *connector) | 2317 | #define ENHANCEMENT(name, NAME) do { \ |
2318 | if (enhancements.name) { \ | ||
2319 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \ | ||
2320 | !intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ | ||
2321 | return false; \ | ||
2322 | intel_sdvo_connector->max_##name = data_value[0]; \ | ||
2323 | intel_sdvo_connector->cur_##name = response; \ | ||
2324 | intel_sdvo_connector->name = \ | ||
2325 | drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ | ||
2326 | if (!intel_sdvo_connector->name) return false; \ | ||
2327 | intel_sdvo_connector->name->values[0] = 0; \ | ||
2328 | intel_sdvo_connector->name->values[1] = data_value[0]; \ | ||
2329 | drm_connector_attach_property(connector, \ | ||
2330 | intel_sdvo_connector->name, \ | ||
2331 | intel_sdvo_connector->cur_##name); \ | ||
2332 | DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ | ||
2333 | data_value[0], data_value[1], response); \ | ||
2334 | } \ | ||
2335 | } while(0) | ||
2336 | |||
2337 | static bool | ||
2338 | intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, | ||
2339 | struct intel_sdvo_connector *intel_sdvo_connector, | ||
2340 | struct intel_sdvo_enhancements_reply enhancements) | ||
2456 | { | 2341 | { |
2457 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 2342 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
2458 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 2343 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
2459 | struct intel_connector *intel_connector = to_intel_connector(connector); | ||
2460 | struct intel_sdvo_connector *sdvo_priv = intel_connector->dev_priv; | ||
2461 | struct intel_sdvo_enhancements_reply sdvo_data; | ||
2462 | struct drm_device *dev = connector->dev; | ||
2463 | uint8_t status; | ||
2464 | uint16_t response, data_value[2]; | 2344 | uint16_t response, data_value[2]; |
2465 | 2345 | ||
2466 | intel_sdvo_write_cmd(intel_encoder, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, | 2346 | /* when horizontal overscan is supported, Add the left/right property */ |
2467 | NULL, 0); | 2347 | if (enhancements.overscan_h) { |
2468 | status = intel_sdvo_read_response(intel_encoder, &sdvo_data, | 2348 | if (!intel_sdvo_get_value(intel_sdvo, |
2469 | sizeof(sdvo_data)); | 2349 | SDVO_CMD_GET_MAX_OVERSCAN_H, |
2470 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2350 | &data_value, 4)) |
2471 | DRM_DEBUG_KMS(" incorrect response is returned\n"); | 2351 | return false; |
2472 | return; | 2352 | |
2353 | if (!intel_sdvo_get_value(intel_sdvo, | ||
2354 | SDVO_CMD_GET_OVERSCAN_H, | ||
2355 | &response, 2)) | ||
2356 | return false; | ||
2357 | |||
2358 | intel_sdvo_connector->max_hscan = data_value[0]; | ||
2359 | intel_sdvo_connector->left_margin = data_value[0] - response; | ||
2360 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; | ||
2361 | intel_sdvo_connector->left = | ||
2362 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2363 | "left_margin", 2); | ||
2364 | if (!intel_sdvo_connector->left) | ||
2365 | return false; | ||
2366 | |||
2367 | intel_sdvo_connector->left->values[0] = 0; | ||
2368 | intel_sdvo_connector->left->values[1] = data_value[0]; | ||
2369 | drm_connector_attach_property(connector, | ||
2370 | intel_sdvo_connector->left, | ||
2371 | intel_sdvo_connector->left_margin); | ||
2372 | |||
2373 | intel_sdvo_connector->right = | ||
2374 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2375 | "right_margin", 2); | ||
2376 | if (!intel_sdvo_connector->right) | ||
2377 | return false; | ||
2378 | |||
2379 | intel_sdvo_connector->right->values[0] = 0; | ||
2380 | intel_sdvo_connector->right->values[1] = data_value[0]; | ||
2381 | drm_connector_attach_property(connector, | ||
2382 | intel_sdvo_connector->right, | ||
2383 | intel_sdvo_connector->right_margin); | ||
2384 | DRM_DEBUG_KMS("h_overscan: max %d, " | ||
2385 | "default %d, current %d\n", | ||
2386 | data_value[0], data_value[1], response); | ||
2473 | } | 2387 | } |
2474 | response = *((uint16_t *)&sdvo_data); | 2388 | |
2475 | if (!response) { | 2389 | if (enhancements.overscan_v) { |
2476 | DRM_DEBUG_KMS("No enhancement is supported\n"); | 2390 | if (!intel_sdvo_get_value(intel_sdvo, |
2477 | return; | 2391 | SDVO_CMD_GET_MAX_OVERSCAN_V, |
2392 | &data_value, 4)) | ||
2393 | return false; | ||
2394 | |||
2395 | if (!intel_sdvo_get_value(intel_sdvo, | ||
2396 | SDVO_CMD_GET_OVERSCAN_V, | ||
2397 | &response, 2)) | ||
2398 | return false; | ||
2399 | |||
2400 | intel_sdvo_connector->max_vscan = data_value[0]; | ||
2401 | intel_sdvo_connector->top_margin = data_value[0] - response; | ||
2402 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; | ||
2403 | intel_sdvo_connector->top = | ||
2404 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2405 | "top_margin", 2); | ||
2406 | if (!intel_sdvo_connector->top) | ||
2407 | return false; | ||
2408 | |||
2409 | intel_sdvo_connector->top->values[0] = 0; | ||
2410 | intel_sdvo_connector->top->values[1] = data_value[0]; | ||
2411 | drm_connector_attach_property(connector, | ||
2412 | intel_sdvo_connector->top, | ||
2413 | intel_sdvo_connector->top_margin); | ||
2414 | |||
2415 | intel_sdvo_connector->bottom = | ||
2416 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2417 | "bottom_margin", 2); | ||
2418 | if (!intel_sdvo_connector->bottom) | ||
2419 | return false; | ||
2420 | |||
2421 | intel_sdvo_connector->bottom->values[0] = 0; | ||
2422 | intel_sdvo_connector->bottom->values[1] = data_value[0]; | ||
2423 | drm_connector_attach_property(connector, | ||
2424 | intel_sdvo_connector->bottom, | ||
2425 | intel_sdvo_connector->bottom_margin); | ||
2426 | DRM_DEBUG_KMS("v_overscan: max %d, " | ||
2427 | "default %d, current %d\n", | ||
2428 | data_value[0], data_value[1], response); | ||
2478 | } | 2429 | } |
2479 | if (IS_TV(sdvo_priv)) { | 2430 | |
2480 | /* when horizontal overscan is supported, Add the left/right | 2431 | ENHANCEMENT(hpos, HPOS); |
2481 | * property | 2432 | ENHANCEMENT(vpos, VPOS); |
2482 | */ | 2433 | ENHANCEMENT(saturation, SATURATION); |
2483 | if (sdvo_data.overscan_h) { | 2434 | ENHANCEMENT(contrast, CONTRAST); |
2484 | intel_sdvo_write_cmd(intel_encoder, | 2435 | ENHANCEMENT(hue, HUE); |
2485 | SDVO_CMD_GET_MAX_OVERSCAN_H, NULL, 0); | 2436 | ENHANCEMENT(sharpness, SHARPNESS); |
2486 | status = intel_sdvo_read_response(intel_encoder, | 2437 | ENHANCEMENT(brightness, BRIGHTNESS); |
2487 | &data_value, 4); | 2438 | ENHANCEMENT(flicker_filter, FLICKER_FILTER); |
2488 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2439 | ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); |
2489 | DRM_DEBUG_KMS("Incorrect SDVO max " | 2440 | ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D); |
2490 | "h_overscan\n"); | 2441 | ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); |
2491 | return; | 2442 | ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); |
2492 | } | 2443 | |
2493 | intel_sdvo_write_cmd(intel_encoder, | 2444 | if (enhancements.dot_crawl) { |
2494 | SDVO_CMD_GET_OVERSCAN_H, NULL, 0); | 2445 | if (!intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2)) |
2495 | status = intel_sdvo_read_response(intel_encoder, | 2446 | return false; |
2496 | &response, 2); | 2447 | |
2497 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2448 | intel_sdvo_connector->max_dot_crawl = 1; |
2498 | DRM_DEBUG_KMS("Incorrect SDVO h_overscan\n"); | 2449 | intel_sdvo_connector->cur_dot_crawl = response & 0x1; |
2499 | return; | 2450 | intel_sdvo_connector->dot_crawl = |
2500 | } | 2451 | drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); |
2501 | sdvo_priv->max_hscan = data_value[0]; | 2452 | if (!intel_sdvo_connector->dot_crawl) |
2502 | sdvo_priv->left_margin = data_value[0] - response; | 2453 | return false; |
2503 | sdvo_priv->right_margin = sdvo_priv->left_margin; | 2454 | |
2504 | sdvo_priv->left_property = | 2455 | intel_sdvo_connector->dot_crawl->values[0] = 0; |
2505 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2456 | intel_sdvo_connector->dot_crawl->values[1] = 1; |
2506 | "left_margin", 2); | 2457 | drm_connector_attach_property(connector, |
2507 | sdvo_priv->left_property->values[0] = 0; | 2458 | intel_sdvo_connector->dot_crawl, |
2508 | sdvo_priv->left_property->values[1] = data_value[0]; | 2459 | intel_sdvo_connector->cur_dot_crawl); |
2509 | drm_connector_attach_property(connector, | 2460 | DRM_DEBUG_KMS("dot crawl: current %d\n", response); |
2510 | sdvo_priv->left_property, | ||
2511 | sdvo_priv->left_margin); | ||
2512 | sdvo_priv->right_property = | ||
2513 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2514 | "right_margin", 2); | ||
2515 | sdvo_priv->right_property->values[0] = 0; | ||
2516 | sdvo_priv->right_property->values[1] = data_value[0]; | ||
2517 | drm_connector_attach_property(connector, | ||
2518 | sdvo_priv->right_property, | ||
2519 | sdvo_priv->right_margin); | ||
2520 | DRM_DEBUG_KMS("h_overscan: max %d, " | ||
2521 | "default %d, current %d\n", | ||
2522 | data_value[0], data_value[1], response); | ||
2523 | } | ||
2524 | if (sdvo_data.overscan_v) { | ||
2525 | intel_sdvo_write_cmd(intel_encoder, | ||
2526 | SDVO_CMD_GET_MAX_OVERSCAN_V, NULL, 0); | ||
2527 | status = intel_sdvo_read_response(intel_encoder, | ||
2528 | &data_value, 4); | ||
2529 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2530 | DRM_DEBUG_KMS("Incorrect SDVO max " | ||
2531 | "v_overscan\n"); | ||
2532 | return; | ||
2533 | } | ||
2534 | intel_sdvo_write_cmd(intel_encoder, | ||
2535 | SDVO_CMD_GET_OVERSCAN_V, NULL, 0); | ||
2536 | status = intel_sdvo_read_response(intel_encoder, | ||
2537 | &response, 2); | ||
2538 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2539 | DRM_DEBUG_KMS("Incorrect SDVO v_overscan\n"); | ||
2540 | return; | ||
2541 | } | ||
2542 | sdvo_priv->max_vscan = data_value[0]; | ||
2543 | sdvo_priv->top_margin = data_value[0] - response; | ||
2544 | sdvo_priv->bottom_margin = sdvo_priv->top_margin; | ||
2545 | sdvo_priv->top_property = | ||
2546 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2547 | "top_margin", 2); | ||
2548 | sdvo_priv->top_property->values[0] = 0; | ||
2549 | sdvo_priv->top_property->values[1] = data_value[0]; | ||
2550 | drm_connector_attach_property(connector, | ||
2551 | sdvo_priv->top_property, | ||
2552 | sdvo_priv->top_margin); | ||
2553 | sdvo_priv->bottom_property = | ||
2554 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2555 | "bottom_margin", 2); | ||
2556 | sdvo_priv->bottom_property->values[0] = 0; | ||
2557 | sdvo_priv->bottom_property->values[1] = data_value[0]; | ||
2558 | drm_connector_attach_property(connector, | ||
2559 | sdvo_priv->bottom_property, | ||
2560 | sdvo_priv->bottom_margin); | ||
2561 | DRM_DEBUG_KMS("v_overscan: max %d, " | ||
2562 | "default %d, current %d\n", | ||
2563 | data_value[0], data_value[1], response); | ||
2564 | } | ||
2565 | if (sdvo_data.position_h) { | ||
2566 | intel_sdvo_write_cmd(intel_encoder, | ||
2567 | SDVO_CMD_GET_MAX_POSITION_H, NULL, 0); | ||
2568 | status = intel_sdvo_read_response(intel_encoder, | ||
2569 | &data_value, 4); | ||
2570 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2571 | DRM_DEBUG_KMS("Incorrect SDVO Max h_pos\n"); | ||
2572 | return; | ||
2573 | } | ||
2574 | intel_sdvo_write_cmd(intel_encoder, | ||
2575 | SDVO_CMD_GET_POSITION_H, NULL, 0); | ||
2576 | status = intel_sdvo_read_response(intel_encoder, | ||
2577 | &response, 2); | ||
2578 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2579 | DRM_DEBUG_KMS("Incorrect SDVO get h_postion\n"); | ||
2580 | return; | ||
2581 | } | ||
2582 | sdvo_priv->max_hpos = data_value[0]; | ||
2583 | sdvo_priv->cur_hpos = response; | ||
2584 | sdvo_priv->hpos_property = | ||
2585 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2586 | "hpos", 2); | ||
2587 | sdvo_priv->hpos_property->values[0] = 0; | ||
2588 | sdvo_priv->hpos_property->values[1] = data_value[0]; | ||
2589 | drm_connector_attach_property(connector, | ||
2590 | sdvo_priv->hpos_property, | ||
2591 | sdvo_priv->cur_hpos); | ||
2592 | DRM_DEBUG_KMS("h_position: max %d, " | ||
2593 | "default %d, current %d\n", | ||
2594 | data_value[0], data_value[1], response); | ||
2595 | } | ||
2596 | if (sdvo_data.position_v) { | ||
2597 | intel_sdvo_write_cmd(intel_encoder, | ||
2598 | SDVO_CMD_GET_MAX_POSITION_V, NULL, 0); | ||
2599 | status = intel_sdvo_read_response(intel_encoder, | ||
2600 | &data_value, 4); | ||
2601 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2602 | DRM_DEBUG_KMS("Incorrect SDVO Max v_pos\n"); | ||
2603 | return; | ||
2604 | } | ||
2605 | intel_sdvo_write_cmd(intel_encoder, | ||
2606 | SDVO_CMD_GET_POSITION_V, NULL, 0); | ||
2607 | status = intel_sdvo_read_response(intel_encoder, | ||
2608 | &response, 2); | ||
2609 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2610 | DRM_DEBUG_KMS("Incorrect SDVO get v_postion\n"); | ||
2611 | return; | ||
2612 | } | ||
2613 | sdvo_priv->max_vpos = data_value[0]; | ||
2614 | sdvo_priv->cur_vpos = response; | ||
2615 | sdvo_priv->vpos_property = | ||
2616 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2617 | "vpos", 2); | ||
2618 | sdvo_priv->vpos_property->values[0] = 0; | ||
2619 | sdvo_priv->vpos_property->values[1] = data_value[0]; | ||
2620 | drm_connector_attach_property(connector, | ||
2621 | sdvo_priv->vpos_property, | ||
2622 | sdvo_priv->cur_vpos); | ||
2623 | DRM_DEBUG_KMS("v_position: max %d, " | ||
2624 | "default %d, current %d\n", | ||
2625 | data_value[0], data_value[1], response); | ||
2626 | } | ||
2627 | if (sdvo_data.saturation) { | ||
2628 | intel_sdvo_write_cmd(intel_encoder, | ||
2629 | SDVO_CMD_GET_MAX_SATURATION, NULL, 0); | ||
2630 | status = intel_sdvo_read_response(intel_encoder, | ||
2631 | &data_value, 4); | ||
2632 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2633 | DRM_DEBUG_KMS("Incorrect SDVO Max sat\n"); | ||
2634 | return; | ||
2635 | } | ||
2636 | intel_sdvo_write_cmd(intel_encoder, | ||
2637 | SDVO_CMD_GET_SATURATION, NULL, 0); | ||
2638 | status = intel_sdvo_read_response(intel_encoder, | ||
2639 | &response, 2); | ||
2640 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2641 | DRM_DEBUG_KMS("Incorrect SDVO get sat\n"); | ||
2642 | return; | ||
2643 | } | ||
2644 | sdvo_priv->max_saturation = data_value[0]; | ||
2645 | sdvo_priv->cur_saturation = response; | ||
2646 | sdvo_priv->saturation_property = | ||
2647 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2648 | "saturation", 2); | ||
2649 | sdvo_priv->saturation_property->values[0] = 0; | ||
2650 | sdvo_priv->saturation_property->values[1] = | ||
2651 | data_value[0]; | ||
2652 | drm_connector_attach_property(connector, | ||
2653 | sdvo_priv->saturation_property, | ||
2654 | sdvo_priv->cur_saturation); | ||
2655 | DRM_DEBUG_KMS("saturation: max %d, " | ||
2656 | "default %d, current %d\n", | ||
2657 | data_value[0], data_value[1], response); | ||
2658 | } | ||
2659 | if (sdvo_data.contrast) { | ||
2660 | intel_sdvo_write_cmd(intel_encoder, | ||
2661 | SDVO_CMD_GET_MAX_CONTRAST, NULL, 0); | ||
2662 | status = intel_sdvo_read_response(intel_encoder, | ||
2663 | &data_value, 4); | ||
2664 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2665 | DRM_DEBUG_KMS("Incorrect SDVO Max contrast\n"); | ||
2666 | return; | ||
2667 | } | ||
2668 | intel_sdvo_write_cmd(intel_encoder, | ||
2669 | SDVO_CMD_GET_CONTRAST, NULL, 0); | ||
2670 | status = intel_sdvo_read_response(intel_encoder, | ||
2671 | &response, 2); | ||
2672 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2673 | DRM_DEBUG_KMS("Incorrect SDVO get contrast\n"); | ||
2674 | return; | ||
2675 | } | ||
2676 | sdvo_priv->max_contrast = data_value[0]; | ||
2677 | sdvo_priv->cur_contrast = response; | ||
2678 | sdvo_priv->contrast_property = | ||
2679 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2680 | "contrast", 2); | ||
2681 | sdvo_priv->contrast_property->values[0] = 0; | ||
2682 | sdvo_priv->contrast_property->values[1] = data_value[0]; | ||
2683 | drm_connector_attach_property(connector, | ||
2684 | sdvo_priv->contrast_property, | ||
2685 | sdvo_priv->cur_contrast); | ||
2686 | DRM_DEBUG_KMS("contrast: max %d, " | ||
2687 | "default %d, current %d\n", | ||
2688 | data_value[0], data_value[1], response); | ||
2689 | } | ||
2690 | if (sdvo_data.hue) { | ||
2691 | intel_sdvo_write_cmd(intel_encoder, | ||
2692 | SDVO_CMD_GET_MAX_HUE, NULL, 0); | ||
2693 | status = intel_sdvo_read_response(intel_encoder, | ||
2694 | &data_value, 4); | ||
2695 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2696 | DRM_DEBUG_KMS("Incorrect SDVO Max hue\n"); | ||
2697 | return; | ||
2698 | } | ||
2699 | intel_sdvo_write_cmd(intel_encoder, | ||
2700 | SDVO_CMD_GET_HUE, NULL, 0); | ||
2701 | status = intel_sdvo_read_response(intel_encoder, | ||
2702 | &response, 2); | ||
2703 | if (status != SDVO_CMD_STATUS_SUCCESS) { | ||
2704 | DRM_DEBUG_KMS("Incorrect SDVO get hue\n"); | ||
2705 | return; | ||
2706 | } | ||
2707 | sdvo_priv->max_hue = data_value[0]; | ||
2708 | sdvo_priv->cur_hue = response; | ||
2709 | sdvo_priv->hue_property = | ||
2710 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | ||
2711 | "hue", 2); | ||
2712 | sdvo_priv->hue_property->values[0] = 0; | ||
2713 | sdvo_priv->hue_property->values[1] = | ||
2714 | data_value[0]; | ||
2715 | drm_connector_attach_property(connector, | ||
2716 | sdvo_priv->hue_property, | ||
2717 | sdvo_priv->cur_hue); | ||
2718 | DRM_DEBUG_KMS("hue: max %d, default %d, current %d\n", | ||
2719 | data_value[0], data_value[1], response); | ||
2720 | } | ||
2721 | } | 2461 | } |
2722 | if (IS_TV(sdvo_priv) || IS_LVDS(sdvo_priv)) { | 2462 | |
2723 | if (sdvo_data.brightness) { | 2463 | return true; |
2724 | intel_sdvo_write_cmd(intel_encoder, | 2464 | } |
2725 | SDVO_CMD_GET_MAX_BRIGHTNESS, NULL, 0); | 2465 | |
2726 | status = intel_sdvo_read_response(intel_encoder, | 2466 | static bool |
2727 | &data_value, 4); | 2467 | intel_sdvo_create_enhance_property_lvds(struct intel_sdvo *intel_sdvo, |
2728 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2468 | struct intel_sdvo_connector *intel_sdvo_connector, |
2729 | DRM_DEBUG_KMS("Incorrect SDVO Max bright\n"); | 2469 | struct intel_sdvo_enhancements_reply enhancements) |
2730 | return; | 2470 | { |
2731 | } | 2471 | struct drm_device *dev = intel_sdvo->base.enc.dev; |
2732 | intel_sdvo_write_cmd(intel_encoder, | 2472 | struct drm_connector *connector = &intel_sdvo_connector->base.base; |
2733 | SDVO_CMD_GET_BRIGHTNESS, NULL, 0); | 2473 | uint16_t response, data_value[2]; |
2734 | status = intel_sdvo_read_response(intel_encoder, | 2474 | |
2735 | &response, 2); | 2475 | ENHANCEMENT(brightness, BRIGHTNESS); |
2736 | if (status != SDVO_CMD_STATUS_SUCCESS) { | 2476 | |
2737 | DRM_DEBUG_KMS("Incorrect SDVO get brigh\n"); | 2477 | return true; |
2738 | return; | 2478 | } |
2739 | } | 2479 | #undef ENHANCEMENT |
2740 | sdvo_priv->max_brightness = data_value[0]; | 2480 | |
2741 | sdvo_priv->cur_brightness = response; | 2481 | static bool intel_sdvo_create_enhance_property(struct intel_sdvo *intel_sdvo, |
2742 | sdvo_priv->brightness_property = | 2482 | struct intel_sdvo_connector *intel_sdvo_connector) |
2743 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2483 | { |
2744 | "brightness", 2); | 2484 | union { |
2745 | sdvo_priv->brightness_property->values[0] = 0; | 2485 | struct intel_sdvo_enhancements_reply reply; |
2746 | sdvo_priv->brightness_property->values[1] = | 2486 | uint16_t response; |
2747 | data_value[0]; | 2487 | } enhancements; |
2748 | drm_connector_attach_property(connector, | 2488 | |
2749 | sdvo_priv->brightness_property, | 2489 | if (!intel_sdvo_get_value(intel_sdvo, |
2750 | sdvo_priv->cur_brightness); | 2490 | SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, |
2751 | DRM_DEBUG_KMS("brightness: max %d, " | 2491 | &enhancements, sizeof(enhancements))) |
2752 | "default %d, current %d\n", | 2492 | return false; |
2753 | data_value[0], data_value[1], response); | 2493 | |
2754 | } | 2494 | if (enhancements.response == 0) { |
2495 | DRM_DEBUG_KMS("No enhancement is supported\n"); | ||
2496 | return true; | ||
2755 | } | 2497 | } |
2756 | return; | 2498 | |
2499 | if (IS_TV(intel_sdvo_connector)) | ||
2500 | return intel_sdvo_create_enhance_property_tv(intel_sdvo, intel_sdvo_connector, enhancements.reply); | ||
2501 | else if(IS_LVDS(intel_sdvo_connector)) | ||
2502 | return intel_sdvo_create_enhance_property_lvds(intel_sdvo, intel_sdvo_connector, enhancements.reply); | ||
2503 | else | ||
2504 | return true; | ||
2505 | |||
2757 | } | 2506 | } |
2758 | 2507 | ||
2759 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | 2508 | bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) |
2760 | { | 2509 | { |
2761 | struct drm_i915_private *dev_priv = dev->dev_private; | 2510 | struct drm_i915_private *dev_priv = dev->dev_private; |
2762 | struct intel_encoder *intel_encoder; | 2511 | struct intel_encoder *intel_encoder; |
2763 | struct intel_sdvo_priv *sdvo_priv; | 2512 | struct intel_sdvo *intel_sdvo; |
2764 | u8 ch[0x40]; | 2513 | u8 ch[0x40]; |
2765 | int i; | 2514 | int i; |
2766 | u32 i2c_reg, ddc_reg, analog_ddc_reg; | 2515 | u32 i2c_reg, ddc_reg, analog_ddc_reg; |
2767 | 2516 | ||
2768 | intel_encoder = kcalloc(sizeof(struct intel_encoder)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 2517 | intel_sdvo = kzalloc(sizeof(struct intel_sdvo), GFP_KERNEL); |
2769 | if (!intel_encoder) { | 2518 | if (!intel_sdvo) |
2770 | return false; | 2519 | return false; |
2771 | } | ||
2772 | 2520 | ||
2773 | sdvo_priv = (struct intel_sdvo_priv *)(intel_encoder + 1); | 2521 | intel_sdvo->sdvo_reg = sdvo_reg; |
2774 | sdvo_priv->sdvo_reg = sdvo_reg; | ||
2775 | 2522 | ||
2776 | intel_encoder->dev_priv = sdvo_priv; | 2523 | intel_encoder = &intel_sdvo->base; |
2777 | intel_encoder->type = INTEL_OUTPUT_SDVO; | 2524 | intel_encoder->type = INTEL_OUTPUT_SDVO; |
2778 | 2525 | ||
2779 | if (HAS_PCH_SPLIT(dev)) { | 2526 | if (HAS_PCH_SPLIT(dev)) { |
@@ -2795,14 +2542,14 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2795 | if (!intel_encoder->i2c_bus) | 2542 | if (!intel_encoder->i2c_bus) |
2796 | goto err_inteloutput; | 2543 | goto err_inteloutput; |
2797 | 2544 | ||
2798 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); | 2545 | intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg); |
2799 | 2546 | ||
2800 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ | 2547 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
2801 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; | 2548 | intel_sdvo_i2c_bit_algo.functionality = intel_encoder->i2c_bus->algo->functionality; |
2802 | 2549 | ||
2803 | /* Read the regs to test if we can talk to the device */ | 2550 | /* Read the regs to test if we can talk to the device */ |
2804 | for (i = 0; i < 0x40; i++) { | 2551 | for (i = 0; i < 0x40; i++) { |
2805 | if (!intel_sdvo_read_byte(intel_encoder, i, &ch[i])) { | 2552 | if (!intel_sdvo_read_byte(intel_sdvo, i, &ch[i])) { |
2806 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", | 2553 | DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", |
2807 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2554 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2808 | goto err_i2c; | 2555 | goto err_i2c; |
@@ -2812,17 +2559,16 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2812 | /* setup the DDC bus. */ | 2559 | /* setup the DDC bus. */ |
2813 | if (IS_SDVOB(sdvo_reg)) { | 2560 | if (IS_SDVOB(sdvo_reg)) { |
2814 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); | 2561 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOB DDC BUS"); |
2815 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | 2562 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2816 | "SDVOB/VGA DDC BUS"); | 2563 | "SDVOB/VGA DDC BUS"); |
2817 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; | 2564 | dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; |
2818 | } else { | 2565 | } else { |
2819 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); | 2566 | intel_encoder->ddc_bus = intel_i2c_create(dev, ddc_reg, "SDVOC DDC BUS"); |
2820 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, | 2567 | intel_sdvo->analog_ddc_bus = intel_i2c_create(dev, analog_ddc_reg, |
2821 | "SDVOC/VGA DDC BUS"); | 2568 | "SDVOC/VGA DDC BUS"); |
2822 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; | 2569 | dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; |
2823 | } | 2570 | } |
2824 | 2571 | if (intel_encoder->ddc_bus == NULL || intel_sdvo->analog_ddc_bus == NULL) | |
2825 | if (intel_encoder->ddc_bus == NULL) | ||
2826 | goto err_i2c; | 2572 | goto err_i2c; |
2827 | 2573 | ||
2828 | /* Wrap with our custom algo which switches to DDC mode */ | 2574 | /* Wrap with our custom algo which switches to DDC mode */ |
@@ -2833,53 +2579,56 @@ bool intel_sdvo_init(struct drm_device *dev, int sdvo_reg) | |||
2833 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); | 2579 | drm_encoder_helper_add(&intel_encoder->enc, &intel_sdvo_helper_funcs); |
2834 | 2580 | ||
2835 | /* In default case sdvo lvds is false */ | 2581 | /* In default case sdvo lvds is false */ |
2836 | intel_sdvo_get_capabilities(intel_encoder, &sdvo_priv->caps); | 2582 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
2583 | goto err_enc; | ||
2837 | 2584 | ||
2838 | if (intel_sdvo_output_setup(intel_encoder, | 2585 | if (intel_sdvo_output_setup(intel_sdvo, |
2839 | sdvo_priv->caps.output_flags) != true) { | 2586 | intel_sdvo->caps.output_flags) != true) { |
2840 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", | 2587 | DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", |
2841 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); | 2588 | IS_SDVOB(sdvo_reg) ? 'B' : 'C'); |
2842 | goto err_i2c; | 2589 | goto err_enc; |
2843 | } | 2590 | } |
2844 | 2591 | ||
2845 | intel_sdvo_select_ddc_bus(dev_priv, sdvo_priv, sdvo_reg); | 2592 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
2846 | 2593 | ||
2847 | /* Set the input timing to the screen. Assume always input 0. */ | 2594 | /* Set the input timing to the screen. Assume always input 0. */ |
2848 | intel_sdvo_set_target_input(intel_encoder, true, false); | 2595 | if (!intel_sdvo_set_target_input(intel_sdvo)) |
2849 | 2596 | goto err_enc; | |
2850 | intel_sdvo_get_input_pixel_clock_range(intel_encoder, | ||
2851 | &sdvo_priv->pixel_clock_min, | ||
2852 | &sdvo_priv->pixel_clock_max); | ||
2853 | 2597 | ||
2598 | if (!intel_sdvo_get_input_pixel_clock_range(intel_sdvo, | ||
2599 | &intel_sdvo->pixel_clock_min, | ||
2600 | &intel_sdvo->pixel_clock_max)) | ||
2601 | goto err_enc; | ||
2854 | 2602 | ||
2855 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " | 2603 | DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " |
2856 | "clock range %dMHz - %dMHz, " | 2604 | "clock range %dMHz - %dMHz, " |
2857 | "input 1: %c, input 2: %c, " | 2605 | "input 1: %c, input 2: %c, " |
2858 | "output 1: %c, output 2: %c\n", | 2606 | "output 1: %c, output 2: %c\n", |
2859 | SDVO_NAME(sdvo_priv), | 2607 | SDVO_NAME(intel_sdvo), |
2860 | sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id, | 2608 | intel_sdvo->caps.vendor_id, intel_sdvo->caps.device_id, |
2861 | sdvo_priv->caps.device_rev_id, | 2609 | intel_sdvo->caps.device_rev_id, |
2862 | sdvo_priv->pixel_clock_min / 1000, | 2610 | intel_sdvo->pixel_clock_min / 1000, |
2863 | sdvo_priv->pixel_clock_max / 1000, | 2611 | intel_sdvo->pixel_clock_max / 1000, |
2864 | (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', | 2612 | (intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', |
2865 | (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', | 2613 | (intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', |
2866 | /* check currently supported outputs */ | 2614 | /* check currently supported outputs */ |
2867 | sdvo_priv->caps.output_flags & | 2615 | intel_sdvo->caps.output_flags & |
2868 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', | 2616 | (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', |
2869 | sdvo_priv->caps.output_flags & | 2617 | intel_sdvo->caps.output_flags & |
2870 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 2618 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
2871 | |||
2872 | return true; | 2619 | return true; |
2873 | 2620 | ||
2621 | err_enc: | ||
2622 | drm_encoder_cleanup(&intel_encoder->enc); | ||
2874 | err_i2c: | 2623 | err_i2c: |
2875 | if (sdvo_priv->analog_ddc_bus != NULL) | 2624 | if (intel_sdvo->analog_ddc_bus != NULL) |
2876 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | 2625 | intel_i2c_destroy(intel_sdvo->analog_ddc_bus); |
2877 | if (intel_encoder->ddc_bus != NULL) | 2626 | if (intel_encoder->ddc_bus != NULL) |
2878 | intel_i2c_destroy(intel_encoder->ddc_bus); | 2627 | intel_i2c_destroy(intel_encoder->ddc_bus); |
2879 | if (intel_encoder->i2c_bus != NULL) | 2628 | if (intel_encoder->i2c_bus != NULL) |
2880 | intel_i2c_destroy(intel_encoder->i2c_bus); | 2629 | intel_i2c_destroy(intel_encoder->i2c_bus); |
2881 | err_inteloutput: | 2630 | err_inteloutput: |
2882 | kfree(intel_encoder); | 2631 | kfree(intel_sdvo); |
2883 | 2632 | ||
2884 | return false; | 2633 | return false; |
2885 | } | 2634 | } |
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h index ba5cdf8ae40b..a386b022e538 100644 --- a/drivers/gpu/drm/i915/intel_sdvo_regs.h +++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h | |||
@@ -312,7 +312,7 @@ struct intel_sdvo_set_target_input_args { | |||
312 | # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) | 312 | # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) |
313 | 313 | ||
314 | #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 | 314 | #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 |
315 | /** 5 bytes of bit flags for TV formats shared by all TV format functions */ | 315 | /** 6 bytes of bit flags for TV formats shared by all TV format functions */ |
316 | struct intel_sdvo_tv_format { | 316 | struct intel_sdvo_tv_format { |
317 | unsigned int ntsc_m:1; | 317 | unsigned int ntsc_m:1; |
318 | unsigned int ntsc_j:1; | 318 | unsigned int ntsc_j:1; |
@@ -596,32 +596,32 @@ struct intel_sdvo_enhancements_reply { | |||
596 | unsigned int overscan_h:1; | 596 | unsigned int overscan_h:1; |
597 | 597 | ||
598 | unsigned int overscan_v:1; | 598 | unsigned int overscan_v:1; |
599 | unsigned int position_h:1; | 599 | unsigned int hpos:1; |
600 | unsigned int position_v:1; | 600 | unsigned int vpos:1; |
601 | unsigned int sharpness:1; | 601 | unsigned int sharpness:1; |
602 | unsigned int dot_crawl:1; | 602 | unsigned int dot_crawl:1; |
603 | unsigned int dither:1; | 603 | unsigned int dither:1; |
604 | unsigned int max_tv_chroma_filter:1; | 604 | unsigned int tv_chroma_filter:1; |
605 | unsigned int max_tv_luma_filter:1; | 605 | unsigned int tv_luma_filter:1; |
606 | } __attribute__((packed)); | 606 | } __attribute__((packed)); |
607 | 607 | ||
608 | /* Picture enhancement limits below are dependent on the current TV format, | 608 | /* Picture enhancement limits below are dependent on the current TV format, |
609 | * and thus need to be queried and set after it. | 609 | * and thus need to be queried and set after it. |
610 | */ | 610 | */ |
611 | #define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d | 611 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d |
612 | #define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b | 612 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b |
613 | #define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52 | 613 | #define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52 |
614 | #define SDVO_CMD_GET_MAX_SATURATION 0x55 | 614 | #define SDVO_CMD_GET_MAX_SATURATION 0x55 |
615 | #define SDVO_CMD_GET_MAX_HUE 0x58 | 615 | #define SDVO_CMD_GET_MAX_HUE 0x58 |
616 | #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b | 616 | #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b |
617 | #define SDVO_CMD_GET_MAX_CONTRAST 0x5e | 617 | #define SDVO_CMD_GET_MAX_CONTRAST 0x5e |
618 | #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 | 618 | #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 |
619 | #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 | 619 | #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 |
620 | #define SDVO_CMD_GET_MAX_POSITION_H 0x67 | 620 | #define SDVO_CMD_GET_MAX_HPOS 0x67 |
621 | #define SDVO_CMD_GET_MAX_POSITION_V 0x6a | 621 | #define SDVO_CMD_GET_MAX_VPOS 0x6a |
622 | #define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d | 622 | #define SDVO_CMD_GET_MAX_SHARPNESS 0x6d |
623 | #define SDVO_CMD_GET_MAX_TV_CHROMA 0x74 | 623 | #define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74 |
624 | #define SDVO_CMD_GET_MAX_TV_LUMA 0x77 | 624 | #define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77 |
625 | struct intel_sdvo_enhancement_limits_reply { | 625 | struct intel_sdvo_enhancement_limits_reply { |
626 | u16 max_value; | 626 | u16 max_value; |
627 | u16 default_value; | 627 | u16 default_value; |
@@ -638,10 +638,10 @@ struct intel_sdvo_enhancement_limits_reply { | |||
638 | 638 | ||
639 | #define SDVO_CMD_GET_FLICKER_FILTER 0x4e | 639 | #define SDVO_CMD_GET_FLICKER_FILTER 0x4e |
640 | #define SDVO_CMD_SET_FLICKER_FILTER 0x4f | 640 | #define SDVO_CMD_SET_FLICKER_FILTER 0x4f |
641 | #define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50 | 641 | #define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50 |
642 | #define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51 | 642 | #define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51 |
643 | #define SDVO_CMD_GET_2D_FLICKER_FITER 0x53 | 643 | #define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53 |
644 | #define SDVO_CMD_SET_2D_FLICKER_FITER 0x54 | 644 | #define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54 |
645 | #define SDVO_CMD_GET_SATURATION 0x56 | 645 | #define SDVO_CMD_GET_SATURATION 0x56 |
646 | #define SDVO_CMD_SET_SATURATION 0x57 | 646 | #define SDVO_CMD_SET_SATURATION 0x57 |
647 | #define SDVO_CMD_GET_HUE 0x59 | 647 | #define SDVO_CMD_GET_HUE 0x59 |
@@ -654,16 +654,16 @@ struct intel_sdvo_enhancement_limits_reply { | |||
654 | #define SDVO_CMD_SET_OVERSCAN_H 0x63 | 654 | #define SDVO_CMD_SET_OVERSCAN_H 0x63 |
655 | #define SDVO_CMD_GET_OVERSCAN_V 0x65 | 655 | #define SDVO_CMD_GET_OVERSCAN_V 0x65 |
656 | #define SDVO_CMD_SET_OVERSCAN_V 0x66 | 656 | #define SDVO_CMD_SET_OVERSCAN_V 0x66 |
657 | #define SDVO_CMD_GET_POSITION_H 0x68 | 657 | #define SDVO_CMD_GET_HPOS 0x68 |
658 | #define SDVO_CMD_SET_POSITION_H 0x69 | 658 | #define SDVO_CMD_SET_HPOS 0x69 |
659 | #define SDVO_CMD_GET_POSITION_V 0x6b | 659 | #define SDVO_CMD_GET_VPOS 0x6b |
660 | #define SDVO_CMD_SET_POSITION_V 0x6c | 660 | #define SDVO_CMD_SET_VPOS 0x6c |
661 | #define SDVO_CMD_GET_SHARPNESS 0x6e | 661 | #define SDVO_CMD_GET_SHARPNESS 0x6e |
662 | #define SDVO_CMD_SET_SHARPNESS 0x6f | 662 | #define SDVO_CMD_SET_SHARPNESS 0x6f |
663 | #define SDVO_CMD_GET_TV_CHROMA 0x75 | 663 | #define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75 |
664 | #define SDVO_CMD_SET_TV_CHROMA 0x76 | 664 | #define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76 |
665 | #define SDVO_CMD_GET_TV_LUMA 0x78 | 665 | #define SDVO_CMD_GET_TV_LUMA_FILTER 0x78 |
666 | #define SDVO_CMD_SET_TV_LUMA 0x79 | 666 | #define SDVO_CMD_SET_TV_LUMA_FILTER 0x79 |
667 | struct intel_sdvo_enhancements_arg { | 667 | struct intel_sdvo_enhancements_arg { |
668 | u16 value; | 668 | u16 value; |
669 | }__attribute__((packed)); | 669 | }__attribute__((packed)); |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index cc3726a4a1cb..d2029efee982 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -44,7 +44,9 @@ enum tv_margin { | |||
44 | }; | 44 | }; |
45 | 45 | ||
46 | /** Private structure for the integrated TV support */ | 46 | /** Private structure for the integrated TV support */ |
47 | struct intel_tv_priv { | 47 | struct intel_tv { |
48 | struct intel_encoder base; | ||
49 | |||
48 | int type; | 50 | int type; |
49 | char *tv_format; | 51 | char *tv_format; |
50 | int margin[4]; | 52 | int margin[4]; |
@@ -896,6 +898,11 @@ static const struct tv_mode tv_modes[] = { | |||
896 | }, | 898 | }, |
897 | }; | 899 | }; |
898 | 900 | ||
901 | static struct intel_tv *enc_to_intel_tv(struct drm_encoder *encoder) | ||
902 | { | ||
903 | return container_of(enc_to_intel_encoder(encoder), struct intel_tv, base); | ||
904 | } | ||
905 | |||
899 | static void | 906 | static void |
900 | intel_tv_dpms(struct drm_encoder *encoder, int mode) | 907 | intel_tv_dpms(struct drm_encoder *encoder, int mode) |
901 | { | 908 | { |
@@ -929,19 +936,17 @@ intel_tv_mode_lookup (char *tv_format) | |||
929 | } | 936 | } |
930 | 937 | ||
931 | static const struct tv_mode * | 938 | static const struct tv_mode * |
932 | intel_tv_mode_find (struct intel_encoder *intel_encoder) | 939 | intel_tv_mode_find (struct intel_tv *intel_tv) |
933 | { | 940 | { |
934 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 941 | return intel_tv_mode_lookup(intel_tv->tv_format); |
935 | |||
936 | return intel_tv_mode_lookup(tv_priv->tv_format); | ||
937 | } | 942 | } |
938 | 943 | ||
939 | static enum drm_mode_status | 944 | static enum drm_mode_status |
940 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) | 945 | intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) |
941 | { | 946 | { |
942 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 947 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
943 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 948 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
944 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 949 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
945 | 950 | ||
946 | /* Ensure TV refresh is close to desired refresh */ | 951 | /* Ensure TV refresh is close to desired refresh */ |
947 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) | 952 | if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode) * 1000) |
@@ -957,8 +962,8 @@ intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
957 | { | 962 | { |
958 | struct drm_device *dev = encoder->dev; | 963 | struct drm_device *dev = encoder->dev; |
959 | struct drm_mode_config *drm_config = &dev->mode_config; | 964 | struct drm_mode_config *drm_config = &dev->mode_config; |
960 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 965 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
961 | const struct tv_mode *tv_mode = intel_tv_mode_find (intel_encoder); | 966 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
962 | struct drm_encoder *other_encoder; | 967 | struct drm_encoder *other_encoder; |
963 | 968 | ||
964 | if (!tv_mode) | 969 | if (!tv_mode) |
@@ -983,9 +988,8 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
983 | struct drm_i915_private *dev_priv = dev->dev_private; | 988 | struct drm_i915_private *dev_priv = dev->dev_private; |
984 | struct drm_crtc *crtc = encoder->crtc; | 989 | struct drm_crtc *crtc = encoder->crtc; |
985 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 990 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
986 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 991 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
987 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 992 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
988 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
989 | u32 tv_ctl; | 993 | u32 tv_ctl; |
990 | u32 hctl1, hctl2, hctl3; | 994 | u32 hctl1, hctl2, hctl3; |
991 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; | 995 | u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; |
@@ -1001,7 +1005,7 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1001 | tv_ctl = I915_READ(TV_CTL); | 1005 | tv_ctl = I915_READ(TV_CTL); |
1002 | tv_ctl &= TV_CTL_SAVE; | 1006 | tv_ctl &= TV_CTL_SAVE; |
1003 | 1007 | ||
1004 | switch (tv_priv->type) { | 1008 | switch (intel_tv->type) { |
1005 | default: | 1009 | default: |
1006 | case DRM_MODE_CONNECTOR_Unknown: | 1010 | case DRM_MODE_CONNECTOR_Unknown: |
1007 | case DRM_MODE_CONNECTOR_Composite: | 1011 | case DRM_MODE_CONNECTOR_Composite: |
@@ -1154,11 +1158,11 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1154 | 1158 | ||
1155 | /* Wait for vblank for the disable to take effect */ | 1159 | /* Wait for vblank for the disable to take effect */ |
1156 | if (!IS_I9XX(dev)) | 1160 | if (!IS_I9XX(dev)) |
1157 | intel_wait_for_vblank(dev); | 1161 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1158 | 1162 | ||
1159 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); | 1163 | I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); |
1160 | /* Wait for vblank for the disable to take effect. */ | 1164 | /* Wait for vblank for the disable to take effect. */ |
1161 | intel_wait_for_vblank(dev); | 1165 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1162 | 1166 | ||
1163 | /* Filter ctl must be set before TV_WIN_SIZE */ | 1167 | /* Filter ctl must be set before TV_WIN_SIZE */ |
1164 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); | 1168 | I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE); |
@@ -1168,12 +1172,12 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1168 | else | 1172 | else |
1169 | ysize = 2*tv_mode->nbr_end + 1; | 1173 | ysize = 2*tv_mode->nbr_end + 1; |
1170 | 1174 | ||
1171 | xpos += tv_priv->margin[TV_MARGIN_LEFT]; | 1175 | xpos += intel_tv->margin[TV_MARGIN_LEFT]; |
1172 | ypos += tv_priv->margin[TV_MARGIN_TOP]; | 1176 | ypos += intel_tv->margin[TV_MARGIN_TOP]; |
1173 | xsize -= (tv_priv->margin[TV_MARGIN_LEFT] + | 1177 | xsize -= (intel_tv->margin[TV_MARGIN_LEFT] + |
1174 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1178 | intel_tv->margin[TV_MARGIN_RIGHT]); |
1175 | ysize -= (tv_priv->margin[TV_MARGIN_TOP] + | 1179 | ysize -= (intel_tv->margin[TV_MARGIN_TOP] + |
1176 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1180 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
1177 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); | 1181 | I915_WRITE(TV_WIN_POS, (xpos<<16)|ypos); |
1178 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); | 1182 | I915_WRITE(TV_WIN_SIZE, (xsize<<16)|ysize); |
1179 | 1183 | ||
@@ -1222,11 +1226,12 @@ static const struct drm_display_mode reported_modes[] = { | |||
1222 | * \return false if TV is disconnected. | 1226 | * \return false if TV is disconnected. |
1223 | */ | 1227 | */ |
1224 | static int | 1228 | static int |
1225 | intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder) | 1229 | intel_tv_detect_type (struct intel_tv *intel_tv) |
1226 | { | 1230 | { |
1227 | struct drm_encoder *encoder = &intel_encoder->enc; | 1231 | struct drm_encoder *encoder = &intel_tv->base.enc; |
1228 | struct drm_device *dev = encoder->dev; | 1232 | struct drm_device *dev = encoder->dev; |
1229 | struct drm_i915_private *dev_priv = dev->dev_private; | 1233 | struct drm_i915_private *dev_priv = dev->dev_private; |
1234 | struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc); | ||
1230 | unsigned long irqflags; | 1235 | unsigned long irqflags; |
1231 | u32 tv_ctl, save_tv_ctl; | 1236 | u32 tv_ctl, save_tv_ctl; |
1232 | u32 tv_dac, save_tv_dac; | 1237 | u32 tv_dac, save_tv_dac; |
@@ -1263,11 +1268,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
1263 | DAC_C_0_7_V); | 1268 | DAC_C_0_7_V); |
1264 | I915_WRITE(TV_CTL, tv_ctl); | 1269 | I915_WRITE(TV_CTL, tv_ctl); |
1265 | I915_WRITE(TV_DAC, tv_dac); | 1270 | I915_WRITE(TV_DAC, tv_dac); |
1266 | intel_wait_for_vblank(dev); | 1271 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1267 | tv_dac = I915_READ(TV_DAC); | 1272 | tv_dac = I915_READ(TV_DAC); |
1268 | I915_WRITE(TV_DAC, save_tv_dac); | 1273 | I915_WRITE(TV_DAC, save_tv_dac); |
1269 | I915_WRITE(TV_CTL, save_tv_ctl); | 1274 | I915_WRITE(TV_CTL, save_tv_ctl); |
1270 | intel_wait_for_vblank(dev); | 1275 | intel_wait_for_vblank(dev, intel_crtc->pipe); |
1271 | /* | 1276 | /* |
1272 | * A B C | 1277 | * A B C |
1273 | * 0 1 1 Composite | 1278 | * 0 1 1 Composite |
@@ -1304,12 +1309,11 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct intel_encoder *intel_encoder | |||
1304 | static void intel_tv_find_better_format(struct drm_connector *connector) | 1309 | static void intel_tv_find_better_format(struct drm_connector *connector) |
1305 | { | 1310 | { |
1306 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1311 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1307 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1312 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1308 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1313 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1309 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | ||
1310 | int i; | 1314 | int i; |
1311 | 1315 | ||
1312 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1316 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
1313 | tv_mode->component_only) | 1317 | tv_mode->component_only) |
1314 | return; | 1318 | return; |
1315 | 1319 | ||
@@ -1317,12 +1321,12 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
1317 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { | 1321 | for (i = 0; i < sizeof(tv_modes) / sizeof(*tv_modes); i++) { |
1318 | tv_mode = tv_modes + i; | 1322 | tv_mode = tv_modes + i; |
1319 | 1323 | ||
1320 | if ((tv_priv->type == DRM_MODE_CONNECTOR_Component) == | 1324 | if ((intel_tv->type == DRM_MODE_CONNECTOR_Component) == |
1321 | tv_mode->component_only) | 1325 | tv_mode->component_only) |
1322 | break; | 1326 | break; |
1323 | } | 1327 | } |
1324 | 1328 | ||
1325 | tv_priv->tv_format = tv_mode->name; | 1329 | intel_tv->tv_format = tv_mode->name; |
1326 | drm_connector_property_set_value(connector, | 1330 | drm_connector_property_set_value(connector, |
1327 | connector->dev->mode_config.tv_mode_property, i); | 1331 | connector->dev->mode_config.tv_mode_property, i); |
1328 | } | 1332 | } |
@@ -1336,31 +1340,31 @@ static void intel_tv_find_better_format(struct drm_connector *connector) | |||
1336 | static enum drm_connector_status | 1340 | static enum drm_connector_status |
1337 | intel_tv_detect(struct drm_connector *connector) | 1341 | intel_tv_detect(struct drm_connector *connector) |
1338 | { | 1342 | { |
1339 | struct drm_crtc *crtc; | ||
1340 | struct drm_display_mode mode; | 1343 | struct drm_display_mode mode; |
1341 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1344 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1342 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1345 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1343 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | 1346 | int type; |
1344 | int dpms_mode; | ||
1345 | int type = tv_priv->type; | ||
1346 | 1347 | ||
1347 | mode = reported_modes[0]; | 1348 | mode = reported_modes[0]; |
1348 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); | 1349 | drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V); |
1349 | 1350 | ||
1350 | if (encoder->crtc && encoder->crtc->enabled) { | 1351 | if (encoder->crtc && encoder->crtc->enabled) { |
1351 | type = intel_tv_detect_type(encoder->crtc, intel_encoder); | 1352 | type = intel_tv_detect_type(intel_tv); |
1352 | } else { | 1353 | } else { |
1353 | crtc = intel_get_load_detect_pipe(intel_encoder, connector, | 1354 | struct drm_crtc *crtc; |
1355 | int dpms_mode; | ||
1356 | |||
1357 | crtc = intel_get_load_detect_pipe(&intel_tv->base, connector, | ||
1354 | &mode, &dpms_mode); | 1358 | &mode, &dpms_mode); |
1355 | if (crtc) { | 1359 | if (crtc) { |
1356 | type = intel_tv_detect_type(crtc, intel_encoder); | 1360 | type = intel_tv_detect_type(intel_tv); |
1357 | intel_release_load_detect_pipe(intel_encoder, connector, | 1361 | intel_release_load_detect_pipe(&intel_tv->base, connector, |
1358 | dpms_mode); | 1362 | dpms_mode); |
1359 | } else | 1363 | } else |
1360 | type = -1; | 1364 | type = -1; |
1361 | } | 1365 | } |
1362 | 1366 | ||
1363 | tv_priv->type = type; | 1367 | intel_tv->type = type; |
1364 | 1368 | ||
1365 | if (type < 0) | 1369 | if (type < 0) |
1366 | return connector_status_disconnected; | 1370 | return connector_status_disconnected; |
@@ -1391,8 +1395,8 @@ intel_tv_chose_preferred_modes(struct drm_connector *connector, | |||
1391 | struct drm_display_mode *mode_ptr) | 1395 | struct drm_display_mode *mode_ptr) |
1392 | { | 1396 | { |
1393 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1397 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1394 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1398 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1395 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1399 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1396 | 1400 | ||
1397 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) | 1401 | if (tv_mode->nbr_end < 480 && mode_ptr->vdisplay == 480) |
1398 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; | 1402 | mode_ptr->type |= DRM_MODE_TYPE_PREFERRED; |
@@ -1417,8 +1421,8 @@ intel_tv_get_modes(struct drm_connector *connector) | |||
1417 | { | 1421 | { |
1418 | struct drm_display_mode *mode_ptr; | 1422 | struct drm_display_mode *mode_ptr; |
1419 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1423 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1420 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1424 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1421 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_encoder); | 1425 | const struct tv_mode *tv_mode = intel_tv_mode_find(intel_tv); |
1422 | int j, count = 0; | 1426 | int j, count = 0; |
1423 | u64 tmp; | 1427 | u64 tmp; |
1424 | 1428 | ||
@@ -1483,8 +1487,7 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1483 | { | 1487 | { |
1484 | struct drm_device *dev = connector->dev; | 1488 | struct drm_device *dev = connector->dev; |
1485 | struct drm_encoder *encoder = intel_attached_encoder(connector); | 1489 | struct drm_encoder *encoder = intel_attached_encoder(connector); |
1486 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | 1490 | struct intel_tv *intel_tv = enc_to_intel_tv(encoder); |
1487 | struct intel_tv_priv *tv_priv = intel_encoder->dev_priv; | ||
1488 | struct drm_crtc *crtc = encoder->crtc; | 1491 | struct drm_crtc *crtc = encoder->crtc; |
1489 | int ret = 0; | 1492 | int ret = 0; |
1490 | bool changed = false; | 1493 | bool changed = false; |
@@ -1494,30 +1497,30 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop | |||
1494 | goto out; | 1497 | goto out; |
1495 | 1498 | ||
1496 | if (property == dev->mode_config.tv_left_margin_property && | 1499 | if (property == dev->mode_config.tv_left_margin_property && |
1497 | tv_priv->margin[TV_MARGIN_LEFT] != val) { | 1500 | intel_tv->margin[TV_MARGIN_LEFT] != val) { |
1498 | tv_priv->margin[TV_MARGIN_LEFT] = val; | 1501 | intel_tv->margin[TV_MARGIN_LEFT] = val; |
1499 | changed = true; | 1502 | changed = true; |
1500 | } else if (property == dev->mode_config.tv_right_margin_property && | 1503 | } else if (property == dev->mode_config.tv_right_margin_property && |
1501 | tv_priv->margin[TV_MARGIN_RIGHT] != val) { | 1504 | intel_tv->margin[TV_MARGIN_RIGHT] != val) { |
1502 | tv_priv->margin[TV_MARGIN_RIGHT] = val; | 1505 | intel_tv->margin[TV_MARGIN_RIGHT] = val; |
1503 | changed = true; | 1506 | changed = true; |
1504 | } else if (property == dev->mode_config.tv_top_margin_property && | 1507 | } else if (property == dev->mode_config.tv_top_margin_property && |
1505 | tv_priv->margin[TV_MARGIN_TOP] != val) { | 1508 | intel_tv->margin[TV_MARGIN_TOP] != val) { |
1506 | tv_priv->margin[TV_MARGIN_TOP] = val; | 1509 | intel_tv->margin[TV_MARGIN_TOP] = val; |
1507 | changed = true; | 1510 | changed = true; |
1508 | } else if (property == dev->mode_config.tv_bottom_margin_property && | 1511 | } else if (property == dev->mode_config.tv_bottom_margin_property && |
1509 | tv_priv->margin[TV_MARGIN_BOTTOM] != val) { | 1512 | intel_tv->margin[TV_MARGIN_BOTTOM] != val) { |
1510 | tv_priv->margin[TV_MARGIN_BOTTOM] = val; | 1513 | intel_tv->margin[TV_MARGIN_BOTTOM] = val; |
1511 | changed = true; | 1514 | changed = true; |
1512 | } else if (property == dev->mode_config.tv_mode_property) { | 1515 | } else if (property == dev->mode_config.tv_mode_property) { |
1513 | if (val >= ARRAY_SIZE(tv_modes)) { | 1516 | if (val >= ARRAY_SIZE(tv_modes)) { |
1514 | ret = -EINVAL; | 1517 | ret = -EINVAL; |
1515 | goto out; | 1518 | goto out; |
1516 | } | 1519 | } |
1517 | if (!strcmp(tv_priv->tv_format, tv_modes[val].name)) | 1520 | if (!strcmp(intel_tv->tv_format, tv_modes[val].name)) |
1518 | goto out; | 1521 | goto out; |
1519 | 1522 | ||
1520 | tv_priv->tv_format = tv_modes[val].name; | 1523 | intel_tv->tv_format = tv_modes[val].name; |
1521 | changed = true; | 1524 | changed = true; |
1522 | } else { | 1525 | } else { |
1523 | ret = -EINVAL; | 1526 | ret = -EINVAL; |
@@ -1553,16 +1556,8 @@ static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = | |||
1553 | .best_encoder = intel_attached_encoder, | 1556 | .best_encoder = intel_attached_encoder, |
1554 | }; | 1557 | }; |
1555 | 1558 | ||
1556 | static void intel_tv_enc_destroy(struct drm_encoder *encoder) | ||
1557 | { | ||
1558 | struct intel_encoder *intel_encoder = enc_to_intel_encoder(encoder); | ||
1559 | |||
1560 | drm_encoder_cleanup(encoder); | ||
1561 | kfree(intel_encoder); | ||
1562 | } | ||
1563 | |||
1564 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { | 1559 | static const struct drm_encoder_funcs intel_tv_enc_funcs = { |
1565 | .destroy = intel_tv_enc_destroy, | 1560 | .destroy = intel_encoder_destroy, |
1566 | }; | 1561 | }; |
1567 | 1562 | ||
1568 | /* | 1563 | /* |
@@ -1606,9 +1601,9 @@ intel_tv_init(struct drm_device *dev) | |||
1606 | { | 1601 | { |
1607 | struct drm_i915_private *dev_priv = dev->dev_private; | 1602 | struct drm_i915_private *dev_priv = dev->dev_private; |
1608 | struct drm_connector *connector; | 1603 | struct drm_connector *connector; |
1604 | struct intel_tv *intel_tv; | ||
1609 | struct intel_encoder *intel_encoder; | 1605 | struct intel_encoder *intel_encoder; |
1610 | struct intel_connector *intel_connector; | 1606 | struct intel_connector *intel_connector; |
1611 | struct intel_tv_priv *tv_priv; | ||
1612 | u32 tv_dac_on, tv_dac_off, save_tv_dac; | 1607 | u32 tv_dac_on, tv_dac_off, save_tv_dac; |
1613 | char **tv_format_names; | 1608 | char **tv_format_names; |
1614 | int i, initial_mode = 0; | 1609 | int i, initial_mode = 0; |
@@ -1647,18 +1642,18 @@ intel_tv_init(struct drm_device *dev) | |||
1647 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) | 1642 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) |
1648 | return; | 1643 | return; |
1649 | 1644 | ||
1650 | intel_encoder = kzalloc(sizeof(struct intel_encoder) + | 1645 | intel_tv = kzalloc(sizeof(struct intel_tv), GFP_KERNEL); |
1651 | sizeof(struct intel_tv_priv), GFP_KERNEL); | 1646 | if (!intel_tv) { |
1652 | if (!intel_encoder) { | ||
1653 | return; | 1647 | return; |
1654 | } | 1648 | } |
1655 | 1649 | ||
1656 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1650 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1657 | if (!intel_connector) { | 1651 | if (!intel_connector) { |
1658 | kfree(intel_encoder); | 1652 | kfree(intel_tv); |
1659 | return; | 1653 | return; |
1660 | } | 1654 | } |
1661 | 1655 | ||
1656 | intel_encoder = &intel_tv->base; | ||
1662 | connector = &intel_connector->base; | 1657 | connector = &intel_connector->base; |
1663 | 1658 | ||
1664 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1659 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
@@ -1668,22 +1663,20 @@ intel_tv_init(struct drm_device *dev) | |||
1668 | DRM_MODE_ENCODER_TVDAC); | 1663 | DRM_MODE_ENCODER_TVDAC); |
1669 | 1664 | ||
1670 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); | 1665 | drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); |
1671 | tv_priv = (struct intel_tv_priv *)(intel_encoder + 1); | ||
1672 | intel_encoder->type = INTEL_OUTPUT_TVOUT; | 1666 | intel_encoder->type = INTEL_OUTPUT_TVOUT; |
1673 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); | 1667 | intel_encoder->crtc_mask = (1 << 0) | (1 << 1); |
1674 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); | 1668 | intel_encoder->clone_mask = (1 << INTEL_TV_CLONE_BIT); |
1675 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); | 1669 | intel_encoder->enc.possible_crtcs = ((1 << 0) | (1 << 1)); |
1676 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); | 1670 | intel_encoder->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); |
1677 | intel_encoder->dev_priv = tv_priv; | 1671 | intel_tv->type = DRM_MODE_CONNECTOR_Unknown; |
1678 | tv_priv->type = DRM_MODE_CONNECTOR_Unknown; | ||
1679 | 1672 | ||
1680 | /* BIOS margin values */ | 1673 | /* BIOS margin values */ |
1681 | tv_priv->margin[TV_MARGIN_LEFT] = 54; | 1674 | intel_tv->margin[TV_MARGIN_LEFT] = 54; |
1682 | tv_priv->margin[TV_MARGIN_TOP] = 36; | 1675 | intel_tv->margin[TV_MARGIN_TOP] = 36; |
1683 | tv_priv->margin[TV_MARGIN_RIGHT] = 46; | 1676 | intel_tv->margin[TV_MARGIN_RIGHT] = 46; |
1684 | tv_priv->margin[TV_MARGIN_BOTTOM] = 37; | 1677 | intel_tv->margin[TV_MARGIN_BOTTOM] = 37; |
1685 | 1678 | ||
1686 | tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); | 1679 | intel_tv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL); |
1687 | 1680 | ||
1688 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); | 1681 | drm_encoder_helper_add(&intel_encoder->enc, &intel_tv_helper_funcs); |
1689 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); | 1682 | drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs); |
@@ -1703,16 +1696,16 @@ intel_tv_init(struct drm_device *dev) | |||
1703 | initial_mode); | 1696 | initial_mode); |
1704 | drm_connector_attach_property(connector, | 1697 | drm_connector_attach_property(connector, |
1705 | dev->mode_config.tv_left_margin_property, | 1698 | dev->mode_config.tv_left_margin_property, |
1706 | tv_priv->margin[TV_MARGIN_LEFT]); | 1699 | intel_tv->margin[TV_MARGIN_LEFT]); |
1707 | drm_connector_attach_property(connector, | 1700 | drm_connector_attach_property(connector, |
1708 | dev->mode_config.tv_top_margin_property, | 1701 | dev->mode_config.tv_top_margin_property, |
1709 | tv_priv->margin[TV_MARGIN_TOP]); | 1702 | intel_tv->margin[TV_MARGIN_TOP]); |
1710 | drm_connector_attach_property(connector, | 1703 | drm_connector_attach_property(connector, |
1711 | dev->mode_config.tv_right_margin_property, | 1704 | dev->mode_config.tv_right_margin_property, |
1712 | tv_priv->margin[TV_MARGIN_RIGHT]); | 1705 | intel_tv->margin[TV_MARGIN_RIGHT]); |
1713 | drm_connector_attach_property(connector, | 1706 | drm_connector_attach_property(connector, |
1714 | dev->mode_config.tv_bottom_margin_property, | 1707 | dev->mode_config.tv_bottom_margin_property, |
1715 | tv_priv->margin[TV_MARGIN_BOTTOM]); | 1708 | intel_tv->margin[TV_MARGIN_BOTTOM]); |
1716 | out: | 1709 | out: |
1717 | drm_sysfs_connector_add(connector); | 1710 | drm_sysfs_connector_add(connector); |
1718 | } | 1711 | } |
diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c index fff82045c427..9ce2827f8c00 100644 --- a/drivers/gpu/drm/mga/mga_state.c +++ b/drivers/gpu/drm/mga/mga_state.c | |||
@@ -1085,19 +1085,19 @@ file_priv) | |||
1085 | } | 1085 | } |
1086 | 1086 | ||
1087 | struct drm_ioctl_desc mga_ioctls[] = { | 1087 | struct drm_ioctl_desc mga_ioctls[] = { |
1088 | DRM_IOCTL_DEF(DRM_MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1088 | DRM_IOCTL_DEF_DRV(MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1089 | DRM_IOCTL_DEF(DRM_MGA_FLUSH, mga_dma_flush, DRM_AUTH), | 1089 | DRM_IOCTL_DEF_DRV(MGA_FLUSH, mga_dma_flush, DRM_AUTH), |
1090 | DRM_IOCTL_DEF(DRM_MGA_RESET, mga_dma_reset, DRM_AUTH), | 1090 | DRM_IOCTL_DEF_DRV(MGA_RESET, mga_dma_reset, DRM_AUTH), |
1091 | DRM_IOCTL_DEF(DRM_MGA_SWAP, mga_dma_swap, DRM_AUTH), | 1091 | DRM_IOCTL_DEF_DRV(MGA_SWAP, mga_dma_swap, DRM_AUTH), |
1092 | DRM_IOCTL_DEF(DRM_MGA_CLEAR, mga_dma_clear, DRM_AUTH), | 1092 | DRM_IOCTL_DEF_DRV(MGA_CLEAR, mga_dma_clear, DRM_AUTH), |
1093 | DRM_IOCTL_DEF(DRM_MGA_VERTEX, mga_dma_vertex, DRM_AUTH), | 1093 | DRM_IOCTL_DEF_DRV(MGA_VERTEX, mga_dma_vertex, DRM_AUTH), |
1094 | DRM_IOCTL_DEF(DRM_MGA_INDICES, mga_dma_indices, DRM_AUTH), | 1094 | DRM_IOCTL_DEF_DRV(MGA_INDICES, mga_dma_indices, DRM_AUTH), |
1095 | DRM_IOCTL_DEF(DRM_MGA_ILOAD, mga_dma_iload, DRM_AUTH), | 1095 | DRM_IOCTL_DEF_DRV(MGA_ILOAD, mga_dma_iload, DRM_AUTH), |
1096 | DRM_IOCTL_DEF(DRM_MGA_BLIT, mga_dma_blit, DRM_AUTH), | 1096 | DRM_IOCTL_DEF_DRV(MGA_BLIT, mga_dma_blit, DRM_AUTH), |
1097 | DRM_IOCTL_DEF(DRM_MGA_GETPARAM, mga_getparam, DRM_AUTH), | 1097 | DRM_IOCTL_DEF_DRV(MGA_GETPARAM, mga_getparam, DRM_AUTH), |
1098 | DRM_IOCTL_DEF(DRM_MGA_SET_FENCE, mga_set_fence, DRM_AUTH), | 1098 | DRM_IOCTL_DEF_DRV(MGA_SET_FENCE, mga_set_fence, DRM_AUTH), |
1099 | DRM_IOCTL_DEF(DRM_MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), | 1099 | DRM_IOCTL_DEF_DRV(MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH), |
1100 | DRM_IOCTL_DEF(DRM_MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1100 | DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1101 | }; | 1101 | }; |
1102 | 1102 | ||
1103 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); | 1103 | int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 0b69a9628c95..974b0f8ae048 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -2166,7 +2166,7 @@ peek_fb(struct drm_device *dev, struct io_mapping *fb, | |||
2166 | uint32_t val = 0; | 2166 | uint32_t val = 0; |
2167 | 2167 | ||
2168 | if (off < pci_resource_len(dev->pdev, 1)) { | 2168 | if (off < pci_resource_len(dev->pdev, 1)) { |
2169 | uint32_t __iomem *p = | 2169 | uint8_t __iomem *p = |
2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2170 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); |
2171 | 2171 | ||
2172 | val = ioread32(p + (off & ~PAGE_MASK)); | 2172 | val = ioread32(p + (off & ~PAGE_MASK)); |
@@ -2182,7 +2182,7 @@ poke_fb(struct drm_device *dev, struct io_mapping *fb, | |||
2182 | uint32_t off, uint32_t val) | 2182 | uint32_t off, uint32_t val) |
2183 | { | 2183 | { |
2184 | if (off < pci_resource_len(dev->pdev, 1)) { | 2184 | if (off < pci_resource_len(dev->pdev, 1)) { |
2185 | uint32_t __iomem *p = | 2185 | uint8_t __iomem *p = |
2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); | 2186 | io_mapping_map_atomic_wc(fb, off & PAGE_MASK, KM_USER0); |
2187 | 2187 | ||
2188 | iowrite32(val, p + (off & ~PAGE_MASK)); | 2188 | iowrite32(val, p + (off & ~PAGE_MASK)); |
@@ -3869,27 +3869,10 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entr | |||
3869 | } | 3869 | } |
3870 | #ifdef __powerpc__ | 3870 | #ifdef __powerpc__ |
3871 | /* Powerbook specific quirks */ | 3871 | /* Powerbook specific quirks */ |
3872 | if ((dev->pci_device & 0xffff) == 0x0179 || | 3872 | if (script == LVDS_RESET && |
3873 | (dev->pci_device & 0xffff) == 0x0189 || | 3873 | (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || |
3874 | (dev->pci_device & 0xffff) == 0x0329) { | 3874 | dev->pci_device == 0x0329)) |
3875 | if (script == LVDS_RESET) { | 3875 | nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); |
3876 | nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); | ||
3877 | |||
3878 | } else if (script == LVDS_PANEL_ON) { | ||
3879 | bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, | ||
3880 | bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | ||
3881 | | (1 << 31)); | ||
3882 | bios_wr32(bios, NV_PCRTC_GPIO_EXT, | ||
3883 | bios_rd32(bios, NV_PCRTC_GPIO_EXT) | 1); | ||
3884 | |||
3885 | } else if (script == LVDS_PANEL_OFF) { | ||
3886 | bios_wr32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL, | ||
3887 | bios_rd32(bios, NV_PBUS_DEBUG_DUALHEAD_CTL) | ||
3888 | & ~(1 << 31)); | ||
3889 | bios_wr32(bios, NV_PCRTC_GPIO_EXT, | ||
3890 | bios_rd32(bios, NV_PCRTC_GPIO_EXT) & ~3); | ||
3891 | } | ||
3892 | } | ||
3893 | #endif | 3876 | #endif |
3894 | 3877 | ||
3895 | return 0; | 3878 | return 0; |
@@ -4381,11 +4364,8 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
4381 | * | 4364 | * |
4382 | * For the moment, a quirk will do :) | 4365 | * For the moment, a quirk will do :) |
4383 | */ | 4366 | */ |
4384 | if ((dev->pdev->device == 0x01d7) && | 4367 | if (nv_match_device(dev, 0x01d7, 0x1028, 0x01c2)) |
4385 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
4386 | (dev->pdev->subsystem_device == 0x01c2)) { | ||
4387 | bios->fp.duallink_transition_clk = 80000; | 4368 | bios->fp.duallink_transition_clk = 80000; |
4388 | } | ||
4389 | 4369 | ||
4390 | /* set dual_link flag for EDID case */ | 4370 | /* set dual_link flag for EDID case */ |
4391 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) | 4371 | if (pxclk && (chip_version < 0x25 || chip_version > 0x28)) |
@@ -4587,7 +4567,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4587 | return 1; | 4567 | return 1; |
4588 | } | 4568 | } |
4589 | 4569 | ||
4590 | NV_TRACE(dev, "0x%04X: parsing output script 0\n", script); | 4570 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); |
4591 | nouveau_bios_run_init_table(dev, script, dcbent); | 4571 | nouveau_bios_run_init_table(dev, script, dcbent); |
4592 | } else | 4572 | } else |
4593 | if (pxclk == -1) { | 4573 | if (pxclk == -1) { |
@@ -4597,7 +4577,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4597 | return 1; | 4577 | return 1; |
4598 | } | 4578 | } |
4599 | 4579 | ||
4600 | NV_TRACE(dev, "0x%04X: parsing output script 1\n", script); | 4580 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); |
4601 | nouveau_bios_run_init_table(dev, script, dcbent); | 4581 | nouveau_bios_run_init_table(dev, script, dcbent); |
4602 | } else | 4582 | } else |
4603 | if (pxclk == -2) { | 4583 | if (pxclk == -2) { |
@@ -4610,7 +4590,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4610 | return 1; | 4590 | return 1; |
4611 | } | 4591 | } |
4612 | 4592 | ||
4613 | NV_TRACE(dev, "0x%04X: parsing output script 2\n", script); | 4593 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); |
4614 | nouveau_bios_run_init_table(dev, script, dcbent); | 4594 | nouveau_bios_run_init_table(dev, script, dcbent); |
4615 | } else | 4595 | } else |
4616 | if (pxclk > 0) { | 4596 | if (pxclk > 0) { |
@@ -4622,7 +4602,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4622 | return 1; | 4602 | return 1; |
4623 | } | 4603 | } |
4624 | 4604 | ||
4625 | NV_TRACE(dev, "0x%04X: parsing clock script 0\n", script); | 4605 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); |
4626 | nouveau_bios_run_init_table(dev, script, dcbent); | 4606 | nouveau_bios_run_init_table(dev, script, dcbent); |
4627 | } else | 4607 | } else |
4628 | if (pxclk < 0) { | 4608 | if (pxclk < 0) { |
@@ -4634,7 +4614,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
4634 | return 1; | 4614 | return 1; |
4635 | } | 4615 | } |
4636 | 4616 | ||
4637 | NV_TRACE(dev, "0x%04X: parsing clock script 1\n", script); | 4617 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); |
4638 | nouveau_bios_run_init_table(dev, script, dcbent); | 4618 | nouveau_bios_run_init_table(dev, script, dcbent); |
4639 | } | 4619 | } |
4640 | 4620 | ||
@@ -5357,19 +5337,17 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios, | |||
5357 | } | 5337 | } |
5358 | 5338 | ||
5359 | tmdstableptr = ROM16(bios->data[bitentry->offset]); | 5339 | tmdstableptr = ROM16(bios->data[bitentry->offset]); |
5360 | 5340 | if (!tmdstableptr) { | |
5361 | if (tmdstableptr == 0x0) { | ||
5362 | NV_ERROR(dev, "Pointer to TMDS table invalid\n"); | 5341 | NV_ERROR(dev, "Pointer to TMDS table invalid\n"); |
5363 | return -EINVAL; | 5342 | return -EINVAL; |
5364 | } | 5343 | } |
5365 | 5344 | ||
5345 | NV_INFO(dev, "TMDS table version %d.%d\n", | ||
5346 | bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); | ||
5347 | |||
5366 | /* nv50+ has v2.0, but we don't parse it atm */ | 5348 | /* nv50+ has v2.0, but we don't parse it atm */ |
5367 | if (bios->data[tmdstableptr] != 0x11) { | 5349 | if (bios->data[tmdstableptr] != 0x11) |
5368 | NV_WARN(dev, | ||
5369 | "TMDS table revision %d.%d not currently supported\n", | ||
5370 | bios->data[tmdstableptr] >> 4, bios->data[tmdstableptr] & 0xf); | ||
5371 | return -ENOSYS; | 5350 | return -ENOSYS; |
5372 | } | ||
5373 | 5351 | ||
5374 | /* | 5352 | /* |
5375 | * These two scripts are odd: they don't seem to get run even when | 5353 | * These two scripts are odd: they don't seem to get run even when |
@@ -5809,6 +5787,20 @@ parse_dcb_gpio_table(struct nvbios *bios) | |||
5809 | gpio->line = tvdac_gpio[1] >> 4; | 5787 | gpio->line = tvdac_gpio[1] >> 4; |
5810 | gpio->invert = tvdac_gpio[0] & 2; | 5788 | gpio->invert = tvdac_gpio[0] & 2; |
5811 | } | 5789 | } |
5790 | } else { | ||
5791 | /* | ||
5792 | * No systematic way to store GPIO info on pre-v2.2 | ||
5793 | * DCBs, try to match the PCI device IDs. | ||
5794 | */ | ||
5795 | |||
5796 | /* Apple iMac G4 NV18 */ | ||
5797 | if (nv_match_device(dev, 0x0189, 0x10de, 0x0010)) { | ||
5798 | struct dcb_gpio_entry *gpio = new_gpio_entry(bios); | ||
5799 | |||
5800 | gpio->tag = DCB_GPIO_TVDAC0; | ||
5801 | gpio->line = 4; | ||
5802 | } | ||
5803 | |||
5812 | } | 5804 | } |
5813 | 5805 | ||
5814 | if (!gpio_table_ptr) | 5806 | if (!gpio_table_ptr) |
@@ -5884,9 +5876,7 @@ apply_dcb_connector_quirks(struct nvbios *bios, int idx) | |||
5884 | struct drm_device *dev = bios->dev; | 5876 | struct drm_device *dev = bios->dev; |
5885 | 5877 | ||
5886 | /* Gigabyte NX85T */ | 5878 | /* Gigabyte NX85T */ |
5887 | if ((dev->pdev->device == 0x0421) && | 5879 | if (nv_match_device(dev, 0x0421, 0x1458, 0x344c)) { |
5888 | (dev->pdev->subsystem_vendor == 0x1458) && | ||
5889 | (dev->pdev->subsystem_device == 0x344c)) { | ||
5890 | if (cte->type == DCB_CONNECTOR_HDMI_1) | 5880 | if (cte->type == DCB_CONNECTOR_HDMI_1) |
5891 | cte->type = DCB_CONNECTOR_DVI_I; | 5881 | cte->type = DCB_CONNECTOR_DVI_I; |
5892 | } | 5882 | } |
@@ -6139,7 +6129,7 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
6139 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; | 6129 | entry->tmdsconf.slave_addr = (conf & 0x00000070) >> 4; |
6140 | 6130 | ||
6141 | break; | 6131 | break; |
6142 | case 0xe: | 6132 | case OUTPUT_EOL: |
6143 | /* weird g80 mobile type that "nv" treats as a terminator */ | 6133 | /* weird g80 mobile type that "nv" treats as a terminator */ |
6144 | dcb->entries--; | 6134 | dcb->entries--; |
6145 | return false; | 6135 | return false; |
@@ -6176,22 +6166,14 @@ parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
6176 | entry->type = OUTPUT_TV; | 6166 | entry->type = OUTPUT_TV; |
6177 | break; | 6167 | break; |
6178 | case 2: | 6168 | case 2: |
6179 | case 3: | ||
6180 | entry->type = OUTPUT_LVDS; | ||
6181 | break; | ||
6182 | case 4: | 6169 | case 4: |
6183 | switch ((conn & 0x000000f0) >> 4) { | 6170 | if (conn & 0x10) |
6184 | case 0: | ||
6185 | entry->type = OUTPUT_TMDS; | ||
6186 | break; | ||
6187 | case 1: | ||
6188 | entry->type = OUTPUT_LVDS; | 6171 | entry->type = OUTPUT_LVDS; |
6189 | break; | 6172 | else |
6190 | default: | 6173 | entry->type = OUTPUT_TMDS; |
6191 | NV_ERROR(dev, "Unknown DCB subtype 4/%d\n", | 6174 | break; |
6192 | (conn & 0x000000f0) >> 4); | 6175 | case 3: |
6193 | return false; | 6176 | entry->type = OUTPUT_LVDS; |
6194 | } | ||
6195 | break; | 6177 | break; |
6196 | default: | 6178 | default: |
6197 | NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); | 6179 | NV_ERROR(dev, "Unknown DCB type %d\n", conn & 0x0000000f); |
@@ -6307,9 +6289,7 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) | |||
6307 | * nasty problems until this is sorted (assuming it's not a | 6289 | * nasty problems until this is sorted (assuming it's not a |
6308 | * VBIOS bug). | 6290 | * VBIOS bug). |
6309 | */ | 6291 | */ |
6310 | if ((dev->pdev->device == 0x040d) && | 6292 | if (nv_match_device(dev, 0x040d, 0x1028, 0x019b)) { |
6311 | (dev->pdev->subsystem_vendor == 0x1028) && | ||
6312 | (dev->pdev->subsystem_device == 0x019b)) { | ||
6313 | if (*conn == 0x02026312 && *conf == 0x00000020) | 6293 | if (*conn == 0x02026312 && *conf == 0x00000020) |
6314 | return false; | 6294 | return false; |
6315 | } | 6295 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index fd14dfd3d780..c1de2f3fcb0e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -95,6 +95,7 @@ enum dcb_type { | |||
95 | OUTPUT_TMDS = 2, | 95 | OUTPUT_TMDS = 2, |
96 | OUTPUT_LVDS = 3, | 96 | OUTPUT_LVDS = 3, |
97 | OUTPUT_DP = 6, | 97 | OUTPUT_DP = 6, |
98 | OUTPUT_EOL = 14, /* DCB 4.0+, appears to be end-of-list */ | ||
98 | OUTPUT_ANY = -1 | 99 | OUTPUT_ANY = -1 |
99 | }; | 100 | }; |
100 | 101 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 84f85183d041..f6f44779d82f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -36,6 +36,21 @@ | |||
36 | #include <linux/log2.h> | 36 | #include <linux/log2.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | 38 | ||
39 | int | ||
40 | nouveau_bo_sync_gpu(struct nouveau_bo *nvbo, struct nouveau_channel *chan) | ||
41 | { | ||
42 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
43 | int ret; | ||
44 | |||
45 | if (!prev_fence || nouveau_fence_channel(prev_fence) == chan) | ||
46 | return 0; | ||
47 | |||
48 | spin_lock(&nvbo->bo.lock); | ||
49 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | ||
50 | spin_unlock(&nvbo->bo.lock); | ||
51 | return ret; | ||
52 | } | ||
53 | |||
39 | static void | 54 | static void |
40 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) | 55 | nouveau_bo_del_ttm(struct ttm_buffer_object *bo) |
41 | { | 56 | { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 90fdcda332be..0480f064f2c1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -426,18 +426,18 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, | |||
426 | ***********************************/ | 426 | ***********************************/ |
427 | 427 | ||
428 | struct drm_ioctl_desc nouveau_ioctls[] = { | 428 | struct drm_ioctl_desc nouveau_ioctls[] = { |
429 | DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), | 429 | DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), |
430 | DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 430 | DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
431 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), | 431 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), |
432 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), | 432 | DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), |
433 | DRM_IOCTL_DEF(DRM_NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), | 433 | DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), |
434 | DRM_IOCTL_DEF(DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), | 434 | DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), |
435 | DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), | 435 | DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), |
436 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), | 436 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), |
437 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), | 437 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), |
438 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), | 438 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), |
439 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), | 439 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), |
440 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), | 440 | DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), |
441 | }; | 441 | }; |
442 | 442 | ||
443 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); | 443 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index b1b22baf1428..a1473fff06ac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -104,7 +104,7 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
104 | int i; | 104 | int i; |
105 | 105 | ||
106 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { | 106 | for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { |
107 | struct nouveau_i2c_chan *i2c; | 107 | struct nouveau_i2c_chan *i2c = NULL; |
108 | struct nouveau_encoder *nv_encoder; | 108 | struct nouveau_encoder *nv_encoder; |
109 | struct drm_mode_object *obj; | 109 | struct drm_mode_object *obj; |
110 | int id; | 110 | int id; |
@@ -117,7 +117,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector, | |||
117 | if (!obj) | 117 | if (!obj) |
118 | continue; | 118 | continue; |
119 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); | 119 | nv_encoder = nouveau_encoder(obj_to_encoder(obj)); |
120 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | 120 | |
121 | if (nv_encoder->dcb->i2c_index < 0xf) | ||
122 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | ||
121 | 123 | ||
122 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { | 124 | if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) { |
123 | *pnv_encoder = nv_encoder; | 125 | *pnv_encoder = nv_encoder; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e424bf74d706..b1be617373b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -1165,6 +1165,7 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); | |||
1165 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); | 1165 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); |
1166 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); | 1166 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); |
1167 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); | 1167 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); |
1168 | extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *); | ||
1168 | 1169 | ||
1169 | /* nouveau_fence.c */ | 1170 | /* nouveau_fence.c */ |
1170 | struct nouveau_fence; | 1171 | struct nouveau_fence; |
@@ -1388,6 +1389,15 @@ nv_two_reg_pll(struct drm_device *dev) | |||
1388 | return false; | 1389 | return false; |
1389 | } | 1390 | } |
1390 | 1391 | ||
1392 | static inline bool | ||
1393 | nv_match_device(struct drm_device *dev, unsigned device, | ||
1394 | unsigned sub_vendor, unsigned sub_device) | ||
1395 | { | ||
1396 | return dev->pdev->device == device && | ||
1397 | dev->pdev->subsystem_vendor == sub_vendor && | ||
1398 | dev->pdev->subsystem_device == sub_device; | ||
1399 | } | ||
1400 | |||
1391 | #define NV_SW 0x0000506e | 1401 | #define NV_SW 0x0000506e |
1392 | #define NV_SW_DMA_SEMAPHORE 0x00000060 | 1402 | #define NV_SW_DMA_SEMAPHORE 0x00000060 |
1393 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 | 1403 | #define NV_SW_SEMAPHORE_OFFSET 0x00000064 |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0f417ac1b696..581c67cd7b24 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -337,7 +337,9 @@ retry: | |||
337 | return -EINVAL; | 337 | return -EINVAL; |
338 | } | 338 | } |
339 | 339 | ||
340 | mutex_unlock(&drm_global_mutex); | ||
340 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); | 341 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); |
342 | mutex_lock(&drm_global_mutex); | ||
341 | if (ret) { | 343 | if (ret) { |
342 | NV_ERROR(dev, "fail wait_cpu\n"); | 344 | NV_ERROR(dev, "fail wait_cpu\n"); |
343 | return ret; | 345 | return ret; |
@@ -361,16 +363,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
361 | 363 | ||
362 | list_for_each_entry(nvbo, list, entry) { | 364 | list_for_each_entry(nvbo, list, entry) { |
363 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; | 365 | struct drm_nouveau_gem_pushbuf_bo *b = &pbbo[nvbo->pbbo_index]; |
364 | struct nouveau_fence *prev_fence = nvbo->bo.sync_obj; | ||
365 | 366 | ||
366 | if (prev_fence && nouveau_fence_channel(prev_fence) != chan) { | 367 | ret = nouveau_bo_sync_gpu(nvbo, chan); |
367 | spin_lock(&nvbo->bo.lock); | 368 | if (unlikely(ret)) { |
368 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | 369 | NV_ERROR(dev, "fail pre-validate sync\n"); |
369 | spin_unlock(&nvbo->bo.lock); | 370 | return ret; |
370 | if (unlikely(ret)) { | ||
371 | NV_ERROR(dev, "fail wait other chan\n"); | ||
372 | return ret; | ||
373 | } | ||
374 | } | 371 | } |
375 | 372 | ||
376 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, | 373 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, |
@@ -381,7 +378,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
381 | return ret; | 378 | return ret; |
382 | } | 379 | } |
383 | 380 | ||
384 | nvbo->channel = chan; | 381 | nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan; |
385 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, | 382 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, |
386 | false, false, false); | 383 | false, false, false); |
387 | nvbo->channel = NULL; | 384 | nvbo->channel = NULL; |
@@ -390,6 +387,12 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
390 | return ret; | 387 | return ret; |
391 | } | 388 | } |
392 | 389 | ||
390 | ret = nouveau_bo_sync_gpu(nvbo, chan); | ||
391 | if (unlikely(ret)) { | ||
392 | NV_ERROR(dev, "fail post-validate sync\n"); | ||
393 | return ret; | ||
394 | } | ||
395 | |||
393 | if (nvbo->bo.offset == b->presumed.offset && | 396 | if (nvbo->bo.offset == b->presumed.offset && |
394 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && | 397 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && |
395 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || | 398 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || |
@@ -615,6 +618,21 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
615 | 618 | ||
616 | mutex_lock(&dev->struct_mutex); | 619 | mutex_lock(&dev->struct_mutex); |
617 | 620 | ||
621 | /* Mark push buffers as being used on PFIFO, the validation code | ||
622 | * will then make sure that if the pushbuf bo moves, that they | ||
623 | * happen on the kernel channel, which will in turn cause a sync | ||
624 | * to happen before we try and submit the push buffer. | ||
625 | */ | ||
626 | for (i = 0; i < req->nr_push; i++) { | ||
627 | if (push[i].bo_index >= req->nr_buffers) { | ||
628 | NV_ERROR(dev, "push %d buffer not in list\n", i); | ||
629 | ret = -EINVAL; | ||
630 | goto out; | ||
631 | } | ||
632 | |||
633 | bo[push[i].bo_index].read_domains |= (1 << 31); | ||
634 | } | ||
635 | |||
618 | /* Validate buffer list */ | 636 | /* Validate buffer list */ |
619 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, | 637 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, |
620 | req->nr_buffers, &op, &do_reloc); | 638 | req->nr_buffers, &op, &do_reloc); |
@@ -647,7 +665,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | |||
647 | push[i].length); | 665 | push[i].length); |
648 | } | 666 | } |
649 | } else | 667 | } else |
650 | if (dev_priv->card_type >= NV_20) { | 668 | if (dev_priv->chipset >= 0x25) { |
651 | ret = RING_SPACE(chan, req->nr_push * 2); | 669 | ret = RING_SPACE(chan, req->nr_push * 2); |
652 | if (ret) { | 670 | if (ret) { |
653 | NV_ERROR(dev, "cal_space: %d\n", ret); | 671 | NV_ERROR(dev, "cal_space: %d\n", ret); |
@@ -722,7 +740,7 @@ out_next: | |||
722 | req->suffix0 = 0x00000000; | 740 | req->suffix0 = 0x00000000; |
723 | req->suffix1 = 0x00000000; | 741 | req->suffix1 = 0x00000000; |
724 | } else | 742 | } else |
725 | if (dev_priv->card_type >= NV_20) { | 743 | if (dev_priv->chipset >= 0x25) { |
726 | req->suffix0 = 0x00020000; | 744 | req->suffix0 = 0x00020000; |
727 | req->suffix1 = 0x00000000; | 745 | req->suffix1 = 0x00000000; |
728 | } else { | 746 | } else { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 0bd407ca3d42..84614858728b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -163,7 +163,7 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index) | |||
163 | if (entry->chan) | 163 | if (entry->chan) |
164 | return -EEXIST; | 164 | return -EEXIST; |
165 | 165 | ||
166 | if (dev_priv->card_type == NV_C0 && entry->read >= NV50_I2C_PORTS) { | 166 | if (dev_priv->card_type >= NV_50 && entry->read >= NV50_I2C_PORTS) { |
167 | NV_ERROR(dev, "unknown i2c port %d\n", entry->read); | 167 | NV_ERROR(dev, "unknown i2c port %d\n", entry->read); |
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 491767fe4fcf..6b9187d7f67d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -214,6 +214,7 @@ int | |||
214 | nouveau_sgdma_init(struct drm_device *dev) | 214 | nouveau_sgdma_init(struct drm_device *dev) |
215 | { | 215 | { |
216 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 216 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
217 | struct pci_dev *pdev = dev->pdev; | ||
217 | struct nouveau_gpuobj *gpuobj = NULL; | 218 | struct nouveau_gpuobj *gpuobj = NULL; |
218 | uint32_t aper_size, obj_size; | 219 | uint32_t aper_size, obj_size; |
219 | int i, ret; | 220 | int i, ret; |
@@ -239,10 +240,19 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
239 | 240 | ||
240 | dev_priv->gart_info.sg_dummy_page = | 241 | dev_priv->gart_info.sg_dummy_page = |
241 | alloc_page(GFP_KERNEL|__GFP_DMA32); | 242 | alloc_page(GFP_KERNEL|__GFP_DMA32); |
243 | if (!dev_priv->gart_info.sg_dummy_page) { | ||
244 | nouveau_gpuobj_del(dev, &gpuobj); | ||
245 | return -ENOMEM; | ||
246 | } | ||
247 | |||
242 | set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); | 248 | set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); |
243 | dev_priv->gart_info.sg_dummy_bus = | 249 | dev_priv->gart_info.sg_dummy_bus = |
244 | pci_map_page(dev->pdev, dev_priv->gart_info.sg_dummy_page, 0, | 250 | pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0, |
245 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); | 251 | PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
252 | if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) { | ||
253 | nouveau_gpuobj_del(dev, &gpuobj); | ||
254 | return -EFAULT; | ||
255 | } | ||
246 | 256 | ||
247 | if (dev_priv->card_type < NV_50) { | 257 | if (dev_priv->card_type < NV_50) { |
248 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and | 258 | /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index a5dcf7685800..0d3206a7046c 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -444,6 +444,7 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
444 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 444 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
445 | struct dcb_entry *dcbe = nv_encoder->dcb; | 445 | struct dcb_entry *dcbe = nv_encoder->dcb; |
446 | int head = nouveau_crtc(encoder->crtc)->index; | 446 | int head = nouveau_crtc(encoder->crtc)->index; |
447 | struct drm_encoder *slave_encoder; | ||
447 | 448 | ||
448 | if (dcbe->type == OUTPUT_TMDS) | 449 | if (dcbe->type == OUTPUT_TMDS) |
449 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); | 450 | run_tmds_table(dev, dcbe, head, nv_encoder->mode.clock); |
@@ -462,9 +463,10 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
462 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); | 463 | NVWriteRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + nv04_dac_output_offset(encoder), 0x00100000); |
463 | 464 | ||
464 | /* Init external transmitters */ | 465 | /* Init external transmitters */ |
465 | if (get_tmds_slave(encoder)) | 466 | slave_encoder = get_tmds_slave(encoder); |
466 | get_slave_funcs(get_tmds_slave(encoder))->mode_set( | 467 | if (slave_encoder) |
467 | encoder, &nv_encoder->mode, &nv_encoder->mode); | 468 | get_slave_funcs(slave_encoder)->mode_set( |
469 | slave_encoder, &nv_encoder->mode, &nv_encoder->mode); | ||
468 | 470 | ||
469 | helper->dpms(encoder, DRM_MODE_DPMS_ON); | 471 | helper->dpms(encoder, DRM_MODE_DPMS_ON); |
470 | 472 | ||
@@ -473,6 +475,27 @@ static void nv04_dfp_commit(struct drm_encoder *encoder) | |||
473 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); | 475 | nv_crtc->index, '@' + ffs(nv_encoder->dcb->or)); |
474 | } | 476 | } |
475 | 477 | ||
478 | static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) | ||
479 | { | ||
480 | #ifdef __powerpc__ | ||
481 | struct drm_device *dev = encoder->dev; | ||
482 | |||
483 | /* BIOS scripts usually take care of the backlight, thanks | ||
484 | * Apple for your consistency. | ||
485 | */ | ||
486 | if (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || | ||
487 | dev->pci_device == 0x0329) { | ||
488 | if (mode == DRM_MODE_DPMS_ON) { | ||
489 | nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31); | ||
490 | nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 1); | ||
491 | } else { | ||
492 | nv_mask(dev, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0); | ||
493 | nv_mask(dev, NV_PCRTC_GPIO_EXT, 3, 0); | ||
494 | } | ||
495 | } | ||
496 | #endif | ||
497 | } | ||
498 | |||
476 | static inline bool is_powersaving_dpms(int mode) | 499 | static inline bool is_powersaving_dpms(int mode) |
477 | { | 500 | { |
478 | return (mode != DRM_MODE_DPMS_ON); | 501 | return (mode != DRM_MODE_DPMS_ON); |
@@ -520,6 +543,7 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
520 | LVDS_PANEL_OFF, 0); | 543 | LVDS_PANEL_OFF, 0); |
521 | } | 544 | } |
522 | 545 | ||
546 | nv04_dfp_update_backlight(encoder, mode); | ||
523 | nv04_dfp_update_fp_control(encoder, mode); | 547 | nv04_dfp_update_fp_control(encoder, mode); |
524 | 548 | ||
525 | if (mode == DRM_MODE_DPMS_ON) | 549 | if (mode == DRM_MODE_DPMS_ON) |
@@ -543,6 +567,7 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode) | |||
543 | NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", | 567 | NV_INFO(dev, "Setting dpms mode %d on tmds encoder (output %d)\n", |
544 | mode, nv_encoder->dcb->index); | 568 | mode, nv_encoder->dcb->index); |
545 | 569 | ||
570 | nv04_dfp_update_backlight(encoder, mode); | ||
546 | nv04_dfp_update_fp_control(encoder, mode); | 571 | nv04_dfp_update_fp_control(encoder, mode); |
547 | } | 572 | } |
548 | 573 | ||
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 44fefb0c7083..13cdc05b7c2d 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -121,10 +121,14 @@ static bool | |||
121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) | 121 | get_tv_detect_quirks(struct drm_device *dev, uint32_t *pin_mask) |
122 | { | 122 | { |
123 | /* Zotac FX5200 */ | 123 | /* Zotac FX5200 */ |
124 | if (dev->pdev->device == 0x0322 && | 124 | if (nv_match_device(dev, 0x0322, 0x19da, 0x1035) || |
125 | dev->pdev->subsystem_vendor == 0x19da && | 125 | nv_match_device(dev, 0x0322, 0x19da, 0x2035)) { |
126 | (dev->pdev->subsystem_device == 0x1035 || | 126 | *pin_mask = 0xc; |
127 | dev->pdev->subsystem_device == 0x2035)) { | 127 | return false; |
128 | } | ||
129 | |||
130 | /* MSI nForce2 IGP */ | ||
131 | if (nv_match_device(dev, 0x01f0, 0x1462, 0x5710)) { | ||
128 | *pin_mask = 0xc; | 132 | *pin_mask = 0xc; |
129 | return false; | 133 | return false; |
130 | } | 134 | } |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 37c7b48ab24a..c95bf9b681dd 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -278,7 +278,7 @@ nv50_instmem_init(struct drm_device *dev) | |||
278 | /*XXX: incorrect, but needed to make hash func "work" */ | 278 | /*XXX: incorrect, but needed to make hash func "work" */ |
279 | dev_priv->ramht_offset = 0x10000; | 279 | dev_priv->ramht_offset = 0x10000; |
280 | dev_priv->ramht_bits = 9; | 280 | dev_priv->ramht_bits = 9; |
281 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits); | 281 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8; |
282 | return 0; | 282 | return 0; |
283 | } | 283 | } |
284 | 284 | ||
diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c index 3ab3cdc42173..6b451f864783 100644 --- a/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c | |||
@@ -142,14 +142,16 @@ int | |||
142 | nvc0_instmem_suspend(struct drm_device *dev) | 142 | nvc0_instmem_suspend(struct drm_device *dev) |
143 | { | 143 | { |
144 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 144 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
145 | u32 *buf; | ||
145 | int i; | 146 | int i; |
146 | 147 | ||
147 | dev_priv->susres.ramin_copy = vmalloc(65536); | 148 | dev_priv->susres.ramin_copy = vmalloc(65536); |
148 | if (!dev_priv->susres.ramin_copy) | 149 | if (!dev_priv->susres.ramin_copy) |
149 | return -ENOMEM; | 150 | return -ENOMEM; |
151 | buf = dev_priv->susres.ramin_copy; | ||
150 | 152 | ||
151 | for (i = 0x700000; i < 0x710000; i += 4) | 153 | for (i = 0; i < 65536; i += 4) |
152 | dev_priv->susres.ramin_copy[i/4] = nv_rd32(dev, i); | 154 | buf[i/4] = nv_rd32(dev, NV04_PRAMIN + i); |
153 | return 0; | 155 | return 0; |
154 | } | 156 | } |
155 | 157 | ||
@@ -157,14 +159,15 @@ void | |||
157 | nvc0_instmem_resume(struct drm_device *dev) | 159 | nvc0_instmem_resume(struct drm_device *dev) |
158 | { | 160 | { |
159 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 161 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
162 | u32 *buf = dev_priv->susres.ramin_copy; | ||
160 | u64 chan; | 163 | u64 chan; |
161 | int i; | 164 | int i; |
162 | 165 | ||
163 | chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; | 166 | chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; |
164 | nv_wr32(dev, 0x001700, chan >> 16); | 167 | nv_wr32(dev, 0x001700, chan >> 16); |
165 | 168 | ||
166 | for (i = 0x700000; i < 0x710000; i += 4) | 169 | for (i = 0; i < 65536; i += 4) |
167 | nv_wr32(dev, i, dev_priv->susres.ramin_copy[i/4]); | 170 | nv_wr32(dev, NV04_PRAMIN + i, buf[i/4]); |
168 | vfree(dev_priv->susres.ramin_copy); | 171 | vfree(dev_priv->susres.ramin_copy); |
169 | dev_priv->susres.ramin_copy = NULL; | 172 | dev_priv->susres.ramin_copy = NULL; |
170 | 173 | ||
@@ -221,7 +224,7 @@ nvc0_instmem_init(struct drm_device *dev) | |||
221 | /*XXX: incorrect, but needed to make hash func "work" */ | 224 | /*XXX: incorrect, but needed to make hash func "work" */ |
222 | dev_priv->ramht_offset = 0x10000; | 225 | dev_priv->ramht_offset = 0x10000; |
223 | dev_priv->ramht_bits = 9; | 226 | dev_priv->ramht_bits = 9; |
224 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits); | 227 | dev_priv->ramht_size = (1 << dev_priv->ramht_bits) * 8; |
225 | return 0; | 228 | return 0; |
226 | } | 229 | } |
227 | 230 | ||
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index 077af1f2f9b4..a9e33ce65918 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c | |||
@@ -1639,30 +1639,29 @@ void r128_driver_preclose(struct drm_device *dev, struct drm_file *file_priv) | |||
1639 | r128_do_cleanup_pageflip(dev); | 1639 | r128_do_cleanup_pageflip(dev); |
1640 | } | 1640 | } |
1641 | } | 1641 | } |
1642 | |||
1643 | void r128_driver_lastclose(struct drm_device *dev) | 1642 | void r128_driver_lastclose(struct drm_device *dev) |
1644 | { | 1643 | { |
1645 | r128_do_cleanup_cce(dev); | 1644 | r128_do_cleanup_cce(dev); |
1646 | } | 1645 | } |
1647 | 1646 | ||
1648 | struct drm_ioctl_desc r128_ioctls[] = { | 1647 | struct drm_ioctl_desc r128_ioctls[] = { |
1649 | DRM_IOCTL_DEF(DRM_R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1648 | DRM_IOCTL_DEF_DRV(R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1650 | DRM_IOCTL_DEF(DRM_R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1649 | DRM_IOCTL_DEF_DRV(R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1651 | DRM_IOCTL_DEF(DRM_R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1650 | DRM_IOCTL_DEF_DRV(R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1652 | DRM_IOCTL_DEF(DRM_R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1651 | DRM_IOCTL_DEF_DRV(R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1653 | DRM_IOCTL_DEF(DRM_R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), | 1652 | DRM_IOCTL_DEF_DRV(R128_CCE_IDLE, r128_cce_idle, DRM_AUTH), |
1654 | DRM_IOCTL_DEF(DRM_R128_RESET, r128_engine_reset, DRM_AUTH), | 1653 | DRM_IOCTL_DEF_DRV(R128_RESET, r128_engine_reset, DRM_AUTH), |
1655 | DRM_IOCTL_DEF(DRM_R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), | 1654 | DRM_IOCTL_DEF_DRV(R128_FULLSCREEN, r128_fullscreen, DRM_AUTH), |
1656 | DRM_IOCTL_DEF(DRM_R128_SWAP, r128_cce_swap, DRM_AUTH), | 1655 | DRM_IOCTL_DEF_DRV(R128_SWAP, r128_cce_swap, DRM_AUTH), |
1657 | DRM_IOCTL_DEF(DRM_R128_FLIP, r128_cce_flip, DRM_AUTH), | 1656 | DRM_IOCTL_DEF_DRV(R128_FLIP, r128_cce_flip, DRM_AUTH), |
1658 | DRM_IOCTL_DEF(DRM_R128_CLEAR, r128_cce_clear, DRM_AUTH), | 1657 | DRM_IOCTL_DEF_DRV(R128_CLEAR, r128_cce_clear, DRM_AUTH), |
1659 | DRM_IOCTL_DEF(DRM_R128_VERTEX, r128_cce_vertex, DRM_AUTH), | 1658 | DRM_IOCTL_DEF_DRV(R128_VERTEX, r128_cce_vertex, DRM_AUTH), |
1660 | DRM_IOCTL_DEF(DRM_R128_INDICES, r128_cce_indices, DRM_AUTH), | 1659 | DRM_IOCTL_DEF_DRV(R128_INDICES, r128_cce_indices, DRM_AUTH), |
1661 | DRM_IOCTL_DEF(DRM_R128_BLIT, r128_cce_blit, DRM_AUTH), | 1660 | DRM_IOCTL_DEF_DRV(R128_BLIT, r128_cce_blit, DRM_AUTH), |
1662 | DRM_IOCTL_DEF(DRM_R128_DEPTH, r128_cce_depth, DRM_AUTH), | 1661 | DRM_IOCTL_DEF_DRV(R128_DEPTH, r128_cce_depth, DRM_AUTH), |
1663 | DRM_IOCTL_DEF(DRM_R128_STIPPLE, r128_cce_stipple, DRM_AUTH), | 1662 | DRM_IOCTL_DEF_DRV(R128_STIPPLE, r128_cce_stipple, DRM_AUTH), |
1664 | DRM_IOCTL_DEF(DRM_R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1663 | DRM_IOCTL_DEF_DRV(R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1665 | DRM_IOCTL_DEF(DRM_R128_GETPARAM, r128_getparam, DRM_AUTH), | 1664 | DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH), |
1666 | }; | 1665 | }; |
1667 | 1666 | ||
1668 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); | 1667 | int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 12ad512bd3d3..577239a24fd5 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -471,6 +471,8 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
471 | struct radeon_encoder *radeon_encoder = NULL; | 471 | struct radeon_encoder *radeon_encoder = NULL; |
472 | u32 adjusted_clock = mode->clock; | 472 | u32 adjusted_clock = mode->clock; |
473 | int encoder_mode = 0; | 473 | int encoder_mode = 0; |
474 | u32 dp_clock = mode->clock; | ||
475 | int bpc = 8; | ||
474 | 476 | ||
475 | /* reset the pll flags */ | 477 | /* reset the pll flags */ |
476 | pll->flags = 0; | 478 | pll->flags = 0; |
@@ -513,6 +515,17 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
513 | if (encoder->crtc == crtc) { | 515 | if (encoder->crtc == crtc) { |
514 | radeon_encoder = to_radeon_encoder(encoder); | 516 | radeon_encoder = to_radeon_encoder(encoder); |
515 | encoder_mode = atombios_get_encoder_mode(encoder); | 517 | encoder_mode = atombios_get_encoder_mode(encoder); |
518 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) { | ||
519 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | ||
520 | if (connector) { | ||
521 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
522 | struct radeon_connector_atom_dig *dig_connector = | ||
523 | radeon_connector->con_priv; | ||
524 | |||
525 | dp_clock = dig_connector->dp_clock; | ||
526 | } | ||
527 | } | ||
528 | |||
516 | if (ASIC_IS_AVIVO(rdev)) { | 529 | if (ASIC_IS_AVIVO(rdev)) { |
517 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 530 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
518 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 531 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
@@ -555,6 +568,14 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
555 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); | 568 | args.v1.usPixelClock = cpu_to_le16(mode->clock / 10); |
556 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; | 569 | args.v1.ucTransmitterID = radeon_encoder->encoder_id; |
557 | args.v1.ucEncodeMode = encoder_mode; | 570 | args.v1.ucEncodeMode = encoder_mode; |
571 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { | ||
572 | /* may want to enable SS on DP eventually */ | ||
573 | /* args.v1.ucConfig |= | ||
574 | ADJUST_DISPLAY_CONFIG_SS_ENABLE;*/ | ||
575 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
576 | args.v1.ucConfig |= | ||
577 | ADJUST_DISPLAY_CONFIG_SS_ENABLE; | ||
578 | } | ||
558 | 579 | ||
559 | atom_execute_table(rdev->mode_info.atom_context, | 580 | atom_execute_table(rdev->mode_info.atom_context, |
560 | index, (uint32_t *)&args); | 581 | index, (uint32_t *)&args); |
@@ -568,10 +589,20 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
568 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { | 589 | if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) { |
569 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 590 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
570 | 591 | ||
571 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 592 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
593 | /* may want to enable SS on DP/eDP eventually */ | ||
594 | /*args.v3.sInput.ucDispPllConfig |= | ||
595 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
572 | args.v3.sInput.ucDispPllConfig |= | 596 | args.v3.sInput.ucDispPllConfig |= |
573 | DISPPLL_CONFIG_COHERENT_MODE; | 597 | DISPPLL_CONFIG_COHERENT_MODE; |
574 | else { | 598 | /* 16200 or 27000 */ |
599 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
600 | } else { | ||
601 | if (encoder_mode == ATOM_ENCODER_MODE_HDMI) { | ||
602 | /* deep color support */ | ||
603 | args.v3.sInput.usPixelClock = | ||
604 | cpu_to_le16((mode->clock * bpc / 8) / 10); | ||
605 | } | ||
575 | if (dig->coherent_mode) | 606 | if (dig->coherent_mode) |
576 | args.v3.sInput.ucDispPllConfig |= | 607 | args.v3.sInput.ucDispPllConfig |= |
577 | DISPPLL_CONFIG_COHERENT_MODE; | 608 | DISPPLL_CONFIG_COHERENT_MODE; |
@@ -580,13 +611,19 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
580 | DISPPLL_CONFIG_DUAL_LINK; | 611 | DISPPLL_CONFIG_DUAL_LINK; |
581 | } | 612 | } |
582 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 613 | } else if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
583 | /* may want to enable SS on DP/eDP eventually */ | 614 | if (encoder_mode == ATOM_ENCODER_MODE_DP) { |
584 | /*args.v3.sInput.ucDispPllConfig |= | 615 | /* may want to enable SS on DP/eDP eventually */ |
585 | DISPPLL_CONFIG_SS_ENABLE;*/ | 616 | /*args.v3.sInput.ucDispPllConfig |= |
586 | if (encoder_mode == ATOM_ENCODER_MODE_DP) | 617 | DISPPLL_CONFIG_SS_ENABLE;*/ |
587 | args.v3.sInput.ucDispPllConfig |= | 618 | args.v3.sInput.ucDispPllConfig |= |
588 | DISPPLL_CONFIG_COHERENT_MODE; | 619 | DISPPLL_CONFIG_COHERENT_MODE; |
589 | else { | 620 | /* 16200 or 27000 */ |
621 | args.v3.sInput.usPixelClock = cpu_to_le16(dp_clock / 10); | ||
622 | } else if (encoder_mode == ATOM_ENCODER_MODE_LVDS) { | ||
623 | /* want to enable SS on LVDS eventually */ | ||
624 | /*args.v3.sInput.ucDispPllConfig |= | ||
625 | DISPPLL_CONFIG_SS_ENABLE;*/ | ||
626 | } else { | ||
590 | if (mode->clock > 165000) | 627 | if (mode->clock > 165000) |
591 | args.v3.sInput.ucDispPllConfig |= | 628 | args.v3.sInput.ucDispPllConfig |= |
592 | DISPPLL_CONFIG_DUAL_LINK; | 629 | DISPPLL_CONFIG_DUAL_LINK; |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 36e0d4b545e6..4e7778d44b8d 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -610,7 +610,7 @@ void dp_link_train(struct drm_encoder *encoder, | |||
610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; | 610 | enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER; |
611 | else | 611 | else |
612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; | 612 | enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER; |
613 | if (dig_connector->linkb) | 613 | if (dig->linkb) |
614 | enc_id |= ATOM_DP_CONFIG_LINK_B; | 614 | enc_id |= ATOM_DP_CONFIG_LINK_B; |
615 | else | 615 | else |
616 | enc_id |= ATOM_DP_CONFIG_LINK_A; | 616 | enc_id |= ATOM_DP_CONFIG_LINK_A; |
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index f40dfb77f9b1..bd2f33e5c91a 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -156,7 +156,13 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
156 | } | 156 | } |
157 | 157 | ||
158 | mode.mode = info.mode; | 158 | mode.mode = info.mode; |
159 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | 159 | /* chips with the agp to pcie bridge don't have the AGP_STATUS register |
160 | * Just use the whatever mode the host sets up. | ||
161 | */ | ||
162 | if (rdev->family <= CHIP_RV350) | ||
163 | agp_status = (RREG32(RADEON_AGP_STATUS) | RADEON_AGPv3_MODE) & mode.mode; | ||
164 | else | ||
165 | agp_status = mode.mode; | ||
160 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); | 166 | is_v3 = !!(agp_status & RADEON_AGPv3_MODE); |
161 | 167 | ||
162 | if (is_v3) { | 168 | if (is_v3) { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 646f96f97c77..a21bf88e8c2d 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -733,6 +733,7 @@ static struct radeon_asic evergreen_asic = { | |||
733 | .set_engine_clock = &radeon_atom_set_engine_clock, | 733 | .set_engine_clock = &radeon_atom_set_engine_clock, |
734 | .get_memory_clock = &radeon_atom_get_memory_clock, | 734 | .get_memory_clock = &radeon_atom_get_memory_clock, |
735 | .set_memory_clock = &radeon_atom_set_memory_clock, | 735 | .set_memory_clock = &radeon_atom_set_memory_clock, |
736 | .get_pcie_lanes = NULL, | ||
736 | .set_pcie_lanes = NULL, | 737 | .set_pcie_lanes = NULL, |
737 | .set_clock_gating = NULL, | 738 | .set_clock_gating = NULL, |
738 | .set_surface_reg = r600_set_surface_reg, | 739 | .set_surface_reg = r600_set_surface_reg, |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 6d30868744ee..61141981880d 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -32,11 +32,11 @@ | |||
32 | 32 | ||
33 | /* from radeon_encoder.c */ | 33 | /* from radeon_encoder.c */ |
34 | extern uint32_t | 34 | extern uint32_t |
35 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, | 35 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
36 | uint8_t dac); | 36 | uint8_t dac); |
37 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 37 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
38 | extern void | 38 | extern void |
39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, | 39 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, |
40 | uint32_t supported_device); | 40 | uint32_t supported_device); |
41 | 41 | ||
42 | /* from radeon_connector.c */ | 42 | /* from radeon_connector.c */ |
@@ -46,14 +46,14 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
46 | uint32_t supported_device, | 46 | uint32_t supported_device, |
47 | int connector_type, | 47 | int connector_type, |
48 | struct radeon_i2c_bus_rec *i2c_bus, | 48 | struct radeon_i2c_bus_rec *i2c_bus, |
49 | bool linkb, uint32_t igp_lane_info, | 49 | uint32_t igp_lane_info, |
50 | uint16_t connector_object_id, | 50 | uint16_t connector_object_id, |
51 | struct radeon_hpd *hpd, | 51 | struct radeon_hpd *hpd, |
52 | struct radeon_router *router); | 52 | struct radeon_router *router); |
53 | 53 | ||
54 | /* from radeon_legacy_encoder.c */ | 54 | /* from radeon_legacy_encoder.c */ |
55 | extern void | 55 | extern void |
56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, | 56 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
57 | uint32_t supported_device); | 57 | uint32_t supported_device); |
58 | 58 | ||
59 | union atom_supported_devices { | 59 | union atom_supported_devices { |
@@ -226,6 +226,8 @@ static struct radeon_hpd radeon_atom_get_hpd_info_from_gpio(struct radeon_device | |||
226 | struct radeon_hpd hpd; | 226 | struct radeon_hpd hpd; |
227 | u32 reg; | 227 | u32 reg; |
228 | 228 | ||
229 | memset(&hpd, 0, sizeof(struct radeon_hpd)); | ||
230 | |||
229 | if (ASIC_IS_DCE4(rdev)) | 231 | if (ASIC_IS_DCE4(rdev)) |
230 | reg = EVERGREEN_DC_GPIO_HPD_A; | 232 | reg = EVERGREEN_DC_GPIO_HPD_A; |
231 | else | 233 | else |
@@ -477,7 +479,6 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
477 | int i, j, k, path_size, device_support; | 479 | int i, j, k, path_size, device_support; |
478 | int connector_type; | 480 | int connector_type; |
479 | u16 igp_lane_info, conn_id, connector_object_id; | 481 | u16 igp_lane_info, conn_id, connector_object_id; |
480 | bool linkb; | ||
481 | struct radeon_i2c_bus_rec ddc_bus; | 482 | struct radeon_i2c_bus_rec ddc_bus; |
482 | struct radeon_router router; | 483 | struct radeon_router router; |
483 | struct radeon_gpio_rec gpio; | 484 | struct radeon_gpio_rec gpio; |
@@ -510,7 +511,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
510 | addr += path_size; | 511 | addr += path_size; |
511 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; | 512 | path = (ATOM_DISPLAY_OBJECT_PATH *) addr; |
512 | path_size += le16_to_cpu(path->usSize); | 513 | path_size += le16_to_cpu(path->usSize); |
513 | linkb = false; | 514 | |
514 | if (device_support & le16_to_cpu(path->usDeviceTag)) { | 515 | if (device_support & le16_to_cpu(path->usDeviceTag)) { |
515 | uint8_t con_obj_id, con_obj_num, con_obj_type; | 516 | uint8_t con_obj_id, con_obj_num, con_obj_type; |
516 | 517 | ||
@@ -601,13 +602,10 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
601 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; | 602 | OBJECT_TYPE_MASK) >> OBJECT_TYPE_SHIFT; |
602 | 603 | ||
603 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { | 604 | if (grph_obj_type == GRAPH_OBJECT_TYPE_ENCODER) { |
604 | if (grph_obj_num == 2) | 605 | u16 encoder_obj = le16_to_cpu(path->usGraphicObjIds[j]); |
605 | linkb = true; | ||
606 | else | ||
607 | linkb = false; | ||
608 | 606 | ||
609 | radeon_add_atom_encoder(dev, | 607 | radeon_add_atom_encoder(dev, |
610 | grph_obj_id, | 608 | encoder_obj, |
611 | le16_to_cpu | 609 | le16_to_cpu |
612 | (path-> | 610 | (path-> |
613 | usDeviceTag)); | 611 | usDeviceTag)); |
@@ -744,7 +742,7 @@ bool radeon_get_atom_connector_info_from_object_table(struct drm_device *dev) | |||
744 | le16_to_cpu(path-> | 742 | le16_to_cpu(path-> |
745 | usDeviceTag), | 743 | usDeviceTag), |
746 | connector_type, &ddc_bus, | 744 | connector_type, &ddc_bus, |
747 | linkb, igp_lane_info, | 745 | igp_lane_info, |
748 | connector_object_id, | 746 | connector_object_id, |
749 | &hpd, | 747 | &hpd, |
750 | &router); | 748 | &router); |
@@ -933,13 +931,13 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
933 | 931 | ||
934 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) | 932 | if (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom) |
935 | radeon_add_atom_encoder(dev, | 933 | radeon_add_atom_encoder(dev, |
936 | radeon_get_encoder_id(dev, | 934 | radeon_get_encoder_enum(dev, |
937 | (1 << i), | 935 | (1 << i), |
938 | dac), | 936 | dac), |
939 | (1 << i)); | 937 | (1 << i)); |
940 | else | 938 | else |
941 | radeon_add_legacy_encoder(dev, | 939 | radeon_add_legacy_encoder(dev, |
942 | radeon_get_encoder_id(dev, | 940 | radeon_get_encoder_enum(dev, |
943 | (1 << i), | 941 | (1 << i), |
944 | dac), | 942 | dac), |
945 | (1 << i)); | 943 | (1 << i)); |
@@ -996,7 +994,7 @@ bool radeon_get_atom_connector_info_from_supported_devices_table(struct | |||
996 | bios_connectors[i]. | 994 | bios_connectors[i]. |
997 | connector_type, | 995 | connector_type, |
998 | &bios_connectors[i].ddc_bus, | 996 | &bios_connectors[i].ddc_bus, |
999 | false, 0, | 997 | 0, |
1000 | connector_object_id, | 998 | connector_object_id, |
1001 | &bios_connectors[i].hpd, | 999 | &bios_connectors[i].hpd, |
1002 | &router); | 1000 | &router); |
@@ -1183,7 +1181,7 @@ bool radeon_atombios_sideport_present(struct radeon_device *rdev) | |||
1183 | return true; | 1181 | return true; |
1184 | break; | 1182 | break; |
1185 | case 2: | 1183 | case 2: |
1186 | if (igp_info->info_2.ucMemoryType & 0x0f) | 1184 | if (igp_info->info_2.ulBootUpSidePortClock) |
1187 | return true; | 1185 | return true; |
1188 | break; | 1186 | break; |
1189 | default: | 1187 | default: |
@@ -1305,6 +1303,7 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1305 | union lvds_info *lvds_info; | 1303 | union lvds_info *lvds_info; |
1306 | uint8_t frev, crev; | 1304 | uint8_t frev, crev; |
1307 | struct radeon_encoder_atom_dig *lvds = NULL; | 1305 | struct radeon_encoder_atom_dig *lvds = NULL; |
1306 | int encoder_enum = (encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
1308 | 1307 | ||
1309 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 1308 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
1310 | &frev, &crev, &data_offset)) { | 1309 | &frev, &crev, &data_offset)) { |
@@ -1368,6 +1367,12 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1368 | } | 1367 | } |
1369 | 1368 | ||
1370 | encoder->native_mode = lvds->native_mode; | 1369 | encoder->native_mode = lvds->native_mode; |
1370 | |||
1371 | if (encoder_enum == 2) | ||
1372 | lvds->linkb = true; | ||
1373 | else | ||
1374 | lvds->linkb = false; | ||
1375 | |||
1371 | } | 1376 | } |
1372 | return lvds; | 1377 | return lvds; |
1373 | } | 1378 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 885dcfac1838..bd74e428bd14 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -39,8 +39,8 @@ | |||
39 | 39 | ||
40 | /* from radeon_encoder.c */ | 40 | /* from radeon_encoder.c */ |
41 | extern uint32_t | 41 | extern uint32_t |
42 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, | 42 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, |
43 | uint8_t dac); | 43 | uint8_t dac); |
44 | extern void radeon_link_encoder_connector(struct drm_device *dev); | 44 | extern void radeon_link_encoder_connector(struct drm_device *dev); |
45 | 45 | ||
46 | /* from radeon_connector.c */ | 46 | /* from radeon_connector.c */ |
@@ -55,7 +55,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
55 | 55 | ||
56 | /* from radeon_legacy_encoder.c */ | 56 | /* from radeon_legacy_encoder.c */ |
57 | extern void | 57 | extern void |
58 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, | 58 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, |
59 | uint32_t supported_device); | 59 | uint32_t supported_device); |
60 | 60 | ||
61 | /* old legacy ATI BIOS routines */ | 61 | /* old legacy ATI BIOS routines */ |
@@ -1505,7 +1505,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1505 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1505 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1506 | hpd.hpd = RADEON_HPD_NONE; | 1506 | hpd.hpd = RADEON_HPD_NONE; |
1507 | radeon_add_legacy_encoder(dev, | 1507 | radeon_add_legacy_encoder(dev, |
1508 | radeon_get_encoder_id(dev, | 1508 | radeon_get_encoder_enum(dev, |
1509 | ATOM_DEVICE_CRT1_SUPPORT, | 1509 | ATOM_DEVICE_CRT1_SUPPORT, |
1510 | 1), | 1510 | 1), |
1511 | ATOM_DEVICE_CRT1_SUPPORT); | 1511 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1520,7 +1520,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1520 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); | 1520 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_NONE_DETECTED, 0, 0); |
1521 | hpd.hpd = RADEON_HPD_NONE; | 1521 | hpd.hpd = RADEON_HPD_NONE; |
1522 | radeon_add_legacy_encoder(dev, | 1522 | radeon_add_legacy_encoder(dev, |
1523 | radeon_get_encoder_id(dev, | 1523 | radeon_get_encoder_enum(dev, |
1524 | ATOM_DEVICE_LCD1_SUPPORT, | 1524 | ATOM_DEVICE_LCD1_SUPPORT, |
1525 | 0), | 1525 | 0), |
1526 | ATOM_DEVICE_LCD1_SUPPORT); | 1526 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1535,7 +1535,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1535 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1535 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1536 | hpd.hpd = RADEON_HPD_NONE; | 1536 | hpd.hpd = RADEON_HPD_NONE; |
1537 | radeon_add_legacy_encoder(dev, | 1537 | radeon_add_legacy_encoder(dev, |
1538 | radeon_get_encoder_id(dev, | 1538 | radeon_get_encoder_enum(dev, |
1539 | ATOM_DEVICE_CRT1_SUPPORT, | 1539 | ATOM_DEVICE_CRT1_SUPPORT, |
1540 | 1), | 1540 | 1), |
1541 | ATOM_DEVICE_CRT1_SUPPORT); | 1541 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1550,12 +1550,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1550 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1550 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1551 | hpd.hpd = RADEON_HPD_1; | 1551 | hpd.hpd = RADEON_HPD_1; |
1552 | radeon_add_legacy_encoder(dev, | 1552 | radeon_add_legacy_encoder(dev, |
1553 | radeon_get_encoder_id(dev, | 1553 | radeon_get_encoder_enum(dev, |
1554 | ATOM_DEVICE_DFP1_SUPPORT, | 1554 | ATOM_DEVICE_DFP1_SUPPORT, |
1555 | 0), | 1555 | 0), |
1556 | ATOM_DEVICE_DFP1_SUPPORT); | 1556 | ATOM_DEVICE_DFP1_SUPPORT); |
1557 | radeon_add_legacy_encoder(dev, | 1557 | radeon_add_legacy_encoder(dev, |
1558 | radeon_get_encoder_id(dev, | 1558 | radeon_get_encoder_enum(dev, |
1559 | ATOM_DEVICE_CRT2_SUPPORT, | 1559 | ATOM_DEVICE_CRT2_SUPPORT, |
1560 | 2), | 1560 | 2), |
1561 | ATOM_DEVICE_CRT2_SUPPORT); | 1561 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1571,7 +1571,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1571 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1571 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1572 | hpd.hpd = RADEON_HPD_NONE; | 1572 | hpd.hpd = RADEON_HPD_NONE; |
1573 | radeon_add_legacy_encoder(dev, | 1573 | radeon_add_legacy_encoder(dev, |
1574 | radeon_get_encoder_id(dev, | 1574 | radeon_get_encoder_enum(dev, |
1575 | ATOM_DEVICE_CRT1_SUPPORT, | 1575 | ATOM_DEVICE_CRT1_SUPPORT, |
1576 | 1), | 1576 | 1), |
1577 | ATOM_DEVICE_CRT1_SUPPORT); | 1577 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1588,7 +1588,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1588 | ddc_i2c.valid = false; | 1588 | ddc_i2c.valid = false; |
1589 | hpd.hpd = RADEON_HPD_NONE; | 1589 | hpd.hpd = RADEON_HPD_NONE; |
1590 | radeon_add_legacy_encoder(dev, | 1590 | radeon_add_legacy_encoder(dev, |
1591 | radeon_get_encoder_id(dev, | 1591 | radeon_get_encoder_enum(dev, |
1592 | ATOM_DEVICE_TV1_SUPPORT, | 1592 | ATOM_DEVICE_TV1_SUPPORT, |
1593 | 2), | 1593 | 2), |
1594 | ATOM_DEVICE_TV1_SUPPORT); | 1594 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1607,7 +1607,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1607 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1607 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1608 | hpd.hpd = RADEON_HPD_NONE; | 1608 | hpd.hpd = RADEON_HPD_NONE; |
1609 | radeon_add_legacy_encoder(dev, | 1609 | radeon_add_legacy_encoder(dev, |
1610 | radeon_get_encoder_id(dev, | 1610 | radeon_get_encoder_enum(dev, |
1611 | ATOM_DEVICE_LCD1_SUPPORT, | 1611 | ATOM_DEVICE_LCD1_SUPPORT, |
1612 | 0), | 1612 | 0), |
1613 | ATOM_DEVICE_LCD1_SUPPORT); | 1613 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1619,7 +1619,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1619 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1619 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1620 | hpd.hpd = RADEON_HPD_NONE; | 1620 | hpd.hpd = RADEON_HPD_NONE; |
1621 | radeon_add_legacy_encoder(dev, | 1621 | radeon_add_legacy_encoder(dev, |
1622 | radeon_get_encoder_id(dev, | 1622 | radeon_get_encoder_enum(dev, |
1623 | ATOM_DEVICE_CRT2_SUPPORT, | 1623 | ATOM_DEVICE_CRT2_SUPPORT, |
1624 | 2), | 1624 | 2), |
1625 | ATOM_DEVICE_CRT2_SUPPORT); | 1625 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1631,7 +1631,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1631 | ddc_i2c.valid = false; | 1631 | ddc_i2c.valid = false; |
1632 | hpd.hpd = RADEON_HPD_NONE; | 1632 | hpd.hpd = RADEON_HPD_NONE; |
1633 | radeon_add_legacy_encoder(dev, | 1633 | radeon_add_legacy_encoder(dev, |
1634 | radeon_get_encoder_id(dev, | 1634 | radeon_get_encoder_enum(dev, |
1635 | ATOM_DEVICE_TV1_SUPPORT, | 1635 | ATOM_DEVICE_TV1_SUPPORT, |
1636 | 2), | 1636 | 2), |
1637 | ATOM_DEVICE_TV1_SUPPORT); | 1637 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1648,7 +1648,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1648 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1648 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1649 | hpd.hpd = RADEON_HPD_NONE; | 1649 | hpd.hpd = RADEON_HPD_NONE; |
1650 | radeon_add_legacy_encoder(dev, | 1650 | radeon_add_legacy_encoder(dev, |
1651 | radeon_get_encoder_id(dev, | 1651 | radeon_get_encoder_enum(dev, |
1652 | ATOM_DEVICE_LCD1_SUPPORT, | 1652 | ATOM_DEVICE_LCD1_SUPPORT, |
1653 | 0), | 1653 | 0), |
1654 | ATOM_DEVICE_LCD1_SUPPORT); | 1654 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1660,12 +1660,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1660 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1660 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1661 | hpd.hpd = RADEON_HPD_2; /* ??? */ | 1661 | hpd.hpd = RADEON_HPD_2; /* ??? */ |
1662 | radeon_add_legacy_encoder(dev, | 1662 | radeon_add_legacy_encoder(dev, |
1663 | radeon_get_encoder_id(dev, | 1663 | radeon_get_encoder_enum(dev, |
1664 | ATOM_DEVICE_DFP2_SUPPORT, | 1664 | ATOM_DEVICE_DFP2_SUPPORT, |
1665 | 0), | 1665 | 0), |
1666 | ATOM_DEVICE_DFP2_SUPPORT); | 1666 | ATOM_DEVICE_DFP2_SUPPORT); |
1667 | radeon_add_legacy_encoder(dev, | 1667 | radeon_add_legacy_encoder(dev, |
1668 | radeon_get_encoder_id(dev, | 1668 | radeon_get_encoder_enum(dev, |
1669 | ATOM_DEVICE_CRT1_SUPPORT, | 1669 | ATOM_DEVICE_CRT1_SUPPORT, |
1670 | 1), | 1670 | 1), |
1671 | ATOM_DEVICE_CRT1_SUPPORT); | 1671 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1680,7 +1680,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1680 | ddc_i2c.valid = false; | 1680 | ddc_i2c.valid = false; |
1681 | hpd.hpd = RADEON_HPD_NONE; | 1681 | hpd.hpd = RADEON_HPD_NONE; |
1682 | radeon_add_legacy_encoder(dev, | 1682 | radeon_add_legacy_encoder(dev, |
1683 | radeon_get_encoder_id(dev, | 1683 | radeon_get_encoder_enum(dev, |
1684 | ATOM_DEVICE_TV1_SUPPORT, | 1684 | ATOM_DEVICE_TV1_SUPPORT, |
1685 | 2), | 1685 | 2), |
1686 | ATOM_DEVICE_TV1_SUPPORT); | 1686 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1697,7 +1697,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1697 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1697 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1698 | hpd.hpd = RADEON_HPD_NONE; | 1698 | hpd.hpd = RADEON_HPD_NONE; |
1699 | radeon_add_legacy_encoder(dev, | 1699 | radeon_add_legacy_encoder(dev, |
1700 | radeon_get_encoder_id(dev, | 1700 | radeon_get_encoder_enum(dev, |
1701 | ATOM_DEVICE_LCD1_SUPPORT, | 1701 | ATOM_DEVICE_LCD1_SUPPORT, |
1702 | 0), | 1702 | 0), |
1703 | ATOM_DEVICE_LCD1_SUPPORT); | 1703 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1709,12 +1709,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1709 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1709 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1710 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1710 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1711 | radeon_add_legacy_encoder(dev, | 1711 | radeon_add_legacy_encoder(dev, |
1712 | radeon_get_encoder_id(dev, | 1712 | radeon_get_encoder_enum(dev, |
1713 | ATOM_DEVICE_DFP1_SUPPORT, | 1713 | ATOM_DEVICE_DFP1_SUPPORT, |
1714 | 0), | 1714 | 0), |
1715 | ATOM_DEVICE_DFP1_SUPPORT); | 1715 | ATOM_DEVICE_DFP1_SUPPORT); |
1716 | radeon_add_legacy_encoder(dev, | 1716 | radeon_add_legacy_encoder(dev, |
1717 | radeon_get_encoder_id(dev, | 1717 | radeon_get_encoder_enum(dev, |
1718 | ATOM_DEVICE_CRT1_SUPPORT, | 1718 | ATOM_DEVICE_CRT1_SUPPORT, |
1719 | 1), | 1719 | 1), |
1720 | ATOM_DEVICE_CRT1_SUPPORT); | 1720 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1728,7 +1728,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1728 | ddc_i2c.valid = false; | 1728 | ddc_i2c.valid = false; |
1729 | hpd.hpd = RADEON_HPD_NONE; | 1729 | hpd.hpd = RADEON_HPD_NONE; |
1730 | radeon_add_legacy_encoder(dev, | 1730 | radeon_add_legacy_encoder(dev, |
1731 | radeon_get_encoder_id(dev, | 1731 | radeon_get_encoder_enum(dev, |
1732 | ATOM_DEVICE_TV1_SUPPORT, | 1732 | ATOM_DEVICE_TV1_SUPPORT, |
1733 | 2), | 1733 | 2), |
1734 | ATOM_DEVICE_TV1_SUPPORT); | 1734 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1745,7 +1745,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1745 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1745 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1746 | hpd.hpd = RADEON_HPD_NONE; | 1746 | hpd.hpd = RADEON_HPD_NONE; |
1747 | radeon_add_legacy_encoder(dev, | 1747 | radeon_add_legacy_encoder(dev, |
1748 | radeon_get_encoder_id(dev, | 1748 | radeon_get_encoder_enum(dev, |
1749 | ATOM_DEVICE_LCD1_SUPPORT, | 1749 | ATOM_DEVICE_LCD1_SUPPORT, |
1750 | 0), | 1750 | 0), |
1751 | ATOM_DEVICE_LCD1_SUPPORT); | 1751 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -1757,7 +1757,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1757 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1757 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1758 | hpd.hpd = RADEON_HPD_NONE; | 1758 | hpd.hpd = RADEON_HPD_NONE; |
1759 | radeon_add_legacy_encoder(dev, | 1759 | radeon_add_legacy_encoder(dev, |
1760 | radeon_get_encoder_id(dev, | 1760 | radeon_get_encoder_enum(dev, |
1761 | ATOM_DEVICE_CRT1_SUPPORT, | 1761 | ATOM_DEVICE_CRT1_SUPPORT, |
1762 | 1), | 1762 | 1), |
1763 | ATOM_DEVICE_CRT1_SUPPORT); | 1763 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1769,7 +1769,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1769 | ddc_i2c.valid = false; | 1769 | ddc_i2c.valid = false; |
1770 | hpd.hpd = RADEON_HPD_NONE; | 1770 | hpd.hpd = RADEON_HPD_NONE; |
1771 | radeon_add_legacy_encoder(dev, | 1771 | radeon_add_legacy_encoder(dev, |
1772 | radeon_get_encoder_id(dev, | 1772 | radeon_get_encoder_enum(dev, |
1773 | ATOM_DEVICE_TV1_SUPPORT, | 1773 | ATOM_DEVICE_TV1_SUPPORT, |
1774 | 2), | 1774 | 2), |
1775 | ATOM_DEVICE_TV1_SUPPORT); | 1775 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1786,12 +1786,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1786 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1786 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1787 | hpd.hpd = RADEON_HPD_2; /* ??? */ | 1787 | hpd.hpd = RADEON_HPD_2; /* ??? */ |
1788 | radeon_add_legacy_encoder(dev, | 1788 | radeon_add_legacy_encoder(dev, |
1789 | radeon_get_encoder_id(dev, | 1789 | radeon_get_encoder_enum(dev, |
1790 | ATOM_DEVICE_DFP2_SUPPORT, | 1790 | ATOM_DEVICE_DFP2_SUPPORT, |
1791 | 0), | 1791 | 0), |
1792 | ATOM_DEVICE_DFP2_SUPPORT); | 1792 | ATOM_DEVICE_DFP2_SUPPORT); |
1793 | radeon_add_legacy_encoder(dev, | 1793 | radeon_add_legacy_encoder(dev, |
1794 | radeon_get_encoder_id(dev, | 1794 | radeon_get_encoder_enum(dev, |
1795 | ATOM_DEVICE_CRT2_SUPPORT, | 1795 | ATOM_DEVICE_CRT2_SUPPORT, |
1796 | 2), | 1796 | 2), |
1797 | ATOM_DEVICE_CRT2_SUPPORT); | 1797 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1806,7 +1806,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1806 | ddc_i2c.valid = false; | 1806 | ddc_i2c.valid = false; |
1807 | hpd.hpd = RADEON_HPD_NONE; | 1807 | hpd.hpd = RADEON_HPD_NONE; |
1808 | radeon_add_legacy_encoder(dev, | 1808 | radeon_add_legacy_encoder(dev, |
1809 | radeon_get_encoder_id(dev, | 1809 | radeon_get_encoder_enum(dev, |
1810 | ATOM_DEVICE_TV1_SUPPORT, | 1810 | ATOM_DEVICE_TV1_SUPPORT, |
1811 | 2), | 1811 | 2), |
1812 | ATOM_DEVICE_TV1_SUPPORT); | 1812 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1823,12 +1823,12 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1823 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1823 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1824 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1824 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1825 | radeon_add_legacy_encoder(dev, | 1825 | radeon_add_legacy_encoder(dev, |
1826 | radeon_get_encoder_id(dev, | 1826 | radeon_get_encoder_enum(dev, |
1827 | ATOM_DEVICE_DFP1_SUPPORT, | 1827 | ATOM_DEVICE_DFP1_SUPPORT, |
1828 | 0), | 1828 | 0), |
1829 | ATOM_DEVICE_DFP1_SUPPORT); | 1829 | ATOM_DEVICE_DFP1_SUPPORT); |
1830 | radeon_add_legacy_encoder(dev, | 1830 | radeon_add_legacy_encoder(dev, |
1831 | radeon_get_encoder_id(dev, | 1831 | radeon_get_encoder_enum(dev, |
1832 | ATOM_DEVICE_CRT2_SUPPORT, | 1832 | ATOM_DEVICE_CRT2_SUPPORT, |
1833 | 2), | 1833 | 2), |
1834 | ATOM_DEVICE_CRT2_SUPPORT); | 1834 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1842,7 +1842,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1842 | ddc_i2c.valid = false; | 1842 | ddc_i2c.valid = false; |
1843 | hpd.hpd = RADEON_HPD_NONE; | 1843 | hpd.hpd = RADEON_HPD_NONE; |
1844 | radeon_add_legacy_encoder(dev, | 1844 | radeon_add_legacy_encoder(dev, |
1845 | radeon_get_encoder_id(dev, | 1845 | radeon_get_encoder_enum(dev, |
1846 | ATOM_DEVICE_TV1_SUPPORT, | 1846 | ATOM_DEVICE_TV1_SUPPORT, |
1847 | 2), | 1847 | 2), |
1848 | ATOM_DEVICE_TV1_SUPPORT); | 1848 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1859,7 +1859,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1859 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); | 1859 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); |
1860 | hpd.hpd = RADEON_HPD_1; /* ??? */ | 1860 | hpd.hpd = RADEON_HPD_1; /* ??? */ |
1861 | radeon_add_legacy_encoder(dev, | 1861 | radeon_add_legacy_encoder(dev, |
1862 | radeon_get_encoder_id(dev, | 1862 | radeon_get_encoder_enum(dev, |
1863 | ATOM_DEVICE_DFP1_SUPPORT, | 1863 | ATOM_DEVICE_DFP1_SUPPORT, |
1864 | 0), | 1864 | 0), |
1865 | ATOM_DEVICE_DFP1_SUPPORT); | 1865 | ATOM_DEVICE_DFP1_SUPPORT); |
@@ -1871,7 +1871,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1871 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); | 1871 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0); |
1872 | hpd.hpd = RADEON_HPD_NONE; | 1872 | hpd.hpd = RADEON_HPD_NONE; |
1873 | radeon_add_legacy_encoder(dev, | 1873 | radeon_add_legacy_encoder(dev, |
1874 | radeon_get_encoder_id(dev, | 1874 | radeon_get_encoder_enum(dev, |
1875 | ATOM_DEVICE_CRT2_SUPPORT, | 1875 | ATOM_DEVICE_CRT2_SUPPORT, |
1876 | 2), | 1876 | 2), |
1877 | ATOM_DEVICE_CRT2_SUPPORT); | 1877 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1883,7 +1883,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1883 | ddc_i2c.valid = false; | 1883 | ddc_i2c.valid = false; |
1884 | hpd.hpd = RADEON_HPD_NONE; | 1884 | hpd.hpd = RADEON_HPD_NONE; |
1885 | radeon_add_legacy_encoder(dev, | 1885 | radeon_add_legacy_encoder(dev, |
1886 | radeon_get_encoder_id(dev, | 1886 | radeon_get_encoder_enum(dev, |
1887 | ATOM_DEVICE_TV1_SUPPORT, | 1887 | ATOM_DEVICE_TV1_SUPPORT, |
1888 | 2), | 1888 | 2), |
1889 | ATOM_DEVICE_TV1_SUPPORT); | 1889 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1900,7 +1900,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1900 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1900 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1901 | hpd.hpd = RADEON_HPD_NONE; | 1901 | hpd.hpd = RADEON_HPD_NONE; |
1902 | radeon_add_legacy_encoder(dev, | 1902 | radeon_add_legacy_encoder(dev, |
1903 | radeon_get_encoder_id(dev, | 1903 | radeon_get_encoder_enum(dev, |
1904 | ATOM_DEVICE_CRT1_SUPPORT, | 1904 | ATOM_DEVICE_CRT1_SUPPORT, |
1905 | 1), | 1905 | 1), |
1906 | ATOM_DEVICE_CRT1_SUPPORT); | 1906 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1912,7 +1912,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1912 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1912 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1913 | hpd.hpd = RADEON_HPD_NONE; | 1913 | hpd.hpd = RADEON_HPD_NONE; |
1914 | radeon_add_legacy_encoder(dev, | 1914 | radeon_add_legacy_encoder(dev, |
1915 | radeon_get_encoder_id(dev, | 1915 | radeon_get_encoder_enum(dev, |
1916 | ATOM_DEVICE_CRT2_SUPPORT, | 1916 | ATOM_DEVICE_CRT2_SUPPORT, |
1917 | 2), | 1917 | 2), |
1918 | ATOM_DEVICE_CRT2_SUPPORT); | 1918 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -1924,7 +1924,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1924 | ddc_i2c.valid = false; | 1924 | ddc_i2c.valid = false; |
1925 | hpd.hpd = RADEON_HPD_NONE; | 1925 | hpd.hpd = RADEON_HPD_NONE; |
1926 | radeon_add_legacy_encoder(dev, | 1926 | radeon_add_legacy_encoder(dev, |
1927 | radeon_get_encoder_id(dev, | 1927 | radeon_get_encoder_enum(dev, |
1928 | ATOM_DEVICE_TV1_SUPPORT, | 1928 | ATOM_DEVICE_TV1_SUPPORT, |
1929 | 2), | 1929 | 2), |
1930 | ATOM_DEVICE_TV1_SUPPORT); | 1930 | ATOM_DEVICE_TV1_SUPPORT); |
@@ -1941,7 +1941,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1941 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); | 1941 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0); |
1942 | hpd.hpd = RADEON_HPD_NONE; | 1942 | hpd.hpd = RADEON_HPD_NONE; |
1943 | radeon_add_legacy_encoder(dev, | 1943 | radeon_add_legacy_encoder(dev, |
1944 | radeon_get_encoder_id(dev, | 1944 | radeon_get_encoder_enum(dev, |
1945 | ATOM_DEVICE_CRT1_SUPPORT, | 1945 | ATOM_DEVICE_CRT1_SUPPORT, |
1946 | 1), | 1946 | 1), |
1947 | ATOM_DEVICE_CRT1_SUPPORT); | 1947 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -1952,7 +1952,7 @@ bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) | |||
1952 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 1952 | ddc_i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
1953 | hpd.hpd = RADEON_HPD_NONE; | 1953 | hpd.hpd = RADEON_HPD_NONE; |
1954 | radeon_add_legacy_encoder(dev, | 1954 | radeon_add_legacy_encoder(dev, |
1955 | radeon_get_encoder_id(dev, | 1955 | radeon_get_encoder_enum(dev, |
1956 | ATOM_DEVICE_CRT2_SUPPORT, | 1956 | ATOM_DEVICE_CRT2_SUPPORT, |
1957 | 2), | 1957 | 2), |
1958 | ATOM_DEVICE_CRT2_SUPPORT); | 1958 | ATOM_DEVICE_CRT2_SUPPORT); |
@@ -2109,7 +2109,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2109 | else | 2109 | else |
2110 | devices = ATOM_DEVICE_DFP1_SUPPORT; | 2110 | devices = ATOM_DEVICE_DFP1_SUPPORT; |
2111 | radeon_add_legacy_encoder(dev, | 2111 | radeon_add_legacy_encoder(dev, |
2112 | radeon_get_encoder_id | 2112 | radeon_get_encoder_enum |
2113 | (dev, devices, 0), | 2113 | (dev, devices, 0), |
2114 | devices); | 2114 | devices); |
2115 | radeon_add_legacy_connector(dev, i, devices, | 2115 | radeon_add_legacy_connector(dev, i, devices, |
@@ -2123,7 +2123,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2123 | if (tmp & 0x1) { | 2123 | if (tmp & 0x1) { |
2124 | devices = ATOM_DEVICE_CRT2_SUPPORT; | 2124 | devices = ATOM_DEVICE_CRT2_SUPPORT; |
2125 | radeon_add_legacy_encoder(dev, | 2125 | radeon_add_legacy_encoder(dev, |
2126 | radeon_get_encoder_id | 2126 | radeon_get_encoder_enum |
2127 | (dev, | 2127 | (dev, |
2128 | ATOM_DEVICE_CRT2_SUPPORT, | 2128 | ATOM_DEVICE_CRT2_SUPPORT, |
2129 | 2), | 2129 | 2), |
@@ -2131,7 +2131,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2131 | } else { | 2131 | } else { |
2132 | devices = ATOM_DEVICE_CRT1_SUPPORT; | 2132 | devices = ATOM_DEVICE_CRT1_SUPPORT; |
2133 | radeon_add_legacy_encoder(dev, | 2133 | radeon_add_legacy_encoder(dev, |
2134 | radeon_get_encoder_id | 2134 | radeon_get_encoder_enum |
2135 | (dev, | 2135 | (dev, |
2136 | ATOM_DEVICE_CRT1_SUPPORT, | 2136 | ATOM_DEVICE_CRT1_SUPPORT, |
2137 | 1), | 2137 | 1), |
@@ -2151,7 +2151,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2151 | if (tmp & 0x1) { | 2151 | if (tmp & 0x1) { |
2152 | devices |= ATOM_DEVICE_CRT2_SUPPORT; | 2152 | devices |= ATOM_DEVICE_CRT2_SUPPORT; |
2153 | radeon_add_legacy_encoder(dev, | 2153 | radeon_add_legacy_encoder(dev, |
2154 | radeon_get_encoder_id | 2154 | radeon_get_encoder_enum |
2155 | (dev, | 2155 | (dev, |
2156 | ATOM_DEVICE_CRT2_SUPPORT, | 2156 | ATOM_DEVICE_CRT2_SUPPORT, |
2157 | 2), | 2157 | 2), |
@@ -2159,7 +2159,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2159 | } else { | 2159 | } else { |
2160 | devices |= ATOM_DEVICE_CRT1_SUPPORT; | 2160 | devices |= ATOM_DEVICE_CRT1_SUPPORT; |
2161 | radeon_add_legacy_encoder(dev, | 2161 | radeon_add_legacy_encoder(dev, |
2162 | radeon_get_encoder_id | 2162 | radeon_get_encoder_enum |
2163 | (dev, | 2163 | (dev, |
2164 | ATOM_DEVICE_CRT1_SUPPORT, | 2164 | ATOM_DEVICE_CRT1_SUPPORT, |
2165 | 1), | 2165 | 1), |
@@ -2168,7 +2168,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2168 | if ((tmp >> 4) & 0x1) { | 2168 | if ((tmp >> 4) & 0x1) { |
2169 | devices |= ATOM_DEVICE_DFP2_SUPPORT; | 2169 | devices |= ATOM_DEVICE_DFP2_SUPPORT; |
2170 | radeon_add_legacy_encoder(dev, | 2170 | radeon_add_legacy_encoder(dev, |
2171 | radeon_get_encoder_id | 2171 | radeon_get_encoder_enum |
2172 | (dev, | 2172 | (dev, |
2173 | ATOM_DEVICE_DFP2_SUPPORT, | 2173 | ATOM_DEVICE_DFP2_SUPPORT, |
2174 | 0), | 2174 | 0), |
@@ -2177,7 +2177,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2177 | } else { | 2177 | } else { |
2178 | devices |= ATOM_DEVICE_DFP1_SUPPORT; | 2178 | devices |= ATOM_DEVICE_DFP1_SUPPORT; |
2179 | radeon_add_legacy_encoder(dev, | 2179 | radeon_add_legacy_encoder(dev, |
2180 | radeon_get_encoder_id | 2180 | radeon_get_encoder_enum |
2181 | (dev, | 2181 | (dev, |
2182 | ATOM_DEVICE_DFP1_SUPPORT, | 2182 | ATOM_DEVICE_DFP1_SUPPORT, |
2183 | 0), | 2183 | 0), |
@@ -2202,7 +2202,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2202 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; | 2202 | connector_object_id = CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_I; |
2203 | } | 2203 | } |
2204 | radeon_add_legacy_encoder(dev, | 2204 | radeon_add_legacy_encoder(dev, |
2205 | radeon_get_encoder_id | 2205 | radeon_get_encoder_enum |
2206 | (dev, devices, 0), | 2206 | (dev, devices, 0), |
2207 | devices); | 2207 | devices); |
2208 | radeon_add_legacy_connector(dev, i, devices, | 2208 | radeon_add_legacy_connector(dev, i, devices, |
@@ -2215,7 +2215,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2215 | case CONNECTOR_CTV_LEGACY: | 2215 | case CONNECTOR_CTV_LEGACY: |
2216 | case CONNECTOR_STV_LEGACY: | 2216 | case CONNECTOR_STV_LEGACY: |
2217 | radeon_add_legacy_encoder(dev, | 2217 | radeon_add_legacy_encoder(dev, |
2218 | radeon_get_encoder_id | 2218 | radeon_get_encoder_enum |
2219 | (dev, | 2219 | (dev, |
2220 | ATOM_DEVICE_TV1_SUPPORT, | 2220 | ATOM_DEVICE_TV1_SUPPORT, |
2221 | 2), | 2221 | 2), |
@@ -2242,12 +2242,12 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2242 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); | 2242 | DRM_DEBUG_KMS("Found DFP table, assuming DVI connector\n"); |
2243 | 2243 | ||
2244 | radeon_add_legacy_encoder(dev, | 2244 | radeon_add_legacy_encoder(dev, |
2245 | radeon_get_encoder_id(dev, | 2245 | radeon_get_encoder_enum(dev, |
2246 | ATOM_DEVICE_CRT1_SUPPORT, | 2246 | ATOM_DEVICE_CRT1_SUPPORT, |
2247 | 1), | 2247 | 1), |
2248 | ATOM_DEVICE_CRT1_SUPPORT); | 2248 | ATOM_DEVICE_CRT1_SUPPORT); |
2249 | radeon_add_legacy_encoder(dev, | 2249 | radeon_add_legacy_encoder(dev, |
2250 | radeon_get_encoder_id(dev, | 2250 | radeon_get_encoder_enum(dev, |
2251 | ATOM_DEVICE_DFP1_SUPPORT, | 2251 | ATOM_DEVICE_DFP1_SUPPORT, |
2252 | 0), | 2252 | 0), |
2253 | ATOM_DEVICE_DFP1_SUPPORT); | 2253 | ATOM_DEVICE_DFP1_SUPPORT); |
@@ -2268,7 +2268,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2268 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); | 2268 | DRM_DEBUG_KMS("Found CRT table, assuming VGA connector\n"); |
2269 | if (crt_info) { | 2269 | if (crt_info) { |
2270 | radeon_add_legacy_encoder(dev, | 2270 | radeon_add_legacy_encoder(dev, |
2271 | radeon_get_encoder_id(dev, | 2271 | radeon_get_encoder_enum(dev, |
2272 | ATOM_DEVICE_CRT1_SUPPORT, | 2272 | ATOM_DEVICE_CRT1_SUPPORT, |
2273 | 1), | 2273 | 1), |
2274 | ATOM_DEVICE_CRT1_SUPPORT); | 2274 | ATOM_DEVICE_CRT1_SUPPORT); |
@@ -2297,7 +2297,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2297 | COMBIOS_LCD_DDC_INFO_TABLE); | 2297 | COMBIOS_LCD_DDC_INFO_TABLE); |
2298 | 2298 | ||
2299 | radeon_add_legacy_encoder(dev, | 2299 | radeon_add_legacy_encoder(dev, |
2300 | radeon_get_encoder_id(dev, | 2300 | radeon_get_encoder_enum(dev, |
2301 | ATOM_DEVICE_LCD1_SUPPORT, | 2301 | ATOM_DEVICE_LCD1_SUPPORT, |
2302 | 0), | 2302 | 0), |
2303 | ATOM_DEVICE_LCD1_SUPPORT); | 2303 | ATOM_DEVICE_LCD1_SUPPORT); |
@@ -2351,7 +2351,7 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2351 | hpd.hpd = RADEON_HPD_NONE; | 2351 | hpd.hpd = RADEON_HPD_NONE; |
2352 | ddc_i2c.valid = false; | 2352 | ddc_i2c.valid = false; |
2353 | radeon_add_legacy_encoder(dev, | 2353 | radeon_add_legacy_encoder(dev, |
2354 | radeon_get_encoder_id | 2354 | radeon_get_encoder_enum |
2355 | (dev, | 2355 | (dev, |
2356 | ATOM_DEVICE_TV1_SUPPORT, | 2356 | ATOM_DEVICE_TV1_SUPPORT, |
2357 | 2), | 2357 | 2), |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 47c4b276d30c..1a5ee392e9c7 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -977,27 +977,29 @@ static enum drm_connector_status radeon_dp_detect(struct drm_connector *connecto | |||
977 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 977 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
978 | enum drm_connector_status ret = connector_status_disconnected; | 978 | enum drm_connector_status ret = connector_status_disconnected; |
979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; | 979 | struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv; |
980 | u8 sink_type; | ||
981 | 980 | ||
982 | if (radeon_connector->edid) { | 981 | if (radeon_connector->edid) { |
983 | kfree(radeon_connector->edid); | 982 | kfree(radeon_connector->edid); |
984 | radeon_connector->edid = NULL; | 983 | radeon_connector->edid = NULL; |
985 | } | 984 | } |
986 | 985 | ||
987 | sink_type = radeon_dp_getsinktype(radeon_connector); | 986 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
988 | if ((sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 987 | /* eDP is always DP */ |
989 | (sink_type == CONNECTOR_OBJECT_ID_eDP)) { | 988 | radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT; |
990 | if (radeon_dp_getdpcd(radeon_connector)) { | 989 | if (radeon_dp_getdpcd(radeon_connector)) |
991 | radeon_dig_connector->dp_sink_type = sink_type; | ||
992 | ret = connector_status_connected; | 990 | ret = connector_status_connected; |
993 | } | ||
994 | } else { | 991 | } else { |
995 | if (radeon_ddc_probe(radeon_connector)) { | 992 | radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector); |
996 | radeon_dig_connector->dp_sink_type = sink_type; | 993 | if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) { |
997 | ret = connector_status_connected; | 994 | if (radeon_dp_getdpcd(radeon_connector)) |
995 | ret = connector_status_connected; | ||
996 | } else { | ||
997 | if (radeon_ddc_probe(radeon_connector)) | ||
998 | ret = connector_status_connected; | ||
998 | } | 999 | } |
999 | } | 1000 | } |
1000 | 1001 | ||
1002 | radeon_connector_update_scratch_regs(connector, ret); | ||
1001 | return ret; | 1003 | return ret; |
1002 | } | 1004 | } |
1003 | 1005 | ||
@@ -1037,7 +1039,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1037 | uint32_t supported_device, | 1039 | uint32_t supported_device, |
1038 | int connector_type, | 1040 | int connector_type, |
1039 | struct radeon_i2c_bus_rec *i2c_bus, | 1041 | struct radeon_i2c_bus_rec *i2c_bus, |
1040 | bool linkb, | ||
1041 | uint32_t igp_lane_info, | 1042 | uint32_t igp_lane_info, |
1042 | uint16_t connector_object_id, | 1043 | uint16_t connector_object_id, |
1043 | struct radeon_hpd *hpd, | 1044 | struct radeon_hpd *hpd, |
@@ -1128,7 +1129,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1128 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1129 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1129 | if (!radeon_dig_connector) | 1130 | if (!radeon_dig_connector) |
1130 | goto failed; | 1131 | goto failed; |
1131 | radeon_dig_connector->linkb = linkb; | ||
1132 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1132 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1133 | radeon_connector->con_priv = radeon_dig_connector; | 1133 | radeon_connector->con_priv = radeon_dig_connector; |
1134 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1134 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
@@ -1158,7 +1158,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1158 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1158 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1159 | if (!radeon_dig_connector) | 1159 | if (!radeon_dig_connector) |
1160 | goto failed; | 1160 | goto failed; |
1161 | radeon_dig_connector->linkb = linkb; | ||
1162 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1161 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1163 | radeon_connector->con_priv = radeon_dig_connector; | 1162 | radeon_connector->con_priv = radeon_dig_connector; |
1164 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); | 1163 | drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type); |
@@ -1182,7 +1181,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1182 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1181 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1183 | if (!radeon_dig_connector) | 1182 | if (!radeon_dig_connector) |
1184 | goto failed; | 1183 | goto failed; |
1185 | radeon_dig_connector->linkb = linkb; | ||
1186 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1184 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1187 | radeon_connector->con_priv = radeon_dig_connector; | 1185 | radeon_connector->con_priv = radeon_dig_connector; |
1188 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); | 1186 | drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type); |
@@ -1229,7 +1227,6 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1229 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); | 1227 | radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL); |
1230 | if (!radeon_dig_connector) | 1228 | if (!radeon_dig_connector) |
1231 | goto failed; | 1229 | goto failed; |
1232 | radeon_dig_connector->linkb = linkb; | ||
1233 | radeon_dig_connector->igp_lane_info = igp_lane_info; | 1230 | radeon_dig_connector->igp_lane_info = igp_lane_info; |
1234 | radeon_connector->con_priv = radeon_dig_connector; | 1231 | radeon_connector->con_priv = radeon_dig_connector; |
1235 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); | 1232 | drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 4f7a170d1566..69b3c2291e92 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -199,7 +199,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
199 | mc->mc_vram_size = mc->aper_size; | 199 | mc->mc_vram_size = mc->aper_size; |
200 | } | 200 | } |
201 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 201 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
202 | if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_end <= mc->gtt_end) { | 202 | if (rdev->flags & RADEON_IS_AGP && mc->vram_end > mc->gtt_start && mc->vram_start <= mc->gtt_end) { |
203 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); | 203 | dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n"); |
204 | mc->real_vram_size = mc->aper_size; | 204 | mc->real_vram_size = mc->aper_size; |
205 | mc->mc_vram_size = mc->aper_size; | 205 | mc->mc_vram_size = mc->aper_size; |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 5764f4d3b4f1..6dd434ad2429 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -1094,6 +1094,18 @@ void radeon_modeset_fini(struct radeon_device *rdev) | |||
1094 | radeon_i2c_fini(rdev); | 1094 | radeon_i2c_fini(rdev); |
1095 | } | 1095 | } |
1096 | 1096 | ||
1097 | static bool is_hdtv_mode(struct drm_display_mode *mode) | ||
1098 | { | ||
1099 | /* try and guess if this is a tv or a monitor */ | ||
1100 | if ((mode->vdisplay == 480 && mode->hdisplay == 720) || /* 480p */ | ||
1101 | (mode->vdisplay == 576) || /* 576p */ | ||
1102 | (mode->vdisplay == 720) || /* 720p */ | ||
1103 | (mode->vdisplay == 1080)) /* 1080p */ | ||
1104 | return true; | ||
1105 | else | ||
1106 | return false; | ||
1107 | } | ||
1108 | |||
1097 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | 1109 | bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, |
1098 | struct drm_display_mode *mode, | 1110 | struct drm_display_mode *mode, |
1099 | struct drm_display_mode *adjusted_mode) | 1111 | struct drm_display_mode *adjusted_mode) |
@@ -1141,7 +1153,8 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, | |||
1141 | if (ASIC_IS_AVIVO(rdev) && | 1153 | if (ASIC_IS_AVIVO(rdev) && |
1142 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || | 1154 | ((radeon_encoder->underscan_type == UNDERSCAN_ON) || |
1143 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && | 1155 | ((radeon_encoder->underscan_type == UNDERSCAN_AUTO) && |
1144 | drm_detect_hdmi_monitor(radeon_connector->edid)))) { | 1156 | drm_detect_hdmi_monitor(radeon_connector->edid) && |
1157 | is_hdtv_mode(mode)))) { | ||
1145 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; | 1158 | radeon_crtc->h_border = (mode->hdisplay >> 5) + 16; |
1146 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; | 1159 | radeon_crtc->v_border = (mode->vdisplay >> 5) + 16; |
1147 | radeon_crtc->rmx_type = RMX_FULL; | 1160 | radeon_crtc->rmx_type = RMX_FULL; |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 263c8098d7dd..2c293e8304d6 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -81,7 +81,7 @@ void radeon_setup_encoder_clones(struct drm_device *dev) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | uint32_t | 83 | uint32_t |
84 | radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t dac) | 84 | radeon_get_encoder_enum(struct drm_device *dev, uint32_t supported_device, uint8_t dac) |
85 | { | 85 | { |
86 | struct radeon_device *rdev = dev->dev_private; | 86 | struct radeon_device *rdev = dev->dev_private; |
87 | uint32_t ret = 0; | 87 | uint32_t ret = 0; |
@@ -97,59 +97,59 @@ radeon_get_encoder_id(struct drm_device *dev, uint32_t supported_device, uint8_t | |||
97 | if ((rdev->family == CHIP_RS300) || | 97 | if ((rdev->family == CHIP_RS300) || |
98 | (rdev->family == CHIP_RS400) || | 98 | (rdev->family == CHIP_RS400) || |
99 | (rdev->family == CHIP_RS480)) | 99 | (rdev->family == CHIP_RS480)) |
100 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; | 100 | ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; |
101 | else if (ASIC_IS_AVIVO(rdev)) | 101 | else if (ASIC_IS_AVIVO(rdev)) |
102 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1; | 102 | ret = ENCODER_INTERNAL_KLDSCP_DAC1_ENUM_ID1; |
103 | else | 103 | else |
104 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC1; | 104 | ret = ENCODER_INTERNAL_DAC1_ENUM_ID1; |
105 | break; | 105 | break; |
106 | case 2: /* dac b */ | 106 | case 2: /* dac b */ |
107 | if (ASIC_IS_AVIVO(rdev)) | 107 | if (ASIC_IS_AVIVO(rdev)) |
108 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2; | 108 | ret = ENCODER_INTERNAL_KLDSCP_DAC2_ENUM_ID1; |
109 | else { | 109 | else { |
110 | /*if (rdev->family == CHIP_R200) | 110 | /*if (rdev->family == CHIP_R200) |
111 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 111 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
112 | else*/ | 112 | else*/ |
113 | ret = ENCODER_OBJECT_ID_INTERNAL_DAC2; | 113 | ret = ENCODER_INTERNAL_DAC2_ENUM_ID1; |
114 | } | 114 | } |
115 | break; | 115 | break; |
116 | case 3: /* external dac */ | 116 | case 3: /* external dac */ |
117 | if (ASIC_IS_AVIVO(rdev)) | 117 | if (ASIC_IS_AVIVO(rdev)) |
118 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; | 118 | ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; |
119 | else | 119 | else |
120 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 120 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
121 | break; | 121 | break; |
122 | } | 122 | } |
123 | break; | 123 | break; |
124 | case ATOM_DEVICE_LCD1_SUPPORT: | 124 | case ATOM_DEVICE_LCD1_SUPPORT: |
125 | if (ASIC_IS_AVIVO(rdev)) | 125 | if (ASIC_IS_AVIVO(rdev)) |
126 | ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; | 126 | ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; |
127 | else | 127 | else |
128 | ret = ENCODER_OBJECT_ID_INTERNAL_LVDS; | 128 | ret = ENCODER_INTERNAL_LVDS_ENUM_ID1; |
129 | break; | 129 | break; |
130 | case ATOM_DEVICE_DFP1_SUPPORT: | 130 | case ATOM_DEVICE_DFP1_SUPPORT: |
131 | if ((rdev->family == CHIP_RS300) || | 131 | if ((rdev->family == CHIP_RS300) || |
132 | (rdev->family == CHIP_RS400) || | 132 | (rdev->family == CHIP_RS400) || |
133 | (rdev->family == CHIP_RS480)) | 133 | (rdev->family == CHIP_RS480)) |
134 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 134 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
135 | else if (ASIC_IS_AVIVO(rdev)) | 135 | else if (ASIC_IS_AVIVO(rdev)) |
136 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1; | 136 | ret = ENCODER_INTERNAL_KLDSCP_TMDS1_ENUM_ID1; |
137 | else | 137 | else |
138 | ret = ENCODER_OBJECT_ID_INTERNAL_TMDS1; | 138 | ret = ENCODER_INTERNAL_TMDS1_ENUM_ID1; |
139 | break; | 139 | break; |
140 | case ATOM_DEVICE_LCD2_SUPPORT: | 140 | case ATOM_DEVICE_LCD2_SUPPORT: |
141 | case ATOM_DEVICE_DFP2_SUPPORT: | 141 | case ATOM_DEVICE_DFP2_SUPPORT: |
142 | if ((rdev->family == CHIP_RS600) || | 142 | if ((rdev->family == CHIP_RS600) || |
143 | (rdev->family == CHIP_RS690) || | 143 | (rdev->family == CHIP_RS690) || |
144 | (rdev->family == CHIP_RS740)) | 144 | (rdev->family == CHIP_RS740)) |
145 | ret = ENCODER_OBJECT_ID_INTERNAL_DDI; | 145 | ret = ENCODER_INTERNAL_DDI_ENUM_ID1; |
146 | else if (ASIC_IS_AVIVO(rdev)) | 146 | else if (ASIC_IS_AVIVO(rdev)) |
147 | ret = ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1; | 147 | ret = ENCODER_INTERNAL_KLDSCP_DVO1_ENUM_ID1; |
148 | else | 148 | else |
149 | ret = ENCODER_OBJECT_ID_INTERNAL_DVO1; | 149 | ret = ENCODER_INTERNAL_DVO1_ENUM_ID1; |
150 | break; | 150 | break; |
151 | case ATOM_DEVICE_DFP3_SUPPORT: | 151 | case ATOM_DEVICE_DFP3_SUPPORT: |
152 | ret = ENCODER_OBJECT_ID_INTERNAL_LVTM1; | 152 | ret = ENCODER_INTERNAL_LVTM1_ENUM_ID1; |
153 | break; | 153 | break; |
154 | } | 154 | } |
155 | 155 | ||
@@ -228,32 +228,6 @@ radeon_get_connector_for_encoder(struct drm_encoder *encoder) | |||
228 | return NULL; | 228 | return NULL; |
229 | } | 229 | } |
230 | 230 | ||
231 | static struct radeon_connector_atom_dig * | ||
232 | radeon_get_atom_connector_priv_from_encoder(struct drm_encoder *encoder) | ||
233 | { | ||
234 | struct drm_device *dev = encoder->dev; | ||
235 | struct radeon_device *rdev = dev->dev_private; | ||
236 | struct drm_connector *connector; | ||
237 | struct radeon_connector *radeon_connector; | ||
238 | struct radeon_connector_atom_dig *dig_connector; | ||
239 | |||
240 | if (!rdev->is_atom_bios) | ||
241 | return NULL; | ||
242 | |||
243 | connector = radeon_get_connector_for_encoder(encoder); | ||
244 | if (!connector) | ||
245 | return NULL; | ||
246 | |||
247 | radeon_connector = to_radeon_connector(connector); | ||
248 | |||
249 | if (!radeon_connector->con_priv) | ||
250 | return NULL; | ||
251 | |||
252 | dig_connector = radeon_connector->con_priv; | ||
253 | |||
254 | return dig_connector; | ||
255 | } | ||
256 | |||
257 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, | 231 | void radeon_panel_mode_fixup(struct drm_encoder *encoder, |
258 | struct drm_display_mode *adjusted_mode) | 232 | struct drm_display_mode *adjusted_mode) |
259 | { | 233 | { |
@@ -512,14 +486,12 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
512 | struct radeon_device *rdev = dev->dev_private; | 486 | struct radeon_device *rdev = dev->dev_private; |
513 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 487 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
514 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 488 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
515 | struct radeon_connector_atom_dig *dig_connector = | ||
516 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
517 | union lvds_encoder_control args; | 489 | union lvds_encoder_control args; |
518 | int index = 0; | 490 | int index = 0; |
519 | int hdmi_detected = 0; | 491 | int hdmi_detected = 0; |
520 | uint8_t frev, crev; | 492 | uint8_t frev, crev; |
521 | 493 | ||
522 | if (!dig || !dig_connector) | 494 | if (!dig) |
523 | return; | 495 | return; |
524 | 496 | ||
525 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) | 497 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_HDMI) |
@@ -562,7 +534,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
562 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) | 534 | if (dig->lvds_misc & ATOM_PANEL_MISC_888RGB) |
563 | args.v1.ucMisc |= (1 << 1); | 535 | args.v1.ucMisc |= (1 << 1); |
564 | } else { | 536 | } else { |
565 | if (dig_connector->linkb) | 537 | if (dig->linkb) |
566 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 538 | args.v1.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
567 | if (radeon_encoder->pixel_clock > 165000) | 539 | if (radeon_encoder->pixel_clock > 165000) |
568 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 540 | args.v1.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
@@ -601,7 +573,7 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
601 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; | 573 | args.v2.ucTemporal |= PANEL_ENCODER_TEMPORAL_LEVEL_4; |
602 | } | 574 | } |
603 | } else { | 575 | } else { |
604 | if (dig_connector->linkb) | 576 | if (dig->linkb) |
605 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; | 577 | args.v2.ucMisc |= PANEL_ENCODER_MISC_TMDS_LINKB; |
606 | if (radeon_encoder->pixel_clock > 165000) | 578 | if (radeon_encoder->pixel_clock > 165000) |
607 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; | 579 | args.v2.ucMisc |= PANEL_ENCODER_MISC_DUAL; |
@@ -623,6 +595,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) | |||
623 | int | 595 | int |
624 | atombios_get_encoder_mode(struct drm_encoder *encoder) | 596 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
625 | { | 597 | { |
598 | struct drm_device *dev = encoder->dev; | ||
599 | struct radeon_device *rdev = dev->dev_private; | ||
626 | struct drm_connector *connector; | 600 | struct drm_connector *connector; |
627 | struct radeon_connector *radeon_connector; | 601 | struct radeon_connector *radeon_connector; |
628 | struct radeon_connector_atom_dig *dig_connector; | 602 | struct radeon_connector_atom_dig *dig_connector; |
@@ -636,9 +610,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
636 | switch (connector->connector_type) { | 610 | switch (connector->connector_type) { |
637 | case DRM_MODE_CONNECTOR_DVII: | 611 | case DRM_MODE_CONNECTOR_DVII: |
638 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ | 612 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
639 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 613 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
640 | return ATOM_ENCODER_MODE_HDMI; | 614 | /* fix me */ |
641 | else if (radeon_connector->use_digital) | 615 | if (ASIC_IS_DCE4(rdev)) |
616 | return ATOM_ENCODER_MODE_DVI; | ||
617 | else | ||
618 | return ATOM_ENCODER_MODE_HDMI; | ||
619 | } else if (radeon_connector->use_digital) | ||
642 | return ATOM_ENCODER_MODE_DVI; | 620 | return ATOM_ENCODER_MODE_DVI; |
643 | else | 621 | else |
644 | return ATOM_ENCODER_MODE_CRT; | 622 | return ATOM_ENCODER_MODE_CRT; |
@@ -646,9 +624,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
646 | case DRM_MODE_CONNECTOR_DVID: | 624 | case DRM_MODE_CONNECTOR_DVID: |
647 | case DRM_MODE_CONNECTOR_HDMIA: | 625 | case DRM_MODE_CONNECTOR_HDMIA: |
648 | default: | 626 | default: |
649 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 627 | if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
650 | return ATOM_ENCODER_MODE_HDMI; | 628 | /* fix me */ |
651 | else | 629 | if (ASIC_IS_DCE4(rdev)) |
630 | return ATOM_ENCODER_MODE_DVI; | ||
631 | else | ||
632 | return ATOM_ENCODER_MODE_HDMI; | ||
633 | } else | ||
652 | return ATOM_ENCODER_MODE_DVI; | 634 | return ATOM_ENCODER_MODE_DVI; |
653 | break; | 635 | break; |
654 | case DRM_MODE_CONNECTOR_LVDS: | 636 | case DRM_MODE_CONNECTOR_LVDS: |
@@ -660,9 +642,13 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) | |||
660 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || | 642 | if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) || |
661 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) | 643 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
662 | return ATOM_ENCODER_MODE_DP; | 644 | return ATOM_ENCODER_MODE_DP; |
663 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) | 645 | else if (drm_detect_hdmi_monitor(radeon_connector->edid)) { |
664 | return ATOM_ENCODER_MODE_HDMI; | 646 | /* fix me */ |
665 | else | 647 | if (ASIC_IS_DCE4(rdev)) |
648 | return ATOM_ENCODER_MODE_DVI; | ||
649 | else | ||
650 | return ATOM_ENCODER_MODE_HDMI; | ||
651 | } else | ||
666 | return ATOM_ENCODER_MODE_DVI; | 652 | return ATOM_ENCODER_MODE_DVI; |
667 | break; | 653 | break; |
668 | case DRM_MODE_CONNECTOR_DVIA: | 654 | case DRM_MODE_CONNECTOR_DVIA: |
@@ -729,13 +715,24 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
729 | struct radeon_device *rdev = dev->dev_private; | 715 | struct radeon_device *rdev = dev->dev_private; |
730 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 716 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
731 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 717 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
732 | struct radeon_connector_atom_dig *dig_connector = | 718 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
733 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
734 | union dig_encoder_control args; | 719 | union dig_encoder_control args; |
735 | int index = 0; | 720 | int index = 0; |
736 | uint8_t frev, crev; | 721 | uint8_t frev, crev; |
722 | int dp_clock = 0; | ||
723 | int dp_lane_count = 0; | ||
724 | |||
725 | if (connector) { | ||
726 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | ||
727 | struct radeon_connector_atom_dig *dig_connector = | ||
728 | radeon_connector->con_priv; | ||
737 | 729 | ||
738 | if (!dig || !dig_connector) | 730 | dp_clock = dig_connector->dp_clock; |
731 | dp_lane_count = dig_connector->dp_lane_count; | ||
732 | } | ||
733 | |||
734 | /* no dig encoder assigned */ | ||
735 | if (dig->dig_encoder == -1) | ||
739 | return; | 736 | return; |
740 | 737 | ||
741 | memset(&args, 0, sizeof(args)); | 738 | memset(&args, 0, sizeof(args)); |
@@ -757,9 +754,9 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
757 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); | 754 | args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder); |
758 | 755 | ||
759 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { | 756 | if (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) { |
760 | if (dig_connector->dp_clock == 270000) | 757 | if (dp_clock == 270000) |
761 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; | 758 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ; |
762 | args.v1.ucLaneNum = dig_connector->dp_lane_count; | 759 | args.v1.ucLaneNum = dp_lane_count; |
763 | } else if (radeon_encoder->pixel_clock > 165000) | 760 | } else if (radeon_encoder->pixel_clock > 165000) |
764 | args.v1.ucLaneNum = 8; | 761 | args.v1.ucLaneNum = 8; |
765 | else | 762 | else |
@@ -781,7 +778,7 @@ atombios_dig_encoder_setup(struct drm_encoder *encoder, int action) | |||
781 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; | 778 | args.v1.ucConfig = ATOM_ENCODER_CONFIG_V2_TRANSMITTER3; |
782 | break; | 779 | break; |
783 | } | 780 | } |
784 | if (dig_connector->linkb) | 781 | if (dig->linkb) |
785 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; | 782 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKB; |
786 | else | 783 | else |
787 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; | 784 | args.v1.ucConfig |= ATOM_ENCODER_CONFIG_LINKA; |
@@ -804,38 +801,47 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
804 | struct radeon_device *rdev = dev->dev_private; | 801 | struct radeon_device *rdev = dev->dev_private; |
805 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); | 802 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
806 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; | 803 | struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv; |
807 | struct radeon_connector_atom_dig *dig_connector = | 804 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
808 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
809 | struct drm_connector *connector; | ||
810 | struct radeon_connector *radeon_connector; | ||
811 | union dig_transmitter_control args; | 805 | union dig_transmitter_control args; |
812 | int index = 0; | 806 | int index = 0; |
813 | uint8_t frev, crev; | 807 | uint8_t frev, crev; |
814 | bool is_dp = false; | 808 | bool is_dp = false; |
815 | int pll_id = 0; | 809 | int pll_id = 0; |
810 | int dp_clock = 0; | ||
811 | int dp_lane_count = 0; | ||
812 | int connector_object_id = 0; | ||
813 | int igp_lane_info = 0; | ||
816 | 814 | ||
817 | if (!dig || !dig_connector) | 815 | if (connector) { |
818 | return; | 816 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
817 | struct radeon_connector_atom_dig *dig_connector = | ||
818 | radeon_connector->con_priv; | ||
819 | 819 | ||
820 | connector = radeon_get_connector_for_encoder(encoder); | 820 | dp_clock = dig_connector->dp_clock; |
821 | radeon_connector = to_radeon_connector(connector); | 821 | dp_lane_count = dig_connector->dp_lane_count; |
822 | connector_object_id = | ||
823 | (radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
824 | igp_lane_info = dig_connector->igp_lane_info; | ||
825 | } | ||
826 | |||
827 | /* no dig encoder assigned */ | ||
828 | if (dig->dig_encoder == -1) | ||
829 | return; | ||
822 | 830 | ||
823 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) | 831 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) |
824 | is_dp = true; | 832 | is_dp = true; |
825 | 833 | ||
826 | memset(&args, 0, sizeof(args)); | 834 | memset(&args, 0, sizeof(args)); |
827 | 835 | ||
828 | if (ASIC_IS_DCE32(rdev) || ASIC_IS_DCE4(rdev)) | 836 | switch (radeon_encoder->encoder_id) { |
837 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | ||
838 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | ||
839 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | ||
829 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); | 840 | index = GetIndexIntoMasterTable(COMMAND, UNIPHYTransmitterControl); |
830 | else { | 841 | break; |
831 | switch (radeon_encoder->encoder_id) { | 842 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: |
832 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 843 | index = GetIndexIntoMasterTable(COMMAND, LVTMATransmitterControl); |
833 | index = GetIndexIntoMasterTable(COMMAND, DIG1TransmitterControl); | 844 | break; |
834 | break; | ||
835 | case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_LVTMA: | ||
836 | index = GetIndexIntoMasterTable(COMMAND, DIG2TransmitterControl); | ||
837 | break; | ||
838 | } | ||
839 | } | 845 | } |
840 | 846 | ||
841 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 847 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
@@ -843,14 +849,14 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
843 | 849 | ||
844 | args.v1.ucAction = action; | 850 | args.v1.ucAction = action; |
845 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { | 851 | if (action == ATOM_TRANSMITTER_ACTION_INIT) { |
846 | args.v1.usInitInfo = radeon_connector->connector_object_id; | 852 | args.v1.usInitInfo = connector_object_id; |
847 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { | 853 | } else if (action == ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH) { |
848 | args.v1.asMode.ucLaneSel = lane_num; | 854 | args.v1.asMode.ucLaneSel = lane_num; |
849 | args.v1.asMode.ucLaneSet = lane_set; | 855 | args.v1.asMode.ucLaneSet = lane_set; |
850 | } else { | 856 | } else { |
851 | if (is_dp) | 857 | if (is_dp) |
852 | args.v1.usPixelClock = | 858 | args.v1.usPixelClock = |
853 | cpu_to_le16(dig_connector->dp_clock / 10); | 859 | cpu_to_le16(dp_clock / 10); |
854 | else if (radeon_encoder->pixel_clock > 165000) | 860 | else if (radeon_encoder->pixel_clock > 165000) |
855 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); | 861 | args.v1.usPixelClock = cpu_to_le16((radeon_encoder->pixel_clock / 2) / 10); |
856 | else | 862 | else |
@@ -858,13 +864,13 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
858 | } | 864 | } |
859 | if (ASIC_IS_DCE4(rdev)) { | 865 | if (ASIC_IS_DCE4(rdev)) { |
860 | if (is_dp) | 866 | if (is_dp) |
861 | args.v3.ucLaneNum = dig_connector->dp_lane_count; | 867 | args.v3.ucLaneNum = dp_lane_count; |
862 | else if (radeon_encoder->pixel_clock > 165000) | 868 | else if (radeon_encoder->pixel_clock > 165000) |
863 | args.v3.ucLaneNum = 8; | 869 | args.v3.ucLaneNum = 8; |
864 | else | 870 | else |
865 | args.v3.ucLaneNum = 4; | 871 | args.v3.ucLaneNum = 4; |
866 | 872 | ||
867 | if (dig_connector->linkb) { | 873 | if (dig->linkb) { |
868 | args.v3.acConfig.ucLinkSel = 1; | 874 | args.v3.acConfig.ucLinkSel = 1; |
869 | args.v3.acConfig.ucEncoderSel = 1; | 875 | args.v3.acConfig.ucEncoderSel = 1; |
870 | } | 876 | } |
@@ -904,7 +910,7 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
904 | } | 910 | } |
905 | } else if (ASIC_IS_DCE32(rdev)) { | 911 | } else if (ASIC_IS_DCE32(rdev)) { |
906 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; | 912 | args.v2.acConfig.ucEncoderSel = dig->dig_encoder; |
907 | if (dig_connector->linkb) | 913 | if (dig->linkb) |
908 | args.v2.acConfig.ucLinkSel = 1; | 914 | args.v2.acConfig.ucLinkSel = 1; |
909 | 915 | ||
910 | switch (radeon_encoder->encoder_id) { | 916 | switch (radeon_encoder->encoder_id) { |
@@ -938,23 +944,23 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t | |||
938 | if ((rdev->flags & RADEON_IS_IGP) && | 944 | if ((rdev->flags & RADEON_IS_IGP) && |
939 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { | 945 | (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_UNIPHY)) { |
940 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { | 946 | if (is_dp || (radeon_encoder->pixel_clock <= 165000)) { |
941 | if (dig_connector->igp_lane_info & 0x1) | 947 | if (igp_lane_info & 0x1) |
942 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; | 948 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_3; |
943 | else if (dig_connector->igp_lane_info & 0x2) | 949 | else if (igp_lane_info & 0x2) |
944 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; | 950 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_4_7; |
945 | else if (dig_connector->igp_lane_info & 0x4) | 951 | else if (igp_lane_info & 0x4) |
946 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; | 952 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_11; |
947 | else if (dig_connector->igp_lane_info & 0x8) | 953 | else if (igp_lane_info & 0x8) |
948 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; | 954 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_12_15; |
949 | } else { | 955 | } else { |
950 | if (dig_connector->igp_lane_info & 0x3) | 956 | if (igp_lane_info & 0x3) |
951 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; | 957 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_0_7; |
952 | else if (dig_connector->igp_lane_info & 0xc) | 958 | else if (igp_lane_info & 0xc) |
953 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; | 959 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LANE_8_15; |
954 | } | 960 | } |
955 | } | 961 | } |
956 | 962 | ||
957 | if (dig_connector->linkb) | 963 | if (dig->linkb) |
958 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; | 964 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKB; |
959 | else | 965 | else |
960 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; | 966 | args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_LINKA; |
@@ -1072,8 +1078,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1072 | if (is_dig) { | 1078 | if (is_dig) { |
1073 | switch (mode) { | 1079 | switch (mode) { |
1074 | case DRM_MODE_DPMS_ON: | 1080 | case DRM_MODE_DPMS_ON: |
1075 | if (!ASIC_IS_DCE4(rdev)) | 1081 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); |
1076 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0); | ||
1077 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1082 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
1078 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); | 1083 | struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); |
1079 | 1084 | ||
@@ -1085,8 +1090,7 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
1085 | case DRM_MODE_DPMS_STANDBY: | 1090 | case DRM_MODE_DPMS_STANDBY: |
1086 | case DRM_MODE_DPMS_SUSPEND: | 1091 | case DRM_MODE_DPMS_SUSPEND: |
1087 | case DRM_MODE_DPMS_OFF: | 1092 | case DRM_MODE_DPMS_OFF: |
1088 | if (!ASIC_IS_DCE4(rdev)) | 1093 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); |
1089 | atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE_OUTPUT, 0, 0); | ||
1090 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { | 1094 | if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP) { |
1091 | if (ASIC_IS_DCE4(rdev)) | 1095 | if (ASIC_IS_DCE4(rdev)) |
1092 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); | 1096 | atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF); |
@@ -1290,24 +1294,22 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) | |||
1290 | uint32_t dig_enc_in_use = 0; | 1294 | uint32_t dig_enc_in_use = 0; |
1291 | 1295 | ||
1292 | if (ASIC_IS_DCE4(rdev)) { | 1296 | if (ASIC_IS_DCE4(rdev)) { |
1293 | struct radeon_connector_atom_dig *dig_connector = | 1297 | dig = radeon_encoder->enc_priv; |
1294 | radeon_get_atom_connector_priv_from_encoder(encoder); | ||
1295 | |||
1296 | switch (radeon_encoder->encoder_id) { | 1298 | switch (radeon_encoder->encoder_id) { |
1297 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: | 1299 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: |
1298 | if (dig_connector->linkb) | 1300 | if (dig->linkb) |
1299 | return 1; | 1301 | return 1; |
1300 | else | 1302 | else |
1301 | return 0; | 1303 | return 0; |
1302 | break; | 1304 | break; |
1303 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: | 1305 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: |
1304 | if (dig_connector->linkb) | 1306 | if (dig->linkb) |
1305 | return 3; | 1307 | return 3; |
1306 | else | 1308 | else |
1307 | return 2; | 1309 | return 2; |
1308 | break; | 1310 | break; |
1309 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: | 1311 | case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: |
1310 | if (dig_connector->linkb) | 1312 | if (dig->linkb) |
1311 | return 5; | 1313 | return 5; |
1312 | else | 1314 | else |
1313 | return 4; | 1315 | return 4; |
@@ -1641,6 +1643,7 @@ radeon_atombios_set_dac_info(struct radeon_encoder *radeon_encoder) | |||
1641 | struct radeon_encoder_atom_dig * | 1643 | struct radeon_encoder_atom_dig * |
1642 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | 1644 | radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) |
1643 | { | 1645 | { |
1646 | int encoder_enum = (radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; | ||
1644 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); | 1647 | struct radeon_encoder_atom_dig *dig = kzalloc(sizeof(struct radeon_encoder_atom_dig), GFP_KERNEL); |
1645 | 1648 | ||
1646 | if (!dig) | 1649 | if (!dig) |
@@ -1650,11 +1653,16 @@ radeon_atombios_set_dig_info(struct radeon_encoder *radeon_encoder) | |||
1650 | dig->coherent_mode = true; | 1653 | dig->coherent_mode = true; |
1651 | dig->dig_encoder = -1; | 1654 | dig->dig_encoder = -1; |
1652 | 1655 | ||
1656 | if (encoder_enum == 2) | ||
1657 | dig->linkb = true; | ||
1658 | else | ||
1659 | dig->linkb = false; | ||
1660 | |||
1653 | return dig; | 1661 | return dig; |
1654 | } | 1662 | } |
1655 | 1663 | ||
1656 | void | 1664 | void |
1657 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1665 | radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) |
1658 | { | 1666 | { |
1659 | struct radeon_device *rdev = dev->dev_private; | 1667 | struct radeon_device *rdev = dev->dev_private; |
1660 | struct drm_encoder *encoder; | 1668 | struct drm_encoder *encoder; |
@@ -1663,7 +1671,7 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1663 | /* see if we already added it */ | 1671 | /* see if we already added it */ |
1664 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1672 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1665 | radeon_encoder = to_radeon_encoder(encoder); | 1673 | radeon_encoder = to_radeon_encoder(encoder); |
1666 | if (radeon_encoder->encoder_id == encoder_id) { | 1674 | if (radeon_encoder->encoder_enum == encoder_enum) { |
1667 | radeon_encoder->devices |= supported_device; | 1675 | radeon_encoder->devices |= supported_device; |
1668 | return; | 1676 | return; |
1669 | } | 1677 | } |
@@ -1691,7 +1699,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t su | |||
1691 | 1699 | ||
1692 | radeon_encoder->enc_priv = NULL; | 1700 | radeon_encoder->enc_priv = NULL; |
1693 | 1701 | ||
1694 | radeon_encoder->encoder_id = encoder_id; | 1702 | radeon_encoder->encoder_enum = encoder_enum; |
1703 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
1695 | radeon_encoder->devices = supported_device; | 1704 | radeon_encoder->devices = supported_device; |
1696 | radeon_encoder->rmx_type = RMX_OFF; | 1705 | radeon_encoder->rmx_type = RMX_OFF; |
1697 | radeon_encoder->underscan_type = UNDERSCAN_OFF; | 1706 | radeon_encoder->underscan_type = UNDERSCAN_OFF; |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index dbf86962bdd1..c74a8b20d941 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -118,7 +118,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, | |||
118 | aligned_size = ALIGN(size, PAGE_SIZE); | 118 | aligned_size = ALIGN(size, PAGE_SIZE); |
119 | ret = radeon_gem_object_create(rdev, aligned_size, 0, | 119 | ret = radeon_gem_object_create(rdev, aligned_size, 0, |
120 | RADEON_GEM_DOMAIN_VRAM, | 120 | RADEON_GEM_DOMAIN_VRAM, |
121 | false, ttm_bo_type_kernel, | 121 | false, true, |
122 | &gobj); | 122 | &gobj); |
123 | if (ret) { | 123 | if (ret) { |
124 | printk(KERN_ERR "failed to allocate framebuffer (%d)\n", | 124 | printk(KERN_ERR "failed to allocate framebuffer (%d)\n", |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index bfd2ce5f5372..0416804d8f30 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -99,6 +99,13 @@ static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) | |||
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
102 | /* switch the pads to ddc mode */ | ||
103 | if (ASIC_IS_DCE3(rdev) && rec->hw_capable) { | ||
104 | temp = RREG32(rec->mask_clk_reg); | ||
105 | temp &= ~(1 << 16); | ||
106 | WREG32(rec->mask_clk_reg, temp); | ||
107 | } | ||
108 | |||
102 | /* clear the output pin values */ | 109 | /* clear the output pin values */ |
103 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; | 110 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; |
104 | WREG32(rec->a_clk_reg, temp); | 111 | WREG32(rec->a_clk_reg, temp); |
diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 059bfa4098d7..a108c7ed14f5 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c | |||
@@ -121,11 +121,12 @@ int radeon_irq_kms_init(struct radeon_device *rdev) | |||
121 | * chips. Disable MSI on them for now. | 121 | * chips. Disable MSI on them for now. |
122 | */ | 122 | */ |
123 | if ((rdev->family >= CHIP_RV380) && | 123 | if ((rdev->family >= CHIP_RV380) && |
124 | (!(rdev->flags & RADEON_IS_IGP))) { | 124 | (!(rdev->flags & RADEON_IS_IGP)) && |
125 | (!(rdev->flags & RADEON_IS_AGP))) { | ||
125 | int ret = pci_enable_msi(rdev->pdev); | 126 | int ret = pci_enable_msi(rdev->pdev); |
126 | if (!ret) { | 127 | if (!ret) { |
127 | rdev->msi_enabled = 1; | 128 | rdev->msi_enabled = 1; |
128 | DRM_INFO("radeon: using MSI.\n"); | 129 | dev_info(rdev->dev, "radeon: using MSI.\n"); |
129 | } | 130 | } |
130 | } | 131 | } |
131 | rdev->irq.installed = true; | 132 | rdev->irq.installed = true; |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index b1c8ace5f080..5eee3c41d124 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -161,6 +161,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
161 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); | 161 | DRM_DEBUG_KMS("tiling config is r6xx+ only!\n"); |
162 | return -EINVAL; | 162 | return -EINVAL; |
163 | } | 163 | } |
164 | break; | ||
164 | case RADEON_INFO_WANT_HYPERZ: | 165 | case RADEON_INFO_WANT_HYPERZ: |
165 | /* The "value" here is both an input and output parameter. | 166 | /* The "value" here is both an input and output parameter. |
166 | * If the input value is 1, filp requests hyper-z access. | 167 | * If the input value is 1, filp requests hyper-z access. |
@@ -323,45 +324,45 @@ KMS_INVALID_IOCTL(radeon_surface_free_kms) | |||
323 | 324 | ||
324 | 325 | ||
325 | struct drm_ioctl_desc radeon_ioctls_kms[] = { | 326 | struct drm_ioctl_desc radeon_ioctls_kms[] = { |
326 | DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 327 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
327 | DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 328 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
328 | DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 329 | DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
329 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 330 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
330 | DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), | 331 | DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle_kms, DRM_AUTH), |
331 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), | 332 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume_kms, DRM_AUTH), |
332 | DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), | 333 | DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset_kms, DRM_AUTH), |
333 | DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), | 334 | DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen_kms, DRM_AUTH), |
334 | DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), | 335 | DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap_kms, DRM_AUTH), |
335 | DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), | 336 | DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear_kms, DRM_AUTH), |
336 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), | 337 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex_kms, DRM_AUTH), |
337 | DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), | 338 | DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices_kms, DRM_AUTH), |
338 | DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), | 339 | DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture_kms, DRM_AUTH), |
339 | DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), | 340 | DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple_kms, DRM_AUTH), |
340 | DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 341 | DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
341 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), | 342 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2_kms, DRM_AUTH), |
342 | DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), | 343 | DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf_kms, DRM_AUTH), |
343 | DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), | 344 | DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam_kms, DRM_AUTH), |
344 | DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), | 345 | DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip_kms, DRM_AUTH), |
345 | DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), | 346 | DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc_kms, DRM_AUTH), |
346 | DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), | 347 | DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free_kms, DRM_AUTH), |
347 | DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 348 | DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap_kms, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
348 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), | 349 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit_kms, DRM_AUTH), |
349 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), | 350 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait_kms, DRM_AUTH), |
350 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), | 351 | DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam_kms, DRM_AUTH), |
351 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), | 352 | DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc_kms, DRM_AUTH), |
352 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), | 353 | DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free_kms, DRM_AUTH), |
353 | /* KMS */ | 354 | /* KMS */ |
354 | DRM_IOCTL_DEF(DRM_RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), | 355 | DRM_IOCTL_DEF_DRV(RADEON_GEM_INFO, radeon_gem_info_ioctl, DRM_AUTH|DRM_UNLOCKED), |
355 | DRM_IOCTL_DEF(DRM_RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), | 356 | DRM_IOCTL_DEF_DRV(RADEON_GEM_CREATE, radeon_gem_create_ioctl, DRM_AUTH|DRM_UNLOCKED), |
356 | DRM_IOCTL_DEF(DRM_RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), | 357 | DRM_IOCTL_DEF_DRV(RADEON_GEM_MMAP, radeon_gem_mmap_ioctl, DRM_AUTH|DRM_UNLOCKED), |
357 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), | 358 | DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_DOMAIN, radeon_gem_set_domain_ioctl, DRM_AUTH|DRM_UNLOCKED), |
358 | DRM_IOCTL_DEF(DRM_RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), | 359 | DRM_IOCTL_DEF_DRV(RADEON_GEM_PREAD, radeon_gem_pread_ioctl, DRM_AUTH|DRM_UNLOCKED), |
359 | DRM_IOCTL_DEF(DRM_RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), | 360 | DRM_IOCTL_DEF_DRV(RADEON_GEM_PWRITE, radeon_gem_pwrite_ioctl, DRM_AUTH|DRM_UNLOCKED), |
360 | DRM_IOCTL_DEF(DRM_RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), | 361 | DRM_IOCTL_DEF_DRV(RADEON_GEM_WAIT_IDLE, radeon_gem_wait_idle_ioctl, DRM_AUTH|DRM_UNLOCKED), |
361 | DRM_IOCTL_DEF(DRM_RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), | 362 | DRM_IOCTL_DEF_DRV(RADEON_CS, radeon_cs_ioctl, DRM_AUTH|DRM_UNLOCKED), |
362 | DRM_IOCTL_DEF(DRM_RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), | 363 | DRM_IOCTL_DEF_DRV(RADEON_INFO, radeon_info_ioctl, DRM_AUTH|DRM_UNLOCKED), |
363 | DRM_IOCTL_DEF(DRM_RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), | 364 | DRM_IOCTL_DEF_DRV(RADEON_GEM_SET_TILING, radeon_gem_set_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), |
364 | DRM_IOCTL_DEF(DRM_RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), | 365 | DRM_IOCTL_DEF_DRV(RADEON_GEM_GET_TILING, radeon_gem_get_tiling_ioctl, DRM_AUTH|DRM_UNLOCKED), |
365 | DRM_IOCTL_DEF(DRM_RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), | 366 | DRM_IOCTL_DEF_DRV(RADEON_GEM_BUSY, radeon_gem_busy_ioctl, DRM_AUTH|DRM_UNLOCKED), |
366 | }; | 367 | }; |
367 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); | 368 | int radeon_max_kms_ioctl = DRM_ARRAY_SIZE(radeon_ioctls_kms); |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 989df519a1e4..305049afde15 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -272,7 +272,7 @@ static uint8_t radeon_compute_pll_gain(uint16_t ref_freq, uint16_t ref_div, | |||
272 | if (!ref_div) | 272 | if (!ref_div) |
273 | return 1; | 273 | return 1; |
274 | 274 | ||
275 | vcoFreq = ((unsigned)ref_freq & fb_div) / ref_div; | 275 | vcoFreq = ((unsigned)ref_freq * fb_div) / ref_div; |
276 | 276 | ||
277 | /* | 277 | /* |
278 | * This is horribly crude: the VCO frequency range is divided into | 278 | * This is horribly crude: the VCO frequency range is divided into |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index b8149cbc0c70..0b8397000f4c 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -1345,7 +1345,7 @@ static struct radeon_encoder_ext_tmds *radeon_legacy_get_ext_tmds_info(struct ra | |||
1345 | } | 1345 | } |
1346 | 1346 | ||
1347 | void | 1347 | void |
1348 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t supported_device) | 1348 | radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t supported_device) |
1349 | { | 1349 | { |
1350 | struct radeon_device *rdev = dev->dev_private; | 1350 | struct radeon_device *rdev = dev->dev_private; |
1351 | struct drm_encoder *encoder; | 1351 | struct drm_encoder *encoder; |
@@ -1354,7 +1354,7 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1354 | /* see if we already added it */ | 1354 | /* see if we already added it */ |
1355 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 1355 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
1356 | radeon_encoder = to_radeon_encoder(encoder); | 1356 | radeon_encoder = to_radeon_encoder(encoder); |
1357 | if (radeon_encoder->encoder_id == encoder_id) { | 1357 | if (radeon_encoder->encoder_enum == encoder_enum) { |
1358 | radeon_encoder->devices |= supported_device; | 1358 | radeon_encoder->devices |= supported_device; |
1359 | return; | 1359 | return; |
1360 | } | 1360 | } |
@@ -1374,7 +1374,8 @@ radeon_add_legacy_encoder(struct drm_device *dev, uint32_t encoder_id, uint32_t | |||
1374 | 1374 | ||
1375 | radeon_encoder->enc_priv = NULL; | 1375 | radeon_encoder->enc_priv = NULL; |
1376 | 1376 | ||
1377 | radeon_encoder->encoder_id = encoder_id; | 1377 | radeon_encoder->encoder_enum = encoder_enum; |
1378 | radeon_encoder->encoder_id = (encoder_enum & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT; | ||
1378 | radeon_encoder->devices = supported_device; | 1379 | radeon_encoder->devices = supported_device; |
1379 | radeon_encoder->rmx_type = RMX_OFF; | 1380 | radeon_encoder->rmx_type = RMX_OFF; |
1380 | 1381 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 5bbc086b9267..8f93e2b4b0c8 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -342,6 +342,7 @@ struct radeon_atom_ss { | |||
342 | }; | 342 | }; |
343 | 343 | ||
344 | struct radeon_encoder_atom_dig { | 344 | struct radeon_encoder_atom_dig { |
345 | bool linkb; | ||
345 | /* atom dig */ | 346 | /* atom dig */ |
346 | bool coherent_mode; | 347 | bool coherent_mode; |
347 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ | 348 | int dig_encoder; /* -1 disabled, 0 DIGA, 1 DIGB */ |
@@ -360,6 +361,7 @@ struct radeon_encoder_atom_dac { | |||
360 | 361 | ||
361 | struct radeon_encoder { | 362 | struct radeon_encoder { |
362 | struct drm_encoder base; | 363 | struct drm_encoder base; |
364 | uint32_t encoder_enum; | ||
363 | uint32_t encoder_id; | 365 | uint32_t encoder_id; |
364 | uint32_t devices; | 366 | uint32_t devices; |
365 | uint32_t active_device; | 367 | uint32_t active_device; |
@@ -378,7 +380,6 @@ struct radeon_encoder { | |||
378 | 380 | ||
379 | struct radeon_connector_atom_dig { | 381 | struct radeon_connector_atom_dig { |
380 | uint32_t igp_lane_info; | 382 | uint32_t igp_lane_info; |
381 | bool linkb; | ||
382 | /* displayport */ | 383 | /* displayport */ |
383 | struct radeon_i2c_chan *dp_i2c_bus; | 384 | struct radeon_i2c_chan *dp_i2c_bus; |
384 | u8 dpcd[8]; | 385 | u8 dpcd[8]; |
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 58038f5cab38..f87efec76236 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -226,6 +226,11 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) | |||
226 | { | 226 | { |
227 | int i; | 227 | int i; |
228 | 228 | ||
229 | /* no need to take locks, etc. if nothing's going to change */ | ||
230 | if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) && | ||
231 | (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index)) | ||
232 | return; | ||
233 | |||
229 | mutex_lock(&rdev->ddev->struct_mutex); | 234 | mutex_lock(&rdev->ddev->struct_mutex); |
230 | mutex_lock(&rdev->vram_mutex); | 235 | mutex_lock(&rdev->vram_mutex); |
231 | mutex_lock(&rdev->cp.mutex); | 236 | mutex_lock(&rdev->cp.mutex); |
@@ -632,8 +637,6 @@ void radeon_pm_fini(struct radeon_device *rdev) | |||
632 | } | 637 | } |
633 | 638 | ||
634 | radeon_hwmon_fini(rdev); | 639 | radeon_hwmon_fini(rdev); |
635 | if (rdev->pm.i2c_bus) | ||
636 | radeon_i2c_destroy(rdev->pm.i2c_bus); | ||
637 | } | 640 | } |
638 | 641 | ||
639 | void radeon_pm_compute_clocks(struct radeon_device *rdev) | 642 | void radeon_pm_compute_clocks(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index b3ba44c0a818..4ae5a3d1074e 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -3228,34 +3228,34 @@ void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
3228 | } | 3228 | } |
3229 | 3229 | ||
3230 | struct drm_ioctl_desc radeon_ioctls[] = { | 3230 | struct drm_ioctl_desc radeon_ioctls[] = { |
3231 | DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3231 | DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3232 | DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3232 | DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3233 | DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3233 | DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3234 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3234 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3235 | DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), | 3235 | DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), |
3236 | DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), | 3236 | DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), |
3237 | DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH), | 3237 | DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH), |
3238 | DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), | 3238 | DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), |
3239 | DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH), | 3239 | DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH), |
3240 | DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), | 3240 | DRM_IOCTL_DEF_DRV(RADEON_CLEAR, radeon_cp_clear, DRM_AUTH), |
3241 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), | 3241 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH), |
3242 | DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH), | 3242 | DRM_IOCTL_DEF_DRV(RADEON_INDICES, radeon_cp_indices, DRM_AUTH), |
3243 | DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), | 3243 | DRM_IOCTL_DEF_DRV(RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH), |
3244 | DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), | 3244 | DRM_IOCTL_DEF_DRV(RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH), |
3245 | DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3245 | DRM_IOCTL_DEF_DRV(RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3246 | DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), | 3246 | DRM_IOCTL_DEF_DRV(RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH), |
3247 | DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), | 3247 | DRM_IOCTL_DEF_DRV(RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH), |
3248 | DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), | 3248 | DRM_IOCTL_DEF_DRV(RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH), |
3249 | DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH), | 3249 | DRM_IOCTL_DEF_DRV(RADEON_FLIP, radeon_cp_flip, DRM_AUTH), |
3250 | DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), | 3250 | DRM_IOCTL_DEF_DRV(RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH), |
3251 | DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH), | 3251 | DRM_IOCTL_DEF_DRV(RADEON_FREE, radeon_mem_free, DRM_AUTH), |
3252 | DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 3252 | DRM_IOCTL_DEF_DRV(RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
3253 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), | 3253 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH), |
3254 | DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), | 3254 | DRM_IOCTL_DEF_DRV(RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH), |
3255 | DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), | 3255 | DRM_IOCTL_DEF_DRV(RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH), |
3256 | DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), | 3256 | DRM_IOCTL_DEF_DRV(RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH), |
3257 | DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), | 3257 | DRM_IOCTL_DEF_DRV(RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH), |
3258 | DRM_IOCTL_DEF(DRM_RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) | 3258 | DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) |
3259 | }; | 3259 | }; |
3260 | 3260 | ||
3261 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); | 3261 | int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls); |
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index 976dc8d25280..bf5f83ea14fe 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c | |||
@@ -1082,10 +1082,10 @@ void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv) | |||
1082 | } | 1082 | } |
1083 | 1083 | ||
1084 | struct drm_ioctl_desc savage_ioctls[] = { | 1084 | struct drm_ioctl_desc savage_ioctls[] = { |
1085 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 1085 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
1086 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), | 1086 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH), |
1087 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), | 1087 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH), |
1088 | DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), | 1088 | DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), |
1089 | }; | 1089 | }; |
1090 | 1090 | ||
1091 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); | 1091 | int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls); |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index 07d0f2979cac..7fe2b63412ce 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
@@ -320,12 +320,12 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, | |||
320 | } | 320 | } |
321 | 321 | ||
322 | struct drm_ioctl_desc sis_ioctls[] = { | 322 | struct drm_ioctl_desc sis_ioctls[] = { |
323 | DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), | 323 | DRM_IOCTL_DEF_DRV(SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH), |
324 | DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_drm_free, DRM_AUTH), | 324 | DRM_IOCTL_DEF_DRV(SIS_FB_FREE, sis_drm_free, DRM_AUTH), |
325 | DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), | 325 | DRM_IOCTL_DEF_DRV(SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), |
326 | DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), | 326 | DRM_IOCTL_DEF_DRV(SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH), |
327 | DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_drm_free, DRM_AUTH), | 327 | DRM_IOCTL_DEF_DRV(SIS_AGP_FREE, sis_drm_free, DRM_AUTH), |
328 | DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), | 328 | DRM_IOCTL_DEF_DRV(SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), |
329 | }; | 329 | }; |
330 | 330 | ||
331 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); | 331 | int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls); |
diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c index 68dda74a50ae..cc0ffa9abd00 100644 --- a/drivers/gpu/drm/via/via_dma.c +++ b/drivers/gpu/drm/via/via_dma.c | |||
@@ -722,20 +722,20 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file * | |||
722 | } | 722 | } |
723 | 723 | ||
724 | struct drm_ioctl_desc via_ioctls[] = { | 724 | struct drm_ioctl_desc via_ioctls[] = { |
725 | DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), | 725 | DRM_IOCTL_DEF_DRV(VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH), |
726 | DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH), | 726 | DRM_IOCTL_DEF_DRV(VIA_FREEMEM, via_mem_free, DRM_AUTH), |
727 | DRM_IOCTL_DEF(DRM_VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), | 727 | DRM_IOCTL_DEF_DRV(VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER), |
728 | DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), | 728 | DRM_IOCTL_DEF_DRV(VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER), |
729 | DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), | 729 | DRM_IOCTL_DEF_DRV(VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER), |
730 | DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), | 730 | DRM_IOCTL_DEF_DRV(VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH), |
731 | DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH), | 731 | DRM_IOCTL_DEF_DRV(VIA_DMA_INIT, via_dma_init, DRM_AUTH), |
732 | DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), | 732 | DRM_IOCTL_DEF_DRV(VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH), |
733 | DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH), | 733 | DRM_IOCTL_DEF_DRV(VIA_FLUSH, via_flush_ioctl, DRM_AUTH), |
734 | DRM_IOCTL_DEF(DRM_VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), | 734 | DRM_IOCTL_DEF_DRV(VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH), |
735 | DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), | 735 | DRM_IOCTL_DEF_DRV(VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH), |
736 | DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), | 736 | DRM_IOCTL_DEF_DRV(VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH), |
737 | DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), | 737 | DRM_IOCTL_DEF_DRV(VIA_DMA_BLIT, via_dma_blit, DRM_AUTH), |
738 | DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) | 738 | DRM_IOCTL_DEF_DRV(VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) |
739 | }; | 739 | }; |
740 | 740 | ||
741 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); | 741 | int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 9dd395b90216..72ec2e2b6e97 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -99,47 +99,47 @@ | |||
99 | */ | 99 | */ |
100 | 100 | ||
101 | #define VMW_IOCTL_DEF(ioctl, func, flags) \ | 101 | #define VMW_IOCTL_DEF(ioctl, func, flags) \ |
102 | [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func} | 102 | [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_##ioctl, flags, func, DRM_IOCTL_##ioctl} |
103 | 103 | ||
104 | /** | 104 | /** |
105 | * Ioctl definitions. | 105 | * Ioctl definitions. |
106 | */ | 106 | */ |
107 | 107 | ||
108 | static struct drm_ioctl_desc vmw_ioctls[] = { | 108 | static struct drm_ioctl_desc vmw_ioctls[] = { |
109 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_GET_PARAM, vmw_getparam_ioctl, | 109 | VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl, |
110 | DRM_AUTH | DRM_UNLOCKED), | 110 | DRM_AUTH | DRM_UNLOCKED), |
111 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, | 111 | VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, |
112 | DRM_AUTH | DRM_UNLOCKED), | 112 | DRM_AUTH | DRM_UNLOCKED), |
113 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, | 113 | VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, |
114 | DRM_AUTH | DRM_UNLOCKED), | 114 | DRM_AUTH | DRM_UNLOCKED), |
115 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CURSOR_BYPASS, | 115 | VMW_IOCTL_DEF(VMW_CURSOR_BYPASS, |
116 | vmw_kms_cursor_bypass_ioctl, | 116 | vmw_kms_cursor_bypass_ioctl, |
117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 117 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
118 | 118 | ||
119 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CONTROL_STREAM, vmw_overlay_ioctl, | 119 | VMW_IOCTL_DEF(VMW_CONTROL_STREAM, vmw_overlay_ioctl, |
120 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 120 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
121 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, | 121 | VMW_IOCTL_DEF(VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, |
122 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 122 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
123 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_STREAM, vmw_stream_unref_ioctl, | 123 | VMW_IOCTL_DEF(VMW_UNREF_STREAM, vmw_stream_unref_ioctl, |
124 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), | 124 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), |
125 | 125 | ||
126 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_CONTEXT, vmw_context_define_ioctl, | 126 | VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl, |
127 | DRM_AUTH | DRM_UNLOCKED), | 127 | DRM_AUTH | DRM_UNLOCKED), |
128 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, | 128 | VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, |
129 | DRM_AUTH | DRM_UNLOCKED), | 129 | DRM_AUTH | DRM_UNLOCKED), |
130 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_CREATE_SURFACE, vmw_surface_define_ioctl, | 130 | VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl, |
131 | DRM_AUTH | DRM_UNLOCKED), | 131 | DRM_AUTH | DRM_UNLOCKED), |
132 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, | 132 | VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, |
133 | DRM_AUTH | DRM_UNLOCKED), | 133 | DRM_AUTH | DRM_UNLOCKED), |
134 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_REF_SURFACE, vmw_surface_reference_ioctl, | 134 | VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl, |
135 | DRM_AUTH | DRM_UNLOCKED), | 135 | DRM_AUTH | DRM_UNLOCKED), |
136 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_EXECBUF, vmw_execbuf_ioctl, | 136 | VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, |
137 | DRM_AUTH | DRM_UNLOCKED), | 137 | DRM_AUTH | DRM_UNLOCKED), |
138 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, | 138 | VMW_IOCTL_DEF(VMW_FIFO_DEBUG, vmw_fifo_debug_ioctl, |
139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), | 139 | DRM_AUTH | DRM_ROOT_ONLY | DRM_MASTER | DRM_UNLOCKED), |
140 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_FENCE_WAIT, vmw_fence_wait_ioctl, | 140 | VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_wait_ioctl, |
141 | DRM_AUTH | DRM_UNLOCKED), | 141 | DRM_AUTH | DRM_UNLOCKED), |
142 | VMW_IOCTL_DEF(DRM_IOCTL_VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, | 142 | VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, |
143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) | 143 | DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED) |
144 | }; | 144 | }; |
145 | 145 | ||
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index e635199a0cd2..0c52899be964 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1299,6 +1299,7 @@ static const struct hid_device_id hid_blacklist[] = { | |||
1299 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, | 1299 | { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) }, |
1300 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, | 1300 | { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) }, |
1301 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 1301 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
1302 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | ||
1302 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, | 1303 | { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, |
1303 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, | 1304 | { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, |
1304 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, | 1305 | { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, |
diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c index f44bdc084cb2..8ca7f65cf2f8 100644 --- a/drivers/hid/hid-egalax.c +++ b/drivers/hid/hid-egalax.c | |||
@@ -159,6 +159,13 @@ static int egalax_event(struct hid_device *hid, struct hid_field *field, | |||
159 | { | 159 | { |
160 | struct egalax_data *td = hid_get_drvdata(hid); | 160 | struct egalax_data *td = hid_get_drvdata(hid); |
161 | 161 | ||
162 | /* Note, eGalax has two product lines: the first is resistive and | ||
163 | * uses a standard parallel multitouch protocol (product ID == | ||
164 | * 48xx). The second is capacitive and uses an unusual "serial" | ||
165 | * protocol with a different message for each multitouch finger | ||
166 | * (product ID == 72xx). We do not yet generate a correct event | ||
167 | * sequence for the capacitive/serial protocol. | ||
168 | */ | ||
162 | if (hid->claimed & HID_CLAIMED_INPUT) { | 169 | if (hid->claimed & HID_CLAIMED_INPUT) { |
163 | struct input_dev *input = field->hidinput->input; | 170 | struct input_dev *input = field->hidinput->input; |
164 | 171 | ||
@@ -246,6 +253,8 @@ static void egalax_remove(struct hid_device *hdev) | |||
246 | static const struct hid_device_id egalax_devices[] = { | 253 | static const struct hid_device_id egalax_devices[] = { |
247 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | 254 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, |
248 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, | 255 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, |
256 | { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, | ||
257 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, | ||
249 | { } | 258 | { } |
250 | }; | 259 | }; |
251 | MODULE_DEVICE_TABLE(hid, egalax_devices); | 260 | MODULE_DEVICE_TABLE(hid, egalax_devices); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index d3fc13ae094d..85c6d13c9ffa 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -188,6 +188,7 @@ | |||
188 | #define USB_VENDOR_ID_DWAV 0x0eef | 188 | #define USB_VENDOR_ID_DWAV 0x0eef |
189 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 | 189 | #define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001 |
190 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d | 190 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d |
191 | #define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1 0x720c | ||
191 | 192 | ||
192 | #define USB_VENDOR_ID_ELECOM 0x056e | 193 | #define USB_VENDOR_ID_ELECOM 0x056e |
193 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 | 194 | #define USB_DEVICE_ID_ELECOM_BM084 0x0061 |
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index 346f0e34987e..bc2e07740628 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c | |||
@@ -547,11 +547,11 @@ static void picolcd_fb_destroy(struct fb_info *info) | |||
547 | ref_cnt--; | 547 | ref_cnt--; |
548 | mutex_lock(&info->lock); | 548 | mutex_lock(&info->lock); |
549 | (*ref_cnt)--; | 549 | (*ref_cnt)--; |
550 | may_release = !ref_cnt; | 550 | may_release = !*ref_cnt; |
551 | mutex_unlock(&info->lock); | 551 | mutex_unlock(&info->lock); |
552 | if (may_release) { | 552 | if (may_release) { |
553 | framebuffer_release(info); | ||
554 | vfree((u8 *)info->fix.smem_start); | 553 | vfree((u8 *)info->fix.smem_start); |
554 | framebuffer_release(info); | ||
555 | } | 555 | } |
556 | } | 556 | } |
557 | 557 | ||
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 254a003af048..0a29c51114aa 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c | |||
@@ -266,13 +266,15 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
266 | { | 266 | { |
267 | struct hiddev_list *list; | 267 | struct hiddev_list *list; |
268 | struct usb_interface *intf; | 268 | struct usb_interface *intf; |
269 | struct hid_device *hid; | ||
269 | struct hiddev *hiddev; | 270 | struct hiddev *hiddev; |
270 | int res; | 271 | int res; |
271 | 272 | ||
272 | intf = usb_find_interface(&hiddev_driver, iminor(inode)); | 273 | intf = usb_find_interface(&hiddev_driver, iminor(inode)); |
273 | if (!intf) | 274 | if (!intf) |
274 | return -ENODEV; | 275 | return -ENODEV; |
275 | hiddev = usb_get_intfdata(intf); | 276 | hid = usb_get_intfdata(intf); |
277 | hiddev = hid->hiddev; | ||
276 | 278 | ||
277 | if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) | 279 | if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL))) |
278 | return -ENOMEM; | 280 | return -ENOMEM; |
@@ -587,7 +589,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
587 | struct hiddev_list *list = file->private_data; | 589 | struct hiddev_list *list = file->private_data; |
588 | struct hiddev *hiddev = list->hiddev; | 590 | struct hiddev *hiddev = list->hiddev; |
589 | struct hid_device *hid = hiddev->hid; | 591 | struct hid_device *hid = hiddev->hid; |
590 | struct usb_device *dev = hid_to_usb_dev(hid); | 592 | struct usb_device *dev; |
591 | struct hiddev_collection_info cinfo; | 593 | struct hiddev_collection_info cinfo; |
592 | struct hiddev_report_info rinfo; | 594 | struct hiddev_report_info rinfo; |
593 | struct hiddev_field_info finfo; | 595 | struct hiddev_field_info finfo; |
@@ -601,9 +603,11 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
601 | /* Called without BKL by compat methods so no BKL taken */ | 603 | /* Called without BKL by compat methods so no BKL taken */ |
602 | 604 | ||
603 | /* FIXME: Who or what stop this racing with a disconnect ?? */ | 605 | /* FIXME: Who or what stop this racing with a disconnect ?? */ |
604 | if (!hiddev->exist) | 606 | if (!hiddev->exist || !hid) |
605 | return -EIO; | 607 | return -EIO; |
606 | 608 | ||
609 | dev = hid_to_usb_dev(hid); | ||
610 | |||
607 | switch (cmd) { | 611 | switch (cmd) { |
608 | 612 | ||
609 | case HIDIOCGVERSION: | 613 | case HIDIOCGVERSION: |
@@ -888,7 +892,6 @@ int hiddev_connect(struct hid_device *hid, unsigned int force) | |||
888 | hid->hiddev = hiddev; | 892 | hid->hiddev = hiddev; |
889 | hiddev->hid = hid; | 893 | hiddev->hid = hid; |
890 | hiddev->exist = 1; | 894 | hiddev->exist = 1; |
891 | usb_set_intfdata(usbhid->intf, usbhid); | ||
892 | retval = usb_register_dev(usbhid->intf, &hiddev_class); | 895 | retval = usb_register_dev(usbhid->intf, &hiddev_class); |
893 | if (retval) { | 896 | if (retval) { |
894 | err_hid("Not able to get a minor for this device."); | 897 | err_hid("Not able to get a minor for this device."); |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 0fba82943125..4d4d09bdec0a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -332,11 +332,11 @@ config SENSORS_F71805F | |||
332 | will be called f71805f. | 332 | will be called f71805f. |
333 | 333 | ||
334 | config SENSORS_F71882FG | 334 | config SENSORS_F71882FG |
335 | tristate "Fintek F71808E, F71858FG, F71862FG, F71882FG, F71889FG and F8000" | 335 | tristate "Fintek F71858FG, F71862FG, F71882FG, F71889FG and F8000" |
336 | depends on EXPERIMENTAL | 336 | depends on EXPERIMENTAL |
337 | help | 337 | help |
338 | If you say yes here you get support for hardware monitoring features | 338 | If you say yes here you get support for hardware monitoring |
339 | of the Fintek F71808E, F71858FG, F71862FG/71863FG, F71882FG/F71883FG, | 339 | features of the Fintek F71858FG, F71862FG/71863FG, F71882FG/F71883FG, |
340 | F71889FG and F8000 Super-I/O chips. | 340 | F71889FG and F8000 Super-I/O chips. |
341 | 341 | ||
342 | This driver can also be built as a module. If so, the module | 342 | This driver can also be built as a module. If so, the module |
diff --git a/drivers/hwmon/ads7871.c b/drivers/hwmon/ads7871.c index b300a2048af1..52319340e182 100644 --- a/drivers/hwmon/ads7871.c +++ b/drivers/hwmon/ads7871.c | |||
@@ -160,30 +160,12 @@ static const struct attribute_group ads7871_group = { | |||
160 | 160 | ||
161 | static int __devinit ads7871_probe(struct spi_device *spi) | 161 | static int __devinit ads7871_probe(struct spi_device *spi) |
162 | { | 162 | { |
163 | int status, ret, err = 0; | 163 | int ret, err; |
164 | uint8_t val; | 164 | uint8_t val; |
165 | struct ads7871_data *pdata; | 165 | struct ads7871_data *pdata; |
166 | 166 | ||
167 | dev_dbg(&spi->dev, "probe\n"); | 167 | dev_dbg(&spi->dev, "probe\n"); |
168 | 168 | ||
169 | pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL); | ||
170 | if (!pdata) { | ||
171 | err = -ENOMEM; | ||
172 | goto exit; | ||
173 | } | ||
174 | |||
175 | status = sysfs_create_group(&spi->dev.kobj, &ads7871_group); | ||
176 | if (status < 0) | ||
177 | goto error_free; | ||
178 | |||
179 | pdata->hwmon_dev = hwmon_device_register(&spi->dev); | ||
180 | if (IS_ERR(pdata->hwmon_dev)) { | ||
181 | err = PTR_ERR(pdata->hwmon_dev); | ||
182 | goto error_remove; | ||
183 | } | ||
184 | |||
185 | spi_set_drvdata(spi, pdata); | ||
186 | |||
187 | /* Configure the SPI bus */ | 169 | /* Configure the SPI bus */ |
188 | spi->mode = (SPI_MODE_0); | 170 | spi->mode = (SPI_MODE_0); |
189 | spi->bits_per_word = 8; | 171 | spi->bits_per_word = 8; |
@@ -201,6 +183,24 @@ static int __devinit ads7871_probe(struct spi_device *spi) | |||
201 | we need to make sure we really have a chip*/ | 183 | we need to make sure we really have a chip*/ |
202 | if (val != ret) { | 184 | if (val != ret) { |
203 | err = -ENODEV; | 185 | err = -ENODEV; |
186 | goto exit; | ||
187 | } | ||
188 | |||
189 | pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL); | ||
190 | if (!pdata) { | ||
191 | err = -ENOMEM; | ||
192 | goto exit; | ||
193 | } | ||
194 | |||
195 | err = sysfs_create_group(&spi->dev.kobj, &ads7871_group); | ||
196 | if (err < 0) | ||
197 | goto error_free; | ||
198 | |||
199 | spi_set_drvdata(spi, pdata); | ||
200 | |||
201 | pdata->hwmon_dev = hwmon_device_register(&spi->dev); | ||
202 | if (IS_ERR(pdata->hwmon_dev)) { | ||
203 | err = PTR_ERR(pdata->hwmon_dev); | ||
204 | goto error_remove; | 204 | goto error_remove; |
205 | } | 205 | } |
206 | 206 | ||
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index c070c9714cbe..de8111114f46 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -518,7 +518,6 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { | |||
518 | static int __init coretemp_init(void) | 518 | static int __init coretemp_init(void) |
519 | { | 519 | { |
520 | int i, err = -ENODEV; | 520 | int i, err = -ENODEV; |
521 | struct pdev_entry *p, *n; | ||
522 | 521 | ||
523 | /* quick check if we run Intel */ | 522 | /* quick check if we run Intel */ |
524 | if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) | 523 | if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) |
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c index 6207120dcd4d..537841ef44b9 100644 --- a/drivers/hwmon/f71882fg.c +++ b/drivers/hwmon/f71882fg.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ | 45 | #define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */ |
46 | 46 | ||
47 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ | 47 | #define SIO_FINTEK_ID 0x1934 /* Manufacturers ID */ |
48 | #define SIO_F71808_ID 0x0901 /* Chipset ID */ | ||
49 | #define SIO_F71858_ID 0x0507 /* Chipset ID */ | 48 | #define SIO_F71858_ID 0x0507 /* Chipset ID */ |
50 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ | 49 | #define SIO_F71862_ID 0x0601 /* Chipset ID */ |
51 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ | 50 | #define SIO_F71882_ID 0x0541 /* Chipset ID */ |
@@ -97,10 +96,9 @@ static unsigned short force_id; | |||
97 | module_param(force_id, ushort, 0); | 96 | module_param(force_id, ushort, 0); |
98 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); | 97 | MODULE_PARM_DESC(force_id, "Override the detected device ID"); |
99 | 98 | ||
100 | enum chips { f71808fg, f71858fg, f71862fg, f71882fg, f71889fg, f8000 }; | 99 | enum chips { f71858fg, f71862fg, f71882fg, f71889fg, f8000 }; |
101 | 100 | ||
102 | static const char *f71882fg_names[] = { | 101 | static const char *f71882fg_names[] = { |
103 | "f71808fg", | ||
104 | "f71858fg", | 102 | "f71858fg", |
105 | "f71862fg", | 103 | "f71862fg", |
106 | "f71882fg", | 104 | "f71882fg", |
@@ -308,8 +306,8 @@ static struct sensor_device_attribute_2 f71858fg_in_temp_attr[] = { | |||
308 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), | 306 | SENSOR_ATTR_2(temp3_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), |
309 | }; | 307 | }; |
310 | 308 | ||
311 | /* In attr common to the f71862fg, f71882fg and f71889fg */ | 309 | /* Temp and in attr common to the f71862fg, f71882fg and f71889fg */ |
312 | static struct sensor_device_attribute_2 fxxxx_in_attr[] = { | 310 | static struct sensor_device_attribute_2 fxxxx_in_temp_attr[] = { |
313 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | 311 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), |
314 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | 312 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), |
315 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | 313 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), |
@@ -319,22 +317,6 @@ static struct sensor_device_attribute_2 fxxxx_in_attr[] = { | |||
319 | SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), | 317 | SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 6), |
320 | SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), | 318 | SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 7), |
321 | SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), | 319 | SENSOR_ATTR_2(in8_input, S_IRUGO, show_in, NULL, 0, 8), |
322 | }; | ||
323 | |||
324 | /* In attr for the f71808fg */ | ||
325 | static struct sensor_device_attribute_2 f71808_in_attr[] = { | ||
326 | SENSOR_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, 0), | ||
327 | SENSOR_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 0, 1), | ||
328 | SENSOR_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 0, 2), | ||
329 | SENSOR_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 0, 3), | ||
330 | SENSOR_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 0, 4), | ||
331 | SENSOR_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 0, 5), | ||
332 | SENSOR_ATTR_2(in6_input, S_IRUGO, show_in, NULL, 0, 7), | ||
333 | SENSOR_ATTR_2(in7_input, S_IRUGO, show_in, NULL, 0, 8), | ||
334 | }; | ||
335 | |||
336 | /* Temp attr common to the f71808fg, f71862fg, f71882fg and f71889fg */ | ||
337 | static struct sensor_device_attribute_2 fxxxx_temp_attr[] = { | ||
338 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), | 320 | SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 1), |
339 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, | 321 | SENSOR_ATTR_2(temp1_max, S_IRUGO|S_IWUSR, show_temp_max, |
340 | store_temp_max, 0, 1), | 322 | store_temp_max, 0, 1), |
@@ -373,10 +355,6 @@ static struct sensor_device_attribute_2 fxxxx_temp_attr[] = { | |||
373 | store_temp_beep, 0, 6), | 355 | store_temp_beep, 0, 6), |
374 | SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2), | 356 | SENSOR_ATTR_2(temp2_type, S_IRUGO, show_temp_type, NULL, 0, 2), |
375 | SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), | 357 | SENSOR_ATTR_2(temp2_fault, S_IRUGO, show_temp_fault, NULL, 0, 2), |
376 | }; | ||
377 | |||
378 | /* Temp and in attr common to the f71862fg, f71882fg and f71889fg */ | ||
379 | static struct sensor_device_attribute_2 f71862_temp_attr[] = { | ||
380 | SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3), | 358 | SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 0, 3), |
381 | SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, | 359 | SENSOR_ATTR_2(temp3_max, S_IRUGO|S_IWUSR, show_temp_max, |
382 | store_temp_max, 0, 3), | 360 | store_temp_max, 0, 3), |
@@ -1011,11 +989,6 @@ static struct f71882fg_data *f71882fg_update_device(struct device *dev) | |||
1011 | data->temp_type[1] = 6; | 989 | data->temp_type[1] = 6; |
1012 | break; | 990 | break; |
1013 | } | 991 | } |
1014 | } else if (data->type == f71808fg) { | ||
1015 | reg = f71882fg_read8(data, F71882FG_REG_TEMP_TYPE); | ||
1016 | data->temp_type[1] = (reg & 0x02) ? 2 : 4; | ||
1017 | data->temp_type[2] = (reg & 0x04) ? 2 : 4; | ||
1018 | |||
1019 | } else { | 992 | } else { |
1020 | reg2 = f71882fg_read8(data, F71882FG_REG_PECI); | 993 | reg2 = f71882fg_read8(data, F71882FG_REG_PECI); |
1021 | if ((reg2 & 0x03) == 0x01) | 994 | if ((reg2 & 0x03) == 0x01) |
@@ -1898,8 +1871,7 @@ static ssize_t store_pwm_auto_point_temp(struct device *dev, | |||
1898 | 1871 | ||
1899 | val /= 1000; | 1872 | val /= 1000; |
1900 | 1873 | ||
1901 | if (data->type == f71889fg | 1874 | if (data->type == f71889fg) |
1902 | || data->type == f71808fg) | ||
1903 | val = SENSORS_LIMIT(val, -128, 127); | 1875 | val = SENSORS_LIMIT(val, -128, 127); |
1904 | else | 1876 | else |
1905 | val = SENSORS_LIMIT(val, 0, 127); | 1877 | val = SENSORS_LIMIT(val, 0, 127); |
@@ -2002,28 +1974,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2002 | /* fall through! */ | 1974 | /* fall through! */ |
2003 | case f71862fg: | 1975 | case f71862fg: |
2004 | err = f71882fg_create_sysfs_files(pdev, | 1976 | err = f71882fg_create_sysfs_files(pdev, |
2005 | f71862_temp_attr, | 1977 | fxxxx_in_temp_attr, |
2006 | ARRAY_SIZE(f71862_temp_attr)); | 1978 | ARRAY_SIZE(fxxxx_in_temp_attr)); |
2007 | if (err) | ||
2008 | goto exit_unregister_sysfs; | ||
2009 | err = f71882fg_create_sysfs_files(pdev, | ||
2010 | fxxxx_in_attr, | ||
2011 | ARRAY_SIZE(fxxxx_in_attr)); | ||
2012 | if (err) | ||
2013 | goto exit_unregister_sysfs; | ||
2014 | err = f71882fg_create_sysfs_files(pdev, | ||
2015 | fxxxx_temp_attr, | ||
2016 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2017 | break; | ||
2018 | case f71808fg: | ||
2019 | err = f71882fg_create_sysfs_files(pdev, | ||
2020 | f71808_in_attr, | ||
2021 | ARRAY_SIZE(f71808_in_attr)); | ||
2022 | if (err) | ||
2023 | goto exit_unregister_sysfs; | ||
2024 | err = f71882fg_create_sysfs_files(pdev, | ||
2025 | fxxxx_temp_attr, | ||
2026 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2027 | break; | 1979 | break; |
2028 | case f8000: | 1980 | case f8000: |
2029 | err = f71882fg_create_sysfs_files(pdev, | 1981 | err = f71882fg_create_sysfs_files(pdev, |
@@ -2050,7 +2002,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2050 | case f71862fg: | 2002 | case f71862fg: |
2051 | err = (data->pwm_enable & 0x15) != 0x15; | 2003 | err = (data->pwm_enable & 0x15) != 0x15; |
2052 | break; | 2004 | break; |
2053 | case f71808fg: | ||
2054 | case f71882fg: | 2005 | case f71882fg: |
2055 | case f71889fg: | 2006 | case f71889fg: |
2056 | err = 0; | 2007 | err = 0; |
@@ -2096,7 +2047,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev) | |||
2096 | f8000_auto_pwm_attr, | 2047 | f8000_auto_pwm_attr, |
2097 | ARRAY_SIZE(f8000_auto_pwm_attr)); | 2048 | ARRAY_SIZE(f8000_auto_pwm_attr)); |
2098 | break; | 2049 | break; |
2099 | case f71808fg: | ||
2100 | case f71889fg: | 2050 | case f71889fg: |
2101 | for (i = 0; i < nr_fans; i++) { | 2051 | for (i = 0; i < nr_fans; i++) { |
2102 | data->pwm_auto_point_mapping[i] = | 2052 | data->pwm_auto_point_mapping[i] = |
@@ -2176,22 +2126,8 @@ static int f71882fg_remove(struct platform_device *pdev) | |||
2176 | /* fall through! */ | 2126 | /* fall through! */ |
2177 | case f71862fg: | 2127 | case f71862fg: |
2178 | f71882fg_remove_sysfs_files(pdev, | 2128 | f71882fg_remove_sysfs_files(pdev, |
2179 | f71862_temp_attr, | 2129 | fxxxx_in_temp_attr, |
2180 | ARRAY_SIZE(f71862_temp_attr)); | 2130 | ARRAY_SIZE(fxxxx_in_temp_attr)); |
2181 | f71882fg_remove_sysfs_files(pdev, | ||
2182 | fxxxx_in_attr, | ||
2183 | ARRAY_SIZE(fxxxx_in_attr)); | ||
2184 | f71882fg_remove_sysfs_files(pdev, | ||
2185 | fxxxx_temp_attr, | ||
2186 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2187 | break; | ||
2188 | case f71808fg: | ||
2189 | f71882fg_remove_sysfs_files(pdev, | ||
2190 | f71808_in_attr, | ||
2191 | ARRAY_SIZE(f71808_in_attr)); | ||
2192 | f71882fg_remove_sysfs_files(pdev, | ||
2193 | fxxxx_temp_attr, | ||
2194 | ARRAY_SIZE(fxxxx_temp_attr)); | ||
2195 | break; | 2131 | break; |
2196 | case f8000: | 2132 | case f8000: |
2197 | f71882fg_remove_sysfs_files(pdev, | 2133 | f71882fg_remove_sysfs_files(pdev, |
@@ -2259,9 +2195,6 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address, | |||
2259 | 2195 | ||
2260 | devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); | 2196 | devid = force_id ? force_id : superio_inw(sioaddr, SIO_REG_DEVID); |
2261 | switch (devid) { | 2197 | switch (devid) { |
2262 | case SIO_F71808_ID: | ||
2263 | sio_data->type = f71808fg; | ||
2264 | break; | ||
2265 | case SIO_F71858_ID: | 2198 | case SIO_F71858_ID: |
2266 | sio_data->type = f71858fg; | 2199 | sio_data->type = f71858fg; |
2267 | break; | 2200 | break; |
diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index b9bb3e0ca530..39ead2a4d3c5 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c | |||
@@ -143,6 +143,37 @@ static const struct pci_device_id k8temp_ids[] = { | |||
143 | 143 | ||
144 | MODULE_DEVICE_TABLE(pci, k8temp_ids); | 144 | MODULE_DEVICE_TABLE(pci, k8temp_ids); |
145 | 145 | ||
146 | static int __devinit is_rev_g_desktop(u8 model) | ||
147 | { | ||
148 | u32 brandidx; | ||
149 | |||
150 | if (model < 0x69) | ||
151 | return 0; | ||
152 | |||
153 | if (model == 0xc1 || model == 0x6c || model == 0x7c) | ||
154 | return 0; | ||
155 | |||
156 | /* | ||
157 | * Differentiate between AM2 and ASB1. | ||
158 | * See "Constructing the processor Name String" in "Revision | ||
159 | * Guide for AMD NPT Family 0Fh Processors" (33610). | ||
160 | */ | ||
161 | brandidx = cpuid_ebx(0x80000001); | ||
162 | brandidx = (brandidx >> 9) & 0x1f; | ||
163 | |||
164 | /* Single core */ | ||
165 | if ((model == 0x6f || model == 0x7f) && | ||
166 | (brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc)) | ||
167 | return 0; | ||
168 | |||
169 | /* Dual core */ | ||
170 | if (model == 0x6b && | ||
171 | (brandidx == 0xb || brandidx == 0xc)) | ||
172 | return 0; | ||
173 | |||
174 | return 1; | ||
175 | } | ||
176 | |||
146 | static int __devinit k8temp_probe(struct pci_dev *pdev, | 177 | static int __devinit k8temp_probe(struct pci_dev *pdev, |
147 | const struct pci_device_id *id) | 178 | const struct pci_device_id *id) |
148 | { | 179 | { |
@@ -179,9 +210,7 @@ static int __devinit k8temp_probe(struct pci_dev *pdev, | |||
179 | "wrong - check erratum #141\n"); | 210 | "wrong - check erratum #141\n"); |
180 | } | 211 | } |
181 | 212 | ||
182 | if ((model >= 0x69) && | 213 | if (is_rev_g_desktop(model)) { |
183 | !(model == 0xc1 || model == 0x6c || model == 0x7c || | ||
184 | model == 0x6b || model == 0x6f || model == 0x7f)) { | ||
185 | /* | 214 | /* |
186 | * RevG desktop CPUs (i.e. no socket S1G1 or | 215 | * RevG desktop CPUs (i.e. no socket S1G1 or |
187 | * ASB1 parts) need additional offset, | 216 | * ASB1 parts) need additional offset, |
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index d0dc1db80b29..50815022cff1 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -1106,7 +1106,7 @@ static int ohci_iso_recv_init(struct hpsb_iso *iso) | |||
1106 | if (recv->block_irq_interval * 4 > iso->buf_packets) | 1106 | if (recv->block_irq_interval * 4 > iso->buf_packets) |
1107 | recv->block_irq_interval = iso->buf_packets / 4; | 1107 | recv->block_irq_interval = iso->buf_packets / 4; |
1108 | if (recv->block_irq_interval < 1) | 1108 | if (recv->block_irq_interval < 1) |
1109 | recv->block_irq_interval = 1; | 1109 | recv->block_irq_interval = 1; |
1110 | 1110 | ||
1111 | /* choose a buffer stride */ | 1111 | /* choose a buffer stride */ |
1112 | /* must be a power of 2, and <= PAGE_SIZE */ | 1112 | /* must be a power of 2, and <= PAGE_SIZE */ |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index dcc86b97a153..19fa94af207a 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -232,13 +232,13 @@ static void hil_dev_handle_ptr_events(struct hil_dev *ptr) | |||
232 | if (absdev) { | 232 | if (absdev) { |
233 | val = lo + (hi << 8); | 233 | val = lo + (hi << 8); |
234 | #ifdef TABLET_AUTOADJUST | 234 | #ifdef TABLET_AUTOADJUST |
235 | if (val < input_abs_min(dev, ABS_X + i)) | 235 | if (val < input_abs_get_min(dev, ABS_X + i)) |
236 | input_abs_set_min(dev, ABS_X + i, val); | 236 | input_abs_set_min(dev, ABS_X + i, val); |
237 | if (val > input_abs_max(dev, ABS_X + i)) | 237 | if (val > input_abs_get_max(dev, ABS_X + i)) |
238 | input_abs_set_max(dev, ABS_X + i, val); | 238 | input_abs_set_max(dev, ABS_X + i, val); |
239 | #endif | 239 | #endif |
240 | if (i % 3) | 240 | if (i % 3) |
241 | val = input_abs_max(dev, ABS_X + i) - val; | 241 | val = input_abs_get_max(dev, ABS_X + i) - val; |
242 | input_report_abs(dev, ABS_X + i, val); | 242 | input_report_abs(dev, ABS_X + i, val); |
243 | } else { | 243 | } else { |
244 | val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); | 244 | val = (int) (((int8_t) lo) | ((int8_t) hi << 8)); |
@@ -388,11 +388,11 @@ static void hil_dev_pointer_setup(struct hil_dev *ptr) | |||
388 | 388 | ||
389 | #ifdef TABLET_AUTOADJUST | 389 | #ifdef TABLET_AUTOADJUST |
390 | for (i = 0; i < ABS_MAX; i++) { | 390 | for (i = 0; i < ABS_MAX; i++) { |
391 | int diff = input_abs_max(input_dev, ABS_X + i) / 10; | 391 | int diff = input_abs_get_max(input_dev, ABS_X + i) / 10; |
392 | input_abs_set_min(input_dev, ABS_X + i, | 392 | input_abs_set_min(input_dev, ABS_X + i, |
393 | input_abs_min(input_dev, ABS_X + i) + diff) | 393 | input_abs_get_min(input_dev, ABS_X + i) + diff); |
394 | input_abs_set_max(input_dev, ABS_X + i, | 394 | input_abs_set_max(input_dev, ABS_X + i, |
395 | input_abs_max(input_dev, ABS_X + i) - diff) | 395 | input_abs_get_max(input_dev, ABS_X + i) - diff); |
396 | } | 396 | } |
397 | #endif | 397 | #endif |
398 | 398 | ||
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 0e53b3bc39af..f32404f99189 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -567,8 +567,6 @@ static int __devexit pxa27x_keypad_remove(struct platform_device *pdev) | |||
567 | clk_put(keypad->clk); | 567 | clk_put(keypad->clk); |
568 | 568 | ||
569 | input_unregister_device(keypad->input_dev); | 569 | input_unregister_device(keypad->input_dev); |
570 | input_free_device(keypad->input_dev); | ||
571 | |||
572 | iounmap(keypad->mmio_base); | 570 | iounmap(keypad->mmio_base); |
573 | 571 | ||
574 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 572 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index bb53fd33cd1c..0d4266a533a5 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
@@ -811,6 +811,8 @@ static struct miscdevice uinput_misc = { | |||
811 | .minor = UINPUT_MINOR, | 811 | .minor = UINPUT_MINOR, |
812 | .name = UINPUT_NAME, | 812 | .name = UINPUT_NAME, |
813 | }; | 813 | }; |
814 | MODULE_ALIAS_MISCDEV(UINPUT_MINOR); | ||
815 | MODULE_ALIAS("devname:" UINPUT_NAME); | ||
814 | 816 | ||
815 | static int __init uinput_init(void) | 817 | static int __init uinput_init(void) |
816 | { | 818 | { |
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 83c24cca234a..d528a2dba064 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
@@ -138,8 +138,8 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
138 | 138 | ||
139 | fx(0) = value; | 139 | fx(0) = value; |
140 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 140 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
141 | size = input_abs_get_min(dev, ABS_X) - | 141 | size = input_abs_get_max(dev, ABS_X) - |
142 | input_abs_get_max(dev, ABS_X); | 142 | input_abs_get_min(dev, ABS_X); |
143 | if (size == 0) | 143 | if (size == 0) |
144 | size = 256 * 2; | 144 | size = 256 * 2; |
145 | 145 | ||
@@ -155,8 +155,8 @@ static void mousedev_touchpad_event(struct input_dev *dev, | |||
155 | fy(0) = value; | 155 | fy(0) = value; |
156 | if (mousedev->touch && mousedev->pkt_count >= 2) { | 156 | if (mousedev->touch && mousedev->pkt_count >= 2) { |
157 | /* use X size for ABS_Y to keep the same scale */ | 157 | /* use X size for ABS_Y to keep the same scale */ |
158 | size = input_abs_get_min(dev, ABS_X) - | 158 | size = input_abs_get_max(dev, ABS_X) - |
159 | input_abs_get_max(dev, ABS_X); | 159 | input_abs_get_min(dev, ABS_X); |
160 | if (size == 0) | 160 | if (size == 0) |
161 | size = 256 * 2; | 161 | size = 256 * 2; |
162 | 162 | ||
diff --git a/drivers/isdn/hardware/avm/Kconfig b/drivers/isdn/hardware/avm/Kconfig index 5dbcbe3a54a6..b99b906ea9b1 100644 --- a/drivers/isdn/hardware/avm/Kconfig +++ b/drivers/isdn/hardware/avm/Kconfig | |||
@@ -36,12 +36,13 @@ config ISDN_DRV_AVMB1_T1ISA | |||
36 | 36 | ||
37 | config ISDN_DRV_AVMB1_B1PCMCIA | 37 | config ISDN_DRV_AVMB1_B1PCMCIA |
38 | tristate "AVM B1/M1/M2 PCMCIA support" | 38 | tristate "AVM B1/M1/M2 PCMCIA support" |
39 | depends on PCMCIA | ||
39 | help | 40 | help |
40 | Enable support for the PCMCIA version of the AVM B1 card. | 41 | Enable support for the PCMCIA version of the AVM B1 card. |
41 | 42 | ||
42 | config ISDN_DRV_AVMB1_AVM_CS | 43 | config ISDN_DRV_AVMB1_AVM_CS |
43 | tristate "AVM B1/M1/M2 PCMCIA cs module" | 44 | tristate "AVM B1/M1/M2 PCMCIA cs module" |
44 | depends on ISDN_DRV_AVMB1_B1PCMCIA && PCMCIA | 45 | depends on ISDN_DRV_AVMB1_B1PCMCIA |
45 | help | 46 | help |
46 | Enable the PCMCIA client driver for the AVM B1/M1/M2 | 47 | Enable the PCMCIA client driver for the AVM B1/M1/M2 |
47 | PCMCIA cards. | 48 | PCMCIA cards. |
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 35bc2737412f..2d17e76066bd 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/syscalls.h> | 45 | #include <linux/syscalls.h> |
46 | #include <linux/suspend.h> | 46 | #include <linux/suspend.h> |
47 | #include <linux/cpu.h> | 47 | #include <linux/cpu.h> |
48 | #include <linux/compat.h> | ||
48 | #include <asm/prom.h> | 49 | #include <asm/prom.h> |
49 | #include <asm/machdep.h> | 50 | #include <asm/machdep.h> |
50 | #include <asm/io.h> | 51 | #include <asm/io.h> |
@@ -2349,11 +2350,52 @@ static long pmu_unlocked_ioctl(struct file *filp, | |||
2349 | return ret; | 2350 | return ret; |
2350 | } | 2351 | } |
2351 | 2352 | ||
2353 | #ifdef CONFIG_COMPAT | ||
2354 | #define PMU_IOC_GET_BACKLIGHT32 _IOR('B', 1, compat_size_t) | ||
2355 | #define PMU_IOC_SET_BACKLIGHT32 _IOW('B', 2, compat_size_t) | ||
2356 | #define PMU_IOC_GET_MODEL32 _IOR('B', 3, compat_size_t) | ||
2357 | #define PMU_IOC_HAS_ADB32 _IOR('B', 4, compat_size_t) | ||
2358 | #define PMU_IOC_CAN_SLEEP32 _IOR('B', 5, compat_size_t) | ||
2359 | #define PMU_IOC_GRAB_BACKLIGHT32 _IOR('B', 6, compat_size_t) | ||
2360 | |||
2361 | static long compat_pmu_ioctl (struct file *filp, u_int cmd, u_long arg) | ||
2362 | { | ||
2363 | switch (cmd) { | ||
2364 | case PMU_IOC_SLEEP: | ||
2365 | break; | ||
2366 | case PMU_IOC_GET_BACKLIGHT32: | ||
2367 | cmd = PMU_IOC_GET_BACKLIGHT; | ||
2368 | break; | ||
2369 | case PMU_IOC_SET_BACKLIGHT32: | ||
2370 | cmd = PMU_IOC_SET_BACKLIGHT; | ||
2371 | break; | ||
2372 | case PMU_IOC_GET_MODEL32: | ||
2373 | cmd = PMU_IOC_GET_MODEL; | ||
2374 | break; | ||
2375 | case PMU_IOC_HAS_ADB32: | ||
2376 | cmd = PMU_IOC_HAS_ADB; | ||
2377 | break; | ||
2378 | case PMU_IOC_CAN_SLEEP32: | ||
2379 | cmd = PMU_IOC_CAN_SLEEP; | ||
2380 | break; | ||
2381 | case PMU_IOC_GRAB_BACKLIGHT32: | ||
2382 | cmd = PMU_IOC_GRAB_BACKLIGHT; | ||
2383 | break; | ||
2384 | default: | ||
2385 | return -ENOIOCTLCMD; | ||
2386 | } | ||
2387 | return pmu_unlocked_ioctl(filp, cmd, (unsigned long)compat_ptr(arg)); | ||
2388 | } | ||
2389 | #endif | ||
2390 | |||
2352 | static const struct file_operations pmu_device_fops = { | 2391 | static const struct file_operations pmu_device_fops = { |
2353 | .read = pmu_read, | 2392 | .read = pmu_read, |
2354 | .write = pmu_write, | 2393 | .write = pmu_write, |
2355 | .poll = pmu_fpoll, | 2394 | .poll = pmu_fpoll, |
2356 | .unlocked_ioctl = pmu_unlocked_ioctl, | 2395 | .unlocked_ioctl = pmu_unlocked_ioctl, |
2396 | #ifdef CONFIG_COMPAT | ||
2397 | .compat_ioctl = compat_pmu_ioctl, | ||
2398 | #endif | ||
2357 | .open = pmu_open, | 2399 | .open = pmu_open, |
2358 | .release = pmu_release, | 2400 | .release = pmu_release, |
2359 | }; | 2401 | }; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 11567c7999a2..c148b6302154 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -2136,16 +2136,6 @@ static void sync_sbs(mddev_t * mddev, int nospares) | |||
2136 | * with the rest of the array) | 2136 | * with the rest of the array) |
2137 | */ | 2137 | */ |
2138 | mdk_rdev_t *rdev; | 2138 | mdk_rdev_t *rdev; |
2139 | |||
2140 | /* First make sure individual recovery_offsets are correct */ | ||
2141 | list_for_each_entry(rdev, &mddev->disks, same_set) { | ||
2142 | if (rdev->raid_disk >= 0 && | ||
2143 | mddev->delta_disks >= 0 && | ||
2144 | !test_bit(In_sync, &rdev->flags) && | ||
2145 | mddev->curr_resync_completed > rdev->recovery_offset) | ||
2146 | rdev->recovery_offset = mddev->curr_resync_completed; | ||
2147 | |||
2148 | } | ||
2149 | list_for_each_entry(rdev, &mddev->disks, same_set) { | 2139 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
2150 | if (rdev->sb_events == mddev->events || | 2140 | if (rdev->sb_events == mddev->events || |
2151 | (nospares && | 2141 | (nospares && |
@@ -2167,12 +2157,27 @@ static void md_update_sb(mddev_t * mddev, int force_change) | |||
2167 | int sync_req; | 2157 | int sync_req; |
2168 | int nospares = 0; | 2158 | int nospares = 0; |
2169 | 2159 | ||
2170 | mddev->utime = get_seconds(); | ||
2171 | if (mddev->external) | ||
2172 | return; | ||
2173 | repeat: | 2160 | repeat: |
2161 | /* First make sure individual recovery_offsets are correct */ | ||
2162 | list_for_each_entry(rdev, &mddev->disks, same_set) { | ||
2163 | if (rdev->raid_disk >= 0 && | ||
2164 | mddev->delta_disks >= 0 && | ||
2165 | !test_bit(In_sync, &rdev->flags) && | ||
2166 | mddev->curr_resync_completed > rdev->recovery_offset) | ||
2167 | rdev->recovery_offset = mddev->curr_resync_completed; | ||
2168 | |||
2169 | } | ||
2170 | if (mddev->external || !mddev->persistent) { | ||
2171 | clear_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
2172 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
2173 | wake_up(&mddev->sb_wait); | ||
2174 | return; | ||
2175 | } | ||
2176 | |||
2174 | spin_lock_irq(&mddev->write_lock); | 2177 | spin_lock_irq(&mddev->write_lock); |
2175 | 2178 | ||
2179 | mddev->utime = get_seconds(); | ||
2180 | |||
2176 | set_bit(MD_CHANGE_PENDING, &mddev->flags); | 2181 | set_bit(MD_CHANGE_PENDING, &mddev->flags); |
2177 | if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) | 2182 | if (test_and_clear_bit(MD_CHANGE_DEVS, &mddev->flags)) |
2178 | force_change = 1; | 2183 | force_change = 1; |
@@ -2221,19 +2226,6 @@ repeat: | |||
2221 | MD_BUG(); | 2226 | MD_BUG(); |
2222 | mddev->events --; | 2227 | mddev->events --; |
2223 | } | 2228 | } |
2224 | |||
2225 | /* | ||
2226 | * do not write anything to disk if using | ||
2227 | * nonpersistent superblocks | ||
2228 | */ | ||
2229 | if (!mddev->persistent) { | ||
2230 | if (!mddev->external) | ||
2231 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
2232 | |||
2233 | spin_unlock_irq(&mddev->write_lock); | ||
2234 | wake_up(&mddev->sb_wait); | ||
2235 | return; | ||
2236 | } | ||
2237 | sync_sbs(mddev, nospares); | 2229 | sync_sbs(mddev, nospares); |
2238 | spin_unlock_irq(&mddev->write_lock); | 2230 | spin_unlock_irq(&mddev->write_lock); |
2239 | 2231 | ||
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 73cc74ffc26b..ad83a4dcadc3 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -787,8 +787,8 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
787 | struct bio_list bl; | 787 | struct bio_list bl; |
788 | struct page **behind_pages = NULL; | 788 | struct page **behind_pages = NULL; |
789 | const int rw = bio_data_dir(bio); | 789 | const int rw = bio_data_dir(bio); |
790 | const bool do_sync = (bio->bi_rw & REQ_SYNC); | 790 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); |
791 | bool do_barriers; | 791 | unsigned long do_barriers; |
792 | mdk_rdev_t *blocked_rdev; | 792 | mdk_rdev_t *blocked_rdev; |
793 | 793 | ||
794 | /* | 794 | /* |
@@ -1120,6 +1120,8 @@ static int raid1_spare_active(mddev_t *mddev) | |||
1120 | { | 1120 | { |
1121 | int i; | 1121 | int i; |
1122 | conf_t *conf = mddev->private; | 1122 | conf_t *conf = mddev->private; |
1123 | int count = 0; | ||
1124 | unsigned long flags; | ||
1123 | 1125 | ||
1124 | /* | 1126 | /* |
1125 | * Find all failed disks within the RAID1 configuration | 1127 | * Find all failed disks within the RAID1 configuration |
@@ -1131,15 +1133,16 @@ static int raid1_spare_active(mddev_t *mddev) | |||
1131 | if (rdev | 1133 | if (rdev |
1132 | && !test_bit(Faulty, &rdev->flags) | 1134 | && !test_bit(Faulty, &rdev->flags) |
1133 | && !test_and_set_bit(In_sync, &rdev->flags)) { | 1135 | && !test_and_set_bit(In_sync, &rdev->flags)) { |
1134 | unsigned long flags; | 1136 | count++; |
1135 | spin_lock_irqsave(&conf->device_lock, flags); | 1137 | sysfs_notify_dirent(rdev->sysfs_state); |
1136 | mddev->degraded--; | ||
1137 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1138 | } | 1138 | } |
1139 | } | 1139 | } |
1140 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1141 | mddev->degraded -= count; | ||
1142 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1140 | 1143 | ||
1141 | print_conf(conf); | 1144 | print_conf(conf); |
1142 | return 0; | 1145 | return count; |
1143 | } | 1146 | } |
1144 | 1147 | ||
1145 | 1148 | ||
@@ -1640,7 +1643,7 @@ static void raid1d(mddev_t *mddev) | |||
1640 | * We already have a nr_pending reference on these rdevs. | 1643 | * We already have a nr_pending reference on these rdevs. |
1641 | */ | 1644 | */ |
1642 | int i; | 1645 | int i; |
1643 | const bool do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC); | 1646 | const unsigned long do_sync = (r1_bio->master_bio->bi_rw & REQ_SYNC); |
1644 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); | 1647 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); |
1645 | clear_bit(R1BIO_Barrier, &r1_bio->state); | 1648 | clear_bit(R1BIO_Barrier, &r1_bio->state); |
1646 | for (i=0; i < conf->raid_disks; i++) | 1649 | for (i=0; i < conf->raid_disks; i++) |
@@ -1696,7 +1699,7 @@ static void raid1d(mddev_t *mddev) | |||
1696 | (unsigned long long)r1_bio->sector); | 1699 | (unsigned long long)r1_bio->sector); |
1697 | raid_end_bio_io(r1_bio); | 1700 | raid_end_bio_io(r1_bio); |
1698 | } else { | 1701 | } else { |
1699 | const bool do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC; | 1702 | const unsigned long do_sync = r1_bio->master_bio->bi_rw & REQ_SYNC; |
1700 | r1_bio->bios[r1_bio->read_disk] = | 1703 | r1_bio->bios[r1_bio->read_disk] = |
1701 | mddev->ro ? IO_BLOCKED : NULL; | 1704 | mddev->ro ? IO_BLOCKED : NULL; |
1702 | r1_bio->read_disk = disk; | 1705 | r1_bio->read_disk = disk; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index a88aeb5198c7..84718383124d 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -799,7 +799,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
799 | int i; | 799 | int i; |
800 | int chunk_sects = conf->chunk_mask + 1; | 800 | int chunk_sects = conf->chunk_mask + 1; |
801 | const int rw = bio_data_dir(bio); | 801 | const int rw = bio_data_dir(bio); |
802 | const bool do_sync = (bio->bi_rw & REQ_SYNC); | 802 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); |
803 | struct bio_list bl; | 803 | struct bio_list bl; |
804 | unsigned long flags; | 804 | unsigned long flags; |
805 | mdk_rdev_t *blocked_rdev; | 805 | mdk_rdev_t *blocked_rdev; |
@@ -1116,6 +1116,8 @@ static int raid10_spare_active(mddev_t *mddev) | |||
1116 | int i; | 1116 | int i; |
1117 | conf_t *conf = mddev->private; | 1117 | conf_t *conf = mddev->private; |
1118 | mirror_info_t *tmp; | 1118 | mirror_info_t *tmp; |
1119 | int count = 0; | ||
1120 | unsigned long flags; | ||
1119 | 1121 | ||
1120 | /* | 1122 | /* |
1121 | * Find all non-in_sync disks within the RAID10 configuration | 1123 | * Find all non-in_sync disks within the RAID10 configuration |
@@ -1126,15 +1128,16 @@ static int raid10_spare_active(mddev_t *mddev) | |||
1126 | if (tmp->rdev | 1128 | if (tmp->rdev |
1127 | && !test_bit(Faulty, &tmp->rdev->flags) | 1129 | && !test_bit(Faulty, &tmp->rdev->flags) |
1128 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { | 1130 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { |
1129 | unsigned long flags; | 1131 | count++; |
1130 | spin_lock_irqsave(&conf->device_lock, flags); | 1132 | sysfs_notify_dirent(tmp->rdev->sysfs_state); |
1131 | mddev->degraded--; | ||
1132 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1133 | } | 1133 | } |
1134 | } | 1134 | } |
1135 | spin_lock_irqsave(&conf->device_lock, flags); | ||
1136 | mddev->degraded -= count; | ||
1137 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
1135 | 1138 | ||
1136 | print_conf(conf); | 1139 | print_conf(conf); |
1137 | return 0; | 1140 | return count; |
1138 | } | 1141 | } |
1139 | 1142 | ||
1140 | 1143 | ||
@@ -1734,7 +1737,7 @@ static void raid10d(mddev_t *mddev) | |||
1734 | raid_end_bio_io(r10_bio); | 1737 | raid_end_bio_io(r10_bio); |
1735 | bio_put(bio); | 1738 | bio_put(bio); |
1736 | } else { | 1739 | } else { |
1737 | const bool do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC); | 1740 | const unsigned long do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC); |
1738 | bio_put(bio); | 1741 | bio_put(bio); |
1739 | rdev = conf->mirrors[mirror].rdev; | 1742 | rdev = conf->mirrors[mirror].rdev; |
1740 | if (printk_ratelimit()) | 1743 | if (printk_ratelimit()) |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 866d4b5a144c..69b0a169e43d 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -5330,6 +5330,8 @@ static int raid5_spare_active(mddev_t *mddev) | |||
5330 | int i; | 5330 | int i; |
5331 | raid5_conf_t *conf = mddev->private; | 5331 | raid5_conf_t *conf = mddev->private; |
5332 | struct disk_info *tmp; | 5332 | struct disk_info *tmp; |
5333 | int count = 0; | ||
5334 | unsigned long flags; | ||
5333 | 5335 | ||
5334 | for (i = 0; i < conf->raid_disks; i++) { | 5336 | for (i = 0; i < conf->raid_disks; i++) { |
5335 | tmp = conf->disks + i; | 5337 | tmp = conf->disks + i; |
@@ -5337,14 +5339,15 @@ static int raid5_spare_active(mddev_t *mddev) | |||
5337 | && tmp->rdev->recovery_offset == MaxSector | 5339 | && tmp->rdev->recovery_offset == MaxSector |
5338 | && !test_bit(Faulty, &tmp->rdev->flags) | 5340 | && !test_bit(Faulty, &tmp->rdev->flags) |
5339 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { | 5341 | && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { |
5340 | unsigned long flags; | 5342 | count++; |
5341 | spin_lock_irqsave(&conf->device_lock, flags); | 5343 | sysfs_notify_dirent(tmp->rdev->sysfs_state); |
5342 | mddev->degraded--; | ||
5343 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
5344 | } | 5344 | } |
5345 | } | 5345 | } |
5346 | spin_lock_irqsave(&conf->device_lock, flags); | ||
5347 | mddev->degraded -= count; | ||
5348 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
5346 | print_raid5_conf(conf); | 5349 | print_raid5_conf(conf); |
5347 | return 0; | 5350 | return count; |
5348 | } | 5351 | } |
5349 | 5352 | ||
5350 | static int raid5_remove_disk(mddev_t *mddev, int number) | 5353 | static int raid5_remove_disk(mddev_t *mddev, int number) |
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig index decdeda840d0..fd0830ed10d8 100644 --- a/drivers/media/dvb/mantis/Kconfig +++ b/drivers/media/dvb/mantis/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config MANTIS_CORE | 1 | config MANTIS_CORE |
2 | tristate "Mantis/Hopper PCI bridge based devices" | 2 | tristate "Mantis/Hopper PCI bridge based devices" |
3 | depends on PCI && I2C && INPUT | 3 | depends on PCI && I2C && INPUT && IR_CORE |
4 | 4 | ||
5 | help | 5 | help |
6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. | 6 | Support for PCI cards based on the Mantis and Hopper PCi bridge. |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 0efe631e50ca..d80cfdc8edd2 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -86,7 +86,9 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) | |||
86 | init_waitqueue_head(&host->wq); | 86 | init_waitqueue_head(&host->wq); |
87 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); | 87 | INIT_DELAYED_WORK(&host->detect, mmc_rescan); |
88 | INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable); | 88 | INIT_DELAYED_WORK_DEFERRABLE(&host->disable, mmc_host_deeper_disable); |
89 | #ifdef CONFIG_PM | ||
89 | host->pm_notify.notifier_call = mmc_pm_notify; | 90 | host->pm_notify.notifier_call = mmc_pm_notify; |
91 | #endif | ||
90 | 92 | ||
91 | /* | 93 | /* |
92 | * By default, hosts do not support SGIO or large requests. | 94 | * By default, hosts do not support SGIO or large requests. |
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 283190bc2a40..68d12794cfd9 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig | |||
@@ -132,7 +132,7 @@ config MMC_SDHCI_CNS3XXX | |||
132 | 132 | ||
133 | config MMC_SDHCI_S3C | 133 | config MMC_SDHCI_S3C |
134 | tristate "SDHCI support on Samsung S3C SoC" | 134 | tristate "SDHCI support on Samsung S3C SoC" |
135 | depends on MMC_SDHCI && (PLAT_S3C24XX || PLAT_S3C64XX) | 135 | depends on MMC_SDHCI && PLAT_SAMSUNG |
136 | help | 136 | help |
137 | This selects the Secure Digital Host Controller Interface (SDHCI) | 137 | This selects the Secure Digital Host Controller Interface (SDHCI) |
138 | often referrered to as the HSMMC block in some of the Samsung S3C | 138 | often referrered to as the HSMMC block in some of the Samsung S3C |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 0a7f2614c6f0..71ad4163b95e 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -242,7 +242,7 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | |||
242 | { | 242 | { |
243 | struct sdhci_host *host = platform_get_drvdata(dev); | 243 | struct sdhci_host *host = platform_get_drvdata(dev); |
244 | if (host) { | 244 | if (host) { |
245 | mutex_lock(&host->lock); | 245 | spin_lock(&host->lock); |
246 | if (state) { | 246 | if (state) { |
247 | dev_dbg(&dev->dev, "card inserted.\n"); | 247 | dev_dbg(&dev->dev, "card inserted.\n"); |
248 | host->flags &= ~SDHCI_DEVICE_DEAD; | 248 | host->flags &= ~SDHCI_DEVICE_DEAD; |
@@ -252,8 +252,8 @@ static void sdhci_s3c_notify_change(struct platform_device *dev, int state) | |||
252 | host->flags |= SDHCI_DEVICE_DEAD; | 252 | host->flags |= SDHCI_DEVICE_DEAD; |
253 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; | 253 | host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION; |
254 | } | 254 | } |
255 | sdhci_card_detect(host); | 255 | tasklet_schedule(&host->card_tasklet); |
256 | mutex_unlock(&host->lock); | 256 | spin_unlock(&host->lock); |
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 785512133b50..401527d273b5 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1180,7 +1180,8 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
1180 | else | 1180 | else |
1181 | ctrl &= ~SDHCI_CTRL_4BITBUS; | 1181 | ctrl &= ~SDHCI_CTRL_4BITBUS; |
1182 | 1182 | ||
1183 | if (ios->timing == MMC_TIMING_SD_HS) | 1183 | if (ios->timing == MMC_TIMING_SD_HS && |
1184 | !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)) | ||
1184 | ctrl |= SDHCI_CTRL_HISPD; | 1185 | ctrl |= SDHCI_CTRL_HISPD; |
1185 | else | 1186 | else |
1186 | ctrl &= ~SDHCI_CTRL_HISPD; | 1187 | ctrl &= ~SDHCI_CTRL_HISPD; |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index 036cfae76368..d316bc79b636 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -245,6 +245,8 @@ struct sdhci_host { | |||
245 | #define SDHCI_QUIRK_MISSING_CAPS (1<<27) | 245 | #define SDHCI_QUIRK_MISSING_CAPS (1<<27) |
246 | /* Controller uses Auto CMD12 command to stop the transfer */ | 246 | /* Controller uses Auto CMD12 command to stop the transfer */ |
247 | #define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1<<28) | 247 | #define SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12 (1<<28) |
248 | /* Controller doesn't have HISPD bit field in HI-SPEED SD card */ | ||
249 | #define SDHCI_QUIRK_NO_HISPD_BIT (1<<29) | ||
248 | 250 | ||
249 | int irq; /* Device IRQ */ | 251 | int irq; /* Device IRQ */ |
250 | void __iomem * ioaddr; /* Mapped address */ | 252 | void __iomem * ioaddr; /* Mapped address */ |
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 00af55d7afba..fe63f6bd663c 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/mtd/partitions.h> | 22 | #include <linux/mtd/partitions.h> |
23 | #include <linux/mtd/concat.h> | 23 | #include <linux/mtd/concat.h> |
24 | #include <linux/of.h> | 24 | #include <linux/of.h> |
25 | #include <linux/of_address.h> | ||
25 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | 28 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index a3c7473dd409..d551ddd9537a 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -2866,6 +2866,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2866 | */ | 2866 | */ |
2867 | if (id_data[0] == id_data[6] && id_data[1] == id_data[7] && | 2867 | if (id_data[0] == id_data[6] && id_data[1] == id_data[7] && |
2868 | id_data[0] == NAND_MFR_SAMSUNG && | 2868 | id_data[0] == NAND_MFR_SAMSUNG && |
2869 | (chip->cellinfo & NAND_CI_CELLTYPE_MSK) && | ||
2869 | id_data[5] != 0x00) { | 2870 | id_data[5] != 0x00) { |
2870 | /* Calc pagesize */ | 2871 | /* Calc pagesize */ |
2871 | mtd->writesize = 2048 << (extid & 0x03); | 2872 | mtd->writesize = 2048 << (extid & 0x03); |
@@ -2934,14 +2935,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
2934 | chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1; | 2935 | chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)) + 32 - 1; |
2935 | 2936 | ||
2936 | /* Set the bad block position */ | 2937 | /* Set the bad block position */ |
2937 | if (!(busw & NAND_BUSWIDTH_16) && (*maf_id == NAND_MFR_STMICRO || | 2938 | if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16)) |
2938 | (*maf_id == NAND_MFR_SAMSUNG && | ||
2939 | mtd->writesize == 512) || | ||
2940 | *maf_id == NAND_MFR_AMD)) | ||
2941 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; | ||
2942 | else | ||
2943 | chip->badblockpos = NAND_LARGE_BADBLOCK_POS; | 2939 | chip->badblockpos = NAND_LARGE_BADBLOCK_POS; |
2944 | 2940 | else | |
2941 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; | ||
2945 | 2942 | ||
2946 | /* Get chip options, preserve non chip based options */ | 2943 | /* Get chip options, preserve non chip based options */ |
2947 | chip->options &= ~NAND_CHIPOPTIONS_MSK; | 2944 | chip->options &= ~NAND_CHIPOPTIONS_MSK; |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index e02fa4f0e3c9..4d89f3780207 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -363,7 +363,7 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = { | |||
363 | #define tAR_NDTR1(r) (((r) >> 0) & 0xf) | 363 | #define tAR_NDTR1(r) (((r) >> 0) & 0xf) |
364 | 364 | ||
365 | /* convert nano-seconds to nand flash controller clock cycles */ | 365 | /* convert nano-seconds to nand flash controller clock cycles */ |
366 | #define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1) | 366 | #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) |
367 | 367 | ||
368 | /* convert nand flash controller clock cycles to nano-seconds */ | 368 | /* convert nand flash controller clock cycles to nano-seconds */ |
369 | #define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000)) | 369 | #define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000)) |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index c754d88e5ec9..c685a55fc2f4 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -633,7 +633,8 @@ struct vortex_private { | |||
633 | open:1, | 633 | open:1, |
634 | medialock:1, | 634 | medialock:1, |
635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ | 635 | must_free_region:1, /* Flag: if zero, Cardbus owns the I/O region */ |
636 | large_frames:1; /* accept large frames */ | 636 | large_frames:1, /* accept large frames */ |
637 | handling_irq:1; /* private in_irq indicator */ | ||
637 | int drv_flags; | 638 | int drv_flags; |
638 | u16 status_enable; | 639 | u16 status_enable; |
639 | u16 intr_enable; | 640 | u16 intr_enable; |
@@ -2133,6 +2134,15 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2133 | dev->name, vp->cur_tx); | 2134 | dev->name, vp->cur_tx); |
2134 | } | 2135 | } |
2135 | 2136 | ||
2137 | /* | ||
2138 | * We can't allow a recursion from our interrupt handler back into the | ||
2139 | * tx routine, as they take the same spin lock, and that causes | ||
2140 | * deadlock. Just return NETDEV_TX_BUSY and let the stack try again in | ||
2141 | * a bit | ||
2142 | */ | ||
2143 | if (vp->handling_irq) | ||
2144 | return NETDEV_TX_BUSY; | ||
2145 | |||
2136 | if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { | 2146 | if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) { |
2137 | if (vortex_debug > 0) | 2147 | if (vortex_debug > 0) |
2138 | pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n", | 2148 | pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n", |
@@ -2335,11 +2345,13 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2335 | 2345 | ||
2336 | ioaddr = vp->ioaddr; | 2346 | ioaddr = vp->ioaddr; |
2337 | 2347 | ||
2348 | |||
2338 | /* | 2349 | /* |
2339 | * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout | 2350 | * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout |
2340 | * and boomerang_start_xmit | 2351 | * and boomerang_start_xmit |
2341 | */ | 2352 | */ |
2342 | spin_lock(&vp->lock); | 2353 | spin_lock(&vp->lock); |
2354 | vp->handling_irq = 1; | ||
2343 | 2355 | ||
2344 | status = ioread16(ioaddr + EL3_STATUS); | 2356 | status = ioread16(ioaddr + EL3_STATUS); |
2345 | 2357 | ||
@@ -2447,6 +2459,7 @@ boomerang_interrupt(int irq, void *dev_id) | |||
2447 | pr_debug("%s: exiting interrupt, status %4.4x.\n", | 2459 | pr_debug("%s: exiting interrupt, status %4.4x.\n", |
2448 | dev->name, status); | 2460 | dev->name, status); |
2449 | handler_exit: | 2461 | handler_exit: |
2462 | vp->handling_irq = 0; | ||
2450 | spin_unlock(&vp->lock); | 2463 | spin_unlock(&vp->lock); |
2451 | return IRQ_HANDLED; | 2464 | return IRQ_HANDLED; |
2452 | } | 2465 | } |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 5a6895320b48..2cc81a54cbf3 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -928,6 +928,16 @@ config SMC91X | |||
928 | The module will be called smc91x. If you want to compile it as a | 928 | The module will be called smc91x. If you want to compile it as a |
929 | module, say M here and read <file:Documentation/kbuild/modules.txt>. | 929 | module, say M here and read <file:Documentation/kbuild/modules.txt>. |
930 | 930 | ||
931 | config PXA168_ETH | ||
932 | tristate "Marvell pxa168 ethernet support" | ||
933 | depends on CPU_PXA168 | ||
934 | select PHYLIB | ||
935 | help | ||
936 | This driver supports the pxa168 Ethernet ports. | ||
937 | |||
938 | To compile this driver as a module, choose M here. The module | ||
939 | will be called pxa168_eth. | ||
940 | |||
931 | config NET_NETX | 941 | config NET_NETX |
932 | tristate "NetX Ethernet support" | 942 | tristate "NetX Ethernet support" |
933 | select MII | 943 | select MII |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 56e8c27f77ce..3e8f150c4b14 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -244,6 +244,7 @@ obj-$(CONFIG_MYRI10GE) += myri10ge/ | |||
244 | obj-$(CONFIG_SMC91X) += smc91x.o | 244 | obj-$(CONFIG_SMC91X) += smc91x.o |
245 | obj-$(CONFIG_SMC911X) += smc911x.o | 245 | obj-$(CONFIG_SMC911X) += smc911x.o |
246 | obj-$(CONFIG_SMSC911X) += smsc911x.o | 246 | obj-$(CONFIG_SMSC911X) += smsc911x.o |
247 | obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o | ||
247 | obj-$(CONFIG_BFIN_MAC) += bfin_mac.o | 248 | obj-$(CONFIG_BFIN_MAC) += bfin_mac.o |
248 | obj-$(CONFIG_DM9000) += dm9000.o | 249 | obj-$(CONFIG_DM9000) += dm9000.o |
249 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o | 250 | obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o |
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 53af9c93e75c..0c2d96ed561c 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -20,8 +20,8 @@ | |||
20 | * (you will need to reboot afterwards) */ | 20 | * (you will need to reboot afterwards) */ |
21 | /* #define BNX2X_STOP_ON_ERROR */ | 21 | /* #define BNX2X_STOP_ON_ERROR */ |
22 | 22 | ||
23 | #define DRV_MODULE_VERSION "1.52.53-3" | 23 | #define DRV_MODULE_VERSION "1.52.53-4" |
24 | #define DRV_MODULE_RELDATE "2010/18/04" | 24 | #define DRV_MODULE_RELDATE "2010/16/08" |
25 | #define BNX2X_BC_VER 0x040200 | 25 | #define BNX2X_BC_VER 0x040200 |
26 | 26 | ||
27 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | 27 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) |
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index b4ec2b02a465..f8c3f08e4ce7 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c | |||
@@ -4328,10 +4328,12 @@ static int bnx2x_init_port(struct bnx2x *bp) | |||
4328 | val |= aeu_gpio_mask; | 4328 | val |= aeu_gpio_mask; |
4329 | REG_WR(bp, offset, val); | 4329 | REG_WR(bp, offset, val); |
4330 | } | 4330 | } |
4331 | bp->port.need_hw_lock = 1; | ||
4331 | break; | 4332 | break; |
4332 | 4333 | ||
4333 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | ||
4334 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: | 4334 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: |
4335 | bp->port.need_hw_lock = 1; | ||
4336 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: | ||
4335 | /* add SPIO 5 to group 0 */ | 4337 | /* add SPIO 5 to group 0 */ |
4336 | { | 4338 | { |
4337 | u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : | 4339 | u32 reg_addr = (port ? MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0 : |
@@ -4341,7 +4343,10 @@ static int bnx2x_init_port(struct bnx2x *bp) | |||
4341 | REG_WR(bp, reg_addr, val); | 4343 | REG_WR(bp, reg_addr, val); |
4342 | } | 4344 | } |
4343 | break; | 4345 | break; |
4344 | 4346 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: | |
4347 | case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: | ||
4348 | bp->port.need_hw_lock = 1; | ||
4349 | break; | ||
4345 | default: | 4350 | default: |
4346 | break; | 4351 | break; |
4347 | } | 4352 | } |
diff --git a/drivers/net/caif/Kconfig b/drivers/net/caif/Kconfig index 631a6242b011..75bfc3a9d95f 100644 --- a/drivers/net/caif/Kconfig +++ b/drivers/net/caif/Kconfig | |||
@@ -15,7 +15,7 @@ config CAIF_TTY | |||
15 | 15 | ||
16 | config CAIF_SPI_SLAVE | 16 | config CAIF_SPI_SLAVE |
17 | tristate "CAIF SPI transport driver for slave interface" | 17 | tristate "CAIF SPI transport driver for slave interface" |
18 | depends on CAIF | 18 | depends on CAIF && HAS_DMA |
19 | default n | 19 | default n |
20 | ---help--- | 20 | ---help--- |
21 | The CAIF Link layer SPI Protocol driver for Slave SPI interface. | 21 | The CAIF Link layer SPI Protocol driver for Slave SPI interface. |
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index a4a0d2b6eb1c..d3d4a57e2450 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c | |||
@@ -936,12 +936,14 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | |||
936 | ew32(IMC, 0xffffffff); | 936 | ew32(IMC, 0xffffffff); |
937 | icr = er32(ICR); | 937 | icr = er32(ICR); |
938 | 938 | ||
939 | /* Install any alternate MAC address into RAR0 */ | 939 | if (hw->mac.type == e1000_82571) { |
940 | ret_val = e1000_check_alt_mac_addr_generic(hw); | 940 | /* Install any alternate MAC address into RAR0 */ |
941 | if (ret_val) | 941 | ret_val = e1000_check_alt_mac_addr_generic(hw); |
942 | return ret_val; | 942 | if (ret_val) |
943 | return ret_val; | ||
943 | 944 | ||
944 | e1000e_set_laa_state_82571(hw, true); | 945 | e1000e_set_laa_state_82571(hw, true); |
946 | } | ||
945 | 947 | ||
946 | /* Reinitialize the 82571 serdes link state machine */ | 948 | /* Reinitialize the 82571 serdes link state machine */ |
947 | if (hw->phy.media_type == e1000_media_type_internal_serdes) | 949 | if (hw->phy.media_type == e1000_media_type_internal_serdes) |
@@ -1618,14 +1620,16 @@ static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) | |||
1618 | { | 1620 | { |
1619 | s32 ret_val = 0; | 1621 | s32 ret_val = 0; |
1620 | 1622 | ||
1621 | /* | 1623 | if (hw->mac.type == e1000_82571) { |
1622 | * If there's an alternate MAC address place it in RAR0 | 1624 | /* |
1623 | * so that it will override the Si installed default perm | 1625 | * If there's an alternate MAC address place it in RAR0 |
1624 | * address. | 1626 | * so that it will override the Si installed default perm |
1625 | */ | 1627 | * address. |
1626 | ret_val = e1000_check_alt_mac_addr_generic(hw); | 1628 | */ |
1627 | if (ret_val) | 1629 | ret_val = e1000_check_alt_mac_addr_generic(hw); |
1628 | goto out; | 1630 | if (ret_val) |
1631 | goto out; | ||
1632 | } | ||
1629 | 1633 | ||
1630 | ret_val = e1000_read_mac_addr_generic(hw); | 1634 | ret_val = e1000_read_mac_addr_generic(hw); |
1631 | 1635 | ||
@@ -1833,6 +1837,7 @@ struct e1000_info e1000_82573_info = { | |||
1833 | | FLAG_HAS_SMART_POWER_DOWN | 1837 | | FLAG_HAS_SMART_POWER_DOWN |
1834 | | FLAG_HAS_AMT | 1838 | | FLAG_HAS_AMT |
1835 | | FLAG_HAS_SWSM_ON_LOAD, | 1839 | | FLAG_HAS_SWSM_ON_LOAD, |
1840 | .flags2 = FLAG2_DISABLE_ASPM_L1, | ||
1836 | .pba = 20, | 1841 | .pba = 20, |
1837 | .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, | 1842 | .max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN, |
1838 | .get_variants = e1000_get_variants_82571, | 1843 | .get_variants = e1000_get_variants_82571, |
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h index 307a72f483ee..93b3bedae8d2 100644 --- a/drivers/net/e1000e/defines.h +++ b/drivers/net/e1000e/defines.h | |||
@@ -621,6 +621,7 @@ | |||
621 | #define E1000_FLASH_UPDATES 2000 | 621 | #define E1000_FLASH_UPDATES 2000 |
622 | 622 | ||
623 | /* NVM Word Offsets */ | 623 | /* NVM Word Offsets */ |
624 | #define NVM_COMPAT 0x0003 | ||
624 | #define NVM_ID_LED_SETTINGS 0x0004 | 625 | #define NVM_ID_LED_SETTINGS 0x0004 |
625 | #define NVM_INIT_CONTROL2_REG 0x000F | 626 | #define NVM_INIT_CONTROL2_REG 0x000F |
626 | #define NVM_INIT_CONTROL3_PORT_B 0x0014 | 627 | #define NVM_INIT_CONTROL3_PORT_B 0x0014 |
@@ -643,6 +644,9 @@ | |||
643 | /* Mask bits for fields in Word 0x1a of the NVM */ | 644 | /* Mask bits for fields in Word 0x1a of the NVM */ |
644 | #define NVM_WORD1A_ASPM_MASK 0x000C | 645 | #define NVM_WORD1A_ASPM_MASK 0x000C |
645 | 646 | ||
647 | /* Mask bits for fields in Word 0x03 of the EEPROM */ | ||
648 | #define NVM_COMPAT_LOM 0x0800 | ||
649 | |||
646 | /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ | 650 | /* For checksumming, the sum of all words in the NVM should equal 0xBABA. */ |
647 | #define NVM_SUM 0xBABA | 651 | #define NVM_SUM 0xBABA |
648 | 652 | ||
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index df4a27922931..0fd4eb5ac5fb 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
@@ -183,6 +183,16 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) | |||
183 | u16 offset, nvm_alt_mac_addr_offset, nvm_data; | 183 | u16 offset, nvm_alt_mac_addr_offset, nvm_data; |
184 | u8 alt_mac_addr[ETH_ALEN]; | 184 | u8 alt_mac_addr[ETH_ALEN]; |
185 | 185 | ||
186 | ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data); | ||
187 | if (ret_val) | ||
188 | goto out; | ||
189 | |||
190 | /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ | ||
191 | if (!((nvm_data & NVM_COMPAT_LOM) || | ||
192 | (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || | ||
193 | (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD))) | ||
194 | goto out; | ||
195 | |||
186 | ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, | 196 | ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, |
187 | &nvm_alt_mac_addr_offset); | 197 | &nvm_alt_mac_addr_offset); |
188 | if (ret_val) { | 198 | if (ret_val) { |
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 99a929964e3c..1846623c6ae6 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | 41 | ||
42 | #define DRV_NAME "ehea" | 42 | #define DRV_NAME "ehea" |
43 | #define DRV_VERSION "EHEA_0105" | 43 | #define DRV_VERSION "EHEA_0106" |
44 | 44 | ||
45 | /* eHEA capability flags */ | 45 | /* eHEA capability flags */ |
46 | #define DLPAR_PORT_ADD_REM 1 | 46 | #define DLPAR_PORT_ADD_REM 1 |
@@ -400,6 +400,7 @@ struct ehea_port_res { | |||
400 | u32 poll_counter; | 400 | u32 poll_counter; |
401 | struct net_lro_mgr lro_mgr; | 401 | struct net_lro_mgr lro_mgr; |
402 | struct net_lro_desc lro_desc[MAX_LRO_DESCRIPTORS]; | 402 | struct net_lro_desc lro_desc[MAX_LRO_DESCRIPTORS]; |
403 | int sq_restart_flag; | ||
403 | }; | 404 | }; |
404 | 405 | ||
405 | 406 | ||
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 897719b49f96..a333b42111b8 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -776,6 +776,53 @@ static int ehea_proc_rwqes(struct net_device *dev, | |||
776 | return processed; | 776 | return processed; |
777 | } | 777 | } |
778 | 778 | ||
779 | #define SWQE_RESTART_CHECK 0xdeadbeaff00d0000ull | ||
780 | |||
781 | static void reset_sq_restart_flag(struct ehea_port *port) | ||
782 | { | ||
783 | int i; | ||
784 | |||
785 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | ||
786 | struct ehea_port_res *pr = &port->port_res[i]; | ||
787 | pr->sq_restart_flag = 0; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | static void check_sqs(struct ehea_port *port) | ||
792 | { | ||
793 | struct ehea_swqe *swqe; | ||
794 | int swqe_index; | ||
795 | int i, k; | ||
796 | |||
797 | for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) { | ||
798 | struct ehea_port_res *pr = &port->port_res[i]; | ||
799 | k = 0; | ||
800 | swqe = ehea_get_swqe(pr->qp, &swqe_index); | ||
801 | memset(swqe, 0, SWQE_HEADER_SIZE); | ||
802 | atomic_dec(&pr->swqe_avail); | ||
803 | |||
804 | swqe->tx_control |= EHEA_SWQE_PURGE; | ||
805 | swqe->wr_id = SWQE_RESTART_CHECK; | ||
806 | swqe->tx_control |= EHEA_SWQE_SIGNALLED_COMPLETION; | ||
807 | swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT; | ||
808 | swqe->immediate_data_length = 80; | ||
809 | |||
810 | ehea_post_swqe(pr->qp, swqe); | ||
811 | |||
812 | while (pr->sq_restart_flag == 0) { | ||
813 | msleep(5); | ||
814 | if (++k == 100) { | ||
815 | ehea_error("HW/SW queues out of sync"); | ||
816 | ehea_schedule_port_reset(pr->port); | ||
817 | return; | ||
818 | } | ||
819 | } | ||
820 | } | ||
821 | |||
822 | return; | ||
823 | } | ||
824 | |||
825 | |||
779 | static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) | 826 | static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) |
780 | { | 827 | { |
781 | struct sk_buff *skb; | 828 | struct sk_buff *skb; |
@@ -793,6 +840,13 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota) | |||
793 | 840 | ||
794 | cqe_counter++; | 841 | cqe_counter++; |
795 | rmb(); | 842 | rmb(); |
843 | |||
844 | if (cqe->wr_id == SWQE_RESTART_CHECK) { | ||
845 | pr->sq_restart_flag = 1; | ||
846 | swqe_av++; | ||
847 | break; | ||
848 | } | ||
849 | |||
796 | if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { | 850 | if (cqe->status & EHEA_CQE_STAT_ERR_MASK) { |
797 | ehea_error("Bad send completion status=0x%04X", | 851 | ehea_error("Bad send completion status=0x%04X", |
798 | cqe->status); | 852 | cqe->status); |
@@ -2675,8 +2729,10 @@ static void ehea_flush_sq(struct ehea_port *port) | |||
2675 | int k = 0; | 2729 | int k = 0; |
2676 | while (atomic_read(&pr->swqe_avail) < swqe_max) { | 2730 | while (atomic_read(&pr->swqe_avail) < swqe_max) { |
2677 | msleep(5); | 2731 | msleep(5); |
2678 | if (++k == 20) | 2732 | if (++k == 20) { |
2733 | ehea_error("WARNING: sq not flushed completely"); | ||
2679 | break; | 2734 | break; |
2735 | } | ||
2680 | } | 2736 | } |
2681 | } | 2737 | } |
2682 | } | 2738 | } |
@@ -2917,6 +2973,7 @@ static void ehea_rereg_mrs(struct work_struct *work) | |||
2917 | port_napi_disable(port); | 2973 | port_napi_disable(port); |
2918 | mutex_unlock(&port->port_lock); | 2974 | mutex_unlock(&port->port_lock); |
2919 | } | 2975 | } |
2976 | reset_sq_restart_flag(port); | ||
2920 | } | 2977 | } |
2921 | 2978 | ||
2922 | /* Unregister old memory region */ | 2979 | /* Unregister old memory region */ |
@@ -2951,6 +3008,7 @@ static void ehea_rereg_mrs(struct work_struct *work) | |||
2951 | mutex_lock(&port->port_lock); | 3008 | mutex_lock(&port->port_lock); |
2952 | port_napi_enable(port); | 3009 | port_napi_enable(port); |
2953 | ret = ehea_restart_qps(dev); | 3010 | ret = ehea_restart_qps(dev); |
3011 | check_sqs(port); | ||
2954 | if (!ret) | 3012 | if (!ret) |
2955 | netif_wake_queue(dev); | 3013 | netif_wake_queue(dev); |
2956 | mutex_unlock(&port->port_lock); | 3014 | mutex_unlock(&port->port_lock); |
diff --git a/drivers/net/ibm_newemac/debug.c b/drivers/net/ibm_newemac/debug.c index 3995fafc1e08..8c6c1e2a8750 100644 --- a/drivers/net/ibm_newemac/debug.c +++ b/drivers/net/ibm_newemac/debug.c | |||
@@ -238,7 +238,7 @@ void emac_dbg_dump_all(void) | |||
238 | } | 238 | } |
239 | 239 | ||
240 | #if defined(CONFIG_MAGIC_SYSRQ) | 240 | #if defined(CONFIG_MAGIC_SYSRQ) |
241 | static void emac_sysrq_handler(int key, struct tty_struct *tty) | 241 | static void emac_sysrq_handler(int key) |
242 | { | 242 | { |
243 | emac_dbg_dump_all(); | 243 | emac_dbg_dump_all(); |
244 | } | 244 | } |
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c index 2602852cc55a..4734c939ad03 100644 --- a/drivers/net/ibmveth.c +++ b/drivers/net/ibmveth.c | |||
@@ -1113,7 +1113,8 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) | |||
1113 | struct ibmveth_adapter *adapter = netdev_priv(dev); | 1113 | struct ibmveth_adapter *adapter = netdev_priv(dev); |
1114 | struct vio_dev *viodev = adapter->vdev; | 1114 | struct vio_dev *viodev = adapter->vdev; |
1115 | int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; | 1115 | int new_mtu_oh = new_mtu + IBMVETH_BUFF_OH; |
1116 | int i; | 1116 | int i, rc; |
1117 | int need_restart = 0; | ||
1117 | 1118 | ||
1118 | if (new_mtu < IBMVETH_MAX_MTU) | 1119 | if (new_mtu < IBMVETH_MAX_MTU) |
1119 | return -EINVAL; | 1120 | return -EINVAL; |
@@ -1127,35 +1128,32 @@ static int ibmveth_change_mtu(struct net_device *dev, int new_mtu) | |||
1127 | 1128 | ||
1128 | /* Deactivate all the buffer pools so that the next loop can activate | 1129 | /* Deactivate all the buffer pools so that the next loop can activate |
1129 | only the buffer pools necessary to hold the new MTU */ | 1130 | only the buffer pools necessary to hold the new MTU */ |
1130 | for (i = 0; i < IbmVethNumBufferPools; i++) | 1131 | if (netif_running(adapter->netdev)) { |
1131 | if (adapter->rx_buff_pool[i].active) { | 1132 | need_restart = 1; |
1132 | ibmveth_free_buffer_pool(adapter, | 1133 | adapter->pool_config = 1; |
1133 | &adapter->rx_buff_pool[i]); | 1134 | ibmveth_close(adapter->netdev); |
1134 | adapter->rx_buff_pool[i].active = 0; | 1135 | adapter->pool_config = 0; |
1135 | } | 1136 | } |
1136 | 1137 | ||
1137 | /* Look for an active buffer pool that can hold the new MTU */ | 1138 | /* Look for an active buffer pool that can hold the new MTU */ |
1138 | for(i = 0; i<IbmVethNumBufferPools; i++) { | 1139 | for(i = 0; i<IbmVethNumBufferPools; i++) { |
1139 | adapter->rx_buff_pool[i].active = 1; | 1140 | adapter->rx_buff_pool[i].active = 1; |
1140 | 1141 | ||
1141 | if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { | 1142 | if (new_mtu_oh < adapter->rx_buff_pool[i].buff_size) { |
1142 | if (netif_running(adapter->netdev)) { | ||
1143 | adapter->pool_config = 1; | ||
1144 | ibmveth_close(adapter->netdev); | ||
1145 | adapter->pool_config = 0; | ||
1146 | dev->mtu = new_mtu; | ||
1147 | vio_cmo_set_dev_desired(viodev, | ||
1148 | ibmveth_get_desired_dma | ||
1149 | (viodev)); | ||
1150 | return ibmveth_open(adapter->netdev); | ||
1151 | } | ||
1152 | dev->mtu = new_mtu; | 1143 | dev->mtu = new_mtu; |
1153 | vio_cmo_set_dev_desired(viodev, | 1144 | vio_cmo_set_dev_desired(viodev, |
1154 | ibmveth_get_desired_dma | 1145 | ibmveth_get_desired_dma |
1155 | (viodev)); | 1146 | (viodev)); |
1147 | if (need_restart) { | ||
1148 | return ibmveth_open(adapter->netdev); | ||
1149 | } | ||
1156 | return 0; | 1150 | return 0; |
1157 | } | 1151 | } |
1158 | } | 1152 | } |
1153 | |||
1154 | if (need_restart && (rc = ibmveth_open(adapter->netdev))) | ||
1155 | return rc; | ||
1156 | |||
1159 | return -EINVAL; | 1157 | return -EINVAL; |
1160 | } | 1158 | } |
1161 | 1159 | ||
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index c7b624711f5e..bdf2149e5296 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c | |||
@@ -902,8 +902,8 @@ temac_poll_controller(struct net_device *ndev) | |||
902 | disable_irq(lp->tx_irq); | 902 | disable_irq(lp->tx_irq); |
903 | disable_irq(lp->rx_irq); | 903 | disable_irq(lp->rx_irq); |
904 | 904 | ||
905 | ll_temac_rx_irq(lp->tx_irq, lp); | 905 | ll_temac_rx_irq(lp->tx_irq, ndev); |
906 | ll_temac_tx_irq(lp->rx_irq, lp); | 906 | ll_temac_tx_irq(lp->rx_irq, ndev); |
907 | 907 | ||
908 | enable_irq(lp->tx_irq); | 908 | enable_irq(lp->tx_irq); |
909 | enable_irq(lp->rx_irq); | 909 | enable_irq(lp->rx_irq); |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index ffa1b9ce1cc5..6dca3574e355 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -53,8 +53,8 @@ | |||
53 | 53 | ||
54 | #define _NETXEN_NIC_LINUX_MAJOR 4 | 54 | #define _NETXEN_NIC_LINUX_MAJOR 4 |
55 | #define _NETXEN_NIC_LINUX_MINOR 0 | 55 | #define _NETXEN_NIC_LINUX_MINOR 0 |
56 | #define _NETXEN_NIC_LINUX_SUBVERSION 73 | 56 | #define _NETXEN_NIC_LINUX_SUBVERSION 74 |
57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.73" | 57 | #define NETXEN_NIC_LINUX_VERSIONID "4.0.74" |
58 | 58 | ||
59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) | 59 | #define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c)) |
60 | #define _major(v) (((v) >> 24) & 0xff) | 60 | #define _major(v) (((v) >> 24) & 0xff) |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index c865dda2adf1..cabae7bb1fc6 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -1805,8 +1805,6 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, | |||
1805 | netxen_ctx_msg msg = 0; | 1805 | netxen_ctx_msg msg = 0; |
1806 | struct list_head *head; | 1806 | struct list_head *head; |
1807 | 1807 | ||
1808 | spin_lock(&rds_ring->lock); | ||
1809 | |||
1810 | producer = rds_ring->producer; | 1808 | producer = rds_ring->producer; |
1811 | 1809 | ||
1812 | head = &rds_ring->free_list; | 1810 | head = &rds_ring->free_list; |
@@ -1853,8 +1851,6 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, | |||
1853 | NETXEN_RCV_PRODUCER_OFFSET), msg); | 1851 | NETXEN_RCV_PRODUCER_OFFSET), msg); |
1854 | } | 1852 | } |
1855 | } | 1853 | } |
1856 | |||
1857 | spin_unlock(&rds_ring->lock); | ||
1858 | } | 1854 | } |
1859 | 1855 | ||
1860 | static void | 1856 | static void |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index fd86e18604e6..73d314592230 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -2032,8 +2032,6 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) | |||
2032 | struct netxen_adapter *adapter = netdev_priv(netdev); | 2032 | struct netxen_adapter *adapter = netdev_priv(netdev); |
2033 | struct net_device_stats *stats = &netdev->stats; | 2033 | struct net_device_stats *stats = &netdev->stats; |
2034 | 2034 | ||
2035 | memset(stats, 0, sizeof(*stats)); | ||
2036 | |||
2037 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; | 2035 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; |
2038 | stats->tx_packets = adapter->stats.xmitfinished; | 2036 | stats->tx_packets = adapter->stats.xmitfinished; |
2039 | stats->rx_bytes = adapter->stats.rxbytes; | 2037 | stats->rx_bytes = adapter->stats.rxbytes; |
@@ -2133,9 +2131,16 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
2133 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2131 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2134 | static void netxen_nic_poll_controller(struct net_device *netdev) | 2132 | static void netxen_nic_poll_controller(struct net_device *netdev) |
2135 | { | 2133 | { |
2134 | int ring; | ||
2135 | struct nx_host_sds_ring *sds_ring; | ||
2136 | struct netxen_adapter *adapter = netdev_priv(netdev); | 2136 | struct netxen_adapter *adapter = netdev_priv(netdev); |
2137 | struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; | ||
2138 | |||
2137 | disable_irq(adapter->irq); | 2139 | disable_irq(adapter->irq); |
2138 | netxen_intr(adapter->irq, adapter); | 2140 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
2141 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
2142 | netxen_intr(adapter->irq, sds_ring); | ||
2143 | } | ||
2139 | enable_irq(adapter->irq); | 2144 | enable_irq(adapter->irq); |
2140 | } | 2145 | } |
2141 | #endif | 2146 | #endif |
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index c0761197c07e..16ddc77313cb 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c | |||
@@ -466,6 +466,8 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev, | |||
466 | 466 | ||
467 | phydev->interface = interface; | 467 | phydev->interface = interface; |
468 | 468 | ||
469 | phydev->state = PHY_READY; | ||
470 | |||
469 | /* Do initial configuration here, now that | 471 | /* Do initial configuration here, now that |
470 | * we have certain key parameters | 472 | * we have certain key parameters |
471 | * (dev_flags and interface) */ | 473 | * (dev_flags and interface) */ |
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c new file mode 100644 index 000000000000..410ea0a61371 --- /dev/null +++ b/drivers/net/pxa168_eth.c | |||
@@ -0,0 +1,1664 @@ | |||
1 | /* | ||
2 | * PXA168 ethernet driver. | ||
3 | * Most of the code is derived from mv643xx ethernet driver. | ||
4 | * | ||
5 | * Copyright (C) 2010 Marvell International Ltd. | ||
6 | * Sachin Sanap <ssanap@marvell.com> | ||
7 | * Philip Rakity <prakity@marvell.com> | ||
8 | * Mark Brown <markb@marvell.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/init.h> | ||
26 | #include <linux/dma-mapping.h> | ||
27 | #include <linux/in.h> | ||
28 | #include <linux/ip.h> | ||
29 | #include <linux/tcp.h> | ||
30 | #include <linux/udp.h> | ||
31 | #include <linux/etherdevice.h> | ||
32 | #include <linux/bitops.h> | ||
33 | #include <linux/delay.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/kernel.h> | ||
38 | #include <linux/workqueue.h> | ||
39 | #include <linux/clk.h> | ||
40 | #include <linux/phy.h> | ||
41 | #include <linux/io.h> | ||
42 | #include <linux/types.h> | ||
43 | #include <asm/pgtable.h> | ||
44 | #include <asm/system.h> | ||
45 | #include <linux/delay.h> | ||
46 | #include <linux/dma-mapping.h> | ||
47 | #include <asm/cacheflush.h> | ||
48 | #include <linux/pxa168_eth.h> | ||
49 | |||
50 | #define DRIVER_NAME "pxa168-eth" | ||
51 | #define DRIVER_VERSION "0.3" | ||
52 | |||
53 | /* | ||
54 | * Registers | ||
55 | */ | ||
56 | |||
57 | #define PHY_ADDRESS 0x0000 | ||
58 | #define SMI 0x0010 | ||
59 | #define PORT_CONFIG 0x0400 | ||
60 | #define PORT_CONFIG_EXT 0x0408 | ||
61 | #define PORT_COMMAND 0x0410 | ||
62 | #define PORT_STATUS 0x0418 | ||
63 | #define HTPR 0x0428 | ||
64 | #define SDMA_CONFIG 0x0440 | ||
65 | #define SDMA_CMD 0x0448 | ||
66 | #define INT_CAUSE 0x0450 | ||
67 | #define INT_W_CLEAR 0x0454 | ||
68 | #define INT_MASK 0x0458 | ||
69 | #define ETH_F_RX_DESC_0 0x0480 | ||
70 | #define ETH_C_RX_DESC_0 0x04A0 | ||
71 | #define ETH_C_TX_DESC_1 0x04E4 | ||
72 | |||
73 | /* smi register */ | ||
74 | #define SMI_BUSY (1 << 28) /* 0 - Write, 1 - Read */ | ||
75 | #define SMI_R_VALID (1 << 27) /* 0 - Write, 1 - Read */ | ||
76 | #define SMI_OP_W (0 << 26) /* Write operation */ | ||
77 | #define SMI_OP_R (1 << 26) /* Read operation */ | ||
78 | |||
79 | #define PHY_WAIT_ITERATIONS 10 | ||
80 | |||
81 | #define PXA168_ETH_PHY_ADDR_DEFAULT 0 | ||
82 | /* RX & TX descriptor command */ | ||
83 | #define BUF_OWNED_BY_DMA (1 << 31) | ||
84 | |||
85 | /* RX descriptor status */ | ||
86 | #define RX_EN_INT (1 << 23) | ||
87 | #define RX_FIRST_DESC (1 << 17) | ||
88 | #define RX_LAST_DESC (1 << 16) | ||
89 | #define RX_ERROR (1 << 15) | ||
90 | |||
91 | /* TX descriptor command */ | ||
92 | #define TX_EN_INT (1 << 23) | ||
93 | #define TX_GEN_CRC (1 << 22) | ||
94 | #define TX_ZERO_PADDING (1 << 18) | ||
95 | #define TX_FIRST_DESC (1 << 17) | ||
96 | #define TX_LAST_DESC (1 << 16) | ||
97 | #define TX_ERROR (1 << 15) | ||
98 | |||
99 | /* SDMA_CMD */ | ||
100 | #define SDMA_CMD_AT (1 << 31) | ||
101 | #define SDMA_CMD_TXDL (1 << 24) | ||
102 | #define SDMA_CMD_TXDH (1 << 23) | ||
103 | #define SDMA_CMD_AR (1 << 15) | ||
104 | #define SDMA_CMD_ERD (1 << 7) | ||
105 | |||
106 | /* Bit definitions of the Port Config Reg */ | ||
107 | #define PCR_HS (1 << 12) | ||
108 | #define PCR_EN (1 << 7) | ||
109 | #define PCR_PM (1 << 0) | ||
110 | |||
111 | /* Bit definitions of the Port Config Extend Reg */ | ||
112 | #define PCXR_2BSM (1 << 28) | ||
113 | #define PCXR_DSCP_EN (1 << 21) | ||
114 | #define PCXR_MFL_1518 (0 << 14) | ||
115 | #define PCXR_MFL_1536 (1 << 14) | ||
116 | #define PCXR_MFL_2048 (2 << 14) | ||
117 | #define PCXR_MFL_64K (3 << 14) | ||
118 | #define PCXR_FLP (1 << 11) | ||
119 | #define PCXR_PRIO_TX_OFF 3 | ||
120 | #define PCXR_TX_HIGH_PRI (7 << PCXR_PRIO_TX_OFF) | ||
121 | |||
122 | /* Bit definitions of the SDMA Config Reg */ | ||
123 | #define SDCR_BSZ_OFF 12 | ||
124 | #define SDCR_BSZ8 (3 << SDCR_BSZ_OFF) | ||
125 | #define SDCR_BSZ4 (2 << SDCR_BSZ_OFF) | ||
126 | #define SDCR_BSZ2 (1 << SDCR_BSZ_OFF) | ||
127 | #define SDCR_BSZ1 (0 << SDCR_BSZ_OFF) | ||
128 | #define SDCR_BLMR (1 << 6) | ||
129 | #define SDCR_BLMT (1 << 7) | ||
130 | #define SDCR_RIFB (1 << 9) | ||
131 | #define SDCR_RC_OFF 2 | ||
132 | #define SDCR_RC_MAX_RETRANS (0xf << SDCR_RC_OFF) | ||
133 | |||
134 | /* | ||
135 | * Bit definitions of the Interrupt Cause Reg | ||
136 | * and Interrupt MASK Reg is the same | ||
137 | */ | ||
138 | #define ICR_RXBUF (1 << 0) | ||
139 | #define ICR_TXBUF_H (1 << 2) | ||
140 | #define ICR_TXBUF_L (1 << 3) | ||
141 | #define ICR_TXEND_H (1 << 6) | ||
142 | #define ICR_TXEND_L (1 << 7) | ||
143 | #define ICR_RXERR (1 << 8) | ||
144 | #define ICR_TXERR_H (1 << 10) | ||
145 | #define ICR_TXERR_L (1 << 11) | ||
146 | #define ICR_TX_UDR (1 << 13) | ||
147 | #define ICR_MII_CH (1 << 28) | ||
148 | |||
149 | #define ALL_INTS (ICR_TXBUF_H | ICR_TXBUF_L | ICR_TX_UDR |\ | ||
150 | ICR_TXERR_H | ICR_TXERR_L |\ | ||
151 | ICR_TXEND_H | ICR_TXEND_L |\ | ||
152 | ICR_RXBUF | ICR_RXERR | ICR_MII_CH) | ||
153 | |||
154 | #define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */ | ||
155 | |||
156 | #define NUM_RX_DESCS 64 | ||
157 | #define NUM_TX_DESCS 64 | ||
158 | |||
159 | #define HASH_ADD 0 | ||
160 | #define HASH_DELETE 1 | ||
161 | #define HASH_ADDR_TABLE_SIZE 0x4000 /* 16K (1/2K address - PCR_HS == 1) */ | ||
162 | #define HOP_NUMBER 12 | ||
163 | |||
164 | /* Bit definitions for Port status */ | ||
165 | #define PORT_SPEED_100 (1 << 0) | ||
166 | #define FULL_DUPLEX (1 << 1) | ||
167 | #define FLOW_CONTROL_ENABLED (1 << 2) | ||
168 | #define LINK_UP (1 << 3) | ||
169 | |||
170 | /* Bit definitions for work to be done */ | ||
171 | #define WORK_LINK (1 << 0) | ||
172 | #define WORK_TX_DONE (1 << 1) | ||
173 | |||
174 | /* | ||
175 | * Misc definitions. | ||
176 | */ | ||
177 | #define SKB_DMA_REALIGN ((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES) | ||
178 | |||
179 | struct rx_desc { | ||
180 | u32 cmd_sts; /* Descriptor command status */ | ||
181 | u16 byte_cnt; /* Descriptor buffer byte count */ | ||
182 | u16 buf_size; /* Buffer size */ | ||
183 | u32 buf_ptr; /* Descriptor buffer pointer */ | ||
184 | u32 next_desc_ptr; /* Next descriptor pointer */ | ||
185 | }; | ||
186 | |||
187 | struct tx_desc { | ||
188 | u32 cmd_sts; /* Command/status field */ | ||
189 | u16 reserved; | ||
190 | u16 byte_cnt; /* buffer byte count */ | ||
191 | u32 buf_ptr; /* pointer to buffer for this descriptor */ | ||
192 | u32 next_desc_ptr; /* Pointer to next descriptor */ | ||
193 | }; | ||
194 | |||
195 | struct pxa168_eth_private { | ||
196 | int port_num; /* User Ethernet port number */ | ||
197 | |||
198 | int rx_resource_err; /* Rx ring resource error flag */ | ||
199 | |||
200 | /* Next available and first returning Rx resource */ | ||
201 | int rx_curr_desc_q, rx_used_desc_q; | ||
202 | |||
203 | /* Next available and first returning Tx resource */ | ||
204 | int tx_curr_desc_q, tx_used_desc_q; | ||
205 | |||
206 | struct rx_desc *p_rx_desc_area; | ||
207 | dma_addr_t rx_desc_dma; | ||
208 | int rx_desc_area_size; | ||
209 | struct sk_buff **rx_skb; | ||
210 | |||
211 | struct tx_desc *p_tx_desc_area; | ||
212 | dma_addr_t tx_desc_dma; | ||
213 | int tx_desc_area_size; | ||
214 | struct sk_buff **tx_skb; | ||
215 | |||
216 | struct work_struct tx_timeout_task; | ||
217 | |||
218 | struct net_device *dev; | ||
219 | struct napi_struct napi; | ||
220 | u8 work_todo; | ||
221 | int skb_size; | ||
222 | |||
223 | struct net_device_stats stats; | ||
224 | /* Size of Tx Ring per queue */ | ||
225 | int tx_ring_size; | ||
226 | /* Number of tx descriptors in use */ | ||
227 | int tx_desc_count; | ||
228 | /* Size of Rx Ring per queue */ | ||
229 | int rx_ring_size; | ||
230 | /* Number of rx descriptors in use */ | ||
231 | int rx_desc_count; | ||
232 | |||
233 | /* | ||
234 | * Used in case RX Ring is empty, which can occur when | ||
235 | * system does not have resources (skb's) | ||
236 | */ | ||
237 | struct timer_list timeout; | ||
238 | struct mii_bus *smi_bus; | ||
239 | struct phy_device *phy; | ||
240 | |||
241 | /* clock */ | ||
242 | struct clk *clk; | ||
243 | struct pxa168_eth_platform_data *pd; | ||
244 | /* | ||
245 | * Ethernet controller base address. | ||
246 | */ | ||
247 | void __iomem *base; | ||
248 | |||
249 | /* Pointer to the hardware address filter table */ | ||
250 | void *htpr; | ||
251 | dma_addr_t htpr_dma; | ||
252 | }; | ||
253 | |||
254 | struct addr_table_entry { | ||
255 | __le32 lo; | ||
256 | __le32 hi; | ||
257 | }; | ||
258 | |||
259 | /* Bit fields of a Hash Table Entry */ | ||
260 | enum hash_table_entry { | ||
261 | HASH_ENTRY_VALID = 1, | ||
262 | SKIP = 2, | ||
263 | HASH_ENTRY_RECEIVE_DISCARD = 4, | ||
264 | HASH_ENTRY_RECEIVE_DISCARD_BIT = 2 | ||
265 | }; | ||
266 | |||
267 | static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); | ||
268 | static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd); | ||
269 | static int pxa168_init_hw(struct pxa168_eth_private *pep); | ||
270 | static void eth_port_reset(struct net_device *dev); | ||
271 | static void eth_port_start(struct net_device *dev); | ||
272 | static int pxa168_eth_open(struct net_device *dev); | ||
273 | static int pxa168_eth_stop(struct net_device *dev); | ||
274 | static int ethernet_phy_setup(struct net_device *dev); | ||
275 | |||
276 | static inline u32 rdl(struct pxa168_eth_private *pep, int offset) | ||
277 | { | ||
278 | return readl(pep->base + offset); | ||
279 | } | ||
280 | |||
281 | static inline void wrl(struct pxa168_eth_private *pep, int offset, u32 data) | ||
282 | { | ||
283 | writel(data, pep->base + offset); | ||
284 | } | ||
285 | |||
286 | static void abort_dma(struct pxa168_eth_private *pep) | ||
287 | { | ||
288 | int delay; | ||
289 | int max_retries = 40; | ||
290 | |||
291 | do { | ||
292 | wrl(pep, SDMA_CMD, SDMA_CMD_AR | SDMA_CMD_AT); | ||
293 | udelay(100); | ||
294 | |||
295 | delay = 10; | ||
296 | while ((rdl(pep, SDMA_CMD) & (SDMA_CMD_AR | SDMA_CMD_AT)) | ||
297 | && delay-- > 0) { | ||
298 | udelay(10); | ||
299 | } | ||
300 | } while (max_retries-- > 0 && delay <= 0); | ||
301 | |||
302 | if (max_retries <= 0) | ||
303 | printk(KERN_ERR "%s : DMA Stuck\n", __func__); | ||
304 | } | ||
305 | |||
306 | static int ethernet_phy_get(struct pxa168_eth_private *pep) | ||
307 | { | ||
308 | unsigned int reg_data; | ||
309 | |||
310 | reg_data = rdl(pep, PHY_ADDRESS); | ||
311 | |||
312 | return (reg_data >> (5 * pep->port_num)) & 0x1f; | ||
313 | } | ||
314 | |||
315 | static void ethernet_phy_set_addr(struct pxa168_eth_private *pep, int phy_addr) | ||
316 | { | ||
317 | u32 reg_data; | ||
318 | int addr_shift = 5 * pep->port_num; | ||
319 | |||
320 | reg_data = rdl(pep, PHY_ADDRESS); | ||
321 | reg_data &= ~(0x1f << addr_shift); | ||
322 | reg_data |= (phy_addr & 0x1f) << addr_shift; | ||
323 | wrl(pep, PHY_ADDRESS, reg_data); | ||
324 | } | ||
325 | |||
326 | static void ethernet_phy_reset(struct pxa168_eth_private *pep) | ||
327 | { | ||
328 | int data; | ||
329 | |||
330 | data = phy_read(pep->phy, MII_BMCR); | ||
331 | if (data < 0) | ||
332 | return; | ||
333 | |||
334 | data |= BMCR_RESET; | ||
335 | if (phy_write(pep->phy, MII_BMCR, data) < 0) | ||
336 | return; | ||
337 | |||
338 | do { | ||
339 | data = phy_read(pep->phy, MII_BMCR); | ||
340 | } while (data >= 0 && data & BMCR_RESET); | ||
341 | } | ||
342 | |||
343 | static void rxq_refill(struct net_device *dev) | ||
344 | { | ||
345 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
346 | struct sk_buff *skb; | ||
347 | struct rx_desc *p_used_rx_desc; | ||
348 | int used_rx_desc; | ||
349 | |||
350 | while (pep->rx_desc_count < pep->rx_ring_size) { | ||
351 | int size; | ||
352 | |||
353 | skb = dev_alloc_skb(pep->skb_size); | ||
354 | if (!skb) | ||
355 | break; | ||
356 | if (SKB_DMA_REALIGN) | ||
357 | skb_reserve(skb, SKB_DMA_REALIGN); | ||
358 | pep->rx_desc_count++; | ||
359 | /* Get 'used' Rx descriptor */ | ||
360 | used_rx_desc = pep->rx_used_desc_q; | ||
361 | p_used_rx_desc = &pep->p_rx_desc_area[used_rx_desc]; | ||
362 | size = skb->end - skb->data; | ||
363 | p_used_rx_desc->buf_ptr = dma_map_single(NULL, | ||
364 | skb->data, | ||
365 | size, | ||
366 | DMA_FROM_DEVICE); | ||
367 | p_used_rx_desc->buf_size = size; | ||
368 | pep->rx_skb[used_rx_desc] = skb; | ||
369 | |||
370 | /* Return the descriptor to DMA ownership */ | ||
371 | wmb(); | ||
372 | p_used_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT; | ||
373 | wmb(); | ||
374 | |||
375 | /* Move the used descriptor pointer to the next descriptor */ | ||
376 | pep->rx_used_desc_q = (used_rx_desc + 1) % pep->rx_ring_size; | ||
377 | |||
378 | /* Any Rx return cancels the Rx resource error status */ | ||
379 | pep->rx_resource_err = 0; | ||
380 | |||
381 | skb_reserve(skb, ETH_HW_IP_ALIGN); | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * If RX ring is empty of SKB, set a timer to try allocating | ||
386 | * again at a later time. | ||
387 | */ | ||
388 | if (pep->rx_desc_count == 0) { | ||
389 | pep->timeout.expires = jiffies + (HZ / 10); | ||
390 | add_timer(&pep->timeout); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | static inline void rxq_refill_timer_wrapper(unsigned long data) | ||
395 | { | ||
396 | struct pxa168_eth_private *pep = (void *)data; | ||
397 | napi_schedule(&pep->napi); | ||
398 | } | ||
399 | |||
400 | static inline u8 flip_8_bits(u8 x) | ||
401 | { | ||
402 | return (((x) & 0x01) << 3) | (((x) & 0x02) << 1) | ||
403 | | (((x) & 0x04) >> 1) | (((x) & 0x08) >> 3) | ||
404 | | (((x) & 0x10) << 3) | (((x) & 0x20) << 1) | ||
405 | | (((x) & 0x40) >> 1) | (((x) & 0x80) >> 3); | ||
406 | } | ||
407 | |||
408 | static void nibble_swap_every_byte(unsigned char *mac_addr) | ||
409 | { | ||
410 | int i; | ||
411 | for (i = 0; i < ETH_ALEN; i++) { | ||
412 | mac_addr[i] = ((mac_addr[i] & 0x0f) << 4) | | ||
413 | ((mac_addr[i] & 0xf0) >> 4); | ||
414 | } | ||
415 | } | ||
416 | |||
417 | static void inverse_every_nibble(unsigned char *mac_addr) | ||
418 | { | ||
419 | int i; | ||
420 | for (i = 0; i < ETH_ALEN; i++) | ||
421 | mac_addr[i] = flip_8_bits(mac_addr[i]); | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | * ---------------------------------------------------------------------------- | ||
426 | * This function will calculate the hash function of the address. | ||
427 | * Inputs | ||
428 | * mac_addr_orig - MAC address. | ||
429 | * Outputs | ||
430 | * return the calculated entry. | ||
431 | */ | ||
432 | static u32 hash_function(unsigned char *mac_addr_orig) | ||
433 | { | ||
434 | u32 hash_result; | ||
435 | u32 addr0; | ||
436 | u32 addr1; | ||
437 | u32 addr2; | ||
438 | u32 addr3; | ||
439 | unsigned char mac_addr[ETH_ALEN]; | ||
440 | |||
441 | /* Make a copy of MAC address since we are going to performe bit | ||
442 | * operations on it | ||
443 | */ | ||
444 | memcpy(mac_addr, mac_addr_orig, ETH_ALEN); | ||
445 | |||
446 | nibble_swap_every_byte(mac_addr); | ||
447 | inverse_every_nibble(mac_addr); | ||
448 | |||
449 | addr0 = (mac_addr[5] >> 2) & 0x3f; | ||
450 | addr1 = (mac_addr[5] & 0x03) | (((mac_addr[4] & 0x7f)) << 2); | ||
451 | addr2 = ((mac_addr[4] & 0x80) >> 7) | mac_addr[3] << 1; | ||
452 | addr3 = (mac_addr[2] & 0xff) | ((mac_addr[1] & 1) << 8); | ||
453 | |||
454 | hash_result = (addr0 << 9) | (addr1 ^ addr2 ^ addr3); | ||
455 | hash_result = hash_result & 0x07ff; | ||
456 | return hash_result; | ||
457 | } | ||
458 | |||
459 | /* | ||
460 | * ---------------------------------------------------------------------------- | ||
461 | * This function will add/del an entry to the address table. | ||
462 | * Inputs | ||
463 | * pep - ETHERNET . | ||
464 | * mac_addr - MAC address. | ||
465 | * skip - if 1, skip this address.Used in case of deleting an entry which is a | ||
466 | * part of chain in the hash table.We cant just delete the entry since | ||
467 | * that will break the chain.We need to defragment the tables time to | ||
468 | * time. | ||
469 | * rd - 0 Discard packet upon match. | ||
470 | * - 1 Receive packet upon match. | ||
471 | * Outputs | ||
472 | * address table entry is added/deleted. | ||
473 | * 0 if success. | ||
474 | * -ENOSPC if table full | ||
475 | */ | ||
476 | static int add_del_hash_entry(struct pxa168_eth_private *pep, | ||
477 | unsigned char *mac_addr, | ||
478 | u32 rd, u32 skip, int del) | ||
479 | { | ||
480 | struct addr_table_entry *entry, *start; | ||
481 | u32 new_high; | ||
482 | u32 new_low; | ||
483 | u32 i; | ||
484 | |||
485 | new_low = (((mac_addr[1] >> 4) & 0xf) << 15) | ||
486 | | (((mac_addr[1] >> 0) & 0xf) << 11) | ||
487 | | (((mac_addr[0] >> 4) & 0xf) << 7) | ||
488 | | (((mac_addr[0] >> 0) & 0xf) << 3) | ||
489 | | (((mac_addr[3] >> 4) & 0x1) << 31) | ||
490 | | (((mac_addr[3] >> 0) & 0xf) << 27) | ||
491 | | (((mac_addr[2] >> 4) & 0xf) << 23) | ||
492 | | (((mac_addr[2] >> 0) & 0xf) << 19) | ||
493 | | (skip << SKIP) | (rd << HASH_ENTRY_RECEIVE_DISCARD_BIT) | ||
494 | | HASH_ENTRY_VALID; | ||
495 | |||
496 | new_high = (((mac_addr[5] >> 4) & 0xf) << 15) | ||
497 | | (((mac_addr[5] >> 0) & 0xf) << 11) | ||
498 | | (((mac_addr[4] >> 4) & 0xf) << 7) | ||
499 | | (((mac_addr[4] >> 0) & 0xf) << 3) | ||
500 | | (((mac_addr[3] >> 5) & 0x7) << 0); | ||
501 | |||
502 | /* | ||
503 | * Pick the appropriate table, start scanning for free/reusable | ||
504 | * entries at the index obtained by hashing the specified MAC address | ||
505 | */ | ||
506 | start = (struct addr_table_entry *)(pep->htpr); | ||
507 | entry = start + hash_function(mac_addr); | ||
508 | for (i = 0; i < HOP_NUMBER; i++) { | ||
509 | if (!(le32_to_cpu(entry->lo) & HASH_ENTRY_VALID)) { | ||
510 | break; | ||
511 | } else { | ||
512 | /* if same address put in same position */ | ||
513 | if (((le32_to_cpu(entry->lo) & 0xfffffff8) == | ||
514 | (new_low & 0xfffffff8)) && | ||
515 | (le32_to_cpu(entry->hi) == new_high)) { | ||
516 | break; | ||
517 | } | ||
518 | } | ||
519 | if (entry == start + 0x7ff) | ||
520 | entry = start; | ||
521 | else | ||
522 | entry++; | ||
523 | } | ||
524 | |||
525 | if (((le32_to_cpu(entry->lo) & 0xfffffff8) != (new_low & 0xfffffff8)) && | ||
526 | (le32_to_cpu(entry->hi) != new_high) && del) | ||
527 | return 0; | ||
528 | |||
529 | if (i == HOP_NUMBER) { | ||
530 | if (!del) { | ||
531 | printk(KERN_INFO "%s: table section is full, need to " | ||
532 | "move to 16kB implementation?\n", | ||
533 | __FILE__); | ||
534 | return -ENOSPC; | ||
535 | } else | ||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Update the selected entry | ||
541 | */ | ||
542 | if (del) { | ||
543 | entry->hi = 0; | ||
544 | entry->lo = 0; | ||
545 | } else { | ||
546 | entry->hi = cpu_to_le32(new_high); | ||
547 | entry->lo = cpu_to_le32(new_low); | ||
548 | } | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | /* | ||
554 | * ---------------------------------------------------------------------------- | ||
555 | * Create an addressTable entry from MAC address info | ||
556 | * found in the specifed net_device struct | ||
557 | * | ||
558 | * Input : pointer to ethernet interface network device structure | ||
559 | * Output : N/A | ||
560 | */ | ||
561 | static void update_hash_table_mac_address(struct pxa168_eth_private *pep, | ||
562 | unsigned char *oaddr, | ||
563 | unsigned char *addr) | ||
564 | { | ||
565 | /* Delete old entry */ | ||
566 | if (oaddr) | ||
567 | add_del_hash_entry(pep, oaddr, 1, 0, HASH_DELETE); | ||
568 | /* Add new entry */ | ||
569 | add_del_hash_entry(pep, addr, 1, 0, HASH_ADD); | ||
570 | } | ||
571 | |||
572 | static int init_hash_table(struct pxa168_eth_private *pep) | ||
573 | { | ||
574 | /* | ||
575 | * Hardware expects CPU to build a hash table based on a predefined | ||
576 | * hash function and populate it based on hardware address. The | ||
577 | * location of the hash table is identified by 32-bit pointer stored | ||
578 | * in HTPR internal register. Two possible sizes exists for the hash | ||
579 | * table 8kB (256kB of DRAM required (4 x 64 kB banks)) and 1/2kB | ||
580 | * (16kB of DRAM required (4 x 4 kB banks)).We currently only support | ||
581 | * 1/2kB. | ||
582 | */ | ||
583 | /* TODO: Add support for 8kB hash table and alternative hash | ||
584 | * function.Driver can dynamically switch to them if the 1/2kB hash | ||
585 | * table is full. | ||
586 | */ | ||
587 | if (pep->htpr == NULL) { | ||
588 | pep->htpr = dma_alloc_coherent(pep->dev->dev.parent, | ||
589 | HASH_ADDR_TABLE_SIZE, | ||
590 | &pep->htpr_dma, GFP_KERNEL); | ||
591 | if (pep->htpr == NULL) | ||
592 | return -ENOMEM; | ||
593 | } | ||
594 | memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE); | ||
595 | wrl(pep, HTPR, pep->htpr_dma); | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static void pxa168_eth_set_rx_mode(struct net_device *dev) | ||
600 | { | ||
601 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
602 | struct netdev_hw_addr *ha; | ||
603 | u32 val; | ||
604 | |||
605 | val = rdl(pep, PORT_CONFIG); | ||
606 | if (dev->flags & IFF_PROMISC) | ||
607 | val |= PCR_PM; | ||
608 | else | ||
609 | val &= ~PCR_PM; | ||
610 | wrl(pep, PORT_CONFIG, val); | ||
611 | |||
612 | /* | ||
613 | * Remove the old list of MAC address and add dev->addr | ||
614 | * and multicast address. | ||
615 | */ | ||
616 | memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE); | ||
617 | update_hash_table_mac_address(pep, NULL, dev->dev_addr); | ||
618 | |||
619 | netdev_for_each_mc_addr(ha, dev) | ||
620 | update_hash_table_mac_address(pep, NULL, ha->addr); | ||
621 | } | ||
622 | |||
623 | static int pxa168_eth_set_mac_address(struct net_device *dev, void *addr) | ||
624 | { | ||
625 | struct sockaddr *sa = addr; | ||
626 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
627 | unsigned char oldMac[ETH_ALEN]; | ||
628 | |||
629 | if (!is_valid_ether_addr(sa->sa_data)) | ||
630 | return -EINVAL; | ||
631 | memcpy(oldMac, dev->dev_addr, ETH_ALEN); | ||
632 | memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN); | ||
633 | netif_addr_lock_bh(dev); | ||
634 | update_hash_table_mac_address(pep, oldMac, dev->dev_addr); | ||
635 | netif_addr_unlock_bh(dev); | ||
636 | return 0; | ||
637 | } | ||
638 | |||
639 | static void eth_port_start(struct net_device *dev) | ||
640 | { | ||
641 | unsigned int val = 0; | ||
642 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
643 | int tx_curr_desc, rx_curr_desc; | ||
644 | |||
645 | /* Perform PHY reset, if there is a PHY. */ | ||
646 | if (pep->phy != NULL) { | ||
647 | struct ethtool_cmd cmd; | ||
648 | |||
649 | pxa168_get_settings(pep->dev, &cmd); | ||
650 | ethernet_phy_reset(pep); | ||
651 | pxa168_set_settings(pep->dev, &cmd); | ||
652 | } | ||
653 | |||
654 | /* Assignment of Tx CTRP of given queue */ | ||
655 | tx_curr_desc = pep->tx_curr_desc_q; | ||
656 | wrl(pep, ETH_C_TX_DESC_1, | ||
657 | (u32) (pep->tx_desc_dma + tx_curr_desc * sizeof(struct tx_desc))); | ||
658 | |||
659 | /* Assignment of Rx CRDP of given queue */ | ||
660 | rx_curr_desc = pep->rx_curr_desc_q; | ||
661 | wrl(pep, ETH_C_RX_DESC_0, | ||
662 | (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc))); | ||
663 | |||
664 | wrl(pep, ETH_F_RX_DESC_0, | ||
665 | (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc))); | ||
666 | |||
667 | /* Clear all interrupts */ | ||
668 | wrl(pep, INT_CAUSE, 0); | ||
669 | |||
670 | /* Enable all interrupts for receive, transmit and error. */ | ||
671 | wrl(pep, INT_MASK, ALL_INTS); | ||
672 | |||
673 | val = rdl(pep, PORT_CONFIG); | ||
674 | val |= PCR_EN; | ||
675 | wrl(pep, PORT_CONFIG, val); | ||
676 | |||
677 | /* Start RX DMA engine */ | ||
678 | val = rdl(pep, SDMA_CMD); | ||
679 | val |= SDMA_CMD_ERD; | ||
680 | wrl(pep, SDMA_CMD, val); | ||
681 | } | ||
682 | |||
683 | static void eth_port_reset(struct net_device *dev) | ||
684 | { | ||
685 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
686 | unsigned int val = 0; | ||
687 | |||
688 | /* Stop all interrupts for receive, transmit and error. */ | ||
689 | wrl(pep, INT_MASK, 0); | ||
690 | |||
691 | /* Clear all interrupts */ | ||
692 | wrl(pep, INT_CAUSE, 0); | ||
693 | |||
694 | /* Stop RX DMA */ | ||
695 | val = rdl(pep, SDMA_CMD); | ||
696 | val &= ~SDMA_CMD_ERD; /* abort dma command */ | ||
697 | |||
698 | /* Abort any transmit and receive operations and put DMA | ||
699 | * in idle state. | ||
700 | */ | ||
701 | abort_dma(pep); | ||
702 | |||
703 | /* Disable port */ | ||
704 | val = rdl(pep, PORT_CONFIG); | ||
705 | val &= ~PCR_EN; | ||
706 | wrl(pep, PORT_CONFIG, val); | ||
707 | } | ||
708 | |||
709 | /* | ||
710 | * txq_reclaim - Free the tx desc data for completed descriptors | ||
711 | * If force is non-zero, frees uncompleted descriptors as well | ||
712 | */ | ||
713 | static int txq_reclaim(struct net_device *dev, int force) | ||
714 | { | ||
715 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
716 | struct tx_desc *desc; | ||
717 | u32 cmd_sts; | ||
718 | struct sk_buff *skb; | ||
719 | int tx_index; | ||
720 | dma_addr_t addr; | ||
721 | int count; | ||
722 | int released = 0; | ||
723 | |||
724 | netif_tx_lock(dev); | ||
725 | |||
726 | pep->work_todo &= ~WORK_TX_DONE; | ||
727 | while (pep->tx_desc_count > 0) { | ||
728 | tx_index = pep->tx_used_desc_q; | ||
729 | desc = &pep->p_tx_desc_area[tx_index]; | ||
730 | cmd_sts = desc->cmd_sts; | ||
731 | if (!force && (cmd_sts & BUF_OWNED_BY_DMA)) { | ||
732 | if (released > 0) { | ||
733 | goto txq_reclaim_end; | ||
734 | } else { | ||
735 | released = -1; | ||
736 | goto txq_reclaim_end; | ||
737 | } | ||
738 | } | ||
739 | pep->tx_used_desc_q = (tx_index + 1) % pep->tx_ring_size; | ||
740 | pep->tx_desc_count--; | ||
741 | addr = desc->buf_ptr; | ||
742 | count = desc->byte_cnt; | ||
743 | skb = pep->tx_skb[tx_index]; | ||
744 | if (skb) | ||
745 | pep->tx_skb[tx_index] = NULL; | ||
746 | |||
747 | if (cmd_sts & TX_ERROR) { | ||
748 | if (net_ratelimit()) | ||
749 | printk(KERN_ERR "%s: Error in TX\n", dev->name); | ||
750 | dev->stats.tx_errors++; | ||
751 | } | ||
752 | dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); | ||
753 | if (skb) | ||
754 | dev_kfree_skb_irq(skb); | ||
755 | released++; | ||
756 | } | ||
757 | txq_reclaim_end: | ||
758 | netif_tx_unlock(dev); | ||
759 | return released; | ||
760 | } | ||
761 | |||
762 | static void pxa168_eth_tx_timeout(struct net_device *dev) | ||
763 | { | ||
764 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
765 | |||
766 | printk(KERN_INFO "%s: TX timeout desc_count %d\n", | ||
767 | dev->name, pep->tx_desc_count); | ||
768 | |||
769 | schedule_work(&pep->tx_timeout_task); | ||
770 | } | ||
771 | |||
772 | static void pxa168_eth_tx_timeout_task(struct work_struct *work) | ||
773 | { | ||
774 | struct pxa168_eth_private *pep = container_of(work, | ||
775 | struct pxa168_eth_private, | ||
776 | tx_timeout_task); | ||
777 | struct net_device *dev = pep->dev; | ||
778 | pxa168_eth_stop(dev); | ||
779 | pxa168_eth_open(dev); | ||
780 | } | ||
781 | |||
782 | static int rxq_process(struct net_device *dev, int budget) | ||
783 | { | ||
784 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
785 | struct net_device_stats *stats = &dev->stats; | ||
786 | unsigned int received_packets = 0; | ||
787 | struct sk_buff *skb; | ||
788 | |||
789 | while (budget-- > 0) { | ||
790 | int rx_next_curr_desc, rx_curr_desc, rx_used_desc; | ||
791 | struct rx_desc *rx_desc; | ||
792 | unsigned int cmd_sts; | ||
793 | |||
794 | /* Do not process Rx ring in case of Rx ring resource error */ | ||
795 | if (pep->rx_resource_err) | ||
796 | break; | ||
797 | rx_curr_desc = pep->rx_curr_desc_q; | ||
798 | rx_used_desc = pep->rx_used_desc_q; | ||
799 | rx_desc = &pep->p_rx_desc_area[rx_curr_desc]; | ||
800 | cmd_sts = rx_desc->cmd_sts; | ||
801 | rmb(); | ||
802 | if (cmd_sts & (BUF_OWNED_BY_DMA)) | ||
803 | break; | ||
804 | skb = pep->rx_skb[rx_curr_desc]; | ||
805 | pep->rx_skb[rx_curr_desc] = NULL; | ||
806 | |||
807 | rx_next_curr_desc = (rx_curr_desc + 1) % pep->rx_ring_size; | ||
808 | pep->rx_curr_desc_q = rx_next_curr_desc; | ||
809 | |||
810 | /* Rx descriptors exhausted. */ | ||
811 | /* Set the Rx ring resource error flag */ | ||
812 | if (rx_next_curr_desc == rx_used_desc) | ||
813 | pep->rx_resource_err = 1; | ||
814 | pep->rx_desc_count--; | ||
815 | dma_unmap_single(NULL, rx_desc->buf_ptr, | ||
816 | rx_desc->buf_size, | ||
817 | DMA_FROM_DEVICE); | ||
818 | received_packets++; | ||
819 | /* | ||
820 | * Update statistics. | ||
821 | * Note byte count includes 4 byte CRC count | ||
822 | */ | ||
823 | stats->rx_packets++; | ||
824 | stats->rx_bytes += rx_desc->byte_cnt; | ||
825 | /* | ||
826 | * In case received a packet without first / last bits on OR | ||
827 | * the error summary bit is on, the packets needs to be droped. | ||
828 | */ | ||
829 | if (((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) != | ||
830 | (RX_FIRST_DESC | RX_LAST_DESC)) | ||
831 | || (cmd_sts & RX_ERROR)) { | ||
832 | |||
833 | stats->rx_dropped++; | ||
834 | if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) != | ||
835 | (RX_FIRST_DESC | RX_LAST_DESC)) { | ||
836 | if (net_ratelimit()) | ||
837 | printk(KERN_ERR | ||
838 | "%s: Rx pkt on multiple desc\n", | ||
839 | dev->name); | ||
840 | } | ||
841 | if (cmd_sts & RX_ERROR) | ||
842 | stats->rx_errors++; | ||
843 | dev_kfree_skb_irq(skb); | ||
844 | } else { | ||
845 | /* | ||
846 | * The -4 is for the CRC in the trailer of the | ||
847 | * received packet | ||
848 | */ | ||
849 | skb_put(skb, rx_desc->byte_cnt - 4); | ||
850 | skb->protocol = eth_type_trans(skb, dev); | ||
851 | netif_receive_skb(skb); | ||
852 | } | ||
853 | dev->last_rx = jiffies; | ||
854 | } | ||
855 | /* Fill RX ring with skb's */ | ||
856 | rxq_refill(dev); | ||
857 | return received_packets; | ||
858 | } | ||
859 | |||
860 | static int pxa168_eth_collect_events(struct pxa168_eth_private *pep, | ||
861 | struct net_device *dev) | ||
862 | { | ||
863 | u32 icr; | ||
864 | int ret = 0; | ||
865 | |||
866 | icr = rdl(pep, INT_CAUSE); | ||
867 | if (icr == 0) | ||
868 | return IRQ_NONE; | ||
869 | |||
870 | wrl(pep, INT_CAUSE, ~icr); | ||
871 | if (icr & (ICR_TXBUF_H | ICR_TXBUF_L)) { | ||
872 | pep->work_todo |= WORK_TX_DONE; | ||
873 | ret = 1; | ||
874 | } | ||
875 | if (icr & ICR_RXBUF) | ||
876 | ret = 1; | ||
877 | if (icr & ICR_MII_CH) { | ||
878 | pep->work_todo |= WORK_LINK; | ||
879 | ret = 1; | ||
880 | } | ||
881 | return ret; | ||
882 | } | ||
883 | |||
884 | static void handle_link_event(struct pxa168_eth_private *pep) | ||
885 | { | ||
886 | struct net_device *dev = pep->dev; | ||
887 | u32 port_status; | ||
888 | int speed; | ||
889 | int duplex; | ||
890 | int fc; | ||
891 | |||
892 | port_status = rdl(pep, PORT_STATUS); | ||
893 | if (!(port_status & LINK_UP)) { | ||
894 | if (netif_carrier_ok(dev)) { | ||
895 | printk(KERN_INFO "%s: link down\n", dev->name); | ||
896 | netif_carrier_off(dev); | ||
897 | txq_reclaim(dev, 1); | ||
898 | } | ||
899 | return; | ||
900 | } | ||
901 | if (port_status & PORT_SPEED_100) | ||
902 | speed = 100; | ||
903 | else | ||
904 | speed = 10; | ||
905 | |||
906 | duplex = (port_status & FULL_DUPLEX) ? 1 : 0; | ||
907 | fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0; | ||
908 | printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, " | ||
909 | "flow control %sabled\n", dev->name, | ||
910 | speed, duplex ? "full" : "half", fc ? "en" : "dis"); | ||
911 | if (!netif_carrier_ok(dev)) | ||
912 | netif_carrier_on(dev); | ||
913 | } | ||
914 | |||
915 | static irqreturn_t pxa168_eth_int_handler(int irq, void *dev_id) | ||
916 | { | ||
917 | struct net_device *dev = (struct net_device *)dev_id; | ||
918 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
919 | |||
920 | if (unlikely(!pxa168_eth_collect_events(pep, dev))) | ||
921 | return IRQ_NONE; | ||
922 | /* Disable interrupts */ | ||
923 | wrl(pep, INT_MASK, 0); | ||
924 | napi_schedule(&pep->napi); | ||
925 | return IRQ_HANDLED; | ||
926 | } | ||
927 | |||
928 | static void pxa168_eth_recalc_skb_size(struct pxa168_eth_private *pep) | ||
929 | { | ||
930 | int skb_size; | ||
931 | |||
932 | /* | ||
933 | * Reserve 2+14 bytes for an ethernet header (the hardware | ||
934 | * automatically prepends 2 bytes of dummy data to each | ||
935 | * received packet), 16 bytes for up to four VLAN tags, and | ||
936 | * 4 bytes for the trailing FCS -- 36 bytes total. | ||
937 | */ | ||
938 | skb_size = pep->dev->mtu + 36; | ||
939 | |||
940 | /* | ||
941 | * Make sure that the skb size is a multiple of 8 bytes, as | ||
942 | * the lower three bits of the receive descriptor's buffer | ||
943 | * size field are ignored by the hardware. | ||
944 | */ | ||
945 | pep->skb_size = (skb_size + 7) & ~7; | ||
946 | |||
947 | /* | ||
948 | * If NET_SKB_PAD is smaller than a cache line, | ||
949 | * netdev_alloc_skb() will cause skb->data to be misaligned | ||
950 | * to a cache line boundary. If this is the case, include | ||
951 | * some extra space to allow re-aligning the data area. | ||
952 | */ | ||
953 | pep->skb_size += SKB_DMA_REALIGN; | ||
954 | |||
955 | } | ||
956 | |||
957 | static int set_port_config_ext(struct pxa168_eth_private *pep) | ||
958 | { | ||
959 | int skb_size; | ||
960 | |||
961 | pxa168_eth_recalc_skb_size(pep); | ||
962 | if (pep->skb_size <= 1518) | ||
963 | skb_size = PCXR_MFL_1518; | ||
964 | else if (pep->skb_size <= 1536) | ||
965 | skb_size = PCXR_MFL_1536; | ||
966 | else if (pep->skb_size <= 2048) | ||
967 | skb_size = PCXR_MFL_2048; | ||
968 | else | ||
969 | skb_size = PCXR_MFL_64K; | ||
970 | |||
971 | /* Extended Port Configuration */ | ||
972 | wrl(pep, | ||
973 | PORT_CONFIG_EXT, PCXR_2BSM | /* Two byte prefix aligns IP hdr */ | ||
974 | PCXR_DSCP_EN | /* Enable DSCP in IP */ | ||
975 | skb_size | PCXR_FLP | /* do not force link pass */ | ||
976 | PCXR_TX_HIGH_PRI); /* Transmit - high priority queue */ | ||
977 | |||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | static int pxa168_init_hw(struct pxa168_eth_private *pep) | ||
982 | { | ||
983 | int err = 0; | ||
984 | |||
985 | /* Disable interrupts */ | ||
986 | wrl(pep, INT_MASK, 0); | ||
987 | wrl(pep, INT_CAUSE, 0); | ||
988 | /* Write to ICR to clear interrupts. */ | ||
989 | wrl(pep, INT_W_CLEAR, 0); | ||
990 | /* Abort any transmit and receive operations and put DMA | ||
991 | * in idle state. | ||
992 | */ | ||
993 | abort_dma(pep); | ||
994 | /* Initialize address hash table */ | ||
995 | err = init_hash_table(pep); | ||
996 | if (err) | ||
997 | return err; | ||
998 | /* SDMA configuration */ | ||
999 | wrl(pep, SDMA_CONFIG, SDCR_BSZ8 | /* Burst size = 32 bytes */ | ||
1000 | SDCR_RIFB | /* Rx interrupt on frame */ | ||
1001 | SDCR_BLMT | /* Little endian transmit */ | ||
1002 | SDCR_BLMR | /* Little endian receive */ | ||
1003 | SDCR_RC_MAX_RETRANS); /* Max retransmit count */ | ||
1004 | /* Port Configuration */ | ||
1005 | wrl(pep, PORT_CONFIG, PCR_HS); /* Hash size is 1/2kb */ | ||
1006 | set_port_config_ext(pep); | ||
1007 | |||
1008 | return err; | ||
1009 | } | ||
1010 | |||
1011 | static int rxq_init(struct net_device *dev) | ||
1012 | { | ||
1013 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1014 | struct rx_desc *p_rx_desc; | ||
1015 | int size = 0, i = 0; | ||
1016 | int rx_desc_num = pep->rx_ring_size; | ||
1017 | |||
1018 | /* Allocate RX skb rings */ | ||
1019 | pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size, | ||
1020 | GFP_KERNEL); | ||
1021 | if (!pep->rx_skb) { | ||
1022 | printk(KERN_ERR "%s: Cannot alloc RX skb ring\n", dev->name); | ||
1023 | return -ENOMEM; | ||
1024 | } | ||
1025 | /* Allocate RX ring */ | ||
1026 | pep->rx_desc_count = 0; | ||
1027 | size = pep->rx_ring_size * sizeof(struct rx_desc); | ||
1028 | pep->rx_desc_area_size = size; | ||
1029 | pep->p_rx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size, | ||
1030 | &pep->rx_desc_dma, GFP_KERNEL); | ||
1031 | if (!pep->p_rx_desc_area) { | ||
1032 | printk(KERN_ERR "%s: Cannot alloc RX ring (size %d bytes)\n", | ||
1033 | dev->name, size); | ||
1034 | goto out; | ||
1035 | } | ||
1036 | memset((void *)pep->p_rx_desc_area, 0, size); | ||
1037 | /* initialize the next_desc_ptr links in the Rx descriptors ring */ | ||
1038 | p_rx_desc = (struct rx_desc *)pep->p_rx_desc_area; | ||
1039 | for (i = 0; i < rx_desc_num; i++) { | ||
1040 | p_rx_desc[i].next_desc_ptr = pep->rx_desc_dma + | ||
1041 | ((i + 1) % rx_desc_num) * sizeof(struct rx_desc); | ||
1042 | } | ||
1043 | /* Save Rx desc pointer to driver struct. */ | ||
1044 | pep->rx_curr_desc_q = 0; | ||
1045 | pep->rx_used_desc_q = 0; | ||
1046 | pep->rx_desc_area_size = rx_desc_num * sizeof(struct rx_desc); | ||
1047 | return 0; | ||
1048 | out: | ||
1049 | kfree(pep->rx_skb); | ||
1050 | return -ENOMEM; | ||
1051 | } | ||
1052 | |||
1053 | static void rxq_deinit(struct net_device *dev) | ||
1054 | { | ||
1055 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1056 | int curr; | ||
1057 | |||
1058 | /* Free preallocated skb's on RX rings */ | ||
1059 | for (curr = 0; pep->rx_desc_count && curr < pep->rx_ring_size; curr++) { | ||
1060 | if (pep->rx_skb[curr]) { | ||
1061 | dev_kfree_skb(pep->rx_skb[curr]); | ||
1062 | pep->rx_desc_count--; | ||
1063 | } | ||
1064 | } | ||
1065 | if (pep->rx_desc_count) | ||
1066 | printk(KERN_ERR | ||
1067 | "Error in freeing Rx Ring. %d skb's still\n", | ||
1068 | pep->rx_desc_count); | ||
1069 | /* Free RX ring */ | ||
1070 | if (pep->p_rx_desc_area) | ||
1071 | dma_free_coherent(pep->dev->dev.parent, pep->rx_desc_area_size, | ||
1072 | pep->p_rx_desc_area, pep->rx_desc_dma); | ||
1073 | kfree(pep->rx_skb); | ||
1074 | } | ||
1075 | |||
1076 | static int txq_init(struct net_device *dev) | ||
1077 | { | ||
1078 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1079 | struct tx_desc *p_tx_desc; | ||
1080 | int size = 0, i = 0; | ||
1081 | int tx_desc_num = pep->tx_ring_size; | ||
1082 | |||
1083 | pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size, | ||
1084 | GFP_KERNEL); | ||
1085 | if (!pep->tx_skb) { | ||
1086 | printk(KERN_ERR "%s: Cannot alloc TX skb ring\n", dev->name); | ||
1087 | return -ENOMEM; | ||
1088 | } | ||
1089 | /* Allocate TX ring */ | ||
1090 | pep->tx_desc_count = 0; | ||
1091 | size = pep->tx_ring_size * sizeof(struct tx_desc); | ||
1092 | pep->tx_desc_area_size = size; | ||
1093 | pep->p_tx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size, | ||
1094 | &pep->tx_desc_dma, GFP_KERNEL); | ||
1095 | if (!pep->p_tx_desc_area) { | ||
1096 | printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", | ||
1097 | dev->name, size); | ||
1098 | goto out; | ||
1099 | } | ||
1100 | memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size); | ||
1101 | /* Initialize the next_desc_ptr links in the Tx descriptors ring */ | ||
1102 | p_tx_desc = (struct tx_desc *)pep->p_tx_desc_area; | ||
1103 | for (i = 0; i < tx_desc_num; i++) { | ||
1104 | p_tx_desc[i].next_desc_ptr = pep->tx_desc_dma + | ||
1105 | ((i + 1) % tx_desc_num) * sizeof(struct tx_desc); | ||
1106 | } | ||
1107 | pep->tx_curr_desc_q = 0; | ||
1108 | pep->tx_used_desc_q = 0; | ||
1109 | pep->tx_desc_area_size = tx_desc_num * sizeof(struct tx_desc); | ||
1110 | return 0; | ||
1111 | out: | ||
1112 | kfree(pep->tx_skb); | ||
1113 | return -ENOMEM; | ||
1114 | } | ||
1115 | |||
1116 | static void txq_deinit(struct net_device *dev) | ||
1117 | { | ||
1118 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1119 | |||
1120 | /* Free outstanding skb's on TX ring */ | ||
1121 | txq_reclaim(dev, 1); | ||
1122 | BUG_ON(pep->tx_used_desc_q != pep->tx_curr_desc_q); | ||
1123 | /* Free TX ring */ | ||
1124 | if (pep->p_tx_desc_area) | ||
1125 | dma_free_coherent(pep->dev->dev.parent, pep->tx_desc_area_size, | ||
1126 | pep->p_tx_desc_area, pep->tx_desc_dma); | ||
1127 | kfree(pep->tx_skb); | ||
1128 | } | ||
1129 | |||
1130 | static int pxa168_eth_open(struct net_device *dev) | ||
1131 | { | ||
1132 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1133 | int err; | ||
1134 | |||
1135 | err = request_irq(dev->irq, pxa168_eth_int_handler, | ||
1136 | IRQF_DISABLED, dev->name, dev); | ||
1137 | if (err) { | ||
1138 | dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n"); | ||
1139 | return -EAGAIN; | ||
1140 | } | ||
1141 | pep->rx_resource_err = 0; | ||
1142 | err = rxq_init(dev); | ||
1143 | if (err != 0) | ||
1144 | goto out_free_irq; | ||
1145 | err = txq_init(dev); | ||
1146 | if (err != 0) | ||
1147 | goto out_free_rx_skb; | ||
1148 | pep->rx_used_desc_q = 0; | ||
1149 | pep->rx_curr_desc_q = 0; | ||
1150 | |||
1151 | /* Fill RX ring with skb's */ | ||
1152 | rxq_refill(dev); | ||
1153 | pep->rx_used_desc_q = 0; | ||
1154 | pep->rx_curr_desc_q = 0; | ||
1155 | netif_carrier_off(dev); | ||
1156 | eth_port_start(dev); | ||
1157 | napi_enable(&pep->napi); | ||
1158 | return 0; | ||
1159 | out_free_rx_skb: | ||
1160 | rxq_deinit(dev); | ||
1161 | out_free_irq: | ||
1162 | free_irq(dev->irq, dev); | ||
1163 | return err; | ||
1164 | } | ||
1165 | |||
1166 | static int pxa168_eth_stop(struct net_device *dev) | ||
1167 | { | ||
1168 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1169 | eth_port_reset(dev); | ||
1170 | |||
1171 | /* Disable interrupts */ | ||
1172 | wrl(pep, INT_MASK, 0); | ||
1173 | wrl(pep, INT_CAUSE, 0); | ||
1174 | /* Write to ICR to clear interrupts. */ | ||
1175 | wrl(pep, INT_W_CLEAR, 0); | ||
1176 | napi_disable(&pep->napi); | ||
1177 | del_timer_sync(&pep->timeout); | ||
1178 | netif_carrier_off(dev); | ||
1179 | free_irq(dev->irq, dev); | ||
1180 | rxq_deinit(dev); | ||
1181 | txq_deinit(dev); | ||
1182 | |||
1183 | return 0; | ||
1184 | } | ||
1185 | |||
1186 | static int pxa168_eth_change_mtu(struct net_device *dev, int mtu) | ||
1187 | { | ||
1188 | int retval; | ||
1189 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1190 | |||
1191 | if ((mtu > 9500) || (mtu < 68)) | ||
1192 | return -EINVAL; | ||
1193 | |||
1194 | dev->mtu = mtu; | ||
1195 | retval = set_port_config_ext(pep); | ||
1196 | |||
1197 | if (!netif_running(dev)) | ||
1198 | return 0; | ||
1199 | |||
1200 | /* | ||
1201 | * Stop and then re-open the interface. This will allocate RX | ||
1202 | * skbs of the new MTU. | ||
1203 | * There is a possible danger that the open will not succeed, | ||
1204 | * due to memory being full. | ||
1205 | */ | ||
1206 | pxa168_eth_stop(dev); | ||
1207 | if (pxa168_eth_open(dev)) { | ||
1208 | dev_printk(KERN_ERR, &dev->dev, | ||
1209 | "fatal error on re-opening device after " | ||
1210 | "MTU change\n"); | ||
1211 | } | ||
1212 | |||
1213 | return 0; | ||
1214 | } | ||
1215 | |||
1216 | static int eth_alloc_tx_desc_index(struct pxa168_eth_private *pep) | ||
1217 | { | ||
1218 | int tx_desc_curr; | ||
1219 | |||
1220 | tx_desc_curr = pep->tx_curr_desc_q; | ||
1221 | pep->tx_curr_desc_q = (tx_desc_curr + 1) % pep->tx_ring_size; | ||
1222 | BUG_ON(pep->tx_curr_desc_q == pep->tx_used_desc_q); | ||
1223 | pep->tx_desc_count++; | ||
1224 | |||
1225 | return tx_desc_curr; | ||
1226 | } | ||
1227 | |||
1228 | static int pxa168_rx_poll(struct napi_struct *napi, int budget) | ||
1229 | { | ||
1230 | struct pxa168_eth_private *pep = | ||
1231 | container_of(napi, struct pxa168_eth_private, napi); | ||
1232 | struct net_device *dev = pep->dev; | ||
1233 | int work_done = 0; | ||
1234 | |||
1235 | if (unlikely(pep->work_todo & WORK_LINK)) { | ||
1236 | pep->work_todo &= ~(WORK_LINK); | ||
1237 | handle_link_event(pep); | ||
1238 | } | ||
1239 | /* | ||
1240 | * We call txq_reclaim every time since in NAPI interupts are disabled | ||
1241 | * and due to this we miss the TX_DONE interrupt,which is not updated in | ||
1242 | * interrupt status register. | ||
1243 | */ | ||
1244 | txq_reclaim(dev, 0); | ||
1245 | if (netif_queue_stopped(dev) | ||
1246 | && pep->tx_ring_size - pep->tx_desc_count > 1) { | ||
1247 | netif_wake_queue(dev); | ||
1248 | } | ||
1249 | work_done = rxq_process(dev, budget); | ||
1250 | if (work_done < budget) { | ||
1251 | napi_complete(napi); | ||
1252 | wrl(pep, INT_MASK, ALL_INTS); | ||
1253 | } | ||
1254 | |||
1255 | return work_done; | ||
1256 | } | ||
1257 | |||
1258 | static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1259 | { | ||
1260 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1261 | struct net_device_stats *stats = &dev->stats; | ||
1262 | struct tx_desc *desc; | ||
1263 | int tx_index; | ||
1264 | int length; | ||
1265 | |||
1266 | tx_index = eth_alloc_tx_desc_index(pep); | ||
1267 | desc = &pep->p_tx_desc_area[tx_index]; | ||
1268 | length = skb->len; | ||
1269 | pep->tx_skb[tx_index] = skb; | ||
1270 | desc->byte_cnt = length; | ||
1271 | desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); | ||
1272 | wmb(); | ||
1273 | desc->cmd_sts = BUF_OWNED_BY_DMA | TX_GEN_CRC | TX_FIRST_DESC | | ||
1274 | TX_ZERO_PADDING | TX_LAST_DESC | TX_EN_INT; | ||
1275 | wmb(); | ||
1276 | wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD); | ||
1277 | |||
1278 | stats->tx_bytes += skb->len; | ||
1279 | stats->tx_packets++; | ||
1280 | dev->trans_start = jiffies; | ||
1281 | if (pep->tx_ring_size - pep->tx_desc_count <= 1) { | ||
1282 | /* We handled the current skb, but now we are out of space.*/ | ||
1283 | netif_stop_queue(dev); | ||
1284 | } | ||
1285 | |||
1286 | return NETDEV_TX_OK; | ||
1287 | } | ||
1288 | |||
1289 | static int smi_wait_ready(struct pxa168_eth_private *pep) | ||
1290 | { | ||
1291 | int i = 0; | ||
1292 | |||
1293 | /* wait for the SMI register to become available */ | ||
1294 | for (i = 0; rdl(pep, SMI) & SMI_BUSY; i++) { | ||
1295 | if (i == PHY_WAIT_ITERATIONS) | ||
1296 | return -ETIMEDOUT; | ||
1297 | msleep(10); | ||
1298 | } | ||
1299 | |||
1300 | return 0; | ||
1301 | } | ||
1302 | |||
1303 | static int pxa168_smi_read(struct mii_bus *bus, int phy_addr, int regnum) | ||
1304 | { | ||
1305 | struct pxa168_eth_private *pep = bus->priv; | ||
1306 | int i = 0; | ||
1307 | int val; | ||
1308 | |||
1309 | if (smi_wait_ready(pep)) { | ||
1310 | printk(KERN_WARNING "pxa168_eth: SMI bus busy timeout\n"); | ||
1311 | return -ETIMEDOUT; | ||
1312 | } | ||
1313 | wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | SMI_OP_R); | ||
1314 | /* now wait for the data to be valid */ | ||
1315 | for (i = 0; !((val = rdl(pep, SMI)) & SMI_R_VALID); i++) { | ||
1316 | if (i == PHY_WAIT_ITERATIONS) { | ||
1317 | printk(KERN_WARNING | ||
1318 | "pxa168_eth: SMI bus read not valid\n"); | ||
1319 | return -ENODEV; | ||
1320 | } | ||
1321 | msleep(10); | ||
1322 | } | ||
1323 | |||
1324 | return val & 0xffff; | ||
1325 | } | ||
1326 | |||
1327 | static int pxa168_smi_write(struct mii_bus *bus, int phy_addr, int regnum, | ||
1328 | u16 value) | ||
1329 | { | ||
1330 | struct pxa168_eth_private *pep = bus->priv; | ||
1331 | |||
1332 | if (smi_wait_ready(pep)) { | ||
1333 | printk(KERN_WARNING "pxa168_eth: SMI bus busy timeout\n"); | ||
1334 | return -ETIMEDOUT; | ||
1335 | } | ||
1336 | |||
1337 | wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | | ||
1338 | SMI_OP_W | (value & 0xffff)); | ||
1339 | |||
1340 | if (smi_wait_ready(pep)) { | ||
1341 | printk(KERN_ERR "pxa168_eth: SMI bus busy timeout\n"); | ||
1342 | return -ETIMEDOUT; | ||
1343 | } | ||
1344 | |||
1345 | return 0; | ||
1346 | } | ||
1347 | |||
1348 | static int pxa168_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr, | ||
1349 | int cmd) | ||
1350 | { | ||
1351 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1352 | if (pep->phy != NULL) | ||
1353 | return phy_mii_ioctl(pep->phy, ifr, cmd); | ||
1354 | |||
1355 | return -EOPNOTSUPP; | ||
1356 | } | ||
1357 | |||
1358 | static struct phy_device *phy_scan(struct pxa168_eth_private *pep, int phy_addr) | ||
1359 | { | ||
1360 | struct mii_bus *bus = pep->smi_bus; | ||
1361 | struct phy_device *phydev; | ||
1362 | int start; | ||
1363 | int num; | ||
1364 | int i; | ||
1365 | |||
1366 | if (phy_addr == PXA168_ETH_PHY_ADDR_DEFAULT) { | ||
1367 | /* Scan entire range */ | ||
1368 | start = ethernet_phy_get(pep); | ||
1369 | num = 32; | ||
1370 | } else { | ||
1371 | /* Use phy addr specific to platform */ | ||
1372 | start = phy_addr & 0x1f; | ||
1373 | num = 1; | ||
1374 | } | ||
1375 | phydev = NULL; | ||
1376 | for (i = 0; i < num; i++) { | ||
1377 | int addr = (start + i) & 0x1f; | ||
1378 | if (bus->phy_map[addr] == NULL) | ||
1379 | mdiobus_scan(bus, addr); | ||
1380 | |||
1381 | if (phydev == NULL) { | ||
1382 | phydev = bus->phy_map[addr]; | ||
1383 | if (phydev != NULL) | ||
1384 | ethernet_phy_set_addr(pep, addr); | ||
1385 | } | ||
1386 | } | ||
1387 | |||
1388 | return phydev; | ||
1389 | } | ||
1390 | |||
1391 | static void phy_init(struct pxa168_eth_private *pep, int speed, int duplex) | ||
1392 | { | ||
1393 | struct phy_device *phy = pep->phy; | ||
1394 | ethernet_phy_reset(pep); | ||
1395 | |||
1396 | phy_attach(pep->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_MII); | ||
1397 | |||
1398 | if (speed == 0) { | ||
1399 | phy->autoneg = AUTONEG_ENABLE; | ||
1400 | phy->speed = 0; | ||
1401 | phy->duplex = 0; | ||
1402 | phy->supported &= PHY_BASIC_FEATURES; | ||
1403 | phy->advertising = phy->supported | ADVERTISED_Autoneg; | ||
1404 | } else { | ||
1405 | phy->autoneg = AUTONEG_DISABLE; | ||
1406 | phy->advertising = 0; | ||
1407 | phy->speed = speed; | ||
1408 | phy->duplex = duplex; | ||
1409 | } | ||
1410 | phy_start_aneg(phy); | ||
1411 | } | ||
1412 | |||
1413 | static int ethernet_phy_setup(struct net_device *dev) | ||
1414 | { | ||
1415 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1416 | |||
1417 | if (pep->pd->init) | ||
1418 | pep->pd->init(); | ||
1419 | pep->phy = phy_scan(pep, pep->pd->phy_addr & 0x1f); | ||
1420 | if (pep->phy != NULL) | ||
1421 | phy_init(pep, pep->pd->speed, pep->pd->duplex); | ||
1422 | update_hash_table_mac_address(pep, NULL, dev->dev_addr); | ||
1423 | |||
1424 | return 0; | ||
1425 | } | ||
1426 | |||
1427 | static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1428 | { | ||
1429 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1430 | int err; | ||
1431 | |||
1432 | err = phy_read_status(pep->phy); | ||
1433 | if (err == 0) | ||
1434 | err = phy_ethtool_gset(pep->phy, cmd); | ||
1435 | |||
1436 | return err; | ||
1437 | } | ||
1438 | |||
1439 | static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | ||
1440 | { | ||
1441 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1442 | |||
1443 | return phy_ethtool_sset(pep->phy, cmd); | ||
1444 | } | ||
1445 | |||
1446 | static void pxa168_get_drvinfo(struct net_device *dev, | ||
1447 | struct ethtool_drvinfo *info) | ||
1448 | { | ||
1449 | strncpy(info->driver, DRIVER_NAME, 32); | ||
1450 | strncpy(info->version, DRIVER_VERSION, 32); | ||
1451 | strncpy(info->fw_version, "N/A", 32); | ||
1452 | strncpy(info->bus_info, "N/A", 32); | ||
1453 | } | ||
1454 | |||
1455 | static u32 pxa168_get_link(struct net_device *dev) | ||
1456 | { | ||
1457 | return !!netif_carrier_ok(dev); | ||
1458 | } | ||
1459 | |||
1460 | static const struct ethtool_ops pxa168_ethtool_ops = { | ||
1461 | .get_settings = pxa168_get_settings, | ||
1462 | .set_settings = pxa168_set_settings, | ||
1463 | .get_drvinfo = pxa168_get_drvinfo, | ||
1464 | .get_link = pxa168_get_link, | ||
1465 | }; | ||
1466 | |||
1467 | static const struct net_device_ops pxa168_eth_netdev_ops = { | ||
1468 | .ndo_open = pxa168_eth_open, | ||
1469 | .ndo_stop = pxa168_eth_stop, | ||
1470 | .ndo_start_xmit = pxa168_eth_start_xmit, | ||
1471 | .ndo_set_rx_mode = pxa168_eth_set_rx_mode, | ||
1472 | .ndo_set_mac_address = pxa168_eth_set_mac_address, | ||
1473 | .ndo_validate_addr = eth_validate_addr, | ||
1474 | .ndo_do_ioctl = pxa168_eth_do_ioctl, | ||
1475 | .ndo_change_mtu = pxa168_eth_change_mtu, | ||
1476 | .ndo_tx_timeout = pxa168_eth_tx_timeout, | ||
1477 | }; | ||
1478 | |||
1479 | static int pxa168_eth_probe(struct platform_device *pdev) | ||
1480 | { | ||
1481 | struct pxa168_eth_private *pep = NULL; | ||
1482 | struct net_device *dev = NULL; | ||
1483 | struct resource *res; | ||
1484 | struct clk *clk; | ||
1485 | int err; | ||
1486 | |||
1487 | printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n"); | ||
1488 | |||
1489 | clk = clk_get(&pdev->dev, "MFUCLK"); | ||
1490 | if (IS_ERR(clk)) { | ||
1491 | printk(KERN_ERR "%s: Fast Ethernet failed to get clock\n", | ||
1492 | DRIVER_NAME); | ||
1493 | return -ENODEV; | ||
1494 | } | ||
1495 | clk_enable(clk); | ||
1496 | |||
1497 | dev = alloc_etherdev(sizeof(struct pxa168_eth_private)); | ||
1498 | if (!dev) { | ||
1499 | err = -ENOMEM; | ||
1500 | goto err_clk; | ||
1501 | } | ||
1502 | |||
1503 | platform_set_drvdata(pdev, dev); | ||
1504 | pep = netdev_priv(dev); | ||
1505 | pep->dev = dev; | ||
1506 | pep->clk = clk; | ||
1507 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1508 | if (res == NULL) { | ||
1509 | err = -ENODEV; | ||
1510 | goto err_netdev; | ||
1511 | } | ||
1512 | pep->base = ioremap(res->start, res->end - res->start + 1); | ||
1513 | if (pep->base == NULL) { | ||
1514 | err = -ENOMEM; | ||
1515 | goto err_netdev; | ||
1516 | } | ||
1517 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
1518 | BUG_ON(!res); | ||
1519 | dev->irq = res->start; | ||
1520 | dev->netdev_ops = &pxa168_eth_netdev_ops; | ||
1521 | dev->watchdog_timeo = 2 * HZ; | ||
1522 | dev->base_addr = 0; | ||
1523 | SET_ETHTOOL_OPS(dev, &pxa168_ethtool_ops); | ||
1524 | |||
1525 | INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task); | ||
1526 | |||
1527 | printk(KERN_INFO "%s:Using random mac address\n", DRIVER_NAME); | ||
1528 | random_ether_addr(dev->dev_addr); | ||
1529 | |||
1530 | pep->pd = pdev->dev.platform_data; | ||
1531 | pep->rx_ring_size = NUM_RX_DESCS; | ||
1532 | if (pep->pd->rx_queue_size) | ||
1533 | pep->rx_ring_size = pep->pd->rx_queue_size; | ||
1534 | |||
1535 | pep->tx_ring_size = NUM_TX_DESCS; | ||
1536 | if (pep->pd->tx_queue_size) | ||
1537 | pep->tx_ring_size = pep->pd->tx_queue_size; | ||
1538 | |||
1539 | pep->port_num = pep->pd->port_number; | ||
1540 | /* Hardware supports only 3 ports */ | ||
1541 | BUG_ON(pep->port_num > 2); | ||
1542 | netif_napi_add(dev, &pep->napi, pxa168_rx_poll, pep->rx_ring_size); | ||
1543 | |||
1544 | memset(&pep->timeout, 0, sizeof(struct timer_list)); | ||
1545 | init_timer(&pep->timeout); | ||
1546 | pep->timeout.function = rxq_refill_timer_wrapper; | ||
1547 | pep->timeout.data = (unsigned long)pep; | ||
1548 | |||
1549 | pep->smi_bus = mdiobus_alloc(); | ||
1550 | if (pep->smi_bus == NULL) { | ||
1551 | err = -ENOMEM; | ||
1552 | goto err_base; | ||
1553 | } | ||
1554 | pep->smi_bus->priv = pep; | ||
1555 | pep->smi_bus->name = "pxa168_eth smi"; | ||
1556 | pep->smi_bus->read = pxa168_smi_read; | ||
1557 | pep->smi_bus->write = pxa168_smi_write; | ||
1558 | snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id); | ||
1559 | pep->smi_bus->parent = &pdev->dev; | ||
1560 | pep->smi_bus->phy_mask = 0xffffffff; | ||
1561 | err = mdiobus_register(pep->smi_bus); | ||
1562 | if (err) | ||
1563 | goto err_free_mdio; | ||
1564 | |||
1565 | pxa168_init_hw(pep); | ||
1566 | err = ethernet_phy_setup(dev); | ||
1567 | if (err) | ||
1568 | goto err_mdiobus; | ||
1569 | SET_NETDEV_DEV(dev, &pdev->dev); | ||
1570 | err = register_netdev(dev); | ||
1571 | if (err) | ||
1572 | goto err_mdiobus; | ||
1573 | return 0; | ||
1574 | |||
1575 | err_mdiobus: | ||
1576 | mdiobus_unregister(pep->smi_bus); | ||
1577 | err_free_mdio: | ||
1578 | mdiobus_free(pep->smi_bus); | ||
1579 | err_base: | ||
1580 | iounmap(pep->base); | ||
1581 | err_netdev: | ||
1582 | free_netdev(dev); | ||
1583 | err_clk: | ||
1584 | clk_disable(clk); | ||
1585 | clk_put(clk); | ||
1586 | return err; | ||
1587 | } | ||
1588 | |||
1589 | static int pxa168_eth_remove(struct platform_device *pdev) | ||
1590 | { | ||
1591 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1592 | struct pxa168_eth_private *pep = netdev_priv(dev); | ||
1593 | |||
1594 | if (pep->htpr) { | ||
1595 | dma_free_coherent(pep->dev->dev.parent, HASH_ADDR_TABLE_SIZE, | ||
1596 | pep->htpr, pep->htpr_dma); | ||
1597 | pep->htpr = NULL; | ||
1598 | } | ||
1599 | if (pep->clk) { | ||
1600 | clk_disable(pep->clk); | ||
1601 | clk_put(pep->clk); | ||
1602 | pep->clk = NULL; | ||
1603 | } | ||
1604 | if (pep->phy != NULL) | ||
1605 | phy_detach(pep->phy); | ||
1606 | |||
1607 | iounmap(pep->base); | ||
1608 | pep->base = NULL; | ||
1609 | unregister_netdev(dev); | ||
1610 | flush_scheduled_work(); | ||
1611 | free_netdev(dev); | ||
1612 | platform_set_drvdata(pdev, NULL); | ||
1613 | return 0; | ||
1614 | } | ||
1615 | |||
1616 | static void pxa168_eth_shutdown(struct platform_device *pdev) | ||
1617 | { | ||
1618 | struct net_device *dev = platform_get_drvdata(pdev); | ||
1619 | eth_port_reset(dev); | ||
1620 | } | ||
1621 | |||
1622 | #ifdef CONFIG_PM | ||
1623 | static int pxa168_eth_resume(struct platform_device *pdev) | ||
1624 | { | ||
1625 | return -ENOSYS; | ||
1626 | } | ||
1627 | |||
1628 | static int pxa168_eth_suspend(struct platform_device *pdev, pm_message_t state) | ||
1629 | { | ||
1630 | return -ENOSYS; | ||
1631 | } | ||
1632 | |||
1633 | #else | ||
1634 | #define pxa168_eth_resume NULL | ||
1635 | #define pxa168_eth_suspend NULL | ||
1636 | #endif | ||
1637 | |||
1638 | static struct platform_driver pxa168_eth_driver = { | ||
1639 | .probe = pxa168_eth_probe, | ||
1640 | .remove = pxa168_eth_remove, | ||
1641 | .shutdown = pxa168_eth_shutdown, | ||
1642 | .resume = pxa168_eth_resume, | ||
1643 | .suspend = pxa168_eth_suspend, | ||
1644 | .driver = { | ||
1645 | .name = DRIVER_NAME, | ||
1646 | }, | ||
1647 | }; | ||
1648 | |||
1649 | static int __init pxa168_init_module(void) | ||
1650 | { | ||
1651 | return platform_driver_register(&pxa168_eth_driver); | ||
1652 | } | ||
1653 | |||
1654 | static void __exit pxa168_cleanup_module(void) | ||
1655 | { | ||
1656 | platform_driver_unregister(&pxa168_eth_driver); | ||
1657 | } | ||
1658 | |||
1659 | module_init(pxa168_init_module); | ||
1660 | module_exit(pxa168_cleanup_module); | ||
1661 | |||
1662 | MODULE_LICENSE("GPL"); | ||
1663 | MODULE_DESCRIPTION("Ethernet driver for Marvell PXA168"); | ||
1664 | MODULE_ALIAS("platform:pxa168_eth"); | ||
diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index bf6d87adda4f..66eea5972020 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c | |||
@@ -1983,8 +1983,6 @@ static struct net_device_stats *qlcnic_get_stats(struct net_device *netdev) | |||
1983 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 1983 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
1984 | struct net_device_stats *stats = &netdev->stats; | 1984 | struct net_device_stats *stats = &netdev->stats; |
1985 | 1985 | ||
1986 | memset(stats, 0, sizeof(*stats)); | ||
1987 | |||
1988 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; | 1986 | stats->rx_packets = adapter->stats.rx_pkts + adapter->stats.lro_pkts; |
1989 | stats->tx_packets = adapter->stats.xmitfinished; | 1987 | stats->tx_packets = adapter->stats.xmitfinished; |
1990 | stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes; | 1988 | stats->rx_bytes = adapter->stats.rxbytes + adapter->stats.lrobytes; |
@@ -2190,9 +2188,16 @@ static int qlcnic_rx_poll(struct napi_struct *napi, int budget) | |||
2190 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2188 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2191 | static void qlcnic_poll_controller(struct net_device *netdev) | 2189 | static void qlcnic_poll_controller(struct net_device *netdev) |
2192 | { | 2190 | { |
2191 | int ring; | ||
2192 | struct qlcnic_host_sds_ring *sds_ring; | ||
2193 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 2193 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
2194 | struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx; | ||
2195 | |||
2194 | disable_irq(adapter->irq); | 2196 | disable_irq(adapter->irq); |
2195 | qlcnic_intr(adapter->irq, adapter); | 2197 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
2198 | sds_ring = &recv_ctx->sds_rings[ring]; | ||
2199 | qlcnic_intr(adapter->irq, sds_ring); | ||
2200 | } | ||
2196 | enable_irq(adapter->irq); | 2201 | enable_irq(adapter->irq); |
2197 | } | 2202 | } |
2198 | #endif | 2203 | #endif |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 8d63f69b27d9..5f89e83501f4 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -3919,12 +3919,12 @@ static int ql_adapter_down(struct ql_adapter *qdev) | |||
3919 | for (i = 0; i < qdev->rss_ring_count; i++) | 3919 | for (i = 0; i < qdev->rss_ring_count; i++) |
3920 | netif_napi_del(&qdev->rx_ring[i].napi); | 3920 | netif_napi_del(&qdev->rx_ring[i].napi); |
3921 | 3921 | ||
3922 | ql_free_rx_buffers(qdev); | ||
3923 | |||
3924 | status = ql_adapter_reset(qdev); | 3922 | status = ql_adapter_reset(qdev); |
3925 | if (status) | 3923 | if (status) |
3926 | netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n", | 3924 | netif_err(qdev, ifdown, qdev->ndev, "reset(func #%d) FAILED!\n", |
3927 | qdev->func); | 3925 | qdev->func); |
3926 | ql_free_rx_buffers(qdev); | ||
3927 | |||
3928 | return status; | 3928 | return status; |
3929 | } | 3929 | } |
3930 | 3930 | ||
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index f5a9eb1df593..79fd02bc69fd 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -1437,7 +1437,7 @@ static const struct net_device_ops sh_eth_netdev_ops = { | |||
1437 | 1437 | ||
1438 | static int sh_eth_drv_probe(struct platform_device *pdev) | 1438 | static int sh_eth_drv_probe(struct platform_device *pdev) |
1439 | { | 1439 | { |
1440 | int ret, i, devno = 0; | 1440 | int ret, devno = 0; |
1441 | struct resource *res; | 1441 | struct resource *res; |
1442 | struct net_device *ndev = NULL; | 1442 | struct net_device *ndev = NULL; |
1443 | struct sh_eth_private *mdp; | 1443 | struct sh_eth_private *mdp; |
diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 08e7b6abacdd..8ed30fa35d0a 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c | |||
@@ -58,6 +58,7 @@ | |||
58 | #define USB_PRODUCT_IPHONE 0x1290 | 58 | #define USB_PRODUCT_IPHONE 0x1290 |
59 | #define USB_PRODUCT_IPHONE_3G 0x1292 | 59 | #define USB_PRODUCT_IPHONE_3G 0x1292 |
60 | #define USB_PRODUCT_IPHONE_3GS 0x1294 | 60 | #define USB_PRODUCT_IPHONE_3GS 0x1294 |
61 | #define USB_PRODUCT_IPHONE_4 0x1297 | ||
61 | 62 | ||
62 | #define IPHETH_USBINTF_CLASS 255 | 63 | #define IPHETH_USBINTF_CLASS 255 |
63 | #define IPHETH_USBINTF_SUBCLASS 253 | 64 | #define IPHETH_USBINTF_SUBCLASS 253 |
@@ -92,6 +93,10 @@ static struct usb_device_id ipheth_table[] = { | |||
92 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, | 93 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_3GS, |
93 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | 94 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, |
94 | IPHETH_USBINTF_PROTO) }, | 95 | IPHETH_USBINTF_PROTO) }, |
96 | { USB_DEVICE_AND_INTERFACE_INFO( | ||
97 | USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4, | ||
98 | IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, | ||
99 | IPHETH_USBINTF_PROTO) }, | ||
95 | { } | 100 | { } |
96 | }; | 101 | }; |
97 | MODULE_DEVICE_TABLE(usb, ipheth_table); | 102 | MODULE_DEVICE_TABLE(usb, ipheth_table); |
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index a105087af963..f9aa1bc0a947 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -732,7 +732,7 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan) | |||
732 | 732 | ||
733 | /* Nothing to do for ADMtek BBP */ | 733 | /* Nothing to do for ADMtek BBP */ |
734 | } else if (priv->bbp_type != ADM8211_TYPE_ADMTEK) | 734 | } else if (priv->bbp_type != ADM8211_TYPE_ADMTEK) |
735 | wiphy_debug(dev->wiphy, "unsupported bbp type %d\n", | 735 | wiphy_debug(dev->wiphy, "unsupported BBP type %d\n", |
736 | priv->bbp_type); | 736 | priv->bbp_type); |
737 | 737 | ||
738 | ADM8211_RESTORE(); | 738 | ADM8211_RESTORE(); |
@@ -1032,7 +1032,7 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev) | |||
1032 | break; | 1032 | break; |
1033 | } | 1033 | } |
1034 | } else | 1034 | } else |
1035 | wiphy_debug(dev->wiphy, "unsupported bbp %d\n", priv->bbp_type); | 1035 | wiphy_debug(dev->wiphy, "unsupported BBP %d\n", priv->bbp_type); |
1036 | 1036 | ||
1037 | ADM8211_CSR_WRITE(SYNRF, 0); | 1037 | ADM8211_CSR_WRITE(SYNRF, 0); |
1038 | 1038 | ||
@@ -1525,7 +1525,7 @@ static int adm8211_start(struct ieee80211_hw *dev) | |||
1525 | retval = request_irq(priv->pdev->irq, adm8211_interrupt, | 1525 | retval = request_irq(priv->pdev->irq, adm8211_interrupt, |
1526 | IRQF_SHARED, "adm8211", dev); | 1526 | IRQF_SHARED, "adm8211", dev); |
1527 | if (retval) { | 1527 | if (retval) { |
1528 | wiphy_err(dev->wiphy, "failed to register irq handler\n"); | 1528 | wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); |
1529 | goto fail; | 1529 | goto fail; |
1530 | } | 1530 | } |
1531 | 1531 | ||
@@ -1902,7 +1902,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1902 | goto err_free_eeprom; | 1902 | goto err_free_eeprom; |
1903 | } | 1903 | } |
1904 | 1904 | ||
1905 | wiphy_info(dev->wiphy, "hwaddr %pm, rev 0x%02x\n", | 1905 | wiphy_info(dev->wiphy, "hwaddr %pM, Rev 0x%02x\n", |
1906 | dev->wiphy->perm_addr, pdev->revision); | 1906 | dev->wiphy->perm_addr, pdev->revision); |
1907 | 1907 | ||
1908 | return 0; | 1908 | return 0; |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index d5140a87f073..1128fa8c9ed5 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -655,7 +655,7 @@ static int at76_get_hw_config(struct at76_priv *priv) | |||
655 | exit: | 655 | exit: |
656 | kfree(hwcfg); | 656 | kfree(hwcfg); |
657 | if (ret < 0) | 657 | if (ret < 0) |
658 | wiphy_err(priv->hw->wiphy, "cannot get hw config (error %d)\n", | 658 | wiphy_err(priv->hw->wiphy, "cannot get HW Config (error %d)\n", |
659 | ret); | 659 | ret); |
660 | 660 | ||
661 | return ret; | 661 | return ret; |
@@ -960,7 +960,7 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv) | |||
960 | sizeof(struct mib_mac_addr)); | 960 | sizeof(struct mib_mac_addr)); |
961 | if (ret < 0) { | 961 | if (ret < 0) { |
962 | wiphy_err(priv->hw->wiphy, | 962 | wiphy_err(priv->hw->wiphy, |
963 | "at76_get_mib (mac_addr) failed: %d\n", ret); | 963 | "at76_get_mib (MAC_ADDR) failed: %d\n", ret); |
964 | goto exit; | 964 | goto exit; |
965 | } | 965 | } |
966 | 966 | ||
@@ -989,7 +989,7 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv) | |||
989 | sizeof(struct mib_mac_wep)); | 989 | sizeof(struct mib_mac_wep)); |
990 | if (ret < 0) { | 990 | if (ret < 0) { |
991 | wiphy_err(priv->hw->wiphy, | 991 | wiphy_err(priv->hw->wiphy, |
992 | "at76_get_mib (mac_wep) failed: %d\n", ret); | 992 | "at76_get_mib (MAC_WEP) failed: %d\n", ret); |
993 | goto exit; | 993 | goto exit; |
994 | } | 994 | } |
995 | 995 | ||
@@ -1026,7 +1026,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv) | |||
1026 | sizeof(struct mib_mac_mgmt)); | 1026 | sizeof(struct mib_mac_mgmt)); |
1027 | if (ret < 0) { | 1027 | if (ret < 0) { |
1028 | wiphy_err(priv->hw->wiphy, | 1028 | wiphy_err(priv->hw->wiphy, |
1029 | "at76_get_mib (mac_mgmt) failed: %d\n", ret); | 1029 | "at76_get_mib (MAC_MGMT) failed: %d\n", ret); |
1030 | goto exit; | 1030 | goto exit; |
1031 | } | 1031 | } |
1032 | 1032 | ||
@@ -1062,7 +1062,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv) | |||
1062 | ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); | 1062 | ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac)); |
1063 | if (ret < 0) { | 1063 | if (ret < 0) { |
1064 | wiphy_err(priv->hw->wiphy, | 1064 | wiphy_err(priv->hw->wiphy, |
1065 | "at76_get_mib (mac) failed: %d\n", ret); | 1065 | "at76_get_mib (MAC) failed: %d\n", ret); |
1066 | goto exit; | 1066 | goto exit; |
1067 | } | 1067 | } |
1068 | 1068 | ||
@@ -1099,7 +1099,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv) | |||
1099 | ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); | 1099 | ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy)); |
1100 | if (ret < 0) { | 1100 | if (ret < 0) { |
1101 | wiphy_err(priv->hw->wiphy, | 1101 | wiphy_err(priv->hw->wiphy, |
1102 | "at76_get_mib (phy) failed: %d\n", ret); | 1102 | "at76_get_mib (PHY) failed: %d\n", ret); |
1103 | goto exit; | 1103 | goto exit; |
1104 | } | 1104 | } |
1105 | 1105 | ||
@@ -1132,7 +1132,7 @@ static void at76_dump_mib_local(struct at76_priv *priv) | |||
1132 | ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); | 1132 | ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); |
1133 | if (ret < 0) { | 1133 | if (ret < 0) { |
1134 | wiphy_err(priv->hw->wiphy, | 1134 | wiphy_err(priv->hw->wiphy, |
1135 | "at76_get_mib (local) failed: %d\n", ret); | 1135 | "at76_get_mib (LOCAL) failed: %d\n", ret); |
1136 | goto exit; | 1136 | goto exit; |
1137 | } | 1137 | } |
1138 | 1138 | ||
@@ -1158,7 +1158,7 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv) | |||
1158 | sizeof(struct mib_mdomain)); | 1158 | sizeof(struct mib_mdomain)); |
1159 | if (ret < 0) { | 1159 | if (ret < 0) { |
1160 | wiphy_err(priv->hw->wiphy, | 1160 | wiphy_err(priv->hw->wiphy, |
1161 | "at76_get_mib (mdomain) failed: %d\n", ret); | 1161 | "at76_get_mib (MDOMAIN) failed: %d\n", ret); |
1162 | goto exit; | 1162 | goto exit; |
1163 | } | 1163 | } |
1164 | 1164 | ||
@@ -1229,7 +1229,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv) | |||
1229 | struct sk_buff *skb = priv->rx_skb; | 1229 | struct sk_buff *skb = priv->rx_skb; |
1230 | 1230 | ||
1231 | if (!priv->rx_urb) { | 1231 | if (!priv->rx_urb) { |
1232 | wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is null\n", | 1232 | wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is NULL\n", |
1233 | __func__); | 1233 | __func__); |
1234 | return -EFAULT; | 1234 | return -EFAULT; |
1235 | } | 1235 | } |
@@ -1792,7 +1792,7 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1792 | wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret); | 1792 | wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret); |
1793 | if (ret == -EINVAL) | 1793 | if (ret == -EINVAL) |
1794 | wiphy_err(priv->hw->wiphy, | 1794 | wiphy_err(priv->hw->wiphy, |
1795 | "-einval: tx urb %p hcpriv %p complete %p\n", | 1795 | "-EINVAL: tx urb %p hcpriv %p complete %p\n", |
1796 | priv->tx_urb, | 1796 | priv->tx_urb, |
1797 | priv->tx_urb->hcpriv, priv->tx_urb->complete); | 1797 | priv->tx_urb->hcpriv, priv->tx_urb->complete); |
1798 | } | 1798 | } |
@@ -2310,7 +2310,7 @@ static int at76_init_new_device(struct at76_priv *priv, | |||
2310 | 2310 | ||
2311 | priv->mac80211_registered = 1; | 2311 | priv->mac80211_registered = 1; |
2312 | 2312 | ||
2313 | wiphy_info(priv->hw->wiphy, "usb %s, mac %pm, firmware %d.%d.%d-%d\n", | 2313 | wiphy_info(priv->hw->wiphy, "USB %s, MAC %pM, firmware %d.%d.%d-%d\n", |
2314 | dev_name(&interface->dev), priv->mac_addr, | 2314 | dev_name(&interface->dev), priv->mac_addr, |
2315 | priv->fw_version.major, priv->fw_version.minor, | 2315 | priv->fw_version.major, priv->fw_version.minor, |
2316 | priv->fw_version.patch, priv->fw_version.build); | 2316 | priv->fw_version.patch, priv->fw_version.build); |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index c67b05f3bcbd..debfb0fbc7c5 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -245,7 +245,7 @@ static void __ar9170_dump_txstats(struct ar9170 *ar) | |||
245 | { | 245 | { |
246 | int i; | 246 | int i; |
247 | 247 | ||
248 | wiphy_debug(ar->hw->wiphy, "qos queue stats\n"); | 248 | wiphy_debug(ar->hw->wiphy, "QoS queue stats\n"); |
249 | 249 | ||
250 | for (i = 0; i < __AR9170_NUM_TXQ; i++) | 250 | for (i = 0; i < __AR9170_NUM_TXQ; i++) |
251 | wiphy_debug(ar->hw->wiphy, | 251 | wiphy_debug(ar->hw->wiphy, |
@@ -387,7 +387,7 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, | |||
387 | if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { | 387 | if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) { |
388 | #ifdef AR9170_QUEUE_DEBUG | 388 | #ifdef AR9170_QUEUE_DEBUG |
389 | wiphy_debug(ar->hw->wiphy, | 389 | wiphy_debug(ar->hw->wiphy, |
390 | "skip frame => da %pm != %pm\n", | 390 | "skip frame => DA %pM != %pM\n", |
391 | mac, ieee80211_get_DA(hdr)); | 391 | mac, ieee80211_get_DA(hdr)); |
392 | ar9170_print_txheader(ar, skb); | 392 | ar9170_print_txheader(ar, skb); |
393 | #endif /* AR9170_QUEUE_DEBUG */ | 393 | #endif /* AR9170_QUEUE_DEBUG */ |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 0d5de2574dd1..373dcfec689c 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/netdevice.h> | 48 | #include <linux/netdevice.h> |
49 | #include <linux/cache.h> | 49 | #include <linux/cache.h> |
50 | #include <linux/pci.h> | 50 | #include <linux/pci.h> |
51 | #include <linux/pci-aspm.h> | ||
51 | #include <linux/ethtool.h> | 52 | #include <linux/ethtool.h> |
52 | #include <linux/uaccess.h> | 53 | #include <linux/uaccess.h> |
53 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
@@ -476,6 +477,26 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
476 | int ret; | 477 | int ret; |
477 | u8 csz; | 478 | u8 csz; |
478 | 479 | ||
480 | /* | ||
481 | * L0s needs to be disabled on all ath5k cards. | ||
482 | * | ||
483 | * For distributions shipping with CONFIG_PCIEASPM (this will be enabled | ||
484 | * by default in the future in 2.6.36) this will also mean both L1 and | ||
485 | * L0s will be disabled when a pre 1.1 PCIe device is detected. We do | ||
486 | * know L1 works correctly even for all ath5k pre 1.1 PCIe devices | ||
487 | * though but cannot currently undue the effect of a blacklist, for | ||
488 | * details you can read pcie_aspm_sanity_check() and see how it adjusts | ||
489 | * the device link capability. | ||
490 | * | ||
491 | * It may be possible in the future to implement some PCI API to allow | ||
492 | * drivers to override blacklists for pre 1.1 PCIe but for now it is | ||
493 | * best to accept that both L0s and L1 will be disabled completely for | ||
494 | * distributions shipping with CONFIG_PCIEASPM rather than having this | ||
495 | * issue present. Motivation for adding this new API will be to help | ||
496 | * with power consumption for some of these devices. | ||
497 | */ | ||
498 | pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S); | ||
499 | |||
479 | ret = pci_enable_device(pdev); | 500 | ret = pci_enable_device(pdev); |
480 | if (ret) { | 501 | if (ret) { |
481 | dev_err(&pdev->dev, "can't enable device\n"); | 502 | dev_err(&pdev->dev, "can't enable device\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 8750c558c221..7f48df1e2903 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -191,6 +191,7 @@ | |||
191 | #define AR9287_EEP_NO_BACK_VER AR9287_EEP_MINOR_VER_1 | 191 | #define AR9287_EEP_NO_BACK_VER AR9287_EEP_MINOR_VER_1 |
192 | 192 | ||
193 | #define AR9287_EEP_START_LOC 128 | 193 | #define AR9287_EEP_START_LOC 128 |
194 | #define AR9287_HTC_EEP_START_LOC 256 | ||
194 | #define AR9287_NUM_2G_CAL_PIERS 3 | 195 | #define AR9287_NUM_2G_CAL_PIERS 3 |
195 | #define AR9287_NUM_2G_CCK_TARGET_POWERS 3 | 196 | #define AR9287_NUM_2G_CCK_TARGET_POWERS 3 |
196 | #define AR9287_NUM_2G_20_TARGET_POWERS 3 | 197 | #define AR9287_NUM_2G_20_TARGET_POWERS 3 |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 4a52cf03808b..dff2da777312 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -34,9 +34,14 @@ static bool ath9k_hw_ar9287_fill_eeprom(struct ath_hw *ah) | |||
34 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; | 34 | struct ar9287_eeprom *eep = &ah->eeprom.map9287; |
35 | struct ath_common *common = ath9k_hw_common(ah); | 35 | struct ath_common *common = ath9k_hw_common(ah); |
36 | u16 *eep_data; | 36 | u16 *eep_data; |
37 | int addr, eep_start_loc = AR9287_EEP_START_LOC; | 37 | int addr, eep_start_loc; |
38 | eep_data = (u16 *)eep; | 38 | eep_data = (u16 *)eep; |
39 | 39 | ||
40 | if (ah->hw_version.devid == 0x7015) | ||
41 | eep_start_loc = AR9287_HTC_EEP_START_LOC; | ||
42 | else | ||
43 | eep_start_loc = AR9287_EEP_START_LOC; | ||
44 | |||
40 | if (!ath9k_hw_use_flash(ah)) { | 45 | if (!ath9k_hw_use_flash(ah)) { |
41 | ath_print(common, ATH_DBG_EEPROM, | 46 | ath_print(common, ATH_DBG_EEPROM, |
42 | "Reading from EEPROM, not flash\n"); | 47 | "Reading from EEPROM, not flash\n"); |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 61c1bee3f26a..17e7a9a367e7 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -799,7 +799,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) | |||
799 | } | 799 | } |
800 | kfree(buf); | 800 | kfree(buf); |
801 | 801 | ||
802 | if (hif_dev->device_id == 0x7010) | 802 | if ((hif_dev->device_id == 0x7010) || (hif_dev->device_id == 0x7015)) |
803 | firm_offset = AR7010_FIRMWARE_TEXT; | 803 | firm_offset = AR7010_FIRMWARE_TEXT; |
804 | else | 804 | else |
805 | firm_offset = AR9271_FIRMWARE_TEXT; | 805 | firm_offset = AR9271_FIRMWARE_TEXT; |
@@ -901,6 +901,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, | |||
901 | 901 | ||
902 | switch(hif_dev->device_id) { | 902 | switch(hif_dev->device_id) { |
903 | case 0x7010: | 903 | case 0x7010: |
904 | case 0x7015: | ||
904 | case 0x9018: | 905 | case 0x9018: |
905 | if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) | 906 | if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202) |
906 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; | 907 | hif_dev->fw_name = FIRMWARE_AR7010_1_1; |
@@ -912,11 +913,6 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, | |||
912 | break; | 913 | break; |
913 | } | 914 | } |
914 | 915 | ||
915 | if (!hif_dev->fw_name) { | ||
916 | dev_err(&udev->dev, "Can't determine firmware !\n"); | ||
917 | goto err_htc_hw_alloc; | ||
918 | } | ||
919 | |||
920 | ret = ath9k_hif_usb_dev_init(hif_dev); | 916 | ret = ath9k_hif_usb_dev_init(hif_dev); |
921 | if (ret) { | 917 | if (ret) { |
922 | ret = -EINVAL; | 918 | ret = -EINVAL; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 148b43317fdb..2d4279191d7a 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -245,6 +245,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid) | |||
245 | 245 | ||
246 | switch(devid) { | 246 | switch(devid) { |
247 | case 0x7010: | 247 | case 0x7010: |
248 | case 0x7015: | ||
248 | case 0x9018: | 249 | case 0x9018: |
249 | priv->htc->credits = 45; | 250 | priv->htc->credits = 45; |
250 | break; | 251 | break; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ebed9d1691a5..7d09b4b17bbd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -366,7 +366,8 @@ static void ath9k_htc_setup_rate(struct ath9k_htc_priv *priv, | |||
366 | caps = WLAN_RC_HT_FLAG; | 366 | caps = WLAN_RC_HT_FLAG; |
367 | if (sta->ht_cap.mcs.rx_mask[1]) | 367 | if (sta->ht_cap.mcs.rx_mask[1]) |
368 | caps |= WLAN_RC_DS_FLAG; | 368 | caps |= WLAN_RC_DS_FLAG; |
369 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | 369 | if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) && |
370 | (conf_is_ht40(&priv->hw->conf))) | ||
370 | caps |= WLAN_RC_40_FLAG; | 371 | caps |= WLAN_RC_40_FLAG; |
371 | if (conf_is_ht40(&priv->hw->conf) && | 372 | if (conf_is_ht40(&priv->hw->conf) && |
372 | (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) | 373 | (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index bd0b4acc3ece..2a6e45a293a9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -78,18 +78,23 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
78 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 78 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
79 | struct ieee80211_sta *sta = tx_info->control.sta; | 79 | struct ieee80211_sta *sta = tx_info->control.sta; |
80 | struct ath9k_htc_sta *ista; | 80 | struct ath9k_htc_sta *ista; |
81 | struct ath9k_htc_vif *avp; | ||
82 | struct ath9k_htc_tx_ctl tx_ctl; | 81 | struct ath9k_htc_tx_ctl tx_ctl; |
83 | enum htc_endpoint_id epid; | 82 | enum htc_endpoint_id epid; |
84 | u16 qnum; | 83 | u16 qnum; |
85 | __le16 fc; | 84 | __le16 fc; |
86 | u8 *tx_fhdr; | 85 | u8 *tx_fhdr; |
87 | u8 sta_idx; | 86 | u8 sta_idx, vif_idx; |
88 | 87 | ||
89 | hdr = (struct ieee80211_hdr *) skb->data; | 88 | hdr = (struct ieee80211_hdr *) skb->data; |
90 | fc = hdr->frame_control; | 89 | fc = hdr->frame_control; |
91 | 90 | ||
92 | avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv; | 91 | if (tx_info->control.vif && |
92 | (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv) | ||
93 | vif_idx = ((struct ath9k_htc_vif *) | ||
94 | tx_info->control.vif->drv_priv)->index; | ||
95 | else | ||
96 | vif_idx = priv->nvifs; | ||
97 | |||
93 | if (sta) { | 98 | if (sta) { |
94 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | 99 | ista = (struct ath9k_htc_sta *) sta->drv_priv; |
95 | sta_idx = ista->index; | 100 | sta_idx = ista->index; |
@@ -106,7 +111,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
106 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); | 111 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); |
107 | 112 | ||
108 | tx_hdr.node_idx = sta_idx; | 113 | tx_hdr.node_idx = sta_idx; |
109 | tx_hdr.vif_idx = avp->index; | 114 | tx_hdr.vif_idx = vif_idx; |
110 | 115 | ||
111 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 116 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { |
112 | tx_ctl.type = ATH9K_HTC_AMPDU; | 117 | tx_ctl.type = ATH9K_HTC_AMPDU; |
@@ -169,7 +174,7 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | |||
169 | tx_ctl.type = ATH9K_HTC_NORMAL; | 174 | tx_ctl.type = ATH9K_HTC_NORMAL; |
170 | 175 | ||
171 | mgmt_hdr.node_idx = sta_idx; | 176 | mgmt_hdr.node_idx = sta_idx; |
172 | mgmt_hdr.vif_idx = avp->index; | 177 | mgmt_hdr.vif_idx = vif_idx; |
173 | mgmt_hdr.tidno = 0; | 178 | mgmt_hdr.tidno = 0; |
174 | mgmt_hdr.flags = 0; | 179 | mgmt_hdr.flags = 0; |
175 | 180 | ||
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 633e3d949ec0..d01c4adab8d6 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -899,6 +899,7 @@ | |||
899 | 899 | ||
900 | #define AR_DEVID_7010(_ah) \ | 900 | #define AR_DEVID_7010(_ah) \ |
901 | (((_ah)->hw_version.devid == 0x7010) || \ | 901 | (((_ah)->hw_version.devid == 0x7010) || \ |
902 | ((_ah)->hw_version.devid == 0x7015) || \ | ||
902 | ((_ah)->hw_version.devid == 0x9018)) | 903 | ((_ah)->hw_version.devid == 0x9018)) |
903 | 904 | ||
904 | #define AR_RADIO_SREV_MAJOR 0xf0 | 905 | #define AR_RADIO_SREV_MAJOR 0xf0 |
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index 16bbfa3189a5..996e9d7d7586 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c | |||
@@ -2723,14 +2723,6 @@ static void __ipw2100_rx_process(struct ipw2100_priv *priv) | |||
2723 | 2723 | ||
2724 | packet = &priv->rx_buffers[i]; | 2724 | packet = &priv->rx_buffers[i]; |
2725 | 2725 | ||
2726 | /* Sync the DMA for the STATUS buffer so CPU is sure to get | ||
2727 | * the correct values */ | ||
2728 | pci_dma_sync_single_for_cpu(priv->pci_dev, | ||
2729 | sq->nic + | ||
2730 | sizeof(struct ipw2100_status) * i, | ||
2731 | sizeof(struct ipw2100_status), | ||
2732 | PCI_DMA_FROMDEVICE); | ||
2733 | |||
2734 | /* Sync the DMA for the RX buffer so CPU is sure to get | 2726 | /* Sync the DMA for the RX buffer so CPU is sure to get |
2735 | * the correct values */ | 2727 | * the correct values */ |
2736 | pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr, | 2728 | pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr, |
@@ -6665,12 +6657,13 @@ static int __init ipw2100_init(void) | |||
6665 | printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); | 6657 | printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION); |
6666 | printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); | 6658 | printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT); |
6667 | 6659 | ||
6660 | pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, | ||
6661 | PM_QOS_DEFAULT_VALUE); | ||
6662 | |||
6668 | ret = pci_register_driver(&ipw2100_pci_driver); | 6663 | ret = pci_register_driver(&ipw2100_pci_driver); |
6669 | if (ret) | 6664 | if (ret) |
6670 | goto out; | 6665 | goto out; |
6671 | 6666 | ||
6672 | pm_qos_add_request(&ipw2100_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, | ||
6673 | PM_QOS_DEFAULT_VALUE); | ||
6674 | #ifdef CONFIG_IPW2100_DEBUG | 6667 | #ifdef CONFIG_IPW2100_DEBUG |
6675 | ipw2100_debug_level = debug; | 6668 | ipw2100_debug_level = debug; |
6676 | ret = driver_create_file(&ipw2100_pci_driver.driver, | 6669 | ret = driver_create_file(&ipw2100_pci_driver.driver, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index fec026212326..0b779a41a142 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -265,7 +265,7 @@ struct iwl_cfg iwl1000_bgn_cfg = { | |||
265 | .support_ct_kill_exit = true, | 265 | .support_ct_kill_exit = true, |
266 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, | 266 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
267 | .chain_noise_scale = 1000, | 267 | .chain_noise_scale = 1000, |
268 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 268 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
269 | .max_event_log_size = 128, | 269 | .max_event_log_size = 128, |
270 | .ucode_tracing = true, | 270 | .ucode_tracing = true, |
271 | .sensitivity_calib_by_driver = true, | 271 | .sensitivity_calib_by_driver = true, |
@@ -297,7 +297,7 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
297 | .support_ct_kill_exit = true, | 297 | .support_ct_kill_exit = true, |
298 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, | 298 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF, |
299 | .chain_noise_scale = 1000, | 299 | .chain_noise_scale = 1000, |
300 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 300 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
301 | .max_event_log_size = 128, | 301 | .max_event_log_size = 128, |
302 | .ucode_tracing = true, | 302 | .ucode_tracing = true, |
303 | .sensitivity_calib_by_driver = true, | 303 | .sensitivity_calib_by_driver = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 6950a783913b..8ccfcd08218d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -2731,7 +2731,7 @@ static struct iwl_cfg iwl3945_bg_cfg = { | |||
2731 | .led_compensation = 64, | 2731 | .led_compensation = 64, |
2732 | .broken_powersave = true, | 2732 | .broken_powersave = true, |
2733 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 2733 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
2734 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 2734 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
2735 | .max_event_log_size = 512, | 2735 | .max_event_log_size = 512, |
2736 | .tx_power_by_driver = true, | 2736 | .tx_power_by_driver = true, |
2737 | }; | 2737 | }; |
@@ -2752,7 +2752,7 @@ static struct iwl_cfg iwl3945_abg_cfg = { | |||
2752 | .led_compensation = 64, | 2752 | .led_compensation = 64, |
2753 | .broken_powersave = true, | 2753 | .broken_powersave = true, |
2754 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 2754 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
2755 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 2755 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
2756 | .max_event_log_size = 512, | 2756 | .max_event_log_size = 512, |
2757 | .tx_power_by_driver = true, | 2757 | .tx_power_by_driver = true, |
2758 | }; | 2758 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index d6da356608fa..d92b72909233 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2322,7 +2322,7 @@ struct iwl_cfg iwl4965_agn_cfg = { | |||
2322 | .led_compensation = 61, | 2322 | .led_compensation = 61, |
2323 | .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, | 2323 | .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS, |
2324 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 2324 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
2325 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 2325 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
2326 | .temperature_kelvin = true, | 2326 | .temperature_kelvin = true, |
2327 | .max_event_log_size = 512, | 2327 | .max_event_log_size = 512, |
2328 | .tx_power_by_driver = true, | 2328 | .tx_power_by_driver = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index aacf3770f075..48bdcd8d2e94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -510,7 +510,7 @@ struct iwl_cfg iwl5300_agn_cfg = { | |||
510 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 510 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
511 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 511 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
512 | .chain_noise_scale = 1000, | 512 | .chain_noise_scale = 1000, |
513 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 513 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
514 | .max_event_log_size = 512, | 514 | .max_event_log_size = 512, |
515 | .ucode_tracing = true, | 515 | .ucode_tracing = true, |
516 | .sensitivity_calib_by_driver = true, | 516 | .sensitivity_calib_by_driver = true, |
@@ -541,7 +541,7 @@ struct iwl_cfg iwl5100_bgn_cfg = { | |||
541 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 541 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
542 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 542 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
543 | .chain_noise_scale = 1000, | 543 | .chain_noise_scale = 1000, |
544 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 544 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
545 | .max_event_log_size = 512, | 545 | .max_event_log_size = 512, |
546 | .ucode_tracing = true, | 546 | .ucode_tracing = true, |
547 | .sensitivity_calib_by_driver = true, | 547 | .sensitivity_calib_by_driver = true, |
@@ -570,7 +570,7 @@ struct iwl_cfg iwl5100_abg_cfg = { | |||
570 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 570 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
571 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 571 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
572 | .chain_noise_scale = 1000, | 572 | .chain_noise_scale = 1000, |
573 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 573 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
574 | .max_event_log_size = 512, | 574 | .max_event_log_size = 512, |
575 | .ucode_tracing = true, | 575 | .ucode_tracing = true, |
576 | .sensitivity_calib_by_driver = true, | 576 | .sensitivity_calib_by_driver = true, |
@@ -601,7 +601,7 @@ struct iwl_cfg iwl5100_agn_cfg = { | |||
601 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 601 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
602 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 602 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
603 | .chain_noise_scale = 1000, | 603 | .chain_noise_scale = 1000, |
604 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 604 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
605 | .max_event_log_size = 512, | 605 | .max_event_log_size = 512, |
606 | .ucode_tracing = true, | 606 | .ucode_tracing = true, |
607 | .sensitivity_calib_by_driver = true, | 607 | .sensitivity_calib_by_driver = true, |
@@ -632,7 +632,7 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
632 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 632 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
633 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 633 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
634 | .chain_noise_scale = 1000, | 634 | .chain_noise_scale = 1000, |
635 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 635 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
636 | .max_event_log_size = 512, | 636 | .max_event_log_size = 512, |
637 | .ucode_tracing = true, | 637 | .ucode_tracing = true, |
638 | .sensitivity_calib_by_driver = true, | 638 | .sensitivity_calib_by_driver = true, |
@@ -663,7 +663,7 @@ struct iwl_cfg iwl5150_agn_cfg = { | |||
663 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 663 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
664 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 664 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
665 | .chain_noise_scale = 1000, | 665 | .chain_noise_scale = 1000, |
666 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 666 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
667 | .max_event_log_size = 512, | 667 | .max_event_log_size = 512, |
668 | .ucode_tracing = true, | 668 | .ucode_tracing = true, |
669 | .sensitivity_calib_by_driver = true, | 669 | .sensitivity_calib_by_driver = true, |
@@ -693,7 +693,7 @@ struct iwl_cfg iwl5150_abg_cfg = { | |||
693 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, | 693 | .chain_noise_num_beacons = IWL_CAL_NUM_BEACONS, |
694 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, | 694 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF, |
695 | .chain_noise_scale = 1000, | 695 | .chain_noise_scale = 1000, |
696 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 696 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
697 | .max_event_log_size = 512, | 697 | .max_event_log_size = 512, |
698 | .ucode_tracing = true, | 698 | .ucode_tracing = true, |
699 | .sensitivity_calib_by_driver = true, | 699 | .sensitivity_calib_by_driver = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index af4fd50f3405..cee06b968de8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -388,7 +388,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { | |||
388 | .support_ct_kill_exit = true, | 388 | .support_ct_kill_exit = true, |
389 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 389 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
390 | .chain_noise_scale = 1000, | 390 | .chain_noise_scale = 1000, |
391 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 391 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
392 | .max_event_log_size = 512, | 392 | .max_event_log_size = 512, |
393 | .ucode_tracing = true, | 393 | .ucode_tracing = true, |
394 | .sensitivity_calib_by_driver = true, | 394 | .sensitivity_calib_by_driver = true, |
@@ -424,7 +424,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { | |||
424 | .support_ct_kill_exit = true, | 424 | .support_ct_kill_exit = true, |
425 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 425 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
426 | .chain_noise_scale = 1000, | 426 | .chain_noise_scale = 1000, |
427 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 427 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
428 | .max_event_log_size = 512, | 428 | .max_event_log_size = 512, |
429 | .sensitivity_calib_by_driver = true, | 429 | .sensitivity_calib_by_driver = true, |
430 | .chain_noise_calib_by_driver = true, | 430 | .chain_noise_calib_by_driver = true, |
@@ -459,7 +459,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { | |||
459 | .support_ct_kill_exit = true, | 459 | .support_ct_kill_exit = true, |
460 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 460 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
461 | .chain_noise_scale = 1000, | 461 | .chain_noise_scale = 1000, |
462 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 462 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
463 | .max_event_log_size = 512, | 463 | .max_event_log_size = 512, |
464 | .sensitivity_calib_by_driver = true, | 464 | .sensitivity_calib_by_driver = true, |
465 | .chain_noise_calib_by_driver = true, | 465 | .chain_noise_calib_by_driver = true, |
@@ -496,7 +496,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { | |||
496 | .support_ct_kill_exit = true, | 496 | .support_ct_kill_exit = true, |
497 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 497 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
498 | .chain_noise_scale = 1000, | 498 | .chain_noise_scale = 1000, |
499 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 499 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
500 | .max_event_log_size = 512, | 500 | .max_event_log_size = 512, |
501 | .sensitivity_calib_by_driver = true, | 501 | .sensitivity_calib_by_driver = true, |
502 | .chain_noise_calib_by_driver = true, | 502 | .chain_noise_calib_by_driver = true, |
@@ -532,7 +532,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { | |||
532 | .support_ct_kill_exit = true, | 532 | .support_ct_kill_exit = true, |
533 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 533 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
534 | .chain_noise_scale = 1000, | 534 | .chain_noise_scale = 1000, |
535 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 535 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
536 | .max_event_log_size = 512, | 536 | .max_event_log_size = 512, |
537 | .sensitivity_calib_by_driver = true, | 537 | .sensitivity_calib_by_driver = true, |
538 | .chain_noise_calib_by_driver = true, | 538 | .chain_noise_calib_by_driver = true, |
@@ -570,7 +570,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { | |||
570 | .support_ct_kill_exit = true, | 570 | .support_ct_kill_exit = true, |
571 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 571 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
572 | .chain_noise_scale = 1000, | 572 | .chain_noise_scale = 1000, |
573 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 573 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
574 | .max_event_log_size = 512, | 574 | .max_event_log_size = 512, |
575 | .sensitivity_calib_by_driver = true, | 575 | .sensitivity_calib_by_driver = true, |
576 | .chain_noise_calib_by_driver = true, | 576 | .chain_noise_calib_by_driver = true, |
@@ -606,7 +606,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { | |||
606 | .support_ct_kill_exit = true, | 606 | .support_ct_kill_exit = true, |
607 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 607 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
608 | .chain_noise_scale = 1000, | 608 | .chain_noise_scale = 1000, |
609 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 609 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
610 | .max_event_log_size = 512, | 610 | .max_event_log_size = 512, |
611 | .sensitivity_calib_by_driver = true, | 611 | .sensitivity_calib_by_driver = true, |
612 | .chain_noise_calib_by_driver = true, | 612 | .chain_noise_calib_by_driver = true, |
@@ -644,7 +644,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { | |||
644 | .support_ct_kill_exit = true, | 644 | .support_ct_kill_exit = true, |
645 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 645 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
646 | .chain_noise_scale = 1000, | 646 | .chain_noise_scale = 1000, |
647 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 647 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
648 | .max_event_log_size = 512, | 648 | .max_event_log_size = 512, |
649 | .sensitivity_calib_by_driver = true, | 649 | .sensitivity_calib_by_driver = true, |
650 | .chain_noise_calib_by_driver = true, | 650 | .chain_noise_calib_by_driver = true, |
@@ -680,7 +680,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { | |||
680 | .support_ct_kill_exit = true, | 680 | .support_ct_kill_exit = true, |
681 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 681 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
682 | .chain_noise_scale = 1000, | 682 | .chain_noise_scale = 1000, |
683 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 683 | .monitor_recover_period = IWL_LONG_MONITORING_PERIOD, |
684 | .max_event_log_size = 512, | 684 | .max_event_log_size = 512, |
685 | .sensitivity_calib_by_driver = true, | 685 | .sensitivity_calib_by_driver = true, |
686 | .chain_noise_calib_by_driver = true, | 686 | .chain_noise_calib_by_driver = true, |
@@ -721,7 +721,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = { | |||
721 | .support_ct_kill_exit = true, | 721 | .support_ct_kill_exit = true, |
722 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 722 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
723 | .chain_noise_scale = 1000, | 723 | .chain_noise_scale = 1000, |
724 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 724 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
725 | .max_event_log_size = 1024, | 725 | .max_event_log_size = 1024, |
726 | .ucode_tracing = true, | 726 | .ucode_tracing = true, |
727 | .sensitivity_calib_by_driver = true, | 727 | .sensitivity_calib_by_driver = true, |
@@ -756,7 +756,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = { | |||
756 | .support_ct_kill_exit = true, | 756 | .support_ct_kill_exit = true, |
757 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 757 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
758 | .chain_noise_scale = 1000, | 758 | .chain_noise_scale = 1000, |
759 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 759 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
760 | .max_event_log_size = 1024, | 760 | .max_event_log_size = 1024, |
761 | .ucode_tracing = true, | 761 | .ucode_tracing = true, |
762 | .sensitivity_calib_by_driver = true, | 762 | .sensitivity_calib_by_driver = true, |
@@ -791,7 +791,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
791 | .support_ct_kill_exit = true, | 791 | .support_ct_kill_exit = true, |
792 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 792 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
793 | .chain_noise_scale = 1000, | 793 | .chain_noise_scale = 1000, |
794 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 794 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
795 | .max_event_log_size = 1024, | 795 | .max_event_log_size = 1024, |
796 | .ucode_tracing = true, | 796 | .ucode_tracing = true, |
797 | .sensitivity_calib_by_driver = true, | 797 | .sensitivity_calib_by_driver = true, |
@@ -828,7 +828,7 @@ struct iwl_cfg iwl6050_2agn_cfg = { | |||
828 | .support_ct_kill_exit = true, | 828 | .support_ct_kill_exit = true, |
829 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 829 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
830 | .chain_noise_scale = 1500, | 830 | .chain_noise_scale = 1500, |
831 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 831 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
832 | .max_event_log_size = 1024, | 832 | .max_event_log_size = 1024, |
833 | .ucode_tracing = true, | 833 | .ucode_tracing = true, |
834 | .sensitivity_calib_by_driver = true, | 834 | .sensitivity_calib_by_driver = true, |
@@ -866,7 +866,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { | |||
866 | .support_ct_kill_exit = true, | 866 | .support_ct_kill_exit = true, |
867 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 867 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
868 | .chain_noise_scale = 1500, | 868 | .chain_noise_scale = 1500, |
869 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 869 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
870 | .max_event_log_size = 1024, | 870 | .max_event_log_size = 1024, |
871 | .ucode_tracing = true, | 871 | .ucode_tracing = true, |
872 | .sensitivity_calib_by_driver = true, | 872 | .sensitivity_calib_by_driver = true, |
@@ -902,7 +902,7 @@ struct iwl_cfg iwl6050_2abg_cfg = { | |||
902 | .support_ct_kill_exit = true, | 902 | .support_ct_kill_exit = true, |
903 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 903 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
904 | .chain_noise_scale = 1500, | 904 | .chain_noise_scale = 1500, |
905 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 905 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
906 | .max_event_log_size = 1024, | 906 | .max_event_log_size = 1024, |
907 | .ucode_tracing = true, | 907 | .ucode_tracing = true, |
908 | .sensitivity_calib_by_driver = true, | 908 | .sensitivity_calib_by_driver = true, |
@@ -940,7 +940,7 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
940 | .support_ct_kill_exit = true, | 940 | .support_ct_kill_exit = true, |
941 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, | 941 | .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF, |
942 | .chain_noise_scale = 1000, | 942 | .chain_noise_scale = 1000, |
943 | .monitor_recover_period = IWL_MONITORING_PERIOD, | 943 | .monitor_recover_period = IWL_DEF_MONITORING_PERIOD, |
944 | .max_event_log_size = 1024, | 944 | .max_event_log_size = 1024, |
945 | .ucode_tracing = true, | 945 | .ucode_tracing = true, |
946 | .sensitivity_calib_by_driver = true, | 946 | .sensitivity_calib_by_driver = true, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c1882fd8345d..10d7b9b7f064 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -3667,6 +3667,49 @@ out_exit: | |||
3667 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3667 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
3668 | } | 3668 | } |
3669 | 3669 | ||
3670 | static void iwlagn_configure_filter(struct ieee80211_hw *hw, | ||
3671 | unsigned int changed_flags, | ||
3672 | unsigned int *total_flags, | ||
3673 | u64 multicast) | ||
3674 | { | ||
3675 | struct iwl_priv *priv = hw->priv; | ||
3676 | __le32 filter_or = 0, filter_nand = 0; | ||
3677 | |||
3678 | #define CHK(test, flag) do { \ | ||
3679 | if (*total_flags & (test)) \ | ||
3680 | filter_or |= (flag); \ | ||
3681 | else \ | ||
3682 | filter_nand |= (flag); \ | ||
3683 | } while (0) | ||
3684 | |||
3685 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
3686 | changed_flags, *total_flags); | ||
3687 | |||
3688 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
3689 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); | ||
3690 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
3691 | |||
3692 | #undef CHK | ||
3693 | |||
3694 | mutex_lock(&priv->mutex); | ||
3695 | |||
3696 | priv->staging_rxon.filter_flags &= ~filter_nand; | ||
3697 | priv->staging_rxon.filter_flags |= filter_or; | ||
3698 | |||
3699 | iwlcore_commit_rxon(priv); | ||
3700 | |||
3701 | mutex_unlock(&priv->mutex); | ||
3702 | |||
3703 | /* | ||
3704 | * Receiving all multicast frames is always enabled by the | ||
3705 | * default flags setup in iwl_connection_init_rx_config() | ||
3706 | * since we currently do not support programming multicast | ||
3707 | * filters into the device. | ||
3708 | */ | ||
3709 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
3710 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
3711 | } | ||
3712 | |||
3670 | static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop) | 3713 | static void iwl_mac_flush(struct ieee80211_hw *hw, bool drop) |
3671 | { | 3714 | { |
3672 | struct iwl_priv *priv = hw->priv; | 3715 | struct iwl_priv *priv = hw->priv; |
@@ -3867,7 +3910,7 @@ static struct ieee80211_ops iwl_hw_ops = { | |||
3867 | .add_interface = iwl_mac_add_interface, | 3910 | .add_interface = iwl_mac_add_interface, |
3868 | .remove_interface = iwl_mac_remove_interface, | 3911 | .remove_interface = iwl_mac_remove_interface, |
3869 | .config = iwl_mac_config, | 3912 | .config = iwl_mac_config, |
3870 | .configure_filter = iwl_configure_filter, | 3913 | .configure_filter = iwlagn_configure_filter, |
3871 | .set_key = iwl_mac_set_key, | 3914 | .set_key = iwl_mac_set_key, |
3872 | .update_tkip_key = iwl_mac_update_tkip_key, | 3915 | .update_tkip_key = iwl_mac_update_tkip_key, |
3873 | .conf_tx = iwl_mac_conf_tx, | 3916 | .conf_tx = iwl_mac_conf_tx, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2c03c6e20a72..07dbc2796448 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1328,51 +1328,6 @@ out: | |||
1328 | EXPORT_SYMBOL(iwl_apm_init); | 1328 | EXPORT_SYMBOL(iwl_apm_init); |
1329 | 1329 | ||
1330 | 1330 | ||
1331 | |||
1332 | void iwl_configure_filter(struct ieee80211_hw *hw, | ||
1333 | unsigned int changed_flags, | ||
1334 | unsigned int *total_flags, | ||
1335 | u64 multicast) | ||
1336 | { | ||
1337 | struct iwl_priv *priv = hw->priv; | ||
1338 | __le32 filter_or = 0, filter_nand = 0; | ||
1339 | |||
1340 | #define CHK(test, flag) do { \ | ||
1341 | if (*total_flags & (test)) \ | ||
1342 | filter_or |= (flag); \ | ||
1343 | else \ | ||
1344 | filter_nand |= (flag); \ | ||
1345 | } while (0) | ||
1346 | |||
1347 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
1348 | changed_flags, *total_flags); | ||
1349 | |||
1350 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
1351 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); | ||
1352 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
1353 | |||
1354 | #undef CHK | ||
1355 | |||
1356 | mutex_lock(&priv->mutex); | ||
1357 | |||
1358 | priv->staging_rxon.filter_flags &= ~filter_nand; | ||
1359 | priv->staging_rxon.filter_flags |= filter_or; | ||
1360 | |||
1361 | iwlcore_commit_rxon(priv); | ||
1362 | |||
1363 | mutex_unlock(&priv->mutex); | ||
1364 | |||
1365 | /* | ||
1366 | * Receiving all multicast frames is always enabled by the | ||
1367 | * default flags setup in iwl_connection_init_rx_config() | ||
1368 | * since we currently do not support programming multicast | ||
1369 | * filters into the device. | ||
1370 | */ | ||
1371 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
1372 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
1373 | } | ||
1374 | EXPORT_SYMBOL(iwl_configure_filter); | ||
1375 | |||
1376 | int iwl_set_hw_params(struct iwl_priv *priv) | 1331 | int iwl_set_hw_params(struct iwl_priv *priv) |
1377 | { | 1332 | { |
1378 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | 1333 | priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 4a71dfb10a15..5e6ee3da6bbf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -372,9 +372,6 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv, | |||
372 | u32 decrypt_res, | 372 | u32 decrypt_res, |
373 | struct ieee80211_rx_status *stats); | 373 | struct ieee80211_rx_status *stats); |
374 | void iwl_irq_handle_error(struct iwl_priv *priv); | 374 | void iwl_irq_handle_error(struct iwl_priv *priv); |
375 | void iwl_configure_filter(struct ieee80211_hw *hw, | ||
376 | unsigned int changed_flags, | ||
377 | unsigned int *total_flags, u64 multicast); | ||
378 | int iwl_set_hw_params(struct iwl_priv *priv); | 375 | int iwl_set_hw_params(struct iwl_priv *priv); |
379 | void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif); | 376 | void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif); |
380 | void iwl_bss_info_changed(struct ieee80211_hw *hw, | 377 | void iwl_bss_info_changed(struct ieee80211_hw *hw, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index f35bcad56e36..2e97cd2fa98a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -1049,7 +1049,8 @@ struct iwl_event_log { | |||
1049 | #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) | 1049 | #define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5) |
1050 | 1050 | ||
1051 | /* timer constants use to monitor and recover stuck tx queues in mSecs */ | 1051 | /* timer constants use to monitor and recover stuck tx queues in mSecs */ |
1052 | #define IWL_MONITORING_PERIOD (1000) | 1052 | #define IWL_DEF_MONITORING_PERIOD (1000) |
1053 | #define IWL_LONG_MONITORING_PERIOD (5000) | ||
1053 | #define IWL_ONE_HUNDRED_MSECS (100) | 1054 | #define IWL_ONE_HUNDRED_MSECS (100) |
1054 | #define IWL_SIXTY_SECS (60000) | 1055 | #define IWL_SIXTY_SECS (60000) |
1055 | 1056 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 70c4b8fba0ee..59a308b02f95 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -3391,6 +3391,55 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, | |||
3391 | 3391 | ||
3392 | return 0; | 3392 | return 0; |
3393 | } | 3393 | } |
3394 | |||
3395 | static void iwl3945_configure_filter(struct ieee80211_hw *hw, | ||
3396 | unsigned int changed_flags, | ||
3397 | unsigned int *total_flags, | ||
3398 | u64 multicast) | ||
3399 | { | ||
3400 | struct iwl_priv *priv = hw->priv; | ||
3401 | __le32 filter_or = 0, filter_nand = 0; | ||
3402 | |||
3403 | #define CHK(test, flag) do { \ | ||
3404 | if (*total_flags & (test)) \ | ||
3405 | filter_or |= (flag); \ | ||
3406 | else \ | ||
3407 | filter_nand |= (flag); \ | ||
3408 | } while (0) | ||
3409 | |||
3410 | IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n", | ||
3411 | changed_flags, *total_flags); | ||
3412 | |||
3413 | CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK); | ||
3414 | CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK); | ||
3415 | CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK); | ||
3416 | |||
3417 | #undef CHK | ||
3418 | |||
3419 | mutex_lock(&priv->mutex); | ||
3420 | |||
3421 | priv->staging_rxon.filter_flags &= ~filter_nand; | ||
3422 | priv->staging_rxon.filter_flags |= filter_or; | ||
3423 | |||
3424 | /* | ||
3425 | * Committing directly here breaks for some reason, | ||
3426 | * but we'll eventually commit the filter flags | ||
3427 | * change anyway. | ||
3428 | */ | ||
3429 | |||
3430 | mutex_unlock(&priv->mutex); | ||
3431 | |||
3432 | /* | ||
3433 | * Receiving all multicast frames is always enabled by the | ||
3434 | * default flags setup in iwl_connection_init_rx_config() | ||
3435 | * since we currently do not support programming multicast | ||
3436 | * filters into the device. | ||
3437 | */ | ||
3438 | *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS | | ||
3439 | FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; | ||
3440 | } | ||
3441 | |||
3442 | |||
3394 | /***************************************************************************** | 3443 | /***************************************************************************** |
3395 | * | 3444 | * |
3396 | * sysfs attributes | 3445 | * sysfs attributes |
@@ -3796,7 +3845,7 @@ static struct ieee80211_ops iwl3945_hw_ops = { | |||
3796 | .add_interface = iwl_mac_add_interface, | 3845 | .add_interface = iwl_mac_add_interface, |
3797 | .remove_interface = iwl_mac_remove_interface, | 3846 | .remove_interface = iwl_mac_remove_interface, |
3798 | .config = iwl_mac_config, | 3847 | .config = iwl_mac_config, |
3799 | .configure_filter = iwl_configure_filter, | 3848 | .configure_filter = iwl3945_configure_filter, |
3800 | .set_key = iwl3945_mac_set_key, | 3849 | .set_key = iwl3945_mac_set_key, |
3801 | .conf_tx = iwl_mac_conf_tx, | 3850 | .conf_tx = iwl_mac_conf_tx, |
3802 | .reset_tsf = iwl_mac_reset_tsf, | 3851 | .reset_tsf = iwl_mac_reset_tsf, |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 01ad7f77383a..86fa8abdd66f 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -486,7 +486,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
486 | struct ieee80211_rx_status rx_status; | 486 | struct ieee80211_rx_status rx_status; |
487 | 487 | ||
488 | if (data->idle) { | 488 | if (data->idle) { |
489 | wiphy_debug(hw->wiphy, "trying to tx when idle - reject\n"); | 489 | wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); |
490 | return false; | 490 | return false; |
491 | } | 491 | } |
492 | 492 | ||
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index d761ed2d8af4..f152a25be59f 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -910,14 +910,14 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index) | |||
910 | 910 | ||
911 | rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); | 911 | rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma); |
912 | if (rxq->rxd == NULL) { | 912 | if (rxq->rxd == NULL) { |
913 | wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n"); | 913 | wiphy_err(hw->wiphy, "failed to alloc RX descriptors\n"); |
914 | return -ENOMEM; | 914 | return -ENOMEM; |
915 | } | 915 | } |
916 | memset(rxq->rxd, 0, size); | 916 | memset(rxq->rxd, 0, size); |
917 | 917 | ||
918 | rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); | 918 | rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL); |
919 | if (rxq->buf == NULL) { | 919 | if (rxq->buf == NULL) { |
920 | wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n"); | 920 | wiphy_err(hw->wiphy, "failed to alloc RX skbuff list\n"); |
921 | pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); | 921 | pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma); |
922 | return -ENOMEM; | 922 | return -ENOMEM; |
923 | } | 923 | } |
@@ -1145,14 +1145,14 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index) | |||
1145 | 1145 | ||
1146 | txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); | 1146 | txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma); |
1147 | if (txq->txd == NULL) { | 1147 | if (txq->txd == NULL) { |
1148 | wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n"); | 1148 | wiphy_err(hw->wiphy, "failed to alloc TX descriptors\n"); |
1149 | return -ENOMEM; | 1149 | return -ENOMEM; |
1150 | } | 1150 | } |
1151 | memset(txq->txd, 0, size); | 1151 | memset(txq->txd, 0, size); |
1152 | 1152 | ||
1153 | txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); | 1153 | txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL); |
1154 | if (txq->skb == NULL) { | 1154 | if (txq->skb == NULL) { |
1155 | wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n"); | 1155 | wiphy_err(hw->wiphy, "failed to alloc TX skbuff list\n"); |
1156 | pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); | 1156 | pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma); |
1157 | return -ENOMEM; | 1157 | return -ENOMEM; |
1158 | } | 1158 | } |
@@ -1573,7 +1573,7 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) | |||
1573 | PCI_DMA_BIDIRECTIONAL); | 1573 | PCI_DMA_BIDIRECTIONAL); |
1574 | 1574 | ||
1575 | if (!timeout) { | 1575 | if (!timeout) { |
1576 | wiphy_err(hw->wiphy, "command %s timeout after %u ms\n", | 1576 | wiphy_err(hw->wiphy, "Command %s timeout after %u ms\n", |
1577 | mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | 1577 | mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), |
1578 | MWL8K_CMD_TIMEOUT_MS); | 1578 | MWL8K_CMD_TIMEOUT_MS); |
1579 | rc = -ETIMEDOUT; | 1579 | rc = -ETIMEDOUT; |
@@ -1584,11 +1584,11 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd) | |||
1584 | 1584 | ||
1585 | rc = cmd->result ? -EINVAL : 0; | 1585 | rc = cmd->result ? -EINVAL : 0; |
1586 | if (rc) | 1586 | if (rc) |
1587 | wiphy_err(hw->wiphy, "command %s error 0x%x\n", | 1587 | wiphy_err(hw->wiphy, "Command %s error 0x%x\n", |
1588 | mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), | 1588 | mwl8k_cmd_name(cmd->code, buf, sizeof(buf)), |
1589 | le16_to_cpu(cmd->result)); | 1589 | le16_to_cpu(cmd->result)); |
1590 | else if (ms > 2000) | 1590 | else if (ms > 2000) |
1591 | wiphy_notice(hw->wiphy, "command %s took %d ms\n", | 1591 | wiphy_notice(hw->wiphy, "Command %s took %d ms\n", |
1592 | mwl8k_cmd_name(cmd->code, | 1592 | mwl8k_cmd_name(cmd->code, |
1593 | buf, sizeof(buf)), | 1593 | buf, sizeof(buf)), |
1594 | ms); | 1594 | ms); |
@@ -3210,7 +3210,7 @@ static int mwl8k_start(struct ieee80211_hw *hw) | |||
3210 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | 3210 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
3211 | IRQF_SHARED, MWL8K_NAME, hw); | 3211 | IRQF_SHARED, MWL8K_NAME, hw); |
3212 | if (rc) { | 3212 | if (rc) { |
3213 | wiphy_err(hw->wiphy, "failed to register irq handler\n"); | 3213 | wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); |
3214 | return -EIO; | 3214 | return -EIO; |
3215 | } | 3215 | } |
3216 | 3216 | ||
@@ -3926,7 +3926,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3926 | 3926 | ||
3927 | priv->sram = pci_iomap(pdev, 0, 0x10000); | 3927 | priv->sram = pci_iomap(pdev, 0, 0x10000); |
3928 | if (priv->sram == NULL) { | 3928 | if (priv->sram == NULL) { |
3929 | wiphy_err(hw->wiphy, "cannot map device sram\n"); | 3929 | wiphy_err(hw->wiphy, "Cannot map device SRAM\n"); |
3930 | goto err_iounmap; | 3930 | goto err_iounmap; |
3931 | } | 3931 | } |
3932 | 3932 | ||
@@ -3938,7 +3938,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3938 | if (priv->regs == NULL) { | 3938 | if (priv->regs == NULL) { |
3939 | priv->regs = pci_iomap(pdev, 2, 0x10000); | 3939 | priv->regs = pci_iomap(pdev, 2, 0x10000); |
3940 | if (priv->regs == NULL) { | 3940 | if (priv->regs == NULL) { |
3941 | wiphy_err(hw->wiphy, "cannot map device registers\n"); | 3941 | wiphy_err(hw->wiphy, "Cannot map device registers\n"); |
3942 | goto err_iounmap; | 3942 | goto err_iounmap; |
3943 | } | 3943 | } |
3944 | } | 3944 | } |
@@ -3950,14 +3950,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
3950 | /* Ask userland hotplug daemon for the device firmware */ | 3950 | /* Ask userland hotplug daemon for the device firmware */ |
3951 | rc = mwl8k_request_firmware(priv); | 3951 | rc = mwl8k_request_firmware(priv); |
3952 | if (rc) { | 3952 | if (rc) { |
3953 | wiphy_err(hw->wiphy, "firmware files not found\n"); | 3953 | wiphy_err(hw->wiphy, "Firmware files not found\n"); |
3954 | goto err_stop_firmware; | 3954 | goto err_stop_firmware; |
3955 | } | 3955 | } |
3956 | 3956 | ||
3957 | /* Load firmware into hardware */ | 3957 | /* Load firmware into hardware */ |
3958 | rc = mwl8k_load_firmware(hw); | 3958 | rc = mwl8k_load_firmware(hw); |
3959 | if (rc) { | 3959 | if (rc) { |
3960 | wiphy_err(hw->wiphy, "cannot start firmware\n"); | 3960 | wiphy_err(hw->wiphy, "Cannot start firmware\n"); |
3961 | goto err_stop_firmware; | 3961 | goto err_stop_firmware; |
3962 | } | 3962 | } |
3963 | 3963 | ||
@@ -4047,7 +4047,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
4047 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, | 4047 | rc = request_irq(priv->pdev->irq, mwl8k_interrupt, |
4048 | IRQF_SHARED, MWL8K_NAME, hw); | 4048 | IRQF_SHARED, MWL8K_NAME, hw); |
4049 | if (rc) { | 4049 | if (rc) { |
4050 | wiphy_err(hw->wiphy, "failed to register irq handler\n"); | 4050 | wiphy_err(hw->wiphy, "failed to register IRQ handler\n"); |
4051 | goto err_free_queues; | 4051 | goto err_free_queues; |
4052 | } | 4052 | } |
4053 | 4053 | ||
@@ -4067,7 +4067,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
4067 | rc = mwl8k_cmd_get_hw_spec_sta(hw); | 4067 | rc = mwl8k_cmd_get_hw_spec_sta(hw); |
4068 | } | 4068 | } |
4069 | if (rc) { | 4069 | if (rc) { |
4070 | wiphy_err(hw->wiphy, "cannot initialise firmware\n"); | 4070 | wiphy_err(hw->wiphy, "Cannot initialise firmware\n"); |
4071 | goto err_free_irq; | 4071 | goto err_free_irq; |
4072 | } | 4072 | } |
4073 | 4073 | ||
@@ -4081,14 +4081,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
4081 | /* Turn radio off */ | 4081 | /* Turn radio off */ |
4082 | rc = mwl8k_cmd_radio_disable(hw); | 4082 | rc = mwl8k_cmd_radio_disable(hw); |
4083 | if (rc) { | 4083 | if (rc) { |
4084 | wiphy_err(hw->wiphy, "cannot disable\n"); | 4084 | wiphy_err(hw->wiphy, "Cannot disable\n"); |
4085 | goto err_free_irq; | 4085 | goto err_free_irq; |
4086 | } | 4086 | } |
4087 | 4087 | ||
4088 | /* Clear MAC address */ | 4088 | /* Clear MAC address */ |
4089 | rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); | 4089 | rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00"); |
4090 | if (rc) { | 4090 | if (rc) { |
4091 | wiphy_err(hw->wiphy, "cannot clear mac address\n"); | 4091 | wiphy_err(hw->wiphy, "Cannot clear MAC address\n"); |
4092 | goto err_free_irq; | 4092 | goto err_free_irq; |
4093 | } | 4093 | } |
4094 | 4094 | ||
@@ -4098,7 +4098,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev, | |||
4098 | 4098 | ||
4099 | rc = ieee80211_register_hw(hw); | 4099 | rc = ieee80211_register_hw(hw); |
4100 | if (rc) { | 4100 | if (rc) { |
4101 | wiphy_err(hw->wiphy, "cannot register device\n"); | 4101 | wiphy_err(hw->wiphy, "Cannot register device\n"); |
4102 | goto err_free_queues; | 4102 | goto err_free_queues; |
4103 | } | 4103 | } |
4104 | 4104 | ||
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c index d687cb7f2a59..78347041ec40 100644 --- a/drivers/net/wireless/p54/eeprom.c +++ b/drivers/net/wireless/p54/eeprom.c | |||
@@ -167,7 +167,7 @@ static int p54_generate_band(struct ieee80211_hw *dev, | |||
167 | } | 167 | } |
168 | 168 | ||
169 | if (j == 0) { | 169 | if (j == 0) { |
170 | wiphy_err(dev->wiphy, "disabling totally damaged %d GHz band\n", | 170 | wiphy_err(dev->wiphy, "Disabling totally damaged %d GHz band\n", |
171 | (band == IEEE80211_BAND_2GHZ) ? 2 : 5); | 171 | (band == IEEE80211_BAND_2GHZ) ? 2 : 5); |
172 | 172 | ||
173 | ret = -ENODATA; | 173 | ret = -ENODATA; |
@@ -695,12 +695,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) | |||
695 | u8 perm_addr[ETH_ALEN]; | 695 | u8 perm_addr[ETH_ALEN]; |
696 | 696 | ||
697 | wiphy_warn(dev->wiphy, | 697 | wiphy_warn(dev->wiphy, |
698 | "invalid hwaddr! using randomly generated mac addr\n"); | 698 | "Invalid hwaddr! Using randomly generated MAC addr\n"); |
699 | random_ether_addr(perm_addr); | 699 | random_ether_addr(perm_addr); |
700 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); | 700 | SET_IEEE80211_PERM_ADDR(dev, perm_addr); |
701 | } | 701 | } |
702 | 702 | ||
703 | wiphy_info(dev->wiphy, "hwaddr %pm, mac:isl38%02x rf:%s\n", | 703 | wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", |
704 | dev->wiphy->perm_addr, priv->version, | 704 | dev->wiphy->perm_addr, priv->version, |
705 | p54_rf_chips[priv->rxhw]); | 705 | p54_rf_chips[priv->rxhw]); |
706 | 706 | ||
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c index 47006bca4852..15b20c29a604 100644 --- a/drivers/net/wireless/p54/fwio.c +++ b/drivers/net/wireless/p54/fwio.c | |||
@@ -125,7 +125,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) | |||
125 | 125 | ||
126 | if (fw_version) | 126 | if (fw_version) |
127 | wiphy_info(priv->hw->wiphy, | 127 | wiphy_info(priv->hw->wiphy, |
128 | "fw rev %s - softmac protocol %x.%x\n", | 128 | "FW rev %s - Softmac protocol %x.%x\n", |
129 | fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); | 129 | fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); |
130 | 130 | ||
131 | if (priv->fw_var < 0x500) | 131 | if (priv->fw_var < 0x500) |
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c index ea91f5cce6b3..3837e1eec5f4 100644 --- a/drivers/net/wireless/p54/led.c +++ b/drivers/net/wireless/p54/led.c | |||
@@ -58,7 +58,7 @@ static void p54_update_leds(struct work_struct *work) | |||
58 | err = p54_set_leds(priv); | 58 | err = p54_set_leds(priv); |
59 | if (err && net_ratelimit()) | 59 | if (err && net_ratelimit()) |
60 | wiphy_err(priv->hw->wiphy, | 60 | wiphy_err(priv->hw->wiphy, |
61 | "failed to update leds (%d).\n", err); | 61 | "failed to update LEDs (%d).\n", err); |
62 | 62 | ||
63 | if (rerun) | 63 | if (rerun) |
64 | ieee80211_queue_delayed_work(priv->hw, &priv->led_work, | 64 | ieee80211_queue_delayed_work(priv->hw, &priv->led_work, |
@@ -103,7 +103,7 @@ static int p54_register_led(struct p54_common *priv, | |||
103 | err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev); | 103 | err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev); |
104 | if (err) | 104 | if (err) |
105 | wiphy_err(priv->hw->wiphy, | 105 | wiphy_err(priv->hw->wiphy, |
106 | "failed to register %s led.\n", name); | 106 | "Failed to register %s LED.\n", name); |
107 | else | 107 | else |
108 | led->registered = 1; | 108 | led->registered = 1; |
109 | 109 | ||
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 822f8dc26e9c..1eacba4daa5b 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -466,7 +466,7 @@ static int p54p_open(struct ieee80211_hw *dev) | |||
466 | P54P_READ(dev_int); | 466 | P54P_READ(dev_int); |
467 | 467 | ||
468 | if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { | 468 | if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) { |
469 | wiphy_err(dev->wiphy, "cannot boot firmware!\n"); | 469 | wiphy_err(dev->wiphy, "Cannot boot firmware!\n"); |
470 | p54p_stop(dev); | 470 | p54p_stop(dev); |
471 | return -ETIMEDOUT; | 471 | return -ETIMEDOUT; |
472 | } | 472 | } |
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c index 427b46f558ed..173aec3d6e7e 100644 --- a/drivers/net/wireless/p54/txrx.c +++ b/drivers/net/wireless/p54/txrx.c | |||
@@ -540,7 +540,7 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb) | |||
540 | case P54_TRAP_BEACON_TX: | 540 | case P54_TRAP_BEACON_TX: |
541 | break; | 541 | break; |
542 | case P54_TRAP_RADAR: | 542 | case P54_TRAP_RADAR: |
543 | wiphy_info(priv->hw->wiphy, "radar (freq:%d mhz)\n", freq); | 543 | wiphy_info(priv->hw->wiphy, "radar (freq:%d MHz)\n", freq); |
544 | break; | 544 | break; |
545 | case P54_TRAP_NO_BEACON: | 545 | case P54_TRAP_NO_BEACON: |
546 | if (priv->vif) | 546 | if (priv->vif) |
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c index b50c39aaec05..30107ce78dfb 100644 --- a/drivers/net/wireless/rtl818x/rtl8180_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c | |||
@@ -445,7 +445,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) | |||
445 | &priv->rx_ring_dma); | 445 | &priv->rx_ring_dma); |
446 | 446 | ||
447 | if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { | 447 | if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { |
448 | wiphy_err(dev->wiphy, "cannot allocate rx ring\n"); | 448 | wiphy_err(dev->wiphy, "Cannot allocate RX ring\n"); |
449 | return -ENOMEM; | 449 | return -ENOMEM; |
450 | } | 450 | } |
451 | 451 | ||
@@ -502,7 +502,7 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, | |||
502 | 502 | ||
503 | ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); | 503 | ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); |
504 | if (!ring || (unsigned long)ring & 0xFF) { | 504 | if (!ring || (unsigned long)ring & 0xFF) { |
505 | wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n", | 505 | wiphy_err(dev->wiphy, "Cannot allocate TX ring (prio = %d)\n", |
506 | prio); | 506 | prio); |
507 | return -ENOMEM; | 507 | return -ENOMEM; |
508 | } | 508 | } |
@@ -568,7 +568,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) | |||
568 | ret = request_irq(priv->pdev->irq, rtl8180_interrupt, | 568 | ret = request_irq(priv->pdev->irq, rtl8180_interrupt, |
569 | IRQF_SHARED, KBUILD_MODNAME, dev); | 569 | IRQF_SHARED, KBUILD_MODNAME, dev); |
570 | if (ret) { | 570 | if (ret) { |
571 | wiphy_err(dev->wiphy, "failed to register irq handler\n"); | 571 | wiphy_err(dev->wiphy, "failed to register IRQ handler\n"); |
572 | goto err_free_rings; | 572 | goto err_free_rings; |
573 | } | 573 | } |
574 | 574 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c index 5738a55c1b06..98e0351c1dd6 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c | |||
@@ -573,7 +573,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev) | |||
573 | } while (--i); | 573 | } while (--i); |
574 | 574 | ||
575 | if (!i) { | 575 | if (!i) { |
576 | wiphy_err(dev->wiphy, "reset timeout!\n"); | 576 | wiphy_err(dev->wiphy, "Reset timeout!\n"); |
577 | return -ETIMEDOUT; | 577 | return -ETIMEDOUT; |
578 | } | 578 | } |
579 | 579 | ||
@@ -1526,7 +1526,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf, | |||
1526 | mutex_init(&priv->conf_mutex); | 1526 | mutex_init(&priv->conf_mutex); |
1527 | skb_queue_head_init(&priv->b_tx_status.queue); | 1527 | skb_queue_head_init(&priv->b_tx_status.queue); |
1528 | 1528 | ||
1529 | wiphy_info(dev->wiphy, "hwaddr %pm, %s v%d + %s, rfkill mask %d\n", | 1529 | wiphy_info(dev->wiphy, "hwaddr %pM, %s V%d + %s, rfkill mask %d\n", |
1530 | mac_addr, chip_name, priv->asic_rev, priv->rf->name, | 1530 | mac_addr, chip_name, priv->asic_rev, priv->rf->name, |
1531 | priv->rfkill_mask); | 1531 | priv->rfkill_mask); |
1532 | 1532 | ||
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c index fd96f9112322..97eebdcf7eb9 100644 --- a/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c +++ b/drivers/net/wireless/rtl818x/rtl8187_rtl8225.c | |||
@@ -366,7 +366,7 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev) | |||
366 | rtl8225_write(dev, 0x02, 0x044d); | 366 | rtl8225_write(dev, 0x02, 0x044d); |
367 | msleep(100); | 367 | msleep(100); |
368 | if (!(rtl8225_read(dev, 6) & (1 << 7))) | 368 | if (!(rtl8225_read(dev, 6) & (1 << 7))) |
369 | wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", | 369 | wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", |
370 | rtl8225_read(dev, 6)); | 370 | rtl8225_read(dev, 6)); |
371 | } | 371 | } |
372 | 372 | ||
@@ -735,7 +735,7 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev) | |||
735 | rtl8225_write(dev, 0x02, 0x044D); | 735 | rtl8225_write(dev, 0x02, 0x044D); |
736 | msleep(100); | 736 | msleep(100); |
737 | if (!(rtl8225_read(dev, 6) & (1 << 7))) | 737 | if (!(rtl8225_read(dev, 6) & (1 << 7))) |
738 | wiphy_warn(dev->wiphy, "rf calibration failed! %x\n", | 738 | wiphy_warn(dev->wiphy, "RF Calibration Failed! %x\n", |
739 | rtl8225_read(dev, 6)); | 739 | rtl8225_read(dev, 6)); |
740 | } | 740 | } |
741 | 741 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c index a37b30cef489..ce3722f4c3e3 100644 --- a/drivers/net/wireless/wl12xx/wl1251_cmd.c +++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c | |||
@@ -484,7 +484,7 @@ int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout) | |||
484 | 484 | ||
485 | cmd->timeout = timeout; | 485 | cmd->timeout = timeout; |
486 | 486 | ||
487 | ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd)); | 487 | ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd)); |
488 | if (ret < 0) { | 488 | if (ret < 0) { |
489 | wl1251_error("cmd trigger scan to failed: %d", ret); | 489 | wl1251_error("cmd trigger scan to failed: %d", ret); |
490 | goto out; | 490 | goto out; |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 044f430f3b43..cff7cc2c1f02 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -486,10 +486,12 @@ config TOPSTAR_LAPTOP | |||
486 | config ACPI_TOSHIBA | 486 | config ACPI_TOSHIBA |
487 | tristate "Toshiba Laptop Extras" | 487 | tristate "Toshiba Laptop Extras" |
488 | depends on ACPI | 488 | depends on ACPI |
489 | depends on LEDS_CLASS | ||
490 | depends on NEW_LEDS | ||
491 | depends on BACKLIGHT_CLASS_DEVICE | ||
489 | depends on INPUT | 492 | depends on INPUT |
490 | depends on RFKILL || RFKILL = n | 493 | depends on RFKILL || RFKILL = n |
491 | select INPUT_POLLDEV | 494 | select INPUT_POLLDEV |
492 | select BACKLIGHT_CLASS_DEVICE | ||
493 | ---help--- | 495 | ---help--- |
494 | This driver adds support for access to certain system settings | 496 | This driver adds support for access to certain system settings |
495 | on "legacy free" Toshiba laptops. These laptops can be recognized by | 497 | on "legacy free" Toshiba laptops. These laptops can be recognized by |
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index e058c2ba2a15..ca05aefd03bf 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c | |||
@@ -938,10 +938,11 @@ static int set_brightness(int value) | |||
938 | /* SPLV laptop */ | 938 | /* SPLV laptop */ |
939 | if (hotk->methods->brightness_set) { | 939 | if (hotk->methods->brightness_set) { |
940 | if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, | 940 | if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set, |
941 | value, NULL)) | 941 | value, NULL)) { |
942 | printk(KERN_WARNING | 942 | printk(KERN_WARNING |
943 | "Asus ACPI: Error changing brightness\n"); | 943 | "Asus ACPI: Error changing brightness\n"); |
944 | ret = -EIO; | 944 | ret = -EIO; |
945 | } | ||
945 | goto out; | 946 | goto out; |
946 | } | 947 | } |
947 | 948 | ||
@@ -953,10 +954,11 @@ static int set_brightness(int value) | |||
953 | hotk->methods->brightness_down, | 954 | hotk->methods->brightness_down, |
954 | NULL, NULL); | 955 | NULL, NULL); |
955 | (value > 0) ? value-- : value++; | 956 | (value > 0) ? value-- : value++; |
956 | if (ACPI_FAILURE(status)) | 957 | if (ACPI_FAILURE(status)) { |
957 | printk(KERN_WARNING | 958 | printk(KERN_WARNING |
958 | "Asus ACPI: Error changing brightness\n"); | 959 | "Asus ACPI: Error changing brightness\n"); |
959 | ret = -EIO; | 960 | ret = -EIO; |
961 | } | ||
960 | } | 962 | } |
961 | out: | 963 | out: |
962 | return ret; | 964 | return ret; |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index d071ce056322..097083cac413 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
@@ -841,6 +841,14 @@ static struct dmi_system_id __initdata compal_dmi_table[] = { | |||
841 | .callback = dmi_check_cb | 841 | .callback = dmi_check_cb |
842 | }, | 842 | }, |
843 | { | 843 | { |
844 | .ident = "Dell Mini 1012", | ||
845 | .matches = { | ||
846 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
847 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), | ||
848 | }, | ||
849 | .callback = dmi_check_cb | ||
850 | }, | ||
851 | { | ||
844 | .ident = "Dell Inspiron 11z", | 852 | .ident = "Dell Inspiron 11z", |
845 | .matches = { | 853 | .matches = { |
846 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 854 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
@@ -1092,5 +1100,6 @@ MODULE_ALIAS("dmi:*:rnJHL90:rvrREFERENCE:*"); | |||
1092 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*"); | 1100 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron910:*"); |
1093 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*"); | 1101 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1010:*"); |
1094 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*"); | 1102 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1011:*"); |
1103 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1012:*"); | ||
1095 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*"); | 1104 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1110:*"); |
1096 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*"); | 1105 | MODULE_ALIAS("dmi:*:svnDellInc.:pnInspiron1210:*"); |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index b41ed5cab3e7..4413975912e0 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -122,6 +122,13 @@ static struct dmi_system_id __devinitdata dell_blacklist[] = { | |||
122 | }, | 122 | }, |
123 | }, | 123 | }, |
124 | { | 124 | { |
125 | .ident = "Dell Mini 1012", | ||
126 | .matches = { | ||
127 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
128 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1012"), | ||
129 | }, | ||
130 | }, | ||
131 | { | ||
125 | .ident = "Dell Inspiron 11z", | 132 | .ident = "Dell Inspiron 11z", |
126 | .matches = { | 133 | .matches = { |
127 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 134 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index f15516374987..c1741142a4cb 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -79,12 +79,13 @@ struct bios_args { | |||
79 | u32 command; | 79 | u32 command; |
80 | u32 commandtype; | 80 | u32 commandtype; |
81 | u32 datasize; | 81 | u32 datasize; |
82 | char *data; | 82 | u32 data; |
83 | }; | 83 | }; |
84 | 84 | ||
85 | struct bios_return { | 85 | struct bios_return { |
86 | u32 sigpass; | 86 | u32 sigpass; |
87 | u32 return_code; | 87 | u32 return_code; |
88 | u32 value; | ||
88 | }; | 89 | }; |
89 | 90 | ||
90 | struct key_entry { | 91 | struct key_entry { |
@@ -148,7 +149,7 @@ static struct platform_driver hp_wmi_driver = { | |||
148 | * buffer = kzalloc(128, GFP_KERNEL); | 149 | * buffer = kzalloc(128, GFP_KERNEL); |
149 | * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) | 150 | * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) |
150 | */ | 151 | */ |
151 | static int hp_wmi_perform_query(int query, int write, char *buffer, | 152 | static int hp_wmi_perform_query(int query, int write, u32 *buffer, |
152 | int buffersize) | 153 | int buffersize) |
153 | { | 154 | { |
154 | struct bios_return bios_return; | 155 | struct bios_return bios_return; |
@@ -159,7 +160,7 @@ static int hp_wmi_perform_query(int query, int write, char *buffer, | |||
159 | .command = write ? 0x2 : 0x1, | 160 | .command = write ? 0x2 : 0x1, |
160 | .commandtype = query, | 161 | .commandtype = query, |
161 | .datasize = buffersize, | 162 | .datasize = buffersize, |
162 | .data = buffer, | 163 | .data = *buffer, |
163 | }; | 164 | }; |
164 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; | 165 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; |
165 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 166 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
@@ -177,29 +178,14 @@ static int hp_wmi_perform_query(int query, int write, char *buffer, | |||
177 | 178 | ||
178 | bios_return = *((struct bios_return *)obj->buffer.pointer); | 179 | bios_return = *((struct bios_return *)obj->buffer.pointer); |
179 | 180 | ||
180 | if (bios_return.return_code) { | 181 | memcpy(buffer, &bios_return.value, sizeof(bios_return.value)); |
181 | printk(KERN_WARNING PREFIX "Query %d returned %d\n", query, | ||
182 | bios_return.return_code); | ||
183 | kfree(obj); | ||
184 | return bios_return.return_code; | ||
185 | } | ||
186 | if (obj->buffer.length - sizeof(bios_return) > buffersize) { | ||
187 | kfree(obj); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | memset(buffer, 0, buffersize); | ||
192 | memcpy(buffer, | ||
193 | ((char *)obj->buffer.pointer) + sizeof(struct bios_return), | ||
194 | obj->buffer.length - sizeof(bios_return)); | ||
195 | kfree(obj); | ||
196 | return 0; | 182 | return 0; |
197 | } | 183 | } |
198 | 184 | ||
199 | static int hp_wmi_display_state(void) | 185 | static int hp_wmi_display_state(void) |
200 | { | 186 | { |
201 | int state; | 187 | int state = 0; |
202 | int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, (char *)&state, | 188 | int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, &state, |
203 | sizeof(state)); | 189 | sizeof(state)); |
204 | if (ret) | 190 | if (ret) |
205 | return -EINVAL; | 191 | return -EINVAL; |
@@ -208,8 +194,8 @@ static int hp_wmi_display_state(void) | |||
208 | 194 | ||
209 | static int hp_wmi_hddtemp_state(void) | 195 | static int hp_wmi_hddtemp_state(void) |
210 | { | 196 | { |
211 | int state; | 197 | int state = 0; |
212 | int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, (char *)&state, | 198 | int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, &state, |
213 | sizeof(state)); | 199 | sizeof(state)); |
214 | if (ret) | 200 | if (ret) |
215 | return -EINVAL; | 201 | return -EINVAL; |
@@ -218,8 +204,8 @@ static int hp_wmi_hddtemp_state(void) | |||
218 | 204 | ||
219 | static int hp_wmi_als_state(void) | 205 | static int hp_wmi_als_state(void) |
220 | { | 206 | { |
221 | int state; | 207 | int state = 0; |
222 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, (char *)&state, | 208 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, &state, |
223 | sizeof(state)); | 209 | sizeof(state)); |
224 | if (ret) | 210 | if (ret) |
225 | return -EINVAL; | 211 | return -EINVAL; |
@@ -228,8 +214,8 @@ static int hp_wmi_als_state(void) | |||
228 | 214 | ||
229 | static int hp_wmi_dock_state(void) | 215 | static int hp_wmi_dock_state(void) |
230 | { | 216 | { |
231 | int state; | 217 | int state = 0; |
232 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state, | 218 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, |
233 | sizeof(state)); | 219 | sizeof(state)); |
234 | 220 | ||
235 | if (ret) | 221 | if (ret) |
@@ -240,8 +226,8 @@ static int hp_wmi_dock_state(void) | |||
240 | 226 | ||
241 | static int hp_wmi_tablet_state(void) | 227 | static int hp_wmi_tablet_state(void) |
242 | { | 228 | { |
243 | int state; | 229 | int state = 0; |
244 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state, | 230 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, |
245 | sizeof(state)); | 231 | sizeof(state)); |
246 | if (ret) | 232 | if (ret) |
247 | return ret; | 233 | return ret; |
@@ -256,7 +242,7 @@ static int hp_wmi_set_block(void *data, bool blocked) | |||
256 | int ret; | 242 | int ret; |
257 | 243 | ||
258 | ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, | 244 | ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, |
259 | (char *)&query, sizeof(query)); | 245 | &query, sizeof(query)); |
260 | if (ret) | 246 | if (ret) |
261 | return -EINVAL; | 247 | return -EINVAL; |
262 | return 0; | 248 | return 0; |
@@ -268,10 +254,10 @@ static const struct rfkill_ops hp_wmi_rfkill_ops = { | |||
268 | 254 | ||
269 | static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) | 255 | static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) |
270 | { | 256 | { |
271 | int wireless; | 257 | int wireless = 0; |
272 | int mask; | 258 | int mask; |
273 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, | 259 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, |
274 | (char *)&wireless, sizeof(wireless)); | 260 | &wireless, sizeof(wireless)); |
275 | /* TBD: Pass error */ | 261 | /* TBD: Pass error */ |
276 | 262 | ||
277 | mask = 0x200 << (r * 8); | 263 | mask = 0x200 << (r * 8); |
@@ -284,10 +270,10 @@ static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) | |||
284 | 270 | ||
285 | static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) | 271 | static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) |
286 | { | 272 | { |
287 | int wireless; | 273 | int wireless = 0; |
288 | int mask; | 274 | int mask; |
289 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, | 275 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, |
290 | (char *)&wireless, sizeof(wireless)); | 276 | &wireless, sizeof(wireless)); |
291 | /* TBD: Pass error */ | 277 | /* TBD: Pass error */ |
292 | 278 | ||
293 | mask = 0x800 << (r * 8); | 279 | mask = 0x800 << (r * 8); |
@@ -347,7 +333,7 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr, | |||
347 | const char *buf, size_t count) | 333 | const char *buf, size_t count) |
348 | { | 334 | { |
349 | u32 tmp = simple_strtoul(buf, NULL, 10); | 335 | u32 tmp = simple_strtoul(buf, NULL, 10); |
350 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, (char *)&tmp, | 336 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, &tmp, |
351 | sizeof(tmp)); | 337 | sizeof(tmp)); |
352 | if (ret) | 338 | if (ret) |
353 | return -EINVAL; | 339 | return -EINVAL; |
@@ -421,7 +407,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
421 | static struct key_entry *key; | 407 | static struct key_entry *key; |
422 | union acpi_object *obj; | 408 | union acpi_object *obj; |
423 | u32 event_id, event_data; | 409 | u32 event_id, event_data; |
424 | int key_code, ret; | 410 | int key_code = 0, ret; |
425 | u32 *location; | 411 | u32 *location; |
426 | acpi_status status; | 412 | acpi_status status; |
427 | 413 | ||
@@ -475,7 +461,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
475 | break; | 461 | break; |
476 | case HPWMI_BEZEL_BUTTON: | 462 | case HPWMI_BEZEL_BUTTON: |
477 | ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, | 463 | ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, |
478 | (char *)&key_code, | 464 | &key_code, |
479 | sizeof(key_code)); | 465 | sizeof(key_code)); |
480 | if (ret) | 466 | if (ret) |
481 | break; | 467 | break; |
@@ -578,9 +564,9 @@ static void cleanup_sysfs(struct platform_device *device) | |||
578 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) | 564 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) |
579 | { | 565 | { |
580 | int err; | 566 | int err; |
581 | int wireless; | 567 | int wireless = 0; |
582 | 568 | ||
583 | err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, (char *)&wireless, | 569 | err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, &wireless, |
584 | sizeof(wireless)); | 570 | sizeof(wireless)); |
585 | if (err) | 571 | if (err) |
586 | return err; | 572 | return err; |
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index afe82e50dfea..9024480a8228 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c | |||
@@ -1342,8 +1342,10 @@ static struct ips_mcp_limits *ips_detect_cpu(struct ips_driver *ips) | |||
1342 | limits = &ips_lv_limits; | 1342 | limits = &ips_lv_limits; |
1343 | else if (strstr(boot_cpu_data.x86_model_id, "CPU U")) | 1343 | else if (strstr(boot_cpu_data.x86_model_id, "CPU U")) |
1344 | limits = &ips_ulv_limits; | 1344 | limits = &ips_ulv_limits; |
1345 | else | 1345 | else { |
1346 | dev_info(&ips->dev->dev, "No CPUID match found.\n"); | 1346 | dev_info(&ips->dev->dev, "No CPUID match found.\n"); |
1347 | goto out; | ||
1348 | } | ||
1347 | 1349 | ||
1348 | rdmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_power); | 1350 | rdmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_power); |
1349 | tdp = turbo_power & TURBO_TDP_MASK; | 1351 | tdp = turbo_power & TURBO_TDP_MASK; |
@@ -1432,6 +1434,12 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1432 | 1434 | ||
1433 | spin_lock_init(&ips->turbo_status_lock); | 1435 | spin_lock_init(&ips->turbo_status_lock); |
1434 | 1436 | ||
1437 | ret = pci_enable_device(dev); | ||
1438 | if (ret) { | ||
1439 | dev_err(&dev->dev, "can't enable PCI device, aborting\n"); | ||
1440 | goto error_free; | ||
1441 | } | ||
1442 | |||
1435 | if (!pci_resource_start(dev, 0)) { | 1443 | if (!pci_resource_start(dev, 0)) { |
1436 | dev_err(&dev->dev, "TBAR not assigned, aborting\n"); | 1444 | dev_err(&dev->dev, "TBAR not assigned, aborting\n"); |
1437 | ret = -ENXIO; | 1445 | ret = -ENXIO; |
@@ -1444,11 +1452,6 @@ static int ips_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1444 | goto error_free; | 1452 | goto error_free; |
1445 | } | 1453 | } |
1446 | 1454 | ||
1447 | ret = pci_enable_device(dev); | ||
1448 | if (ret) { | ||
1449 | dev_err(&dev->dev, "can't enable PCI device, aborting\n"); | ||
1450 | goto error_free; | ||
1451 | } | ||
1452 | 1455 | ||
1453 | ips->regmap = ioremap(pci_resource_start(dev, 0), | 1456 | ips->regmap = ioremap(pci_resource_start(dev, 0), |
1454 | pci_resource_len(dev, 0)); | 1457 | pci_resource_len(dev, 0)); |
diff --git a/drivers/platform/x86/intel_rar_register.c b/drivers/platform/x86/intel_rar_register.c index 73f8e6d72669..2b11a33325e6 100644 --- a/drivers/platform/x86/intel_rar_register.c +++ b/drivers/platform/x86/intel_rar_register.c | |||
@@ -145,7 +145,7 @@ static void free_rar_device(struct rar_device *rar) | |||
145 | */ | 145 | */ |
146 | static struct rar_device *_rar_to_device(int rar, int *off) | 146 | static struct rar_device *_rar_to_device(int rar, int *off) |
147 | { | 147 | { |
148 | if (rar >= 0 && rar <= 3) { | 148 | if (rar >= 0 && rar < MRST_NUM_RAR) { |
149 | *off = rar; | 149 | *off = rar; |
150 | return &my_rar_device; | 150 | return &my_rar_device; |
151 | } | 151 | } |
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c index 943f9084dcb1..6abe18e638e9 100644 --- a/drivers/platform/x86/intel_scu_ipc.c +++ b/drivers/platform/x86/intel_scu_ipc.c | |||
@@ -487,7 +487,7 @@ int intel_scu_ipc_i2c_cntrl(u32 addr, u32 *data) | |||
487 | mdelay(1); | 487 | mdelay(1); |
488 | *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); | 488 | *data = readl(ipcdev.i2c_base + I2C_DATA_ADDR); |
489 | } else if (cmd == IPC_I2C_WRITE) { | 489 | } else if (cmd == IPC_I2C_WRITE) { |
490 | writel(addr, ipcdev.i2c_base + I2C_DATA_ADDR); | 490 | writel(*data, ipcdev.i2c_base + I2C_DATA_ADDR); |
491 | mdelay(1); | 491 | mdelay(1); |
492 | writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); | 492 | writel(addr, ipcdev.i2c_base + IPC_I2C_CNTRL_ADDR); |
493 | } else { | 493 | } else { |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 5d6119bed00c..e35ed128bdef 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -1911,6 +1911,17 @@ enum { /* hot key scan codes (derived from ACPI DSDT) */ | |||
1911 | TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, | 1911 | TP_ACPI_HOTKEYSCAN_VOLUMEDOWN, |
1912 | TP_ACPI_HOTKEYSCAN_MUTE, | 1912 | TP_ACPI_HOTKEYSCAN_MUTE, |
1913 | TP_ACPI_HOTKEYSCAN_THINKPAD, | 1913 | TP_ACPI_HOTKEYSCAN_THINKPAD, |
1914 | TP_ACPI_HOTKEYSCAN_UNK1, | ||
1915 | TP_ACPI_HOTKEYSCAN_UNK2, | ||
1916 | TP_ACPI_HOTKEYSCAN_UNK3, | ||
1917 | TP_ACPI_HOTKEYSCAN_UNK4, | ||
1918 | TP_ACPI_HOTKEYSCAN_UNK5, | ||
1919 | TP_ACPI_HOTKEYSCAN_UNK6, | ||
1920 | TP_ACPI_HOTKEYSCAN_UNK7, | ||
1921 | TP_ACPI_HOTKEYSCAN_UNK8, | ||
1922 | |||
1923 | /* Hotkey keymap size */ | ||
1924 | TPACPI_HOTKEY_MAP_LEN | ||
1914 | }; | 1925 | }; |
1915 | 1926 | ||
1916 | enum { /* Keys/events available through NVRAM polling */ | 1927 | enum { /* Keys/events available through NVRAM polling */ |
@@ -3082,6 +3093,8 @@ static const struct tpacpi_quirk tpacpi_hotkey_qtable[] __initconst = { | |||
3082 | TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ | 3093 | TPACPI_Q_IBM('1', 'D', TPACPI_HK_Q_INIMASK), /* X22, X23, X24 */ |
3083 | }; | 3094 | }; |
3084 | 3095 | ||
3096 | typedef u16 tpacpi_keymap_t[TPACPI_HOTKEY_MAP_LEN]; | ||
3097 | |||
3085 | static int __init hotkey_init(struct ibm_init_struct *iibm) | 3098 | static int __init hotkey_init(struct ibm_init_struct *iibm) |
3086 | { | 3099 | { |
3087 | /* Requirements for changing the default keymaps: | 3100 | /* Requirements for changing the default keymaps: |
@@ -3113,9 +3126,17 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3113 | * If the above is too much to ask, don't change the keymap. | 3126 | * If the above is too much to ask, don't change the keymap. |
3114 | * Ask the thinkpad-acpi maintainer to do it, instead. | 3127 | * Ask the thinkpad-acpi maintainer to do it, instead. |
3115 | */ | 3128 | */ |
3116 | static u16 ibm_keycode_map[] __initdata = { | 3129 | |
3130 | enum keymap_index { | ||
3131 | TPACPI_KEYMAP_IBM_GENERIC = 0, | ||
3132 | TPACPI_KEYMAP_LENOVO_GENERIC, | ||
3133 | }; | ||
3134 | |||
3135 | static const tpacpi_keymap_t tpacpi_keymaps[] __initconst = { | ||
3136 | /* Generic keymap for IBM ThinkPads */ | ||
3137 | [TPACPI_KEYMAP_IBM_GENERIC] = { | ||
3117 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | 3138 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ |
3118 | KEY_FN_F1, KEY_FN_F2, KEY_COFFEE, KEY_SLEEP, | 3139 | KEY_FN_F1, KEY_BATTERY, KEY_COFFEE, KEY_SLEEP, |
3119 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, | 3140 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, |
3120 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | 3141 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, |
3121 | 3142 | ||
@@ -3146,11 +3167,13 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3146 | /* (assignments unknown, please report if found) */ | 3167 | /* (assignments unknown, please report if found) */ |
3147 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3168 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3148 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3169 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3149 | }; | 3170 | }, |
3150 | static u16 lenovo_keycode_map[] __initdata = { | 3171 | |
3172 | /* Generic keymap for Lenovo ThinkPads */ | ||
3173 | [TPACPI_KEYMAP_LENOVO_GENERIC] = { | ||
3151 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ | 3174 | /* Scan Codes 0x00 to 0x0B: ACPI HKEY FN+F1..F12 */ |
3152 | KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, | 3175 | KEY_FN_F1, KEY_COFFEE, KEY_BATTERY, KEY_SLEEP, |
3153 | KEY_WLAN, KEY_FN_F6, KEY_SWITCHVIDEOMODE, KEY_FN_F8, | 3176 | KEY_WLAN, KEY_CAMERA, KEY_SWITCHVIDEOMODE, KEY_FN_F8, |
3154 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, | 3177 | KEY_FN_F9, KEY_FN_F10, KEY_FN_F11, KEY_SUSPEND, |
3155 | 3178 | ||
3156 | /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ | 3179 | /* Scan codes 0x0C to 0x1F: Other ACPI HKEY hot keys */ |
@@ -3189,11 +3212,25 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3189 | /* (assignments unknown, please report if found) */ | 3212 | /* (assignments unknown, please report if found) */ |
3190 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3213 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3191 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, | 3214 | KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, |
3215 | }, | ||
3216 | }; | ||
3217 | |||
3218 | static const struct tpacpi_quirk tpacpi_keymap_qtable[] __initconst = { | ||
3219 | /* Generic maps (fallback) */ | ||
3220 | { | ||
3221 | .vendor = PCI_VENDOR_ID_IBM, | ||
3222 | .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY, | ||
3223 | .quirks = TPACPI_KEYMAP_IBM_GENERIC, | ||
3224 | }, | ||
3225 | { | ||
3226 | .vendor = PCI_VENDOR_ID_LENOVO, | ||
3227 | .bios = TPACPI_MATCH_ANY, .ec = TPACPI_MATCH_ANY, | ||
3228 | .quirks = TPACPI_KEYMAP_LENOVO_GENERIC, | ||
3229 | }, | ||
3192 | }; | 3230 | }; |
3193 | 3231 | ||
3194 | #define TPACPI_HOTKEY_MAP_LEN ARRAY_SIZE(ibm_keycode_map) | 3232 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(tpacpi_keymap_t) |
3195 | #define TPACPI_HOTKEY_MAP_SIZE sizeof(ibm_keycode_map) | 3233 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(tpacpi_keymap_t[0]) |
3196 | #define TPACPI_HOTKEY_MAP_TYPESIZE sizeof(ibm_keycode_map[0]) | ||
3197 | 3234 | ||
3198 | int res, i; | 3235 | int res, i; |
3199 | int status; | 3236 | int status; |
@@ -3202,6 +3239,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3202 | bool tabletsw_state = false; | 3239 | bool tabletsw_state = false; |
3203 | 3240 | ||
3204 | unsigned long quirks; | 3241 | unsigned long quirks; |
3242 | unsigned long keymap_id; | ||
3205 | 3243 | ||
3206 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | 3244 | vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
3207 | "initializing hotkey subdriver\n"); | 3245 | "initializing hotkey subdriver\n"); |
@@ -3342,7 +3380,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3342 | goto err_exit; | 3380 | goto err_exit; |
3343 | 3381 | ||
3344 | /* Set up key map */ | 3382 | /* Set up key map */ |
3345 | |||
3346 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, | 3383 | hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE, |
3347 | GFP_KERNEL); | 3384 | GFP_KERNEL); |
3348 | if (!hotkey_keycode_map) { | 3385 | if (!hotkey_keycode_map) { |
@@ -3352,17 +3389,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) | |||
3352 | goto err_exit; | 3389 | goto err_exit; |
3353 | } | 3390 | } |
3354 | 3391 | ||
3355 | if (tpacpi_is_lenovo()) { | 3392 | keymap_id = tpacpi_check_quirks(tpacpi_keymap_qtable, |
3356 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | 3393 | ARRAY_SIZE(tpacpi_keymap_qtable)); |
3357 | "using Lenovo default hot key map\n"); | 3394 | BUG_ON(keymap_id >= ARRAY_SIZE(tpacpi_keymaps)); |
3358 | memcpy(hotkey_keycode_map, &lenovo_keycode_map, | 3395 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, |
3359 | TPACPI_HOTKEY_MAP_SIZE); | 3396 | "using keymap number %lu\n", keymap_id); |
3360 | } else { | 3397 | |
3361 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY, | 3398 | memcpy(hotkey_keycode_map, &tpacpi_keymaps[keymap_id], |
3362 | "using IBM default hot key map\n"); | 3399 | TPACPI_HOTKEY_MAP_SIZE); |
3363 | memcpy(hotkey_keycode_map, &ibm_keycode_map, | ||
3364 | TPACPI_HOTKEY_MAP_SIZE); | ||
3365 | } | ||
3366 | 3400 | ||
3367 | input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN); | 3401 | input_set_capability(tpacpi_inputdev, EV_MSC, MSC_SCAN); |
3368 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; | 3402 | tpacpi_inputdev->keycodesize = TPACPI_HOTKEY_MAP_TYPESIZE; |
@@ -3469,7 +3503,8 @@ static bool hotkey_notify_hotkey(const u32 hkey, | |||
3469 | *send_acpi_ev = true; | 3503 | *send_acpi_ev = true; |
3470 | *ignore_acpi_ev = false; | 3504 | *ignore_acpi_ev = false; |
3471 | 3505 | ||
3472 | if (scancode > 0 && scancode < 0x21) { | 3506 | /* HKEY event 0x1001 is scancode 0x00 */ |
3507 | if (scancode > 0 && scancode <= TPACPI_HOTKEY_MAP_LEN) { | ||
3473 | scancode--; | 3508 | scancode--; |
3474 | if (!(hotkey_source_mask & (1 << scancode))) { | 3509 | if (!(hotkey_source_mask & (1 << scancode))) { |
3475 | tpacpi_input_send_key_masked(scancode); | 3510 | tpacpi_input_send_key_masked(scancode); |
@@ -6080,13 +6115,18 @@ static struct backlight_ops ibm_backlight_data = { | |||
6080 | 6115 | ||
6081 | /* --------------------------------------------------------------------- */ | 6116 | /* --------------------------------------------------------------------- */ |
6082 | 6117 | ||
6118 | /* | ||
6119 | * Call _BCL method of video device. On some ThinkPads this will | ||
6120 | * switch the firmware to the ACPI brightness control mode. | ||
6121 | */ | ||
6122 | |||
6083 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) | 6123 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) |
6084 | { | 6124 | { |
6085 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 6125 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
6086 | union acpi_object *obj; | 6126 | union acpi_object *obj; |
6087 | int rc; | 6127 | int rc; |
6088 | 6128 | ||
6089 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { | 6129 | if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { |
6090 | obj = (union acpi_object *)buffer.pointer; | 6130 | obj = (union acpi_object *)buffer.pointer; |
6091 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { | 6131 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { |
6092 | printk(TPACPI_ERR "Unknown _BCL data, " | 6132 | printk(TPACPI_ERR "Unknown _BCL data, " |
@@ -6103,55 +6143,22 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle) | |||
6103 | return rc; | 6143 | return rc; |
6104 | } | 6144 | } |
6105 | 6145 | ||
6106 | static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle, | ||
6107 | u32 lvl, void *context, void **rv) | ||
6108 | { | ||
6109 | char name[ACPI_PATH_SEGMENT_LENGTH]; | ||
6110 | struct acpi_buffer buffer = { sizeof(name), &name }; | ||
6111 | |||
6112 | if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && | ||
6113 | !strncmp("_BCL", name, sizeof(name) - 1)) { | ||
6114 | BUG_ON(!rv || !*rv); | ||
6115 | **(int **)rv = tpacpi_query_bcl_levels(handle); | ||
6116 | return AE_CTRL_TERMINATE; | ||
6117 | } else { | ||
6118 | return AE_OK; | ||
6119 | } | ||
6120 | } | ||
6121 | 6146 | ||
6122 | /* | 6147 | /* |
6123 | * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map | 6148 | * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map |
6124 | */ | 6149 | */ |
6125 | static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) | 6150 | static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) |
6126 | { | 6151 | { |
6127 | int status; | 6152 | acpi_handle video_device; |
6128 | int bcl_levels = 0; | 6153 | int bcl_levels = 0; |
6129 | void *bcl_ptr = &bcl_levels; | ||
6130 | |||
6131 | if (!vid_handle) | ||
6132 | TPACPI_ACPIHANDLE_INIT(vid); | ||
6133 | |||
6134 | if (!vid_handle) | ||
6135 | return 0; | ||
6136 | |||
6137 | /* | ||
6138 | * Search for a _BCL method, and execute it. This is safe on all | ||
6139 | * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista | ||
6140 | * BIOS in ACPI backlight control mode. We do NOT have to care | ||
6141 | * about calling the _BCL method in an enabled video device, any | ||
6142 | * will do for our purposes. | ||
6143 | */ | ||
6144 | 6154 | ||
6145 | status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, | 6155 | tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device); |
6146 | tpacpi_acpi_walk_find_bcl, NULL, NULL, | 6156 | if (video_device) |
6147 | &bcl_ptr); | 6157 | bcl_levels = tpacpi_query_bcl_levels(video_device); |
6148 | 6158 | ||
6149 | if (ACPI_SUCCESS(status) && bcl_levels > 2) { | 6159 | tp_features.bright_acpimode = (bcl_levels > 0); |
6150 | tp_features.bright_acpimode = 1; | ||
6151 | return bcl_levels - 2; | ||
6152 | } | ||
6153 | 6160 | ||
6154 | return 0; | 6161 | return (bcl_levels > 2) ? (bcl_levels - 2) : 0; |
6155 | } | 6162 | } |
6156 | 6163 | ||
6157 | /* | 6164 | /* |
@@ -6244,28 +6251,6 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6244 | if (tp_features.bright_unkfw) | 6251 | if (tp_features.bright_unkfw) |
6245 | return 1; | 6252 | return 1; |
6246 | 6253 | ||
6247 | if (tp_features.bright_acpimode) { | ||
6248 | if (acpi_video_backlight_support()) { | ||
6249 | if (brightness_enable > 1) { | ||
6250 | printk(TPACPI_NOTICE | ||
6251 | "Standard ACPI backlight interface " | ||
6252 | "available, not loading native one.\n"); | ||
6253 | return 1; | ||
6254 | } else if (brightness_enable == 1) { | ||
6255 | printk(TPACPI_NOTICE | ||
6256 | "Backlight control force enabled, even if standard " | ||
6257 | "ACPI backlight interface is available\n"); | ||
6258 | } | ||
6259 | } else { | ||
6260 | if (brightness_enable > 1) { | ||
6261 | printk(TPACPI_NOTICE | ||
6262 | "Standard ACPI backlight interface not " | ||
6263 | "available, thinkpad_acpi native " | ||
6264 | "brightness control enabled\n"); | ||
6265 | } | ||
6266 | } | ||
6267 | } | ||
6268 | |||
6269 | if (!brightness_enable) { | 6254 | if (!brightness_enable) { |
6270 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, | 6255 | dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT, |
6271 | "brightness support disabled by " | 6256 | "brightness support disabled by " |
@@ -6273,6 +6258,26 @@ static int __init brightness_init(struct ibm_init_struct *iibm) | |||
6273 | return 1; | 6258 | return 1; |
6274 | } | 6259 | } |
6275 | 6260 | ||
6261 | if (acpi_video_backlight_support()) { | ||
6262 | if (brightness_enable > 1) { | ||
6263 | printk(TPACPI_INFO | ||
6264 | "Standard ACPI backlight interface " | ||
6265 | "available, not loading native one.\n"); | ||
6266 | return 1; | ||
6267 | } else if (brightness_enable == 1) { | ||
6268 | printk(TPACPI_WARN | ||
6269 | "Cannot enable backlight brightness support, " | ||
6270 | "ACPI is already handling it. Refer to the " | ||
6271 | "acpi_backlight kernel parameter\n"); | ||
6272 | return 1; | ||
6273 | } | ||
6274 | } else if (tp_features.bright_acpimode && brightness_enable > 1) { | ||
6275 | printk(TPACPI_NOTICE | ||
6276 | "Standard ACPI backlight interface not " | ||
6277 | "available, thinkpad_acpi native " | ||
6278 | "brightness control enabled\n"); | ||
6279 | } | ||
6280 | |||
6276 | /* | 6281 | /* |
6277 | * Check for module parameter bogosity, note that we | 6282 | * Check for module parameter bogosity, note that we |
6278 | * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be | 6283 | * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be |
diff --git a/drivers/s390/char/ctrlchar.c b/drivers/s390/char/ctrlchar.c index c6cbcb3f925e..0e9a309b9669 100644 --- a/drivers/s390/char/ctrlchar.c +++ b/drivers/s390/char/ctrlchar.c | |||
@@ -16,12 +16,11 @@ | |||
16 | 16 | ||
17 | #ifdef CONFIG_MAGIC_SYSRQ | 17 | #ifdef CONFIG_MAGIC_SYSRQ |
18 | static int ctrlchar_sysrq_key; | 18 | static int ctrlchar_sysrq_key; |
19 | static struct tty_struct *sysrq_tty; | ||
20 | 19 | ||
21 | static void | 20 | static void |
22 | ctrlchar_handle_sysrq(struct work_struct *work) | 21 | ctrlchar_handle_sysrq(struct work_struct *work) |
23 | { | 22 | { |
24 | handle_sysrq(ctrlchar_sysrq_key, sysrq_tty); | 23 | handle_sysrq(ctrlchar_sysrq_key); |
25 | } | 24 | } |
26 | 25 | ||
27 | static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); | 26 | static DECLARE_WORK(ctrlchar_work, ctrlchar_handle_sysrq); |
@@ -54,7 +53,6 @@ ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty) | |||
54 | /* racy */ | 53 | /* racy */ |
55 | if (len == 3 && buf[1] == '-') { | 54 | if (len == 3 && buf[1] == '-') { |
56 | ctrlchar_sysrq_key = buf[2]; | 55 | ctrlchar_sysrq_key = buf[2]; |
57 | sysrq_tty = tty; | ||
58 | schedule_work(&ctrlchar_work); | 56 | schedule_work(&ctrlchar_work); |
59 | return CTRLCHAR_SYSRQ; | 57 | return CTRLCHAR_SYSRQ; |
60 | } | 58 | } |
diff --git a/drivers/s390/char/keyboard.c b/drivers/s390/char/keyboard.c index 18d9a497863b..8cd58e412b5e 100644 --- a/drivers/s390/char/keyboard.c +++ b/drivers/s390/char/keyboard.c | |||
@@ -305,7 +305,7 @@ kbd_keycode(struct kbd_data *kbd, unsigned int keycode) | |||
305 | if (kbd->sysrq) { | 305 | if (kbd->sysrq) { |
306 | if (kbd->sysrq == K(KT_LATIN, '-')) { | 306 | if (kbd->sysrq == K(KT_LATIN, '-')) { |
307 | kbd->sysrq = 0; | 307 | kbd->sysrq = 0; |
308 | handle_sysrq(value, kbd->tty); | 308 | handle_sysrq(value); |
309 | return; | 309 | return; |
310 | } | 310 | } |
311 | if (value == '-') { | 311 | if (value == '-') { |
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 95a895dd4f13..c8dc392edd57 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/delay.h> | 56 | #include <linux/delay.h> |
57 | #include <linux/dma-mapping.h> | 57 | #include <linux/dma-mapping.h> |
58 | #include <linux/timer.h> | 58 | #include <linux/timer.h> |
59 | #include <linux/slab.h> | ||
59 | #include <linux/pci.h> | 60 | #include <linux/pci.h> |
60 | #include <linux/aer.h> | 61 | #include <linux/aer.h> |
61 | #include <asm/dma.h> | 62 | #include <asm/dma.h> |
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index f065204e401b..95a26fb1626c 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h | |||
@@ -132,7 +132,7 @@ void qla4_8xxx_idc_unlock(struct scsi_qla_host *ha); | |||
132 | int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha); | 132 | int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha); |
133 | void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha); | 133 | void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha); |
134 | void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha); | 134 | void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha); |
135 | inline void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha); | 135 | void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha); |
136 | 136 | ||
137 | extern int ql4xextended_error_logging; | 137 | extern int ql4xextended_error_logging; |
138 | extern int ql4xdiscoverywait; | 138 | extern int ql4xdiscoverywait; |
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index e031a734836e..5d4a3822382d 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c | |||
@@ -1418,7 +1418,7 @@ static int qla4_8xxx_rcvpeg_ready(struct scsi_qla_host *ha) | |||
1418 | return QLA_SUCCESS; | 1418 | return QLA_SUCCESS; |
1419 | } | 1419 | } |
1420 | 1420 | ||
1421 | inline void | 1421 | void |
1422 | qla4_8xxx_set_drv_active(struct scsi_qla_host *ha) | 1422 | qla4_8xxx_set_drv_active(struct scsi_qla_host *ha) |
1423 | { | 1423 | { |
1424 | uint32_t drv_active; | 1424 | uint32_t drv_active; |
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c index 7356a56ac458..be0ebce36e54 100644 --- a/drivers/serial/68328serial.c +++ b/drivers/serial/68328serial.c | |||
@@ -869,7 +869,9 @@ static int get_serial_info(struct m68k_serial * info, | |||
869 | tmp.close_delay = info->close_delay; | 869 | tmp.close_delay = info->close_delay; |
870 | tmp.closing_wait = info->closing_wait; | 870 | tmp.closing_wait = info->closing_wait; |
871 | tmp.custom_divisor = info->custom_divisor; | 871 | tmp.custom_divisor = info->custom_divisor; |
872 | copy_to_user(retinfo,&tmp,sizeof(*retinfo)); | 872 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
873 | return -EFAULT; | ||
874 | |||
873 | return 0; | 875 | return 0; |
874 | } | 876 | } |
875 | 877 | ||
@@ -882,7 +884,8 @@ static int set_serial_info(struct m68k_serial * info, | |||
882 | 884 | ||
883 | if (!new_info) | 885 | if (!new_info) |
884 | return -EFAULT; | 886 | return -EFAULT; |
885 | copy_from_user(&new_serial,new_info,sizeof(new_serial)); | 887 | if (copy_from_user(&new_serial, new_info, sizeof(new_serial))) |
888 | return -EFAULT; | ||
886 | old_info = *info; | 889 | old_info = *info; |
887 | 890 | ||
888 | if (!capable(CAP_SYS_ADMIN)) { | 891 | if (!capable(CAP_SYS_ADMIN)) { |
@@ -943,8 +946,7 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) | |||
943 | status = 0; | 946 | status = 0; |
944 | #endif | 947 | #endif |
945 | local_irq_restore(flags); | 948 | local_irq_restore(flags); |
946 | put_user(status,value); | 949 | return put_user(status, value); |
947 | return 0; | ||
948 | } | 950 | } |
949 | 951 | ||
950 | /* | 952 | /* |
@@ -999,27 +1001,18 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, | |||
999 | send_break(info, arg ? arg*(100) : 250); | 1001 | send_break(info, arg ? arg*(100) : 250); |
1000 | return 0; | 1002 | return 0; |
1001 | case TIOCGSERIAL: | 1003 | case TIOCGSERIAL: |
1002 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1004 | return get_serial_info(info, |
1003 | sizeof(struct serial_struct))) | 1005 | (struct serial_struct *) arg); |
1004 | return get_serial_info(info, | ||
1005 | (struct serial_struct *) arg); | ||
1006 | return -EFAULT; | ||
1007 | case TIOCSSERIAL: | 1006 | case TIOCSSERIAL: |
1008 | return set_serial_info(info, | 1007 | return set_serial_info(info, |
1009 | (struct serial_struct *) arg); | 1008 | (struct serial_struct *) arg); |
1010 | case TIOCSERGETLSR: /* Get line status register */ | 1009 | case TIOCSERGETLSR: /* Get line status register */ |
1011 | if (access_ok(VERIFY_WRITE, (void *) arg, | 1010 | return get_lsr_info(info, (unsigned int *) arg); |
1012 | sizeof(unsigned int))) | ||
1013 | return get_lsr_info(info, (unsigned int *) arg); | ||
1014 | return -EFAULT; | ||
1015 | case TIOCSERGSTRUCT: | 1011 | case TIOCSERGSTRUCT: |
1016 | if (!access_ok(VERIFY_WRITE, (void *) arg, | 1012 | if (copy_to_user((struct m68k_serial *) arg, |
1017 | sizeof(struct m68k_serial))) | 1013 | info, sizeof(struct m68k_serial))) |
1018 | return -EFAULT; | 1014 | return -EFAULT; |
1019 | copy_to_user((struct m68k_serial *) arg, | ||
1020 | info, sizeof(struct m68k_serial)); | ||
1021 | return 0; | 1015 | return 0; |
1022 | |||
1023 | default: | 1016 | default: |
1024 | return -ENOIOCTLCMD; | 1017 | return -ENOIOCTLCMD; |
1025 | } | 1018 | } |
diff --git a/drivers/serial/8250_early.c b/drivers/serial/8250_early.c index b745792ec25a..eaafb98debed 100644 --- a/drivers/serial/8250_early.c +++ b/drivers/serial/8250_early.c | |||
@@ -203,13 +203,13 @@ static int __init parse_options(struct early_serial8250_device *device, | |||
203 | 203 | ||
204 | if (mmio || mmio32) | 204 | if (mmio || mmio32) |
205 | printk(KERN_INFO | 205 | printk(KERN_INFO |
206 | "Early serial console at MMIO%s 0x%llu (options '%s')\n", | 206 | "Early serial console at MMIO%s 0x%llx (options '%s')\n", |
207 | mmio32 ? "32" : "", | 207 | mmio32 ? "32" : "", |
208 | (unsigned long long)port->mapbase, | 208 | (unsigned long long)port->mapbase, |
209 | device->options); | 209 | device->options); |
210 | else | 210 | else |
211 | printk(KERN_INFO | 211 | printk(KERN_INFO |
212 | "Early serial console at I/O port 0x%lu (options '%s')\n", | 212 | "Early serial console at I/O port 0x%lx (options '%s')\n", |
213 | port->iobase, | 213 | port->iobase, |
214 | device->options); | 214 | device->options); |
215 | 215 | ||
diff --git a/drivers/serial/of_serial.c b/drivers/serial/of_serial.c index 659a695bdad6..2af8fd113123 100644 --- a/drivers/serial/of_serial.c +++ b/drivers/serial/of_serial.c | |||
@@ -14,11 +14,10 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/serial_core.h> | 15 | #include <linux/serial_core.h> |
16 | #include <linux/serial_8250.h> | 16 | #include <linux/serial_8250.h> |
17 | #include <linux/of_address.h> | ||
17 | #include <linux/of_platform.h> | 18 | #include <linux/of_platform.h> |
18 | #include <linux/nwpserial.h> | 19 | #include <linux/nwpserial.h> |
19 | 20 | ||
20 | #include <asm/prom.h> | ||
21 | |||
22 | struct of_serial_info { | 21 | struct of_serial_info { |
23 | int type; | 22 | int type; |
24 | int line; | 23 | int line; |
diff --git a/drivers/serial/sn_console.c b/drivers/serial/sn_console.c index 7e5e5efea4e2..cff9a306660f 100644 --- a/drivers/serial/sn_console.c +++ b/drivers/serial/sn_console.c | |||
@@ -492,7 +492,7 @@ sn_receive_chars(struct sn_cons_port *port, unsigned long flags) | |||
492 | sysrq_requested = 0; | 492 | sysrq_requested = 0; |
493 | if (ch && time_before(jiffies, sysrq_timeout)) { | 493 | if (ch && time_before(jiffies, sysrq_timeout)) { |
494 | spin_unlock_irqrestore(&port->sc_port.lock, flags); | 494 | spin_unlock_irqrestore(&port->sc_port.lock, flags); |
495 | handle_sysrq(ch, NULL); | 495 | handle_sysrq(ch); |
496 | spin_lock_irqsave(&port->sc_port.lock, flags); | 496 | spin_lock_irqsave(&port->sc_port.lock, flags); |
497 | /* ignore actual sysrq command char */ | 497 | /* ignore actual sysrq command char */ |
498 | continue; | 498 | continue; |
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index 544f2e25d0e5..6381a0282ee7 100644 --- a/drivers/serial/suncore.c +++ b/drivers/serial/suncore.c | |||
@@ -55,7 +55,12 @@ EXPORT_SYMBOL(sunserial_unregister_minors); | |||
55 | int sunserial_console_match(struct console *con, struct device_node *dp, | 55 | int sunserial_console_match(struct console *con, struct device_node *dp, |
56 | struct uart_driver *drv, int line, bool ignore_line) | 56 | struct uart_driver *drv, int line, bool ignore_line) |
57 | { | 57 | { |
58 | if (!con || of_console_device != dp) | 58 | if (!con) |
59 | return 0; | ||
60 | |||
61 | drv->cons = con; | ||
62 | |||
63 | if (of_console_device != dp) | ||
59 | return 0; | 64 | return 0; |
60 | 65 | ||
61 | if (!ignore_line) { | 66 | if (!ignore_line) { |
@@ -69,12 +74,10 @@ int sunserial_console_match(struct console *con, struct device_node *dp, | |||
69 | return 0; | 74 | return 0; |
70 | } | 75 | } |
71 | 76 | ||
72 | con->index = line; | 77 | if (!console_set_on_cmdline) { |
73 | drv->cons = con; | 78 | con->index = line; |
74 | |||
75 | if (!console_set_on_cmdline) | ||
76 | add_preferred_console(con->name, line, NULL); | 79 | add_preferred_console(con->name, line, NULL); |
77 | 80 | } | |
78 | return 1; | 81 | return 1; |
79 | } | 82 | } |
80 | EXPORT_SYMBOL(sunserial_console_match); | 83 | EXPORT_SYMBOL(sunserial_console_match); |
diff --git a/drivers/spi/coldfire_qspi.c b/drivers/spi/coldfire_qspi.c index 59be3efe0636..052b3c7fa6a0 100644 --- a/drivers/spi/coldfire_qspi.c +++ b/drivers/spi/coldfire_qspi.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/sched.h> | ||
27 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
29 | #include <linux/io.h> | 30 | #include <linux/io.h> |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 4a7a7a7f11b6..335311a98fdc 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -113,8 +113,6 @@ source "drivers/staging/vme/Kconfig" | |||
113 | 113 | ||
114 | source "drivers/staging/memrar/Kconfig" | 114 | source "drivers/staging/memrar/Kconfig" |
115 | 115 | ||
116 | source "drivers/staging/sep/Kconfig" | ||
117 | |||
118 | source "drivers/staging/iio/Kconfig" | 116 | source "drivers/staging/iio/Kconfig" |
119 | 117 | ||
120 | source "drivers/staging/zram/Kconfig" | 118 | source "drivers/staging/zram/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index ca5c03eb3ce3..e3f1e1b6095e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -38,7 +38,6 @@ obj-$(CONFIG_FB_UDL) += udlfb/ | |||
38 | obj-$(CONFIG_HYPERV) += hv/ | 38 | obj-$(CONFIG_HYPERV) += hv/ |
39 | obj-$(CONFIG_VME_BUS) += vme/ | 39 | obj-$(CONFIG_VME_BUS) += vme/ |
40 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ | 40 | obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ |
41 | obj-$(CONFIG_DX_SEP) += sep/ | ||
42 | obj-$(CONFIG_IIO) += iio/ | 41 | obj-$(CONFIG_IIO) += iio/ |
43 | obj-$(CONFIG_ZRAM) += zram/ | 42 | obj-$(CONFIG_ZRAM) += zram/ |
44 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ | 43 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ |
diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index b4a8d5eb64fa..05ca15a6c9f8 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c | |||
@@ -267,6 +267,10 @@ static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr, | |||
267 | if (atomic_read(&bat_priv->log_level) == log_level_tmp) | 267 | if (atomic_read(&bat_priv->log_level) == log_level_tmp) |
268 | return count; | 268 | return count; |
269 | 269 | ||
270 | bat_info(net_dev, "Changing log level from: %i to: %li\n", | ||
271 | atomic_read(&bat_priv->log_level), | ||
272 | log_level_tmp); | ||
273 | |||
270 | atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); | 274 | atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); |
271 | return count; | 275 | return count; |
272 | } | 276 | } |
diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index 92c216a56885..baa8b05b9e8d 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c | |||
@@ -129,6 +129,9 @@ static bool hardif_is_iface_up(struct batman_if *batman_if) | |||
129 | 129 | ||
130 | static void update_mac_addresses(struct batman_if *batman_if) | 130 | static void update_mac_addresses(struct batman_if *batman_if) |
131 | { | 131 | { |
132 | if (!batman_if || !batman_if->packet_buff) | ||
133 | return; | ||
134 | |||
132 | addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); | 135 | addr_to_string(batman_if->addr_str, batman_if->net_dev->dev_addr); |
133 | 136 | ||
134 | memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, | 137 | memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, |
@@ -194,8 +197,6 @@ static void hardif_activate_interface(struct net_device *net_dev, | |||
194 | if (batman_if->if_status != IF_INACTIVE) | 197 | if (batman_if->if_status != IF_INACTIVE) |
195 | return; | 198 | return; |
196 | 199 | ||
197 | dev_hold(batman_if->net_dev); | ||
198 | |||
199 | update_mac_addresses(batman_if); | 200 | update_mac_addresses(batman_if); |
200 | batman_if->if_status = IF_TO_BE_ACTIVATED; | 201 | batman_if->if_status = IF_TO_BE_ACTIVATED; |
201 | 202 | ||
@@ -222,8 +223,6 @@ static void hardif_deactivate_interface(struct net_device *net_dev, | |||
222 | (batman_if->if_status != IF_TO_BE_ACTIVATED)) | 223 | (batman_if->if_status != IF_TO_BE_ACTIVATED)) |
223 | return; | 224 | return; |
224 | 225 | ||
225 | dev_put(batman_if->net_dev); | ||
226 | |||
227 | batman_if->if_status = IF_INACTIVE; | 226 | batman_if->if_status = IF_INACTIVE; |
228 | 227 | ||
229 | bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); | 228 | bat_info(net_dev, "Interface deactivated: %s\n", batman_if->dev); |
@@ -318,11 +317,13 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) | |||
318 | if (ret != 1) | 317 | if (ret != 1) |
319 | goto out; | 318 | goto out; |
320 | 319 | ||
320 | dev_hold(net_dev); | ||
321 | |||
321 | batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); | 322 | batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); |
322 | if (!batman_if) { | 323 | if (!batman_if) { |
323 | pr_err("Can't add interface (%s): out of memory\n", | 324 | pr_err("Can't add interface (%s): out of memory\n", |
324 | net_dev->name); | 325 | net_dev->name); |
325 | goto out; | 326 | goto release_dev; |
326 | } | 327 | } |
327 | 328 | ||
328 | batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); | 329 | batman_if->dev = kstrdup(net_dev->name, GFP_ATOMIC); |
@@ -336,6 +337,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) | |||
336 | batman_if->if_num = -1; | 337 | batman_if->if_num = -1; |
337 | batman_if->net_dev = net_dev; | 338 | batman_if->net_dev = net_dev; |
338 | batman_if->if_status = IF_NOT_IN_USE; | 339 | batman_if->if_status = IF_NOT_IN_USE; |
340 | batman_if->packet_buff = NULL; | ||
339 | INIT_LIST_HEAD(&batman_if->list); | 341 | INIT_LIST_HEAD(&batman_if->list); |
340 | 342 | ||
341 | check_known_mac_addr(batman_if->net_dev->dev_addr); | 343 | check_known_mac_addr(batman_if->net_dev->dev_addr); |
@@ -346,6 +348,8 @@ free_dev: | |||
346 | kfree(batman_if->dev); | 348 | kfree(batman_if->dev); |
347 | free_if: | 349 | free_if: |
348 | kfree(batman_if); | 350 | kfree(batman_if); |
351 | release_dev: | ||
352 | dev_put(net_dev); | ||
349 | out: | 353 | out: |
350 | return NULL; | 354 | return NULL; |
351 | } | 355 | } |
@@ -374,6 +378,7 @@ static void hardif_remove_interface(struct batman_if *batman_if) | |||
374 | batman_if->if_status = IF_TO_BE_REMOVED; | 378 | batman_if->if_status = IF_TO_BE_REMOVED; |
375 | list_del_rcu(&batman_if->list); | 379 | list_del_rcu(&batman_if->list); |
376 | sysfs_del_hardif(&batman_if->hardif_obj); | 380 | sysfs_del_hardif(&batman_if->hardif_obj); |
381 | dev_put(batman_if->net_dev); | ||
377 | call_rcu(&batman_if->rcu, hardif_free_interface); | 382 | call_rcu(&batman_if->rcu, hardif_free_interface); |
378 | } | 383 | } |
379 | 384 | ||
@@ -393,15 +398,13 @@ static int hard_if_event(struct notifier_block *this, | |||
393 | /* FIXME: each batman_if will be attached to a softif */ | 398 | /* FIXME: each batman_if will be attached to a softif */ |
394 | struct bat_priv *bat_priv = netdev_priv(soft_device); | 399 | struct bat_priv *bat_priv = netdev_priv(soft_device); |
395 | 400 | ||
396 | if (!batman_if) | 401 | if (!batman_if && event == NETDEV_REGISTER) |
397 | batman_if = hardif_add_interface(net_dev); | 402 | batman_if = hardif_add_interface(net_dev); |
398 | 403 | ||
399 | if (!batman_if) | 404 | if (!batman_if) |
400 | goto out; | 405 | goto out; |
401 | 406 | ||
402 | switch (event) { | 407 | switch (event) { |
403 | case NETDEV_REGISTER: | ||
404 | break; | ||
405 | case NETDEV_UP: | 408 | case NETDEV_UP: |
406 | hardif_activate_interface(soft_device, bat_priv, batman_if); | 409 | hardif_activate_interface(soft_device, bat_priv, batman_if); |
407 | break; | 410 | break; |
@@ -442,8 +445,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
442 | struct bat_priv *bat_priv = netdev_priv(soft_device); | 445 | struct bat_priv *bat_priv = netdev_priv(soft_device); |
443 | struct batman_packet *batman_packet; | 446 | struct batman_packet *batman_packet; |
444 | struct batman_if *batman_if; | 447 | struct batman_if *batman_if; |
445 | struct net_device_stats *stats; | ||
446 | struct rtnl_link_stats64 temp; | ||
447 | int ret; | 448 | int ret; |
448 | 449 | ||
449 | skb = skb_share_check(skb, GFP_ATOMIC); | 450 | skb = skb_share_check(skb, GFP_ATOMIC); |
@@ -479,12 +480,6 @@ int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | |||
479 | if (batman_if->if_status != IF_ACTIVE) | 480 | if (batman_if->if_status != IF_ACTIVE) |
480 | goto err_free; | 481 | goto err_free; |
481 | 482 | ||
482 | stats = (struct net_device_stats *)dev_get_stats(skb->dev, &temp); | ||
483 | if (stats) { | ||
484 | stats->rx_packets++; | ||
485 | stats->rx_bytes += skb->len; | ||
486 | } | ||
487 | |||
488 | batman_packet = (struct batman_packet *)skb->data; | 483 | batman_packet = (struct batman_packet *)skb->data; |
489 | 484 | ||
490 | if (batman_packet->version != COMPAT_VERSION) { | 485 | if (batman_packet->version != COMPAT_VERSION) { |
diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c index fc3d32c12729..3ae7dd2d2d4d 100644 --- a/drivers/staging/batman-adv/icmp_socket.c +++ b/drivers/staging/batman-adv/icmp_socket.c | |||
@@ -67,6 +67,7 @@ static int bat_socket_open(struct inode *inode, struct file *file) | |||
67 | INIT_LIST_HEAD(&socket_client->queue_list); | 67 | INIT_LIST_HEAD(&socket_client->queue_list); |
68 | socket_client->queue_len = 0; | 68 | socket_client->queue_len = 0; |
69 | socket_client->index = i; | 69 | socket_client->index = i; |
70 | socket_client->bat_priv = inode->i_private; | ||
70 | spin_lock_init(&socket_client->lock); | 71 | spin_lock_init(&socket_client->lock); |
71 | init_waitqueue_head(&socket_client->queue_wait); | 72 | init_waitqueue_head(&socket_client->queue_wait); |
72 | 73 | ||
@@ -151,9 +152,8 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf, | |||
151 | static ssize_t bat_socket_write(struct file *file, const char __user *buff, | 152 | static ssize_t bat_socket_write(struct file *file, const char __user *buff, |
152 | size_t len, loff_t *off) | 153 | size_t len, loff_t *off) |
153 | { | 154 | { |
154 | /* FIXME: each orig_node->batman_if will be attached to a softif */ | ||
155 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
156 | struct socket_client *socket_client = file->private_data; | 155 | struct socket_client *socket_client = file->private_data; |
156 | struct bat_priv *bat_priv = socket_client->bat_priv; | ||
157 | struct icmp_packet_rr icmp_packet; | 157 | struct icmp_packet_rr icmp_packet; |
158 | struct orig_node *orig_node; | 158 | struct orig_node *orig_node; |
159 | struct batman_if *batman_if; | 159 | struct batman_if *batman_if; |
@@ -168,6 +168,9 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, | |||
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
170 | 170 | ||
171 | if (!bat_priv->primary_if) | ||
172 | return -EFAULT; | ||
173 | |||
171 | if (len >= sizeof(struct icmp_packet_rr)) | 174 | if (len >= sizeof(struct icmp_packet_rr)) |
172 | packet_len = sizeof(struct icmp_packet_rr); | 175 | packet_len = sizeof(struct icmp_packet_rr); |
173 | 176 | ||
@@ -223,7 +226,8 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, | |||
223 | if (batman_if->if_status != IF_ACTIVE) | 226 | if (batman_if->if_status != IF_ACTIVE) |
224 | goto dst_unreach; | 227 | goto dst_unreach; |
225 | 228 | ||
226 | memcpy(icmp_packet.orig, batman_if->net_dev->dev_addr, ETH_ALEN); | 229 | memcpy(icmp_packet.orig, |
230 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
227 | 231 | ||
228 | if (packet_len == sizeof(struct icmp_packet_rr)) | 232 | if (packet_len == sizeof(struct icmp_packet_rr)) |
229 | memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN); | 233 | memcpy(icmp_packet.rr, batman_if->net_dev->dev_addr, ETH_ALEN); |
@@ -271,7 +275,7 @@ int bat_socket_setup(struct bat_priv *bat_priv) | |||
271 | goto err; | 275 | goto err; |
272 | 276 | ||
273 | d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, | 277 | d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, |
274 | bat_priv->debug_dir, NULL, &fops); | 278 | bat_priv->debug_dir, bat_priv, &fops); |
275 | if (d) | 279 | if (d) |
276 | goto err; | 280 | goto err; |
277 | 281 | ||
diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 2686019fe4e1..ef7c20ae7979 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c | |||
@@ -250,10 +250,13 @@ int choose_orig(void *data, int32_t size) | |||
250 | int is_my_mac(uint8_t *addr) | 250 | int is_my_mac(uint8_t *addr) |
251 | { | 251 | { |
252 | struct batman_if *batman_if; | 252 | struct batman_if *batman_if; |
253 | |||
253 | rcu_read_lock(); | 254 | rcu_read_lock(); |
254 | list_for_each_entry_rcu(batman_if, &if_list, list) { | 255 | list_for_each_entry_rcu(batman_if, &if_list, list) { |
255 | if ((batman_if->net_dev) && | 256 | if (batman_if->if_status != IF_ACTIVE) |
256 | (compare_orig(batman_if->net_dev->dev_addr, addr))) { | 257 | continue; |
258 | |||
259 | if (compare_orig(batman_if->net_dev->dev_addr, addr)) { | ||
257 | rcu_read_unlock(); | 260 | rcu_read_unlock(); |
258 | return 1; | 261 | return 1; |
259 | } | 262 | } |
diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 28bb627ffa13..de5a8c1a8104 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c | |||
@@ -391,11 +391,12 @@ static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) | |||
391 | int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) | 391 | int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) |
392 | { | 392 | { |
393 | struct orig_node *orig_node; | 393 | struct orig_node *orig_node; |
394 | unsigned long flags; | ||
394 | HASHIT(hashit); | 395 | HASHIT(hashit); |
395 | 396 | ||
396 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 397 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
397 | * if_num */ | 398 | * if_num */ |
398 | spin_lock(&orig_hash_lock); | 399 | spin_lock_irqsave(&orig_hash_lock, flags); |
399 | 400 | ||
400 | while (hash_iterate(orig_hash, &hashit)) { | 401 | while (hash_iterate(orig_hash, &hashit)) { |
401 | orig_node = hashit.bucket->data; | 402 | orig_node = hashit.bucket->data; |
@@ -404,11 +405,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) | |||
404 | goto err; | 405 | goto err; |
405 | } | 406 | } |
406 | 407 | ||
407 | spin_unlock(&orig_hash_lock); | 408 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
408 | return 0; | 409 | return 0; |
409 | 410 | ||
410 | err: | 411 | err: |
411 | spin_unlock(&orig_hash_lock); | 412 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
412 | return -ENOMEM; | 413 | return -ENOMEM; |
413 | } | 414 | } |
414 | 415 | ||
@@ -468,12 +469,13 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) | |||
468 | { | 469 | { |
469 | struct batman_if *batman_if_tmp; | 470 | struct batman_if *batman_if_tmp; |
470 | struct orig_node *orig_node; | 471 | struct orig_node *orig_node; |
472 | unsigned long flags; | ||
471 | HASHIT(hashit); | 473 | HASHIT(hashit); |
472 | int ret; | 474 | int ret; |
473 | 475 | ||
474 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on | 476 | /* resize all orig nodes because orig_node->bcast_own(_sum) depend on |
475 | * if_num */ | 477 | * if_num */ |
476 | spin_lock(&orig_hash_lock); | 478 | spin_lock_irqsave(&orig_hash_lock, flags); |
477 | 479 | ||
478 | while (hash_iterate(orig_hash, &hashit)) { | 480 | while (hash_iterate(orig_hash, &hashit)) { |
479 | orig_node = hashit.bucket->data; | 481 | orig_node = hashit.bucket->data; |
@@ -500,10 +502,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) | |||
500 | rcu_read_unlock(); | 502 | rcu_read_unlock(); |
501 | 503 | ||
502 | batman_if->if_num = -1; | 504 | batman_if->if_num = -1; |
503 | spin_unlock(&orig_hash_lock); | 505 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
504 | return 0; | 506 | return 0; |
505 | 507 | ||
506 | err: | 508 | err: |
507 | spin_unlock(&orig_hash_lock); | 509 | spin_unlock_irqrestore(&orig_hash_lock, flags); |
508 | return -ENOMEM; | 510 | return -ENOMEM; |
509 | } | 511 | } |
diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 066cc9149bf1..032195e6de94 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c | |||
@@ -783,6 +783,8 @@ int recv_bat_packet(struct sk_buff *skb, | |||
783 | 783 | ||
784 | static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | 784 | static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) |
785 | { | 785 | { |
786 | /* FIXME: each batman_if will be attached to a softif */ | ||
787 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
786 | struct orig_node *orig_node; | 788 | struct orig_node *orig_node; |
787 | struct icmp_packet_rr *icmp_packet; | 789 | struct icmp_packet_rr *icmp_packet; |
788 | struct ethhdr *ethhdr; | 790 | struct ethhdr *ethhdr; |
@@ -801,6 +803,9 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
801 | return NET_RX_DROP; | 803 | return NET_RX_DROP; |
802 | } | 804 | } |
803 | 805 | ||
806 | if (!bat_priv->primary_if) | ||
807 | return NET_RX_DROP; | ||
808 | |||
804 | /* answer echo request (ping) */ | 809 | /* answer echo request (ping) */ |
805 | /* get routing information */ | 810 | /* get routing information */ |
806 | spin_lock_irqsave(&orig_hash_lock, flags); | 811 | spin_lock_irqsave(&orig_hash_lock, flags); |
@@ -830,7 +835,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
830 | } | 835 | } |
831 | 836 | ||
832 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); | 837 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); |
833 | memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); | 838 | memcpy(icmp_packet->orig, |
839 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
834 | icmp_packet->msg_type = ECHO_REPLY; | 840 | icmp_packet->msg_type = ECHO_REPLY; |
835 | icmp_packet->ttl = TTL; | 841 | icmp_packet->ttl = TTL; |
836 | 842 | ||
@@ -845,6 +851,8 @@ static int recv_my_icmp_packet(struct sk_buff *skb, size_t icmp_len) | |||
845 | 851 | ||
846 | static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | 852 | static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) |
847 | { | 853 | { |
854 | /* FIXME: each batman_if will be attached to a softif */ | ||
855 | struct bat_priv *bat_priv = netdev_priv(soft_device); | ||
848 | struct orig_node *orig_node; | 856 | struct orig_node *orig_node; |
849 | struct icmp_packet *icmp_packet; | 857 | struct icmp_packet *icmp_packet; |
850 | struct ethhdr *ethhdr; | 858 | struct ethhdr *ethhdr; |
@@ -865,6 +873,9 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | |||
865 | return NET_RX_DROP; | 873 | return NET_RX_DROP; |
866 | } | 874 | } |
867 | 875 | ||
876 | if (!bat_priv->primary_if) | ||
877 | return NET_RX_DROP; | ||
878 | |||
868 | /* get routing information */ | 879 | /* get routing information */ |
869 | spin_lock_irqsave(&orig_hash_lock, flags); | 880 | spin_lock_irqsave(&orig_hash_lock, flags); |
870 | orig_node = ((struct orig_node *) | 881 | orig_node = ((struct orig_node *) |
@@ -892,7 +903,8 @@ static int recv_icmp_ttl_exceeded(struct sk_buff *skb, size_t icmp_len) | |||
892 | } | 903 | } |
893 | 904 | ||
894 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); | 905 | memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); |
895 | memcpy(icmp_packet->orig, ethhdr->h_dest, ETH_ALEN); | 906 | memcpy(icmp_packet->orig, |
907 | bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); | ||
896 | icmp_packet->msg_type = TTL_EXCEEDED; | 908 | icmp_packet->msg_type = TTL_EXCEEDED; |
897 | icmp_packet->ttl = TTL; | 909 | icmp_packet->ttl = TTL; |
898 | 910 | ||
diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 21d0717afb09..9aa9d369c752 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h | |||
@@ -126,6 +126,7 @@ struct socket_client { | |||
126 | unsigned char index; | 126 | unsigned char index; |
127 | spinlock_t lock; | 127 | spinlock_t lock; |
128 | wait_queue_head_t queue_wait; | 128 | wait_queue_head_t queue_wait; |
129 | struct bat_priv *bat_priv; | ||
129 | }; | 130 | }; |
130 | 131 | ||
131 | struct socket_packet { | 132 | struct socket_packet { |
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c index cdc4dd50d638..8ec83d2dffb7 100644 --- a/drivers/staging/pohmelfs/path_entry.c +++ b/drivers/staging/pohmelfs/path_entry.c | |||
@@ -44,9 +44,9 @@ int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int le | |||
44 | return -ENOENT; | 44 | return -ENOENT; |
45 | } | 45 | } |
46 | 46 | ||
47 | read_lock(¤t->fs->lock); | 47 | spin_lock(¤t->fs->lock); |
48 | path.mnt = mntget(current->fs->root.mnt); | 48 | path.mnt = mntget(current->fs->root.mnt); |
49 | read_unlock(¤t->fs->lock); | 49 | spin_unlock(¤t->fs->lock); |
50 | 50 | ||
51 | path.dentry = d; | 51 | path.dentry = d; |
52 | 52 | ||
@@ -91,9 +91,9 @@ int pohmelfs_path_length(struct pohmelfs_inode *pi) | |||
91 | return -ENOENT; | 91 | return -ENOENT; |
92 | } | 92 | } |
93 | 93 | ||
94 | read_lock(¤t->fs->lock); | 94 | spin_lock(¤t->fs->lock); |
95 | root = dget(current->fs->root.dentry); | 95 | root = dget(current->fs->root.dentry); |
96 | read_unlock(¤t->fs->lock); | 96 | spin_unlock(¤t->fs->lock); |
97 | 97 | ||
98 | spin_lock(&dcache_lock); | 98 | spin_lock(&dcache_lock); |
99 | 99 | ||
diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig deleted file mode 100644 index 0a9c39c7f2bd..000000000000 --- a/drivers/staging/sep/Kconfig +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | config DX_SEP | ||
2 | tristate "Discretix SEP driver" | ||
3 | # depends on MRST | ||
4 | depends on RAR_REGISTER && PCI | ||
5 | default y | ||
6 | help | ||
7 | Discretix SEP driver | ||
8 | |||
9 | If unsure say M. The compiled module will be | ||
10 | called sep_driver.ko | ||
diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile deleted file mode 100644 index 628d5f919414..000000000000 --- a/drivers/staging/sep/Makefile +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | obj-$(CONFIG_DX_SEP) := sep_driver.o | ||
2 | |||
diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO deleted file mode 100644 index ff0e931dab64..000000000000 --- a/drivers/staging/sep/TODO +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | Todo's so far (from Alan Cox) | ||
2 | - Fix firmware loading | ||
3 | - Get firmware into firmware git tree | ||
4 | - Review and tidy each algorithm function | ||
5 | - Check whether it can be plugged into any of the kernel crypto API | ||
6 | interfaces | ||
7 | - Do something about the magic shared memory interface and replace it | ||
8 | with something saner (in Linux terms) | ||
diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h deleted file mode 100644 index 9200524bb64d..000000000000 --- a/drivers/staging/sep/sep_dev.h +++ /dev/null | |||
@@ -1,110 +0,0 @@ | |||
1 | #ifndef __SEP_DEV_H__ | ||
2 | #define __SEP_DEV_H__ | ||
3 | |||
4 | /* | ||
5 | * | ||
6 | * sep_dev.h - Security Processor Device Structures | ||
7 | * | ||
8 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
9 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the Free | ||
13 | * Software Foundation; either version 2 of the License, or (at your option) | ||
14 | * any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
17 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
18 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
19 | * more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License along with | ||
22 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
23 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
24 | * | ||
25 | * CONTACTS: | ||
26 | * | ||
27 | * Alan Cox alan@linux.intel.com | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | struct sep_device { | ||
32 | /* pointer to pci dev */ | ||
33 | struct pci_dev *pdev; | ||
34 | |||
35 | unsigned long in_use; | ||
36 | |||
37 | /* address of the shared memory allocated during init for SEP driver | ||
38 | (coherent alloc) */ | ||
39 | void *shared_addr; | ||
40 | /* the physical address of the shared area */ | ||
41 | dma_addr_t shared_bus; | ||
42 | |||
43 | /* restricted access region (coherent alloc) */ | ||
44 | dma_addr_t rar_bus; | ||
45 | void *rar_addr; | ||
46 | /* firmware regions: cache is at rar_addr */ | ||
47 | unsigned long cache_size; | ||
48 | |||
49 | /* follows the cache */ | ||
50 | dma_addr_t resident_bus; | ||
51 | unsigned long resident_size; | ||
52 | void *resident_addr; | ||
53 | |||
54 | /* start address of the access to the SEP registers from driver */ | ||
55 | void __iomem *reg_addr; | ||
56 | /* transaction counter that coordinates the transactions between SEP and HOST */ | ||
57 | unsigned long send_ct; | ||
58 | /* counter for the messages from sep */ | ||
59 | unsigned long reply_ct; | ||
60 | /* counter for the number of bytes allocated in the pool for the current | ||
61 | transaction */ | ||
62 | unsigned long data_pool_bytes_allocated; | ||
63 | |||
64 | /* array of pointers to the pages that represent input data for the synchronic | ||
65 | DMA action */ | ||
66 | struct page **in_page_array; | ||
67 | |||
68 | /* array of pointers to the pages that represent out data for the synchronic | ||
69 | DMA action */ | ||
70 | struct page **out_page_array; | ||
71 | |||
72 | /* number of pages in the sep_in_page_array */ | ||
73 | unsigned long in_num_pages; | ||
74 | |||
75 | /* number of pages in the sep_out_page_array */ | ||
76 | unsigned long out_num_pages; | ||
77 | |||
78 | /* global data for every flow */ | ||
79 | struct sep_flow_context_t flows[SEP_DRIVER_NUM_FLOWS]; | ||
80 | |||
81 | /* pointer to the workqueue that handles the flow done interrupts */ | ||
82 | struct workqueue_struct *flow_wq; | ||
83 | |||
84 | }; | ||
85 | |||
86 | static struct sep_device *sep_dev; | ||
87 | |||
88 | static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value) | ||
89 | { | ||
90 | void __iomem *addr = dev->reg_addr + reg; | ||
91 | writel(value, addr); | ||
92 | } | ||
93 | |||
94 | static inline u32 sep_read_reg(struct sep_device *dev, int reg) | ||
95 | { | ||
96 | void __iomem *addr = dev->reg_addr + reg; | ||
97 | return readl(addr); | ||
98 | } | ||
99 | |||
100 | /* wait for SRAM write complete(indirect write */ | ||
101 | static inline void sep_wait_sram_write(struct sep_device *dev) | ||
102 | { | ||
103 | u32 reg_val; | ||
104 | do | ||
105 | reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR); | ||
106 | while (!(reg_val & 1)); | ||
107 | } | ||
108 | |||
109 | |||
110 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c deleted file mode 100644 index ecbde3467b1b..000000000000 --- a/drivers/staging/sep/sep_driver.c +++ /dev/null | |||
@@ -1,2742 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver.c - Security Processor Driver main group of functions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #include <linux/init.h> | ||
33 | #include <linux/module.h> | ||
34 | #include <linux/fs.h> | ||
35 | #include <linux/cdev.h> | ||
36 | #include <linux/kdev_t.h> | ||
37 | #include <linux/mutex.h> | ||
38 | #include <linux/sched.h> | ||
39 | #include <linux/mm.h> | ||
40 | #include <linux/poll.h> | ||
41 | #include <linux/wait.h> | ||
42 | #include <linux/pci.h> | ||
43 | #include <linux/firmware.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <asm/ioctl.h> | ||
46 | #include <linux/ioport.h> | ||
47 | #include <asm/io.h> | ||
48 | #include <linux/interrupt.h> | ||
49 | #include <linux/pagemap.h> | ||
50 | #include <asm/cacheflush.h> | ||
51 | #include "sep_driver_hw_defs.h" | ||
52 | #include "sep_driver_config.h" | ||
53 | #include "sep_driver_api.h" | ||
54 | #include "sep_dev.h" | ||
55 | |||
56 | #if SEP_DRIVER_ARM_DEBUG_MODE | ||
57 | |||
58 | #define CRYS_SEP_ROM_length 0x4000 | ||
59 | #define CRYS_SEP_ROM_start_address 0x8000C000UL | ||
60 | #define CRYS_SEP_ROM_start_address_offset 0xC000UL | ||
61 | #define SEP_ROM_BANK_register 0x80008420UL | ||
62 | #define SEP_ROM_BANK_register_offset 0x8420UL | ||
63 | #define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0x82000000 | ||
64 | |||
65 | /* | ||
66 | * THESE 2 definitions are specific to the board - must be | ||
67 | * defined during integration | ||
68 | */ | ||
69 | #define SEP_RAR_IO_MEM_REGION_START_ADDRESS 0xFF0D0000 | ||
70 | |||
71 | /* 2M size */ | ||
72 | |||
73 | static void sep_load_rom_code(struct sep_device *sep) | ||
74 | { | ||
75 | /* Index variables */ | ||
76 | unsigned long i, k, j; | ||
77 | u32 reg; | ||
78 | u32 error; | ||
79 | u32 warning; | ||
80 | |||
81 | /* Loading ROM from SEP_ROM_image.h file */ | ||
82 | k = sizeof(CRYS_SEP_ROM); | ||
83 | |||
84 | edbg("SEP Driver: DX_CC_TST_SepRomLoader start\n"); | ||
85 | |||
86 | edbg("SEP Driver: k is %lu\n", k); | ||
87 | edbg("SEP Driver: sep->reg_addr is %p\n", sep->reg_addr); | ||
88 | edbg("SEP Driver: CRYS_SEP_ROM_start_address_offset is %p\n", CRYS_SEP_ROM_start_address_offset); | ||
89 | |||
90 | for (i = 0; i < 4; i++) { | ||
91 | /* write bank */ | ||
92 | sep_write_reg(sep, SEP_ROM_BANK_register_offset, i); | ||
93 | |||
94 | for (j = 0; j < CRYS_SEP_ROM_length / 4; j++) { | ||
95 | sep_write_reg(sep, CRYS_SEP_ROM_start_address_offset + 4 * j, CRYS_SEP_ROM[i * 0x1000 + j]); | ||
96 | |||
97 | k = k - 4; | ||
98 | |||
99 | if (k == 0) { | ||
100 | j = CRYS_SEP_ROM_length; | ||
101 | i = 4; | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
106 | /* reset the SEP */ | ||
107 | sep_write_reg(sep, HW_HOST_SEP_SW_RST_REG_ADDR, 0x1); | ||
108 | |||
109 | /* poll for SEP ROM boot finish */ | ||
110 | do | ||
111 | reg = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
112 | while (!reg); | ||
113 | |||
114 | edbg("SEP Driver: ROM polling ended\n"); | ||
115 | |||
116 | switch (reg) { | ||
117 | case 0x1: | ||
118 | /* fatal error - read erro status from GPRO */ | ||
119 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
120 | edbg("SEP Driver: ROM polling case 1\n"); | ||
121 | break; | ||
122 | case 0x4: | ||
123 | /* Cold boot ended successfully */ | ||
124 | case 0x8: | ||
125 | /* Warmboot ended successfully */ | ||
126 | case 0x10: | ||
127 | /* ColdWarm boot ended successfully */ | ||
128 | error = 0; | ||
129 | case 0x2: | ||
130 | /* Boot First Phase ended */ | ||
131 | warning = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
132 | case 0x20: | ||
133 | edbg("SEP Driver: ROM polling case %d\n", reg); | ||
134 | break; | ||
135 | } | ||
136 | |||
137 | } | ||
138 | |||
139 | #else | ||
140 | static void sep_load_rom_code(struct sep_device *sep) { } | ||
141 | #endif /* SEP_DRIVER_ARM_DEBUG_MODE */ | ||
142 | |||
143 | |||
144 | |||
145 | /*---------------------------------------- | ||
146 | DEFINES | ||
147 | -----------------------------------------*/ | ||
148 | |||
149 | #define BASE_ADDRESS_FOR_SYSTEM 0xfffc0000 | ||
150 | #define SEP_RAR_IO_MEM_REGION_SIZE 0x40000 | ||
151 | |||
152 | /*-------------------------------------------- | ||
153 | GLOBAL variables | ||
154 | --------------------------------------------*/ | ||
155 | |||
156 | /* debug messages level */ | ||
157 | static int debug; | ||
158 | module_param(debug, int , 0); | ||
159 | MODULE_PARM_DESC(debug, "Flag to enable SEP debug messages"); | ||
160 | |||
161 | /* Keep this a single static object for now to keep the conversion easy */ | ||
162 | |||
163 | static struct sep_device sep_instance; | ||
164 | static struct sep_device *sep_dev = &sep_instance; | ||
165 | |||
166 | /* | ||
167 | mutex for the access to the internals of the sep driver | ||
168 | */ | ||
169 | static DEFINE_MUTEX(sep_mutex); | ||
170 | |||
171 | |||
172 | /* wait queue head (event) of the driver */ | ||
173 | static DECLARE_WAIT_QUEUE_HEAD(sep_event); | ||
174 | |||
175 | /** | ||
176 | * sep_load_firmware - copy firmware cache/resident | ||
177 | * @sep: device we are loading | ||
178 | * | ||
179 | * This functions copies the cache and resident from their source | ||
180 | * location into destination shared memory. | ||
181 | */ | ||
182 | |||
183 | static int sep_load_firmware(struct sep_device *sep) | ||
184 | { | ||
185 | const struct firmware *fw; | ||
186 | char *cache_name = "sep/cache.image.bin"; | ||
187 | char *res_name = "sep/resident.image.bin"; | ||
188 | int error; | ||
189 | |||
190 | edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); | ||
191 | edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); | ||
192 | |||
193 | /* load cache */ | ||
194 | error = request_firmware(&fw, cache_name, &sep->pdev->dev); | ||
195 | if (error) { | ||
196 | edbg("SEP Driver:cant request cache fw\n"); | ||
197 | return error; | ||
198 | } | ||
199 | edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data); | ||
200 | |||
201 | memcpy(sep->rar_addr, (void *)fw->data, fw->size); | ||
202 | sep->cache_size = fw->size; | ||
203 | release_firmware(fw); | ||
204 | |||
205 | sep->resident_bus = sep->rar_bus + sep->cache_size; | ||
206 | sep->resident_addr = sep->rar_addr + sep->cache_size; | ||
207 | |||
208 | /* load resident */ | ||
209 | error = request_firmware(&fw, res_name, &sep->pdev->dev); | ||
210 | if (error) { | ||
211 | edbg("SEP Driver:cant request res fw\n"); | ||
212 | return error; | ||
213 | } | ||
214 | edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data); | ||
215 | |||
216 | memcpy(sep->resident_addr, (void *) fw->data, fw->size); | ||
217 | sep->resident_size = fw->size; | ||
218 | release_firmware(fw); | ||
219 | |||
220 | edbg("sep: resident v %p b %08llx cache v %p b %08llx\n", | ||
221 | sep->resident_addr, (unsigned long long)sep->resident_bus, | ||
222 | sep->rar_addr, (unsigned long long)sep->rar_bus); | ||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | MODULE_FIRMWARE("sep/cache.image.bin"); | ||
227 | MODULE_FIRMWARE("sep/resident.image.bin"); | ||
228 | |||
229 | /** | ||
230 | * sep_map_and_alloc_shared_area - allocate shared block | ||
231 | * @sep: security processor | ||
232 | * @size: size of shared area | ||
233 | * | ||
234 | * Allocate a shared buffer in host memory that can be used by both the | ||
235 | * kernel and also the hardware interface via DMA. | ||
236 | */ | ||
237 | |||
238 | static int sep_map_and_alloc_shared_area(struct sep_device *sep, | ||
239 | unsigned long size) | ||
240 | { | ||
241 | /* shared_addr = ioremap_nocache(0xda00000,shared_area_size); */ | ||
242 | sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, size, | ||
243 | &sep->shared_bus, GFP_KERNEL); | ||
244 | |||
245 | if (!sep->shared_addr) { | ||
246 | edbg("sep_driver :shared memory dma_alloc_coherent failed\n"); | ||
247 | return -ENOMEM; | ||
248 | } | ||
249 | /* set the bus address of the shared area */ | ||
250 | edbg("sep: shared_addr %ld bytes @%p (bus %08llx)\n", | ||
251 | size, sep->shared_addr, (unsigned long long)sep->shared_bus); | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | /** | ||
256 | * sep_unmap_and_free_shared_area - free shared block | ||
257 | * @sep: security processor | ||
258 | * | ||
259 | * Free the shared area allocated to the security processor. The | ||
260 | * processor must have finished with this and any final posted | ||
261 | * writes cleared before we do so. | ||
262 | */ | ||
263 | static void sep_unmap_and_free_shared_area(struct sep_device *sep, int size) | ||
264 | { | ||
265 | dma_free_coherent(&sep->pdev->dev, size, | ||
266 | sep->shared_addr, sep->shared_bus); | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * sep_shared_virt_to_bus - convert bus/virt addresses | ||
271 | * | ||
272 | * Returns the bus address inside the shared area according | ||
273 | * to the virtual address. | ||
274 | */ | ||
275 | |||
276 | static dma_addr_t sep_shared_virt_to_bus(struct sep_device *sep, | ||
277 | void *virt_address) | ||
278 | { | ||
279 | dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr); | ||
280 | edbg("sep: virt to bus b %08llx v %p\n", (unsigned long long) pa, | ||
281 | virt_address); | ||
282 | return pa; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * sep_shared_bus_to_virt - convert bus/virt addresses | ||
287 | * | ||
288 | * Returns virtual address inside the shared area according | ||
289 | * to the bus address. | ||
290 | */ | ||
291 | |||
292 | static void *sep_shared_bus_to_virt(struct sep_device *sep, | ||
293 | dma_addr_t bus_address) | ||
294 | { | ||
295 | return sep->shared_addr + (bus_address - sep->shared_bus); | ||
296 | } | ||
297 | |||
298 | |||
299 | /** | ||
300 | * sep_try_open - attempt to open a SEP device | ||
301 | * @sep: device to attempt to open | ||
302 | * | ||
303 | * Atomically attempt to get ownership of a SEP device. | ||
304 | * Returns 1 if the device was opened, 0 on failure. | ||
305 | */ | ||
306 | |||
307 | static int sep_try_open(struct sep_device *sep) | ||
308 | { | ||
309 | if (!test_and_set_bit(0, &sep->in_use)) | ||
310 | return 1; | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | /** | ||
315 | * sep_open - device open method | ||
316 | * @inode: inode of sep device | ||
317 | * @filp: file handle to sep device | ||
318 | * | ||
319 | * Open method for the SEP device. Called when userspace opens | ||
320 | * the SEP device node. Must also release the memory data pool | ||
321 | * allocations. | ||
322 | * | ||
323 | * Returns zero on success otherwise an error code. | ||
324 | */ | ||
325 | |||
326 | static int sep_open(struct inode *inode, struct file *filp) | ||
327 | { | ||
328 | if (sep_dev == NULL) | ||
329 | return -ENODEV; | ||
330 | |||
331 | /* check the blocking mode */ | ||
332 | if (filp->f_flags & O_NDELAY) { | ||
333 | if (sep_try_open(sep_dev) == 0) | ||
334 | return -EAGAIN; | ||
335 | } else | ||
336 | if (wait_event_interruptible(sep_event, sep_try_open(sep_dev)) < 0) | ||
337 | return -EINTR; | ||
338 | |||
339 | /* Bind to the device, we only have one which makes it easy */ | ||
340 | filp->private_data = sep_dev; | ||
341 | /* release data pool allocations */ | ||
342 | sep_dev->data_pool_bytes_allocated = 0; | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | |||
347 | /** | ||
348 | * sep_release - close a SEP device | ||
349 | * @inode: inode of SEP device | ||
350 | * @filp: file handle being closed | ||
351 | * | ||
352 | * Called on the final close of a SEP device. As the open protects against | ||
353 | * multiple simultaenous opens that means this method is called when the | ||
354 | * final reference to the open handle is dropped. | ||
355 | */ | ||
356 | |||
357 | static int sep_release(struct inode *inode, struct file *filp) | ||
358 | { | ||
359 | struct sep_device *sep = filp->private_data; | ||
360 | #if 0 /*!SEP_DRIVER_POLLING_MODE */ | ||
361 | /* close IMR */ | ||
362 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF); | ||
363 | /* release IRQ line */ | ||
364 | free_irq(SEP_DIRVER_IRQ_NUM, sep); | ||
365 | |||
366 | #endif | ||
367 | /* Ensure any blocked open progresses */ | ||
368 | clear_bit(0, &sep->in_use); | ||
369 | wake_up(&sep_event); | ||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | /*--------------------------------------------------------------- | ||
374 | map function - this functions maps the message shared area | ||
375 | -----------------------------------------------------------------*/ | ||
376 | static int sep_mmap(struct file *filp, struct vm_area_struct *vma) | ||
377 | { | ||
378 | dma_addr_t bus_addr; | ||
379 | struct sep_device *sep = filp->private_data; | ||
380 | |||
381 | dbg("-------->SEP Driver: mmap start\n"); | ||
382 | |||
383 | /* check that the size of the mapped range is as the size of the message | ||
384 | shared area */ | ||
385 | if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { | ||
386 | edbg("SEP Driver mmap requested size is more than allowed\n"); | ||
387 | printk(KERN_WARNING "SEP Driver mmap requested size is more than allowed\n"); | ||
388 | printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_end); | ||
389 | printk(KERN_WARNING "SEP Driver vma->vm_end is %08lx\n", vma->vm_start); | ||
390 | return -EAGAIN; | ||
391 | } | ||
392 | |||
393 | edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr); | ||
394 | |||
395 | /* get bus address */ | ||
396 | bus_addr = sep->shared_bus; | ||
397 | |||
398 | edbg("SEP Driver: phys_addr is %08llx\n", (unsigned long long)bus_addr); | ||
399 | |||
400 | if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { | ||
401 | edbg("SEP Driver remap_page_range failed\n"); | ||
402 | printk(KERN_WARNING "SEP Driver remap_page_range failed\n"); | ||
403 | return -EAGAIN; | ||
404 | } | ||
405 | |||
406 | dbg("SEP Driver:<-------- mmap end\n"); | ||
407 | |||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | |||
412 | /*----------------------------------------------- | ||
413 | poll function | ||
414 | *----------------------------------------------*/ | ||
415 | static unsigned int sep_poll(struct file *filp, poll_table * wait) | ||
416 | { | ||
417 | unsigned long count; | ||
418 | unsigned int mask = 0; | ||
419 | unsigned long retval = 0; /* flow id */ | ||
420 | struct sep_device *sep = filp->private_data; | ||
421 | |||
422 | dbg("---------->SEP Driver poll: start\n"); | ||
423 | |||
424 | |||
425 | #if SEP_DRIVER_POLLING_MODE | ||
426 | |||
427 | while (sep->send_ct != (retval & 0x7FFFFFFF)) { | ||
428 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); | ||
429 | |||
430 | for (count = 0; count < 10 * 4; count += 4) | ||
431 | edbg("Poll Debug Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + count))); | ||
432 | } | ||
433 | |||
434 | sep->reply_ct++; | ||
435 | #else | ||
436 | /* add the event to the polling wait table */ | ||
437 | poll_wait(filp, &sep_event, wait); | ||
438 | |||
439 | #endif | ||
440 | |||
441 | edbg("sep->send_ct is %lu\n", sep->send_ct); | ||
442 | edbg("sep->reply_ct is %lu\n", sep->reply_ct); | ||
443 | |||
444 | /* check if the data is ready */ | ||
445 | if (sep->send_ct == sep->reply_ct) { | ||
446 | for (count = 0; count < 12 * 4; count += 4) | ||
447 | edbg("Sep Mesg Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count))); | ||
448 | |||
449 | for (count = 0; count < 10 * 4; count += 4) | ||
450 | edbg("Debug Data Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + 0x1800 + count))); | ||
451 | |||
452 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); | ||
453 | edbg("retval is %lu\n", retval); | ||
454 | /* check if the this is sep reply or request */ | ||
455 | if (retval >> 31) { | ||
456 | edbg("SEP Driver: sep request in\n"); | ||
457 | /* request */ | ||
458 | mask |= POLLOUT | POLLWRNORM; | ||
459 | } else { | ||
460 | edbg("SEP Driver: sep reply in\n"); | ||
461 | mask |= POLLIN | POLLRDNORM; | ||
462 | } | ||
463 | } | ||
464 | dbg("SEP Driver:<-------- poll exit\n"); | ||
465 | return mask; | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * sep_time_address - address in SEP memory of time | ||
470 | * @sep: SEP device we want the address from | ||
471 | * | ||
472 | * Return the address of the two dwords in memory used for time | ||
473 | * setting. | ||
474 | */ | ||
475 | |||
476 | static u32 *sep_time_address(struct sep_device *sep) | ||
477 | { | ||
478 | return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; | ||
479 | } | ||
480 | |||
481 | /** | ||
482 | * sep_set_time - set the SEP time | ||
483 | * @sep: the SEP we are setting the time for | ||
484 | * | ||
485 | * Calculates time and sets it at the predefined address. | ||
486 | * Called with the sep mutex held. | ||
487 | */ | ||
488 | static unsigned long sep_set_time(struct sep_device *sep) | ||
489 | { | ||
490 | struct timeval time; | ||
491 | u32 *time_addr; /* address of time as seen by the kernel */ | ||
492 | |||
493 | |||
494 | dbg("sep:sep_set_time start\n"); | ||
495 | |||
496 | do_gettimeofday(&time); | ||
497 | |||
498 | /* set value in the SYSTEM MEMORY offset */ | ||
499 | time_addr = sep_time_address(sep); | ||
500 | |||
501 | time_addr[0] = SEP_TIME_VAL_TOKEN; | ||
502 | time_addr[1] = time.tv_sec; | ||
503 | |||
504 | edbg("SEP Driver:time.tv_sec is %lu\n", time.tv_sec); | ||
505 | edbg("SEP Driver:time_addr is %p\n", time_addr); | ||
506 | edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr); | ||
507 | |||
508 | return time.tv_sec; | ||
509 | } | ||
510 | |||
511 | /** | ||
512 | * sep_dump_message - dump the message that is pending | ||
513 | * @sep: sep device | ||
514 | * | ||
515 | * Dump out the message pending in the shared message area | ||
516 | */ | ||
517 | |||
518 | static void sep_dump_message(struct sep_device *sep) | ||
519 | { | ||
520 | int count; | ||
521 | for (count = 0; count < 12 * 4; count += 4) | ||
522 | edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count))); | ||
523 | } | ||
524 | |||
525 | /** | ||
526 | * sep_send_command_handler - kick off a command | ||
527 | * @sep: sep being signalled | ||
528 | * | ||
529 | * This function raises interrupt to SEP that signals that is has a new | ||
530 | * command from the host | ||
531 | */ | ||
532 | |||
533 | static void sep_send_command_handler(struct sep_device *sep) | ||
534 | { | ||
535 | dbg("sep:sep_send_command_handler start\n"); | ||
536 | |||
537 | mutex_lock(&sep_mutex); | ||
538 | sep_set_time(sep); | ||
539 | |||
540 | /* FIXME: flush cache */ | ||
541 | flush_cache_all(); | ||
542 | |||
543 | sep_dump_message(sep); | ||
544 | /* update counter */ | ||
545 | sep->send_ct++; | ||
546 | /* send interrupt to SEP */ | ||
547 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); | ||
548 | dbg("SEP Driver:<-------- sep_send_command_handler end\n"); | ||
549 | mutex_unlock(&sep_mutex); | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | /** | ||
554 | * sep_send_reply_command_handler - kick off a command reply | ||
555 | * @sep: sep being signalled | ||
556 | * | ||
557 | * This function raises interrupt to SEP that signals that is has a new | ||
558 | * command from the host | ||
559 | */ | ||
560 | |||
561 | static void sep_send_reply_command_handler(struct sep_device *sep) | ||
562 | { | ||
563 | dbg("sep:sep_send_reply_command_handler start\n"); | ||
564 | |||
565 | /* flash cache */ | ||
566 | flush_cache_all(); | ||
567 | |||
568 | sep_dump_message(sep); | ||
569 | |||
570 | mutex_lock(&sep_mutex); | ||
571 | sep->send_ct++; /* update counter */ | ||
572 | /* send the interrupt to SEP */ | ||
573 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct); | ||
574 | /* update both counters */ | ||
575 | sep->send_ct++; | ||
576 | sep->reply_ct++; | ||
577 | mutex_unlock(&sep_mutex); | ||
578 | dbg("sep: sep_send_reply_command_handler end\n"); | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | This function handles the allocate data pool memory request | ||
583 | This function returns calculates the bus address of the | ||
584 | allocated memory, and the offset of this area from the mapped address. | ||
585 | Therefore, the FVOs in user space can calculate the exact virtual | ||
586 | address of this allocated memory | ||
587 | */ | ||
588 | static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, | ||
589 | unsigned long arg) | ||
590 | { | ||
591 | int error; | ||
592 | struct sep_driver_alloc_t command_args; | ||
593 | |||
594 | dbg("SEP Driver:--------> sep_allocate_data_pool_memory_handler start\n"); | ||
595 | |||
596 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_alloc_t)); | ||
597 | if (error) { | ||
598 | error = -EFAULT; | ||
599 | goto end_function; | ||
600 | } | ||
601 | |||
602 | /* allocate memory */ | ||
603 | if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { | ||
604 | error = -ENOMEM; | ||
605 | goto end_function; | ||
606 | } | ||
607 | |||
608 | /* set the virtual and bus address */ | ||
609 | command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; | ||
610 | command_args.phys_address = sep->shared_bus + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; | ||
611 | |||
612 | /* write the memory back to the user space */ | ||
613 | error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_alloc_t)); | ||
614 | if (error) { | ||
615 | error = -EFAULT; | ||
616 | goto end_function; | ||
617 | } | ||
618 | |||
619 | /* set the allocation */ | ||
620 | sep->data_pool_bytes_allocated += command_args.num_bytes; | ||
621 | |||
622 | end_function: | ||
623 | dbg("SEP Driver:<-------- sep_allocate_data_pool_memory_handler end\n"); | ||
624 | return error; | ||
625 | } | ||
626 | |||
627 | /* | ||
628 | This function handles write into allocated data pool command | ||
629 | */ | ||
630 | static int sep_write_into_data_pool_handler(struct sep_device *sep, unsigned long arg) | ||
631 | { | ||
632 | int error; | ||
633 | void *virt_address; | ||
634 | unsigned long va; | ||
635 | unsigned long app_in_address; | ||
636 | unsigned long num_bytes; | ||
637 | void *data_pool_area_addr; | ||
638 | |||
639 | dbg("SEP Driver:--------> sep_write_into_data_pool_handler start\n"); | ||
640 | |||
641 | /* get the application address */ | ||
642 | error = get_user(app_in_address, &(((struct sep_driver_write_t *) arg)->app_address)); | ||
643 | if (error) | ||
644 | goto end_function; | ||
645 | |||
646 | /* get the virtual kernel address address */ | ||
647 | error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address)); | ||
648 | if (error) | ||
649 | goto end_function; | ||
650 | virt_address = (void *)va; | ||
651 | |||
652 | /* get the number of bytes */ | ||
653 | error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes)); | ||
654 | if (error) | ||
655 | goto end_function; | ||
656 | |||
657 | /* calculate the start of the data pool */ | ||
658 | data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES; | ||
659 | |||
660 | |||
661 | /* check that the range of the virtual kernel address is correct */ | ||
662 | if (virt_address < data_pool_area_addr || virt_address > (data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES)) { | ||
663 | error = -EINVAL; | ||
664 | goto end_function; | ||
665 | } | ||
666 | /* copy the application data */ | ||
667 | error = copy_from_user(virt_address, (void *) app_in_address, num_bytes); | ||
668 | if (error) | ||
669 | error = -EFAULT; | ||
670 | end_function: | ||
671 | dbg("SEP Driver:<-------- sep_write_into_data_pool_handler end\n"); | ||
672 | return error; | ||
673 | } | ||
674 | |||
675 | /* | ||
676 | this function handles the read from data pool command | ||
677 | */ | ||
678 | static int sep_read_from_data_pool_handler(struct sep_device *sep, unsigned long arg) | ||
679 | { | ||
680 | int error; | ||
681 | /* virtual address of dest application buffer */ | ||
682 | unsigned long app_out_address; | ||
683 | /* virtual address of the data pool */ | ||
684 | unsigned long va; | ||
685 | void *virt_address; | ||
686 | unsigned long num_bytes; | ||
687 | void *data_pool_area_addr; | ||
688 | |||
689 | dbg("SEP Driver:--------> sep_read_from_data_pool_handler start\n"); | ||
690 | |||
691 | /* get the application address */ | ||
692 | error = get_user(app_out_address, &(((struct sep_driver_write_t *) arg)->app_address)); | ||
693 | if (error) | ||
694 | goto end_function; | ||
695 | |||
696 | /* get the virtual kernel address address */ | ||
697 | error = get_user(va, &(((struct sep_driver_write_t *) arg)->datapool_address)); | ||
698 | if (error) | ||
699 | goto end_function; | ||
700 | virt_address = (void *)va; | ||
701 | |||
702 | /* get the number of bytes */ | ||
703 | error = get_user(num_bytes, &(((struct sep_driver_write_t *) arg)->num_bytes)); | ||
704 | if (error) | ||
705 | goto end_function; | ||
706 | |||
707 | /* calculate the start of the data pool */ | ||
708 | data_pool_area_addr = sep->shared_addr + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES; | ||
709 | |||
710 | /* FIXME: These are incomplete all over the driver: what about + len | ||
711 | and when doing that also overflows */ | ||
712 | /* check that the range of the virtual kernel address is correct */ | ||
713 | if (virt_address < data_pool_area_addr || virt_address > data_pool_area_addr + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { | ||
714 | error = -EINVAL; | ||
715 | goto end_function; | ||
716 | } | ||
717 | |||
718 | /* copy the application data */ | ||
719 | error = copy_to_user((void *) app_out_address, virt_address, num_bytes); | ||
720 | if (error) | ||
721 | error = -EFAULT; | ||
722 | end_function: | ||
723 | dbg("SEP Driver:<-------- sep_read_from_data_pool_handler end\n"); | ||
724 | return error; | ||
725 | } | ||
726 | |||
727 | /* | ||
728 | This function releases all the application virtual buffer physical pages, | ||
729 | that were previously locked | ||
730 | */ | ||
731 | static int sep_free_dma_pages(struct page **page_array_ptr, unsigned long num_pages, unsigned long dirtyFlag) | ||
732 | { | ||
733 | unsigned long count; | ||
734 | |||
735 | if (dirtyFlag) { | ||
736 | for (count = 0; count < num_pages; count++) { | ||
737 | /* the out array was written, therefore the data was changed */ | ||
738 | if (!PageReserved(page_array_ptr[count])) | ||
739 | SetPageDirty(page_array_ptr[count]); | ||
740 | page_cache_release(page_array_ptr[count]); | ||
741 | } | ||
742 | } else { | ||
743 | /* free in pages - the data was only read, therefore no update was done | ||
744 | on those pages */ | ||
745 | for (count = 0; count < num_pages; count++) | ||
746 | page_cache_release(page_array_ptr[count]); | ||
747 | } | ||
748 | |||
749 | if (page_array_ptr) | ||
750 | /* free the array */ | ||
751 | kfree(page_array_ptr); | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | /* | ||
757 | This function locks all the physical pages of the kernel virtual buffer | ||
758 | and construct a basic lli array, where each entry holds the physical | ||
759 | page address and the size that application data holds in this physical pages | ||
760 | */ | ||
761 | static int sep_lock_kernel_pages(struct sep_device *sep, | ||
762 | unsigned long kernel_virt_addr, | ||
763 | unsigned long data_size, | ||
764 | unsigned long *num_pages_ptr, | ||
765 | struct sep_lli_entry_t **lli_array_ptr, | ||
766 | struct page ***page_array_ptr) | ||
767 | { | ||
768 | int error = 0; | ||
769 | /* the the page of the end address of the user space buffer */ | ||
770 | unsigned long end_page; | ||
771 | /* the page of the start address of the user space buffer */ | ||
772 | unsigned long start_page; | ||
773 | /* the range in pages */ | ||
774 | unsigned long num_pages; | ||
775 | struct sep_lli_entry_t *lli_array; | ||
776 | /* next kernel address to map */ | ||
777 | unsigned long next_kernel_address; | ||
778 | unsigned long count; | ||
779 | |||
780 | dbg("SEP Driver:--------> sep_lock_kernel_pages start\n"); | ||
781 | |||
782 | /* set start and end pages and num pages */ | ||
783 | end_page = (kernel_virt_addr + data_size - 1) >> PAGE_SHIFT; | ||
784 | start_page = kernel_virt_addr >> PAGE_SHIFT; | ||
785 | num_pages = end_page - start_page + 1; | ||
786 | |||
787 | edbg("SEP Driver: kernel_virt_addr is %08lx\n", kernel_virt_addr); | ||
788 | edbg("SEP Driver: data_size is %lu\n", data_size); | ||
789 | edbg("SEP Driver: start_page is %lx\n", start_page); | ||
790 | edbg("SEP Driver: end_page is %lx\n", end_page); | ||
791 | edbg("SEP Driver: num_pages is %lu\n", num_pages); | ||
792 | |||
793 | lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC); | ||
794 | if (!lli_array) { | ||
795 | edbg("SEP Driver: kmalloc for lli_array failed\n"); | ||
796 | error = -ENOMEM; | ||
797 | goto end_function; | ||
798 | } | ||
799 | |||
800 | /* set the start address of the first page - app data may start not at | ||
801 | the beginning of the page */ | ||
802 | lli_array[0].physical_address = (unsigned long) virt_to_phys((unsigned long *) kernel_virt_addr); | ||
803 | |||
804 | /* check that not all the data is in the first page only */ | ||
805 | if ((PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK))) >= data_size) | ||
806 | lli_array[0].block_size = data_size; | ||
807 | else | ||
808 | lli_array[0].block_size = PAGE_SIZE - (kernel_virt_addr & (~PAGE_MASK)); | ||
809 | |||
810 | /* debug print */ | ||
811 | dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size); | ||
812 | |||
813 | /* advance the address to the start of the next page */ | ||
814 | next_kernel_address = (kernel_virt_addr & PAGE_MASK) + PAGE_SIZE; | ||
815 | |||
816 | /* go from the second page to the prev before last */ | ||
817 | for (count = 1; count < (num_pages - 1); count++) { | ||
818 | lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address); | ||
819 | lli_array[count].block_size = PAGE_SIZE; | ||
820 | |||
821 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
822 | next_kernel_address += PAGE_SIZE; | ||
823 | } | ||
824 | |||
825 | /* if more then 1 pages locked - then update for the last page size needed */ | ||
826 | if (num_pages > 1) { | ||
827 | /* update the address of the last page */ | ||
828 | lli_array[count].physical_address = (unsigned long) virt_to_phys((unsigned long *) next_kernel_address); | ||
829 | |||
830 | /* set the size of the last page */ | ||
831 | lli_array[count].block_size = (kernel_virt_addr + data_size) & (~PAGE_MASK); | ||
832 | |||
833 | if (lli_array[count].block_size == 0) { | ||
834 | dbg("app_virt_addr is %08lx\n", kernel_virt_addr); | ||
835 | dbg("data_size is %lu\n", data_size); | ||
836 | while (1); | ||
837 | } | ||
838 | |||
839 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
840 | } | ||
841 | /* set output params */ | ||
842 | *lli_array_ptr = lli_array; | ||
843 | *num_pages_ptr = num_pages; | ||
844 | *page_array_ptr = 0; | ||
845 | end_function: | ||
846 | dbg("SEP Driver:<-------- sep_lock_kernel_pages end\n"); | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | /* | ||
851 | This function locks all the physical pages of the application virtual buffer | ||
852 | and construct a basic lli array, where each entry holds the physical page | ||
853 | address and the size that application data holds in this physical pages | ||
854 | */ | ||
855 | static int sep_lock_user_pages(struct sep_device *sep, | ||
856 | unsigned long app_virt_addr, | ||
857 | unsigned long data_size, | ||
858 | unsigned long *num_pages_ptr, | ||
859 | struct sep_lli_entry_t **lli_array_ptr, | ||
860 | struct page ***page_array_ptr) | ||
861 | { | ||
862 | int error = 0; | ||
863 | /* the the page of the end address of the user space buffer */ | ||
864 | unsigned long end_page; | ||
865 | /* the page of the start address of the user space buffer */ | ||
866 | unsigned long start_page; | ||
867 | /* the range in pages */ | ||
868 | unsigned long num_pages; | ||
869 | struct page **page_array; | ||
870 | struct sep_lli_entry_t *lli_array; | ||
871 | unsigned long count; | ||
872 | int result; | ||
873 | |||
874 | dbg("SEP Driver:--------> sep_lock_user_pages start\n"); | ||
875 | |||
876 | /* set start and end pages and num pages */ | ||
877 | end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; | ||
878 | start_page = app_virt_addr >> PAGE_SHIFT; | ||
879 | num_pages = end_page - start_page + 1; | ||
880 | |||
881 | edbg("SEP Driver: app_virt_addr is %08lx\n", app_virt_addr); | ||
882 | edbg("SEP Driver: data_size is %lu\n", data_size); | ||
883 | edbg("SEP Driver: start_page is %lu\n", start_page); | ||
884 | edbg("SEP Driver: end_page is %lu\n", end_page); | ||
885 | edbg("SEP Driver: num_pages is %lu\n", num_pages); | ||
886 | |||
887 | /* allocate array of pages structure pointers */ | ||
888 | page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); | ||
889 | if (!page_array) { | ||
890 | edbg("SEP Driver: kmalloc for page_array failed\n"); | ||
891 | |||
892 | error = -ENOMEM; | ||
893 | goto end_function; | ||
894 | } | ||
895 | |||
896 | lli_array = kmalloc(sizeof(struct sep_lli_entry_t) * num_pages, GFP_ATOMIC); | ||
897 | if (!lli_array) { | ||
898 | edbg("SEP Driver: kmalloc for lli_array failed\n"); | ||
899 | |||
900 | error = -ENOMEM; | ||
901 | goto end_function_with_error1; | ||
902 | } | ||
903 | |||
904 | /* convert the application virtual address into a set of physical */ | ||
905 | down_read(¤t->mm->mmap_sem); | ||
906 | result = get_user_pages(current, current->mm, app_virt_addr, num_pages, 1, 0, page_array, 0); | ||
907 | up_read(¤t->mm->mmap_sem); | ||
908 | |||
909 | /* check the number of pages locked - if not all then exit with error */ | ||
910 | if (result != num_pages) { | ||
911 | dbg("SEP Driver: not all pages locked by get_user_pages\n"); | ||
912 | |||
913 | error = -ENOMEM; | ||
914 | goto end_function_with_error2; | ||
915 | } | ||
916 | |||
917 | /* flush the cache */ | ||
918 | for (count = 0; count < num_pages; count++) | ||
919 | flush_dcache_page(page_array[count]); | ||
920 | |||
921 | /* set the start address of the first page - app data may start not at | ||
922 | the beginning of the page */ | ||
923 | lli_array[0].physical_address = ((unsigned long) page_to_phys(page_array[0])) + (app_virt_addr & (~PAGE_MASK)); | ||
924 | |||
925 | /* check that not all the data is in the first page only */ | ||
926 | if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) | ||
927 | lli_array[0].block_size = data_size; | ||
928 | else | ||
929 | lli_array[0].block_size = PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); | ||
930 | |||
931 | /* debug print */ | ||
932 | dbg("lli_array[0].physical_address is %08lx, lli_array[0].block_size is %lu\n", lli_array[0].physical_address, lli_array[0].block_size); | ||
933 | |||
934 | /* go from the second page to the prev before last */ | ||
935 | for (count = 1; count < (num_pages - 1); count++) { | ||
936 | lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]); | ||
937 | lli_array[count].block_size = PAGE_SIZE; | ||
938 | |||
939 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", count, lli_array[count].physical_address, count, lli_array[count].block_size); | ||
940 | } | ||
941 | |||
942 | /* if more then 1 pages locked - then update for the last page size needed */ | ||
943 | if (num_pages > 1) { | ||
944 | /* update the address of the last page */ | ||
945 | lli_array[count].physical_address = (unsigned long) page_to_phys(page_array[count]); | ||
946 | |||
947 | /* set the size of the last page */ | ||
948 | lli_array[count].block_size = (app_virt_addr + data_size) & (~PAGE_MASK); | ||
949 | |||
950 | if (lli_array[count].block_size == 0) { | ||
951 | dbg("app_virt_addr is %08lx\n", app_virt_addr); | ||
952 | dbg("data_size is %lu\n", data_size); | ||
953 | while (1); | ||
954 | } | ||
955 | edbg("lli_array[%lu].physical_address is %08lx, lli_array[%lu].block_size is %lu\n", | ||
956 | count, lli_array[count].physical_address, | ||
957 | count, lli_array[count].block_size); | ||
958 | } | ||
959 | |||
960 | /* set output params */ | ||
961 | *lli_array_ptr = lli_array; | ||
962 | *num_pages_ptr = num_pages; | ||
963 | *page_array_ptr = page_array; | ||
964 | goto end_function; | ||
965 | |||
966 | end_function_with_error2: | ||
967 | /* release the cache */ | ||
968 | for (count = 0; count < num_pages; count++) | ||
969 | page_cache_release(page_array[count]); | ||
970 | kfree(lli_array); | ||
971 | end_function_with_error1: | ||
972 | kfree(page_array); | ||
973 | end_function: | ||
974 | dbg("SEP Driver:<-------- sep_lock_user_pages end\n"); | ||
975 | return 0; | ||
976 | } | ||
977 | |||
978 | |||
979 | /* | ||
980 | this function calculates the size of data that can be inserted into the lli | ||
981 | table from this array the condition is that either the table is full | ||
982 | (all etnries are entered), or there are no more entries in the lli array | ||
983 | */ | ||
984 | static unsigned long sep_calculate_lli_table_max_size(struct sep_lli_entry_t *lli_in_array_ptr, unsigned long num_array_entries) | ||
985 | { | ||
986 | unsigned long table_data_size = 0; | ||
987 | unsigned long counter; | ||
988 | |||
989 | /* calculate the data in the out lli table if till we fill the whole | ||
990 | table or till the data has ended */ | ||
991 | for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && (counter < num_array_entries); counter++) | ||
992 | table_data_size += lli_in_array_ptr[counter].block_size; | ||
993 | return table_data_size; | ||
994 | } | ||
995 | |||
996 | /* | ||
997 | this functions builds ont lli table from the lli_array according to | ||
998 | the given size of data | ||
999 | */ | ||
1000 | static void sep_build_lli_table(struct sep_lli_entry_t *lli_array_ptr, struct sep_lli_entry_t *lli_table_ptr, unsigned long *num_processed_entries_ptr, unsigned long *num_table_entries_ptr, unsigned long table_data_size) | ||
1001 | { | ||
1002 | unsigned long curr_table_data_size; | ||
1003 | /* counter of lli array entry */ | ||
1004 | unsigned long array_counter; | ||
1005 | |||
1006 | dbg("SEP Driver:--------> sep_build_lli_table start\n"); | ||
1007 | |||
1008 | /* init currrent table data size and lli array entry counter */ | ||
1009 | curr_table_data_size = 0; | ||
1010 | array_counter = 0; | ||
1011 | *num_table_entries_ptr = 1; | ||
1012 | |||
1013 | edbg("SEP Driver:table_data_size is %lu\n", table_data_size); | ||
1014 | |||
1015 | /* fill the table till table size reaches the needed amount */ | ||
1016 | while (curr_table_data_size < table_data_size) { | ||
1017 | /* update the number of entries in table */ | ||
1018 | (*num_table_entries_ptr)++; | ||
1019 | |||
1020 | lli_table_ptr->physical_address = lli_array_ptr[array_counter].physical_address; | ||
1021 | lli_table_ptr->block_size = lli_array_ptr[array_counter].block_size; | ||
1022 | curr_table_data_size += lli_table_ptr->block_size; | ||
1023 | |||
1024 | edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr); | ||
1025 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1026 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1027 | |||
1028 | /* check for overflow of the table data */ | ||
1029 | if (curr_table_data_size > table_data_size) { | ||
1030 | edbg("SEP Driver:curr_table_data_size > table_data_size\n"); | ||
1031 | |||
1032 | /* update the size of block in the table */ | ||
1033 | lli_table_ptr->block_size -= (curr_table_data_size - table_data_size); | ||
1034 | |||
1035 | /* update the physical address in the lli array */ | ||
1036 | lli_array_ptr[array_counter].physical_address += lli_table_ptr->block_size; | ||
1037 | |||
1038 | /* update the block size left in the lli array */ | ||
1039 | lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size); | ||
1040 | } else | ||
1041 | /* advance to the next entry in the lli_array */ | ||
1042 | array_counter++; | ||
1043 | |||
1044 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1045 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1046 | |||
1047 | /* move to the next entry in table */ | ||
1048 | lli_table_ptr++; | ||
1049 | } | ||
1050 | |||
1051 | /* set the info entry to default */ | ||
1052 | lli_table_ptr->physical_address = 0xffffffff; | ||
1053 | lli_table_ptr->block_size = 0; | ||
1054 | |||
1055 | edbg("SEP Driver:lli_table_ptr is %08lx\n", (unsigned long) lli_table_ptr); | ||
1056 | edbg("SEP Driver:lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1057 | edbg("SEP Driver:lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1058 | |||
1059 | /* set the output parameter */ | ||
1060 | *num_processed_entries_ptr += array_counter; | ||
1061 | |||
1062 | edbg("SEP Driver:*num_processed_entries_ptr is %lu\n", *num_processed_entries_ptr); | ||
1063 | dbg("SEP Driver:<-------- sep_build_lli_table end\n"); | ||
1064 | return; | ||
1065 | } | ||
1066 | |||
1067 | /* | ||
1068 | this function goes over the list of the print created tables and | ||
1069 | prints all the data | ||
1070 | */ | ||
1071 | static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry_t *lli_table_ptr, unsigned long num_table_entries, unsigned long table_data_size) | ||
1072 | { | ||
1073 | unsigned long table_count; | ||
1074 | unsigned long entries_count; | ||
1075 | |||
1076 | dbg("SEP Driver:--------> sep_debug_print_lli_tables start\n"); | ||
1077 | |||
1078 | table_count = 1; | ||
1079 | while ((unsigned long) lli_table_ptr != 0xffffffff) { | ||
1080 | edbg("SEP Driver: lli table %08lx, table_data_size is %lu\n", table_count, table_data_size); | ||
1081 | edbg("SEP Driver: num_table_entries is %lu\n", num_table_entries); | ||
1082 | |||
1083 | /* print entries of the table (without info entry) */ | ||
1084 | for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) { | ||
1085 | edbg("SEP Driver:lli_table_ptr address is %08lx\n", (unsigned long) lli_table_ptr); | ||
1086 | edbg("SEP Driver:phys address is %08lx block size is %lu\n", lli_table_ptr->physical_address, lli_table_ptr->block_size); | ||
1087 | } | ||
1088 | |||
1089 | /* point to the info entry */ | ||
1090 | lli_table_ptr--; | ||
1091 | |||
1092 | edbg("SEP Driver:phys lli_table_ptr->block_size is %lu\n", lli_table_ptr->block_size); | ||
1093 | edbg("SEP Driver:phys lli_table_ptr->physical_address is %08lx\n", lli_table_ptr->physical_address); | ||
1094 | |||
1095 | |||
1096 | table_data_size = lli_table_ptr->block_size & 0xffffff; | ||
1097 | num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; | ||
1098 | lli_table_ptr = (struct sep_lli_entry_t *) | ||
1099 | (lli_table_ptr->physical_address); | ||
1100 | |||
1101 | edbg("SEP Driver:phys table_data_size is %lu num_table_entries is %lu lli_table_ptr is%lu\n", table_data_size, num_table_entries, (unsigned long) lli_table_ptr); | ||
1102 | |||
1103 | if ((unsigned long) lli_table_ptr != 0xffffffff) | ||
1104 | lli_table_ptr = (struct sep_lli_entry_t *) sep_shared_bus_to_virt(sep, (unsigned long) lli_table_ptr); | ||
1105 | |||
1106 | table_count++; | ||
1107 | } | ||
1108 | dbg("SEP Driver:<-------- sep_debug_print_lli_tables end\n"); | ||
1109 | } | ||
1110 | |||
1111 | |||
1112 | /* | ||
1113 | This function prepares only input DMA table for synhronic symmetric | ||
1114 | operations (HASH) | ||
1115 | */ | ||
1116 | static int sep_prepare_input_dma_table(struct sep_device *sep, | ||
1117 | unsigned long app_virt_addr, | ||
1118 | unsigned long data_size, | ||
1119 | unsigned long block_size, | ||
1120 | unsigned long *lli_table_ptr, | ||
1121 | unsigned long *num_entries_ptr, | ||
1122 | unsigned long *table_data_size_ptr, | ||
1123 | bool isKernelVirtualAddress) | ||
1124 | { | ||
1125 | /* pointer to the info entry of the table - the last entry */ | ||
1126 | struct sep_lli_entry_t *info_entry_ptr; | ||
1127 | /* array of pointers ot page */ | ||
1128 | struct sep_lli_entry_t *lli_array_ptr; | ||
1129 | /* points to the first entry to be processed in the lli_in_array */ | ||
1130 | unsigned long current_entry; | ||
1131 | /* num entries in the virtual buffer */ | ||
1132 | unsigned long sep_lli_entries; | ||
1133 | /* lli table pointer */ | ||
1134 | struct sep_lli_entry_t *in_lli_table_ptr; | ||
1135 | /* the total data in one table */ | ||
1136 | unsigned long table_data_size; | ||
1137 | /* number of entries in lli table */ | ||
1138 | unsigned long num_entries_in_table; | ||
1139 | /* next table address */ | ||
1140 | void *lli_table_alloc_addr; | ||
1141 | unsigned long result; | ||
1142 | |||
1143 | dbg("SEP Driver:--------> sep_prepare_input_dma_table start\n"); | ||
1144 | |||
1145 | edbg("SEP Driver:data_size is %lu\n", data_size); | ||
1146 | edbg("SEP Driver:block_size is %lu\n", block_size); | ||
1147 | |||
1148 | /* initialize the pages pointers */ | ||
1149 | sep->in_page_array = 0; | ||
1150 | sep->in_num_pages = 0; | ||
1151 | |||
1152 | if (data_size == 0) { | ||
1153 | /* special case - created 2 entries table with zero data */ | ||
1154 | in_lli_table_ptr = (struct sep_lli_entry_t *) (sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES); | ||
1155 | /* FIXME: Should the entry below not be for _bus */ | ||
1156 | in_lli_table_ptr->physical_address = (unsigned long)sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1157 | in_lli_table_ptr->block_size = 0; | ||
1158 | |||
1159 | in_lli_table_ptr++; | ||
1160 | in_lli_table_ptr->physical_address = 0xFFFFFFFF; | ||
1161 | in_lli_table_ptr->block_size = 0; | ||
1162 | |||
1163 | *lli_table_ptr = sep->shared_bus + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1164 | *num_entries_ptr = 2; | ||
1165 | *table_data_size_ptr = 0; | ||
1166 | |||
1167 | goto end_function; | ||
1168 | } | ||
1169 | |||
1170 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1171 | if (isKernelVirtualAddress == true) | ||
1172 | /* lock the pages of the kernel buffer and translate them to pages */ | ||
1173 | result = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array); | ||
1174 | else | ||
1175 | /* lock the pages of the user buffer and translate them to pages */ | ||
1176 | result = sep_lock_user_pages(sep, app_virt_addr, data_size, &sep->in_num_pages, &lli_array_ptr, &sep->in_page_array); | ||
1177 | |||
1178 | if (result) | ||
1179 | return result; | ||
1180 | |||
1181 | edbg("SEP Driver:output sep->in_num_pages is %lu\n", sep->in_num_pages); | ||
1182 | |||
1183 | current_entry = 0; | ||
1184 | info_entry_ptr = 0; | ||
1185 | sep_lli_entries = sep->in_num_pages; | ||
1186 | |||
1187 | /* initiate to point after the message area */ | ||
1188 | lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1189 | |||
1190 | /* loop till all the entries in in array are not processed */ | ||
1191 | while (current_entry < sep_lli_entries) { | ||
1192 | /* set the new input and output tables */ | ||
1193 | in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1194 | |||
1195 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1196 | |||
1197 | /* calculate the maximum size of data for input table */ | ||
1198 | table_data_size = sep_calculate_lli_table_max_size(&lli_array_ptr[current_entry], (sep_lli_entries - current_entry)); | ||
1199 | |||
1200 | /* now calculate the table size so that it will be module block size */ | ||
1201 | table_data_size = (table_data_size / block_size) * block_size; | ||
1202 | |||
1203 | edbg("SEP Driver:output table_data_size is %lu\n", table_data_size); | ||
1204 | |||
1205 | /* construct input lli table */ | ||
1206 | sep_build_lli_table(&lli_array_ptr[current_entry], in_lli_table_ptr, ¤t_entry, &num_entries_in_table, table_data_size); | ||
1207 | |||
1208 | if (info_entry_ptr == 0) { | ||
1209 | /* set the output parameters to physical addresses */ | ||
1210 | *lli_table_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1211 | *num_entries_ptr = num_entries_in_table; | ||
1212 | *table_data_size_ptr = table_data_size; | ||
1213 | |||
1214 | edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_ptr); | ||
1215 | } else { | ||
1216 | /* update the info entry of the previous in table */ | ||
1217 | info_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1218 | info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size); | ||
1219 | } | ||
1220 | |||
1221 | /* save the pointer to the info entry of the current tables */ | ||
1222 | info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; | ||
1223 | } | ||
1224 | |||
1225 | /* print input tables */ | ||
1226 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1227 | sep_shared_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr); | ||
1228 | |||
1229 | /* the array of the pages */ | ||
1230 | kfree(lli_array_ptr); | ||
1231 | end_function: | ||
1232 | dbg("SEP Driver:<-------- sep_prepare_input_dma_table end\n"); | ||
1233 | return 0; | ||
1234 | |||
1235 | } | ||
1236 | |||
1237 | /* | ||
1238 | This function creates the input and output dma tables for | ||
1239 | symmetric operations (AES/DES) according to the block size from LLI arays | ||
1240 | */ | ||
1241 | static int sep_construct_dma_tables_from_lli(struct sep_device *sep, | ||
1242 | struct sep_lli_entry_t *lli_in_array, | ||
1243 | unsigned long sep_in_lli_entries, | ||
1244 | struct sep_lli_entry_t *lli_out_array, | ||
1245 | unsigned long sep_out_lli_entries, | ||
1246 | unsigned long block_size, unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr) | ||
1247 | { | ||
1248 | /* points to the area where next lli table can be allocated: keep void * | ||
1249 | as there is pointer scaling to fix otherwise */ | ||
1250 | void *lli_table_alloc_addr; | ||
1251 | /* input lli table */ | ||
1252 | struct sep_lli_entry_t *in_lli_table_ptr; | ||
1253 | /* output lli table */ | ||
1254 | struct sep_lli_entry_t *out_lli_table_ptr; | ||
1255 | /* pointer to the info entry of the table - the last entry */ | ||
1256 | struct sep_lli_entry_t *info_in_entry_ptr; | ||
1257 | /* pointer to the info entry of the table - the last entry */ | ||
1258 | struct sep_lli_entry_t *info_out_entry_ptr; | ||
1259 | /* points to the first entry to be processed in the lli_in_array */ | ||
1260 | unsigned long current_in_entry; | ||
1261 | /* points to the first entry to be processed in the lli_out_array */ | ||
1262 | unsigned long current_out_entry; | ||
1263 | /* max size of the input table */ | ||
1264 | unsigned long in_table_data_size; | ||
1265 | /* max size of the output table */ | ||
1266 | unsigned long out_table_data_size; | ||
1267 | /* flag te signifies if this is the first tables build from the arrays */ | ||
1268 | unsigned long first_table_flag; | ||
1269 | /* the data size that should be in table */ | ||
1270 | unsigned long table_data_size; | ||
1271 | /* number of etnries in the input table */ | ||
1272 | unsigned long num_entries_in_table; | ||
1273 | /* number of etnries in the output table */ | ||
1274 | unsigned long num_entries_out_table; | ||
1275 | |||
1276 | dbg("SEP Driver:--------> sep_construct_dma_tables_from_lli start\n"); | ||
1277 | |||
1278 | /* initiate to pint after the message area */ | ||
1279 | lli_table_alloc_addr = sep->shared_addr + SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1280 | |||
1281 | current_in_entry = 0; | ||
1282 | current_out_entry = 0; | ||
1283 | first_table_flag = 1; | ||
1284 | info_in_entry_ptr = 0; | ||
1285 | info_out_entry_ptr = 0; | ||
1286 | |||
1287 | /* loop till all the entries in in array are not processed */ | ||
1288 | while (current_in_entry < sep_in_lli_entries) { | ||
1289 | /* set the new input and output tables */ | ||
1290 | in_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1291 | |||
1292 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1293 | |||
1294 | /* set the first output tables */ | ||
1295 | out_lli_table_ptr = (struct sep_lli_entry_t *) lli_table_alloc_addr; | ||
1296 | |||
1297 | lli_table_alloc_addr += sizeof(struct sep_lli_entry_t) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; | ||
1298 | |||
1299 | /* calculate the maximum size of data for input table */ | ||
1300 | in_table_data_size = sep_calculate_lli_table_max_size(&lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry)); | ||
1301 | |||
1302 | /* calculate the maximum size of data for output table */ | ||
1303 | out_table_data_size = sep_calculate_lli_table_max_size(&lli_out_array[current_out_entry], (sep_out_lli_entries - current_out_entry)); | ||
1304 | |||
1305 | edbg("SEP Driver:in_table_data_size is %lu\n", in_table_data_size); | ||
1306 | edbg("SEP Driver:out_table_data_size is %lu\n", out_table_data_size); | ||
1307 | |||
1308 | /* check where the data is smallest */ | ||
1309 | table_data_size = in_table_data_size; | ||
1310 | if (table_data_size > out_table_data_size) | ||
1311 | table_data_size = out_table_data_size; | ||
1312 | |||
1313 | /* now calculate the table size so that it will be module block size */ | ||
1314 | table_data_size = (table_data_size / block_size) * block_size; | ||
1315 | |||
1316 | dbg("SEP Driver:table_data_size is %lu\n", table_data_size); | ||
1317 | |||
1318 | /* construct input lli table */ | ||
1319 | sep_build_lli_table(&lli_in_array[current_in_entry], in_lli_table_ptr, ¤t_in_entry, &num_entries_in_table, table_data_size); | ||
1320 | |||
1321 | /* construct output lli table */ | ||
1322 | sep_build_lli_table(&lli_out_array[current_out_entry], out_lli_table_ptr, ¤t_out_entry, &num_entries_out_table, table_data_size); | ||
1323 | |||
1324 | /* if info entry is null - this is the first table built */ | ||
1325 | if (info_in_entry_ptr == 0) { | ||
1326 | /* set the output parameters to physical addresses */ | ||
1327 | *lli_table_in_ptr = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1328 | *in_num_entries_ptr = num_entries_in_table; | ||
1329 | *lli_table_out_ptr = sep_shared_virt_to_bus(sep, out_lli_table_ptr); | ||
1330 | *out_num_entries_ptr = num_entries_out_table; | ||
1331 | *table_data_size_ptr = table_data_size; | ||
1332 | |||
1333 | edbg("SEP Driver:output lli_table_in_ptr is %08lx\n", *lli_table_in_ptr); | ||
1334 | edbg("SEP Driver:output lli_table_out_ptr is %08lx\n", *lli_table_out_ptr); | ||
1335 | } else { | ||
1336 | /* update the info entry of the previous in table */ | ||
1337 | info_in_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, in_lli_table_ptr); | ||
1338 | info_in_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size); | ||
1339 | |||
1340 | /* update the info entry of the previous in table */ | ||
1341 | info_out_entry_ptr->physical_address = sep_shared_virt_to_bus(sep, out_lli_table_ptr); | ||
1342 | info_out_entry_ptr->block_size = ((num_entries_out_table) << 24) | (table_data_size); | ||
1343 | } | ||
1344 | |||
1345 | /* save the pointer to the info entry of the current tables */ | ||
1346 | info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; | ||
1347 | info_out_entry_ptr = out_lli_table_ptr + num_entries_out_table - 1; | ||
1348 | |||
1349 | edbg("SEP Driver:output num_entries_out_table is %lu\n", (unsigned long) num_entries_out_table); | ||
1350 | edbg("SEP Driver:output info_in_entry_ptr is %lu\n", (unsigned long) info_in_entry_ptr); | ||
1351 | edbg("SEP Driver:output info_out_entry_ptr is %lu\n", (unsigned long) info_out_entry_ptr); | ||
1352 | } | ||
1353 | |||
1354 | /* print input tables */ | ||
1355 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1356 | sep_shared_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr); | ||
1357 | /* print output tables */ | ||
1358 | sep_debug_print_lli_tables(sep, (struct sep_lli_entry_t *) | ||
1359 | sep_shared_bus_to_virt(sep, *lli_table_out_ptr), *out_num_entries_ptr, *table_data_size_ptr); | ||
1360 | dbg("SEP Driver:<-------- sep_construct_dma_tables_from_lli end\n"); | ||
1361 | return 0; | ||
1362 | } | ||
1363 | |||
1364 | |||
1365 | /* | ||
1366 | This function builds input and output DMA tables for synhronic | ||
1367 | symmetric operations (AES, DES). It also checks that each table | ||
1368 | is of the modular block size | ||
1369 | */ | ||
1370 | static int sep_prepare_input_output_dma_table(struct sep_device *sep, | ||
1371 | unsigned long app_virt_in_addr, | ||
1372 | unsigned long app_virt_out_addr, | ||
1373 | unsigned long data_size, | ||
1374 | unsigned long block_size, | ||
1375 | unsigned long *lli_table_in_ptr, unsigned long *lli_table_out_ptr, unsigned long *in_num_entries_ptr, unsigned long *out_num_entries_ptr, unsigned long *table_data_size_ptr, bool isKernelVirtualAddress) | ||
1376 | { | ||
1377 | /* array of pointers of page */ | ||
1378 | struct sep_lli_entry_t *lli_in_array; | ||
1379 | /* array of pointers of page */ | ||
1380 | struct sep_lli_entry_t *lli_out_array; | ||
1381 | int result = 0; | ||
1382 | |||
1383 | dbg("SEP Driver:--------> sep_prepare_input_output_dma_table start\n"); | ||
1384 | |||
1385 | /* initialize the pages pointers */ | ||
1386 | sep->in_page_array = 0; | ||
1387 | sep->out_page_array = 0; | ||
1388 | |||
1389 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1390 | if (isKernelVirtualAddress == true) { | ||
1391 | /* lock the pages of the kernel buffer and translate them to pages */ | ||
1392 | result = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array); | ||
1393 | if (result) { | ||
1394 | edbg("SEP Driver: sep_lock_kernel_pages for input virtual buffer failed\n"); | ||
1395 | goto end_function; | ||
1396 | } | ||
1397 | } else { | ||
1398 | /* lock the pages of the user buffer and translate them to pages */ | ||
1399 | result = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &sep->in_num_pages, &lli_in_array, &sep->in_page_array); | ||
1400 | if (result) { | ||
1401 | edbg("SEP Driver: sep_lock_user_pages for input virtual buffer failed\n"); | ||
1402 | goto end_function; | ||
1403 | } | ||
1404 | } | ||
1405 | |||
1406 | if (isKernelVirtualAddress == true) { | ||
1407 | result = sep_lock_kernel_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array); | ||
1408 | if (result) { | ||
1409 | edbg("SEP Driver: sep_lock_kernel_pages for output virtual buffer failed\n"); | ||
1410 | goto end_function_with_error1; | ||
1411 | } | ||
1412 | } else { | ||
1413 | result = sep_lock_user_pages(sep, app_virt_out_addr, data_size, &sep->out_num_pages, &lli_out_array, &sep->out_page_array); | ||
1414 | if (result) { | ||
1415 | edbg("SEP Driver: sep_lock_user_pages for output virtual buffer failed\n"); | ||
1416 | goto end_function_with_error1; | ||
1417 | } | ||
1418 | } | ||
1419 | edbg("sep->in_num_pages is %lu\n", sep->in_num_pages); | ||
1420 | edbg("sep->out_num_pages is %lu\n", sep->out_num_pages); | ||
1421 | edbg("SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); | ||
1422 | |||
1423 | |||
1424 | /* call the fucntion that creates table from the lli arrays */ | ||
1425 | result = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->in_num_pages, lli_out_array, sep->out_num_pages, block_size, lli_table_in_ptr, lli_table_out_ptr, in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr); | ||
1426 | if (result) { | ||
1427 | edbg("SEP Driver: sep_construct_dma_tables_from_lli failed\n"); | ||
1428 | goto end_function_with_error2; | ||
1429 | } | ||
1430 | |||
1431 | /* fall through - free the lli entry arrays */ | ||
1432 | dbg("in_num_entries_ptr is %08lx\n", *in_num_entries_ptr); | ||
1433 | dbg("out_num_entries_ptr is %08lx\n", *out_num_entries_ptr); | ||
1434 | dbg("table_data_size_ptr is %08lx\n", *table_data_size_ptr); | ||
1435 | end_function_with_error2: | ||
1436 | kfree(lli_out_array); | ||
1437 | end_function_with_error1: | ||
1438 | kfree(lli_in_array); | ||
1439 | end_function: | ||
1440 | dbg("SEP Driver:<-------- sep_prepare_input_output_dma_table end result = %d\n", (int) result); | ||
1441 | return result; | ||
1442 | |||
1443 | } | ||
1444 | |||
1445 | /* | ||
1446 | this function handles tha request for creation of the DMA table | ||
1447 | for the synchronic symmetric operations (AES,DES) | ||
1448 | */ | ||
1449 | static int sep_create_sync_dma_tables_handler(struct sep_device *sep, | ||
1450 | unsigned long arg) | ||
1451 | { | ||
1452 | int error; | ||
1453 | /* command arguments */ | ||
1454 | struct sep_driver_build_sync_table_t command_args; | ||
1455 | |||
1456 | dbg("SEP Driver:--------> sep_create_sync_dma_tables_handler start\n"); | ||
1457 | |||
1458 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_sync_table_t)); | ||
1459 | if (error) { | ||
1460 | error = -EFAULT; | ||
1461 | goto end_function; | ||
1462 | } | ||
1463 | |||
1464 | edbg("app_in_address is %08lx\n", command_args.app_in_address); | ||
1465 | edbg("app_out_address is %08lx\n", command_args.app_out_address); | ||
1466 | edbg("data_size is %lu\n", command_args.data_in_size); | ||
1467 | edbg("block_size is %lu\n", command_args.block_size); | ||
1468 | |||
1469 | /* check if we need to build only input table or input/output */ | ||
1470 | if (command_args.app_out_address) | ||
1471 | /* prepare input and output tables */ | ||
1472 | error = sep_prepare_input_output_dma_table(sep, | ||
1473 | command_args.app_in_address, | ||
1474 | command_args.app_out_address, | ||
1475 | command_args.data_in_size, | ||
1476 | command_args.block_size, | ||
1477 | &command_args.in_table_address, | ||
1478 | &command_args.out_table_address, &command_args.in_table_num_entries, &command_args.out_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress); | ||
1479 | else | ||
1480 | /* prepare input tables */ | ||
1481 | error = sep_prepare_input_dma_table(sep, | ||
1482 | command_args.app_in_address, | ||
1483 | command_args.data_in_size, command_args.block_size, &command_args.in_table_address, &command_args.in_table_num_entries, &command_args.table_data_size, command_args.isKernelVirtualAddress); | ||
1484 | |||
1485 | if (error) | ||
1486 | goto end_function; | ||
1487 | /* copy to user */ | ||
1488 | if (copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_build_sync_table_t))) | ||
1489 | error = -EFAULT; | ||
1490 | end_function: | ||
1491 | dbg("SEP Driver:<-------- sep_create_sync_dma_tables_handler end\n"); | ||
1492 | return error; | ||
1493 | } | ||
1494 | |||
1495 | /* | ||
1496 | this function handles the request for freeing dma table for synhronic actions | ||
1497 | */ | ||
1498 | static int sep_free_dma_table_data_handler(struct sep_device *sep) | ||
1499 | { | ||
1500 | dbg("SEP Driver:--------> sep_free_dma_table_data_handler start\n"); | ||
1501 | |||
1502 | /* free input pages array */ | ||
1503 | sep_free_dma_pages(sep->in_page_array, sep->in_num_pages, 0); | ||
1504 | |||
1505 | /* free output pages array if needed */ | ||
1506 | if (sep->out_page_array) | ||
1507 | sep_free_dma_pages(sep->out_page_array, sep->out_num_pages, 1); | ||
1508 | |||
1509 | /* reset all the values */ | ||
1510 | sep->in_page_array = 0; | ||
1511 | sep->out_page_array = 0; | ||
1512 | sep->in_num_pages = 0; | ||
1513 | sep->out_num_pages = 0; | ||
1514 | dbg("SEP Driver:<-------- sep_free_dma_table_data_handler end\n"); | ||
1515 | return 0; | ||
1516 | } | ||
1517 | |||
1518 | /* | ||
1519 | this function find a space for the new flow dma table | ||
1520 | */ | ||
1521 | static int sep_find_free_flow_dma_table_space(struct sep_device *sep, | ||
1522 | unsigned long **table_address_ptr) | ||
1523 | { | ||
1524 | int error = 0; | ||
1525 | /* pointer to the id field of the flow dma table */ | ||
1526 | unsigned long *start_table_ptr; | ||
1527 | /* Do not make start_addr unsigned long * unless fixing the offset | ||
1528 | computations ! */ | ||
1529 | void *flow_dma_area_start_addr; | ||
1530 | unsigned long *flow_dma_area_end_addr; | ||
1531 | /* maximum table size in words */ | ||
1532 | unsigned long table_size_in_words; | ||
1533 | |||
1534 | /* find the start address of the flow DMA table area */ | ||
1535 | flow_dma_area_start_addr = sep->shared_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES; | ||
1536 | |||
1537 | /* set end address of the flow table area */ | ||
1538 | flow_dma_area_end_addr = flow_dma_area_start_addr + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES; | ||
1539 | |||
1540 | /* set table size in words */ | ||
1541 | table_size_in_words = SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE * (sizeof(struct sep_lli_entry_t) / sizeof(long)) + 2; | ||
1542 | |||
1543 | /* set the pointer to the start address of DMA area */ | ||
1544 | start_table_ptr = flow_dma_area_start_addr; | ||
1545 | |||
1546 | /* find the space for the next table */ | ||
1547 | while (((*start_table_ptr & 0x7FFFFFFF) != 0) && start_table_ptr < flow_dma_area_end_addr) | ||
1548 | start_table_ptr += table_size_in_words; | ||
1549 | |||
1550 | /* check if we reached the end of floa tables area */ | ||
1551 | if (start_table_ptr >= flow_dma_area_end_addr) | ||
1552 | error = -1; | ||
1553 | else | ||
1554 | *table_address_ptr = start_table_ptr; | ||
1555 | |||
1556 | return error; | ||
1557 | } | ||
1558 | |||
1559 | /* | ||
1560 | This function creates one DMA table for flow and returns its data, | ||
1561 | and pointer to its info entry | ||
1562 | */ | ||
1563 | static int sep_prepare_one_flow_dma_table(struct sep_device *sep, | ||
1564 | unsigned long virt_buff_addr, | ||
1565 | unsigned long virt_buff_size, | ||
1566 | struct sep_lli_entry_t *table_data, | ||
1567 | struct sep_lli_entry_t **info_entry_ptr, | ||
1568 | struct sep_flow_context_t *flow_data_ptr, | ||
1569 | bool isKernelVirtualAddress) | ||
1570 | { | ||
1571 | int error; | ||
1572 | /* the range in pages */ | ||
1573 | unsigned long lli_array_size; | ||
1574 | struct sep_lli_entry_t *lli_array; | ||
1575 | struct sep_lli_entry_t *flow_dma_table_entry_ptr; | ||
1576 | unsigned long *start_dma_table_ptr; | ||
1577 | /* total table data counter */ | ||
1578 | unsigned long dma_table_data_count; | ||
1579 | /* pointer that will keep the pointer to the pages of the virtual buffer */ | ||
1580 | struct page **page_array_ptr; | ||
1581 | unsigned long entry_count; | ||
1582 | |||
1583 | /* find the space for the new table */ | ||
1584 | error = sep_find_free_flow_dma_table_space(sep, &start_dma_table_ptr); | ||
1585 | if (error) | ||
1586 | goto end_function; | ||
1587 | |||
1588 | /* check if the pages are in Kernel Virtual Address layout */ | ||
1589 | if (isKernelVirtualAddress == true) | ||
1590 | /* lock kernel buffer in the memory */ | ||
1591 | error = sep_lock_kernel_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr); | ||
1592 | else | ||
1593 | /* lock user buffer in the memory */ | ||
1594 | error = sep_lock_user_pages(sep, virt_buff_addr, virt_buff_size, &lli_array_size, &lli_array, &page_array_ptr); | ||
1595 | |||
1596 | if (error) | ||
1597 | goto end_function; | ||
1598 | |||
1599 | /* set the pointer to page array at the beginning of table - this table is | ||
1600 | now considered taken */ | ||
1601 | *start_dma_table_ptr = lli_array_size; | ||
1602 | |||
1603 | /* point to the place of the pages pointers of the table */ | ||
1604 | start_dma_table_ptr++; | ||
1605 | |||
1606 | /* set the pages pointer */ | ||
1607 | *start_dma_table_ptr = (unsigned long) page_array_ptr; | ||
1608 | |||
1609 | /* set the pointer to the first entry */ | ||
1610 | flow_dma_table_entry_ptr = (struct sep_lli_entry_t *) (++start_dma_table_ptr); | ||
1611 | |||
1612 | /* now create the entries for table */ | ||
1613 | for (dma_table_data_count = entry_count = 0; entry_count < lli_array_size; entry_count++) { | ||
1614 | flow_dma_table_entry_ptr->physical_address = lli_array[entry_count].physical_address; | ||
1615 | |||
1616 | flow_dma_table_entry_ptr->block_size = lli_array[entry_count].block_size; | ||
1617 | |||
1618 | /* set the total data of a table */ | ||
1619 | dma_table_data_count += lli_array[entry_count].block_size; | ||
1620 | |||
1621 | flow_dma_table_entry_ptr++; | ||
1622 | } | ||
1623 | |||
1624 | /* set the physical address */ | ||
1625 | table_data->physical_address = virt_to_phys(start_dma_table_ptr); | ||
1626 | |||
1627 | /* set the num_entries and total data size */ | ||
1628 | table_data->block_size = ((lli_array_size + 1) << SEP_NUM_ENTRIES_OFFSET_IN_BITS) | (dma_table_data_count); | ||
1629 | |||
1630 | /* set the info entry */ | ||
1631 | flow_dma_table_entry_ptr->physical_address = 0xffffffff; | ||
1632 | flow_dma_table_entry_ptr->block_size = 0; | ||
1633 | |||
1634 | /* set the pointer to info entry */ | ||
1635 | *info_entry_ptr = flow_dma_table_entry_ptr; | ||
1636 | |||
1637 | /* the array of the lli entries */ | ||
1638 | kfree(lli_array); | ||
1639 | end_function: | ||
1640 | return error; | ||
1641 | } | ||
1642 | |||
1643 | |||
1644 | |||
1645 | /* | ||
1646 | This function creates a list of tables for flow and returns the data for | ||
1647 | the first and last tables of the list | ||
1648 | */ | ||
1649 | static int sep_prepare_flow_dma_tables(struct sep_device *sep, | ||
1650 | unsigned long num_virtual_buffers, | ||
1651 | unsigned long first_buff_addr, struct sep_flow_context_t *flow_data_ptr, struct sep_lli_entry_t *first_table_data_ptr, struct sep_lli_entry_t *last_table_data_ptr, bool isKernelVirtualAddress) | ||
1652 | { | ||
1653 | int error; | ||
1654 | unsigned long virt_buff_addr; | ||
1655 | unsigned long virt_buff_size; | ||
1656 | struct sep_lli_entry_t table_data; | ||
1657 | struct sep_lli_entry_t *info_entry_ptr; | ||
1658 | struct sep_lli_entry_t *prev_info_entry_ptr; | ||
1659 | unsigned long i; | ||
1660 | |||
1661 | /* init vars */ | ||
1662 | error = 0; | ||
1663 | prev_info_entry_ptr = 0; | ||
1664 | |||
1665 | /* init the first table to default */ | ||
1666 | table_data.physical_address = 0xffffffff; | ||
1667 | first_table_data_ptr->physical_address = 0xffffffff; | ||
1668 | table_data.block_size = 0; | ||
1669 | |||
1670 | for (i = 0; i < num_virtual_buffers; i++) { | ||
1671 | /* get the virtual buffer address */ | ||
1672 | error = get_user(virt_buff_addr, &first_buff_addr); | ||
1673 | if (error) | ||
1674 | goto end_function; | ||
1675 | |||
1676 | /* get the virtual buffer size */ | ||
1677 | first_buff_addr++; | ||
1678 | error = get_user(virt_buff_size, &first_buff_addr); | ||
1679 | if (error) | ||
1680 | goto end_function; | ||
1681 | |||
1682 | /* advance the address to point to the next pair of address|size */ | ||
1683 | first_buff_addr++; | ||
1684 | |||
1685 | /* now prepare the one flow LLI table from the data */ | ||
1686 | error = sep_prepare_one_flow_dma_table(sep, virt_buff_addr, virt_buff_size, &table_data, &info_entry_ptr, flow_data_ptr, isKernelVirtualAddress); | ||
1687 | if (error) | ||
1688 | goto end_function; | ||
1689 | |||
1690 | if (i == 0) { | ||
1691 | /* if this is the first table - save it to return to the user | ||
1692 | application */ | ||
1693 | *first_table_data_ptr = table_data; | ||
1694 | |||
1695 | /* set the pointer to info entry */ | ||
1696 | prev_info_entry_ptr = info_entry_ptr; | ||
1697 | } else { | ||
1698 | /* not first table - the previous table info entry should | ||
1699 | be updated */ | ||
1700 | prev_info_entry_ptr->block_size = (0x1 << SEP_INT_FLAG_OFFSET_IN_BITS) | (table_data.block_size); | ||
1701 | |||
1702 | /* set the pointer to info entry */ | ||
1703 | prev_info_entry_ptr = info_entry_ptr; | ||
1704 | } | ||
1705 | } | ||
1706 | |||
1707 | /* set the last table data */ | ||
1708 | *last_table_data_ptr = table_data; | ||
1709 | end_function: | ||
1710 | return error; | ||
1711 | } | ||
1712 | |||
1713 | /* | ||
1714 | this function goes over all the flow tables connected to the given | ||
1715 | table and deallocate them | ||
1716 | */ | ||
1717 | static void sep_deallocated_flow_tables(struct sep_lli_entry_t *first_table_ptr) | ||
1718 | { | ||
1719 | /* id pointer */ | ||
1720 | unsigned long *table_ptr; | ||
1721 | /* end address of the flow dma area */ | ||
1722 | unsigned long num_entries; | ||
1723 | unsigned long num_pages; | ||
1724 | struct page **pages_ptr; | ||
1725 | /* maximum table size in words */ | ||
1726 | struct sep_lli_entry_t *info_entry_ptr; | ||
1727 | |||
1728 | /* set the pointer to the first table */ | ||
1729 | table_ptr = (unsigned long *) first_table_ptr->physical_address; | ||
1730 | |||
1731 | /* set the num of entries */ | ||
1732 | num_entries = (first_table_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) | ||
1733 | & SEP_NUM_ENTRIES_MASK; | ||
1734 | |||
1735 | /* go over all the connected tables */ | ||
1736 | while (*table_ptr != 0xffffffff) { | ||
1737 | /* get number of pages */ | ||
1738 | num_pages = *(table_ptr - 2); | ||
1739 | |||
1740 | /* get the pointer to the pages */ | ||
1741 | pages_ptr = (struct page **) (*(table_ptr - 1)); | ||
1742 | |||
1743 | /* free the pages */ | ||
1744 | sep_free_dma_pages(pages_ptr, num_pages, 1); | ||
1745 | |||
1746 | /* goto to the info entry */ | ||
1747 | info_entry_ptr = ((struct sep_lli_entry_t *) table_ptr) + (num_entries - 1); | ||
1748 | |||
1749 | table_ptr = (unsigned long *) info_entry_ptr->physical_address; | ||
1750 | num_entries = (info_entry_ptr->block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1751 | } | ||
1752 | |||
1753 | return; | ||
1754 | } | ||
1755 | |||
1756 | /** | ||
1757 | * sep_find_flow_context - find a flow | ||
1758 | * @sep: the SEP we are working with | ||
1759 | * @flow_id: flow identifier | ||
1760 | * | ||
1761 | * Returns a pointer the matching flow, or NULL if the flow does not | ||
1762 | * exist. | ||
1763 | */ | ||
1764 | |||
1765 | static struct sep_flow_context_t *sep_find_flow_context(struct sep_device *sep, | ||
1766 | unsigned long flow_id) | ||
1767 | { | ||
1768 | int count; | ||
1769 | /* | ||
1770 | * always search for flow with id default first - in case we | ||
1771 | * already started working on the flow there can be no situation | ||
1772 | * when 2 flows are with default flag | ||
1773 | */ | ||
1774 | for (count = 0; count < SEP_DRIVER_NUM_FLOWS; count++) { | ||
1775 | if (sep->flows[count].flow_id == flow_id) | ||
1776 | return &sep->flows[count]; | ||
1777 | } | ||
1778 | return NULL; | ||
1779 | } | ||
1780 | |||
1781 | |||
1782 | /* | ||
1783 | this function handles the request to create the DMA tables for flow | ||
1784 | */ | ||
1785 | static int sep_create_flow_dma_tables_handler(struct sep_device *sep, | ||
1786 | unsigned long arg) | ||
1787 | { | ||
1788 | int error = -ENOENT; | ||
1789 | struct sep_driver_build_flow_table_t command_args; | ||
1790 | /* first table - output */ | ||
1791 | struct sep_lli_entry_t first_table_data; | ||
1792 | /* dma table data */ | ||
1793 | struct sep_lli_entry_t last_table_data; | ||
1794 | /* pointer to the info entry of the previuos DMA table */ | ||
1795 | struct sep_lli_entry_t *prev_info_entry_ptr; | ||
1796 | /* pointer to the flow data strucutre */ | ||
1797 | struct sep_flow_context_t *flow_context_ptr; | ||
1798 | |||
1799 | dbg("SEP Driver:--------> sep_create_flow_dma_tables_handler start\n"); | ||
1800 | |||
1801 | /* init variables */ | ||
1802 | prev_info_entry_ptr = 0; | ||
1803 | first_table_data.physical_address = 0xffffffff; | ||
1804 | |||
1805 | /* find the free structure for flow data */ | ||
1806 | error = -EINVAL; | ||
1807 | flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID); | ||
1808 | if (flow_context_ptr == NULL) | ||
1809 | goto end_function; | ||
1810 | |||
1811 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_build_flow_table_t)); | ||
1812 | if (error) { | ||
1813 | error = -EFAULT; | ||
1814 | goto end_function; | ||
1815 | } | ||
1816 | |||
1817 | /* create flow tables */ | ||
1818 | error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress); | ||
1819 | if (error) | ||
1820 | goto end_function_with_error; | ||
1821 | |||
1822 | /* check if flow is static */ | ||
1823 | if (!command_args.flow_type) | ||
1824 | /* point the info entry of the last to the info entry of the first */ | ||
1825 | last_table_data = first_table_data; | ||
1826 | |||
1827 | /* set output params */ | ||
1828 | command_args.first_table_addr = first_table_data.physical_address; | ||
1829 | command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK); | ||
1830 | command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK); | ||
1831 | |||
1832 | /* send the parameters to user application */ | ||
1833 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_build_flow_table_t)); | ||
1834 | if (error) { | ||
1835 | error = -EFAULT; | ||
1836 | goto end_function_with_error; | ||
1837 | } | ||
1838 | |||
1839 | /* all the flow created - update the flow entry with temp id */ | ||
1840 | flow_context_ptr->flow_id = SEP_TEMP_FLOW_ID; | ||
1841 | |||
1842 | /* set the processing tables data in the context */ | ||
1843 | if (command_args.input_output_flag == SEP_DRIVER_IN_FLAG) | ||
1844 | flow_context_ptr->input_tables_in_process = first_table_data; | ||
1845 | else | ||
1846 | flow_context_ptr->output_tables_in_process = first_table_data; | ||
1847 | |||
1848 | goto end_function; | ||
1849 | |||
1850 | end_function_with_error: | ||
1851 | /* free the allocated tables */ | ||
1852 | sep_deallocated_flow_tables(&first_table_data); | ||
1853 | end_function: | ||
1854 | dbg("SEP Driver:<-------- sep_create_flow_dma_tables_handler end\n"); | ||
1855 | return error; | ||
1856 | } | ||
1857 | |||
1858 | /* | ||
1859 | this function handles add tables to flow | ||
1860 | */ | ||
1861 | static int sep_add_flow_tables_handler(struct sep_device *sep, unsigned long arg) | ||
1862 | { | ||
1863 | int error; | ||
1864 | unsigned long num_entries; | ||
1865 | struct sep_driver_add_flow_table_t command_args; | ||
1866 | struct sep_flow_context_t *flow_context_ptr; | ||
1867 | /* first dma table data */ | ||
1868 | struct sep_lli_entry_t first_table_data; | ||
1869 | /* last dma table data */ | ||
1870 | struct sep_lli_entry_t last_table_data; | ||
1871 | /* pointer to the info entry of the current DMA table */ | ||
1872 | struct sep_lli_entry_t *info_entry_ptr; | ||
1873 | |||
1874 | dbg("SEP Driver:--------> sep_add_flow_tables_handler start\n"); | ||
1875 | |||
1876 | /* get input parameters */ | ||
1877 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_flow_table_t)); | ||
1878 | if (error) { | ||
1879 | error = -EFAULT; | ||
1880 | goto end_function; | ||
1881 | } | ||
1882 | |||
1883 | /* find the flow structure for the flow id */ | ||
1884 | flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id); | ||
1885 | if (flow_context_ptr == NULL) | ||
1886 | goto end_function; | ||
1887 | |||
1888 | /* prepare the flow dma tables */ | ||
1889 | error = sep_prepare_flow_dma_tables(sep, command_args.num_virtual_buffers, command_args.virt_buff_data_addr, flow_context_ptr, &first_table_data, &last_table_data, command_args.isKernelVirtualAddress); | ||
1890 | if (error) | ||
1891 | goto end_function_with_error; | ||
1892 | |||
1893 | /* now check if there is already an existing add table for this flow */ | ||
1894 | if (command_args.inputOutputFlag == SEP_DRIVER_IN_FLAG) { | ||
1895 | /* this buffer was for input buffers */ | ||
1896 | if (flow_context_ptr->input_tables_flag) { | ||
1897 | /* add table already exists - add the new tables to the end | ||
1898 | of the previous */ | ||
1899 | num_entries = (flow_context_ptr->last_input_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1900 | |||
1901 | info_entry_ptr = (struct sep_lli_entry_t *) | ||
1902 | (flow_context_ptr->last_input_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1))); | ||
1903 | |||
1904 | /* connect to list of tables */ | ||
1905 | *info_entry_ptr = first_table_data; | ||
1906 | |||
1907 | /* set the first table data */ | ||
1908 | first_table_data = flow_context_ptr->first_input_table; | ||
1909 | } else { | ||
1910 | /* set the input flag */ | ||
1911 | flow_context_ptr->input_tables_flag = 1; | ||
1912 | |||
1913 | /* set the first table data */ | ||
1914 | flow_context_ptr->first_input_table = first_table_data; | ||
1915 | } | ||
1916 | /* set the last table data */ | ||
1917 | flow_context_ptr->last_input_table = last_table_data; | ||
1918 | } else { /* this is output tables */ | ||
1919 | |||
1920 | /* this buffer was for input buffers */ | ||
1921 | if (flow_context_ptr->output_tables_flag) { | ||
1922 | /* add table already exists - add the new tables to | ||
1923 | the end of the previous */ | ||
1924 | num_entries = (flow_context_ptr->last_output_table.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK; | ||
1925 | |||
1926 | info_entry_ptr = (struct sep_lli_entry_t *) | ||
1927 | (flow_context_ptr->last_output_table.physical_address + (sizeof(struct sep_lli_entry_t) * (num_entries - 1))); | ||
1928 | |||
1929 | /* connect to list of tables */ | ||
1930 | *info_entry_ptr = first_table_data; | ||
1931 | |||
1932 | /* set the first table data */ | ||
1933 | first_table_data = flow_context_ptr->first_output_table; | ||
1934 | } else { | ||
1935 | /* set the input flag */ | ||
1936 | flow_context_ptr->output_tables_flag = 1; | ||
1937 | |||
1938 | /* set the first table data */ | ||
1939 | flow_context_ptr->first_output_table = first_table_data; | ||
1940 | } | ||
1941 | /* set the last table data */ | ||
1942 | flow_context_ptr->last_output_table = last_table_data; | ||
1943 | } | ||
1944 | |||
1945 | /* set output params */ | ||
1946 | command_args.first_table_addr = first_table_data.physical_address; | ||
1947 | command_args.first_table_num_entries = ((first_table_data.block_size >> SEP_NUM_ENTRIES_OFFSET_IN_BITS) & SEP_NUM_ENTRIES_MASK); | ||
1948 | command_args.first_table_data_size = (first_table_data.block_size & SEP_TABLE_DATA_SIZE_MASK); | ||
1949 | |||
1950 | /* send the parameters to user application */ | ||
1951 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_add_flow_table_t)); | ||
1952 | if (error) | ||
1953 | error = -EFAULT; | ||
1954 | end_function_with_error: | ||
1955 | /* free the allocated tables */ | ||
1956 | sep_deallocated_flow_tables(&first_table_data); | ||
1957 | end_function: | ||
1958 | dbg("SEP Driver:<-------- sep_add_flow_tables_handler end\n"); | ||
1959 | return error; | ||
1960 | } | ||
1961 | |||
1962 | /* | ||
1963 | this function add the flow add message to the specific flow | ||
1964 | */ | ||
1965 | static int sep_add_flow_tables_message_handler(struct sep_device *sep, unsigned long arg) | ||
1966 | { | ||
1967 | int error; | ||
1968 | struct sep_driver_add_message_t command_args; | ||
1969 | struct sep_flow_context_t *flow_context_ptr; | ||
1970 | |||
1971 | dbg("SEP Driver:--------> sep_add_flow_tables_message_handler start\n"); | ||
1972 | |||
1973 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_add_message_t)); | ||
1974 | if (error) { | ||
1975 | error = -EFAULT; | ||
1976 | goto end_function; | ||
1977 | } | ||
1978 | |||
1979 | /* check input */ | ||
1980 | if (command_args.message_size_in_bytes > SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES) { | ||
1981 | error = -ENOMEM; | ||
1982 | goto end_function; | ||
1983 | } | ||
1984 | |||
1985 | /* find the flow context */ | ||
1986 | flow_context_ptr = sep_find_flow_context(sep, command_args.flow_id); | ||
1987 | if (flow_context_ptr == NULL) | ||
1988 | goto end_function; | ||
1989 | |||
1990 | /* copy the message into context */ | ||
1991 | flow_context_ptr->message_size_in_bytes = command_args.message_size_in_bytes; | ||
1992 | error = copy_from_user(flow_context_ptr->message, (void *) command_args.message_address, command_args.message_size_in_bytes); | ||
1993 | if (error) | ||
1994 | error = -EFAULT; | ||
1995 | end_function: | ||
1996 | dbg("SEP Driver:<-------- sep_add_flow_tables_message_handler end\n"); | ||
1997 | return error; | ||
1998 | } | ||
1999 | |||
2000 | |||
2001 | /* | ||
2002 | this function returns the bus and virtual addresses of the static pool | ||
2003 | */ | ||
2004 | static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg) | ||
2005 | { | ||
2006 | int error; | ||
2007 | struct sep_driver_static_pool_addr_t command_args; | ||
2008 | |||
2009 | dbg("SEP Driver:--------> sep_get_static_pool_addr_handler start\n"); | ||
2010 | |||
2011 | /*prepare the output parameters in the struct */ | ||
2012 | command_args.physical_static_address = sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; | ||
2013 | command_args.virtual_static_address = (unsigned long)sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; | ||
2014 | |||
2015 | edbg("SEP Driver:bus_static_address is %08lx, virtual_static_address %08lx\n", command_args.physical_static_address, command_args.virtual_static_address); | ||
2016 | |||
2017 | /* send the parameters to user application */ | ||
2018 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_static_pool_addr_t)); | ||
2019 | if (error) | ||
2020 | error = -EFAULT; | ||
2021 | dbg("SEP Driver:<-------- sep_get_static_pool_addr_handler end\n"); | ||
2022 | return error; | ||
2023 | } | ||
2024 | |||
2025 | /* | ||
2026 | this address gets the offset of the physical address from the start | ||
2027 | of the mapped area | ||
2028 | */ | ||
2029 | static int sep_get_physical_mapped_offset_handler(struct sep_device *sep, unsigned long arg) | ||
2030 | { | ||
2031 | int error; | ||
2032 | struct sep_driver_get_mapped_offset_t command_args; | ||
2033 | |||
2034 | dbg("SEP Driver:--------> sep_get_physical_mapped_offset_handler start\n"); | ||
2035 | |||
2036 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_get_mapped_offset_t)); | ||
2037 | if (error) { | ||
2038 | error = -EFAULT; | ||
2039 | goto end_function; | ||
2040 | } | ||
2041 | |||
2042 | if (command_args.physical_address < sep->shared_bus) { | ||
2043 | error = -EINVAL; | ||
2044 | goto end_function; | ||
2045 | } | ||
2046 | |||
2047 | /*prepare the output parameters in the struct */ | ||
2048 | command_args.offset = command_args.physical_address - sep->shared_bus; | ||
2049 | |||
2050 | edbg("SEP Driver:bus_address is %08lx, offset is %lu\n", command_args.physical_address, command_args.offset); | ||
2051 | |||
2052 | /* send the parameters to user application */ | ||
2053 | error = copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_get_mapped_offset_t)); | ||
2054 | if (error) | ||
2055 | error = -EFAULT; | ||
2056 | end_function: | ||
2057 | dbg("SEP Driver:<-------- sep_get_physical_mapped_offset_handler end\n"); | ||
2058 | return error; | ||
2059 | } | ||
2060 | |||
2061 | |||
2062 | /* | ||
2063 | ? | ||
2064 | */ | ||
2065 | static int sep_start_handler(struct sep_device *sep) | ||
2066 | { | ||
2067 | unsigned long reg_val; | ||
2068 | unsigned long error = 0; | ||
2069 | |||
2070 | dbg("SEP Driver:--------> sep_start_handler start\n"); | ||
2071 | |||
2072 | /* wait in polling for message from SEP */ | ||
2073 | do | ||
2074 | reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
2075 | while (!reg_val); | ||
2076 | |||
2077 | /* check the value */ | ||
2078 | if (reg_val == 0x1) | ||
2079 | /* fatal error - read error status from GPRO */ | ||
2080 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
2081 | dbg("SEP Driver:<-------- sep_start_handler end\n"); | ||
2082 | return error; | ||
2083 | } | ||
2084 | |||
2085 | /* | ||
2086 | this function handles the request for SEP initialization | ||
2087 | */ | ||
2088 | static int sep_init_handler(struct sep_device *sep, unsigned long arg) | ||
2089 | { | ||
2090 | unsigned long message_word; | ||
2091 | unsigned long *message_ptr; | ||
2092 | struct sep_driver_init_t command_args; | ||
2093 | unsigned long counter; | ||
2094 | unsigned long error; | ||
2095 | unsigned long reg_val; | ||
2096 | |||
2097 | dbg("SEP Driver:--------> sep_init_handler start\n"); | ||
2098 | error = 0; | ||
2099 | |||
2100 | error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_init_t)); | ||
2101 | if (error) { | ||
2102 | error = -EFAULT; | ||
2103 | goto end_function; | ||
2104 | } | ||
2105 | dbg("SEP Driver:--------> sep_init_handler - finished copy_from_user\n"); | ||
2106 | |||
2107 | /* PATCH - configure the DMA to single -burst instead of multi-burst */ | ||
2108 | /*sep_configure_dma_burst(); */ | ||
2109 | |||
2110 | dbg("SEP Driver:--------> sep_init_handler - finished sep_configure_dma_burst \n"); | ||
2111 | |||
2112 | message_ptr = (unsigned long *) command_args.message_addr; | ||
2113 | |||
2114 | /* set the base address of the SRAM */ | ||
2115 | sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, HW_CC_SRAM_BASE_ADDRESS); | ||
2116 | |||
2117 | for (counter = 0; counter < command_args.message_size_in_words; counter++, message_ptr++) { | ||
2118 | get_user(message_word, message_ptr); | ||
2119 | /* write data to SRAM */ | ||
2120 | sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, message_word); | ||
2121 | edbg("SEP Driver:message_word is %lu\n", message_word); | ||
2122 | /* wait for write complete */ | ||
2123 | sep_wait_sram_write(sep); | ||
2124 | } | ||
2125 | dbg("SEP Driver:--------> sep_init_handler - finished getting messages from user space\n"); | ||
2126 | /* signal SEP */ | ||
2127 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1); | ||
2128 | |||
2129 | do | ||
2130 | reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); | ||
2131 | while (!(reg_val & 0xFFFFFFFD)); | ||
2132 | |||
2133 | dbg("SEP Driver:--------> sep_init_handler - finished waiting for reg_val & 0xFFFFFFFD \n"); | ||
2134 | |||
2135 | /* check the value */ | ||
2136 | if (reg_val == 0x1) { | ||
2137 | edbg("SEP Driver:init failed\n"); | ||
2138 | |||
2139 | error = sep_read_reg(sep, 0x8060); | ||
2140 | edbg("SEP Driver:sw monitor is %lu\n", error); | ||
2141 | |||
2142 | /* fatal error - read erro status from GPRO */ | ||
2143 | error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); | ||
2144 | edbg("SEP Driver:error is %lu\n", error); | ||
2145 | } | ||
2146 | end_function: | ||
2147 | dbg("SEP Driver:<-------- sep_init_handler end\n"); | ||
2148 | return error; | ||
2149 | |||
2150 | } | ||
2151 | |||
2152 | /* | ||
2153 | this function handles the request cache and resident reallocation | ||
2154 | */ | ||
2155 | static int sep_realloc_cache_resident_handler(struct sep_device *sep, | ||
2156 | unsigned long arg) | ||
2157 | { | ||
2158 | struct sep_driver_realloc_cache_resident_t command_args; | ||
2159 | int error; | ||
2160 | |||
2161 | /* copy cache and resident to the their intended locations */ | ||
2162 | error = sep_load_firmware(sep); | ||
2163 | if (error) | ||
2164 | return error; | ||
2165 | |||
2166 | command_args.new_base_addr = sep->shared_bus; | ||
2167 | |||
2168 | /* find the new base address according to the lowest address between | ||
2169 | cache, resident and shared area */ | ||
2170 | if (sep->resident_bus < command_args.new_base_addr) | ||
2171 | command_args.new_base_addr = sep->resident_bus; | ||
2172 | if (sep->rar_bus < command_args.new_base_addr) | ||
2173 | command_args.new_base_addr = sep->rar_bus; | ||
2174 | |||
2175 | /* set the return parameters */ | ||
2176 | command_args.new_cache_addr = sep->rar_bus; | ||
2177 | command_args.new_resident_addr = sep->resident_bus; | ||
2178 | |||
2179 | /* set the new shared area */ | ||
2180 | command_args.new_shared_area_addr = sep->shared_bus; | ||
2181 | |||
2182 | edbg("SEP Driver:command_args.new_shared_addr is %08llx\n", command_args.new_shared_area_addr); | ||
2183 | edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr); | ||
2184 | edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr); | ||
2185 | edbg("SEP Driver:command_args.new_rar_addr is %08llx\n", command_args.new_cache_addr); | ||
2186 | |||
2187 | /* return to user */ | ||
2188 | if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t))) | ||
2189 | return -EFAULT; | ||
2190 | return 0; | ||
2191 | } | ||
2192 | |||
2193 | /** | ||
2194 | * sep_get_time_handler - time request from user space | ||
2195 | * @sep: sep we are to set the time for | ||
2196 | * @arg: pointer to user space arg buffer | ||
2197 | * | ||
2198 | * This function reports back the time and the address in the SEP | ||
2199 | * shared buffer at which it has been placed. (Do we really need this!!!) | ||
2200 | */ | ||
2201 | |||
2202 | static int sep_get_time_handler(struct sep_device *sep, unsigned long arg) | ||
2203 | { | ||
2204 | struct sep_driver_get_time_t command_args; | ||
2205 | |||
2206 | mutex_lock(&sep_mutex); | ||
2207 | command_args.time_value = sep_set_time(sep); | ||
2208 | command_args.time_physical_address = (unsigned long)sep_time_address(sep); | ||
2209 | mutex_unlock(&sep_mutex); | ||
2210 | if (copy_to_user((void __user *)arg, | ||
2211 | &command_args, sizeof(struct sep_driver_get_time_t))) | ||
2212 | return -EFAULT; | ||
2213 | return 0; | ||
2214 | |||
2215 | } | ||
2216 | |||
2217 | /* | ||
2218 | This API handles the end transaction request | ||
2219 | */ | ||
2220 | static int sep_end_transaction_handler(struct sep_device *sep, unsigned long arg) | ||
2221 | { | ||
2222 | dbg("SEP Driver:--------> sep_end_transaction_handler start\n"); | ||
2223 | |||
2224 | #if 0 /*!SEP_DRIVER_POLLING_MODE */ | ||
2225 | /* close IMR */ | ||
2226 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0x7FFF); | ||
2227 | |||
2228 | /* release IRQ line */ | ||
2229 | free_irq(SEP_DIRVER_IRQ_NUM, sep); | ||
2230 | |||
2231 | /* lock the sep mutex */ | ||
2232 | mutex_unlock(&sep_mutex); | ||
2233 | #endif | ||
2234 | |||
2235 | dbg("SEP Driver:<-------- sep_end_transaction_handler end\n"); | ||
2236 | |||
2237 | return 0; | ||
2238 | } | ||
2239 | |||
2240 | |||
2241 | /** | ||
2242 | * sep_set_flow_id_handler - handle flow setting | ||
2243 | * @sep: the SEP we are configuring | ||
2244 | * @flow_id: the flow we are setting | ||
2245 | * | ||
2246 | * This function handler the set flow id command | ||
2247 | */ | ||
2248 | static int sep_set_flow_id_handler(struct sep_device *sep, | ||
2249 | unsigned long flow_id) | ||
2250 | { | ||
2251 | int error = 0; | ||
2252 | struct sep_flow_context_t *flow_data_ptr; | ||
2253 | |||
2254 | /* find the flow data structure that was just used for creating new flow | ||
2255 | - its id should be default */ | ||
2256 | |||
2257 | mutex_lock(&sep_mutex); | ||
2258 | flow_data_ptr = sep_find_flow_context(sep, SEP_TEMP_FLOW_ID); | ||
2259 | if (flow_data_ptr) | ||
2260 | flow_data_ptr->flow_id = flow_id; /* set flow id */ | ||
2261 | else | ||
2262 | error = -EINVAL; | ||
2263 | mutex_unlock(&sep_mutex); | ||
2264 | return error; | ||
2265 | } | ||
2266 | |||
2267 | static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | ||
2268 | { | ||
2269 | int error = 0; | ||
2270 | struct sep_device *sep = filp->private_data; | ||
2271 | |||
2272 | dbg("------------>SEP Driver: ioctl start\n"); | ||
2273 | |||
2274 | edbg("SEP Driver: cmd is %x\n", cmd); | ||
2275 | |||
2276 | switch (cmd) { | ||
2277 | case SEP_IOCSENDSEPCOMMAND: | ||
2278 | /* send command to SEP */ | ||
2279 | sep_send_command_handler(sep); | ||
2280 | edbg("SEP Driver: after sep_send_command_handler\n"); | ||
2281 | break; | ||
2282 | case SEP_IOCSENDSEPRPLYCOMMAND: | ||
2283 | /* send reply command to SEP */ | ||
2284 | sep_send_reply_command_handler(sep); | ||
2285 | break; | ||
2286 | case SEP_IOCALLOCDATAPOLL: | ||
2287 | /* allocate data pool */ | ||
2288 | error = sep_allocate_data_pool_memory_handler(sep, arg); | ||
2289 | break; | ||
2290 | case SEP_IOCWRITEDATAPOLL: | ||
2291 | /* write data into memory pool */ | ||
2292 | error = sep_write_into_data_pool_handler(sep, arg); | ||
2293 | break; | ||
2294 | case SEP_IOCREADDATAPOLL: | ||
2295 | /* read data from data pool into application memory */ | ||
2296 | error = sep_read_from_data_pool_handler(sep, arg); | ||
2297 | break; | ||
2298 | case SEP_IOCCREATESYMDMATABLE: | ||
2299 | /* create dma table for synhronic operation */ | ||
2300 | error = sep_create_sync_dma_tables_handler(sep, arg); | ||
2301 | break; | ||
2302 | case SEP_IOCCREATEFLOWDMATABLE: | ||
2303 | /* create flow dma tables */ | ||
2304 | error = sep_create_flow_dma_tables_handler(sep, arg); | ||
2305 | break; | ||
2306 | case SEP_IOCFREEDMATABLEDATA: | ||
2307 | /* free the pages */ | ||
2308 | error = sep_free_dma_table_data_handler(sep); | ||
2309 | break; | ||
2310 | case SEP_IOCSETFLOWID: | ||
2311 | /* set flow id */ | ||
2312 | error = sep_set_flow_id_handler(sep, (unsigned long)arg); | ||
2313 | break; | ||
2314 | case SEP_IOCADDFLOWTABLE: | ||
2315 | /* add tables to the dynamic flow */ | ||
2316 | error = sep_add_flow_tables_handler(sep, arg); | ||
2317 | break; | ||
2318 | case SEP_IOCADDFLOWMESSAGE: | ||
2319 | /* add message of add tables to flow */ | ||
2320 | error = sep_add_flow_tables_message_handler(sep, arg); | ||
2321 | break; | ||
2322 | case SEP_IOCSEPSTART: | ||
2323 | /* start command to sep */ | ||
2324 | error = sep_start_handler(sep); | ||
2325 | break; | ||
2326 | case SEP_IOCSEPINIT: | ||
2327 | /* init command to sep */ | ||
2328 | error = sep_init_handler(sep, arg); | ||
2329 | break; | ||
2330 | case SEP_IOCGETSTATICPOOLADDR: | ||
2331 | /* get the physical and virtual addresses of the static pool */ | ||
2332 | error = sep_get_static_pool_addr_handler(sep, arg); | ||
2333 | break; | ||
2334 | case SEP_IOCENDTRANSACTION: | ||
2335 | error = sep_end_transaction_handler(sep, arg); | ||
2336 | break; | ||
2337 | case SEP_IOCREALLOCCACHERES: | ||
2338 | error = sep_realloc_cache_resident_handler(sep, arg); | ||
2339 | break; | ||
2340 | case SEP_IOCGETMAPPEDADDROFFSET: | ||
2341 | error = sep_get_physical_mapped_offset_handler(sep, arg); | ||
2342 | break; | ||
2343 | case SEP_IOCGETIME: | ||
2344 | error = sep_get_time_handler(sep, arg); | ||
2345 | break; | ||
2346 | default: | ||
2347 | error = -ENOTTY; | ||
2348 | break; | ||
2349 | } | ||
2350 | dbg("SEP Driver:<-------- ioctl end\n"); | ||
2351 | return error; | ||
2352 | } | ||
2353 | |||
2354 | |||
2355 | |||
2356 | #if !SEP_DRIVER_POLLING_MODE | ||
2357 | |||
2358 | /* handler for flow done interrupt */ | ||
2359 | |||
2360 | static void sep_flow_done_handler(struct work_struct *work) | ||
2361 | { | ||
2362 | struct sep_flow_context_t *flow_data_ptr; | ||
2363 | |||
2364 | /* obtain the mutex */ | ||
2365 | mutex_lock(&sep_mutex); | ||
2366 | |||
2367 | /* get the pointer to context */ | ||
2368 | flow_data_ptr = (struct sep_flow_context_t *) work; | ||
2369 | |||
2370 | /* free all the current input tables in sep */ | ||
2371 | sep_deallocated_flow_tables(&flow_data_ptr->input_tables_in_process); | ||
2372 | |||
2373 | /* free all the current tables output tables in SEP (if needed) */ | ||
2374 | if (flow_data_ptr->output_tables_in_process.physical_address != 0xffffffff) | ||
2375 | sep_deallocated_flow_tables(&flow_data_ptr->output_tables_in_process); | ||
2376 | |||
2377 | /* check if we have additional tables to be sent to SEP only input | ||
2378 | flag may be checked */ | ||
2379 | if (flow_data_ptr->input_tables_flag) { | ||
2380 | /* copy the message to the shared RAM and signal SEP */ | ||
2381 | memcpy((void *) flow_data_ptr->message, (void *) sep->shared_addr, flow_data_ptr->message_size_in_bytes); | ||
2382 | |||
2383 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, 0x2); | ||
2384 | } | ||
2385 | mutex_unlock(&sep_mutex); | ||
2386 | } | ||
2387 | /* | ||
2388 | interrupt handler function | ||
2389 | */ | ||
2390 | static irqreturn_t sep_inthandler(int irq, void *dev_id) | ||
2391 | { | ||
2392 | irqreturn_t int_error; | ||
2393 | unsigned long reg_val; | ||
2394 | unsigned long flow_id; | ||
2395 | struct sep_flow_context_t *flow_context_ptr; | ||
2396 | struct sep_device *sep = dev_id; | ||
2397 | |||
2398 | int_error = IRQ_HANDLED; | ||
2399 | |||
2400 | /* read the IRR register to check if this is SEP interrupt */ | ||
2401 | reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); | ||
2402 | edbg("SEP Interrupt - reg is %08lx\n", reg_val); | ||
2403 | |||
2404 | /* check if this is the flow interrupt */ | ||
2405 | if (0 /*reg_val & (0x1 << 11) */ ) { | ||
2406 | /* read GPRO to find out the which flow is done */ | ||
2407 | flow_id = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); | ||
2408 | |||
2409 | /* find the contex of the flow */ | ||
2410 | flow_context_ptr = sep_find_flow_context(sep, flow_id >> 28); | ||
2411 | if (flow_context_ptr == NULL) | ||
2412 | goto end_function_with_error; | ||
2413 | |||
2414 | /* queue the work */ | ||
2415 | INIT_WORK(&flow_context_ptr->flow_wq, sep_flow_done_handler); | ||
2416 | queue_work(sep->flow_wq, &flow_context_ptr->flow_wq); | ||
2417 | |||
2418 | } else { | ||
2419 | /* check if this is reply interrupt from SEP */ | ||
2420 | if (reg_val & (0x1 << 13)) { | ||
2421 | /* update the counter of reply messages */ | ||
2422 | sep->reply_ct++; | ||
2423 | /* wake up the waiting process */ | ||
2424 | wake_up(&sep_event); | ||
2425 | } else { | ||
2426 | int_error = IRQ_NONE; | ||
2427 | goto end_function; | ||
2428 | } | ||
2429 | } | ||
2430 | end_function_with_error: | ||
2431 | /* clear the interrupt */ | ||
2432 | sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); | ||
2433 | end_function: | ||
2434 | return int_error; | ||
2435 | } | ||
2436 | |||
2437 | #endif | ||
2438 | |||
2439 | |||
2440 | |||
2441 | #if 0 | ||
2442 | |||
2443 | static void sep_wait_busy(struct sep_device *sep) | ||
2444 | { | ||
2445 | u32 reg; | ||
2446 | |||
2447 | do { | ||
2448 | reg = sep_read_reg(sep, HW_HOST_SEP_BUSY_REG_ADDR); | ||
2449 | } while (reg); | ||
2450 | } | ||
2451 | |||
2452 | /* | ||
2453 | PATCH for configuring the DMA to single burst instead of multi-burst | ||
2454 | */ | ||
2455 | static void sep_configure_dma_burst(struct sep_device *sep) | ||
2456 | { | ||
2457 | #define HW_AHB_RD_WR_BURSTS_REG_ADDR 0x0E10UL | ||
2458 | |||
2459 | dbg("SEP Driver:<-------- sep_configure_dma_burst start \n"); | ||
2460 | |||
2461 | /* request access to registers from SEP */ | ||
2462 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); | ||
2463 | |||
2464 | dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (write reg) \n"); | ||
2465 | |||
2466 | sep_wait_busy(sep); | ||
2467 | |||
2468 | dbg("SEP Driver:<-------- sep_configure_dma_burst finished request access to registers from SEP (while(revVal) wait loop) \n"); | ||
2469 | |||
2470 | /* set the DMA burst register to single burst */ | ||
2471 | sep_write_reg(sep, HW_AHB_RD_WR_BURSTS_REG_ADDR, 0x0UL); | ||
2472 | |||
2473 | /* release the sep busy */ | ||
2474 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x0UL); | ||
2475 | sep_wait_busy(sep); | ||
2476 | |||
2477 | dbg("SEP Driver:<-------- sep_configure_dma_burst done \n"); | ||
2478 | |||
2479 | } | ||
2480 | |||
2481 | #endif | ||
2482 | |||
2483 | /* | ||
2484 | Function that is activated on the successful probe of the SEP device | ||
2485 | */ | ||
2486 | static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
2487 | { | ||
2488 | int error = 0; | ||
2489 | struct sep_device *sep; | ||
2490 | int counter; | ||
2491 | int size; /* size of memory for allocation */ | ||
2492 | |||
2493 | edbg("Sep pci probe starting\n"); | ||
2494 | if (sep_dev != NULL) { | ||
2495 | dev_warn(&pdev->dev, "only one SEP supported.\n"); | ||
2496 | return -EBUSY; | ||
2497 | } | ||
2498 | |||
2499 | /* enable the device */ | ||
2500 | error = pci_enable_device(pdev); | ||
2501 | if (error) { | ||
2502 | edbg("error enabling pci device\n"); | ||
2503 | goto end_function; | ||
2504 | } | ||
2505 | |||
2506 | /* set the pci dev pointer */ | ||
2507 | sep_dev = &sep_instance; | ||
2508 | sep = &sep_instance; | ||
2509 | |||
2510 | edbg("sep->shared_addr = %p\n", sep->shared_addr); | ||
2511 | /* transaction counter that coordinates the transactions between SEP | ||
2512 | and HOST */ | ||
2513 | sep->send_ct = 0; | ||
2514 | /* counter for the messages from sep */ | ||
2515 | sep->reply_ct = 0; | ||
2516 | /* counter for the number of bytes allocated in the pool | ||
2517 | for the current transaction */ | ||
2518 | sep->data_pool_bytes_allocated = 0; | ||
2519 | |||
2520 | /* calculate the total size for allocation */ | ||
2521 | size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + | ||
2522 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; | ||
2523 | |||
2524 | /* allocate the shared area */ | ||
2525 | if (sep_map_and_alloc_shared_area(sep, size)) { | ||
2526 | error = -ENOMEM; | ||
2527 | /* allocation failed */ | ||
2528 | goto end_function_error; | ||
2529 | } | ||
2530 | /* now set the memory regions */ | ||
2531 | #if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1) | ||
2532 | /* Note: this test section will need moving before it could ever | ||
2533 | work as the registers are not yet mapped ! */ | ||
2534 | /* send the new SHARED MESSAGE AREA to the SEP */ | ||
2535 | sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); | ||
2536 | |||
2537 | /* poll for SEP response */ | ||
2538 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); | ||
2539 | while (retval != 0xffffffff && retval != sep->shared_bus) | ||
2540 | retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); | ||
2541 | |||
2542 | /* check the return value (register) */ | ||
2543 | if (retval != sep->shared_bus) { | ||
2544 | error = -ENOMEM; | ||
2545 | goto end_function_deallocate_sep_shared_area; | ||
2546 | } | ||
2547 | #endif | ||
2548 | /* init the flow contextes */ | ||
2549 | for (counter = 0; counter < SEP_DRIVER_NUM_FLOWS; counter++) | ||
2550 | sep->flows[counter].flow_id = SEP_FREE_FLOW_ID; | ||
2551 | |||
2552 | sep->flow_wq = create_singlethread_workqueue("sepflowwq"); | ||
2553 | if (sep->flow_wq == NULL) { | ||
2554 | error = -ENOMEM; | ||
2555 | edbg("sep_driver:flow queue creation failed\n"); | ||
2556 | goto end_function_deallocate_sep_shared_area; | ||
2557 | } | ||
2558 | edbg("SEP Driver: create flow workqueue \n"); | ||
2559 | sep->pdev = pci_dev_get(pdev); | ||
2560 | |||
2561 | sep->reg_addr = pci_ioremap_bar(pdev, 0); | ||
2562 | if (!sep->reg_addr) { | ||
2563 | edbg("sep: ioremap of registers failed.\n"); | ||
2564 | goto end_function_deallocate_sep_shared_area; | ||
2565 | } | ||
2566 | edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr); | ||
2567 | |||
2568 | /* load the rom code */ | ||
2569 | sep_load_rom_code(sep); | ||
2570 | |||
2571 | /* set up system base address and shared memory location */ | ||
2572 | sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev, | ||
2573 | 2 * SEP_RAR_IO_MEM_REGION_SIZE, | ||
2574 | &sep->rar_bus, GFP_KERNEL); | ||
2575 | |||
2576 | if (!sep->rar_addr) { | ||
2577 | edbg("SEP Driver:can't allocate rar\n"); | ||
2578 | goto end_function_uniomap; | ||
2579 | } | ||
2580 | |||
2581 | |||
2582 | edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); | ||
2583 | edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); | ||
2584 | |||
2585 | #if !SEP_DRIVER_POLLING_MODE | ||
2586 | |||
2587 | edbg("SEP Driver: about to write IMR and ICR REG_ADDR\n"); | ||
2588 | |||
2589 | /* clear ICR register */ | ||
2590 | sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); | ||
2591 | |||
2592 | /* set the IMR register - open only GPR 2 */ | ||
2593 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); | ||
2594 | |||
2595 | edbg("SEP Driver: about to call request_irq\n"); | ||
2596 | /* get the interrupt line */ | ||
2597 | error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep); | ||
2598 | if (error) | ||
2599 | goto end_function_free_res; | ||
2600 | return 0; | ||
2601 | edbg("SEP Driver: about to write IMR REG_ADDR"); | ||
2602 | |||
2603 | /* set the IMR register - open only GPR 2 */ | ||
2604 | sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); | ||
2605 | |||
2606 | end_function_free_res: | ||
2607 | dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE, | ||
2608 | sep->rar_addr, sep->rar_bus); | ||
2609 | #endif /* SEP_DRIVER_POLLING_MODE */ | ||
2610 | end_function_uniomap: | ||
2611 | iounmap(sep->reg_addr); | ||
2612 | end_function_deallocate_sep_shared_area: | ||
2613 | /* de-allocate shared area */ | ||
2614 | sep_unmap_and_free_shared_area(sep, size); | ||
2615 | end_function_error: | ||
2616 | sep_dev = NULL; | ||
2617 | end_function: | ||
2618 | return error; | ||
2619 | } | ||
2620 | |||
2621 | static const struct pci_device_id sep_pci_id_tbl[] = { | ||
2622 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080c)}, | ||
2623 | {0} | ||
2624 | }; | ||
2625 | |||
2626 | MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); | ||
2627 | |||
2628 | /* field for registering driver to PCI device */ | ||
2629 | static struct pci_driver sep_pci_driver = { | ||
2630 | .name = "sep_sec_driver", | ||
2631 | .id_table = sep_pci_id_tbl, | ||
2632 | .probe = sep_probe | ||
2633 | /* FIXME: remove handler */ | ||
2634 | }; | ||
2635 | |||
2636 | /* major and minor device numbers */ | ||
2637 | static dev_t sep_devno; | ||
2638 | |||
2639 | /* the files operations structure of the driver */ | ||
2640 | static struct file_operations sep_file_operations = { | ||
2641 | .owner = THIS_MODULE, | ||
2642 | .unlocked_ioctl = sep_ioctl, | ||
2643 | .poll = sep_poll, | ||
2644 | .open = sep_open, | ||
2645 | .release = sep_release, | ||
2646 | .mmap = sep_mmap, | ||
2647 | }; | ||
2648 | |||
2649 | |||
2650 | /* cdev struct of the driver */ | ||
2651 | static struct cdev sep_cdev; | ||
2652 | |||
2653 | /* | ||
2654 | this function registers the driver to the file system | ||
2655 | */ | ||
2656 | static int sep_register_driver_to_fs(void) | ||
2657 | { | ||
2658 | int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver"); | ||
2659 | if (ret_val) { | ||
2660 | edbg("sep: major number allocation failed, retval is %d\n", | ||
2661 | ret_val); | ||
2662 | return ret_val; | ||
2663 | } | ||
2664 | /* init cdev */ | ||
2665 | cdev_init(&sep_cdev, &sep_file_operations); | ||
2666 | sep_cdev.owner = THIS_MODULE; | ||
2667 | |||
2668 | /* register the driver with the kernel */ | ||
2669 | ret_val = cdev_add(&sep_cdev, sep_devno, 1); | ||
2670 | if (ret_val) { | ||
2671 | edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val); | ||
2672 | /* unregister dev numbers */ | ||
2673 | unregister_chrdev_region(sep_devno, 1); | ||
2674 | } | ||
2675 | return ret_val; | ||
2676 | } | ||
2677 | |||
2678 | |||
2679 | /*-------------------------------------------------------------- | ||
2680 | init function | ||
2681 | ----------------------------------------------------------------*/ | ||
2682 | static int __init sep_init(void) | ||
2683 | { | ||
2684 | int ret_val = 0; | ||
2685 | dbg("SEP Driver:-------->Init start\n"); | ||
2686 | /* FIXME: Probe can occur before we are ready to survive a probe */ | ||
2687 | ret_val = pci_register_driver(&sep_pci_driver); | ||
2688 | if (ret_val) { | ||
2689 | edbg("sep_driver:sep_driver_to_device failed, ret_val is %d\n", ret_val); | ||
2690 | goto end_function_unregister_from_fs; | ||
2691 | } | ||
2692 | /* register driver to fs */ | ||
2693 | ret_val = sep_register_driver_to_fs(); | ||
2694 | if (ret_val) | ||
2695 | goto end_function_unregister_pci; | ||
2696 | goto end_function; | ||
2697 | end_function_unregister_pci: | ||
2698 | pci_unregister_driver(&sep_pci_driver); | ||
2699 | end_function_unregister_from_fs: | ||
2700 | /* unregister from fs */ | ||
2701 | cdev_del(&sep_cdev); | ||
2702 | /* unregister dev numbers */ | ||
2703 | unregister_chrdev_region(sep_devno, 1); | ||
2704 | end_function: | ||
2705 | dbg("SEP Driver:<-------- Init end\n"); | ||
2706 | return ret_val; | ||
2707 | } | ||
2708 | |||
2709 | |||
2710 | /*------------------------------------------------------------- | ||
2711 | exit function | ||
2712 | --------------------------------------------------------------*/ | ||
2713 | static void __exit sep_exit(void) | ||
2714 | { | ||
2715 | int size; | ||
2716 | |||
2717 | dbg("SEP Driver:--------> Exit start\n"); | ||
2718 | |||
2719 | /* unregister from fs */ | ||
2720 | cdev_del(&sep_cdev); | ||
2721 | /* unregister dev numbers */ | ||
2722 | unregister_chrdev_region(sep_devno, 1); | ||
2723 | /* calculate the total size for de-allocation */ | ||
2724 | size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + | ||
2725 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; | ||
2726 | /* FIXME: We need to do this in the unload for the device */ | ||
2727 | /* free shared area */ | ||
2728 | if (sep_dev) { | ||
2729 | sep_unmap_and_free_shared_area(sep_dev, size); | ||
2730 | edbg("SEP Driver: free pages SEP SHARED AREA \n"); | ||
2731 | iounmap((void *) sep_dev->reg_addr); | ||
2732 | edbg("SEP Driver: iounmap \n"); | ||
2733 | } | ||
2734 | edbg("SEP Driver: release_mem_region \n"); | ||
2735 | dbg("SEP Driver:<-------- Exit end\n"); | ||
2736 | } | ||
2737 | |||
2738 | |||
2739 | module_init(sep_init); | ||
2740 | module_exit(sep_exit); | ||
2741 | |||
2742 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h deleted file mode 100644 index 7ef16da7c4ef..000000000000 --- a/drivers/staging/sep/sep_driver_api.h +++ /dev/null | |||
@@ -1,425 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_api.h - Security Processor Driver api definitions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef __SEP_DRIVER_API_H__ | ||
33 | #define __SEP_DRIVER_API_H__ | ||
34 | |||
35 | |||
36 | |||
37 | /*---------------------------------------------------------------- | ||
38 | IOCTL command defines | ||
39 | -----------------------------------------------------------------*/ | ||
40 | |||
41 | /* magic number 1 of the sep IOCTL command */ | ||
42 | #define SEP_IOC_MAGIC_NUMBER 's' | ||
43 | |||
44 | /* sends interrupt to sep that message is ready */ | ||
45 | #define SEP_IOCSENDSEPCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 0) | ||
46 | |||
47 | /* sends interrupt to sep that message is ready */ | ||
48 | #define SEP_IOCSENDSEPRPLYCOMMAND _IO(SEP_IOC_MAGIC_NUMBER , 1) | ||
49 | |||
50 | /* allocate memory in data pool */ | ||
51 | #define SEP_IOCALLOCDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 2) | ||
52 | |||
53 | /* write to pre-allocated memory in data pool */ | ||
54 | #define SEP_IOCWRITEDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 3) | ||
55 | |||
56 | /* read from pre-allocated memory in data pool */ | ||
57 | #define SEP_IOCREADDATAPOLL _IO(SEP_IOC_MAGIC_NUMBER , 4) | ||
58 | |||
59 | /* create sym dma lli tables */ | ||
60 | #define SEP_IOCCREATESYMDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 5) | ||
61 | |||
62 | /* create flow dma lli tables */ | ||
63 | #define SEP_IOCCREATEFLOWDMATABLE _IO(SEP_IOC_MAGIC_NUMBER , 6) | ||
64 | |||
65 | /* free dynamic data aalocated during table creation */ | ||
66 | #define SEP_IOCFREEDMATABLEDATA _IO(SEP_IOC_MAGIC_NUMBER , 7) | ||
67 | |||
68 | /* get the static pool area addresses (physical and virtual) */ | ||
69 | #define SEP_IOCGETSTATICPOOLADDR _IO(SEP_IOC_MAGIC_NUMBER , 8) | ||
70 | |||
71 | /* set flow id command */ | ||
72 | #define SEP_IOCSETFLOWID _IO(SEP_IOC_MAGIC_NUMBER , 9) | ||
73 | |||
74 | /* add tables to the dynamic flow */ | ||
75 | #define SEP_IOCADDFLOWTABLE _IO(SEP_IOC_MAGIC_NUMBER , 10) | ||
76 | |||
77 | /* add flow add tables message */ | ||
78 | #define SEP_IOCADDFLOWMESSAGE _IO(SEP_IOC_MAGIC_NUMBER , 11) | ||
79 | |||
80 | /* start sep command */ | ||
81 | #define SEP_IOCSEPSTART _IO(SEP_IOC_MAGIC_NUMBER , 12) | ||
82 | |||
83 | /* init sep command */ | ||
84 | #define SEP_IOCSEPINIT _IO(SEP_IOC_MAGIC_NUMBER , 13) | ||
85 | |||
86 | /* end transaction command */ | ||
87 | #define SEP_IOCENDTRANSACTION _IO(SEP_IOC_MAGIC_NUMBER , 15) | ||
88 | |||
89 | /* reallocate cache and resident */ | ||
90 | #define SEP_IOCREALLOCCACHERES _IO(SEP_IOC_MAGIC_NUMBER , 16) | ||
91 | |||
92 | /* get the offset of the address starting from the beginnnig of the map area */ | ||
93 | #define SEP_IOCGETMAPPEDADDROFFSET _IO(SEP_IOC_MAGIC_NUMBER , 17) | ||
94 | |||
95 | /* get time address and value */ | ||
96 | #define SEP_IOCGETIME _IO(SEP_IOC_MAGIC_NUMBER , 19) | ||
97 | |||
98 | /*------------------------------------------- | ||
99 | TYPEDEFS | ||
100 | ----------------------------------------------*/ | ||
101 | |||
102 | /* | ||
103 | init command struct | ||
104 | */ | ||
105 | struct sep_driver_init_t { | ||
106 | /* start of the 1G of the host memory address that SEP can access */ | ||
107 | unsigned long message_addr; | ||
108 | |||
109 | /* start address of resident */ | ||
110 | unsigned long message_size_in_words; | ||
111 | |||
112 | }; | ||
113 | |||
114 | |||
115 | /* | ||
116 | realloc cache resident command | ||
117 | */ | ||
118 | struct sep_driver_realloc_cache_resident_t { | ||
119 | /* new cache address */ | ||
120 | u64 new_cache_addr; | ||
121 | /* new resident address */ | ||
122 | u64 new_resident_addr; | ||
123 | /* new resident address */ | ||
124 | u64 new_shared_area_addr; | ||
125 | /* new base address */ | ||
126 | u64 new_base_addr; | ||
127 | }; | ||
128 | |||
129 | struct sep_driver_alloc_t { | ||
130 | /* virtual address of allocated space */ | ||
131 | unsigned long offset; | ||
132 | |||
133 | /* physical address of allocated space */ | ||
134 | unsigned long phys_address; | ||
135 | |||
136 | /* number of bytes to allocate */ | ||
137 | unsigned long num_bytes; | ||
138 | }; | ||
139 | |||
140 | /* | ||
141 | */ | ||
142 | struct sep_driver_write_t { | ||
143 | /* application space address */ | ||
144 | unsigned long app_address; | ||
145 | |||
146 | /* address of the data pool */ | ||
147 | unsigned long datapool_address; | ||
148 | |||
149 | /* number of bytes to write */ | ||
150 | unsigned long num_bytes; | ||
151 | }; | ||
152 | |||
153 | /* | ||
154 | */ | ||
155 | struct sep_driver_read_t { | ||
156 | /* application space address */ | ||
157 | unsigned long app_address; | ||
158 | |||
159 | /* address of the data pool */ | ||
160 | unsigned long datapool_address; | ||
161 | |||
162 | /* number of bytes to read */ | ||
163 | unsigned long num_bytes; | ||
164 | }; | ||
165 | |||
166 | /* | ||
167 | */ | ||
168 | struct sep_driver_build_sync_table_t { | ||
169 | /* address value of the data in */ | ||
170 | unsigned long app_in_address; | ||
171 | |||
172 | /* size of data in */ | ||
173 | unsigned long data_in_size; | ||
174 | |||
175 | /* address of the data out */ | ||
176 | unsigned long app_out_address; | ||
177 | |||
178 | /* the size of the block of the operation - if needed, | ||
179 | every table will be modulo this parameter */ | ||
180 | unsigned long block_size; | ||
181 | |||
182 | /* the physical address of the first input DMA table */ | ||
183 | unsigned long in_table_address; | ||
184 | |||
185 | /* number of entries in the first input DMA table */ | ||
186 | unsigned long in_table_num_entries; | ||
187 | |||
188 | /* the physical address of the first output DMA table */ | ||
189 | unsigned long out_table_address; | ||
190 | |||
191 | /* number of entries in the first output DMA table */ | ||
192 | unsigned long out_table_num_entries; | ||
193 | |||
194 | /* data in the first input table */ | ||
195 | unsigned long table_data_size; | ||
196 | |||
197 | /* distinct user/kernel layout */ | ||
198 | bool isKernelVirtualAddress; | ||
199 | |||
200 | }; | ||
201 | |||
202 | /* | ||
203 | */ | ||
204 | struct sep_driver_build_flow_table_t { | ||
205 | /* flow type */ | ||
206 | unsigned long flow_type; | ||
207 | |||
208 | /* flag for input output */ | ||
209 | unsigned long input_output_flag; | ||
210 | |||
211 | /* address value of the data in */ | ||
212 | unsigned long virt_buff_data_addr; | ||
213 | |||
214 | /* size of data in */ | ||
215 | unsigned long num_virtual_buffers; | ||
216 | |||
217 | /* the physical address of the first input DMA table */ | ||
218 | unsigned long first_table_addr; | ||
219 | |||
220 | /* number of entries in the first input DMA table */ | ||
221 | unsigned long first_table_num_entries; | ||
222 | |||
223 | /* data in the first input table */ | ||
224 | unsigned long first_table_data_size; | ||
225 | |||
226 | /* distinct user/kernel layout */ | ||
227 | bool isKernelVirtualAddress; | ||
228 | }; | ||
229 | |||
230 | |||
231 | struct sep_driver_add_flow_table_t { | ||
232 | /* flow id */ | ||
233 | unsigned long flow_id; | ||
234 | |||
235 | /* flag for input output */ | ||
236 | unsigned long inputOutputFlag; | ||
237 | |||
238 | /* address value of the data in */ | ||
239 | unsigned long virt_buff_data_addr; | ||
240 | |||
241 | /* size of data in */ | ||
242 | unsigned long num_virtual_buffers; | ||
243 | |||
244 | /* address of the first table */ | ||
245 | unsigned long first_table_addr; | ||
246 | |||
247 | /* number of entries in the first table */ | ||
248 | unsigned long first_table_num_entries; | ||
249 | |||
250 | /* data size of the first table */ | ||
251 | unsigned long first_table_data_size; | ||
252 | |||
253 | /* distinct user/kernel layout */ | ||
254 | bool isKernelVirtualAddress; | ||
255 | |||
256 | }; | ||
257 | |||
258 | /* | ||
259 | command struct for set flow id | ||
260 | */ | ||
261 | struct sep_driver_set_flow_id_t { | ||
262 | /* flow id to set */ | ||
263 | unsigned long flow_id; | ||
264 | }; | ||
265 | |||
266 | |||
267 | /* command struct for add tables message */ | ||
268 | struct sep_driver_add_message_t { | ||
269 | /* flow id to set */ | ||
270 | unsigned long flow_id; | ||
271 | |||
272 | /* message size in bytes */ | ||
273 | unsigned long message_size_in_bytes; | ||
274 | |||
275 | /* address of the message */ | ||
276 | unsigned long message_address; | ||
277 | }; | ||
278 | |||
279 | /* command struct for static pool addresses */ | ||
280 | struct sep_driver_static_pool_addr_t { | ||
281 | /* physical address of the static pool */ | ||
282 | unsigned long physical_static_address; | ||
283 | |||
284 | /* virtual address of the static pool */ | ||
285 | unsigned long virtual_static_address; | ||
286 | }; | ||
287 | |||
288 | /* command struct for getiing offset of the physical address from | ||
289 | the start of the mapped area */ | ||
290 | struct sep_driver_get_mapped_offset_t { | ||
291 | /* physical address of the static pool */ | ||
292 | unsigned long physical_address; | ||
293 | |||
294 | /* virtual address of the static pool */ | ||
295 | unsigned long offset; | ||
296 | }; | ||
297 | |||
298 | /* command struct for getting time value and address */ | ||
299 | struct sep_driver_get_time_t { | ||
300 | /* physical address of stored time */ | ||
301 | unsigned long time_physical_address; | ||
302 | |||
303 | /* value of the stored time */ | ||
304 | unsigned long time_value; | ||
305 | }; | ||
306 | |||
307 | |||
308 | /* | ||
309 | structure that represent one entry in the DMA LLI table | ||
310 | */ | ||
311 | struct sep_lli_entry_t { | ||
312 | /* physical address */ | ||
313 | unsigned long physical_address; | ||
314 | |||
315 | /* block size */ | ||
316 | unsigned long block_size; | ||
317 | }; | ||
318 | |||
319 | /* | ||
320 | structure that reperesents data needed for lli table construction | ||
321 | */ | ||
322 | struct sep_lli_prepare_table_data_t { | ||
323 | /* pointer to the memory where the first lli entry to be built */ | ||
324 | struct sep_lli_entry_t *lli_entry_ptr; | ||
325 | |||
326 | /* pointer to the array of lli entries from which the table is to be built */ | ||
327 | struct sep_lli_entry_t *lli_array_ptr; | ||
328 | |||
329 | /* number of elements in lli array */ | ||
330 | int lli_array_size; | ||
331 | |||
332 | /* number of entries in the created table */ | ||
333 | int num_table_entries; | ||
334 | |||
335 | /* number of array entries processed during table creation */ | ||
336 | int num_array_entries_processed; | ||
337 | |||
338 | /* the totatl data size in the created table */ | ||
339 | int lli_table_total_data_size; | ||
340 | }; | ||
341 | |||
342 | /* | ||
343 | structure that represent tone table - it is not used in code, jkust | ||
344 | to show what table looks like | ||
345 | */ | ||
346 | struct sep_lli_table_t { | ||
347 | /* number of pages mapped in this tables. If 0 - means that the table | ||
348 | is not defined (used as a valid flag) */ | ||
349 | unsigned long num_pages; | ||
350 | /* | ||
351 | pointer to array of page pointers that represent the mapping of the | ||
352 | virtual buffer defined by the table to the physical memory. If this | ||
353 | pointer is NULL, it means that the table is not defined | ||
354 | (used as a valid flag) | ||
355 | */ | ||
356 | struct page **table_page_array_ptr; | ||
357 | |||
358 | /* maximum flow entries in table */ | ||
359 | struct sep_lli_entry_t lli_entries[SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE]; | ||
360 | }; | ||
361 | |||
362 | |||
363 | /* | ||
364 | structure for keeping the mapping of the virtual buffer into physical pages | ||
365 | */ | ||
366 | struct sep_flow_buffer_data { | ||
367 | /* pointer to the array of page structs pointers to the pages of the | ||
368 | virtual buffer */ | ||
369 | struct page **page_array_ptr; | ||
370 | |||
371 | /* number of pages taken by the virtual buffer */ | ||
372 | unsigned long num_pages; | ||
373 | |||
374 | /* this flag signals if this page_array is the last one among many that were | ||
375 | sent in one setting to SEP */ | ||
376 | unsigned long last_page_array_flag; | ||
377 | }; | ||
378 | |||
379 | /* | ||
380 | struct that keeps all the data for one flow | ||
381 | */ | ||
382 | struct sep_flow_context_t { | ||
383 | /* | ||
384 | work struct for handling the flow done interrupt in the workqueue | ||
385 | this structure must be in the first place, since it will be used | ||
386 | forcasting to the containing flow context | ||
387 | */ | ||
388 | struct work_struct flow_wq; | ||
389 | |||
390 | /* flow id */ | ||
391 | unsigned long flow_id; | ||
392 | |||
393 | /* additional input tables exists */ | ||
394 | unsigned long input_tables_flag; | ||
395 | |||
396 | /* additional output tables exists */ | ||
397 | unsigned long output_tables_flag; | ||
398 | |||
399 | /* data of the first input file */ | ||
400 | struct sep_lli_entry_t first_input_table; | ||
401 | |||
402 | /* data of the first output table */ | ||
403 | struct sep_lli_entry_t first_output_table; | ||
404 | |||
405 | /* last input table data */ | ||
406 | struct sep_lli_entry_t last_input_table; | ||
407 | |||
408 | /* last output table data */ | ||
409 | struct sep_lli_entry_t last_output_table; | ||
410 | |||
411 | /* first list of table */ | ||
412 | struct sep_lli_entry_t input_tables_in_process; | ||
413 | |||
414 | /* output table in process (in sep) */ | ||
415 | struct sep_lli_entry_t output_tables_in_process; | ||
416 | |||
417 | /* size of messages in bytes */ | ||
418 | unsigned long message_size_in_bytes; | ||
419 | |||
420 | /* message */ | ||
421 | unsigned char message[SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES]; | ||
422 | }; | ||
423 | |||
424 | |||
425 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h deleted file mode 100644 index 6008fe5eca09..000000000000 --- a/drivers/staging/sep/sep_driver_config.h +++ /dev/null | |||
@@ -1,225 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_config.h - Security Processor Driver configuration | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef __SEP_DRIVER_CONFIG_H__ | ||
33 | #define __SEP_DRIVER_CONFIG_H__ | ||
34 | |||
35 | |||
36 | /*-------------------------------------- | ||
37 | DRIVER CONFIGURATION FLAGS | ||
38 | -------------------------------------*/ | ||
39 | |||
40 | /* if flag is on , then the driver is running in polling and | ||
41 | not interrupt mode */ | ||
42 | #define SEP_DRIVER_POLLING_MODE 1 | ||
43 | |||
44 | /* flag which defines if the shared area address should be | ||
45 | reconfiged (send to SEP anew) during init of the driver */ | ||
46 | #define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0 | ||
47 | |||
48 | /* the mode for running on the ARM1172 Evaluation platform (flag is 1) */ | ||
49 | #define SEP_DRIVER_ARM_DEBUG_MODE 0 | ||
50 | |||
51 | /*------------------------------------------- | ||
52 | INTERNAL DATA CONFIGURATION | ||
53 | -------------------------------------------*/ | ||
54 | |||
55 | /* flag for the input array */ | ||
56 | #define SEP_DRIVER_IN_FLAG 0 | ||
57 | |||
58 | /* flag for output array */ | ||
59 | #define SEP_DRIVER_OUT_FLAG 1 | ||
60 | |||
61 | /* maximum number of entries in one LLI tables */ | ||
62 | #define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 8 | ||
63 | |||
64 | |||
65 | /*-------------------------------------------------------- | ||
66 | SHARED AREA memory total size is 36K | ||
67 | it is divided is following: | ||
68 | |||
69 | SHARED_MESSAGE_AREA 8K } | ||
70 | } | ||
71 | STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K) | ||
72 | } | ||
73 | DATA_POOL_AREA 12K } | ||
74 | |||
75 | SYNCHRONIC_DMA_TABLES_AREA 5K | ||
76 | |||
77 | FLOW_DMA_TABLES_AREA 4K | ||
78 | |||
79 | SYSTEM_MEMORY_AREA 3k | ||
80 | |||
81 | SYSTEM_MEMORY total size is 3k | ||
82 | it is divided as following: | ||
83 | |||
84 | TIME_MEMORY_AREA 8B | ||
85 | -----------------------------------------------------------*/ | ||
86 | |||
87 | |||
88 | |||
89 | /* | ||
90 | the maximum length of the message - the rest of the message shared | ||
91 | area will be dedicated to the dma lli tables | ||
92 | */ | ||
93 | #define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024) | ||
94 | |||
95 | /* the size of the message shared area in pages */ | ||
96 | #define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024) | ||
97 | |||
98 | /* the size of the data pool static area in pages */ | ||
99 | #define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024) | ||
100 | |||
101 | /* the size of the data pool shared area size in pages */ | ||
102 | #define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (12 * 1024) | ||
103 | |||
104 | /* the size of the message shared area in pages */ | ||
105 | #define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 5) | ||
106 | |||
107 | |||
108 | /* the size of the data pool shared area size in pages */ | ||
109 | #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4) | ||
110 | |||
111 | /* system data (time, caller id etc') pool */ | ||
112 | #define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES 100 | ||
113 | |||
114 | |||
115 | /* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and | ||
116 | DATA POOL areas. area must be module 4k */ | ||
117 | #define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 24) | ||
118 | |||
119 | |||
120 | /*----------------------------------------------- | ||
121 | offsets of the areas starting from the shared area start address | ||
122 | */ | ||
123 | |||
124 | /* message area offset */ | ||
125 | #define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0 | ||
126 | |||
127 | /* static pool area offset */ | ||
128 | #define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \ | ||
129 | (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES) | ||
130 | |||
131 | /* data pool area offset */ | ||
132 | #define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \ | ||
133 | (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \ | ||
134 | SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES) | ||
135 | |||
136 | /* synhronic dma tables area offset */ | ||
137 | #define SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES \ | ||
138 | (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \ | ||
139 | SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) | ||
140 | |||
141 | /* sep driver flow dma tables area offset */ | ||
142 | #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES \ | ||
143 | (SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_OFFSET_IN_BYTES + \ | ||
144 | SEP_DRIVER_SYNCHRONIC_DMA_TABLES_AREA_SIZE_IN_BYTES) | ||
145 | |||
146 | /* system memory offset in bytes */ | ||
147 | #define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \ | ||
148 | (SEP_DRIVER_FLOW_DMA_TABLES_AREA_OFFSET_IN_BYTES + \ | ||
149 | SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES) | ||
150 | |||
151 | /* offset of the time area */ | ||
152 | #define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \ | ||
153 | (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES) | ||
154 | |||
155 | |||
156 | |||
157 | /* start physical address of the SEP registers memory in HOST */ | ||
158 | #define SEP_IO_MEM_REGION_START_ADDRESS 0x80000000 | ||
159 | |||
160 | /* size of the SEP registers memory region in HOST (for now 100 registers) */ | ||
161 | #define SEP_IO_MEM_REGION_SIZE (2 * 0x100000) | ||
162 | |||
163 | /* define the number of IRQ for SEP interrupts */ | ||
164 | #define SEP_DIRVER_IRQ_NUM 1 | ||
165 | |||
166 | /* maximum number of add buffers */ | ||
167 | #define SEP_MAX_NUM_ADD_BUFFERS 100 | ||
168 | |||
169 | /* number of flows */ | ||
170 | #define SEP_DRIVER_NUM_FLOWS 4 | ||
171 | |||
172 | /* maximum number of entries in flow table */ | ||
173 | #define SEP_DRIVER_MAX_FLOW_NUM_ENTRIES_IN_TABLE 25 | ||
174 | |||
175 | /* offset of the num entries in the block length entry of the LLI */ | ||
176 | #define SEP_NUM_ENTRIES_OFFSET_IN_BITS 24 | ||
177 | |||
178 | /* offset of the interrupt flag in the block length entry of the LLI */ | ||
179 | #define SEP_INT_FLAG_OFFSET_IN_BITS 31 | ||
180 | |||
181 | /* mask for extracting data size from LLI */ | ||
182 | #define SEP_TABLE_DATA_SIZE_MASK 0xFFFFFF | ||
183 | |||
184 | /* mask for entries after being shifted left */ | ||
185 | #define SEP_NUM_ENTRIES_MASK 0x7F | ||
186 | |||
187 | /* default flow id */ | ||
188 | #define SEP_FREE_FLOW_ID 0xFFFFFFFF | ||
189 | |||
190 | /* temp flow id used during cretiong of new flow until receiving | ||
191 | real flow id from sep */ | ||
192 | #define SEP_TEMP_FLOW_ID (SEP_DRIVER_NUM_FLOWS + 1) | ||
193 | |||
194 | /* maximum add buffers message length in bytes */ | ||
195 | #define SEP_MAX_ADD_MESSAGE_LENGTH_IN_BYTES (7 * 4) | ||
196 | |||
197 | /* maximum number of concurrent virtual buffers */ | ||
198 | #define SEP_MAX_VIRT_BUFFERS_CONCURRENT 100 | ||
199 | |||
200 | /* the token that defines the start of time address */ | ||
201 | #define SEP_TIME_VAL_TOKEN 0x12345678 | ||
202 | |||
203 | /* DEBUG LEVEL MASKS */ | ||
204 | #define SEP_DEBUG_LEVEL_BASIC 0x1 | ||
205 | |||
206 | #define SEP_DEBUG_LEVEL_EXTENDED 0x4 | ||
207 | |||
208 | |||
209 | /* Debug helpers */ | ||
210 | |||
211 | #define dbg(fmt, args...) \ | ||
212 | do {\ | ||
213 | if (debug & SEP_DEBUG_LEVEL_BASIC) \ | ||
214 | printk(KERN_DEBUG fmt, ##args); \ | ||
215 | } while(0); | ||
216 | |||
217 | #define edbg(fmt, args...) \ | ||
218 | do { \ | ||
219 | if (debug & SEP_DEBUG_LEVEL_EXTENDED) \ | ||
220 | printk(KERN_DEBUG fmt, ##args); \ | ||
221 | } while(0); | ||
222 | |||
223 | |||
224 | |||
225 | #endif | ||
diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h deleted file mode 100644 index ea6abd8a14b4..000000000000 --- a/drivers/staging/sep/sep_driver_hw_defs.h +++ /dev/null | |||
@@ -1,232 +0,0 @@ | |||
1 | /* | ||
2 | * | ||
3 | * sep_driver_hw_defs.h - Security Processor Driver hardware definitions | ||
4 | * | ||
5 | * Copyright(c) 2009 Intel Corporation. All rights reserved. | ||
6 | * Copyright(c) 2009 Discretix. All rights reserved. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the Free | ||
10 | * Software Foundation; either version 2 of the License, or (at your option) | ||
11 | * any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
16 | * more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along with | ||
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | * | ||
22 | * CONTACTS: | ||
23 | * | ||
24 | * Mark Allyn mark.a.allyn@intel.com | ||
25 | * | ||
26 | * CHANGES: | ||
27 | * | ||
28 | * 2009.06.26 Initial publish | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | #ifndef SEP_DRIVER_HW_DEFS__H | ||
33 | #define SEP_DRIVER_HW_DEFS__H | ||
34 | |||
35 | /*--------------------------------------------------------------------------*/ | ||
36 | /* Abstract: HW Registers Defines. */ | ||
37 | /* */ | ||
38 | /* Note: This file was automatically created !!! */ | ||
39 | /* DO NOT EDIT THIS FILE !!! */ | ||
40 | /*--------------------------------------------------------------------------*/ | ||
41 | |||
42 | |||
43 | /* cf registers */ | ||
44 | #define HW_R0B_ADDR_0_REG_ADDR 0x0000UL | ||
45 | #define HW_R0B_ADDR_1_REG_ADDR 0x0004UL | ||
46 | #define HW_R0B_ADDR_2_REG_ADDR 0x0008UL | ||
47 | #define HW_R0B_ADDR_3_REG_ADDR 0x000cUL | ||
48 | #define HW_R0B_ADDR_4_REG_ADDR 0x0010UL | ||
49 | #define HW_R0B_ADDR_5_REG_ADDR 0x0014UL | ||
50 | #define HW_R0B_ADDR_6_REG_ADDR 0x0018UL | ||
51 | #define HW_R0B_ADDR_7_REG_ADDR 0x001cUL | ||
52 | #define HW_R0B_ADDR_8_REG_ADDR 0x0020UL | ||
53 | #define HW_R2B_ADDR_0_REG_ADDR 0x0080UL | ||
54 | #define HW_R2B_ADDR_1_REG_ADDR 0x0084UL | ||
55 | #define HW_R2B_ADDR_2_REG_ADDR 0x0088UL | ||
56 | #define HW_R2B_ADDR_3_REG_ADDR 0x008cUL | ||
57 | #define HW_R2B_ADDR_4_REG_ADDR 0x0090UL | ||
58 | #define HW_R2B_ADDR_5_REG_ADDR 0x0094UL | ||
59 | #define HW_R2B_ADDR_6_REG_ADDR 0x0098UL | ||
60 | #define HW_R2B_ADDR_7_REG_ADDR 0x009cUL | ||
61 | #define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL | ||
62 | #define HW_R3B_REG_ADDR 0x00C0UL | ||
63 | #define HW_R4B_REG_ADDR 0x0100UL | ||
64 | #define HW_CSA_ADDR_0_REG_ADDR 0x0140UL | ||
65 | #define HW_CSA_ADDR_1_REG_ADDR 0x0144UL | ||
66 | #define HW_CSA_ADDR_2_REG_ADDR 0x0148UL | ||
67 | #define HW_CSA_ADDR_3_REG_ADDR 0x014cUL | ||
68 | #define HW_CSA_ADDR_4_REG_ADDR 0x0150UL | ||
69 | #define HW_CSA_ADDR_5_REG_ADDR 0x0154UL | ||
70 | #define HW_CSA_ADDR_6_REG_ADDR 0x0158UL | ||
71 | #define HW_CSA_ADDR_7_REG_ADDR 0x015cUL | ||
72 | #define HW_CSA_ADDR_8_REG_ADDR 0x0160UL | ||
73 | #define HW_CSA_REG_ADDR 0x0140UL | ||
74 | #define HW_SINB_REG_ADDR 0x0180UL | ||
75 | #define HW_SOUTB_REG_ADDR 0x0184UL | ||
76 | #define HW_PKI_CONTROL_REG_ADDR 0x01C0UL | ||
77 | #define HW_PKI_STATUS_REG_ADDR 0x01C4UL | ||
78 | #define HW_PKI_BUSY_REG_ADDR 0x01C8UL | ||
79 | #define HW_PKI_A_1025_REG_ADDR 0x01CCUL | ||
80 | #define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL | ||
81 | #define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL | ||
82 | #define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL | ||
83 | #define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL | ||
84 | #define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL | ||
85 | #define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL | ||
86 | #define HW_PKI_CLR_REG_ADDR 0x01E8UL | ||
87 | #define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL | ||
88 | #define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL | ||
89 | #define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL | ||
90 | #define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL | ||
91 | #define HW_DES_KEY_0_REG_ADDR 0x0208UL | ||
92 | #define HW_DES_KEY_1_REG_ADDR 0x020CUL | ||
93 | #define HW_DES_KEY_2_REG_ADDR 0x0210UL | ||
94 | #define HW_DES_KEY_3_REG_ADDR 0x0214UL | ||
95 | #define HW_DES_KEY_4_REG_ADDR 0x0218UL | ||
96 | #define HW_DES_KEY_5_REG_ADDR 0x021CUL | ||
97 | #define HW_DES_CONTROL_0_REG_ADDR 0x0220UL | ||
98 | #define HW_DES_CONTROL_1_REG_ADDR 0x0224UL | ||
99 | #define HW_DES_IV_0_REG_ADDR 0x0228UL | ||
100 | #define HW_DES_IV_1_REG_ADDR 0x022CUL | ||
101 | #define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL | ||
102 | #define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL | ||
103 | #define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL | ||
104 | #define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL | ||
105 | #define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL | ||
106 | #define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL | ||
107 | #define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL | ||
108 | #define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL | ||
109 | #define HW_AES_KEY_0_REG_ADDR 0x0400UL | ||
110 | #define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL | ||
111 | #define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL | ||
112 | #define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL | ||
113 | #define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL | ||
114 | #define HW_AES_IV_0_REG_ADDR 0x0440UL | ||
115 | #define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL | ||
116 | #define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL | ||
117 | #define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL | ||
118 | #define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL | ||
119 | #define HW_AES_CTR1_REG_ADDR 0x0460UL | ||
120 | #define HW_AES_SK_REG_ADDR 0x0478UL | ||
121 | #define HW_AES_MAC_OK_REG_ADDR 0x0480UL | ||
122 | #define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL | ||
123 | #define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL | ||
124 | #define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL | ||
125 | #define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL | ||
126 | #define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL | ||
127 | #define HW_AES_CONTROL_REG_ADDR 0x04C0UL | ||
128 | #define HW_HASH_H0_REG_ADDR 0x0640UL | ||
129 | #define HW_HASH_H1_REG_ADDR 0x0644UL | ||
130 | #define HW_HASH_H2_REG_ADDR 0x0648UL | ||
131 | #define HW_HASH_H3_REG_ADDR 0x064CUL | ||
132 | #define HW_HASH_H4_REG_ADDR 0x0650UL | ||
133 | #define HW_HASH_H5_REG_ADDR 0x0654UL | ||
134 | #define HW_HASH_H6_REG_ADDR 0x0658UL | ||
135 | #define HW_HASH_H7_REG_ADDR 0x065CUL | ||
136 | #define HW_HASH_H8_REG_ADDR 0x0660UL | ||
137 | #define HW_HASH_H9_REG_ADDR 0x0664UL | ||
138 | #define HW_HASH_H10_REG_ADDR 0x0668UL | ||
139 | #define HW_HASH_H11_REG_ADDR 0x066CUL | ||
140 | #define HW_HASH_H12_REG_ADDR 0x0670UL | ||
141 | #define HW_HASH_H13_REG_ADDR 0x0674UL | ||
142 | #define HW_HASH_H14_REG_ADDR 0x0678UL | ||
143 | #define HW_HASH_H15_REG_ADDR 0x067CUL | ||
144 | #define HW_HASH_CONTROL_REG_ADDR 0x07C0UL | ||
145 | #define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL | ||
146 | #define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL | ||
147 | #define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL | ||
148 | #define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL | ||
149 | #define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL | ||
150 | #define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL | ||
151 | #define HW_HASH_PARAM_REG_ADDR 0x07DCUL | ||
152 | #define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL | ||
153 | #define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL | ||
154 | #define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL | ||
155 | #define HW_HASH_DATA_REG_ADDR 0x07ECUL | ||
156 | #define HW_DRNG_CONTROL_REG_ADDR 0x0800UL | ||
157 | #define HW_DRNG_VALID_REG_ADDR 0x0804UL | ||
158 | #define HW_DRNG_DATA_REG_ADDR 0x0808UL | ||
159 | #define HW_RND_SRC_EN_REG_ADDR 0x080CUL | ||
160 | #define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL | ||
161 | #define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL | ||
162 | #define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL | ||
163 | #define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL | ||
164 | #define HW_CLK_STATUS_REG_ADDR 0x0824UL | ||
165 | #define HW_CLK_ENABLE_REG_ADDR 0x0828UL | ||
166 | #define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL | ||
167 | #define HW_RND_SRC_CTL_REG_ADDR 0x0858UL | ||
168 | #define HW_CRYPTO_CTL_REG_ADDR 0x0900UL | ||
169 | #define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL | ||
170 | #define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL | ||
171 | #define HW_AES_BUSY_REG_ADDR 0x0914UL | ||
172 | #define HW_DES_BUSY_REG_ADDR 0x0918UL | ||
173 | #define HW_HASH_BUSY_REG_ADDR 0x091CUL | ||
174 | #define HW_CONTENT_REG_ADDR 0x0924UL | ||
175 | #define HW_VERSION_REG_ADDR 0x0928UL | ||
176 | #define HW_CONTEXT_ID_REG_ADDR 0x0930UL | ||
177 | #define HW_DIN_BUFFER_REG_ADDR 0x0C00UL | ||
178 | #define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL | ||
179 | #define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL | ||
180 | #define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL | ||
181 | #define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL | ||
182 | #define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL | ||
183 | #define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL | ||
184 | #define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL | ||
185 | #define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL | ||
186 | #define HW_OLD_DATA_REG_ADDR 0x0C48UL | ||
187 | #define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL | ||
188 | #define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL | ||
189 | #define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL | ||
190 | #define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL | ||
191 | #define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL | ||
192 | #define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL | ||
193 | #define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL | ||
194 | #define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL | ||
195 | #define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL | ||
196 | #define HW_READ_ALIGN_REG_ADDR 0x0D3CUL | ||
197 | #define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL | ||
198 | #define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL | ||
199 | #define HW_AHB_SINGLE_REG_ADDR 0x0E00UL | ||
200 | #define HW_SRAM_DATA_REG_ADDR 0x0F00UL | ||
201 | #define HW_SRAM_ADDR_REG_ADDR 0x0F04UL | ||
202 | #define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL | ||
203 | #define HW_HOST_IRR_REG_ADDR 0x0A00UL | ||
204 | #define HW_HOST_IMR_REG_ADDR 0x0A04UL | ||
205 | #define HW_HOST_ICR_REG_ADDR 0x0A08UL | ||
206 | #define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL | ||
207 | #define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL | ||
208 | #define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL | ||
209 | #define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL | ||
210 | #define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL | ||
211 | #define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL | ||
212 | #define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL | ||
213 | #define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL | ||
214 | #define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL | ||
215 | #define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL | ||
216 | #define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL | ||
217 | #define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL | ||
218 | #define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL | ||
219 | #define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL | ||
220 | #define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL | ||
221 | #define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL | ||
222 | #define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL | ||
223 | #define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL | ||
224 | #define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL | ||
225 | #define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL | ||
226 | #define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL | ||
227 | #define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL | ||
228 | #define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL | ||
229 | #define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL | ||
230 | #define HW_CC_SRAM_BASE_ADDRESS 0x5800UL | ||
231 | |||
232 | #endif /* ifndef HW_DEFS */ | ||
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index d0c5c97eda3e..44a7fbe7eccd 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/kthread.h> | 27 | #include <linux/kthread.h> |
28 | #include <linux/log2.h> | 28 | #include <linux/log2.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/smp_lock.h> | ||
30 | 31 | ||
31 | /**** Helper functions used for Div, Remainder operation on u64 ****/ | 32 | /**** Helper functions used for Div, Remainder operation on u64 ****/ |
32 | 33 | ||
@@ -113,7 +114,6 @@ u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type) | |||
113 | 114 | ||
114 | #define GLOB_SBD_NAME "nd" | 115 | #define GLOB_SBD_NAME "nd" |
115 | #define GLOB_SBD_IRQ_NUM (29) | 116 | #define GLOB_SBD_IRQ_NUM (29) |
116 | #define GLOB_VERSION "driver version 20091110" | ||
117 | 117 | ||
118 | #define GLOB_SBD_IOCTL_GC (0x7701) | 118 | #define GLOB_SBD_IOCTL_GC (0x7701) |
119 | #define GLOB_SBD_IOCTL_WL (0x7702) | 119 | #define GLOB_SBD_IOCTL_WL (0x7702) |
@@ -272,13 +272,6 @@ static int get_res_blk_num_os(void) | |||
272 | return res_blks; | 272 | return res_blks; |
273 | } | 273 | } |
274 | 274 | ||
275 | static void SBD_prepare_flush(struct request_queue *q, struct request *rq) | ||
276 | { | ||
277 | rq->cmd_type = REQ_TYPE_LINUX_BLOCK; | ||
278 | /* rq->timeout = 5 * HZ; */ | ||
279 | rq->cmd[0] = REQ_LB_OP_FLUSH; | ||
280 | } | ||
281 | |||
282 | /* Transfer a full request. */ | 275 | /* Transfer a full request. */ |
283 | static int do_transfer(struct spectra_nand_dev *tr, struct request *req) | 276 | static int do_transfer(struct spectra_nand_dev *tr, struct request *req) |
284 | { | 277 | { |
@@ -296,8 +289,7 @@ static int do_transfer(struct spectra_nand_dev *tr, struct request *req) | |||
296 | IdentifyDeviceData.PagesPerBlock * | 289 | IdentifyDeviceData.PagesPerBlock * |
297 | res_blks_os; | 290 | res_blks_os; |
298 | 291 | ||
299 | if (req->cmd_type == REQ_TYPE_LINUX_BLOCK && | 292 | if (req->cmd_type & REQ_FLUSH) { |
300 | req->cmd[0] == REQ_LB_OP_FLUSH) { | ||
301 | if (force_flush_cache()) /* Fail to flush cache */ | 293 | if (force_flush_cache()) /* Fail to flush cache */ |
302 | return -EIO; | 294 | return -EIO; |
303 | else | 295 | else |
@@ -597,11 +589,23 @@ int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode, | |||
597 | return -ENOTTY; | 589 | return -ENOTTY; |
598 | } | 590 | } |
599 | 591 | ||
592 | int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode, | ||
593 | unsigned int cmd, unsigned long arg) | ||
594 | { | ||
595 | int ret; | ||
596 | |||
597 | lock_kernel(); | ||
598 | ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg); | ||
599 | unlock_kernel(); | ||
600 | |||
601 | return ret; | ||
602 | } | ||
603 | |||
600 | static struct block_device_operations GLOB_SBD_ops = { | 604 | static struct block_device_operations GLOB_SBD_ops = { |
601 | .owner = THIS_MODULE, | 605 | .owner = THIS_MODULE, |
602 | .open = GLOB_SBD_open, | 606 | .open = GLOB_SBD_open, |
603 | .release = GLOB_SBD_release, | 607 | .release = GLOB_SBD_release, |
604 | .locked_ioctl = GLOB_SBD_ioctl, | 608 | .ioctl = GLOB_SBD_unlocked_ioctl, |
605 | .getgeo = GLOB_SBD_getgeo, | 609 | .getgeo = GLOB_SBD_getgeo, |
606 | }; | 610 | }; |
607 | 611 | ||
@@ -650,8 +654,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which) | |||
650 | /* Here we force report 512 byte hardware sector size to Kernel */ | 654 | /* Here we force report 512 byte hardware sector size to Kernel */ |
651 | blk_queue_logical_block_size(dev->queue, 512); | 655 | blk_queue_logical_block_size(dev->queue, 512); |
652 | 656 | ||
653 | blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH, | 657 | blk_queue_ordered(dev->queue, QUEUE_ORDERED_DRAIN_FLUSH); |
654 | SBD_prepare_flush); | ||
655 | 658 | ||
656 | dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd"); | 659 | dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd"); |
657 | if (IS_ERR(dev->thread)) { | 660 | if (IS_ERR(dev->thread)) { |
diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c index 134aa5166a8d..9b5218b6ada8 100644 --- a/drivers/staging/spectra/flash.c +++ b/drivers/staging/spectra/flash.c | |||
@@ -61,7 +61,6 @@ static void FTL_Cache_Read_Page(u8 *pData, u64 dwPageAddr, | |||
61 | static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr, | 61 | static void FTL_Cache_Write_Page(u8 *pData, u64 dwPageAddr, |
62 | u8 cache_blk, u16 flag); | 62 | u8 cache_blk, u16 flag); |
63 | static int FTL_Cache_Write(void); | 63 | static int FTL_Cache_Write(void); |
64 | static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr); | ||
65 | static void FTL_Calculate_LRU(void); | 64 | static void FTL_Calculate_LRU(void); |
66 | static u32 FTL_Get_Block_Index(u32 wBlockNum); | 65 | static u32 FTL_Get_Block_Index(u32 wBlockNum); |
67 | 66 | ||
@@ -86,8 +85,6 @@ static u32 FTL_Replace_MWBlock(void); | |||
86 | static int FTL_Replace_Block(u64 blk_addr); | 85 | static int FTL_Replace_Block(u64 blk_addr); |
87 | static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX); | 86 | static int FTL_Adjust_Relative_Erase_Count(u32 Index_of_MAX); |
88 | 87 | ||
89 | static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, u64 blk_addr); | ||
90 | |||
91 | struct device_info_tag DeviceInfo; | 88 | struct device_info_tag DeviceInfo; |
92 | struct flash_cache_tag Cache; | 89 | struct flash_cache_tag Cache; |
93 | static struct spectra_l2_cache_info cache_l2; | 90 | static struct spectra_l2_cache_info cache_l2; |
@@ -775,7 +772,7 @@ static void dump_cache_l2_table(void) | |||
775 | { | 772 | { |
776 | struct list_head *p; | 773 | struct list_head *p; |
777 | struct spectra_l2_cache_list *pnd; | 774 | struct spectra_l2_cache_list *pnd; |
778 | int n, i; | 775 | int n; |
779 | 776 | ||
780 | n = 0; | 777 | n = 0; |
781 | list_for_each(p, &cache_l2.table.list) { | 778 | list_for_each(p, &cache_l2.table.list) { |
@@ -1538,79 +1535,6 @@ static int FTL_Cache_Write_All(u8 *pData, u64 blk_addr) | |||
1538 | } | 1535 | } |
1539 | 1536 | ||
1540 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 1537 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
1541 | * Function: FTL_Cache_Update_Block | ||
1542 | * Inputs: pointer to buffer,page address,block address | ||
1543 | * Outputs: PASS=0 / FAIL=1 | ||
1544 | * Description: It updates the cache | ||
1545 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
1546 | static int FTL_Cache_Update_Block(u8 *pData, | ||
1547 | u64 old_page_addr, u64 blk_addr) | ||
1548 | { | ||
1549 | int i, j; | ||
1550 | u8 *buf = pData; | ||
1551 | int wResult = PASS; | ||
1552 | int wFoundInCache; | ||
1553 | u64 page_addr; | ||
1554 | u64 addr; | ||
1555 | u64 old_blk_addr; | ||
1556 | u16 page_offset; | ||
1557 | |||
1558 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
1559 | __FILE__, __LINE__, __func__); | ||
1560 | |||
1561 | old_blk_addr = (u64)(old_page_addr >> | ||
1562 | DeviceInfo.nBitsInBlockDataSize) * DeviceInfo.wBlockDataSize; | ||
1563 | page_offset = (u16)(GLOB_u64_Remainder(old_page_addr, 2) >> | ||
1564 | DeviceInfo.nBitsInPageDataSize); | ||
1565 | |||
1566 | for (i = 0; i < DeviceInfo.wPagesPerBlock; i += Cache.pages_per_item) { | ||
1567 | page_addr = old_blk_addr + i * DeviceInfo.wPageDataSize; | ||
1568 | if (i != page_offset) { | ||
1569 | wFoundInCache = FAIL; | ||
1570 | for (j = 0; j < CACHE_ITEM_NUM; j++) { | ||
1571 | addr = Cache.array[j].address; | ||
1572 | addr = FTL_Get_Physical_Block_Addr(addr) + | ||
1573 | GLOB_u64_Remainder(addr, 2); | ||
1574 | if ((addr >= page_addr) && addr < | ||
1575 | (page_addr + Cache.cache_item_size)) { | ||
1576 | wFoundInCache = PASS; | ||
1577 | buf = Cache.array[j].buf; | ||
1578 | Cache.array[j].changed = SET; | ||
1579 | #if CMD_DMA | ||
1580 | #if RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE | ||
1581 | int_cache[ftl_cmd_cnt].item = j; | ||
1582 | int_cache[ftl_cmd_cnt].cache.address = | ||
1583 | Cache.array[j].address; | ||
1584 | int_cache[ftl_cmd_cnt].cache.changed = | ||
1585 | Cache.array[j].changed; | ||
1586 | #endif | ||
1587 | #endif | ||
1588 | break; | ||
1589 | } | ||
1590 | } | ||
1591 | if (FAIL == wFoundInCache) { | ||
1592 | if (ERR == FTL_Cache_Read_All(g_pTempBuf, | ||
1593 | page_addr)) { | ||
1594 | wResult = FAIL; | ||
1595 | break; | ||
1596 | } | ||
1597 | buf = g_pTempBuf; | ||
1598 | } | ||
1599 | } else { | ||
1600 | buf = pData; | ||
1601 | } | ||
1602 | |||
1603 | if (FAIL == FTL_Cache_Write_All(buf, | ||
1604 | blk_addr + (page_addr - old_blk_addr))) { | ||
1605 | wResult = FAIL; | ||
1606 | break; | ||
1607 | } | ||
1608 | } | ||
1609 | |||
1610 | return wResult; | ||
1611 | } | ||
1612 | |||
1613 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
1614 | * Function: FTL_Copy_Block | 1538 | * Function: FTL_Copy_Block |
1615 | * Inputs: source block address | 1539 | * Inputs: source block address |
1616 | * Destination block address | 1540 | * Destination block address |
@@ -1698,7 +1622,7 @@ static int get_l2_cache_blks(void) | |||
1698 | static int erase_l2_cache_blocks(void) | 1622 | static int erase_l2_cache_blocks(void) |
1699 | { | 1623 | { |
1700 | int i, ret = PASS; | 1624 | int i, ret = PASS; |
1701 | u32 pblk, lblk; | 1625 | u32 pblk, lblk = BAD_BLOCK; |
1702 | u64 addr; | 1626 | u64 addr; |
1703 | u32 *pbt = (u32 *)g_pBlockTable; | 1627 | u32 *pbt = (u32 *)g_pBlockTable; |
1704 | 1628 | ||
@@ -2004,87 +1928,6 @@ static int search_l2_cache(u8 *buf, u64 logical_addr) | |||
2004 | return ret; | 1928 | return ret; |
2005 | } | 1929 | } |
2006 | 1930 | ||
2007 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
2008 | * Function: FTL_Cache_Write_Back | ||
2009 | * Inputs: pointer to data cached in sys memory | ||
2010 | * address of free block in flash | ||
2011 | * Outputs: PASS=0 / FAIL=1 | ||
2012 | * Description: writes all the pages of Cache Block to flash | ||
2013 | * | ||
2014 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
2015 | static int FTL_Cache_Write_Back(u8 *pData, u64 blk_addr) | ||
2016 | { | ||
2017 | int i, j, iErase; | ||
2018 | u64 old_page_addr, addr, phy_addr; | ||
2019 | u32 *pbt = (u32 *)g_pBlockTable; | ||
2020 | u32 lba; | ||
2021 | |||
2022 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
2023 | __FILE__, __LINE__, __func__); | ||
2024 | |||
2025 | old_page_addr = FTL_Get_Physical_Block_Addr(blk_addr) + | ||
2026 | GLOB_u64_Remainder(blk_addr, 2); | ||
2027 | |||
2028 | iErase = (FAIL == FTL_Replace_Block(blk_addr)) ? PASS : FAIL; | ||
2029 | |||
2030 | pbt[BLK_FROM_ADDR(blk_addr)] &= (~SPARE_BLOCK); | ||
2031 | |||
2032 | #if CMD_DMA | ||
2033 | p_BTableChangesDelta = (struct BTableChangesDelta *)g_pBTDelta_Free; | ||
2034 | g_pBTDelta_Free += sizeof(struct BTableChangesDelta); | ||
2035 | |||
2036 | p_BTableChangesDelta->ftl_cmd_cnt = ftl_cmd_cnt; | ||
2037 | p_BTableChangesDelta->BT_Index = (u32)(blk_addr >> | ||
2038 | DeviceInfo.nBitsInBlockDataSize); | ||
2039 | p_BTableChangesDelta->BT_Entry_Value = | ||
2040 | pbt[(u32)(blk_addr >> DeviceInfo.nBitsInBlockDataSize)]; | ||
2041 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
2042 | #endif | ||
2043 | |||
2044 | if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) { | ||
2045 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
2046 | FTL_Write_IN_Progress_Block_Table_Page(); | ||
2047 | } | ||
2048 | |||
2049 | for (i = 0; i < RETRY_TIMES; i++) { | ||
2050 | if (PASS == iErase) { | ||
2051 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
2052 | if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) { | ||
2053 | lba = BLK_FROM_ADDR(blk_addr); | ||
2054 | MARK_BLOCK_AS_BAD(pbt[lba]); | ||
2055 | i = RETRY_TIMES; | ||
2056 | break; | ||
2057 | } | ||
2058 | } | ||
2059 | |||
2060 | for (j = 0; j < CACHE_ITEM_NUM; j++) { | ||
2061 | addr = Cache.array[j].address; | ||
2062 | if ((addr <= blk_addr) && | ||
2063 | ((addr + Cache.cache_item_size) > blk_addr)) | ||
2064 | cache_block_to_write = j; | ||
2065 | } | ||
2066 | |||
2067 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
2068 | if (PASS == FTL_Cache_Update_Block(pData, | ||
2069 | old_page_addr, phy_addr)) { | ||
2070 | cache_block_to_write = UNHIT_CACHE_ITEM; | ||
2071 | break; | ||
2072 | } else { | ||
2073 | iErase = PASS; | ||
2074 | } | ||
2075 | } | ||
2076 | |||
2077 | if (i >= RETRY_TIMES) { | ||
2078 | if (ERR == FTL_Flash_Error_Handle(pData, | ||
2079 | old_page_addr, blk_addr)) | ||
2080 | return ERR; | ||
2081 | else | ||
2082 | return FAIL; | ||
2083 | } | ||
2084 | |||
2085 | return PASS; | ||
2086 | } | ||
2087 | |||
2088 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 1931 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
2089 | * Function: FTL_Cache_Write_Page | 1932 | * Function: FTL_Cache_Write_Page |
2090 | * Inputs: Pointer to buffer, page address, cache block number | 1933 | * Inputs: Pointer to buffer, page address, cache block number |
@@ -2370,159 +2213,6 @@ static int FTL_Write_Block_Table(int wForce) | |||
2370 | return 1; | 2213 | return 1; |
2371 | } | 2214 | } |
2372 | 2215 | ||
2373 | /****************************************************************** | ||
2374 | * Function: GLOB_FTL_Flash_Format | ||
2375 | * Inputs: none | ||
2376 | * Outputs: PASS | ||
2377 | * Description: The block table stores bad block info, including MDF+ | ||
2378 | * blocks gone bad over the ages. Therefore, if we have a | ||
2379 | * block table in place, then use it to scan for bad blocks | ||
2380 | * If not, then scan for MDF. | ||
2381 | * Now, a block table will only be found if spectra was already | ||
2382 | * being used. For a fresh flash, we'll go thru scanning for | ||
2383 | * MDF. If spectra was being used, then there is a chance that | ||
2384 | * the MDF has been corrupted. Spectra avoids writing to the | ||
2385 | * first 2 bytes of the spare area to all pages in a block. This | ||
2386 | * covers all known flash devices. However, since flash | ||
2387 | * manufacturers have no standard of where the MDF is stored, | ||
2388 | * this cannot guarantee that the MDF is protected for future | ||
2389 | * devices too. The initial scanning for the block table assures | ||
2390 | * this. It is ok even if the block table is outdated, as all | ||
2391 | * we're looking for are bad block markers. | ||
2392 | * Use this when mounting a file system or starting a | ||
2393 | * new flash. | ||
2394 | * | ||
2395 | *********************************************************************/ | ||
2396 | static int FTL_Format_Flash(u8 valid_block_table) | ||
2397 | { | ||
2398 | u32 i, j; | ||
2399 | u32 *pbt = (u32 *)g_pBlockTable; | ||
2400 | u32 tempNode; | ||
2401 | int ret; | ||
2402 | |||
2403 | #if CMD_DMA | ||
2404 | u32 *pbtStartingCopy = (u32 *)g_pBTStartingCopy; | ||
2405 | if (ftl_cmd_cnt) | ||
2406 | return FAIL; | ||
2407 | #endif | ||
2408 | |||
2409 | if (FAIL == FTL_Check_Block_Table(FAIL)) | ||
2410 | valid_block_table = 0; | ||
2411 | |||
2412 | if (valid_block_table) { | ||
2413 | u8 switched = 1; | ||
2414 | u32 block, k; | ||
2415 | |||
2416 | k = DeviceInfo.wSpectraStartBlock; | ||
2417 | while (switched && (k < DeviceInfo.wSpectraEndBlock)) { | ||
2418 | switched = 0; | ||
2419 | k++; | ||
2420 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2421 | j <= DeviceInfo.wSpectraEndBlock; | ||
2422 | j++, i++) { | ||
2423 | block = (pbt[i] & ~BAD_BLOCK) - | ||
2424 | DeviceInfo.wSpectraStartBlock; | ||
2425 | if (block != i) { | ||
2426 | switched = 1; | ||
2427 | tempNode = pbt[i]; | ||
2428 | pbt[i] = pbt[block]; | ||
2429 | pbt[block] = tempNode; | ||
2430 | } | ||
2431 | } | ||
2432 | } | ||
2433 | if ((k == DeviceInfo.wSpectraEndBlock) && switched) | ||
2434 | valid_block_table = 0; | ||
2435 | } | ||
2436 | |||
2437 | if (!valid_block_table) { | ||
2438 | memset(g_pBlockTable, 0, | ||
2439 | DeviceInfo.wDataBlockNum * sizeof(u32)); | ||
2440 | memset(g_pWearCounter, 0, | ||
2441 | DeviceInfo.wDataBlockNum * sizeof(u8)); | ||
2442 | if (DeviceInfo.MLCDevice) | ||
2443 | memset(g_pReadCounter, 0, | ||
2444 | DeviceInfo.wDataBlockNum * sizeof(u16)); | ||
2445 | #if CMD_DMA | ||
2446 | memset(g_pBTStartingCopy, 0, | ||
2447 | DeviceInfo.wDataBlockNum * sizeof(u32)); | ||
2448 | memset(g_pWearCounterCopy, 0, | ||
2449 | DeviceInfo.wDataBlockNum * sizeof(u8)); | ||
2450 | if (DeviceInfo.MLCDevice) | ||
2451 | memset(g_pReadCounterCopy, 0, | ||
2452 | DeviceInfo.wDataBlockNum * sizeof(u16)); | ||
2453 | #endif | ||
2454 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2455 | j <= DeviceInfo.wSpectraEndBlock; | ||
2456 | j++, i++) { | ||
2457 | if (GLOB_LLD_Get_Bad_Block((u32)j)) | ||
2458 | pbt[i] = (u32)(BAD_BLOCK | j); | ||
2459 | } | ||
2460 | } | ||
2461 | |||
2462 | nand_dbg_print(NAND_DBG_WARN, "Erasing all blocks in the NAND\n"); | ||
2463 | |||
2464 | for (j = DeviceInfo.wSpectraStartBlock, i = 0; | ||
2465 | j <= DeviceInfo.wSpectraEndBlock; | ||
2466 | j++, i++) { | ||
2467 | if ((pbt[i] & BAD_BLOCK) != BAD_BLOCK) { | ||
2468 | ret = GLOB_LLD_Erase_Block(j); | ||
2469 | if (FAIL == ret) { | ||
2470 | pbt[i] = (u32)(j); | ||
2471 | MARK_BLOCK_AS_BAD(pbt[i]); | ||
2472 | nand_dbg_print(NAND_DBG_WARN, | ||
2473 | "NAND Program fail in %s, Line %d, " | ||
2474 | "Function: %s, new Bad Block %d generated!\n", | ||
2475 | __FILE__, __LINE__, __func__, (int)j); | ||
2476 | } else { | ||
2477 | pbt[i] = (u32)(SPARE_BLOCK | j); | ||
2478 | } | ||
2479 | } | ||
2480 | #if CMD_DMA | ||
2481 | pbtStartingCopy[i] = pbt[i]; | ||
2482 | #endif | ||
2483 | } | ||
2484 | |||
2485 | g_wBlockTableOffset = 0; | ||
2486 | for (i = 0; (i <= (DeviceInfo.wSpectraEndBlock - | ||
2487 | DeviceInfo.wSpectraStartBlock)) | ||
2488 | && ((pbt[i] & BAD_BLOCK) == BAD_BLOCK); i++) | ||
2489 | ; | ||
2490 | if (i > (DeviceInfo.wSpectraEndBlock - DeviceInfo.wSpectraStartBlock)) { | ||
2491 | printk(KERN_ERR "All blocks bad!\n"); | ||
2492 | return FAIL; | ||
2493 | } else { | ||
2494 | g_wBlockTableIndex = pbt[i] & ~BAD_BLOCK; | ||
2495 | if (i != BLOCK_TABLE_INDEX) { | ||
2496 | tempNode = pbt[i]; | ||
2497 | pbt[i] = pbt[BLOCK_TABLE_INDEX]; | ||
2498 | pbt[BLOCK_TABLE_INDEX] = tempNode; | ||
2499 | } | ||
2500 | } | ||
2501 | pbt[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK); | ||
2502 | |||
2503 | #if CMD_DMA | ||
2504 | pbtStartingCopy[BLOCK_TABLE_INDEX] &= (~SPARE_BLOCK); | ||
2505 | #endif | ||
2506 | |||
2507 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
2508 | memset(g_pBTBlocks, 0xFF, | ||
2509 | (1 + LAST_BT_ID - FIRST_BT_ID) * sizeof(u32)); | ||
2510 | g_pBTBlocks[FIRST_BT_ID-FIRST_BT_ID] = g_wBlockTableIndex; | ||
2511 | FTL_Write_Block_Table(FAIL); | ||
2512 | |||
2513 | for (i = 0; i < CACHE_ITEM_NUM; i++) { | ||
2514 | Cache.array[i].address = NAND_CACHE_INIT_ADDR; | ||
2515 | Cache.array[i].use_cnt = 0; | ||
2516 | Cache.array[i].changed = CLEAR; | ||
2517 | } | ||
2518 | |||
2519 | #if (RESTORE_CACHE_ON_CDMA_CHAIN_FAILURE && CMD_DMA) | ||
2520 | memcpy((void *)&cache_start_copy, (void *)&Cache, | ||
2521 | sizeof(struct flash_cache_tag)); | ||
2522 | #endif | ||
2523 | return PASS; | ||
2524 | } | ||
2525 | |||
2526 | static int force_format_nand(void) | 2216 | static int force_format_nand(void) |
2527 | { | 2217 | { |
2528 | u32 i; | 2218 | u32 i; |
@@ -3031,112 +2721,6 @@ static int FTL_Read_Block_Table(void) | |||
3031 | return wResult; | 2721 | return wResult; |
3032 | } | 2722 | } |
3033 | 2723 | ||
3034 | |||
3035 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | ||
3036 | * Function: FTL_Flash_Error_Handle | ||
3037 | * Inputs: Pointer to data | ||
3038 | * Page address | ||
3039 | * Block address | ||
3040 | * Outputs: PASS=0 / FAIL=1 | ||
3041 | * Description: It handles any error occured during Spectra operation | ||
3042 | *&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/ | ||
3043 | static int FTL_Flash_Error_Handle(u8 *pData, u64 old_page_addr, | ||
3044 | u64 blk_addr) | ||
3045 | { | ||
3046 | u32 i; | ||
3047 | int j; | ||
3048 | u32 tmp_node, blk_node = BLK_FROM_ADDR(blk_addr); | ||
3049 | u64 phy_addr; | ||
3050 | int wErase = FAIL; | ||
3051 | int wResult = FAIL; | ||
3052 | u32 *pbt = (u32 *)g_pBlockTable; | ||
3053 | |||
3054 | nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", | ||
3055 | __FILE__, __LINE__, __func__); | ||
3056 | |||
3057 | if (ERR == GLOB_FTL_Garbage_Collection()) | ||
3058 | return ERR; | ||
3059 | |||
3060 | do { | ||
3061 | for (i = DeviceInfo.wSpectraEndBlock - | ||
3062 | DeviceInfo.wSpectraStartBlock; | ||
3063 | i > 0; i--) { | ||
3064 | if (IS_SPARE_BLOCK(i)) { | ||
3065 | tmp_node = (u32)(BAD_BLOCK | | ||
3066 | pbt[blk_node]); | ||
3067 | pbt[blk_node] = (u32)(pbt[i] & | ||
3068 | (~SPARE_BLOCK)); | ||
3069 | pbt[i] = tmp_node; | ||
3070 | #if CMD_DMA | ||
3071 | p_BTableChangesDelta = | ||
3072 | (struct BTableChangesDelta *) | ||
3073 | g_pBTDelta_Free; | ||
3074 | g_pBTDelta_Free += | ||
3075 | sizeof(struct BTableChangesDelta); | ||
3076 | |||
3077 | p_BTableChangesDelta->ftl_cmd_cnt = | ||
3078 | ftl_cmd_cnt; | ||
3079 | p_BTableChangesDelta->BT_Index = | ||
3080 | blk_node; | ||
3081 | p_BTableChangesDelta->BT_Entry_Value = | ||
3082 | pbt[blk_node]; | ||
3083 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
3084 | |||
3085 | p_BTableChangesDelta = | ||
3086 | (struct BTableChangesDelta *) | ||
3087 | g_pBTDelta_Free; | ||
3088 | g_pBTDelta_Free += | ||
3089 | sizeof(struct BTableChangesDelta); | ||
3090 | |||
3091 | p_BTableChangesDelta->ftl_cmd_cnt = | ||
3092 | ftl_cmd_cnt; | ||
3093 | p_BTableChangesDelta->BT_Index = i; | ||
3094 | p_BTableChangesDelta->BT_Entry_Value = pbt[i]; | ||
3095 | p_BTableChangesDelta->ValidFields = 0x0C; | ||
3096 | #endif | ||
3097 | wResult = PASS; | ||
3098 | break; | ||
3099 | } | ||
3100 | } | ||
3101 | |||
3102 | if (FAIL == wResult) { | ||
3103 | if (FAIL == GLOB_FTL_Garbage_Collection()) | ||
3104 | break; | ||
3105 | else | ||
3106 | continue; | ||
3107 | } | ||
3108 | |||
3109 | if (IN_PROGRESS_BLOCK_TABLE != g_cBlockTableStatus) { | ||
3110 | g_cBlockTableStatus = IN_PROGRESS_BLOCK_TABLE; | ||
3111 | FTL_Write_IN_Progress_Block_Table_Page(); | ||
3112 | } | ||
3113 | |||
3114 | phy_addr = FTL_Get_Physical_Block_Addr(blk_addr); | ||
3115 | |||
3116 | for (j = 0; j < RETRY_TIMES; j++) { | ||
3117 | if (PASS == wErase) { | ||
3118 | if (FAIL == GLOB_FTL_Block_Erase(phy_addr)) { | ||
3119 | MARK_BLOCK_AS_BAD(pbt[blk_node]); | ||
3120 | break; | ||
3121 | } | ||
3122 | } | ||
3123 | if (PASS == FTL_Cache_Update_Block(pData, | ||
3124 | old_page_addr, | ||
3125 | phy_addr)) { | ||
3126 | wResult = PASS; | ||
3127 | break; | ||
3128 | } else { | ||
3129 | wResult = FAIL; | ||
3130 | wErase = PASS; | ||
3131 | } | ||
3132 | } | ||
3133 | } while (FAIL == wResult); | ||
3134 | |||
3135 | FTL_Write_Block_Table(FAIL); | ||
3136 | |||
3137 | return wResult; | ||
3138 | } | ||
3139 | |||
3140 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& | 2724 | /*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& |
3141 | * Function: FTL_Get_Page_Num | 2725 | * Function: FTL_Get_Page_Num |
3142 | * Inputs: Size in bytes | 2726 | * Inputs: Size in bytes |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index e483f80822d2..1160c55de7f2 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -723,12 +723,12 @@ int usb_string_ids_tab(struct usb_composite_dev *cdev, struct usb_string *str) | |||
723 | 723 | ||
724 | /** | 724 | /** |
725 | * usb_string_ids_n() - allocate unused string IDs in batch | 725 | * usb_string_ids_n() - allocate unused string IDs in batch |
726 | * @cdev: the device whose string descriptor IDs are being allocated | 726 | * @c: the device whose string descriptor IDs are being allocated |
727 | * @n: number of string IDs to allocate | 727 | * @n: number of string IDs to allocate |
728 | * Context: single threaded during gadget setup | 728 | * Context: single threaded during gadget setup |
729 | * | 729 | * |
730 | * Returns the first requested ID. This ID and next @n-1 IDs are now | 730 | * Returns the first requested ID. This ID and next @n-1 IDs are now |
731 | * valid IDs. At least providind that @n is non zore because if it | 731 | * valid IDs. At least provided that @n is non-zero because if it |
732 | * is, returns last requested ID which is now very useful information. | 732 | * is, returns last requested ID which is now very useful information. |
733 | * | 733 | * |
734 | * @usb_string_ids_n() is called from bind() callbacks to allocate | 734 | * @usb_string_ids_n() is called from bind() callbacks to allocate |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 166bf71fd348..e03058fe23cb 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -1609,6 +1609,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1609 | /* initialize ucd */ | 1609 | /* initialize ucd */ |
1610 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); | 1610 | m66592 = kzalloc(sizeof(struct m66592), GFP_KERNEL); |
1611 | if (m66592 == NULL) { | 1611 | if (m66592 == NULL) { |
1612 | ret = -ENOMEM; | ||
1612 | pr_err("kzalloc error\n"); | 1613 | pr_err("kzalloc error\n"); |
1613 | goto clean_up; | 1614 | goto clean_up; |
1614 | } | 1615 | } |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 70a817842755..2456ccd9965e 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1557,6 +1557,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1557 | /* initialize ucd */ | 1557 | /* initialize ucd */ |
1558 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); | 1558 | r8a66597 = kzalloc(sizeof(struct r8a66597), GFP_KERNEL); |
1559 | if (r8a66597 == NULL) { | 1559 | if (r8a66597 == NULL) { |
1560 | ret = -ENOMEM; | ||
1560 | printk(KERN_ERR "kzalloc error\n"); | 1561 | printk(KERN_ERR "kzalloc error\n"); |
1561 | goto clean_up; | 1562 | goto clean_up; |
1562 | } | 1563 | } |
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c index 2dcffdac86d2..5e807f083bc8 100644 --- a/drivers/usb/gadget/uvc_v4l2.c +++ b/drivers/usb/gadget/uvc_v4l2.c | |||
@@ -94,7 +94,7 @@ uvc_v4l2_set_format(struct uvc_video *video, struct v4l2_format *fmt) | |||
94 | break; | 94 | break; |
95 | } | 95 | } |
96 | 96 | ||
97 | if (format == NULL || format->fcc != fmt->fmt.pix.pixelformat) { | 97 | if (i == ARRAY_SIZE(uvc_formats)) { |
98 | printk(KERN_INFO "Unsupported format 0x%08x.\n", | 98 | printk(KERN_INFO "Unsupported format 0x%08x.\n", |
99 | fmt->fmt.pix.pixelformat); | 99 | fmt->fmt.pix.pixelformat); |
100 | return -EINVAL; | 100 | return -EINVAL; |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index d1a3dfc9a408..bdba8c5d844a 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -829,6 +829,7 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
829 | * almost immediately. With ISP1761, this register requires a delay of | 829 | * almost immediately. With ISP1761, this register requires a delay of |
830 | * 195ns between a write and subsequent read (see section 15.1.1.3). | 830 | * 195ns between a write and subsequent read (see section 15.1.1.3). |
831 | */ | 831 | */ |
832 | mmiowb(); | ||
832 | ndelay(195); | 833 | ndelay(195); |
833 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); | 834 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); |
834 | 835 | ||
@@ -870,6 +871,7 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
870 | * almost immediately. With ISP1761, this register requires a delay of | 871 | * almost immediately. With ISP1761, this register requires a delay of |
871 | * 195ns between a write and subsequent read (see section 15.1.1.3). | 872 | * 195ns between a write and subsequent read (see section 15.1.1.3). |
872 | */ | 873 | */ |
874 | mmiowb(); | ||
873 | ndelay(195); | 875 | ndelay(195); |
874 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); | 876 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); |
875 | 877 | ||
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index bc3f4f427065..48e60d166ff0 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -131,7 +131,7 @@ static void next_trb(struct xhci_hcd *xhci, | |||
131 | *seg = (*seg)->next; | 131 | *seg = (*seg)->next; |
132 | *trb = ((*seg)->trbs); | 132 | *trb = ((*seg)->trbs); |
133 | } else { | 133 | } else { |
134 | *trb = (*trb)++; | 134 | (*trb)++; |
135 | } | 135 | } |
136 | } | 136 | } |
137 | 137 | ||
@@ -1551,6 +1551,10 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1551 | /* calc actual length */ | 1551 | /* calc actual length */ |
1552 | if (ep->skip) { | 1552 | if (ep->skip) { |
1553 | td->urb->iso_frame_desc[idx].actual_length = 0; | 1553 | td->urb->iso_frame_desc[idx].actual_length = 0; |
1554 | /* Update ring dequeue pointer */ | ||
1555 | while (ep_ring->dequeue != td->last_trb) | ||
1556 | inc_deq(xhci, ep_ring, false); | ||
1557 | inc_deq(xhci, ep_ring, false); | ||
1554 | return finish_td(xhci, td, event_trb, event, ep, status, true); | 1558 | return finish_td(xhci, td, event_trb, event, ep, status, true); |
1555 | } | 1559 | } |
1556 | 1560 | ||
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index d240de097c62..801324af9470 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -439,7 +439,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, | |||
439 | /* drain secondary buffer */ | 439 | /* drain secondary buffer */ |
440 | int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary; | 440 | int amount = bytes_to_read < data_in_secondary ? bytes_to_read : data_in_secondary; |
441 | i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount); | 441 | i = copy_to_user(buffer, dev->read_buffer_secondary+dev->secondary_head, amount); |
442 | if (i < 0) { | 442 | if (i) { |
443 | retval = -EFAULT; | 443 | retval = -EFAULT; |
444 | goto exit; | 444 | goto exit; |
445 | } | 445 | } |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 2de49c8887c5..bc88c79875a1 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -542,7 +542,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, | |||
542 | retval = io_res; | 542 | retval = io_res; |
543 | else { | 543 | else { |
544 | io_res = copy_to_user(user_buffer, buffer, dev->report_size); | 544 | io_res = copy_to_user(user_buffer, buffer, dev->report_size); |
545 | if (io_res < 0) | 545 | if (io_res) |
546 | retval = -EFAULT; | 546 | retval = -EFAULT; |
547 | } | 547 | } |
548 | break; | 548 | break; |
@@ -574,7 +574,7 @@ static long iowarrior_ioctl(struct file *file, unsigned int cmd, | |||
574 | } | 574 | } |
575 | io_res = copy_to_user((struct iowarrior_info __user *)arg, &info, | 575 | io_res = copy_to_user((struct iowarrior_info __user *)arg, &info, |
576 | sizeof(struct iowarrior_info)); | 576 | sizeof(struct iowarrior_info)); |
577 | if (io_res < 0) | 577 | if (io_res) |
578 | retval = -EFAULT; | 578 | retval = -EFAULT; |
579 | break; | 579 | break; |
580 | } | 580 | } |
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 0e8888588d4e..05aaac1c3861 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
@@ -550,6 +550,7 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
550 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; | 550 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; |
551 | struct twl4030_usb *twl; | 551 | struct twl4030_usb *twl; |
552 | int status, err; | 552 | int status, err; |
553 | u8 pwr; | ||
553 | 554 | ||
554 | if (!pdata) { | 555 | if (!pdata) { |
555 | dev_dbg(&pdev->dev, "platform_data not available\n"); | 556 | dev_dbg(&pdev->dev, "platform_data not available\n"); |
@@ -568,7 +569,10 @@ static int __devinit twl4030_usb_probe(struct platform_device *pdev) | |||
568 | twl->otg.set_peripheral = twl4030_set_peripheral; | 569 | twl->otg.set_peripheral = twl4030_set_peripheral; |
569 | twl->otg.set_suspend = twl4030_set_suspend; | 570 | twl->otg.set_suspend = twl4030_set_suspend; |
570 | twl->usb_mode = pdata->usb_mode; | 571 | twl->usb_mode = pdata->usb_mode; |
571 | twl->asleep = 1; | 572 | |
573 | pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); | ||
574 | |||
575 | twl->asleep = (pwr & PHY_PWR_PHYPWD); | ||
572 | 576 | ||
573 | /* init spinlock for workqueue */ | 577 | /* init spinlock for workqueue */ |
574 | spin_lock_init(&twl->lock); | 578 | spin_lock_init(&twl->lock); |
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 2bef4415c19c..80bf8333bb03 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -222,8 +222,8 @@ static struct usb_serial_driver cp210x_device = { | |||
222 | #define BITS_STOP_2 0x0002 | 222 | #define BITS_STOP_2 0x0002 |
223 | 223 | ||
224 | /* CP210X_SET_BREAK */ | 224 | /* CP210X_SET_BREAK */ |
225 | #define BREAK_ON 0x0000 | 225 | #define BREAK_ON 0x0001 |
226 | #define BREAK_OFF 0x0001 | 226 | #define BREAK_OFF 0x0000 |
227 | 227 | ||
228 | /* CP210X_(SET_MHS|GET_MDMSTS) */ | 228 | /* CP210X_(SET_MHS|GET_MDMSTS) */ |
229 | #define CONTROL_DTR 0x0001 | 229 | #define CONTROL_DTR 0x0001 |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index eb12d9b096b4..c792c96f590e 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -180,6 +180,7 @@ static struct usb_device_id id_table_combined [] = { | |||
180 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, | 180 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, |
181 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, | 181 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, |
182 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, | 182 | { USB_DEVICE(FTDI_VID, FTDI_SPROG_II) }, |
183 | { USB_DEVICE(FTDI_VID, FTDI_LENZ_LIUSB_PID) }, | ||
183 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, | 184 | { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, |
184 | { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, | 185 | { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, |
185 | { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, | 186 | { USB_DEVICE(FTDI_VID, FTDI_XF_547_PID) }, |
@@ -750,6 +751,8 @@ static struct usb_device_id id_table_combined [] = { | |||
750 | { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), | 751 | { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID), |
751 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 752 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
752 | { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, | 753 | { USB_DEVICE(FTDI_VID, SEGWAY_RMP200_PID) }, |
754 | { USB_DEVICE(IONICS_VID, IONICS_PLUGCOMPUTER_PID), | ||
755 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
753 | { }, /* Optional parameter entry */ | 756 | { }, /* Optional parameter entry */ |
754 | { } /* Terminating entry */ | 757 | { } /* Terminating entry */ |
755 | }; | 758 | }; |
@@ -1376,7 +1379,7 @@ static void ftdi_set_max_packet_size(struct usb_serial_port *port) | |||
1376 | } | 1379 | } |
1377 | 1380 | ||
1378 | /* set max packet size based on descriptor */ | 1381 | /* set max packet size based on descriptor */ |
1379 | priv->max_packet_size = ep_desc->wMaxPacketSize; | 1382 | priv->max_packet_size = le16_to_cpu(ep_desc->wMaxPacketSize); |
1380 | 1383 | ||
1381 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | 1384 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); |
1382 | } | 1385 | } |
@@ -1831,7 +1834,7 @@ static int ftdi_process_packet(struct tty_struct *tty, | |||
1831 | 1834 | ||
1832 | if (port->port.console && port->sysrq) { | 1835 | if (port->port.console && port->sysrq) { |
1833 | for (i = 0; i < len; i++, ch++) { | 1836 | for (i = 0; i < len; i++, ch++) { |
1834 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 1837 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
1835 | tty_insert_flip_char(tty, *ch, flag); | 1838 | tty_insert_flip_char(tty, *ch, flag); |
1836 | } | 1839 | } |
1837 | } else { | 1840 | } else { |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 6e612c52e763..2e95857c9633 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -110,6 +110,9 @@ | |||
110 | /* Propox devices */ | 110 | /* Propox devices */ |
111 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 111 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
112 | 112 | ||
113 | /* Lenz LI-USB Computer Interface. */ | ||
114 | #define FTDI_LENZ_LIUSB_PID 0xD780 | ||
115 | |||
113 | /* | 116 | /* |
114 | * Xsens Technologies BV products (http://www.xsens.com). | 117 | * Xsens Technologies BV products (http://www.xsens.com). |
115 | */ | 118 | */ |
@@ -989,6 +992,12 @@ | |||
989 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ | 992 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ |
990 | 993 | ||
991 | /* | 994 | /* |
995 | * Ionics PlugComputer | ||
996 | */ | ||
997 | #define IONICS_VID 0x1c0c | ||
998 | #define IONICS_PLUGCOMPUTER_PID 0x0102 | ||
999 | |||
1000 | /* | ||
992 | * Dresden Elektronik Sensor Terminal Board | 1001 | * Dresden Elektronik Sensor Terminal Board |
993 | */ | 1002 | */ |
994 | #define DE_VID 0x1cf1 /* Vendor ID */ | 1003 | #define DE_VID 0x1cf1 /* Vendor ID */ |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index ca92f67747cc..e6833e216fc9 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -343,7 +343,7 @@ void usb_serial_generic_process_read_urb(struct urb *urb) | |||
343 | tty_insert_flip_string(tty, ch, urb->actual_length); | 343 | tty_insert_flip_string(tty, ch, urb->actual_length); |
344 | else { | 344 | else { |
345 | for (i = 0; i < urb->actual_length; i++, ch++) { | 345 | for (i = 0; i < urb->actual_length; i++, ch++) { |
346 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 346 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
347 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); | 347 | tty_insert_flip_char(tty, *ch, TTY_NORMAL); |
348 | } | 348 | } |
349 | } | 349 | } |
@@ -448,12 +448,11 @@ void usb_serial_generic_unthrottle(struct tty_struct *tty) | |||
448 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); | 448 | EXPORT_SYMBOL_GPL(usb_serial_generic_unthrottle); |
449 | 449 | ||
450 | #ifdef CONFIG_MAGIC_SYSRQ | 450 | #ifdef CONFIG_MAGIC_SYSRQ |
451 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 451 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
452 | struct usb_serial_port *port, unsigned int ch) | ||
453 | { | 452 | { |
454 | if (port->sysrq && port->port.console) { | 453 | if (port->sysrq && port->port.console) { |
455 | if (ch && time_before(jiffies, port->sysrq)) { | 454 | if (ch && time_before(jiffies, port->sysrq)) { |
456 | handle_sysrq(ch, tty); | 455 | handle_sysrq(ch); |
457 | port->sysrq = 0; | 456 | port->sysrq = 0; |
458 | return 1; | 457 | return 1; |
459 | } | 458 | } |
@@ -462,8 +461,7 @@ int usb_serial_handle_sysrq_char(struct tty_struct *tty, | |||
462 | return 0; | 461 | return 0; |
463 | } | 462 | } |
464 | #else | 463 | #else |
465 | int usb_serial_handle_sysrq_char(struct tty_struct *tty, | 464 | int usb_serial_handle_sysrq_char(struct usb_serial_port *port, unsigned int ch) |
466 | struct usb_serial_port *port, unsigned int ch) | ||
467 | { | 465 | { |
468 | return 0; | 466 | return 0; |
469 | } | 467 | } |
@@ -518,6 +516,7 @@ void usb_serial_generic_disconnect(struct usb_serial *serial) | |||
518 | for (i = 0; i < serial->num_ports; ++i) | 516 | for (i = 0; i < serial->num_ports; ++i) |
519 | generic_cleanup(serial->port[i]); | 517 | generic_cleanup(serial->port[i]); |
520 | } | 518 | } |
519 | EXPORT_SYMBOL_GPL(usb_serial_generic_disconnect); | ||
521 | 520 | ||
522 | void usb_serial_generic_release(struct usb_serial *serial) | 521 | void usb_serial_generic_release(struct usb_serial *serial) |
523 | { | 522 | { |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index dc47f986df57..a7cfc5952937 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -1151,7 +1151,7 @@ static int download_fw(struct edgeport_serial *serial) | |||
1151 | 1151 | ||
1152 | /* Check if we have an old version in the I2C and | 1152 | /* Check if we have an old version in the I2C and |
1153 | update if necessary */ | 1153 | update if necessary */ |
1154 | if (download_cur_ver != download_new_ver) { | 1154 | if (download_cur_ver < download_new_ver) { |
1155 | dbg("%s - Update I2C dld from %d.%d to %d.%d", | 1155 | dbg("%s - Update I2C dld from %d.%d to %d.%d", |
1156 | __func__, | 1156 | __func__, |
1157 | firmware_version->Ver_Major, | 1157 | firmware_version->Ver_Major, |
@@ -1284,7 +1284,7 @@ static int download_fw(struct edgeport_serial *serial) | |||
1284 | kfree(header); | 1284 | kfree(header); |
1285 | kfree(rom_desc); | 1285 | kfree(rom_desc); |
1286 | kfree(ti_manuf_desc); | 1286 | kfree(ti_manuf_desc); |
1287 | return status; | 1287 | return -EINVAL; |
1288 | } | 1288 | } |
1289 | 1289 | ||
1290 | /* Update I2C with type 0xf2 record with correct | 1290 | /* Update I2C with type 0xf2 record with correct |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index a6b207c84917..1f00f243c26c 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -25,6 +25,7 @@ static int debug; | |||
25 | 25 | ||
26 | static const struct usb_device_id id_table[] = { | 26 | static const struct usb_device_id id_table[] = { |
27 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ | 27 | { USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */ |
28 | { USB_DEVICE(0x0df7, 0x0900) }, /* Mobile Action i-gotU */ | ||
28 | { }, | 29 | { }, |
29 | }; | 30 | }; |
30 | MODULE_DEVICE_TABLE(usb, id_table); | 31 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9fc6ea2c681f..adcbdb994de3 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -365,6 +365,10 @@ static void option_instat_callback(struct urb *urb); | |||
365 | #define OLIVETTI_VENDOR_ID 0x0b3c | 365 | #define OLIVETTI_VENDOR_ID 0x0b3c |
366 | #define OLIVETTI_PRODUCT_OLICARD100 0xc000 | 366 | #define OLIVETTI_PRODUCT_OLICARD100 0xc000 |
367 | 367 | ||
368 | /* Celot products */ | ||
369 | #define CELOT_VENDOR_ID 0x211f | ||
370 | #define CELOT_PRODUCT_CT680M 0x6801 | ||
371 | |||
368 | /* some devices interfaces need special handling due to a number of reasons */ | 372 | /* some devices interfaces need special handling due to a number of reasons */ |
369 | enum option_blacklist_reason { | 373 | enum option_blacklist_reason { |
370 | OPTION_BLACKLIST_NONE = 0, | 374 | OPTION_BLACKLIST_NONE = 0, |
@@ -887,10 +891,9 @@ static const struct usb_device_id option_ids[] = { | |||
887 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, | 891 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_100F) }, |
888 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, | 892 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1011)}, |
889 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, | 893 | { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)}, |
890 | |||
891 | { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, | 894 | { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) }, |
892 | |||
893 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, | 895 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, |
896 | { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ | ||
894 | { } /* Terminating entry */ | 897 | { } /* Terminating entry */ |
895 | }; | 898 | }; |
896 | MODULE_DEVICE_TABLE(usb, option_ids); | 899 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 6b6001822279..8ae4c6cbc38a 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -86,6 +86,7 @@ static const struct usb_device_id id_table[] = { | |||
86 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, | 86 | { USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) }, |
87 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, | 87 | { USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) }, |
88 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, | 88 | { USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) }, |
89 | { USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) }, | ||
89 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, | 90 | { USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) }, |
90 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, | 91 | { USB_DEVICE(SANWA_VENDOR_ID, SANWA_PRODUCT_ID) }, |
91 | { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, | 92 | { USB_DEVICE(ADLINK_VENDOR_ID, ADLINK_ND6530_PRODUCT_ID) }, |
@@ -788,7 +789,7 @@ static void pl2303_process_read_urb(struct urb *urb) | |||
788 | 789 | ||
789 | if (port->port.console && port->sysrq) { | 790 | if (port->port.console && port->sysrq) { |
790 | for (i = 0; i < urb->actual_length; ++i) | 791 | for (i = 0; i < urb->actual_length; ++i) |
791 | if (!usb_serial_handle_sysrq_char(tty, port, data[i])) | 792 | if (!usb_serial_handle_sysrq_char(port, data[i])) |
792 | tty_insert_flip_char(tty, data[i], tty_flag); | 793 | tty_insert_flip_char(tty, data[i], tty_flag); |
793 | } else { | 794 | } else { |
794 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, | 795 | tty_insert_flip_string_fixed_flag(tty, data, tty_flag, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index a871645389dd..43eb9bdad422 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -128,6 +128,10 @@ | |||
128 | #define CRESSI_VENDOR_ID 0x04b8 | 128 | #define CRESSI_VENDOR_ID 0x04b8 |
129 | #define CRESSI_EDY_PRODUCT_ID 0x0521 | 129 | #define CRESSI_EDY_PRODUCT_ID 0x0521 |
130 | 130 | ||
131 | /* Zeagle dive computer interface */ | ||
132 | #define ZEAGLE_VENDOR_ID 0x04b8 | ||
133 | #define ZEAGLE_N2ITION3_PRODUCT_ID 0x0522 | ||
134 | |||
131 | /* Sony, USB data cable for CMD-Jxx mobile phones */ | 135 | /* Sony, USB data cable for CMD-Jxx mobile phones */ |
132 | #define SONY_VENDOR_ID 0x054c | 136 | #define SONY_VENDOR_ID 0x054c |
133 | #define SONY_QN3USB_PRODUCT_ID 0x0437 | 137 | #define SONY_QN3USB_PRODUCT_ID 0x0437 |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 6e82d4f54bc8..68c18fdfc6da 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/serial.h> | 15 | #include <linux/serial.h> |
16 | #include <linux/usb.h> | 16 | #include <linux/usb.h> |
17 | #include <linux/usb/serial.h> | 17 | #include <linux/usb/serial.h> |
18 | #include <linux/serial_reg.h> | ||
18 | #include <linux/uaccess.h> | 19 | #include <linux/uaccess.h> |
19 | 20 | ||
20 | #define QT_OPEN_CLOSE_CHANNEL 0xca | 21 | #define QT_OPEN_CLOSE_CHANNEL 0xca |
@@ -27,36 +28,11 @@ | |||
27 | #define QT_HW_FLOW_CONTROL_MASK 0xc5 | 28 | #define QT_HW_FLOW_CONTROL_MASK 0xc5 |
28 | #define QT_SW_FLOW_CONTROL_MASK 0xc6 | 29 | #define QT_SW_FLOW_CONTROL_MASK 0xc6 |
29 | 30 | ||
30 | #define MODEM_CTL_REGISTER 0x04 | ||
31 | #define MODEM_STATUS_REGISTER 0x06 | ||
32 | |||
33 | |||
34 | #define SERIAL_LSR_OE 0x02 | ||
35 | #define SERIAL_LSR_PE 0x04 | ||
36 | #define SERIAL_LSR_FE 0x08 | ||
37 | #define SERIAL_LSR_BI 0x10 | ||
38 | |||
39 | #define SERIAL_LSR_TEMT 0x40 | ||
40 | |||
41 | #define SERIAL_MCR_DTR 0x01 | ||
42 | #define SERIAL_MCR_RTS 0x02 | ||
43 | #define SERIAL_MCR_LOOP 0x10 | ||
44 | |||
45 | #define SERIAL_MSR_CTS 0x10 | ||
46 | #define SERIAL_MSR_CD 0x80 | ||
47 | #define SERIAL_MSR_RI 0x40 | ||
48 | #define SERIAL_MSR_DSR 0x20 | ||
49 | #define SERIAL_MSR_MASK 0xf0 | 31 | #define SERIAL_MSR_MASK 0xf0 |
50 | 32 | ||
51 | #define SERIAL_CRTSCTS ((SERIAL_MCR_RTS << 8) | SERIAL_MSR_CTS) | 33 | #define SERIAL_CRTSCTS ((UART_MCR_RTS << 8) | UART_MSR_CTS) |
52 | 34 | ||
53 | #define SERIAL_8_DATA 0x03 | 35 | #define SERIAL_EVEN_PARITY (UART_LCR_PARITY | UART_LCR_EPAR) |
54 | #define SERIAL_7_DATA 0x02 | ||
55 | #define SERIAL_6_DATA 0x01 | ||
56 | #define SERIAL_5_DATA 0x00 | ||
57 | |||
58 | #define SERIAL_ODD_PARITY 0X08 | ||
59 | #define SERIAL_EVEN_PARITY 0X18 | ||
60 | 36 | ||
61 | #define MAX_BAUD_RATE 460800 | 37 | #define MAX_BAUD_RATE 460800 |
62 | 38 | ||
@@ -99,10 +75,12 @@ static struct usb_driver ssu100_driver = { | |||
99 | }; | 75 | }; |
100 | 76 | ||
101 | struct ssu100_port_private { | 77 | struct ssu100_port_private { |
78 | spinlock_t status_lock; | ||
102 | u8 shadowLSR; | 79 | u8 shadowLSR; |
103 | u8 shadowMSR; | 80 | u8 shadowMSR; |
104 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ | 81 | wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */ |
105 | unsigned short max_packet_size; | 82 | unsigned short max_packet_size; |
83 | struct async_icount icount; | ||
106 | }; | 84 | }; |
107 | 85 | ||
108 | static void ssu100_release(struct usb_serial *serial) | 86 | static void ssu100_release(struct usb_serial *serial) |
@@ -150,9 +128,10 @@ static inline int ssu100_getregister(struct usb_device *dev, | |||
150 | 128 | ||
151 | static inline int ssu100_setregister(struct usb_device *dev, | 129 | static inline int ssu100_setregister(struct usb_device *dev, |
152 | unsigned short uart, | 130 | unsigned short uart, |
131 | unsigned short reg, | ||
153 | u16 data) | 132 | u16 data) |
154 | { | 133 | { |
155 | u16 value = (data << 8) | MODEM_CTL_REGISTER; | 134 | u16 value = (data << 8) | reg; |
156 | 135 | ||
157 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | 136 | return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), |
158 | QT_SET_GET_REGISTER, 0x40, value, uart, | 137 | QT_SET_GET_REGISTER, 0x40, value, uart, |
@@ -178,11 +157,11 @@ static inline int update_mctrl(struct usb_device *dev, unsigned int set, | |||
178 | clear &= ~set; /* 'set' takes precedence over 'clear' */ | 157 | clear &= ~set; /* 'set' takes precedence over 'clear' */ |
179 | urb_value = 0; | 158 | urb_value = 0; |
180 | if (set & TIOCM_DTR) | 159 | if (set & TIOCM_DTR) |
181 | urb_value |= SERIAL_MCR_DTR; | 160 | urb_value |= UART_MCR_DTR; |
182 | if (set & TIOCM_RTS) | 161 | if (set & TIOCM_RTS) |
183 | urb_value |= SERIAL_MCR_RTS; | 162 | urb_value |= UART_MCR_RTS; |
184 | 163 | ||
185 | result = ssu100_setregister(dev, 0, urb_value); | 164 | result = ssu100_setregister(dev, 0, UART_MCR, urb_value); |
186 | if (result < 0) | 165 | if (result < 0) |
187 | dbg("%s Error from MODEM_CTRL urb", __func__); | 166 | dbg("%s Error from MODEM_CTRL urb", __func__); |
188 | 167 | ||
@@ -264,24 +243,24 @@ static void ssu100_set_termios(struct tty_struct *tty, | |||
264 | 243 | ||
265 | if (cflag & PARENB) { | 244 | if (cflag & PARENB) { |
266 | if (cflag & PARODD) | 245 | if (cflag & PARODD) |
267 | urb_value |= SERIAL_ODD_PARITY; | 246 | urb_value |= UART_LCR_PARITY; |
268 | else | 247 | else |
269 | urb_value |= SERIAL_EVEN_PARITY; | 248 | urb_value |= SERIAL_EVEN_PARITY; |
270 | } | 249 | } |
271 | 250 | ||
272 | switch (cflag & CSIZE) { | 251 | switch (cflag & CSIZE) { |
273 | case CS5: | 252 | case CS5: |
274 | urb_value |= SERIAL_5_DATA; | 253 | urb_value |= UART_LCR_WLEN5; |
275 | break; | 254 | break; |
276 | case CS6: | 255 | case CS6: |
277 | urb_value |= SERIAL_6_DATA; | 256 | urb_value |= UART_LCR_WLEN6; |
278 | break; | 257 | break; |
279 | case CS7: | 258 | case CS7: |
280 | urb_value |= SERIAL_7_DATA; | 259 | urb_value |= UART_LCR_WLEN7; |
281 | break; | 260 | break; |
282 | default: | 261 | default: |
283 | case CS8: | 262 | case CS8: |
284 | urb_value |= SERIAL_8_DATA; | 263 | urb_value |= UART_LCR_WLEN8; |
285 | break; | 264 | break; |
286 | } | 265 | } |
287 | 266 | ||
@@ -333,6 +312,7 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
333 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | 312 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); |
334 | u8 *data; | 313 | u8 *data; |
335 | int result; | 314 | int result; |
315 | unsigned long flags; | ||
336 | 316 | ||
337 | dbg("%s - port %d", __func__, port->number); | 317 | dbg("%s - port %d", __func__, port->number); |
338 | 318 | ||
@@ -350,11 +330,10 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
350 | return result; | 330 | return result; |
351 | } | 331 | } |
352 | 332 | ||
353 | priv->shadowLSR = data[0] & (SERIAL_LSR_OE | SERIAL_LSR_PE | | 333 | spin_lock_irqsave(&priv->status_lock, flags); |
354 | SERIAL_LSR_FE | SERIAL_LSR_BI); | 334 | priv->shadowLSR = data[0]; |
355 | 335 | priv->shadowMSR = data[1]; | |
356 | priv->shadowMSR = data[1] & (SERIAL_MSR_CTS | SERIAL_MSR_DSR | | 336 | spin_unlock_irqrestore(&priv->status_lock, flags); |
357 | SERIAL_MSR_RI | SERIAL_MSR_CD); | ||
358 | 337 | ||
359 | kfree(data); | 338 | kfree(data); |
360 | 339 | ||
@@ -398,11 +377,51 @@ static int get_serial_info(struct usb_serial_port *port, | |||
398 | return 0; | 377 | return 0; |
399 | } | 378 | } |
400 | 379 | ||
380 | static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | ||
381 | { | ||
382 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
383 | struct async_icount prev, cur; | ||
384 | unsigned long flags; | ||
385 | |||
386 | spin_lock_irqsave(&priv->status_lock, flags); | ||
387 | prev = priv->icount; | ||
388 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
389 | |||
390 | while (1) { | ||
391 | wait_event_interruptible(priv->delta_msr_wait, | ||
392 | ((priv->icount.rng != prev.rng) || | ||
393 | (priv->icount.dsr != prev.dsr) || | ||
394 | (priv->icount.dcd != prev.dcd) || | ||
395 | (priv->icount.cts != prev.cts))); | ||
396 | |||
397 | if (signal_pending(current)) | ||
398 | return -ERESTARTSYS; | ||
399 | |||
400 | spin_lock_irqsave(&priv->status_lock, flags); | ||
401 | cur = priv->icount; | ||
402 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
403 | |||
404 | if ((prev.rng == cur.rng) && | ||
405 | (prev.dsr == cur.dsr) && | ||
406 | (prev.dcd == cur.dcd) && | ||
407 | (prev.cts == cur.cts)) | ||
408 | return -EIO; | ||
409 | |||
410 | if ((arg & TIOCM_RNG && (prev.rng != cur.rng)) || | ||
411 | (arg & TIOCM_DSR && (prev.dsr != cur.dsr)) || | ||
412 | (arg & TIOCM_CD && (prev.dcd != cur.dcd)) || | ||
413 | (arg & TIOCM_CTS && (prev.cts != cur.cts))) | ||
414 | return 0; | ||
415 | } | ||
416 | return 0; | ||
417 | } | ||
418 | |||
401 | static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | 419 | static int ssu100_ioctl(struct tty_struct *tty, struct file *file, |
402 | unsigned int cmd, unsigned long arg) | 420 | unsigned int cmd, unsigned long arg) |
403 | { | 421 | { |
404 | struct usb_serial_port *port = tty->driver_data; | 422 | struct usb_serial_port *port = tty->driver_data; |
405 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | 423 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); |
424 | void __user *user_arg = (void __user *)arg; | ||
406 | 425 | ||
407 | dbg("%s cmd 0x%04x", __func__, cmd); | 426 | dbg("%s cmd 0x%04x", __func__, cmd); |
408 | 427 | ||
@@ -412,28 +431,28 @@ static int ssu100_ioctl(struct tty_struct *tty, struct file *file, | |||
412 | (struct serial_struct __user *) arg); | 431 | (struct serial_struct __user *) arg); |
413 | 432 | ||
414 | case TIOCMIWAIT: | 433 | case TIOCMIWAIT: |
415 | while (priv != NULL) { | 434 | return wait_modem_info(port, arg); |
416 | u8 prevMSR = priv->shadowMSR & SERIAL_MSR_MASK; | 435 | |
417 | interruptible_sleep_on(&priv->delta_msr_wait); | 436 | case TIOCGICOUNT: |
418 | /* see if a signal did it */ | 437 | { |
419 | if (signal_pending(current)) | 438 | struct serial_icounter_struct icount; |
420 | return -ERESTARTSYS; | 439 | struct async_icount cnow = priv->icount; |
421 | else { | 440 | memset(&icount, 0, sizeof(icount)); |
422 | u8 diff = (priv->shadowMSR & SERIAL_MSR_MASK) ^ prevMSR; | 441 | icount.cts = cnow.cts; |
423 | if (!diff) | 442 | icount.dsr = cnow.dsr; |
424 | return -EIO; /* no change => error */ | 443 | icount.rng = cnow.rng; |
425 | 444 | icount.dcd = cnow.dcd; | |
426 | /* Return 0 if caller wanted to know about | 445 | icount.rx = cnow.rx; |
427 | these bits */ | 446 | icount.tx = cnow.tx; |
428 | 447 | icount.frame = cnow.frame; | |
429 | if (((arg & TIOCM_RNG) && (diff & SERIAL_MSR_RI)) || | 448 | icount.overrun = cnow.overrun; |
430 | ((arg & TIOCM_DSR) && (diff & SERIAL_MSR_DSR)) || | 449 | icount.parity = cnow.parity; |
431 | ((arg & TIOCM_CD) && (diff & SERIAL_MSR_CD)) || | 450 | icount.brk = cnow.brk; |
432 | ((arg & TIOCM_CTS) && (diff & SERIAL_MSR_CTS))) | 451 | icount.buf_overrun = cnow.buf_overrun; |
433 | return 0; | 452 | if (copy_to_user(user_arg, &icount, sizeof(icount))) |
434 | } | 453 | return -EFAULT; |
435 | } | ||
436 | return 0; | 454 | return 0; |
455 | } | ||
437 | 456 | ||
438 | default: | 457 | default: |
439 | break; | 458 | break; |
@@ -455,6 +474,7 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port) | |||
455 | 474 | ||
456 | unsigned num_endpoints; | 475 | unsigned num_endpoints; |
457 | int i; | 476 | int i; |
477 | unsigned long flags; | ||
458 | 478 | ||
459 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; | 479 | num_endpoints = interface->cur_altsetting->desc.bNumEndpoints; |
460 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); | 480 | dev_info(&udev->dev, "Number of endpoints %d\n", num_endpoints); |
@@ -466,7 +486,9 @@ static void ssu100_set_max_packet_size(struct usb_serial_port *port) | |||
466 | } | 486 | } |
467 | 487 | ||
468 | /* set max packet size based on descriptor */ | 488 | /* set max packet size based on descriptor */ |
489 | spin_lock_irqsave(&priv->status_lock, flags); | ||
469 | priv->max_packet_size = ep_desc->wMaxPacketSize; | 490 | priv->max_packet_size = ep_desc->wMaxPacketSize; |
491 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
470 | 492 | ||
471 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); | 493 | dev_info(&udev->dev, "Setting MaxPacketSize %d\n", priv->max_packet_size); |
472 | } | 494 | } |
@@ -485,9 +507,9 @@ static int ssu100_attach(struct usb_serial *serial) | |||
485 | return -ENOMEM; | 507 | return -ENOMEM; |
486 | } | 508 | } |
487 | 509 | ||
510 | spin_lock_init(&priv->status_lock); | ||
488 | init_waitqueue_head(&priv->delta_msr_wait); | 511 | init_waitqueue_head(&priv->delta_msr_wait); |
489 | usb_set_serial_port_data(port, priv); | 512 | usb_set_serial_port_data(port, priv); |
490 | |||
491 | ssu100_set_max_packet_size(port); | 513 | ssu100_set_max_packet_size(port); |
492 | 514 | ||
493 | return ssu100_initdevice(serial->dev); | 515 | return ssu100_initdevice(serial->dev); |
@@ -506,20 +528,20 @@ static int ssu100_tiocmget(struct tty_struct *tty, struct file *file) | |||
506 | if (!d) | 528 | if (!d) |
507 | return -ENOMEM; | 529 | return -ENOMEM; |
508 | 530 | ||
509 | r = ssu100_getregister(dev, 0, MODEM_CTL_REGISTER, d); | 531 | r = ssu100_getregister(dev, 0, UART_MCR, d); |
510 | if (r < 0) | 532 | if (r < 0) |
511 | goto mget_out; | 533 | goto mget_out; |
512 | 534 | ||
513 | r = ssu100_getregister(dev, 0, MODEM_STATUS_REGISTER, d+1); | 535 | r = ssu100_getregister(dev, 0, UART_MSR, d+1); |
514 | if (r < 0) | 536 | if (r < 0) |
515 | goto mget_out; | 537 | goto mget_out; |
516 | 538 | ||
517 | r = (d[0] & SERIAL_MCR_DTR ? TIOCM_DTR : 0) | | 539 | r = (d[0] & UART_MCR_DTR ? TIOCM_DTR : 0) | |
518 | (d[0] & SERIAL_MCR_RTS ? TIOCM_RTS : 0) | | 540 | (d[0] & UART_MCR_RTS ? TIOCM_RTS : 0) | |
519 | (d[1] & SERIAL_MSR_CTS ? TIOCM_CTS : 0) | | 541 | (d[1] & UART_MSR_CTS ? TIOCM_CTS : 0) | |
520 | (d[1] & SERIAL_MSR_CD ? TIOCM_CAR : 0) | | 542 | (d[1] & UART_MSR_DCD ? TIOCM_CAR : 0) | |
521 | (d[1] & SERIAL_MSR_RI ? TIOCM_RI : 0) | | 543 | (d[1] & UART_MSR_RI ? TIOCM_RI : 0) | |
522 | (d[1] & SERIAL_MSR_DSR ? TIOCM_DSR : 0); | 544 | (d[1] & UART_MSR_DSR ? TIOCM_DSR : 0); |
523 | 545 | ||
524 | mget_out: | 546 | mget_out: |
525 | kfree(d); | 547 | kfree(d); |
@@ -546,7 +568,7 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on) | |||
546 | if (!port->serial->disconnected) { | 568 | if (!port->serial->disconnected) { |
547 | /* Disable flow control */ | 569 | /* Disable flow control */ |
548 | if (!on && | 570 | if (!on && |
549 | ssu100_setregister(dev, 0, 0) < 0) | 571 | ssu100_setregister(dev, 0, UART_MCR, 0) < 0) |
550 | dev_err(&port->dev, "error from flowcontrol urb\n"); | 572 | dev_err(&port->dev, "error from flowcontrol urb\n"); |
551 | /* drop RTS and DTR */ | 573 | /* drop RTS and DTR */ |
552 | if (on) | 574 | if (on) |
@@ -557,34 +579,88 @@ static void ssu100_dtr_rts(struct usb_serial_port *port, int on) | |||
557 | mutex_unlock(&port->serial->disc_mutex); | 579 | mutex_unlock(&port->serial->disc_mutex); |
558 | } | 580 | } |
559 | 581 | ||
582 | static void ssu100_update_msr(struct usb_serial_port *port, u8 msr) | ||
583 | { | ||
584 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
585 | unsigned long flags; | ||
586 | |||
587 | spin_lock_irqsave(&priv->status_lock, flags); | ||
588 | priv->shadowMSR = msr; | ||
589 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
590 | |||
591 | if (msr & UART_MSR_ANY_DELTA) { | ||
592 | /* update input line counters */ | ||
593 | if (msr & UART_MSR_DCTS) | ||
594 | priv->icount.cts++; | ||
595 | if (msr & UART_MSR_DDSR) | ||
596 | priv->icount.dsr++; | ||
597 | if (msr & UART_MSR_DDCD) | ||
598 | priv->icount.dcd++; | ||
599 | if (msr & UART_MSR_TERI) | ||
600 | priv->icount.rng++; | ||
601 | wake_up_interruptible(&priv->delta_msr_wait); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static void ssu100_update_lsr(struct usb_serial_port *port, u8 lsr, | ||
606 | char *tty_flag) | ||
607 | { | ||
608 | struct ssu100_port_private *priv = usb_get_serial_port_data(port); | ||
609 | unsigned long flags; | ||
610 | |||
611 | spin_lock_irqsave(&priv->status_lock, flags); | ||
612 | priv->shadowLSR = lsr; | ||
613 | spin_unlock_irqrestore(&priv->status_lock, flags); | ||
614 | |||
615 | *tty_flag = TTY_NORMAL; | ||
616 | if (lsr & UART_LSR_BRK_ERROR_BITS) { | ||
617 | /* we always want to update icount, but we only want to | ||
618 | * update tty_flag for one case */ | ||
619 | if (lsr & UART_LSR_BI) { | ||
620 | priv->icount.brk++; | ||
621 | *tty_flag = TTY_BREAK; | ||
622 | usb_serial_handle_break(port); | ||
623 | } | ||
624 | if (lsr & UART_LSR_PE) { | ||
625 | priv->icount.parity++; | ||
626 | if (*tty_flag == TTY_NORMAL) | ||
627 | *tty_flag = TTY_PARITY; | ||
628 | } | ||
629 | if (lsr & UART_LSR_FE) { | ||
630 | priv->icount.frame++; | ||
631 | if (*tty_flag == TTY_NORMAL) | ||
632 | *tty_flag = TTY_FRAME; | ||
633 | } | ||
634 | if (lsr & UART_LSR_OE){ | ||
635 | priv->icount.overrun++; | ||
636 | if (*tty_flag == TTY_NORMAL) | ||
637 | *tty_flag = TTY_OVERRUN; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | } | ||
642 | |||
560 | static int ssu100_process_packet(struct tty_struct *tty, | 643 | static int ssu100_process_packet(struct tty_struct *tty, |
561 | struct usb_serial_port *port, | 644 | struct usb_serial_port *port, |
562 | struct ssu100_port_private *priv, | 645 | struct ssu100_port_private *priv, |
563 | char *packet, int len) | 646 | char *packet, int len) |
564 | { | 647 | { |
565 | int i; | 648 | int i; |
566 | char flag; | 649 | char flag = TTY_NORMAL; |
567 | char *ch; | 650 | char *ch; |
568 | 651 | ||
569 | dbg("%s - port %d", __func__, port->number); | 652 | dbg("%s - port %d", __func__, port->number); |
570 | 653 | ||
571 | if (len < 4) { | 654 | if ((len >= 4) && |
572 | dbg("%s - malformed packet", __func__); | 655 | (packet[0] == 0x1b) && (packet[1] == 0x1b) && |
573 | return 0; | ||
574 | } | ||
575 | |||
576 | if ((packet[0] == 0x1b) && (packet[1] == 0x1b) && | ||
577 | ((packet[2] == 0x00) || (packet[2] == 0x01))) { | 656 | ((packet[2] == 0x00) || (packet[2] == 0x01))) { |
578 | if (packet[2] == 0x00) | 657 | if (packet[2] == 0x00) { |
579 | priv->shadowLSR = packet[3] & (SERIAL_LSR_OE | | 658 | ssu100_update_lsr(port, packet[3], &flag); |
580 | SERIAL_LSR_PE | | 659 | if (flag == TTY_OVERRUN) |
581 | SERIAL_LSR_FE | | 660 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
582 | SERIAL_LSR_BI); | ||
583 | |||
584 | if (packet[2] == 0x01) { | ||
585 | priv->shadowMSR = packet[3]; | ||
586 | wake_up_interruptible(&priv->delta_msr_wait); | ||
587 | } | 661 | } |
662 | if (packet[2] == 0x01) | ||
663 | ssu100_update_msr(port, packet[3]); | ||
588 | 664 | ||
589 | len -= 4; | 665 | len -= 4; |
590 | ch = packet + 4; | 666 | ch = packet + 4; |
@@ -596,7 +672,7 @@ static int ssu100_process_packet(struct tty_struct *tty, | |||
596 | 672 | ||
597 | if (port->port.console && port->sysrq) { | 673 | if (port->port.console && port->sysrq) { |
598 | for (i = 0; i < len; i++, ch++) { | 674 | for (i = 0; i < len; i++, ch++) { |
599 | if (!usb_serial_handle_sysrq_char(tty, port, *ch)) | 675 | if (!usb_serial_handle_sysrq_char(port, *ch)) |
600 | tty_insert_flip_char(tty, *ch, flag); | 676 | tty_insert_flip_char(tty, *ch, flag); |
601 | } | 677 | } |
602 | } else | 678 | } else |
@@ -631,7 +707,6 @@ static void ssu100_process_read_urb(struct urb *urb) | |||
631 | tty_kref_put(tty); | 707 | tty_kref_put(tty); |
632 | } | 708 | } |
633 | 709 | ||
634 | |||
635 | static struct usb_serial_driver ssu100_device = { | 710 | static struct usb_serial_driver ssu100_device = { |
636 | .driver = { | 711 | .driver = { |
637 | .owner = THIS_MODULE, | 712 | .owner = THIS_MODULE, |
@@ -653,6 +728,7 @@ static struct usb_serial_driver ssu100_device = { | |||
653 | .tiocmset = ssu100_tiocmset, | 728 | .tiocmset = ssu100_tiocmset, |
654 | .ioctl = ssu100_ioctl, | 729 | .ioctl = ssu100_ioctl, |
655 | .set_termios = ssu100_set_termios, | 730 | .set_termios = ssu100_set_termios, |
731 | .disconnect = usb_serial_generic_disconnect, | ||
656 | }; | 732 | }; |
657 | 733 | ||
658 | static int __init ssu100_init(void) | 734 | static int __init ssu100_init(void) |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 2a982e62963b..7a2177c79bde 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -736,6 +736,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
736 | 736 | ||
737 | serial = create_serial(dev, interface, type); | 737 | serial = create_serial(dev, interface, type); |
738 | if (!serial) { | 738 | if (!serial) { |
739 | module_put(type->driver.owner); | ||
739 | dev_err(&interface->dev, "%s - out of memory\n", __func__); | 740 | dev_err(&interface->dev, "%s - out of memory\n", __func__); |
740 | return -ENOMEM; | 741 | return -ENOMEM; |
741 | } | 742 | } |
@@ -746,11 +747,11 @@ int usb_serial_probe(struct usb_interface *interface, | |||
746 | 747 | ||
747 | id = get_iface_id(type, interface); | 748 | id = get_iface_id(type, interface); |
748 | retval = type->probe(serial, id); | 749 | retval = type->probe(serial, id); |
749 | module_put(type->driver.owner); | ||
750 | 750 | ||
751 | if (retval) { | 751 | if (retval) { |
752 | dbg("sub driver rejected device"); | 752 | dbg("sub driver rejected device"); |
753 | kfree(serial); | 753 | kfree(serial); |
754 | module_put(type->driver.owner); | ||
754 | return retval; | 755 | return retval; |
755 | } | 756 | } |
756 | } | 757 | } |
@@ -822,6 +823,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
822 | if (num_bulk_in == 0 || num_bulk_out == 0) { | 823 | if (num_bulk_in == 0 || num_bulk_out == 0) { |
823 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); | 824 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); |
824 | kfree(serial); | 825 | kfree(serial); |
826 | module_put(type->driver.owner); | ||
825 | return -ENODEV; | 827 | return -ENODEV; |
826 | } | 828 | } |
827 | } | 829 | } |
@@ -835,22 +837,15 @@ int usb_serial_probe(struct usb_interface *interface, | |||
835 | dev_err(&interface->dev, | 837 | dev_err(&interface->dev, |
836 | "Generic device with no bulk out, not allowed.\n"); | 838 | "Generic device with no bulk out, not allowed.\n"); |
837 | kfree(serial); | 839 | kfree(serial); |
840 | module_put(type->driver.owner); | ||
838 | return -EIO; | 841 | return -EIO; |
839 | } | 842 | } |
840 | } | 843 | } |
841 | #endif | 844 | #endif |
842 | if (!num_ports) { | 845 | if (!num_ports) { |
843 | /* if this device type has a calc_num_ports function, call it */ | 846 | /* if this device type has a calc_num_ports function, call it */ |
844 | if (type->calc_num_ports) { | 847 | if (type->calc_num_ports) |
845 | if (!try_module_get(type->driver.owner)) { | ||
846 | dev_err(&interface->dev, | ||
847 | "module get failed, exiting\n"); | ||
848 | kfree(serial); | ||
849 | return -EIO; | ||
850 | } | ||
851 | num_ports = type->calc_num_ports(serial); | 848 | num_ports = type->calc_num_ports(serial); |
852 | module_put(type->driver.owner); | ||
853 | } | ||
854 | if (!num_ports) | 849 | if (!num_ports) |
855 | num_ports = type->num_ports; | 850 | num_ports = type->num_ports; |
856 | } | 851 | } |
@@ -1039,13 +1034,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1039 | 1034 | ||
1040 | /* if this device type has an attach function, call it */ | 1035 | /* if this device type has an attach function, call it */ |
1041 | if (type->attach) { | 1036 | if (type->attach) { |
1042 | if (!try_module_get(type->driver.owner)) { | ||
1043 | dev_err(&interface->dev, | ||
1044 | "module get failed, exiting\n"); | ||
1045 | goto probe_error; | ||
1046 | } | ||
1047 | retval = type->attach(serial); | 1037 | retval = type->attach(serial); |
1048 | module_put(type->driver.owner); | ||
1049 | if (retval < 0) | 1038 | if (retval < 0) |
1050 | goto probe_error; | 1039 | goto probe_error; |
1051 | serial->attached = 1; | 1040 | serial->attached = 1; |
@@ -1088,10 +1077,12 @@ int usb_serial_probe(struct usb_interface *interface, | |||
1088 | exit: | 1077 | exit: |
1089 | /* success */ | 1078 | /* success */ |
1090 | usb_set_intfdata(interface, serial); | 1079 | usb_set_intfdata(interface, serial); |
1080 | module_put(type->driver.owner); | ||
1091 | return 0; | 1081 | return 0; |
1092 | 1082 | ||
1093 | probe_error: | 1083 | probe_error: |
1094 | usb_serial_put(serial); | 1084 | usb_serial_put(serial); |
1085 | module_put(type->driver.owner); | ||
1095 | return -EIO; | 1086 | return -EIO; |
1096 | } | 1087 | } |
1097 | EXPORT_SYMBOL_GPL(usb_serial_probe); | 1088 | EXPORT_SYMBOL_GPL(usb_serial_probe); |
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c index afe21e6eb544..1c2c68356ea7 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/amba-clcd.c | |||
@@ -80,7 +80,10 @@ static void clcdfb_disable(struct clcd_fb *fb) | |||
80 | /* | 80 | /* |
81 | * Disable CLCD clock source. | 81 | * Disable CLCD clock source. |
82 | */ | 82 | */ |
83 | clk_disable(fb->clk); | 83 | if (fb->clk_enabled) { |
84 | fb->clk_enabled = false; | ||
85 | clk_disable(fb->clk); | ||
86 | } | ||
84 | } | 87 | } |
85 | 88 | ||
86 | static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) | 89 | static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) |
@@ -88,7 +91,10 @@ static void clcdfb_enable(struct clcd_fb *fb, u32 cntl) | |||
88 | /* | 91 | /* |
89 | * Enable the CLCD clock source. | 92 | * Enable the CLCD clock source. |
90 | */ | 93 | */ |
91 | clk_enable(fb->clk); | 94 | if (!fb->clk_enabled) { |
95 | fb->clk_enabled = true; | ||
96 | clk_enable(fb->clk); | ||
97 | } | ||
92 | 98 | ||
93 | /* | 99 | /* |
94 | * Bring up by first enabling.. | 100 | * Bring up by first enabling.. |
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index f3a4e15672d9..f96a471cb1a8 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h | |||
@@ -151,13 +151,13 @@ static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) { | |||
151 | static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) { | 151 | static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) { |
152 | #if defined(__alpha__) || defined(__i386__) || defined(__x86_64__) | 152 | #if defined(__alpha__) || defined(__i386__) || defined(__x86_64__) |
153 | /* | 153 | /* |
154 | * memcpy_toio works for us if: | 154 | * iowrite32_rep works for us if: |
155 | * (1) Copies data as 32bit quantities, not byte after byte, | 155 | * (1) Copies data as 32bit quantities, not byte after byte, |
156 | * (2) Performs LE ordered stores, and | 156 | * (2) Performs LE ordered stores, and |
157 | * (3) It copes with unaligned source (destination is guaranteed to be page | 157 | * (3) It copes with unaligned source (destination is guaranteed to be page |
158 | * aligned and length is guaranteed to be multiple of 4). | 158 | * aligned and length is guaranteed to be multiple of 4). |
159 | */ | 159 | */ |
160 | memcpy_toio(va.vaddr, src, len); | 160 | iowrite32_rep(va.vaddr, src, len >> 2); |
161 | #else | 161 | #else |
162 | u_int32_t __iomem* addr = va.vaddr; | 162 | u_int32_t __iomem* addr = va.vaddr; |
163 | 163 | ||
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 72f91bff29c7..13365ba35218 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -112,6 +112,7 @@ static inline unsigned long *cpu_evtchn_mask(int cpu) | |||
112 | #define VALID_EVTCHN(chn) ((chn) != 0) | 112 | #define VALID_EVTCHN(chn) ((chn) != 0) |
113 | 113 | ||
114 | static struct irq_chip xen_dynamic_chip; | 114 | static struct irq_chip xen_dynamic_chip; |
115 | static struct irq_chip xen_percpu_chip; | ||
115 | 116 | ||
116 | /* Constructor for packed IRQ information. */ | 117 | /* Constructor for packed IRQ information. */ |
117 | static struct irq_info mk_unbound_info(void) | 118 | static struct irq_info mk_unbound_info(void) |
@@ -377,7 +378,7 @@ int bind_evtchn_to_irq(unsigned int evtchn) | |||
377 | irq = find_unbound_irq(); | 378 | irq = find_unbound_irq(); |
378 | 379 | ||
379 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 380 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, |
380 | handle_level_irq, "event"); | 381 | handle_edge_irq, "event"); |
381 | 382 | ||
382 | evtchn_to_irq[evtchn] = irq; | 383 | evtchn_to_irq[evtchn] = irq; |
383 | irq_info[irq] = mk_evtchn_info(evtchn); | 384 | irq_info[irq] = mk_evtchn_info(evtchn); |
@@ -403,8 +404,8 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu) | |||
403 | if (irq < 0) | 404 | if (irq < 0) |
404 | goto out; | 405 | goto out; |
405 | 406 | ||
406 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 407 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
407 | handle_level_irq, "ipi"); | 408 | handle_percpu_irq, "ipi"); |
408 | 409 | ||
409 | bind_ipi.vcpu = cpu; | 410 | bind_ipi.vcpu = cpu; |
410 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, | 411 | if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_ipi, |
@@ -444,8 +445,8 @@ static int bind_virq_to_irq(unsigned int virq, unsigned int cpu) | |||
444 | 445 | ||
445 | irq = find_unbound_irq(); | 446 | irq = find_unbound_irq(); |
446 | 447 | ||
447 | set_irq_chip_and_handler_name(irq, &xen_dynamic_chip, | 448 | set_irq_chip_and_handler_name(irq, &xen_percpu_chip, |
448 | handle_level_irq, "virq"); | 449 | handle_percpu_irq, "virq"); |
449 | 450 | ||
450 | evtchn_to_irq[evtchn] = irq; | 451 | evtchn_to_irq[evtchn] = irq; |
451 | irq_info[irq] = mk_virq_info(evtchn, virq); | 452 | irq_info[irq] = mk_virq_info(evtchn, virq); |
@@ -964,6 +965,16 @@ static struct irq_chip xen_dynamic_chip __read_mostly = { | |||
964 | .retrigger = retrigger_dynirq, | 965 | .retrigger = retrigger_dynirq, |
965 | }; | 966 | }; |
966 | 967 | ||
968 | static struct irq_chip xen_percpu_chip __read_mostly = { | ||
969 | .name = "xen-percpu", | ||
970 | |||
971 | .disable = disable_dynirq, | ||
972 | .mask = disable_dynirq, | ||
973 | .unmask = enable_dynirq, | ||
974 | |||
975 | .ack = ack_dynirq, | ||
976 | }; | ||
977 | |||
967 | int xen_set_callback_via(uint64_t via) | 978 | int xen_set_callback_via(uint64_t via) |
968 | { | 979 | { |
969 | struct xen_hvm_param a; | 980 | struct xen_hvm_param a; |
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 1799bd890315..ef9c7db52077 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -237,7 +237,7 @@ static void sysrq_handler(struct xenbus_watch *watch, const char **vec, | |||
237 | goto again; | 237 | goto again; |
238 | 238 | ||
239 | if (sysrq_key != '\0') | 239 | if (sysrq_key != '\0') |
240 | handle_sysrq(sysrq_key, NULL); | 240 | handle_sysrq(sysrq_key); |
241 | } | 241 | } |
242 | 242 | ||
243 | static struct xenbus_watch sysrq_watch = { | 243 | static struct xenbus_watch sysrq_watch = { |