diff options
Diffstat (limited to 'drivers')
274 files changed, 2824 insertions, 2124 deletions
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b136c9c1e531..449c556274c0 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -943,6 +943,10 @@ static int acpi_bus_get_flags(struct acpi_device *device) | |||
943 | if (ACPI_SUCCESS(status)) | 943 | if (ACPI_SUCCESS(status)) |
944 | device->flags.lockable = 1; | 944 | device->flags.lockable = 1; |
945 | 945 | ||
946 | /* Power resources cannot be power manageable. */ | ||
947 | if (device->device_type == ACPI_BUS_TYPE_POWER) | ||
948 | return 0; | ||
949 | |||
946 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ | 950 | /* Presence of _PS0|_PR0 indicates 'power manageable' */ |
947 | status = acpi_get_handle(device->handle, "_PS0", &temp); | 951 | status = acpi_get_handle(device->handle, "_PS0", &temp); |
948 | if (ACPI_FAILURE(status)) | 952 | if (ACPI_FAILURE(status)) |
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 821040503154..7025593a58c8 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c | |||
@@ -214,7 +214,7 @@ static int amba_pm_resume_noirq(struct device *dev) | |||
214 | 214 | ||
215 | #endif /* !CONFIG_SUSPEND */ | 215 | #endif /* !CONFIG_SUSPEND */ |
216 | 216 | ||
217 | #ifdef CONFIG_HIBERNATION | 217 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
218 | 218 | ||
219 | static int amba_pm_freeze(struct device *dev) | 219 | static int amba_pm_freeze(struct device *dev) |
220 | { | 220 | { |
@@ -352,7 +352,7 @@ static int amba_pm_restore_noirq(struct device *dev) | |||
352 | return ret; | 352 | return ret; |
353 | } | 353 | } |
354 | 354 | ||
355 | #else /* !CONFIG_HIBERNATION */ | 355 | #else /* !CONFIG_HIBERNATE_CALLBACKS */ |
356 | 356 | ||
357 | #define amba_pm_freeze NULL | 357 | #define amba_pm_freeze NULL |
358 | #define amba_pm_thaw NULL | 358 | #define amba_pm_thaw NULL |
@@ -363,7 +363,7 @@ static int amba_pm_restore_noirq(struct device *dev) | |||
363 | #define amba_pm_poweroff_noirq NULL | 363 | #define amba_pm_poweroff_noirq NULL |
364 | #define amba_pm_restore_noirq NULL | 364 | #define amba_pm_restore_noirq NULL |
365 | 365 | ||
366 | #endif /* !CONFIG_HIBERNATION */ | 366 | #endif /* !CONFIG_HIBERNATE_CALLBACKS */ |
367 | 367 | ||
368 | #ifdef CONFIG_PM | 368 | #ifdef CONFIG_PM |
369 | 369 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 39d829cd82dd..71afe0371311 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -150,7 +150,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
150 | { | 150 | { |
151 | AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP | | 151 | AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP | |
152 | AHCI_HFLAG_YES_NCQ), | 152 | AHCI_HFLAG_YES_NCQ), |
153 | .flags = AHCI_FLAG_COMMON, | 153 | .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM, |
154 | .pio_mask = ATA_PIO4, | 154 | .pio_mask = ATA_PIO4, |
155 | .udma_mask = ATA_UDMA6, | 155 | .udma_mask = ATA_UDMA6, |
156 | .port_ops = &ahci_ops, | 156 | .port_ops = &ahci_ops, |
@@ -261,6 +261,12 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
261 | { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */ | 261 | { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */ |
262 | { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ | 262 | { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */ |
263 | { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ | 263 | { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */ |
264 | { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */ | ||
265 | { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */ | ||
266 | { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */ | ||
267 | { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */ | ||
268 | { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */ | ||
269 | { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */ | ||
264 | 270 | ||
265 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 271 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
266 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 272 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 39865009c251..12c5282e7fca 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h | |||
@@ -229,6 +229,10 @@ enum { | |||
229 | EM_CTL_ALHD = (1 << 26), /* Activity LED */ | 229 | EM_CTL_ALHD = (1 << 26), /* Activity LED */ |
230 | EM_CTL_XMT = (1 << 25), /* Transmit Only */ | 230 | EM_CTL_XMT = (1 << 25), /* Transmit Only */ |
231 | EM_CTL_SMB = (1 << 24), /* Single Message Buffer */ | 231 | EM_CTL_SMB = (1 << 24), /* Single Message Buffer */ |
232 | EM_CTL_SGPIO = (1 << 19), /* SGPIO messages supported */ | ||
233 | EM_CTL_SES = (1 << 18), /* SES-2 messages supported */ | ||
234 | EM_CTL_SAFTE = (1 << 17), /* SAF-TE messages supported */ | ||
235 | EM_CTL_LED = (1 << 16), /* LED messages supported */ | ||
232 | 236 | ||
233 | /* em message type */ | 237 | /* em message type */ |
234 | EM_MSG_TYPE_LED = (1 << 0), /* LED */ | 238 | EM_MSG_TYPE_LED = (1 << 0), /* LED */ |
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 0bc3fd6c3fdb..6f6e7718b05c 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -309,6 +309,14 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
309 | { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | 309 | { 0x8086, 0x1d00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, |
310 | /* SATA Controller IDE (PBG) */ | 310 | /* SATA Controller IDE (PBG) */ |
311 | { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | 311 | { 0x8086, 0x1d08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, |
312 | /* SATA Controller IDE (Panther Point) */ | ||
313 | { 0x8086, 0x1e00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | ||
314 | /* SATA Controller IDE (Panther Point) */ | ||
315 | { 0x8086, 0x1e01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata }, | ||
316 | /* SATA Controller IDE (Panther Point) */ | ||
317 | { 0x8086, 0x1e08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
318 | /* SATA Controller IDE (Panther Point) */ | ||
319 | { 0x8086, 0x1e09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata }, | ||
312 | { } /* terminate list */ | 320 | { } /* terminate list */ |
313 | }; | 321 | }; |
314 | 322 | ||
diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 26d452339e98..ff9d832a163d 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c | |||
@@ -109,6 +109,8 @@ static ssize_t ahci_read_em_buffer(struct device *dev, | |||
109 | static ssize_t ahci_store_em_buffer(struct device *dev, | 109 | static ssize_t ahci_store_em_buffer(struct device *dev, |
110 | struct device_attribute *attr, | 110 | struct device_attribute *attr, |
111 | const char *buf, size_t size); | 111 | const char *buf, size_t size); |
112 | static ssize_t ahci_show_em_supported(struct device *dev, | ||
113 | struct device_attribute *attr, char *buf); | ||
112 | 114 | ||
113 | static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); | 115 | static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL); |
114 | static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); | 116 | static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL); |
@@ -116,6 +118,7 @@ static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL); | |||
116 | static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); | 118 | static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL); |
117 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, | 119 | static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO, |
118 | ahci_read_em_buffer, ahci_store_em_buffer); | 120 | ahci_read_em_buffer, ahci_store_em_buffer); |
121 | static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL); | ||
119 | 122 | ||
120 | struct device_attribute *ahci_shost_attrs[] = { | 123 | struct device_attribute *ahci_shost_attrs[] = { |
121 | &dev_attr_link_power_management_policy, | 124 | &dev_attr_link_power_management_policy, |
@@ -126,6 +129,7 @@ struct device_attribute *ahci_shost_attrs[] = { | |||
126 | &dev_attr_ahci_host_version, | 129 | &dev_attr_ahci_host_version, |
127 | &dev_attr_ahci_port_cmd, | 130 | &dev_attr_ahci_port_cmd, |
128 | &dev_attr_em_buffer, | 131 | &dev_attr_em_buffer, |
132 | &dev_attr_em_message_supported, | ||
129 | NULL | 133 | NULL |
130 | }; | 134 | }; |
131 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); | 135 | EXPORT_SYMBOL_GPL(ahci_shost_attrs); |
@@ -343,6 +347,24 @@ static ssize_t ahci_store_em_buffer(struct device *dev, | |||
343 | return size; | 347 | return size; |
344 | } | 348 | } |
345 | 349 | ||
350 | static ssize_t ahci_show_em_supported(struct device *dev, | ||
351 | struct device_attribute *attr, char *buf) | ||
352 | { | ||
353 | struct Scsi_Host *shost = class_to_shost(dev); | ||
354 | struct ata_port *ap = ata_shost_to_port(shost); | ||
355 | struct ahci_host_priv *hpriv = ap->host->private_data; | ||
356 | void __iomem *mmio = hpriv->mmio; | ||
357 | u32 em_ctl; | ||
358 | |||
359 | em_ctl = readl(mmio + HOST_EM_CTL); | ||
360 | |||
361 | return sprintf(buf, "%s%s%s%s\n", | ||
362 | em_ctl & EM_CTL_LED ? "led " : "", | ||
363 | em_ctl & EM_CTL_SAFTE ? "saf-te " : "", | ||
364 | em_ctl & EM_CTL_SES ? "ses-2 " : "", | ||
365 | em_ctl & EM_CTL_SGPIO ? "sgpio " : ""); | ||
366 | } | ||
367 | |||
346 | /** | 368 | /** |
347 | * ahci_save_initial_config - Save and fixup initial config values | 369 | * ahci_save_initial_config - Save and fixup initial config values |
348 | * @dev: target AHCI device | 370 | * @dev: target AHCI device |
@@ -539,6 +561,27 @@ void ahci_start_engine(struct ata_port *ap) | |||
539 | { | 561 | { |
540 | void __iomem *port_mmio = ahci_port_base(ap); | 562 | void __iomem *port_mmio = ahci_port_base(ap); |
541 | u32 tmp; | 563 | u32 tmp; |
564 | u8 status; | ||
565 | |||
566 | status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
567 | |||
568 | /* | ||
569 | * At end of section 10.1 of AHCI spec (rev 1.3), it states | ||
570 | * Software shall not set PxCMD.ST to 1 until it is determined | ||
571 | * that a functoinal device is present on the port as determined by | ||
572 | * PxTFD.STS.BSY=0, PxTFD.STS.DRQ=0 and PxSSTS.DET=3h | ||
573 | * | ||
574 | * Even though most AHCI host controllers work without this check, | ||
575 | * specific controller will fail under this condition | ||
576 | */ | ||
577 | if (status & (ATA_BUSY | ATA_DRQ)) | ||
578 | return; | ||
579 | else { | ||
580 | ahci_scr_read(&ap->link, SCR_STATUS, &tmp); | ||
581 | |||
582 | if ((tmp & 0xf) != 0x3) | ||
583 | return; | ||
584 | } | ||
542 | 585 | ||
543 | /* start DMA */ | 586 | /* start DMA */ |
544 | tmp = readl(port_mmio + PORT_CMD); | 587 | tmp = readl(port_mmio + PORT_CMD); |
@@ -1897,7 +1940,17 @@ static void ahci_pmp_attach(struct ata_port *ap) | |||
1897 | ahci_enable_fbs(ap); | 1940 | ahci_enable_fbs(ap); |
1898 | 1941 | ||
1899 | pp->intr_mask |= PORT_IRQ_BAD_PMP; | 1942 | pp->intr_mask |= PORT_IRQ_BAD_PMP; |
1900 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | 1943 | |
1944 | /* | ||
1945 | * We must not change the port interrupt mask register if the | ||
1946 | * port is marked frozen, the value in pp->intr_mask will be | ||
1947 | * restored later when the port is thawed. | ||
1948 | * | ||
1949 | * Note that during initialization, the port is marked as | ||
1950 | * frozen since the irq handler is not yet registered. | ||
1951 | */ | ||
1952 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
1953 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
1901 | } | 1954 | } |
1902 | 1955 | ||
1903 | static void ahci_pmp_detach(struct ata_port *ap) | 1956 | static void ahci_pmp_detach(struct ata_port *ap) |
@@ -1913,7 +1966,10 @@ static void ahci_pmp_detach(struct ata_port *ap) | |||
1913 | writel(cmd, port_mmio + PORT_CMD); | 1966 | writel(cmd, port_mmio + PORT_CMD); |
1914 | 1967 | ||
1915 | pp->intr_mask &= ~PORT_IRQ_BAD_PMP; | 1968 | pp->intr_mask &= ~PORT_IRQ_BAD_PMP; |
1916 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | 1969 | |
1970 | /* see comment above in ahci_pmp_attach() */ | ||
1971 | if (!(ap->pflags & ATA_PFLAG_FROZEN)) | ||
1972 | writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK); | ||
1917 | } | 1973 | } |
1918 | 1974 | ||
1919 | int ahci_port_resume(struct ata_port *ap) | 1975 | int ahci_port_resume(struct ata_port *ap) |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 423c0a6952b2..76c3c15cb1e6 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4139,6 +4139,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { | |||
4139 | */ | 4139 | */ |
4140 | { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, | 4140 | { "PIONEER DVD-RW DVRTD08", "1.00", ATA_HORKAGE_NOSETXFER }, |
4141 | { "PIONEER DVD-RW DVR-212D", "1.28", ATA_HORKAGE_NOSETXFER }, | 4141 | { "PIONEER DVD-RW DVR-212D", "1.28", ATA_HORKAGE_NOSETXFER }, |
4142 | { "PIONEER DVD-RW DVR-216D", "1.08", ATA_HORKAGE_NOSETXFER }, | ||
4142 | 4143 | ||
4143 | /* End Marker */ | 4144 | /* End Marker */ |
4144 | { } | 4145 | { } |
@@ -5480,7 +5481,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) | |||
5480 | if (!ap) | 5481 | if (!ap) |
5481 | return NULL; | 5482 | return NULL; |
5482 | 5483 | ||
5483 | ap->pflags |= ATA_PFLAG_INITIALIZING; | 5484 | ap->pflags |= ATA_PFLAG_INITIALIZING | ATA_PFLAG_FROZEN; |
5484 | ap->lock = &host->lock; | 5485 | ap->lock = &host->lock; |
5485 | ap->print_id = -1; | 5486 | ap->print_id = -1; |
5486 | ap->host = host; | 5487 | ap->host = host; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 88cd22fa65cd..f26f2fe3480a 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -3316,6 +3316,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
3316 | struct ata_eh_context *ehc = &link->eh_context; | 3316 | struct ata_eh_context *ehc = &link->eh_context; |
3317 | struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; | 3317 | struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; |
3318 | enum ata_lpm_policy old_policy = link->lpm_policy; | 3318 | enum ata_lpm_policy old_policy = link->lpm_policy; |
3319 | bool no_dipm = ap->flags & ATA_FLAG_NO_DIPM; | ||
3319 | unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; | 3320 | unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; |
3320 | unsigned int err_mask; | 3321 | unsigned int err_mask; |
3321 | int rc; | 3322 | int rc; |
@@ -3332,7 +3333,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
3332 | */ | 3333 | */ |
3333 | ata_for_each_dev(dev, link, ENABLED) { | 3334 | ata_for_each_dev(dev, link, ENABLED) { |
3334 | bool hipm = ata_id_has_hipm(dev->id); | 3335 | bool hipm = ata_id_has_hipm(dev->id); |
3335 | bool dipm = ata_id_has_dipm(dev->id); | 3336 | bool dipm = ata_id_has_dipm(dev->id) && !no_dipm; |
3336 | 3337 | ||
3337 | /* find the first enabled and LPM enabled devices */ | 3338 | /* find the first enabled and LPM enabled devices */ |
3338 | if (!link_dev) | 3339 | if (!link_dev) |
@@ -3389,7 +3390,8 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
3389 | 3390 | ||
3390 | /* host config updated, enable DIPM if transitioning to MIN_POWER */ | 3391 | /* host config updated, enable DIPM if transitioning to MIN_POWER */ |
3391 | ata_for_each_dev(dev, link, ENABLED) { | 3392 | ata_for_each_dev(dev, link, ENABLED) { |
3392 | if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { | 3393 | if (policy == ATA_LPM_MIN_POWER && !no_dipm && |
3394 | ata_id_has_dipm(dev->id)) { | ||
3393 | err_mask = ata_dev_set_feature(dev, | 3395 | err_mask = ata_dev_set_feature(dev, |
3394 | SETFEATURES_SATA_ENABLE, SATA_DIPM); | 3396 | SETFEATURES_SATA_ENABLE, SATA_DIPM); |
3395 | if (err_mask && err_mask != AC_ERR_DEV) { | 3397 | if (err_mask && err_mask != AC_ERR_DEV) { |
diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index 0da0dcc7dd08..a5fdbdcb0faf 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c | |||
@@ -33,11 +33,12 @@ | |||
33 | 33 | ||
34 | 34 | ||
35 | #define DRV_NAME "pata_at91" | 35 | #define DRV_NAME "pata_at91" |
36 | #define DRV_VERSION "0.1" | 36 | #define DRV_VERSION "0.2" |
37 | 37 | ||
38 | #define CF_IDE_OFFSET 0x00c00000 | 38 | #define CF_IDE_OFFSET 0x00c00000 |
39 | #define CF_ALT_IDE_OFFSET 0x00e00000 | 39 | #define CF_ALT_IDE_OFFSET 0x00e00000 |
40 | #define CF_IDE_RES_SIZE 0x08 | 40 | #define CF_IDE_RES_SIZE 0x08 |
41 | #define NCS_RD_PULSE_LIMIT 0x3f /* maximal value for pulse bitfields */ | ||
41 | 42 | ||
42 | struct at91_ide_info { | 43 | struct at91_ide_info { |
43 | unsigned long mode; | 44 | unsigned long mode; |
@@ -49,8 +50,18 @@ struct at91_ide_info { | |||
49 | void __iomem *alt_addr; | 50 | void __iomem *alt_addr; |
50 | }; | 51 | }; |
51 | 52 | ||
52 | static const struct ata_timing initial_timing = | 53 | static const struct ata_timing initial_timing = { |
53 | {XFER_PIO_0, 70, 290, 240, 600, 165, 150, 600, 0}; | 54 | .mode = XFER_PIO_0, |
55 | .setup = 70, | ||
56 | .act8b = 290, | ||
57 | .rec8b = 240, | ||
58 | .cyc8b = 600, | ||
59 | .active = 165, | ||
60 | .recover = 150, | ||
61 | .dmack_hold = 0, | ||
62 | .cycle = 600, | ||
63 | .udma = 0 | ||
64 | }; | ||
54 | 65 | ||
55 | static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz) | 66 | static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz) |
56 | { | 67 | { |
@@ -109,6 +120,11 @@ static void set_smc_timing(struct device *dev, | |||
109 | /* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */ | 120 | /* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */ |
110 | ncs_read_setup = 1; | 121 | ncs_read_setup = 1; |
111 | ncs_read_pulse = read_cycle - 2; | 122 | ncs_read_pulse = read_cycle - 2; |
123 | if (ncs_read_pulse > NCS_RD_PULSE_LIMIT) { | ||
124 | ncs_read_pulse = NCS_RD_PULSE_LIMIT; | ||
125 | dev_warn(dev, "ncs_read_pulse limited to maximal value %lu\n", | ||
126 | ncs_read_pulse); | ||
127 | } | ||
112 | 128 | ||
113 | /* Write timings same as read timings */ | 129 | /* Write timings same as read timings */ |
114 | write_cycle = read_cycle; | 130 | write_cycle = read_cycle; |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f051cfff18af..9e0e4fc24c46 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -149,6 +149,7 @@ static void platform_device_release(struct device *dev) | |||
149 | 149 | ||
150 | of_device_node_put(&pa->pdev.dev); | 150 | of_device_node_put(&pa->pdev.dev); |
151 | kfree(pa->pdev.dev.platform_data); | 151 | kfree(pa->pdev.dev.platform_data); |
152 | kfree(pa->pdev.mfd_cell); | ||
152 | kfree(pa->pdev.resource); | 153 | kfree(pa->pdev.resource); |
153 | kfree(pa); | 154 | kfree(pa); |
154 | } | 155 | } |
@@ -771,7 +772,7 @@ int __weak platform_pm_resume_noirq(struct device *dev) | |||
771 | 772 | ||
772 | #endif /* !CONFIG_SUSPEND */ | 773 | #endif /* !CONFIG_SUSPEND */ |
773 | 774 | ||
774 | #ifdef CONFIG_HIBERNATION | 775 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
775 | 776 | ||
776 | static int platform_pm_freeze(struct device *dev) | 777 | static int platform_pm_freeze(struct device *dev) |
777 | { | 778 | { |
@@ -909,7 +910,7 @@ static int platform_pm_restore_noirq(struct device *dev) | |||
909 | return ret; | 910 | return ret; |
910 | } | 911 | } |
911 | 912 | ||
912 | #else /* !CONFIG_HIBERNATION */ | 913 | #else /* !CONFIG_HIBERNATE_CALLBACKS */ |
913 | 914 | ||
914 | #define platform_pm_freeze NULL | 915 | #define platform_pm_freeze NULL |
915 | #define platform_pm_thaw NULL | 916 | #define platform_pm_thaw NULL |
@@ -920,7 +921,7 @@ static int platform_pm_restore_noirq(struct device *dev) | |||
920 | #define platform_pm_poweroff_noirq NULL | 921 | #define platform_pm_poweroff_noirq NULL |
921 | #define platform_pm_restore_noirq NULL | 922 | #define platform_pm_restore_noirq NULL |
922 | 923 | ||
923 | #endif /* !CONFIG_HIBERNATION */ | 924 | #endif /* !CONFIG_HIBERNATE_CALLBACKS */ |
924 | 925 | ||
925 | #ifdef CONFIG_PM_RUNTIME | 926 | #ifdef CONFIG_PM_RUNTIME |
926 | 927 | ||
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 052dc53eef38..abe3ab709e87 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c | |||
@@ -63,6 +63,7 @@ void device_pm_init(struct device *dev) | |||
63 | dev->power.wakeup = NULL; | 63 | dev->power.wakeup = NULL; |
64 | spin_lock_init(&dev->power.lock); | 64 | spin_lock_init(&dev->power.lock); |
65 | pm_runtime_init(dev); | 65 | pm_runtime_init(dev); |
66 | INIT_LIST_HEAD(&dev->power.entry); | ||
66 | } | 67 | } |
67 | 68 | ||
68 | /** | 69 | /** |
@@ -233,7 +234,7 @@ static int pm_op(struct device *dev, | |||
233 | } | 234 | } |
234 | break; | 235 | break; |
235 | #endif /* CONFIG_SUSPEND */ | 236 | #endif /* CONFIG_SUSPEND */ |
236 | #ifdef CONFIG_HIBERNATION | 237 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
237 | case PM_EVENT_FREEZE: | 238 | case PM_EVENT_FREEZE: |
238 | case PM_EVENT_QUIESCE: | 239 | case PM_EVENT_QUIESCE: |
239 | if (ops->freeze) { | 240 | if (ops->freeze) { |
@@ -260,7 +261,7 @@ static int pm_op(struct device *dev, | |||
260 | suspend_report_result(ops->restore, error); | 261 | suspend_report_result(ops->restore, error); |
261 | } | 262 | } |
262 | break; | 263 | break; |
263 | #endif /* CONFIG_HIBERNATION */ | 264 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ |
264 | default: | 265 | default: |
265 | error = -EINVAL; | 266 | error = -EINVAL; |
266 | } | 267 | } |
@@ -308,7 +309,7 @@ static int pm_noirq_op(struct device *dev, | |||
308 | } | 309 | } |
309 | break; | 310 | break; |
310 | #endif /* CONFIG_SUSPEND */ | 311 | #endif /* CONFIG_SUSPEND */ |
311 | #ifdef CONFIG_HIBERNATION | 312 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
312 | case PM_EVENT_FREEZE: | 313 | case PM_EVENT_FREEZE: |
313 | case PM_EVENT_QUIESCE: | 314 | case PM_EVENT_QUIESCE: |
314 | if (ops->freeze_noirq) { | 315 | if (ops->freeze_noirq) { |
@@ -335,7 +336,7 @@ static int pm_noirq_op(struct device *dev, | |||
335 | suspend_report_result(ops->restore_noirq, error); | 336 | suspend_report_result(ops->restore_noirq, error); |
336 | } | 337 | } |
337 | break; | 338 | break; |
338 | #endif /* CONFIG_HIBERNATION */ | 339 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ |
339 | default: | 340 | default: |
340 | error = -EINVAL; | 341 | error = -EINVAL; |
341 | } | 342 | } |
diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 4573c83df6dd..abbbd33e8d8a 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c | |||
@@ -258,7 +258,7 @@ void device_set_wakeup_capable(struct device *dev, bool capable) | |||
258 | if (!!dev->power.can_wakeup == !!capable) | 258 | if (!!dev->power.can_wakeup == !!capable) |
259 | return; | 259 | return; |
260 | 260 | ||
261 | if (device_is_registered(dev)) { | 261 | if (device_is_registered(dev) && !list_empty(&dev->power.entry)) { |
262 | if (capable) { | 262 | if (capable) { |
263 | if (wakeup_sysfs_add(dev)) | 263 | if (wakeup_sysfs_add(dev)) |
264 | return; | 264 | return; |
diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c index 90af2943f9e4..c126db3cb7d1 100644 --- a/drivers/base/syscore.c +++ b/drivers/base/syscore.c | |||
@@ -73,6 +73,7 @@ int syscore_suspend(void) | |||
73 | 73 | ||
74 | return ret; | 74 | return ret; |
75 | } | 75 | } |
76 | EXPORT_SYMBOL_GPL(syscore_suspend); | ||
76 | 77 | ||
77 | /** | 78 | /** |
78 | * syscore_resume - Execute all the registered system core resume callbacks. | 79 | * syscore_resume - Execute all the registered system core resume callbacks. |
@@ -95,6 +96,7 @@ void syscore_resume(void) | |||
95 | "Interrupts enabled after %pF\n", ops->resume); | 96 | "Interrupts enabled after %pF\n", ops->resume); |
96 | } | 97 | } |
97 | } | 98 | } |
99 | EXPORT_SYMBOL_GPL(syscore_resume); | ||
98 | #endif /* CONFIG_PM_SLEEP */ | 100 | #endif /* CONFIG_PM_SLEEP */ |
99 | 101 | ||
100 | /** | 102 | /** |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 16dc3645291c..3e904717c1c0 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -777,9 +777,9 @@ static int rbd_do_request(struct request *rq, | |||
777 | ops, | 777 | ops, |
778 | false, | 778 | false, |
779 | GFP_NOIO, pages, bio); | 779 | GFP_NOIO, pages, bio); |
780 | if (IS_ERR(req)) { | 780 | if (!req) { |
781 | up_read(&header->snap_rwsem); | 781 | up_read(&header->snap_rwsem); |
782 | ret = PTR_ERR(req); | 782 | ret = -ENOMEM; |
783 | goto done_pages; | 783 | goto done_pages; |
784 | } | 784 | } |
785 | 785 | ||
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 012cba0d6d96..b072648dc3f6 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
@@ -115,6 +115,9 @@ static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages) | |||
115 | struct agp_memory *new; | 115 | struct agp_memory *new; |
116 | unsigned long alloc_size = num_agp_pages*sizeof(struct page *); | 116 | unsigned long alloc_size = num_agp_pages*sizeof(struct page *); |
117 | 117 | ||
118 | if (INT_MAX/sizeof(struct page *) < num_agp_pages) | ||
119 | return NULL; | ||
120 | |||
118 | new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL); | 121 | new = kzalloc(sizeof(struct agp_memory), GFP_KERNEL); |
119 | if (new == NULL) | 122 | if (new == NULL) |
120 | return NULL; | 123 | return NULL; |
@@ -234,11 +237,14 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, | |||
234 | int scratch_pages; | 237 | int scratch_pages; |
235 | struct agp_memory *new; | 238 | struct agp_memory *new; |
236 | size_t i; | 239 | size_t i; |
240 | int cur_memory; | ||
237 | 241 | ||
238 | if (!bridge) | 242 | if (!bridge) |
239 | return NULL; | 243 | return NULL; |
240 | 244 | ||
241 | if ((atomic_read(&bridge->current_memory_agp) + page_count) > bridge->max_memory_agp) | 245 | cur_memory = atomic_read(&bridge->current_memory_agp); |
246 | if ((cur_memory + page_count > bridge->max_memory_agp) || | ||
247 | (cur_memory + page_count < page_count)) | ||
242 | return NULL; | 248 | return NULL; |
243 | 249 | ||
244 | if (type >= AGP_USER_TYPES) { | 250 | if (type >= AGP_USER_TYPES) { |
@@ -1089,8 +1095,8 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type) | |||
1089 | return -EINVAL; | 1095 | return -EINVAL; |
1090 | } | 1096 | } |
1091 | 1097 | ||
1092 | /* AK: could wrap */ | 1098 | if (((pg_start + mem->page_count) > num_entries) || |
1093 | if ((pg_start + mem->page_count) > num_entries) | 1099 | ((pg_start + mem->page_count) < pg_start)) |
1094 | return -EINVAL; | 1100 | return -EINVAL; |
1095 | 1101 | ||
1096 | j = pg_start; | 1102 | j = pg_start; |
@@ -1124,7 +1130,7 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
1124 | { | 1130 | { |
1125 | size_t i; | 1131 | size_t i; |
1126 | struct agp_bridge_data *bridge; | 1132 | struct agp_bridge_data *bridge; |
1127 | int mask_type; | 1133 | int mask_type, num_entries; |
1128 | 1134 | ||
1129 | bridge = mem->bridge; | 1135 | bridge = mem->bridge; |
1130 | if (!bridge) | 1136 | if (!bridge) |
@@ -1136,6 +1142,11 @@ int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
1136 | if (type != mem->type) | 1142 | if (type != mem->type) |
1137 | return -EINVAL; | 1143 | return -EINVAL; |
1138 | 1144 | ||
1145 | num_entries = agp_num_entries(); | ||
1146 | if (((pg_start + mem->page_count) > num_entries) || | ||
1147 | ((pg_start + mem->page_count) < pg_start)) | ||
1148 | return -EINVAL; | ||
1149 | |||
1139 | mask_type = bridge->driver->agp_type_to_mask_type(bridge, type); | 1150 | mask_type = bridge->driver->agp_type_to_mask_type(bridge, type); |
1140 | if (mask_type != 0) { | 1151 | if (mask_type != 0) { |
1141 | /* The generic routines know nothing of memory types */ | 1152 | /* The generic routines know nothing of memory types */ |
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 84b164d1eb2b..838568a7dbf5 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c | |||
@@ -1280,18 +1280,7 @@ static void unplug_port(struct port *port) | |||
1280 | spin_lock_irq(&pdrvdata_lock); | 1280 | spin_lock_irq(&pdrvdata_lock); |
1281 | list_del(&port->cons.list); | 1281 | list_del(&port->cons.list); |
1282 | spin_unlock_irq(&pdrvdata_lock); | 1282 | spin_unlock_irq(&pdrvdata_lock); |
1283 | #if 0 | ||
1284 | /* | ||
1285 | * hvc_remove() not called as removing one hvc port | ||
1286 | * results in other hvc ports getting frozen. | ||
1287 | * | ||
1288 | * Once this is resolved in hvc, this functionality | ||
1289 | * will be enabled. Till that is done, the -EPIPE | ||
1290 | * return from get_chars() above will help | ||
1291 | * hvc_console.c to clean up on ports we remove here. | ||
1292 | */ | ||
1293 | hvc_remove(port->cons.hvc); | 1283 | hvc_remove(port->cons.hvc); |
1294 | #endif | ||
1295 | } | 1284 | } |
1296 | 1285 | ||
1297 | /* Remove unused data this port might have received. */ | 1286 | /* Remove unused data this port might have received. */ |
diff --git a/drivers/clk/clkdev.c b/drivers/clk/clkdev.c index 0fc0a79852de..6db161f64ae0 100644 --- a/drivers/clk/clkdev.c +++ b/drivers/clk/clkdev.c | |||
@@ -32,10 +32,9 @@ static DEFINE_MUTEX(clocks_mutex); | |||
32 | * Then we take the most specific entry - with the following | 32 | * Then we take the most specific entry - with the following |
33 | * order of precedence: dev+con > dev only > con only. | 33 | * order of precedence: dev+con > dev only > con only. |
34 | */ | 34 | */ |
35 | static struct clk *clk_find(const char *dev_id, const char *con_id) | 35 | static struct clk_lookup *clk_find(const char *dev_id, const char *con_id) |
36 | { | 36 | { |
37 | struct clk_lookup *p; | 37 | struct clk_lookup *p, *cl = NULL; |
38 | struct clk *clk = NULL; | ||
39 | int match, best = 0; | 38 | int match, best = 0; |
40 | 39 | ||
41 | list_for_each_entry(p, &clocks, node) { | 40 | list_for_each_entry(p, &clocks, node) { |
@@ -52,27 +51,27 @@ static struct clk *clk_find(const char *dev_id, const char *con_id) | |||
52 | } | 51 | } |
53 | 52 | ||
54 | if (match > best) { | 53 | if (match > best) { |
55 | clk = p->clk; | 54 | cl = p; |
56 | if (match != 3) | 55 | if (match != 3) |
57 | best = match; | 56 | best = match; |
58 | else | 57 | else |
59 | break; | 58 | break; |
60 | } | 59 | } |
61 | } | 60 | } |
62 | return clk; | 61 | return cl; |
63 | } | 62 | } |
64 | 63 | ||
65 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) | 64 | struct clk *clk_get_sys(const char *dev_id, const char *con_id) |
66 | { | 65 | { |
67 | struct clk *clk; | 66 | struct clk_lookup *cl; |
68 | 67 | ||
69 | mutex_lock(&clocks_mutex); | 68 | mutex_lock(&clocks_mutex); |
70 | clk = clk_find(dev_id, con_id); | 69 | cl = clk_find(dev_id, con_id); |
71 | if (clk && !__clk_get(clk)) | 70 | if (cl && !__clk_get(cl->clk)) |
72 | clk = NULL; | 71 | cl = NULL; |
73 | mutex_unlock(&clocks_mutex); | 72 | mutex_unlock(&clocks_mutex); |
74 | 73 | ||
75 | return clk ? clk : ERR_PTR(-ENOENT); | 74 | return cl ? cl->clk : ERR_PTR(-ENOENT); |
76 | } | 75 | } |
77 | EXPORT_SYMBOL(clk_get_sys); | 76 | EXPORT_SYMBOL(clk_get_sys); |
78 | 77 | ||
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 6b396759e7f5..8a781540590c 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -1448,7 +1448,7 @@ static const struct of_device_id fsldma_of_ids[] = { | |||
1448 | {} | 1448 | {} |
1449 | }; | 1449 | }; |
1450 | 1450 | ||
1451 | static struct of_platform_driver fsldma_of_driver = { | 1451 | static struct platform_driver fsldma_of_driver = { |
1452 | .driver = { | 1452 | .driver = { |
1453 | .name = "fsl-elo-dma", | 1453 | .name = "fsl-elo-dma", |
1454 | .owner = THIS_MODULE, | 1454 | .owner = THIS_MODULE, |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 31e71c4fc831..9a8bebcf6b17 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -211,8 +211,6 @@ static int amd64_get_scrub_rate(struct mem_ctl_info *mci) | |||
211 | 211 | ||
212 | scrubval = scrubval & 0x001F; | 212 | scrubval = scrubval & 0x001F; |
213 | 213 | ||
214 | amd64_debug("pci-read, sdram scrub control value: %d\n", scrubval); | ||
215 | |||
216 | for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { | 214 | for (i = 0; i < ARRAY_SIZE(scrubrates); i++) { |
217 | if (scrubrates[i].scrubval == scrubval) { | 215 | if (scrubrates[i].scrubval == scrubval) { |
218 | retval = scrubrates[i].bandwidth; | 216 | retval = scrubrates[i].bandwidth; |
@@ -933,25 +931,74 @@ static int k8_early_channel_count(struct amd64_pvt *pvt) | |||
933 | /* On F10h and later ErrAddr is MC4_ADDR[47:1] */ | 931 | /* On F10h and later ErrAddr is MC4_ADDR[47:1] */ |
934 | static u64 get_error_address(struct mce *m) | 932 | static u64 get_error_address(struct mce *m) |
935 | { | 933 | { |
934 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
935 | u64 addr; | ||
936 | u8 start_bit = 1; | 936 | u8 start_bit = 1; |
937 | u8 end_bit = 47; | 937 | u8 end_bit = 47; |
938 | 938 | ||
939 | if (boot_cpu_data.x86 == 0xf) { | 939 | if (c->x86 == 0xf) { |
940 | start_bit = 3; | 940 | start_bit = 3; |
941 | end_bit = 39; | 941 | end_bit = 39; |
942 | } | 942 | } |
943 | 943 | ||
944 | return m->addr & GENMASK(start_bit, end_bit); | 944 | addr = m->addr & GENMASK(start_bit, end_bit); |
945 | |||
946 | /* | ||
947 | * Erratum 637 workaround | ||
948 | */ | ||
949 | if (c->x86 == 0x15) { | ||
950 | struct amd64_pvt *pvt; | ||
951 | u64 cc6_base, tmp_addr; | ||
952 | u32 tmp; | ||
953 | u8 mce_nid, intlv_en; | ||
954 | |||
955 | if ((addr & GENMASK(24, 47)) >> 24 != 0x00fdf7) | ||
956 | return addr; | ||
957 | |||
958 | mce_nid = amd_get_nb_id(m->extcpu); | ||
959 | pvt = mcis[mce_nid]->pvt_info; | ||
960 | |||
961 | amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_LIM, &tmp); | ||
962 | intlv_en = tmp >> 21 & 0x7; | ||
963 | |||
964 | /* add [47:27] + 3 trailing bits */ | ||
965 | cc6_base = (tmp & GENMASK(0, 20)) << 3; | ||
966 | |||
967 | /* reverse and add DramIntlvEn */ | ||
968 | cc6_base |= intlv_en ^ 0x7; | ||
969 | |||
970 | /* pin at [47:24] */ | ||
971 | cc6_base <<= 24; | ||
972 | |||
973 | if (!intlv_en) | ||
974 | return cc6_base | (addr & GENMASK(0, 23)); | ||
975 | |||
976 | amd64_read_pci_cfg(pvt->F1, DRAM_LOCAL_NODE_BASE, &tmp); | ||
977 | |||
978 | /* faster log2 */ | ||
979 | tmp_addr = (addr & GENMASK(12, 23)) << __fls(intlv_en + 1); | ||
980 | |||
981 | /* OR DramIntlvSel into bits [14:12] */ | ||
982 | tmp_addr |= (tmp & GENMASK(21, 23)) >> 9; | ||
983 | |||
984 | /* add remaining [11:0] bits from original MC4_ADDR */ | ||
985 | tmp_addr |= addr & GENMASK(0, 11); | ||
986 | |||
987 | return cc6_base | tmp_addr; | ||
988 | } | ||
989 | |||
990 | return addr; | ||
945 | } | 991 | } |
946 | 992 | ||
947 | static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) | 993 | static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) |
948 | { | 994 | { |
995 | struct cpuinfo_x86 *c = &boot_cpu_data; | ||
949 | int off = range << 3; | 996 | int off = range << 3; |
950 | 997 | ||
951 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo); | 998 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_LO + off, &pvt->ranges[range].base.lo); |
952 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo); | 999 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_LO + off, &pvt->ranges[range].lim.lo); |
953 | 1000 | ||
954 | if (boot_cpu_data.x86 == 0xf) | 1001 | if (c->x86 == 0xf) |
955 | return; | 1002 | return; |
956 | 1003 | ||
957 | if (!dram_rw(pvt, range)) | 1004 | if (!dram_rw(pvt, range)) |
@@ -959,6 +1006,31 @@ static void read_dram_base_limit_regs(struct amd64_pvt *pvt, unsigned range) | |||
959 | 1006 | ||
960 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi); | 1007 | amd64_read_pci_cfg(pvt->F1, DRAM_BASE_HI + off, &pvt->ranges[range].base.hi); |
961 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi); | 1008 | amd64_read_pci_cfg(pvt->F1, DRAM_LIMIT_HI + off, &pvt->ranges[range].lim.hi); |
1009 | |||
1010 | /* Factor in CC6 save area by reading dst node's limit reg */ | ||
1011 | if (c->x86 == 0x15) { | ||
1012 | struct pci_dev *f1 = NULL; | ||
1013 | u8 nid = dram_dst_node(pvt, range); | ||
1014 | u32 llim; | ||
1015 | |||
1016 | f1 = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x18 + nid, 1)); | ||
1017 | if (WARN_ON(!f1)) | ||
1018 | return; | ||
1019 | |||
1020 | amd64_read_pci_cfg(f1, DRAM_LOCAL_NODE_LIM, &llim); | ||
1021 | |||
1022 | pvt->ranges[range].lim.lo &= GENMASK(0, 15); | ||
1023 | |||
1024 | /* {[39:27],111b} */ | ||
1025 | pvt->ranges[range].lim.lo |= ((llim & 0x1fff) << 3 | 0x7) << 16; | ||
1026 | |||
1027 | pvt->ranges[range].lim.hi &= GENMASK(0, 7); | ||
1028 | |||
1029 | /* [47:40] */ | ||
1030 | pvt->ranges[range].lim.hi |= llim >> 13; | ||
1031 | |||
1032 | pci_dev_put(f1); | ||
1033 | } | ||
962 | } | 1034 | } |
963 | 1035 | ||
964 | static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, | 1036 | static void k8_map_sysaddr_to_csrow(struct mem_ctl_info *mci, u64 sys_addr, |
@@ -1403,12 +1475,8 @@ static int f1x_match_to_this_node(struct amd64_pvt *pvt, unsigned range, | |||
1403 | return -EINVAL; | 1475 | return -EINVAL; |
1404 | } | 1476 | } |
1405 | 1477 | ||
1406 | if (intlv_en && | 1478 | if (intlv_en && (intlv_sel != ((sys_addr >> 12) & intlv_en))) |
1407 | (intlv_sel != ((sys_addr >> 12) & intlv_en))) { | ||
1408 | amd64_warn("Botched intlv bits, en: 0x%x, sel: 0x%x\n", | ||
1409 | intlv_en, intlv_sel); | ||
1410 | return -EINVAL; | 1479 | return -EINVAL; |
1411 | } | ||
1412 | 1480 | ||
1413 | sys_addr = f1x_swap_interleaved_region(pvt, sys_addr); | 1481 | sys_addr = f1x_swap_interleaved_region(pvt, sys_addr); |
1414 | 1482 | ||
diff --git a/drivers/edac/amd64_edac.h b/drivers/edac/amd64_edac.h index 11be36a311eb..9a666cb985b2 100644 --- a/drivers/edac/amd64_edac.h +++ b/drivers/edac/amd64_edac.h | |||
@@ -196,6 +196,9 @@ | |||
196 | 196 | ||
197 | #define DCT_CFG_SEL 0x10C | 197 | #define DCT_CFG_SEL 0x10C |
198 | 198 | ||
199 | #define DRAM_LOCAL_NODE_BASE 0x120 | ||
200 | #define DRAM_LOCAL_NODE_LIM 0x124 | ||
201 | |||
199 | #define DRAM_BASE_HI 0x140 | 202 | #define DRAM_BASE_HI 0x140 |
200 | #define DRAM_LIMIT_HI 0x144 | 203 | #define DRAM_LIMIT_HI 0x144 |
201 | 204 | ||
diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 26343fd46596..29ffa350bfbe 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c | |||
@@ -458,13 +458,13 @@ static ssize_t mci_sdram_scrub_rate_store(struct mem_ctl_info *mci, | |||
458 | return -EINVAL; | 458 | return -EINVAL; |
459 | 459 | ||
460 | new_bw = mci->set_sdram_scrub_rate(mci, bandwidth); | 460 | new_bw = mci->set_sdram_scrub_rate(mci, bandwidth); |
461 | if (new_bw >= 0) { | 461 | if (new_bw < 0) { |
462 | edac_printk(KERN_DEBUG, EDAC_MC, "Scrub rate set to %d\n", new_bw); | 462 | edac_printk(KERN_WARNING, EDAC_MC, |
463 | return count; | 463 | "Error setting scrub rate to: %lu\n", bandwidth); |
464 | return -EINVAL; | ||
464 | } | 465 | } |
465 | 466 | ||
466 | edac_printk(KERN_DEBUG, EDAC_MC, "Error setting scrub rate to: %lu\n", bandwidth); | 467 | return count; |
467 | return -EINVAL; | ||
468 | } | 468 | } |
469 | 469 | ||
470 | /* | 470 | /* |
@@ -483,7 +483,6 @@ static ssize_t mci_sdram_scrub_rate_show(struct mem_ctl_info *mci, char *data) | |||
483 | return bandwidth; | 483 | return bandwidth; |
484 | } | 484 | } |
485 | 485 | ||
486 | edac_printk(KERN_DEBUG, EDAC_MC, "Read scrub rate: %d\n", bandwidth); | ||
487 | return sprintf(data, "%d\n", bandwidth); | 486 | return sprintf(data, "%d\n", bandwidth); |
488 | } | 487 | } |
489 | 488 | ||
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index f903d7b6f34a..23d1468ad253 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -2199,7 +2199,6 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
2199 | { | 2199 | { |
2200 | struct fw_ohci *ohci; | 2200 | struct fw_ohci *ohci; |
2201 | unsigned long flags; | 2201 | unsigned long flags; |
2202 | int ret = -EBUSY; | ||
2203 | __be32 *next_config_rom; | 2202 | __be32 *next_config_rom; |
2204 | dma_addr_t uninitialized_var(next_config_rom_bus); | 2203 | dma_addr_t uninitialized_var(next_config_rom_bus); |
2205 | 2204 | ||
@@ -2240,22 +2239,37 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
2240 | 2239 | ||
2241 | spin_lock_irqsave(&ohci->lock, flags); | 2240 | spin_lock_irqsave(&ohci->lock, flags); |
2242 | 2241 | ||
2242 | /* | ||
2243 | * If there is not an already pending config_rom update, | ||
2244 | * push our new allocation into the ohci->next_config_rom | ||
2245 | * and then mark the local variable as null so that we | ||
2246 | * won't deallocate the new buffer. | ||
2247 | * | ||
2248 | * OTOH, if there is a pending config_rom update, just | ||
2249 | * use that buffer with the new config_rom data, and | ||
2250 | * let this routine free the unused DMA allocation. | ||
2251 | */ | ||
2252 | |||
2243 | if (ohci->next_config_rom == NULL) { | 2253 | if (ohci->next_config_rom == NULL) { |
2244 | ohci->next_config_rom = next_config_rom; | 2254 | ohci->next_config_rom = next_config_rom; |
2245 | ohci->next_config_rom_bus = next_config_rom_bus; | 2255 | ohci->next_config_rom_bus = next_config_rom_bus; |
2256 | next_config_rom = NULL; | ||
2257 | } | ||
2246 | 2258 | ||
2247 | copy_config_rom(ohci->next_config_rom, config_rom, length); | 2259 | copy_config_rom(ohci->next_config_rom, config_rom, length); |
2248 | 2260 | ||
2249 | ohci->next_header = config_rom[0]; | 2261 | ohci->next_header = config_rom[0]; |
2250 | ohci->next_config_rom[0] = 0; | 2262 | ohci->next_config_rom[0] = 0; |
2251 | 2263 | ||
2252 | reg_write(ohci, OHCI1394_ConfigROMmap, | 2264 | reg_write(ohci, OHCI1394_ConfigROMmap, ohci->next_config_rom_bus); |
2253 | ohci->next_config_rom_bus); | ||
2254 | ret = 0; | ||
2255 | } | ||
2256 | 2265 | ||
2257 | spin_unlock_irqrestore(&ohci->lock, flags); | 2266 | spin_unlock_irqrestore(&ohci->lock, flags); |
2258 | 2267 | ||
2268 | /* If we didn't use the DMA allocation, delete it. */ | ||
2269 | if (next_config_rom != NULL) | ||
2270 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | ||
2271 | next_config_rom, next_config_rom_bus); | ||
2272 | |||
2259 | /* | 2273 | /* |
2260 | * Now initiate a bus reset to have the changes take | 2274 | * Now initiate a bus reset to have the changes take |
2261 | * effect. We clean up the old config rom memory and DMA | 2275 | * effect. We clean up the old config rom memory and DMA |
@@ -2263,13 +2277,10 @@ static int ohci_set_config_rom(struct fw_card *card, | |||
2263 | * controller could need to access it before the bus reset | 2277 | * controller could need to access it before the bus reset |
2264 | * takes effect. | 2278 | * takes effect. |
2265 | */ | 2279 | */ |
2266 | if (ret == 0) | ||
2267 | fw_schedule_bus_reset(&ohci->card, true, true); | ||
2268 | else | ||
2269 | dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, | ||
2270 | next_config_rom, next_config_rom_bus); | ||
2271 | 2280 | ||
2272 | return ret; | 2281 | fw_schedule_bus_reset(&ohci->card, true, true); |
2282 | |||
2283 | return 0; | ||
2273 | } | 2284 | } |
2274 | 2285 | ||
2275 | static void ohci_send_request(struct fw_card *card, struct fw_packet *packet) | 2286 | static void ohci_send_request(struct fw_card *card, struct fw_packet *packet) |
diff --git a/drivers/gpio/ml_ioh_gpio.c b/drivers/gpio/ml_ioh_gpio.c index 7f6f01a4b145..0a775f7987c2 100644 --- a/drivers/gpio/ml_ioh_gpio.c +++ b/drivers/gpio/ml_ioh_gpio.c | |||
@@ -116,6 +116,7 @@ static int ioh_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | |||
116 | reg_val |= (1 << nr); | 116 | reg_val |= (1 << nr); |
117 | else | 117 | else |
118 | reg_val &= ~(1 << nr); | 118 | reg_val &= ~(1 << nr); |
119 | iowrite32(reg_val, &chip->reg->regs[chip->ch].po); | ||
119 | 120 | ||
120 | mutex_unlock(&chip->lock); | 121 | mutex_unlock(&chip->lock); |
121 | 122 | ||
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c index 583e92592073..7630ab7b9bec 100644 --- a/drivers/gpio/pca953x.c +++ b/drivers/gpio/pca953x.c | |||
@@ -558,7 +558,7 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
558 | 558 | ||
559 | ret = gpiochip_add(&chip->gpio_chip); | 559 | ret = gpiochip_add(&chip->gpio_chip); |
560 | if (ret) | 560 | if (ret) |
561 | goto out_failed; | 561 | goto out_failed_irq; |
562 | 562 | ||
563 | if (pdata->setup) { | 563 | if (pdata->setup) { |
564 | ret = pdata->setup(client, chip->gpio_chip.base, | 564 | ret = pdata->setup(client, chip->gpio_chip.base, |
@@ -570,8 +570,9 @@ static int __devinit pca953x_probe(struct i2c_client *client, | |||
570 | i2c_set_clientdata(client, chip); | 570 | i2c_set_clientdata(client, chip); |
571 | return 0; | 571 | return 0; |
572 | 572 | ||
573 | out_failed: | 573 | out_failed_irq: |
574 | pca953x_irq_teardown(chip); | 574 | pca953x_irq_teardown(chip); |
575 | out_failed: | ||
575 | kfree(chip->dyn_pdata); | 576 | kfree(chip->dyn_pdata); |
576 | kfree(chip); | 577 | kfree(chip); |
577 | return ret; | 578 | return ret; |
diff --git a/drivers/gpio/pch_gpio.c b/drivers/gpio/pch_gpio.c index 2c6af8705103..f970a5f3585e 100644 --- a/drivers/gpio/pch_gpio.c +++ b/drivers/gpio/pch_gpio.c | |||
@@ -105,6 +105,7 @@ static int pch_gpio_direction_output(struct gpio_chip *gpio, unsigned nr, | |||
105 | reg_val |= (1 << nr); | 105 | reg_val |= (1 << nr); |
106 | else | 106 | else |
107 | reg_val &= ~(1 << nr); | 107 | reg_val &= ~(1 << nr); |
108 | iowrite32(reg_val, &chip->reg->po); | ||
108 | 109 | ||
109 | mutex_unlock(&chip->lock); | 110 | mutex_unlock(&chip->lock); |
110 | 111 | ||
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index a6feb78c404c..b493663c7ba7 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -24,6 +24,7 @@ config DRM_KMS_HELPER | |||
24 | depends on DRM | 24 | depends on DRM |
25 | select FB | 25 | select FB |
26 | select FRAMEBUFFER_CONSOLE if !EXPERT | 26 | select FRAMEBUFFER_CONSOLE if !EXPERT |
27 | select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE | ||
27 | help | 28 | help |
28 | FB and CRTC helpers for KMS drivers. | 29 | FB and CRTC helpers for KMS drivers. |
29 | 30 | ||
@@ -96,6 +97,7 @@ config DRM_I915 | |||
96 | # i915 depends on ACPI_VIDEO when ACPI is enabled | 97 | # i915 depends on ACPI_VIDEO when ACPI is enabled |
97 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | 98 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick |
98 | select BACKLIGHT_CLASS_DEVICE if ACPI | 99 | select BACKLIGHT_CLASS_DEVICE if ACPI |
100 | select VIDEO_OUTPUT_CONTROL if ACPI | ||
99 | select INPUT if ACPI | 101 | select INPUT if ACPI |
100 | select ACPI_VIDEO if ACPI | 102 | select ACPI_VIDEO if ACPI |
101 | select ACPI_BUTTON if ACPI | 103 | select ACPI_BUTTON if ACPI |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 950720473967..11d7a72c22d9 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -342,9 +342,22 @@ int drm_fb_helper_debug_leave(struct fb_info *info) | |||
342 | } | 342 | } |
343 | EXPORT_SYMBOL(drm_fb_helper_debug_leave); | 343 | EXPORT_SYMBOL(drm_fb_helper_debug_leave); |
344 | 344 | ||
345 | bool drm_fb_helper_restore_fbdev_mode(struct drm_fb_helper *fb_helper) | ||
346 | { | ||
347 | bool error = false; | ||
348 | int i, ret; | ||
349 | for (i = 0; i < fb_helper->crtc_count; i++) { | ||
350 | struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set; | ||
351 | ret = drm_crtc_helper_set_config(mode_set); | ||
352 | if (ret) | ||
353 | error = true; | ||
354 | } | ||
355 | return error; | ||
356 | } | ||
357 | EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode); | ||
358 | |||
345 | bool drm_fb_helper_force_kernel_mode(void) | 359 | bool drm_fb_helper_force_kernel_mode(void) |
346 | { | 360 | { |
347 | int i = 0; | ||
348 | bool ret, error = false; | 361 | bool ret, error = false; |
349 | struct drm_fb_helper *helper; | 362 | struct drm_fb_helper *helper; |
350 | 363 | ||
@@ -352,12 +365,12 @@ bool drm_fb_helper_force_kernel_mode(void) | |||
352 | return false; | 365 | return false; |
353 | 366 | ||
354 | list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { | 367 | list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) { |
355 | for (i = 0; i < helper->crtc_count; i++) { | 368 | if (helper->dev->switch_power_state == DRM_SWITCH_POWER_OFF) |
356 | struct drm_mode_set *mode_set = &helper->crtc_info[i].mode_set; | 369 | continue; |
357 | ret = drm_crtc_helper_set_config(mode_set); | 370 | |
358 | if (ret) | 371 | ret = drm_fb_helper_restore_fbdev_mode(helper); |
359 | error = true; | 372 | if (ret) |
360 | } | 373 | error = true; |
361 | } | 374 | } |
362 | return error; | 375 | return error; |
363 | } | 376 | } |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 741457bd1c46..a1f12cb043de 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -932,11 +932,34 @@ EXPORT_SYMBOL(drm_vblank_put); | |||
932 | 932 | ||
933 | void drm_vblank_off(struct drm_device *dev, int crtc) | 933 | void drm_vblank_off(struct drm_device *dev, int crtc) |
934 | { | 934 | { |
935 | struct drm_pending_vblank_event *e, *t; | ||
936 | struct timeval now; | ||
935 | unsigned long irqflags; | 937 | unsigned long irqflags; |
938 | unsigned int seq; | ||
936 | 939 | ||
937 | spin_lock_irqsave(&dev->vbl_lock, irqflags); | 940 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
938 | vblank_disable_and_save(dev, crtc); | 941 | vblank_disable_and_save(dev, crtc); |
939 | DRM_WAKEUP(&dev->vbl_queue[crtc]); | 942 | DRM_WAKEUP(&dev->vbl_queue[crtc]); |
943 | |||
944 | /* Send any queued vblank events, lest the natives grow disquiet */ | ||
945 | seq = drm_vblank_count_and_time(dev, crtc, &now); | ||
946 | list_for_each_entry_safe(e, t, &dev->vblank_event_list, base.link) { | ||
947 | if (e->pipe != crtc) | ||
948 | continue; | ||
949 | DRM_DEBUG("Sending premature vblank event on disable: \ | ||
950 | wanted %d, current %d\n", | ||
951 | e->event.sequence, seq); | ||
952 | |||
953 | e->event.sequence = seq; | ||
954 | e->event.tv_sec = now.tv_sec; | ||
955 | e->event.tv_usec = now.tv_usec; | ||
956 | drm_vblank_put(dev, e->pipe); | ||
957 | list_move_tail(&e->base.link, &e->base.file_priv->event_list); | ||
958 | wake_up_interruptible(&e->base.file_priv->event_wait); | ||
959 | trace_drm_vblank_event_delivered(e->base.pid, e->pipe, | ||
960 | e->event.sequence); | ||
961 | } | ||
962 | |||
940 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); | 963 | spin_unlock_irqrestore(&dev->vbl_lock, irqflags); |
941 | } | 964 | } |
942 | EXPORT_SYMBOL(drm_vblank_off); | 965 | EXPORT_SYMBOL(drm_vblank_off); |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 5d00b0fc0d91..959186cbf328 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -431,7 +431,7 @@ EXPORT_SYMBOL(drm_mm_search_free_in_range); | |||
431 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) | 431 | void drm_mm_replace_node(struct drm_mm_node *old, struct drm_mm_node *new) |
432 | { | 432 | { |
433 | list_replace(&old->node_list, &new->node_list); | 433 | list_replace(&old->node_list, &new->node_list); |
434 | list_replace(&old->node_list, &new->hole_stack); | 434 | list_replace(&old->hole_stack, &new->hole_stack); |
435 | new->hole_follows = old->hole_follows; | 435 | new->hole_follows = old->hole_follows; |
436 | new->mm = old->mm; | 436 | new->mm = old->mm; |
437 | new->start = old->start; | 437 | new->start = old->start; |
@@ -699,8 +699,8 @@ int drm_mm_dump_table(struct seq_file *m, struct drm_mm *mm) | |||
699 | entry->size); | 699 | entry->size); |
700 | total_used += entry->size; | 700 | total_used += entry->size; |
701 | if (entry->hole_follows) { | 701 | if (entry->hole_follows) { |
702 | hole_start = drm_mm_hole_node_start(&mm->head_node); | 702 | hole_start = drm_mm_hole_node_start(entry); |
703 | hole_end = drm_mm_hole_node_end(&mm->head_node); | 703 | hole_end = drm_mm_hole_node_end(entry); |
704 | hole_size = hole_end - hole_start; | 704 | hole_size = hole_end - hole_start; |
705 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", | 705 | seq_printf(m, "0x%08lx-0x%08lx: 0x%08lx: free\n", |
706 | hole_start, hole_end, hole_size); | 706 | hole_start, hole_end, hole_size); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 72730377a01b..12876f2795d2 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -2207,7 +2207,7 @@ void i915_driver_lastclose(struct drm_device * dev) | |||
2207 | drm_i915_private_t *dev_priv = dev->dev_private; | 2207 | drm_i915_private_t *dev_priv = dev->dev_private; |
2208 | 2208 | ||
2209 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { | 2209 | if (!dev_priv || drm_core_check_feature(dev, DRIVER_MODESET)) { |
2210 | drm_fb_helper_restore(); | 2210 | intel_fb_restore_mode(dev); |
2211 | vga_switcheroo_process_delayed_switch(); | 2211 | vga_switcheroo_process_delayed_switch(); |
2212 | return; | 2212 | return; |
2213 | } | 2213 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 432fc04c6bff..373c2a005ec1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -3771,8 +3771,11 @@ static bool g4x_compute_wm0(struct drm_device *dev, | |||
3771 | int entries, tlb_miss; | 3771 | int entries, tlb_miss; |
3772 | 3772 | ||
3773 | crtc = intel_get_crtc_for_plane(dev, plane); | 3773 | crtc = intel_get_crtc_for_plane(dev, plane); |
3774 | if (crtc->fb == NULL || !crtc->enabled) | 3774 | if (crtc->fb == NULL || !crtc->enabled) { |
3775 | *cursor_wm = cursor->guard_size; | ||
3776 | *plane_wm = display->guard_size; | ||
3775 | return false; | 3777 | return false; |
3778 | } | ||
3776 | 3779 | ||
3777 | htotal = crtc->mode.htotal; | 3780 | htotal = crtc->mode.htotal; |
3778 | hdisplay = crtc->mode.hdisplay; | 3781 | hdisplay = crtc->mode.hdisplay; |
@@ -5151,8 +5154,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
5151 | 5154 | ||
5152 | I915_WRITE(DSPCNTR(plane), dspcntr); | 5155 | I915_WRITE(DSPCNTR(plane), dspcntr); |
5153 | POSTING_READ(DSPCNTR(plane)); | 5156 | POSTING_READ(DSPCNTR(plane)); |
5154 | if (!HAS_PCH_SPLIT(dev)) | ||
5155 | intel_enable_plane(dev_priv, plane, pipe); | ||
5156 | 5157 | ||
5157 | ret = intel_pipe_set_base(crtc, x, y, old_fb); | 5158 | ret = intel_pipe_set_base(crtc, x, y, old_fb); |
5158 | 5159 | ||
@@ -5602,9 +5603,9 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc) | |||
5602 | intel_clock_t clock; | 5603 | intel_clock_t clock; |
5603 | 5604 | ||
5604 | if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) | 5605 | if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) |
5605 | fp = FP0(pipe); | 5606 | fp = I915_READ(FP0(pipe)); |
5606 | else | 5607 | else |
5607 | fp = FP1(pipe); | 5608 | fp = I915_READ(FP1(pipe)); |
5608 | 5609 | ||
5609 | clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; | 5610 | clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; |
5610 | if (IS_PINEVIEW(dev)) { | 5611 | if (IS_PINEVIEW(dev)) { |
@@ -6215,36 +6216,6 @@ cleanup_work: | |||
6215 | return ret; | 6216 | return ret; |
6216 | } | 6217 | } |
6217 | 6218 | ||
6218 | static void intel_crtc_reset(struct drm_crtc *crtc) | ||
6219 | { | ||
6220 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6221 | |||
6222 | /* Reset flags back to the 'unknown' status so that they | ||
6223 | * will be correctly set on the initial modeset. | ||
6224 | */ | ||
6225 | intel_crtc->dpms_mode = -1; | ||
6226 | } | ||
6227 | |||
6228 | static struct drm_crtc_helper_funcs intel_helper_funcs = { | ||
6229 | .dpms = intel_crtc_dpms, | ||
6230 | .mode_fixup = intel_crtc_mode_fixup, | ||
6231 | .mode_set = intel_crtc_mode_set, | ||
6232 | .mode_set_base = intel_pipe_set_base, | ||
6233 | .mode_set_base_atomic = intel_pipe_set_base_atomic, | ||
6234 | .load_lut = intel_crtc_load_lut, | ||
6235 | .disable = intel_crtc_disable, | ||
6236 | }; | ||
6237 | |||
6238 | static const struct drm_crtc_funcs intel_crtc_funcs = { | ||
6239 | .reset = intel_crtc_reset, | ||
6240 | .cursor_set = intel_crtc_cursor_set, | ||
6241 | .cursor_move = intel_crtc_cursor_move, | ||
6242 | .gamma_set = intel_crtc_gamma_set, | ||
6243 | .set_config = drm_crtc_helper_set_config, | ||
6244 | .destroy = intel_crtc_destroy, | ||
6245 | .page_flip = intel_crtc_page_flip, | ||
6246 | }; | ||
6247 | |||
6248 | static void intel_sanitize_modesetting(struct drm_device *dev, | 6219 | static void intel_sanitize_modesetting(struct drm_device *dev, |
6249 | int pipe, int plane) | 6220 | int pipe, int plane) |
6250 | { | 6221 | { |
@@ -6281,6 +6252,42 @@ static void intel_sanitize_modesetting(struct drm_device *dev, | |||
6281 | intel_disable_pipe(dev_priv, pipe); | 6252 | intel_disable_pipe(dev_priv, pipe); |
6282 | } | 6253 | } |
6283 | 6254 | ||
6255 | static void intel_crtc_reset(struct drm_crtc *crtc) | ||
6256 | { | ||
6257 | struct drm_device *dev = crtc->dev; | ||
6258 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
6259 | |||
6260 | /* Reset flags back to the 'unknown' status so that they | ||
6261 | * will be correctly set on the initial modeset. | ||
6262 | */ | ||
6263 | intel_crtc->dpms_mode = -1; | ||
6264 | |||
6265 | /* We need to fix up any BIOS configuration that conflicts with | ||
6266 | * our expectations. | ||
6267 | */ | ||
6268 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
6269 | } | ||
6270 | |||
6271 | static struct drm_crtc_helper_funcs intel_helper_funcs = { | ||
6272 | .dpms = intel_crtc_dpms, | ||
6273 | .mode_fixup = intel_crtc_mode_fixup, | ||
6274 | .mode_set = intel_crtc_mode_set, | ||
6275 | .mode_set_base = intel_pipe_set_base, | ||
6276 | .mode_set_base_atomic = intel_pipe_set_base_atomic, | ||
6277 | .load_lut = intel_crtc_load_lut, | ||
6278 | .disable = intel_crtc_disable, | ||
6279 | }; | ||
6280 | |||
6281 | static const struct drm_crtc_funcs intel_crtc_funcs = { | ||
6282 | .reset = intel_crtc_reset, | ||
6283 | .cursor_set = intel_crtc_cursor_set, | ||
6284 | .cursor_move = intel_crtc_cursor_move, | ||
6285 | .gamma_set = intel_crtc_gamma_set, | ||
6286 | .set_config = drm_crtc_helper_set_config, | ||
6287 | .destroy = intel_crtc_destroy, | ||
6288 | .page_flip = intel_crtc_page_flip, | ||
6289 | }; | ||
6290 | |||
6284 | static void intel_crtc_init(struct drm_device *dev, int pipe) | 6291 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
6285 | { | 6292 | { |
6286 | drm_i915_private_t *dev_priv = dev->dev_private; | 6293 | drm_i915_private_t *dev_priv = dev->dev_private; |
@@ -6330,8 +6337,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
6330 | 6337 | ||
6331 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | 6338 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, |
6332 | (unsigned long)intel_crtc); | 6339 | (unsigned long)intel_crtc); |
6333 | |||
6334 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
6335 | } | 6340 | } |
6336 | 6341 | ||
6337 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 6342 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
@@ -6572,8 +6577,10 @@ intel_user_framebuffer_create(struct drm_device *dev, | |||
6572 | return ERR_PTR(-ENOENT); | 6577 | return ERR_PTR(-ENOENT); |
6573 | 6578 | ||
6574 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); | 6579 | intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL); |
6575 | if (!intel_fb) | 6580 | if (!intel_fb) { |
6581 | drm_gem_object_unreference_unlocked(&obj->base); | ||
6576 | return ERR_PTR(-ENOMEM); | 6582 | return ERR_PTR(-ENOMEM); |
6583 | } | ||
6577 | 6584 | ||
6578 | ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); | 6585 | ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); |
6579 | if (ret) { | 6586 | if (ret) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index cb8578b7e443..a4d80314e7f8 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1470,7 +1470,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1470 | 1470 | ||
1471 | if (!HAS_PCH_CPT(dev) && | 1471 | if (!HAS_PCH_CPT(dev) && |
1472 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | 1472 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { |
1473 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | 1473 | struct drm_crtc *crtc = intel_dp->base.base.crtc; |
1474 | |||
1474 | /* Hardware workaround: leaving our transcoder select | 1475 | /* Hardware workaround: leaving our transcoder select |
1475 | * set to transcoder B while it's off will prevent the | 1476 | * set to transcoder B while it's off will prevent the |
1476 | * corresponding HDMI output on transcoder A. | 1477 | * corresponding HDMI output on transcoder A. |
@@ -1485,7 +1486,19 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1485 | /* Changes to enable or select take place the vblank | 1486 | /* Changes to enable or select take place the vblank |
1486 | * after being written. | 1487 | * after being written. |
1487 | */ | 1488 | */ |
1488 | intel_wait_for_vblank(dev, intel_crtc->pipe); | 1489 | if (crtc == NULL) { |
1490 | /* We can arrive here never having been attached | ||
1491 | * to a CRTC, for instance, due to inheriting | ||
1492 | * random state from the BIOS. | ||
1493 | * | ||
1494 | * If the pipe is not running, play safe and | ||
1495 | * wait for the clocks to stabilise before | ||
1496 | * continuing. | ||
1497 | */ | ||
1498 | POSTING_READ(intel_dp->output_reg); | ||
1499 | msleep(50); | ||
1500 | } else | ||
1501 | intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); | ||
1489 | } | 1502 | } |
1490 | 1503 | ||
1491 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); | 1504 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f5b0d8306d83..1d20712d527f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -338,4 +338,5 @@ extern int intel_overlay_attrs(struct drm_device *dev, void *data, | |||
338 | struct drm_file *file_priv); | 338 | struct drm_file *file_priv); |
339 | 339 | ||
340 | extern void intel_fb_output_poll_changed(struct drm_device *dev); | 340 | extern void intel_fb_output_poll_changed(struct drm_device *dev); |
341 | extern void intel_fb_restore_mode(struct drm_device *dev); | ||
341 | #endif /* __INTEL_DRV_H__ */ | 342 | #endif /* __INTEL_DRV_H__ */ |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 512782728e51..ec49bae73382 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -264,3 +264,13 @@ void intel_fb_output_poll_changed(struct drm_device *dev) | |||
264 | drm_i915_private_t *dev_priv = dev->dev_private; | 264 | drm_i915_private_t *dev_priv = dev->dev_private; |
265 | drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); | 265 | drm_fb_helper_hotplug_event(&dev_priv->fbdev->helper); |
266 | } | 266 | } |
267 | |||
268 | void intel_fb_restore_mode(struct drm_device *dev) | ||
269 | { | ||
270 | int ret; | ||
271 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
272 | |||
273 | ret = drm_fb_helper_restore_fbdev_mode(&dev_priv->fbdev->helper); | ||
274 | if (ret) | ||
275 | DRM_DEBUG("failed to restore crtc mode\n"); | ||
276 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index a562bd2648c7..67cb076d271b 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -539,6 +539,9 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
539 | struct drm_device *dev = dev_priv->dev; | 539 | struct drm_device *dev = dev_priv->dev; |
540 | struct drm_connector *connector = dev_priv->int_lvds_connector; | 540 | struct drm_connector *connector = dev_priv->int_lvds_connector; |
541 | 541 | ||
542 | if (dev->switch_power_state != DRM_SWITCH_POWER_ON) | ||
543 | return NOTIFY_OK; | ||
544 | |||
542 | /* | 545 | /* |
543 | * check and update the status of LVDS connector after receiving | 546 | * check and update the status of LVDS connector after receiving |
544 | * the LID nofication event. | 547 | * the LID nofication event. |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 4256b8ef3947..6b22c1dcc015 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
@@ -1151,10 +1151,10 @@ intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
1151 | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); | 1151 | (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); |
1152 | { | 1152 | { |
1153 | int pipeconf_reg = PIPECONF(pipe); | 1153 | int pipeconf_reg = PIPECONF(pipe); |
1154 | int dspcntr_reg = DSPCNTR(pipe); | 1154 | int dspcntr_reg = DSPCNTR(intel_crtc->plane); |
1155 | int pipeconf = I915_READ(pipeconf_reg); | 1155 | int pipeconf = I915_READ(pipeconf_reg); |
1156 | int dspcntr = I915_READ(dspcntr_reg); | 1156 | int dspcntr = I915_READ(dspcntr_reg); |
1157 | int dspbase_reg = DSPADDR(pipe); | 1157 | int dspbase_reg = DSPADDR(intel_crtc->plane); |
1158 | int xpos = 0x0, ypos = 0x0; | 1158 | int xpos = 0x0, ypos = 0x0; |
1159 | unsigned int xsize, ysize; | 1159 | unsigned int xsize, ysize; |
1160 | /* Pipe must be off here */ | 1160 | /* Pipe must be off here */ |
@@ -1378,7 +1378,9 @@ intel_tv_detect(struct drm_connector *connector, bool force) | |||
1378 | if (type < 0) | 1378 | if (type < 0) |
1379 | return connector_status_disconnected; | 1379 | return connector_status_disconnected; |
1380 | 1380 | ||
1381 | intel_tv->type = type; | ||
1381 | intel_tv_find_better_format(connector); | 1382 | intel_tv_find_better_format(connector); |
1383 | |||
1382 | return connector_status_connected; | 1384 | return connector_status_connected; |
1383 | } | 1385 | } |
1384 | 1386 | ||
@@ -1670,8 +1672,7 @@ intel_tv_init(struct drm_device *dev) | |||
1670 | * | 1672 | * |
1671 | * More recent chipsets favour HDMI rather than integrated S-Video. | 1673 | * More recent chipsets favour HDMI rather than integrated S-Video. |
1672 | */ | 1674 | */ |
1673 | connector->polled = | 1675 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; |
1674 | DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; | ||
1675 | 1676 | ||
1676 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, | 1677 | drm_connector_init(dev, connector, &intel_tv_connector_funcs, |
1677 | DRM_MODE_CONNECTOR_SVIDEO); | 1678 | DRM_MODE_CONNECTOR_SVIDEO); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 8314a49b6b9a..90aef64b76f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -269,7 +269,7 @@ struct init_tbl_entry { | |||
269 | int (*handler)(struct nvbios *, uint16_t, struct init_exec *); | 269 | int (*handler)(struct nvbios *, uint16_t, struct init_exec *); |
270 | }; | 270 | }; |
271 | 271 | ||
272 | static int parse_init_table(struct nvbios *, unsigned int, struct init_exec *); | 272 | static int parse_init_table(struct nvbios *, uint16_t, struct init_exec *); |
273 | 273 | ||
274 | #define MACRO_INDEX_SIZE 2 | 274 | #define MACRO_INDEX_SIZE 2 |
275 | #define MACRO_SIZE 8 | 275 | #define MACRO_SIZE 8 |
@@ -2011,6 +2011,27 @@ init_sub_direct(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2011 | } | 2011 | } |
2012 | 2012 | ||
2013 | static int | 2013 | static int |
2014 | init_jump(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | ||
2015 | { | ||
2016 | /* | ||
2017 | * INIT_JUMP opcode: 0x5C ('\') | ||
2018 | * | ||
2019 | * offset (8 bit): opcode | ||
2020 | * offset + 1 (16 bit): offset (in bios) | ||
2021 | * | ||
2022 | * Continue execution of init table from 'offset' | ||
2023 | */ | ||
2024 | |||
2025 | uint16_t jmp_offset = ROM16(bios->data[offset + 1]); | ||
2026 | |||
2027 | if (!iexec->execute) | ||
2028 | return 3; | ||
2029 | |||
2030 | BIOSLOG(bios, "0x%04X: Jump to 0x%04X\n", offset, jmp_offset); | ||
2031 | return jmp_offset - offset; | ||
2032 | } | ||
2033 | |||
2034 | static int | ||
2014 | init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2035 | init_i2c_if(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2015 | { | 2036 | { |
2016 | /* | 2037 | /* |
@@ -3659,6 +3680,7 @@ static struct init_tbl_entry itbl_entry[] = { | |||
3659 | { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence }, | 3680 | { "INIT_ZM_REG_SEQUENCE" , 0x58, init_zm_reg_sequence }, |
3660 | /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ | 3681 | /* INIT_INDIRECT_REG (0x5A, 7, 0, 0) removed due to no example of use */ |
3661 | { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct }, | 3682 | { "INIT_SUB_DIRECT" , 0x5B, init_sub_direct }, |
3683 | { "INIT_JUMP" , 0x5C, init_jump }, | ||
3662 | { "INIT_I2C_IF" , 0x5E, init_i2c_if }, | 3684 | { "INIT_I2C_IF" , 0x5E, init_i2c_if }, |
3663 | { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg }, | 3685 | { "INIT_COPY_NV_REG" , 0x5F, init_copy_nv_reg }, |
3664 | { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io }, | 3686 | { "INIT_ZM_INDEX_IO" , 0x62, init_zm_index_io }, |
@@ -3700,8 +3722,7 @@ static struct init_tbl_entry itbl_entry[] = { | |||
3700 | #define MAX_TABLE_OPS 1000 | 3722 | #define MAX_TABLE_OPS 1000 |
3701 | 3723 | ||
3702 | static int | 3724 | static int |
3703 | parse_init_table(struct nvbios *bios, unsigned int offset, | 3725 | parse_init_table(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
3704 | struct init_exec *iexec) | ||
3705 | { | 3726 | { |
3706 | /* | 3727 | /* |
3707 | * Parses all commands in an init table. | 3728 | * Parses all commands in an init table. |
@@ -6333,6 +6354,32 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) | |||
6333 | } | 6354 | } |
6334 | } | 6355 | } |
6335 | 6356 | ||
6357 | /* XFX GT-240X-YA | ||
6358 | * | ||
6359 | * So many things wrong here, replace the entire encoder table.. | ||
6360 | */ | ||
6361 | if (nv_match_device(dev, 0x0ca3, 0x1682, 0x3003)) { | ||
6362 | if (idx == 0) { | ||
6363 | *conn = 0x02001300; /* VGA, connector 1 */ | ||
6364 | *conf = 0x00000028; | ||
6365 | } else | ||
6366 | if (idx == 1) { | ||
6367 | *conn = 0x01010312; /* DVI, connector 0 */ | ||
6368 | *conf = 0x00020030; | ||
6369 | } else | ||
6370 | if (idx == 2) { | ||
6371 | *conn = 0x01010310; /* VGA, connector 0 */ | ||
6372 | *conf = 0x00000028; | ||
6373 | } else | ||
6374 | if (idx == 3) { | ||
6375 | *conn = 0x02022362; /* HDMI, connector 2 */ | ||
6376 | *conf = 0x00020010; | ||
6377 | } else { | ||
6378 | *conn = 0x0000000e; /* EOL */ | ||
6379 | *conf = 0x00000000; | ||
6380 | } | ||
6381 | } | ||
6382 | |||
6336 | return true; | 6383 | return true; |
6337 | } | 6384 | } |
6338 | 6385 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index ce38e97b9428..568caedd7216 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c | |||
@@ -83,7 +83,7 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
83 | return ret; | 83 | return ret; |
84 | 84 | ||
85 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ | 85 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ |
86 | ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfd0, 0x1000, | 86 | ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000, |
87 | &chan->m2mf_ntfy); | 87 | &chan->m2mf_ntfy); |
88 | if (ret) | 88 | if (ret) |
89 | return ret; | 89 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 57e5302503db..a76514a209b3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -682,6 +682,9 @@ struct drm_nouveau_private { | |||
682 | /* For PFIFO and PGRAPH. */ | 682 | /* For PFIFO and PGRAPH. */ |
683 | spinlock_t context_switch_lock; | 683 | spinlock_t context_switch_lock; |
684 | 684 | ||
685 | /* VM/PRAMIN flush, legacy PRAMIN aperture */ | ||
686 | spinlock_t vm_lock; | ||
687 | |||
685 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ | 688 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ |
686 | struct nouveau_ramht *ramht; | 689 | struct nouveau_ramht *ramht; |
687 | struct nouveau_gpuobj *ramfc; | 690 | struct nouveau_gpuobj *ramfc; |
@@ -1190,7 +1193,7 @@ extern int nv50_graph_load_context(struct nouveau_channel *); | |||
1190 | extern int nv50_graph_unload_context(struct drm_device *); | 1193 | extern int nv50_graph_unload_context(struct drm_device *); |
1191 | extern int nv50_grctx_init(struct nouveau_grctx *); | 1194 | extern int nv50_grctx_init(struct nouveau_grctx *); |
1192 | extern void nv50_graph_tlb_flush(struct drm_device *dev); | 1195 | extern void nv50_graph_tlb_flush(struct drm_device *dev); |
1193 | extern void nv86_graph_tlb_flush(struct drm_device *dev); | 1196 | extern void nv84_graph_tlb_flush(struct drm_device *dev); |
1194 | extern struct nouveau_enum nv50_data_error_names[]; | 1197 | extern struct nouveau_enum nv50_data_error_names[]; |
1195 | 1198 | ||
1196 | /* nvc0_graph.c */ | 1199 | /* nvc0_graph.c */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 889c4454682e..39aee6d4daf8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -181,13 +181,13 @@ nouveau_fbcon_sync(struct fb_info *info) | |||
181 | OUT_RING (chan, 0); | 181 | OUT_RING (chan, 0); |
182 | } | 182 | } |
183 | 183 | ||
184 | nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); | 184 | nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3, 0xffffffff); |
185 | FIRE_RING(chan); | 185 | FIRE_RING(chan); |
186 | mutex_unlock(&chan->mutex); | 186 | mutex_unlock(&chan->mutex); |
187 | 187 | ||
188 | ret = -EBUSY; | 188 | ret = -EBUSY; |
189 | for (i = 0; i < 100000; i++) { | 189 | for (i = 0; i < 100000; i++) { |
190 | if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy + 3)) { | 190 | if (!nouveau_bo_rd32(chan->notifier_bo, chan->m2mf_ntfy/4 + 3)) { |
191 | ret = 0; | 191 | ret = 0; |
192 | break; | 192 | break; |
193 | } | 193 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 2683377f4131..c3e953b08992 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -152,8 +152,6 @@ nouveau_mem_vram_fini(struct drm_device *dev) | |||
152 | { | 152 | { |
153 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 153 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
154 | 154 | ||
155 | nouveau_bo_ref(NULL, &dev_priv->vga_ram); | ||
156 | |||
157 | ttm_bo_device_release(&dev_priv->ttm.bdev); | 155 | ttm_bo_device_release(&dev_priv->ttm.bdev); |
158 | 156 | ||
159 | nouveau_ttm_global_release(dev_priv); | 157 | nouveau_ttm_global_release(dev_priv); |
@@ -398,7 +396,7 @@ nouveau_mem_vram_init(struct drm_device *dev) | |||
398 | dma_bits = 40; | 396 | dma_bits = 40; |
399 | } else | 397 | } else |
400 | if (drm_pci_device_is_pcie(dev) && | 398 | if (drm_pci_device_is_pcie(dev) && |
401 | dev_priv->chipset != 0x40 && | 399 | dev_priv->chipset > 0x40 && |
402 | dev_priv->chipset != 0x45) { | 400 | dev_priv->chipset != 0x45) { |
403 | if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39))) | 401 | if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39))) |
404 | dma_bits = 39; | 402 | dma_bits = 39; |
@@ -552,6 +550,7 @@ nouveau_mem_timing_init(struct drm_device *dev) | |||
552 | u8 tRC; /* Byte 9 */ | 550 | u8 tRC; /* Byte 9 */ |
553 | u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14; | 551 | u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14; |
554 | u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21; | 552 | u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21; |
553 | u8 magic_number = 0; /* Yeah... sorry*/ | ||
555 | u8 *mem = NULL, *entry; | 554 | u8 *mem = NULL, *entry; |
556 | int i, recordlen, entries; | 555 | int i, recordlen, entries; |
557 | 556 | ||
@@ -596,6 +595,12 @@ nouveau_mem_timing_init(struct drm_device *dev) | |||
596 | if (!memtimings->timing) | 595 | if (!memtimings->timing) |
597 | return; | 596 | return; |
598 | 597 | ||
598 | /* Get "some number" from the timing reg for NV_40 | ||
599 | * Used in calculations later */ | ||
600 | if(dev_priv->card_type == NV_40) { | ||
601 | magic_number = (nv_rd32(dev,0x100228) & 0x0f000000) >> 24; | ||
602 | } | ||
603 | |||
599 | entry = mem + mem[1]; | 604 | entry = mem + mem[1]; |
600 | for (i = 0; i < entries; i++, entry += recordlen) { | 605 | for (i = 0; i < entries; i++, entry += recordlen) { |
601 | struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i]; | 606 | struct nouveau_pm_memtiming *timing = &pm->memtimings.timing[i]; |
@@ -635,36 +640,51 @@ nouveau_mem_timing_init(struct drm_device *dev) | |||
635 | 640 | ||
636 | /* XXX: I don't trust the -1's and +1's... they must come | 641 | /* XXX: I don't trust the -1's and +1's... they must come |
637 | * from somewhere! */ | 642 | * from somewhere! */ |
638 | timing->reg_100224 = ((tUNK_0 + tUNK_19 + 1) << 24 | | 643 | timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 | |
639 | tUNK_18 << 16 | | 644 | tUNK_18 << 16 | |
640 | (tUNK_1 + tUNK_19 + 1) << 8 | | 645 | (tUNK_1 + tUNK_19 + 1 + magic_number) << 8; |
641 | (tUNK_2 - 1)); | 646 | if(dev_priv->chipset == 0xa8) { |
647 | timing->reg_100224 |= (tUNK_2 - 1); | ||
648 | } else { | ||
649 | timing->reg_100224 |= (tUNK_2 + 2 - magic_number); | ||
650 | } | ||
642 | 651 | ||
643 | timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); | 652 | timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); |
644 | if(recordlen > 19) { | 653 | if(dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) { |
645 | timing->reg_100228 += (tUNK_19 - 1) << 24; | 654 | timing->reg_100228 |= (tUNK_19 - 1) << 24; |
646 | }/* I cannot back-up this else-statement right now | 655 | } |
647 | else { | 656 | |
648 | timing->reg_100228 += tUNK_12 << 24; | 657 | if(dev_priv->card_type == NV_40) { |
649 | }*/ | 658 | /* NV40: don't know what the rest of the regs are.. |
650 | 659 | * And don't need to know either */ | |
651 | /* XXX: reg_10022c */ | 660 | timing->reg_100228 |= 0x20200000 | magic_number << 24; |
652 | timing->reg_10022c = tUNK_2 - 1; | 661 | } else if(dev_priv->card_type >= NV_50) { |
653 | 662 | /* XXX: reg_10022c */ | |
654 | timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | | 663 | timing->reg_10022c = tUNK_2 - 1; |
655 | tUNK_13 << 8 | tUNK_13); | 664 | |
656 | 665 | timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | | |
657 | /* XXX: +6? */ | 666 | tUNK_13 << 8 | tUNK_13); |
658 | timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC); | 667 | |
659 | timing->reg_100234 += max(tUNK_10,tUNK_11) << 16; | 668 | timing->reg_100234 = (tRAS << 24 | tRC); |
660 | 669 | timing->reg_100234 += max(tUNK_10,tUNK_11) << 16; | |
661 | /* XXX; reg_100238, reg_10023c | 670 | |
662 | * reg: 0x00?????? | 671 | if(dev_priv->chipset < 0xa3) { |
663 | * reg_10023c: | 672 | timing->reg_100234 |= (tUNK_2 + 2) << 8; |
664 | * 0 for pre-NV50 cards | 673 | } else { |
665 | * 0x????0202 for NV50+ cards (empirical evidence) */ | 674 | /* XXX: +6? */ |
666 | if(dev_priv->card_type >= NV_50) { | 675 | timing->reg_100234 |= (tUNK_19 + 6) << 8; |
676 | } | ||
677 | |||
678 | /* XXX; reg_100238, reg_10023c | ||
679 | * reg_100238: 0x00?????? | ||
680 | * reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */ | ||
667 | timing->reg_10023c = 0x202; | 681 | timing->reg_10023c = 0x202; |
682 | if(dev_priv->chipset < 0xa3) { | ||
683 | timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16; | ||
684 | } else { | ||
685 | /* currently unknown | ||
686 | * 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */ | ||
687 | } | ||
668 | } | 688 | } |
669 | 689 | ||
670 | NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, | 690 | NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, |
@@ -675,7 +695,7 @@ nouveau_mem_timing_init(struct drm_device *dev) | |||
675 | timing->reg_100238, timing->reg_10023c); | 695 | timing->reg_100238, timing->reg_10023c); |
676 | } | 696 | } |
677 | 697 | ||
678 | memtimings->nr_timing = entries; | 698 | memtimings->nr_timing = entries; |
679 | memtimings->supported = true; | 699 | memtimings->supported = true; |
680 | } | 700 | } |
681 | 701 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 7ba3fc0b30c1..5b39718ae1f8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -35,19 +35,22 @@ nouveau_notifier_init_channel(struct nouveau_channel *chan) | |||
35 | { | 35 | { |
36 | struct drm_device *dev = chan->dev; | 36 | struct drm_device *dev = chan->dev; |
37 | struct nouveau_bo *ntfy = NULL; | 37 | struct nouveau_bo *ntfy = NULL; |
38 | uint32_t flags; | 38 | uint32_t flags, ttmpl; |
39 | int ret; | 39 | int ret; |
40 | 40 | ||
41 | if (nouveau_vram_notify) | 41 | if (nouveau_vram_notify) { |
42 | flags = NOUVEAU_GEM_DOMAIN_VRAM; | 42 | flags = NOUVEAU_GEM_DOMAIN_VRAM; |
43 | else | 43 | ttmpl = TTM_PL_FLAG_VRAM; |
44 | } else { | ||
44 | flags = NOUVEAU_GEM_DOMAIN_GART; | 45 | flags = NOUVEAU_GEM_DOMAIN_GART; |
46 | ttmpl = TTM_PL_FLAG_TT; | ||
47 | } | ||
45 | 48 | ||
46 | ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, 0, 0, &ntfy); | 49 | ret = nouveau_gem_new(dev, NULL, PAGE_SIZE, 0, flags, 0, 0, &ntfy); |
47 | if (ret) | 50 | if (ret) |
48 | return ret; | 51 | return ret; |
49 | 52 | ||
50 | ret = nouveau_bo_pin(ntfy, flags); | 53 | ret = nouveau_bo_pin(ntfy, ttmpl); |
51 | if (ret) | 54 | if (ret) |
52 | goto out_err; | 55 | goto out_err; |
53 | 56 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 4f00c87ed86e..67a16e01ffa6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
@@ -1039,19 +1039,20 @@ nv_ro32(struct nouveau_gpuobj *gpuobj, u32 offset) | |||
1039 | { | 1039 | { |
1040 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; | 1040 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; |
1041 | struct drm_device *dev = gpuobj->dev; | 1041 | struct drm_device *dev = gpuobj->dev; |
1042 | unsigned long flags; | ||
1042 | 1043 | ||
1043 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { | 1044 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { |
1044 | u64 ptr = gpuobj->vinst + offset; | 1045 | u64 ptr = gpuobj->vinst + offset; |
1045 | u32 base = ptr >> 16; | 1046 | u32 base = ptr >> 16; |
1046 | u32 val; | 1047 | u32 val; |
1047 | 1048 | ||
1048 | spin_lock(&dev_priv->ramin_lock); | 1049 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
1049 | if (dev_priv->ramin_base != base) { | 1050 | if (dev_priv->ramin_base != base) { |
1050 | dev_priv->ramin_base = base; | 1051 | dev_priv->ramin_base = base; |
1051 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); | 1052 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); |
1052 | } | 1053 | } |
1053 | val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); | 1054 | val = nv_rd32(dev, 0x700000 + (ptr & 0xffff)); |
1054 | spin_unlock(&dev_priv->ramin_lock); | 1055 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
1055 | return val; | 1056 | return val; |
1056 | } | 1057 | } |
1057 | 1058 | ||
@@ -1063,18 +1064,19 @@ nv_wo32(struct nouveau_gpuobj *gpuobj, u32 offset, u32 val) | |||
1063 | { | 1064 | { |
1064 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; | 1065 | struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; |
1065 | struct drm_device *dev = gpuobj->dev; | 1066 | struct drm_device *dev = gpuobj->dev; |
1067 | unsigned long flags; | ||
1066 | 1068 | ||
1067 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { | 1069 | if (gpuobj->pinst == ~0 || !dev_priv->ramin_available) { |
1068 | u64 ptr = gpuobj->vinst + offset; | 1070 | u64 ptr = gpuobj->vinst + offset; |
1069 | u32 base = ptr >> 16; | 1071 | u32 base = ptr >> 16; |
1070 | 1072 | ||
1071 | spin_lock(&dev_priv->ramin_lock); | 1073 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
1072 | if (dev_priv->ramin_base != base) { | 1074 | if (dev_priv->ramin_base != base) { |
1073 | dev_priv->ramin_base = base; | 1075 | dev_priv->ramin_base = base; |
1074 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); | 1076 | nv_wr32(dev, 0x001700, dev_priv->ramin_base); |
1075 | } | 1077 | } |
1076 | nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); | 1078 | nv_wr32(dev, 0x700000 + (ptr & 0xffff), val); |
1077 | spin_unlock(&dev_priv->ramin_lock); | 1079 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
1078 | return; | 1080 | return; |
1079 | } | 1081 | } |
1080 | 1082 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c index ac62a1b8c4fc..670e3cb697ec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_perf.c +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c | |||
@@ -134,7 +134,7 @@ nouveau_perf_init(struct drm_device *dev) | |||
134 | case 0x13: | 134 | case 0x13: |
135 | case 0x15: | 135 | case 0x15: |
136 | perflvl->fanspeed = entry[55]; | 136 | perflvl->fanspeed = entry[55]; |
137 | perflvl->voltage = entry[56]; | 137 | perflvl->voltage = (recordlen > 56) ? entry[56] : 0; |
138 | perflvl->core = ROM32(entry[1]) * 10; | 138 | perflvl->core = ROM32(entry[1]) * 10; |
139 | perflvl->memory = ROM32(entry[5]) * 20; | 139 | perflvl->memory = ROM32(entry[5]) * 20; |
140 | break; | 140 | break; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index a33fe4019286..4bce801bc588 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
@@ -55,6 +55,7 @@ nouveau_sgdma_populate(struct ttm_backend *be, unsigned long num_pages, | |||
55 | be->func->clear(be); | 55 | be->func->clear(be); |
56 | return -EFAULT; | 56 | return -EFAULT; |
57 | } | 57 | } |
58 | nvbe->ttm_alloced[nvbe->nr_pages] = false; | ||
58 | } | 59 | } |
59 | 60 | ||
60 | nvbe->nr_pages++; | 61 | nvbe->nr_pages++; |
@@ -427,7 +428,7 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
427 | u32 aper_size, align; | 428 | u32 aper_size, align; |
428 | int ret; | 429 | int ret; |
429 | 430 | ||
430 | if (dev_priv->card_type >= NV_50 || drm_pci_device_is_pcie(dev)) | 431 | if (dev_priv->card_type >= NV_40 && drm_pci_device_is_pcie(dev)) |
431 | aper_size = 512 * 1024 * 1024; | 432 | aper_size = 512 * 1024 * 1024; |
432 | else | 433 | else |
433 | aper_size = 64 * 1024 * 1024; | 434 | aper_size = 64 * 1024 * 1024; |
@@ -457,7 +458,7 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
457 | dev_priv->gart_info.func = &nv50_sgdma_backend; | 458 | dev_priv->gart_info.func = &nv50_sgdma_backend; |
458 | } else | 459 | } else |
459 | if (drm_pci_device_is_pcie(dev) && | 460 | if (drm_pci_device_is_pcie(dev) && |
460 | dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) { | 461 | dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) { |
461 | if (nv44_graph_class(dev)) { | 462 | if (nv44_graph_class(dev)) { |
462 | dev_priv->gart_info.func = &nv44_sgdma_backend; | 463 | dev_priv->gart_info.func = &nv44_sgdma_backend; |
463 | align = 512 * 1024; | 464 | align = 512 * 1024; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 5bb2859001e2..915fbce89595 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -376,15 +376,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
376 | engine->graph.destroy_context = nv50_graph_destroy_context; | 376 | engine->graph.destroy_context = nv50_graph_destroy_context; |
377 | engine->graph.load_context = nv50_graph_load_context; | 377 | engine->graph.load_context = nv50_graph_load_context; |
378 | engine->graph.unload_context = nv50_graph_unload_context; | 378 | engine->graph.unload_context = nv50_graph_unload_context; |
379 | if (dev_priv->chipset != 0x86) | 379 | if (dev_priv->chipset == 0x50 || |
380 | dev_priv->chipset == 0xac) | ||
380 | engine->graph.tlb_flush = nv50_graph_tlb_flush; | 381 | engine->graph.tlb_flush = nv50_graph_tlb_flush; |
381 | else { | 382 | else |
382 | /* from what i can see nvidia do this on every | 383 | engine->graph.tlb_flush = nv84_graph_tlb_flush; |
383 | * pre-NVA3 board except NVAC, but, we've only | ||
384 | * ever seen problems on NV86 | ||
385 | */ | ||
386 | engine->graph.tlb_flush = nv86_graph_tlb_flush; | ||
387 | } | ||
388 | engine->fifo.channels = 128; | 384 | engine->fifo.channels = 128; |
389 | engine->fifo.init = nv50_fifo_init; | 385 | engine->fifo.init = nv50_fifo_init; |
390 | engine->fifo.takedown = nv50_fifo_takedown; | 386 | engine->fifo.takedown = nv50_fifo_takedown; |
@@ -612,6 +608,7 @@ nouveau_card_init(struct drm_device *dev) | |||
612 | spin_lock_init(&dev_priv->channels.lock); | 608 | spin_lock_init(&dev_priv->channels.lock); |
613 | spin_lock_init(&dev_priv->tile.lock); | 609 | spin_lock_init(&dev_priv->tile.lock); |
614 | spin_lock_init(&dev_priv->context_switch_lock); | 610 | spin_lock_init(&dev_priv->context_switch_lock); |
611 | spin_lock_init(&dev_priv->vm_lock); | ||
615 | 612 | ||
616 | /* Make the CRTCs and I2C buses accessible */ | 613 | /* Make the CRTCs and I2C buses accessible */ |
617 | ret = engine->display.early_init(dev); | 614 | ret = engine->display.early_init(dev); |
@@ -771,6 +768,11 @@ static void nouveau_card_takedown(struct drm_device *dev) | |||
771 | engine->mc.takedown(dev); | 768 | engine->mc.takedown(dev); |
772 | engine->display.late_takedown(dev); | 769 | engine->display.late_takedown(dev); |
773 | 770 | ||
771 | if (dev_priv->vga_ram) { | ||
772 | nouveau_bo_unpin(dev_priv->vga_ram); | ||
773 | nouveau_bo_ref(NULL, &dev_priv->vga_ram); | ||
774 | } | ||
775 | |||
774 | mutex_lock(&dev->struct_mutex); | 776 | mutex_lock(&dev->struct_mutex); |
775 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); | 777 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); |
776 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); | 778 | ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index c82db37d9f41..12098bf839c4 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -581,12 +581,13 @@ static void nv04_dfp_restore(struct drm_encoder *encoder) | |||
581 | int head = nv_encoder->restore.head; | 581 | int head = nv_encoder->restore.head; |
582 | 582 | ||
583 | if (nv_encoder->dcb->type == OUTPUT_LVDS) { | 583 | if (nv_encoder->dcb->type == OUTPUT_LVDS) { |
584 | struct drm_display_mode *native_mode = nouveau_encoder_connector_get(nv_encoder)->native_mode; | 584 | struct nouveau_connector *connector = |
585 | if (native_mode) | 585 | nouveau_encoder_connector_get(nv_encoder); |
586 | call_lvds_script(dev, nv_encoder->dcb, head, LVDS_PANEL_ON, | 586 | |
587 | native_mode->clock); | 587 | if (connector && connector->native_mode) |
588 | else | 588 | call_lvds_script(dev, nv_encoder->dcb, head, |
589 | NV_ERROR(dev, "Not restoring LVDS without native mode\n"); | 589 | LVDS_PANEL_ON, |
590 | connector->native_mode->clock); | ||
590 | 591 | ||
591 | } else if (nv_encoder->dcb->type == OUTPUT_TMDS) { | 592 | } else if (nv_encoder->dcb->type == OUTPUT_TMDS) { |
592 | int clock = nouveau_hw_pllvals_to_clk | 593 | int clock = nouveau_hw_pllvals_to_clk |
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 2b9984027f41..a19ccaa025b3 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
@@ -469,9 +469,6 @@ nv50_crtc_wait_complete(struct drm_crtc *crtc) | |||
469 | 469 | ||
470 | start = ptimer->read(dev); | 470 | start = ptimer->read(dev); |
471 | do { | 471 | do { |
472 | nv_wr32(dev, 0x61002c, 0x370); | ||
473 | nv_wr32(dev, 0x000140, 1); | ||
474 | |||
475 | if (nv_ro32(disp->ntfy, 0x000)) | 472 | if (nv_ro32(disp->ntfy, 0x000)) |
476 | return 0; | 473 | return 0; |
477 | } while (ptimer->read(dev) - start < 2000000000ULL); | 474 | } while (ptimer->read(dev) - start < 2000000000ULL); |
diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c index a2cfaa691e9b..c8e83c1a4de8 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.c +++ b/drivers/gpu/drm/nouveau/nv50_evo.c | |||
@@ -186,6 +186,7 @@ nv50_evo_channel_init(struct nouveau_channel *evo) | |||
186 | nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id); | 186 | nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id); |
187 | 187 | ||
188 | evo->dma.max = (4096/4) - 2; | 188 | evo->dma.max = (4096/4) - 2; |
189 | evo->dma.max &= ~7; | ||
189 | evo->dma.put = 0; | 190 | evo->dma.put = 0; |
190 | evo->dma.cur = evo->dma.put; | 191 | evo->dma.cur = evo->dma.put; |
191 | evo->dma.free = evo->dma.max - evo->dma.cur; | 192 | evo->dma.free = evo->dma.max - evo->dma.cur; |
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 8675b00caf18..b02a5b1e7d37 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -503,7 +503,7 @@ nv50_graph_tlb_flush(struct drm_device *dev) | |||
503 | } | 503 | } |
504 | 504 | ||
505 | void | 505 | void |
506 | nv86_graph_tlb_flush(struct drm_device *dev) | 506 | nv84_graph_tlb_flush(struct drm_device *dev) |
507 | { | 507 | { |
508 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 508 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
509 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; | 509 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; |
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index a6f8aa651fc6..4f95a1e5822e 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -404,23 +404,25 @@ void | |||
404 | nv50_instmem_flush(struct drm_device *dev) | 404 | nv50_instmem_flush(struct drm_device *dev) |
405 | { | 405 | { |
406 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 406 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
407 | unsigned long flags; | ||
407 | 408 | ||
408 | spin_lock(&dev_priv->ramin_lock); | 409 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
409 | nv_wr32(dev, 0x00330c, 0x00000001); | 410 | nv_wr32(dev, 0x00330c, 0x00000001); |
410 | if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) | 411 | if (!nv_wait(dev, 0x00330c, 0x00000002, 0x00000000)) |
411 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | 412 | NV_ERROR(dev, "PRAMIN flush timeout\n"); |
412 | spin_unlock(&dev_priv->ramin_lock); | 413 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
413 | } | 414 | } |
414 | 415 | ||
415 | void | 416 | void |
416 | nv84_instmem_flush(struct drm_device *dev) | 417 | nv84_instmem_flush(struct drm_device *dev) |
417 | { | 418 | { |
418 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 419 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
420 | unsigned long flags; | ||
419 | 421 | ||
420 | spin_lock(&dev_priv->ramin_lock); | 422 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
421 | nv_wr32(dev, 0x070000, 0x00000001); | 423 | nv_wr32(dev, 0x070000, 0x00000001); |
422 | if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) | 424 | if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) |
423 | NV_ERROR(dev, "PRAMIN flush timeout\n"); | 425 | NV_ERROR(dev, "PRAMIN flush timeout\n"); |
424 | spin_unlock(&dev_priv->ramin_lock); | 426 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
425 | } | 427 | } |
426 | 428 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index 4fd3432b5b8d..6c2694490741 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c | |||
@@ -174,10 +174,11 @@ void | |||
174 | nv50_vm_flush_engine(struct drm_device *dev, int engine) | 174 | nv50_vm_flush_engine(struct drm_device *dev, int engine) |
175 | { | 175 | { |
176 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 176 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
177 | unsigned long flags; | ||
177 | 178 | ||
178 | spin_lock(&dev_priv->ramin_lock); | 179 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
179 | nv_wr32(dev, 0x100c80, (engine << 16) | 1); | 180 | nv_wr32(dev, 0x100c80, (engine << 16) | 1); |
180 | if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) | 181 | if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) |
181 | NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); | 182 | NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); |
182 | spin_unlock(&dev_priv->ramin_lock); | 183 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); |
183 | } | 184 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c index 69af0ba7edd3..a179e6c55afb 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vm.c +++ b/drivers/gpu/drm/nouveau/nvc0_vm.c | |||
@@ -104,20 +104,27 @@ nvc0_vm_flush(struct nouveau_vm *vm) | |||
104 | struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; | 104 | struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; |
105 | struct drm_device *dev = vm->dev; | 105 | struct drm_device *dev = vm->dev; |
106 | struct nouveau_vm_pgd *vpgd; | 106 | struct nouveau_vm_pgd *vpgd; |
107 | u32 r100c80, engine; | 107 | unsigned long flags; |
108 | u32 engine = (dev_priv->chan_vm == vm) ? 1 : 5; | ||
108 | 109 | ||
109 | pinstmem->flush(vm->dev); | 110 | pinstmem->flush(vm->dev); |
110 | 111 | ||
111 | if (vm == dev_priv->chan_vm) | 112 | spin_lock_irqsave(&dev_priv->vm_lock, flags); |
112 | engine = 1; | ||
113 | else | ||
114 | engine = 5; | ||
115 | |||
116 | list_for_each_entry(vpgd, &vm->pgd_list, head) { | 113 | list_for_each_entry(vpgd, &vm->pgd_list, head) { |
117 | r100c80 = nv_rd32(dev, 0x100c80); | 114 | /* looks like maybe a "free flush slots" counter, the |
115 | * faster you write to 0x100cbc to more it decreases | ||
116 | */ | ||
117 | if (!nv_wait_ne(dev, 0x100c80, 0x00ff0000, 0x00000000)) { | ||
118 | NV_ERROR(dev, "vm timeout 0: 0x%08x %d\n", | ||
119 | nv_rd32(dev, 0x100c80), engine); | ||
120 | } | ||
118 | nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8); | 121 | nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8); |
119 | nv_wr32(dev, 0x100cbc, 0x80000000 | engine); | 122 | nv_wr32(dev, 0x100cbc, 0x80000000 | engine); |
120 | if (!nv_wait(dev, 0x100c80, 0xffffffff, r100c80)) | 123 | /* wait for flush to be queued? */ |
121 | NV_ERROR(dev, "vm flush timeout eng %d\n", engine); | 124 | if (!nv_wait(dev, 0x100c80, 0x00008000, 0x00008000)) { |
125 | NV_ERROR(dev, "vm timeout 1: 0x%08x %d\n", | ||
126 | nv_rd32(dev, 0x100c80), engine); | ||
127 | } | ||
122 | } | 128 | } |
129 | spin_unlock_irqrestore(&dev_priv->vm_lock, flags); | ||
123 | } | 130 | } |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 258fa5e7a2d9..7bd745689097 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "atom.h" | 32 | #include "atom.h" |
33 | #include "atom-names.h" | 33 | #include "atom-names.h" |
34 | #include "atom-bits.h" | 34 | #include "atom-bits.h" |
35 | #include "radeon.h" | ||
35 | 36 | ||
36 | #define ATOM_COND_ABOVE 0 | 37 | #define ATOM_COND_ABOVE 0 |
37 | #define ATOM_COND_ABOVEOREQUAL 1 | 38 | #define ATOM_COND_ABOVEOREQUAL 1 |
@@ -101,7 +102,9 @@ static void debug_print_spaces(int n) | |||
101 | static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | 102 | static uint32_t atom_iio_execute(struct atom_context *ctx, int base, |
102 | uint32_t index, uint32_t data) | 103 | uint32_t index, uint32_t data) |
103 | { | 104 | { |
105 | struct radeon_device *rdev = ctx->card->dev->dev_private; | ||
104 | uint32_t temp = 0xCDCDCDCD; | 106 | uint32_t temp = 0xCDCDCDCD; |
107 | |||
105 | while (1) | 108 | while (1) |
106 | switch (CU8(base)) { | 109 | switch (CU8(base)) { |
107 | case ATOM_IIO_NOP: | 110 | case ATOM_IIO_NOP: |
@@ -112,7 +115,8 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
112 | base += 3; | 115 | base += 3; |
113 | break; | 116 | break; |
114 | case ATOM_IIO_WRITE: | 117 | case ATOM_IIO_WRITE: |
115 | (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1)); | 118 | if (rdev->family == CHIP_RV515) |
119 | (void)ctx->card->ioreg_read(ctx->card, CU16(base + 1)); | ||
116 | ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); | 120 | ctx->card->ioreg_write(ctx->card, CU16(base + 1), temp); |
117 | base += 3; | 121 | base += 3; |
118 | break; | 122 | break; |
@@ -131,7 +135,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
131 | case ATOM_IIO_MOVE_INDEX: | 135 | case ATOM_IIO_MOVE_INDEX: |
132 | temp &= | 136 | temp &= |
133 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << | 137 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
134 | CU8(base + 2)); | 138 | CU8(base + 3)); |
135 | temp |= | 139 | temp |= |
136 | ((index >> CU8(base + 2)) & | 140 | ((index >> CU8(base + 2)) & |
137 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + | 141 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + |
@@ -141,7 +145,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
141 | case ATOM_IIO_MOVE_DATA: | 145 | case ATOM_IIO_MOVE_DATA: |
142 | temp &= | 146 | temp &= |
143 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << | 147 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
144 | CU8(base + 2)); | 148 | CU8(base + 3)); |
145 | temp |= | 149 | temp |= |
146 | ((data >> CU8(base + 2)) & | 150 | ((data >> CU8(base + 2)) & |
147 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + | 151 | (0xFFFFFFFF >> (32 - CU8(base + 1)))) << CU8(base + |
@@ -151,7 +155,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
151 | case ATOM_IIO_MOVE_ATTR: | 155 | case ATOM_IIO_MOVE_ATTR: |
152 | temp &= | 156 | temp &= |
153 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << | 157 | ~((0xFFFFFFFF >> (32 - CU8(base + 1))) << |
154 | CU8(base + 2)); | 158 | CU8(base + 3)); |
155 | temp |= | 159 | temp |= |
156 | ((ctx-> | 160 | ((ctx-> |
157 | io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 - | 161 | io_attr >> CU8(base + 2)) & (0xFFFFFFFF >> (32 - |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index b41ec59c7100..529a3a704731 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -531,6 +531,9 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
531 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; | 531 | pll->flags |= RADEON_PLL_PREFER_HIGH_FB_DIV; |
532 | else | 532 | else |
533 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; | 533 | pll->flags |= RADEON_PLL_PREFER_LOW_REF_DIV; |
534 | |||
535 | if (rdev->family < CHIP_RV770) | ||
536 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | ||
534 | } else { | 537 | } else { |
535 | pll->flags |= RADEON_PLL_LEGACY; | 538 | pll->flags |= RADEON_PLL_LEGACY; |
536 | 539 | ||
@@ -559,7 +562,6 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
559 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 562 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
560 | if (ss_enabled) { | 563 | if (ss_enabled) { |
561 | if (ss->refdiv) { | 564 | if (ss->refdiv) { |
562 | pll->flags |= RADEON_PLL_PREFER_MINM_OVER_MAXP; | ||
563 | pll->flags |= RADEON_PLL_USE_REF_DIV; | 565 | pll->flags |= RADEON_PLL_USE_REF_DIV; |
564 | pll->reference_div = ss->refdiv; | 566 | pll->reference_div = ss->refdiv; |
565 | if (ASIC_IS_AVIVO(rdev)) | 567 | if (ASIC_IS_AVIVO(rdev)) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 0b0cc74c08c0..c20eac3379e6 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -120,11 +120,16 @@ void evergreen_pm_misc(struct radeon_device *rdev) | |||
120 | struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; | 120 | struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; |
121 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; | 121 | struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; |
122 | 122 | ||
123 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | 123 | if (voltage->type == VOLTAGE_SW) { |
124 | if (voltage->voltage != rdev->pm.current_vddc) { | 124 | if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { |
125 | radeon_atom_set_voltage(rdev, voltage->voltage); | 125 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); |
126 | rdev->pm.current_vddc = voltage->voltage; | 126 | rdev->pm.current_vddc = voltage->voltage; |
127 | DRM_DEBUG("Setting: v: %d\n", voltage->voltage); | 127 | DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); |
128 | } | ||
129 | if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { | ||
130 | radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); | ||
131 | rdev->pm.current_vddci = voltage->vddci; | ||
132 | DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci); | ||
128 | } | 133 | } |
129 | } | 134 | } |
130 | } | 135 | } |
@@ -348,7 +353,7 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, | |||
348 | struct drm_display_mode *mode, | 353 | struct drm_display_mode *mode, |
349 | struct drm_display_mode *other_mode) | 354 | struct drm_display_mode *other_mode) |
350 | { | 355 | { |
351 | u32 tmp = 0; | 356 | u32 tmp; |
352 | /* | 357 | /* |
353 | * Line Buffer Setup | 358 | * Line Buffer Setup |
354 | * There are 3 line buffers, each one shared by 2 display controllers. | 359 | * There are 3 line buffers, each one shared by 2 display controllers. |
@@ -358,64 +363,63 @@ static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, | |||
358 | * first display controller | 363 | * first display controller |
359 | * 0 - first half of lb (3840 * 2) | 364 | * 0 - first half of lb (3840 * 2) |
360 | * 1 - first 3/4 of lb (5760 * 2) | 365 | * 1 - first 3/4 of lb (5760 * 2) |
361 | * 2 - whole lb (7680 * 2) | 366 | * 2 - whole lb (7680 * 2), other crtc must be disabled |
362 | * 3 - first 1/4 of lb (1920 * 2) | 367 | * 3 - first 1/4 of lb (1920 * 2) |
363 | * second display controller | 368 | * second display controller |
364 | * 4 - second half of lb (3840 * 2) | 369 | * 4 - second half of lb (3840 * 2) |
365 | * 5 - second 3/4 of lb (5760 * 2) | 370 | * 5 - second 3/4 of lb (5760 * 2) |
366 | * 6 - whole lb (7680 * 2) | 371 | * 6 - whole lb (7680 * 2), other crtc must be disabled |
367 | * 7 - last 1/4 of lb (1920 * 2) | 372 | * 7 - last 1/4 of lb (1920 * 2) |
368 | */ | 373 | */ |
369 | if (mode && other_mode) { | 374 | /* this can get tricky if we have two large displays on a paired group |
370 | if (mode->hdisplay > other_mode->hdisplay) { | 375 | * of crtcs. Ideally for multiple large displays we'd assign them to |
371 | if (mode->hdisplay > 2560) | 376 | * non-linked crtcs for maximum line buffer allocation. |
372 | tmp = 1; /* 3/4 */ | 377 | */ |
373 | else | 378 | if (radeon_crtc->base.enabled && mode) { |
374 | tmp = 0; /* 1/2 */ | 379 | if (other_mode) |
375 | } else if (other_mode->hdisplay > mode->hdisplay) { | ||
376 | if (other_mode->hdisplay > 2560) | ||
377 | tmp = 3; /* 1/4 */ | ||
378 | else | ||
379 | tmp = 0; /* 1/2 */ | ||
380 | } else | ||
381 | tmp = 0; /* 1/2 */ | 380 | tmp = 0; /* 1/2 */ |
382 | } else if (mode) | 381 | else |
383 | tmp = 2; /* whole */ | 382 | tmp = 2; /* whole */ |
384 | else if (other_mode) | 383 | } else |
385 | tmp = 3; /* 1/4 */ | 384 | tmp = 0; |
386 | 385 | ||
387 | /* second controller of the pair uses second half of the lb */ | 386 | /* second controller of the pair uses second half of the lb */ |
388 | if (radeon_crtc->crtc_id % 2) | 387 | if (radeon_crtc->crtc_id % 2) |
389 | tmp += 4; | 388 | tmp += 4; |
390 | WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); | 389 | WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); |
391 | 390 | ||
392 | switch (tmp) { | 391 | if (radeon_crtc->base.enabled && mode) { |
393 | case 0: | 392 | switch (tmp) { |
394 | case 4: | 393 | case 0: |
395 | default: | 394 | case 4: |
396 | if (ASIC_IS_DCE5(rdev)) | 395 | default: |
397 | return 4096 * 2; | 396 | if (ASIC_IS_DCE5(rdev)) |
398 | else | 397 | return 4096 * 2; |
399 | return 3840 * 2; | 398 | else |
400 | case 1: | 399 | return 3840 * 2; |
401 | case 5: | 400 | case 1: |
402 | if (ASIC_IS_DCE5(rdev)) | 401 | case 5: |
403 | return 6144 * 2; | 402 | if (ASIC_IS_DCE5(rdev)) |
404 | else | 403 | return 6144 * 2; |
405 | return 5760 * 2; | 404 | else |
406 | case 2: | 405 | return 5760 * 2; |
407 | case 6: | 406 | case 2: |
408 | if (ASIC_IS_DCE5(rdev)) | 407 | case 6: |
409 | return 8192 * 2; | 408 | if (ASIC_IS_DCE5(rdev)) |
410 | else | 409 | return 8192 * 2; |
411 | return 7680 * 2; | 410 | else |
412 | case 3: | 411 | return 7680 * 2; |
413 | case 7: | 412 | case 3: |
414 | if (ASIC_IS_DCE5(rdev)) | 413 | case 7: |
415 | return 2048 * 2; | 414 | if (ASIC_IS_DCE5(rdev)) |
416 | else | 415 | return 2048 * 2; |
417 | return 1920 * 2; | 416 | else |
417 | return 1920 * 2; | ||
418 | } | ||
418 | } | 419 | } |
420 | |||
421 | /* controller not enabled, so no lb used */ | ||
422 | return 0; | ||
419 | } | 423 | } |
420 | 424 | ||
421 | static u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) | 425 | static u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) |
@@ -858,9 +862,15 @@ int evergreen_pcie_gart_enable(struct radeon_device *rdev) | |||
858 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | | 862 | SYSTEM_ACCESS_MODE_NOT_IN_SYS | |
859 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | | 863 | SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | |
860 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); | 864 | EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); |
861 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | 865 | if (rdev->flags & RADEON_IS_IGP) { |
862 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | 866 | WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); |
863 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | 867 | WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); |
868 | WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
869 | } else { | ||
870 | WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); | ||
871 | WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); | ||
872 | WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); | ||
873 | } | ||
864 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); | 874 | WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); |
865 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); | 875 | WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); |
866 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); | 876 | WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); |
@@ -2576,7 +2586,7 @@ static inline u32 evergreen_get_ih_wptr(struct radeon_device *rdev) | |||
2576 | u32 wptr, tmp; | 2586 | u32 wptr, tmp; |
2577 | 2587 | ||
2578 | if (rdev->wb.enabled) | 2588 | if (rdev->wb.enabled) |
2579 | wptr = rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]; | 2589 | wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); |
2580 | else | 2590 | else |
2581 | wptr = RREG32(IH_RB_WPTR); | 2591 | wptr = RREG32(IH_RB_WPTR); |
2582 | 2592 | ||
@@ -2919,11 +2929,6 @@ static int evergreen_startup(struct radeon_device *rdev) | |||
2919 | rdev->asic->copy = NULL; | 2929 | rdev->asic->copy = NULL; |
2920 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); | 2930 | dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); |
2921 | } | 2931 | } |
2922 | /* XXX: ontario has problems blitting to gart at the moment */ | ||
2923 | if (rdev->family == CHIP_PALM) { | ||
2924 | rdev->asic->copy = NULL; | ||
2925 | radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); | ||
2926 | } | ||
2927 | 2932 | ||
2928 | /* allocate wb buffer */ | 2933 | /* allocate wb buffer */ |
2929 | r = radeon_wb_init(rdev); | 2934 | r = radeon_wb_init(rdev); |
@@ -3036,9 +3041,6 @@ int evergreen_init(struct radeon_device *rdev) | |||
3036 | { | 3041 | { |
3037 | int r; | 3042 | int r; |
3038 | 3043 | ||
3039 | r = radeon_dummy_page_init(rdev); | ||
3040 | if (r) | ||
3041 | return r; | ||
3042 | /* This don't do much */ | 3044 | /* This don't do much */ |
3043 | r = radeon_gem_init(rdev); | 3045 | r = radeon_gem_init(rdev); |
3044 | if (r) | 3046 | if (r) |
@@ -3150,7 +3152,6 @@ void evergreen_fini(struct radeon_device *rdev) | |||
3150 | radeon_atombios_fini(rdev); | 3152 | radeon_atombios_fini(rdev); |
3151 | kfree(rdev->bios); | 3153 | kfree(rdev->bios); |
3152 | rdev->bios = NULL; | 3154 | rdev->bios = NULL; |
3153 | radeon_dummy_page_fini(rdev); | ||
3154 | } | 3155 | } |
3155 | 3156 | ||
3156 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev) | 3157 | static void evergreen_pcie_gen2_enable(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 9aaa3f0c9372..94533849927e 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -221,6 +221,11 @@ | |||
221 | #define MC_VM_MD_L1_TLB0_CNTL 0x2654 | 221 | #define MC_VM_MD_L1_TLB0_CNTL 0x2654 |
222 | #define MC_VM_MD_L1_TLB1_CNTL 0x2658 | 222 | #define MC_VM_MD_L1_TLB1_CNTL 0x2658 |
223 | #define MC_VM_MD_L1_TLB2_CNTL 0x265C | 223 | #define MC_VM_MD_L1_TLB2_CNTL 0x265C |
224 | |||
225 | #define FUS_MC_VM_MD_L1_TLB0_CNTL 0x265C | ||
226 | #define FUS_MC_VM_MD_L1_TLB1_CNTL 0x2660 | ||
227 | #define FUS_MC_VM_MD_L1_TLB2_CNTL 0x2664 | ||
228 | |||
224 | #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C | 229 | #define MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203C |
225 | #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 | 230 | #define MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038 |
226 | #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 | 231 | #define MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034 |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index be271c42de4d..6f27593901c7 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -587,7 +587,7 @@ void r600_pm_misc(struct radeon_device *rdev) | |||
587 | 587 | ||
588 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | 588 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { |
589 | if (voltage->voltage != rdev->pm.current_vddc) { | 589 | if (voltage->voltage != rdev->pm.current_vddc) { |
590 | radeon_atom_set_voltage(rdev, voltage->voltage); | 590 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); |
591 | rdev->pm.current_vddc = voltage->voltage; | 591 | rdev->pm.current_vddc = voltage->voltage; |
592 | DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage); | 592 | DRM_DEBUG_DRIVER("Setting: v: %d\n", voltage->voltage); |
593 | } | 593 | } |
@@ -2509,9 +2509,6 @@ int r600_init(struct radeon_device *rdev) | |||
2509 | { | 2509 | { |
2510 | int r; | 2510 | int r; |
2511 | 2511 | ||
2512 | r = radeon_dummy_page_init(rdev); | ||
2513 | if (r) | ||
2514 | return r; | ||
2515 | if (r600_debugfs_mc_info_init(rdev)) { | 2512 | if (r600_debugfs_mc_info_init(rdev)) { |
2516 | DRM_ERROR("Failed to register debugfs file for mc !\n"); | 2513 | DRM_ERROR("Failed to register debugfs file for mc !\n"); |
2517 | } | 2514 | } |
@@ -2625,7 +2622,6 @@ void r600_fini(struct radeon_device *rdev) | |||
2625 | radeon_atombios_fini(rdev); | 2622 | radeon_atombios_fini(rdev); |
2626 | kfree(rdev->bios); | 2623 | kfree(rdev->bios); |
2627 | rdev->bios = NULL; | 2624 | rdev->bios = NULL; |
2628 | radeon_dummy_page_fini(rdev); | ||
2629 | } | 2625 | } |
2630 | 2626 | ||
2631 | 2627 | ||
@@ -3235,7 +3231,7 @@ static inline u32 r600_get_ih_wptr(struct radeon_device *rdev) | |||
3235 | u32 wptr, tmp; | 3231 | u32 wptr, tmp; |
3236 | 3232 | ||
3237 | if (rdev->wb.enabled) | 3233 | if (rdev->wb.enabled) |
3238 | wptr = rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]; | 3234 | wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); |
3239 | else | 3235 | else |
3240 | wptr = RREG32(IH_RB_WPTR); | 3236 | wptr = RREG32(IH_RB_WPTR); |
3241 | 3237 | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 93f536594c73..ba643b576054 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -177,7 +177,7 @@ void radeon_pm_suspend(struct radeon_device *rdev); | |||
177 | void radeon_pm_resume(struct radeon_device *rdev); | 177 | void radeon_pm_resume(struct radeon_device *rdev); |
178 | void radeon_combios_get_power_modes(struct radeon_device *rdev); | 178 | void radeon_combios_get_power_modes(struct radeon_device *rdev); |
179 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); | 179 | void radeon_atombios_get_power_modes(struct radeon_device *rdev); |
180 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level); | 180 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type); |
181 | void rs690_pm_info(struct radeon_device *rdev); | 181 | void rs690_pm_info(struct radeon_device *rdev); |
182 | extern int rv6xx_get_temp(struct radeon_device *rdev); | 182 | extern int rv6xx_get_temp(struct radeon_device *rdev); |
183 | extern int rv770_get_temp(struct radeon_device *rdev); | 183 | extern int rv770_get_temp(struct radeon_device *rdev); |
@@ -767,7 +767,9 @@ struct radeon_voltage { | |||
767 | u8 vddci_id; /* index into vddci voltage table */ | 767 | u8 vddci_id; /* index into vddci voltage table */ |
768 | bool vddci_enabled; | 768 | bool vddci_enabled; |
769 | /* r6xx+ sw */ | 769 | /* r6xx+ sw */ |
770 | u32 voltage; | 770 | u16 voltage; |
771 | /* evergreen+ vddci */ | ||
772 | u16 vddci; | ||
771 | }; | 773 | }; |
772 | 774 | ||
773 | /* clock mode flags */ | 775 | /* clock mode flags */ |
@@ -835,10 +837,12 @@ struct radeon_pm { | |||
835 | int default_power_state_index; | 837 | int default_power_state_index; |
836 | u32 current_sclk; | 838 | u32 current_sclk; |
837 | u32 current_mclk; | 839 | u32 current_mclk; |
838 | u32 current_vddc; | 840 | u16 current_vddc; |
841 | u16 current_vddci; | ||
839 | u32 default_sclk; | 842 | u32 default_sclk; |
840 | u32 default_mclk; | 843 | u32 default_mclk; |
841 | u32 default_vddc; | 844 | u16 default_vddc; |
845 | u16 default_vddci; | ||
842 | struct radeon_i2c_chan *i2c_bus; | 846 | struct radeon_i2c_chan *i2c_bus; |
843 | /* selected pm method */ | 847 | /* selected pm method */ |
844 | enum radeon_pm_method pm_method; | 848 | enum radeon_pm_method pm_method; |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index eb888ee5f674..ca576191d058 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -94,7 +94,7 @@ static void radeon_register_accessor_init(struct radeon_device *rdev) | |||
94 | rdev->mc_rreg = &rs600_mc_rreg; | 94 | rdev->mc_rreg = &rs600_mc_rreg; |
95 | rdev->mc_wreg = &rs600_mc_wreg; | 95 | rdev->mc_wreg = &rs600_mc_wreg; |
96 | } | 96 | } |
97 | if ((rdev->family >= CHIP_R600) && (rdev->family <= CHIP_HEMLOCK)) { | 97 | if (rdev->family >= CHIP_R600) { |
98 | rdev->pciep_rreg = &r600_pciep_rreg; | 98 | rdev->pciep_rreg = &r600_pciep_rreg; |
99 | rdev->pciep_wreg = &r600_pciep_wreg; | 99 | rdev->pciep_wreg = &r600_pciep_wreg; |
100 | } | 100 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 99768d9d91da..dd881d035f09 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -431,7 +431,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
431 | } | 431 | } |
432 | } | 432 | } |
433 | 433 | ||
434 | /* Acer laptop (Acer TravelMate 5730G) has an HDMI port | 434 | /* Acer laptop (Acer TravelMate 5730/5730G) has an HDMI port |
435 | * on the laptop and a DVI port on the docking station and | 435 | * on the laptop and a DVI port on the docking station and |
436 | * both share the same encoder, hpd pin, and ddc line. | 436 | * both share the same encoder, hpd pin, and ddc line. |
437 | * So while the bios table is technically correct, | 437 | * So while the bios table is technically correct, |
@@ -440,7 +440,7 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev, | |||
440 | * with different crtcs which isn't possible on the hardware | 440 | * with different crtcs which isn't possible on the hardware |
441 | * side and leaves no crtcs for LVDS or VGA. | 441 | * side and leaves no crtcs for LVDS or VGA. |
442 | */ | 442 | */ |
443 | if ((dev->pdev->device == 0x95c4) && | 443 | if (((dev->pdev->device == 0x95c4) || (dev->pdev->device == 0x9591)) && |
444 | (dev->pdev->subsystem_vendor == 0x1025) && | 444 | (dev->pdev->subsystem_vendor == 0x1025) && |
445 | (dev->pdev->subsystem_device == 0x013c)) { | 445 | (dev->pdev->subsystem_device == 0x013c)) { |
446 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && | 446 | if ((*connector_type == DRM_MODE_CONNECTOR_DVII) && |
@@ -1599,9 +1599,10 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct | |||
1599 | memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], | 1599 | memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], |
1600 | fake_edid_record->ucFakeEDIDLength); | 1600 | fake_edid_record->ucFakeEDIDLength); |
1601 | 1601 | ||
1602 | if (drm_edid_is_valid(edid)) | 1602 | if (drm_edid_is_valid(edid)) { |
1603 | rdev->mode_info.bios_hardcoded_edid = edid; | 1603 | rdev->mode_info.bios_hardcoded_edid = edid; |
1604 | else | 1604 | rdev->mode_info.bios_hardcoded_edid_size = edid_size; |
1605 | } else | ||
1605 | kfree(edid); | 1606 | kfree(edid); |
1606 | } | 1607 | } |
1607 | } | 1608 | } |
@@ -2176,24 +2177,27 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r | |||
2176 | } | 2177 | } |
2177 | } | 2178 | } |
2178 | 2179 | ||
2179 | static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) | 2180 | static void radeon_atombios_get_default_voltages(struct radeon_device *rdev, |
2181 | u16 *vddc, u16 *vddci) | ||
2180 | { | 2182 | { |
2181 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 2183 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
2182 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); | 2184 | int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); |
2183 | u8 frev, crev; | 2185 | u8 frev, crev; |
2184 | u16 data_offset; | 2186 | u16 data_offset; |
2185 | union firmware_info *firmware_info; | 2187 | union firmware_info *firmware_info; |
2186 | u16 vddc = 0; | 2188 | |
2189 | *vddc = 0; | ||
2190 | *vddci = 0; | ||
2187 | 2191 | ||
2188 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, | 2192 | if (atom_parse_data_header(mode_info->atom_context, index, NULL, |
2189 | &frev, &crev, &data_offset)) { | 2193 | &frev, &crev, &data_offset)) { |
2190 | firmware_info = | 2194 | firmware_info = |
2191 | (union firmware_info *)(mode_info->atom_context->bios + | 2195 | (union firmware_info *)(mode_info->atom_context->bios + |
2192 | data_offset); | 2196 | data_offset); |
2193 | vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); | 2197 | *vddc = le16_to_cpu(firmware_info->info_14.usBootUpVDDCVoltage); |
2198 | if ((frev == 2) && (crev >= 2)) | ||
2199 | *vddci = le16_to_cpu(firmware_info->info_22.usBootUpVDDCIVoltage); | ||
2194 | } | 2200 | } |
2195 | |||
2196 | return vddc; | ||
2197 | } | 2201 | } |
2198 | 2202 | ||
2199 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, | 2203 | static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, |
@@ -2203,7 +2207,9 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde | |||
2203 | int j; | 2207 | int j; |
2204 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); | 2208 | u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); |
2205 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); | 2209 | u32 misc2 = le16_to_cpu(non_clock_info->usClassification); |
2206 | u16 vddc = radeon_atombios_get_default_vddc(rdev); | 2210 | u16 vddc, vddci; |
2211 | |||
2212 | radeon_atombios_get_default_voltages(rdev, &vddc, &vddci); | ||
2207 | 2213 | ||
2208 | rdev->pm.power_state[state_index].misc = misc; | 2214 | rdev->pm.power_state[state_index].misc = misc; |
2209 | rdev->pm.power_state[state_index].misc2 = misc2; | 2215 | rdev->pm.power_state[state_index].misc2 = misc2; |
@@ -2244,6 +2250,7 @@ static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rde | |||
2244 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; | 2250 | rdev->pm.default_sclk = rdev->pm.power_state[state_index].clock_info[0].sclk; |
2245 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; | 2251 | rdev->pm.default_mclk = rdev->pm.power_state[state_index].clock_info[0].mclk; |
2246 | rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; | 2252 | rdev->pm.default_vddc = rdev->pm.power_state[state_index].clock_info[0].voltage.voltage; |
2253 | rdev->pm.default_vddci = rdev->pm.power_state[state_index].clock_info[0].voltage.vddci; | ||
2247 | } else { | 2254 | } else { |
2248 | /* patch the table values with the default slck/mclk from firmware info */ | 2255 | /* patch the table values with the default slck/mclk from firmware info */ |
2249 | for (j = 0; j < mode_index; j++) { | 2256 | for (j = 0; j < mode_index; j++) { |
@@ -2286,6 +2293,8 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, | |||
2286 | VOLTAGE_SW; | 2293 | VOLTAGE_SW; |
2287 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = | 2294 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = |
2288 | le16_to_cpu(clock_info->evergreen.usVDDC); | 2295 | le16_to_cpu(clock_info->evergreen.usVDDC); |
2296 | rdev->pm.power_state[state_index].clock_info[mode_index].voltage.vddci = | ||
2297 | le16_to_cpu(clock_info->evergreen.usVDDCI); | ||
2289 | } else { | 2298 | } else { |
2290 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); | 2299 | sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); |
2291 | sclk |= clock_info->r600.ucEngineClockHigh << 16; | 2300 | sclk |= clock_info->r600.ucEngineClockHigh << 16; |
@@ -2577,25 +2586,25 @@ union set_voltage { | |||
2577 | struct _SET_VOLTAGE_PARAMETERS_V2 v2; | 2586 | struct _SET_VOLTAGE_PARAMETERS_V2 v2; |
2578 | }; | 2587 | }; |
2579 | 2588 | ||
2580 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 level) | 2589 | void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type) |
2581 | { | 2590 | { |
2582 | union set_voltage args; | 2591 | union set_voltage args; |
2583 | int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); | 2592 | int index = GetIndexIntoMasterTable(COMMAND, SetVoltage); |
2584 | u8 frev, crev, volt_index = level; | 2593 | u8 frev, crev, volt_index = voltage_level; |
2585 | 2594 | ||
2586 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) | 2595 | if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev)) |
2587 | return; | 2596 | return; |
2588 | 2597 | ||
2589 | switch (crev) { | 2598 | switch (crev) { |
2590 | case 1: | 2599 | case 1: |
2591 | args.v1.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; | 2600 | args.v1.ucVoltageType = voltage_type; |
2592 | args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; | 2601 | args.v1.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_ALL_SOURCE; |
2593 | args.v1.ucVoltageIndex = volt_index; | 2602 | args.v1.ucVoltageIndex = volt_index; |
2594 | break; | 2603 | break; |
2595 | case 2: | 2604 | case 2: |
2596 | args.v2.ucVoltageType = SET_VOLTAGE_TYPE_ASIC_VDDC; | 2605 | args.v2.ucVoltageType = voltage_type; |
2597 | args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; | 2606 | args.v2.ucVoltageMode = SET_ASIC_VOLTAGE_MODE_SET_VOLTAGE; |
2598 | args.v2.usVoltageLevel = cpu_to_le16(level); | 2607 | args.v2.usVoltageLevel = cpu_to_le16(voltage_level); |
2599 | break; | 2608 | break; |
2600 | default: | 2609 | default: |
2601 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); | 2610 | DRM_ERROR("Unknown table version %d, %d\n", frev, crev); |
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c index ed5dfe58f29c..9d95792bea3e 100644 --- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c +++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c | |||
@@ -15,6 +15,9 @@ | |||
15 | #define ATPX_VERSION 0 | 15 | #define ATPX_VERSION 0 |
16 | #define ATPX_GPU_PWR 2 | 16 | #define ATPX_GPU_PWR 2 |
17 | #define ATPX_MUX_SELECT 3 | 17 | #define ATPX_MUX_SELECT 3 |
18 | #define ATPX_I2C_MUX_SELECT 4 | ||
19 | #define ATPX_SWITCH_START 5 | ||
20 | #define ATPX_SWITCH_END 6 | ||
18 | 21 | ||
19 | #define ATPX_INTEGRATED 0 | 22 | #define ATPX_INTEGRATED 0 |
20 | #define ATPX_DISCRETE 1 | 23 | #define ATPX_DISCRETE 1 |
@@ -149,13 +152,35 @@ static int radeon_atpx_switch_mux(acpi_handle handle, int mux_id) | |||
149 | return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); | 152 | return radeon_atpx_execute(handle, ATPX_MUX_SELECT, mux_id); |
150 | } | 153 | } |
151 | 154 | ||
155 | static int radeon_atpx_switch_i2c_mux(acpi_handle handle, int mux_id) | ||
156 | { | ||
157 | return radeon_atpx_execute(handle, ATPX_I2C_MUX_SELECT, mux_id); | ||
158 | } | ||
159 | |||
160 | static int radeon_atpx_switch_start(acpi_handle handle, int gpu_id) | ||
161 | { | ||
162 | return radeon_atpx_execute(handle, ATPX_SWITCH_START, gpu_id); | ||
163 | } | ||
164 | |||
165 | static int radeon_atpx_switch_end(acpi_handle handle, int gpu_id) | ||
166 | { | ||
167 | return radeon_atpx_execute(handle, ATPX_SWITCH_END, gpu_id); | ||
168 | } | ||
152 | 169 | ||
153 | static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) | 170 | static int radeon_atpx_switchto(enum vga_switcheroo_client_id id) |
154 | { | 171 | { |
172 | int gpu_id; | ||
173 | |||
155 | if (id == VGA_SWITCHEROO_IGD) | 174 | if (id == VGA_SWITCHEROO_IGD) |
156 | radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 0); | 175 | gpu_id = ATPX_INTEGRATED; |
157 | else | 176 | else |
158 | radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, 1); | 177 | gpu_id = ATPX_DISCRETE; |
178 | |||
179 | radeon_atpx_switch_start(radeon_atpx_priv.atpx_handle, gpu_id); | ||
180 | radeon_atpx_switch_mux(radeon_atpx_priv.atpx_handle, gpu_id); | ||
181 | radeon_atpx_switch_i2c_mux(radeon_atpx_priv.atpx_handle, gpu_id); | ||
182 | radeon_atpx_switch_end(radeon_atpx_priv.atpx_handle, gpu_id); | ||
183 | |||
159 | return 0; | 184 | return 0; |
160 | } | 185 | } |
161 | 186 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2ef6d5135064..5f45fa12bb8b 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -1199,7 +1199,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1199 | if (router->ddc_valid || router->cd_valid) { | 1199 | if (router->ddc_valid || router->cd_valid) { |
1200 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); | 1200 | radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); |
1201 | if (!radeon_connector->router_bus) | 1201 | if (!radeon_connector->router_bus) |
1202 | goto failed; | 1202 | DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n"); |
1203 | } | 1203 | } |
1204 | switch (connector_type) { | 1204 | switch (connector_type) { |
1205 | case DRM_MODE_CONNECTOR_VGA: | 1205 | case DRM_MODE_CONNECTOR_VGA: |
@@ -1208,7 +1208,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1208 | if (i2c_bus->valid) { | 1208 | if (i2c_bus->valid) { |
1209 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1209 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1210 | if (!radeon_connector->ddc_bus) | 1210 | if (!radeon_connector->ddc_bus) |
1211 | goto failed; | 1211 | DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1212 | } | 1212 | } |
1213 | radeon_connector->dac_load_detect = true; | 1213 | radeon_connector->dac_load_detect = true; |
1214 | drm_connector_attach_property(&radeon_connector->base, | 1214 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1226,7 +1226,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1226 | if (i2c_bus->valid) { | 1226 | if (i2c_bus->valid) { |
1227 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1227 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1228 | if (!radeon_connector->ddc_bus) | 1228 | if (!radeon_connector->ddc_bus) |
1229 | goto failed; | 1229 | DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1230 | } | 1230 | } |
1231 | radeon_connector->dac_load_detect = true; | 1231 | radeon_connector->dac_load_detect = true; |
1232 | drm_connector_attach_property(&radeon_connector->base, | 1232 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1249,7 +1249,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1249 | if (i2c_bus->valid) { | 1249 | if (i2c_bus->valid) { |
1250 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1250 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1251 | if (!radeon_connector->ddc_bus) | 1251 | if (!radeon_connector->ddc_bus) |
1252 | goto failed; | 1252 | DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1253 | } | 1253 | } |
1254 | subpixel_order = SubPixelHorizontalRGB; | 1254 | subpixel_order = SubPixelHorizontalRGB; |
1255 | drm_connector_attach_property(&radeon_connector->base, | 1255 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1290,7 +1290,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1290 | if (i2c_bus->valid) { | 1290 | if (i2c_bus->valid) { |
1291 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1291 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1292 | if (!radeon_connector->ddc_bus) | 1292 | if (!radeon_connector->ddc_bus) |
1293 | goto failed; | 1293 | DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1294 | } | 1294 | } |
1295 | drm_connector_attach_property(&radeon_connector->base, | 1295 | drm_connector_attach_property(&radeon_connector->base, |
1296 | rdev->mode_info.coherent_mode_property, | 1296 | rdev->mode_info.coherent_mode_property, |
@@ -1329,10 +1329,10 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1329 | else | 1329 | else |
1330 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); | 1330 | radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch"); |
1331 | if (!radeon_dig_connector->dp_i2c_bus) | 1331 | if (!radeon_dig_connector->dp_i2c_bus) |
1332 | goto failed; | 1332 | DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n"); |
1333 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1333 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1334 | if (!radeon_connector->ddc_bus) | 1334 | if (!radeon_connector->ddc_bus) |
1335 | goto failed; | 1335 | DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1336 | } | 1336 | } |
1337 | subpixel_order = SubPixelHorizontalRGB; | 1337 | subpixel_order = SubPixelHorizontalRGB; |
1338 | drm_connector_attach_property(&radeon_connector->base, | 1338 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1381,7 +1381,7 @@ radeon_add_atom_connector(struct drm_device *dev, | |||
1381 | if (i2c_bus->valid) { | 1381 | if (i2c_bus->valid) { |
1382 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1382 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1383 | if (!radeon_connector->ddc_bus) | 1383 | if (!radeon_connector->ddc_bus) |
1384 | goto failed; | 1384 | DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1385 | } | 1385 | } |
1386 | drm_connector_attach_property(&radeon_connector->base, | 1386 | drm_connector_attach_property(&radeon_connector->base, |
1387 | dev->mode_config.scaling_mode_property, | 1387 | dev->mode_config.scaling_mode_property, |
@@ -1457,7 +1457,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1457 | if (i2c_bus->valid) { | 1457 | if (i2c_bus->valid) { |
1458 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1458 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1459 | if (!radeon_connector->ddc_bus) | 1459 | if (!radeon_connector->ddc_bus) |
1460 | goto failed; | 1460 | DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1461 | } | 1461 | } |
1462 | radeon_connector->dac_load_detect = true; | 1462 | radeon_connector->dac_load_detect = true; |
1463 | drm_connector_attach_property(&radeon_connector->base, | 1463 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1475,7 +1475,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1475 | if (i2c_bus->valid) { | 1475 | if (i2c_bus->valid) { |
1476 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1476 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1477 | if (!radeon_connector->ddc_bus) | 1477 | if (!radeon_connector->ddc_bus) |
1478 | goto failed; | 1478 | DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1479 | } | 1479 | } |
1480 | radeon_connector->dac_load_detect = true; | 1480 | radeon_connector->dac_load_detect = true; |
1481 | drm_connector_attach_property(&radeon_connector->base, | 1481 | drm_connector_attach_property(&radeon_connector->base, |
@@ -1493,7 +1493,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1493 | if (i2c_bus->valid) { | 1493 | if (i2c_bus->valid) { |
1494 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1494 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1495 | if (!radeon_connector->ddc_bus) | 1495 | if (!radeon_connector->ddc_bus) |
1496 | goto failed; | 1496 | DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1497 | } | 1497 | } |
1498 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { | 1498 | if (connector_type == DRM_MODE_CONNECTOR_DVII) { |
1499 | radeon_connector->dac_load_detect = true; | 1499 | radeon_connector->dac_load_detect = true; |
@@ -1538,7 +1538,7 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1538 | if (i2c_bus->valid) { | 1538 | if (i2c_bus->valid) { |
1539 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); | 1539 | radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus); |
1540 | if (!radeon_connector->ddc_bus) | 1540 | if (!radeon_connector->ddc_bus) |
1541 | goto failed; | 1541 | DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n"); |
1542 | } | 1542 | } |
1543 | drm_connector_attach_property(&radeon_connector->base, | 1543 | drm_connector_attach_property(&radeon_connector->base, |
1544 | dev->mode_config.scaling_mode_property, | 1544 | dev->mode_config.scaling_mode_property, |
@@ -1567,9 +1567,4 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1567 | radeon_legacy_backlight_init(radeon_encoder, connector); | 1567 | radeon_legacy_backlight_init(radeon_encoder, connector); |
1568 | } | 1568 | } |
1569 | } | 1569 | } |
1570 | return; | ||
1571 | |||
1572 | failed: | ||
1573 | drm_connector_cleanup(connector); | ||
1574 | kfree(connector); | ||
1575 | } | 1570 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index bdf2fa1189ae..3189a7efb2e9 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -167,9 +167,6 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, | |||
167 | return -EINVAL; | 167 | return -EINVAL; |
168 | } | 168 | } |
169 | 169 | ||
170 | radeon_crtc->cursor_width = width; | ||
171 | radeon_crtc->cursor_height = height; | ||
172 | |||
173 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); | 170 | obj = drm_gem_object_lookup(crtc->dev, file_priv, handle); |
174 | if (!obj) { | 171 | if (!obj) { |
175 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); | 172 | DRM_ERROR("Cannot find cursor object %x for crtc %d\n", handle, radeon_crtc->crtc_id); |
@@ -180,6 +177,9 @@ int radeon_crtc_cursor_set(struct drm_crtc *crtc, | |||
180 | if (ret) | 177 | if (ret) |
181 | goto fail; | 178 | goto fail; |
182 | 179 | ||
180 | radeon_crtc->cursor_width = width; | ||
181 | radeon_crtc->cursor_height = height; | ||
182 | |||
183 | radeon_lock_cursor(crtc, true); | 183 | radeon_lock_cursor(crtc, true); |
184 | /* XXX only 27 bit offset for legacy cursor */ | 184 | /* XXX only 27 bit offset for legacy cursor */ |
185 | radeon_set_cursor(crtc, obj, gpu_addr); | 185 | radeon_set_cursor(crtc, obj, gpu_addr); |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 9e59868d354e..bbcd1dd7bac0 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -79,7 +79,7 @@ static bool radeon_fence_poll_locked(struct radeon_device *rdev) | |||
79 | scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; | 79 | scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
80 | else | 80 | else |
81 | scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; | 81 | scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base; |
82 | seq = rdev->wb.wb[scratch_index/4]; | 82 | seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]); |
83 | } else | 83 | } else |
84 | seq = RREG32(rdev->fence_drv.scratch_reg); | 84 | seq = RREG32(rdev->fence_drv.scratch_reg); |
85 | if (seq != rdev->fence_drv.last_seq) { | 85 | if (seq != rdev->fence_drv.last_seq) { |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index f0534ef2f331..8a955bbdb608 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -285,4 +285,6 @@ void radeon_gart_fini(struct radeon_device *rdev) | |||
285 | rdev->gart.pages = NULL; | 285 | rdev->gart.pages = NULL; |
286 | rdev->gart.pages_addr = NULL; | 286 | rdev->gart.pages_addr = NULL; |
287 | rdev->gart.ttm_alloced = NULL; | 287 | rdev->gart.ttm_alloced = NULL; |
288 | |||
289 | radeon_dummy_page_fini(rdev); | ||
288 | } | 290 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index ded2a45bc95c..983cbac75af0 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -1062,7 +1062,7 @@ void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, | |||
1062 | *val = in_buf[0]; | 1062 | *val = in_buf[0]; |
1063 | DRM_DEBUG("val = 0x%02x\n", *val); | 1063 | DRM_DEBUG("val = 0x%02x\n", *val); |
1064 | } else { | 1064 | } else { |
1065 | DRM_ERROR("i2c 0x%02x 0x%02x read failed\n", | 1065 | DRM_DEBUG("i2c 0x%02x 0x%02x read failed\n", |
1066 | addr, *val); | 1066 | addr, *val); |
1067 | } | 1067 | } |
1068 | } | 1068 | } |
@@ -1084,7 +1084,7 @@ void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, | |||
1084 | out_buf[1] = val; | 1084 | out_buf[1] = val; |
1085 | 1085 | ||
1086 | if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) | 1086 | if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) |
1087 | DRM_ERROR("i2c 0x%02x 0x%02x write failed\n", | 1087 | DRM_DEBUG("i2c 0x%02x 0x%02x write failed\n", |
1088 | addr, val); | 1088 | addr, val); |
1089 | } | 1089 | } |
1090 | 1090 | ||
@@ -1096,6 +1096,9 @@ void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector) | |||
1096 | if (!radeon_connector->router.ddc_valid) | 1096 | if (!radeon_connector->router.ddc_valid) |
1097 | return; | 1097 | return; |
1098 | 1098 | ||
1099 | if (!radeon_connector->router_bus) | ||
1100 | return; | ||
1101 | |||
1099 | radeon_i2c_get_byte(radeon_connector->router_bus, | 1102 | radeon_i2c_get_byte(radeon_connector->router_bus, |
1100 | radeon_connector->router.i2c_addr, | 1103 | radeon_connector->router.i2c_addr, |
1101 | 0x3, &val); | 1104 | 0x3, &val); |
@@ -1121,6 +1124,9 @@ void radeon_router_select_cd_port(struct radeon_connector *radeon_connector) | |||
1121 | if (!radeon_connector->router.cd_valid) | 1124 | if (!radeon_connector->router.cd_valid) |
1122 | return; | 1125 | return; |
1123 | 1126 | ||
1127 | if (!radeon_connector->router_bus) | ||
1128 | return; | ||
1129 | |||
1124 | radeon_i2c_get_byte(radeon_connector->router_bus, | 1130 | radeon_i2c_get_byte(radeon_connector->router_bus, |
1125 | radeon_connector->router.i2c_addr, | 1131 | radeon_connector->router.i2c_addr, |
1126 | 0x3, &val); | 1132 | 0x3, &val); |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index bf7d4c061451..bd58af658581 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -221,6 +221,22 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
221 | return -EINVAL; | 221 | return -EINVAL; |
222 | } | 222 | } |
223 | break; | 223 | break; |
224 | case RADEON_INFO_NUM_TILE_PIPES: | ||
225 | if (rdev->family >= CHIP_CAYMAN) | ||
226 | value = rdev->config.cayman.max_tile_pipes; | ||
227 | else if (rdev->family >= CHIP_CEDAR) | ||
228 | value = rdev->config.evergreen.max_tile_pipes; | ||
229 | else if (rdev->family >= CHIP_RV770) | ||
230 | value = rdev->config.rv770.max_tile_pipes; | ||
231 | else if (rdev->family >= CHIP_R600) | ||
232 | value = rdev->config.r600.max_tile_pipes; | ||
233 | else { | ||
234 | return -EINVAL; | ||
235 | } | ||
236 | break; | ||
237 | case RADEON_INFO_FUSION_GART_WORKING: | ||
238 | value = 1; | ||
239 | break; | ||
224 | default: | 240 | default: |
225 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); | 241 | DRM_DEBUG_KMS("Invalid request %d\n", info->request); |
226 | return -EINVAL; | 242 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c index 5b54268ed6b2..2f46e0c8df53 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_encoders.c | |||
@@ -269,7 +269,7 @@ static const struct drm_encoder_helper_funcs radeon_legacy_lvds_helper_funcs = { | |||
269 | .disable = radeon_legacy_encoder_disable, | 269 | .disable = radeon_legacy_encoder_disable, |
270 | }; | 270 | }; |
271 | 271 | ||
272 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE | 272 | #if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) |
273 | 273 | ||
274 | #define MAX_RADEON_LEVEL 0xFF | 274 | #define MAX_RADEON_LEVEL 0xFF |
275 | 275 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 08de669e025a..86eda1ea94df 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "drmP.h" | 23 | #include "drmP.h" |
24 | #include "radeon.h" | 24 | #include "radeon.h" |
25 | #include "avivod.h" | 25 | #include "avivod.h" |
26 | #include "atom.h" | ||
26 | #ifdef CONFIG_ACPI | 27 | #ifdef CONFIG_ACPI |
27 | #include <linux/acpi.h> | 28 | #include <linux/acpi.h> |
28 | #endif | 29 | #endif |
@@ -535,7 +536,11 @@ void radeon_pm_resume(struct radeon_device *rdev) | |||
535 | /* set up the default clocks if the MC ucode is loaded */ | 536 | /* set up the default clocks if the MC ucode is loaded */ |
536 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { | 537 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { |
537 | if (rdev->pm.default_vddc) | 538 | if (rdev->pm.default_vddc) |
538 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc); | 539 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, |
540 | SET_VOLTAGE_TYPE_ASIC_VDDC); | ||
541 | if (rdev->pm.default_vddci) | ||
542 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddci, | ||
543 | SET_VOLTAGE_TYPE_ASIC_VDDCI); | ||
539 | if (rdev->pm.default_sclk) | 544 | if (rdev->pm.default_sclk) |
540 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); | 545 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); |
541 | if (rdev->pm.default_mclk) | 546 | if (rdev->pm.default_mclk) |
@@ -548,6 +553,7 @@ void radeon_pm_resume(struct radeon_device *rdev) | |||
548 | rdev->pm.current_sclk = rdev->pm.default_sclk; | 553 | rdev->pm.current_sclk = rdev->pm.default_sclk; |
549 | rdev->pm.current_mclk = rdev->pm.default_mclk; | 554 | rdev->pm.current_mclk = rdev->pm.default_mclk; |
550 | rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; | 555 | rdev->pm.current_vddc = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.voltage; |
556 | rdev->pm.current_vddci = rdev->pm.power_state[rdev->pm.default_power_state_index].clock_info[0].voltage.vddci; | ||
551 | if (rdev->pm.pm_method == PM_METHOD_DYNPM | 557 | if (rdev->pm.pm_method == PM_METHOD_DYNPM |
552 | && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { | 558 | && rdev->pm.dynpm_state == DYNPM_STATE_SUSPENDED) { |
553 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; | 559 | rdev->pm.dynpm_state = DYNPM_STATE_ACTIVE; |
@@ -585,7 +591,8 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
585 | /* set up the default clocks if the MC ucode is loaded */ | 591 | /* set up the default clocks if the MC ucode is loaded */ |
586 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { | 592 | if (ASIC_IS_DCE5(rdev) && rdev->mc_fw) { |
587 | if (rdev->pm.default_vddc) | 593 | if (rdev->pm.default_vddc) |
588 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc); | 594 | radeon_atom_set_voltage(rdev, rdev->pm.default_vddc, |
595 | SET_VOLTAGE_TYPE_ASIC_VDDC); | ||
589 | if (rdev->pm.default_sclk) | 596 | if (rdev->pm.default_sclk) |
590 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); | 597 | radeon_set_engine_clock(rdev, rdev->pm.default_sclk); |
591 | if (rdev->pm.default_mclk) | 598 | if (rdev->pm.default_mclk) |
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index bbc9cd823334..c6776e48fdde 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c | |||
@@ -248,7 +248,7 @@ void radeon_ib_pool_fini(struct radeon_device *rdev) | |||
248 | void radeon_ring_free_size(struct radeon_device *rdev) | 248 | void radeon_ring_free_size(struct radeon_device *rdev) |
249 | { | 249 | { |
250 | if (rdev->wb.enabled) | 250 | if (rdev->wb.enabled) |
251 | rdev->cp.rptr = rdev->wb.wb[RADEON_WB_CP_RPTR_OFFSET/4]; | 251 | rdev->cp.rptr = le32_to_cpu(rdev->wb.wb[RADEON_WB_CP_RPTR_OFFSET/4]); |
252 | else { | 252 | else { |
253 | if (rdev->family >= CHIP_R600) | 253 | if (rdev->family >= CHIP_R600) |
254 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); | 254 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index af0da4ae3f55..92f1900dc7ca 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
@@ -708,6 +708,7 @@ r600 0x9400 | |||
708 | 0x00028D0C DB_RENDER_CONTROL | 708 | 0x00028D0C DB_RENDER_CONTROL |
709 | 0x00028D10 DB_RENDER_OVERRIDE | 709 | 0x00028D10 DB_RENDER_OVERRIDE |
710 | 0x0002880C DB_SHADER_CONTROL | 710 | 0x0002880C DB_SHADER_CONTROL |
711 | 0x00028D28 DB_SRESULTS_COMPARE_STATE0 | ||
711 | 0x00028D2C DB_SRESULTS_COMPARE_STATE1 | 712 | 0x00028D2C DB_SRESULTS_COMPARE_STATE1 |
712 | 0x00028430 DB_STENCILREFMASK | 713 | 0x00028430 DB_STENCILREFMASK |
713 | 0x00028434 DB_STENCILREFMASK_BF | 714 | 0x00028434 DB_STENCILREFMASK_BF |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 876cebc4b8ba..6e3b11e5abbe 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -114,7 +114,7 @@ void rs600_pm_misc(struct radeon_device *rdev) | |||
114 | udelay(voltage->delay); | 114 | udelay(voltage->delay); |
115 | } | 115 | } |
116 | } else if (voltage->type == VOLTAGE_VDDC) | 116 | } else if (voltage->type == VOLTAGE_VDDC) |
117 | radeon_atom_set_voltage(rdev, voltage->vddc_id); | 117 | radeon_atom_set_voltage(rdev, voltage->vddc_id, SET_VOLTAGE_TYPE_ASIC_VDDC); |
118 | 118 | ||
119 | dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); | 119 | dyn_pwrmgt_sclk_length = RREG32_PLL(DYN_PWRMGT_SCLK_LENGTH); |
120 | dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf); | 120 | dyn_pwrmgt_sclk_length &= ~REDUCED_POWER_SCLK_HILEN(0xf); |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index b974ac7df8df..ef8a5babe9f7 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -106,7 +106,7 @@ void rv770_pm_misc(struct radeon_device *rdev) | |||
106 | 106 | ||
107 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { | 107 | if ((voltage->type == VOLTAGE_SW) && voltage->voltage) { |
108 | if (voltage->voltage != rdev->pm.current_vddc) { | 108 | if (voltage->voltage != rdev->pm.current_vddc) { |
109 | radeon_atom_set_voltage(rdev, voltage->voltage); | 109 | radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); |
110 | rdev->pm.current_vddc = voltage->voltage; | 110 | rdev->pm.current_vddc = voltage->voltage; |
111 | DRM_DEBUG("Setting: v: %d\n", voltage->voltage); | 111 | DRM_DEBUG("Setting: v: %d\n", voltage->voltage); |
112 | } | 112 | } |
@@ -1255,9 +1255,6 @@ int rv770_init(struct radeon_device *rdev) | |||
1255 | { | 1255 | { |
1256 | int r; | 1256 | int r; |
1257 | 1257 | ||
1258 | r = radeon_dummy_page_init(rdev); | ||
1259 | if (r) | ||
1260 | return r; | ||
1261 | /* This don't do much */ | 1258 | /* This don't do much */ |
1262 | r = radeon_gem_init(rdev); | 1259 | r = radeon_gem_init(rdev); |
1263 | if (r) | 1260 | if (r) |
@@ -1372,7 +1369,6 @@ void rv770_fini(struct radeon_device *rdev) | |||
1372 | radeon_atombios_fini(rdev); | 1369 | radeon_atombios_fini(rdev); |
1373 | kfree(rdev->bios); | 1370 | kfree(rdev->bios); |
1374 | rdev->bios = NULL; | 1371 | rdev->bios = NULL; |
1375 | radeon_dummy_page_fini(rdev); | ||
1376 | } | 1372 | } |
1377 | 1373 | ||
1378 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev) | 1374 | static void rv770_pcie_gen2_enable(struct radeon_device *rdev) |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc.c b/drivers/gpu/drm/ttm/ttm_page_alloc.c index 737a2a2e46a5..9d9d92945f8c 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc.c | |||
@@ -683,22 +683,14 @@ int ttm_get_pages(struct list_head *pages, int flags, | |||
683 | gfp_flags |= GFP_HIGHUSER; | 683 | gfp_flags |= GFP_HIGHUSER; |
684 | 684 | ||
685 | for (r = 0; r < count; ++r) { | 685 | for (r = 0; r < count; ++r) { |
686 | if ((flags & TTM_PAGE_FLAG_DMA32) && dma_address) { | 686 | p = alloc_page(gfp_flags); |
687 | void *addr; | ||
688 | addr = dma_alloc_coherent(NULL, PAGE_SIZE, | ||
689 | &dma_address[r], | ||
690 | gfp_flags); | ||
691 | if (addr == NULL) | ||
692 | return -ENOMEM; | ||
693 | p = virt_to_page(addr); | ||
694 | } else | ||
695 | p = alloc_page(gfp_flags); | ||
696 | if (!p) { | 687 | if (!p) { |
697 | 688 | ||
698 | printk(KERN_ERR TTM_PFX | 689 | printk(KERN_ERR TTM_PFX |
699 | "Unable to allocate page."); | 690 | "Unable to allocate page."); |
700 | return -ENOMEM; | 691 | return -ENOMEM; |
701 | } | 692 | } |
693 | |||
702 | list_add(&p->lru, pages); | 694 | list_add(&p->lru, pages); |
703 | } | 695 | } |
704 | return 0; | 696 | return 0; |
@@ -746,24 +738,12 @@ void ttm_put_pages(struct list_head *pages, unsigned page_count, int flags, | |||
746 | unsigned long irq_flags; | 738 | unsigned long irq_flags; |
747 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); | 739 | struct ttm_page_pool *pool = ttm_get_pool(flags, cstate); |
748 | struct page *p, *tmp; | 740 | struct page *p, *tmp; |
749 | unsigned r; | ||
750 | 741 | ||
751 | if (pool == NULL) { | 742 | if (pool == NULL) { |
752 | /* No pool for this memory type so free the pages */ | 743 | /* No pool for this memory type so free the pages */ |
753 | 744 | ||
754 | r = page_count-1; | ||
755 | list_for_each_entry_safe(p, tmp, pages, lru) { | 745 | list_for_each_entry_safe(p, tmp, pages, lru) { |
756 | if ((flags & TTM_PAGE_FLAG_DMA32) && dma_address) { | 746 | __free_page(p); |
757 | void *addr = page_address(p); | ||
758 | WARN_ON(!addr || !dma_address[r]); | ||
759 | if (addr) | ||
760 | dma_free_coherent(NULL, PAGE_SIZE, | ||
761 | addr, | ||
762 | dma_address[r]); | ||
763 | dma_address[r] = 0; | ||
764 | } else | ||
765 | __free_page(p); | ||
766 | r--; | ||
767 | } | 747 | } |
768 | /* Make the pages list empty */ | 748 | /* Make the pages list empty */ |
769 | INIT_LIST_HEAD(pages); | 749 | INIT_LIST_HEAD(pages); |
diff --git a/drivers/gpu/stub/Kconfig b/drivers/gpu/stub/Kconfig index 70e60a4bb678..419917955bf6 100644 --- a/drivers/gpu/stub/Kconfig +++ b/drivers/gpu/stub/Kconfig | |||
@@ -5,6 +5,7 @@ config STUB_POULSBO | |||
5 | # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled | 5 | # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled |
6 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick | 6 | # but for select to work, need to select ACPI_VIDEO's dependencies, ick |
7 | select BACKLIGHT_CLASS_DEVICE if ACPI | 7 | select BACKLIGHT_CLASS_DEVICE if ACPI |
8 | select VIDEO_OUTPUT_CONTROL if ACPI | ||
8 | select INPUT if ACPI | 9 | select INPUT if ACPI |
9 | select ACPI_VIDEO if ACPI | 10 | select ACPI_VIDEO if ACPI |
10 | select THERMAL if ACPI | 11 | select THERMAL if ACPI |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 060ef6327876..50e40dbd8bb6 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -110,8 +110,7 @@ config SENSORS_ADM1021 | |||
110 | help | 110 | help |
111 | If you say yes here you get support for Analog Devices ADM1021 | 111 | If you say yes here you get support for Analog Devices ADM1021 |
112 | and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, | 112 | and ADM1023 sensor chips and clones: Maxim MAX1617 and MAX1617A, |
113 | Genesys Logic GL523SM, National Semiconductor LM84, TI THMC10, | 113 | Genesys Logic GL523SM, National Semiconductor LM84 and TI THMC10. |
114 | and the XEON processor built-in sensor. | ||
115 | 114 | ||
116 | This driver can also be built as a module. If so, the module | 115 | This driver can also be built as a module. If so, the module |
117 | will be called adm1021. | 116 | will be called adm1021. |
@@ -618,10 +617,10 @@ config SENSORS_LM90 | |||
618 | depends on I2C | 617 | depends on I2C |
619 | help | 618 | help |
620 | If you say yes here you get support for National Semiconductor LM90, | 619 | If you say yes here you get support for National Semiconductor LM90, |
621 | LM86, LM89 and LM99, Analog Devices ADM1032 and ADT7461, Maxim | 620 | LM86, LM89 and LM99, Analog Devices ADM1032, ADT7461, and ADT7461A, |
622 | MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, | 621 | Maxim MAX6646, MAX6647, MAX6648, MAX6649, MAX6657, MAX6658, MAX6659, |
623 | MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, and Winbond/Nuvoton | 622 | MAX6680, MAX6681, MAX6692, MAX6695, MAX6696, ON Semiconductor NCT1008, |
624 | W83L771W/G/AWG/ASG sensor chips. | 623 | and Winbond/Nuvoton W83L771W/G/AWG/ASG sensor chips. |
625 | 624 | ||
626 | This driver can also be built as a module. If so, the module | 625 | This driver can also be built as a module. If so, the module |
627 | will be called lm90. | 626 | will be called lm90. |
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c index 250d099ca398..da72dc12068c 100644 --- a/drivers/hwmon/lm85.c +++ b/drivers/hwmon/lm85.c | |||
@@ -1094,6 +1094,7 @@ static struct attribute *lm85_attributes_minctl[] = { | |||
1094 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, | 1094 | &sensor_dev_attr_pwm1_auto_pwm_minctl.dev_attr.attr, |
1095 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, | 1095 | &sensor_dev_attr_pwm2_auto_pwm_minctl.dev_attr.attr, |
1096 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, | 1096 | &sensor_dev_attr_pwm3_auto_pwm_minctl.dev_attr.attr, |
1097 | NULL | ||
1097 | }; | 1098 | }; |
1098 | 1099 | ||
1099 | static const struct attribute_group lm85_group_minctl = { | 1100 | static const struct attribute_group lm85_group_minctl = { |
@@ -1104,6 +1105,7 @@ static struct attribute *lm85_attributes_temp_off[] = { | |||
1104 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, | 1105 | &sensor_dev_attr_temp1_auto_temp_off.dev_attr.attr, |
1105 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, | 1106 | &sensor_dev_attr_temp2_auto_temp_off.dev_attr.attr, |
1106 | &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, | 1107 | &sensor_dev_attr_temp3_auto_temp_off.dev_attr.attr, |
1108 | NULL | ||
1107 | }; | 1109 | }; |
1108 | 1110 | ||
1109 | static const struct attribute_group lm85_group_temp_off = { | 1111 | static const struct attribute_group lm85_group_temp_off = { |
@@ -1329,11 +1331,11 @@ static int lm85_probe(struct i2c_client *client, | |||
1329 | if (data->type != emc6d103s) { | 1331 | if (data->type != emc6d103s) { |
1330 | err = sysfs_create_group(&client->dev.kobj, &lm85_group_minctl); | 1332 | err = sysfs_create_group(&client->dev.kobj, &lm85_group_minctl); |
1331 | if (err) | 1333 | if (err) |
1332 | goto err_kfree; | 1334 | goto err_remove_files; |
1333 | err = sysfs_create_group(&client->dev.kobj, | 1335 | err = sysfs_create_group(&client->dev.kobj, |
1334 | &lm85_group_temp_off); | 1336 | &lm85_group_temp_off); |
1335 | if (err) | 1337 | if (err) |
1336 | goto err_kfree; | 1338 | goto err_remove_files; |
1337 | } | 1339 | } |
1338 | 1340 | ||
1339 | /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used | 1341 | /* The ADT7463/68 have an optional VRM 10 mode where pin 21 is used |
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index c43b4e9f96a9..2f94f9504804 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
@@ -49,10 +49,10 @@ | |||
49 | * chips, but support three temperature sensors instead of two. MAX6695 | 49 | * chips, but support three temperature sensors instead of two. MAX6695 |
50 | * and MAX6696 only differ in the pinout so they can be treated identically. | 50 | * and MAX6696 only differ in the pinout so they can be treated identically. |
51 | * | 51 | * |
52 | * This driver also supports the ADT7461 chip from Analog Devices. | 52 | * This driver also supports ADT7461 and ADT7461A from Analog Devices as well as |
53 | * It's supported in both compatibility and extended mode. It is mostly | 53 | * NCT1008 from ON Semiconductor. The chips are supported in both compatibility |
54 | * compatible with LM90 except for a data format difference for the | 54 | * and extended mode. They are mostly compatible with LM90 except for a data |
55 | * temperature value registers. | 55 | * format difference for the temperature value registers. |
56 | * | 56 | * |
57 | * Since the LM90 was the first chipset supported by this driver, most | 57 | * Since the LM90 was the first chipset supported by this driver, most |
58 | * comments will refer to this chipset, but are actually general and | 58 | * comments will refer to this chipset, but are actually general and |
@@ -88,9 +88,10 @@ | |||
88 | * Addresses to scan | 88 | * Addresses to scan |
89 | * Address is fully defined internally and cannot be changed except for | 89 | * Address is fully defined internally and cannot be changed except for |
90 | * MAX6659, MAX6680 and MAX6681. | 90 | * MAX6659, MAX6680 and MAX6681. |
91 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, MAX6649, MAX6657, | 91 | * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, ADT7461A, MAX6649, |
92 | * MAX6658 and W83L771 have address 0x4c. | 92 | * MAX6657, MAX6658, NCT1008 and W83L771 have address 0x4c. |
93 | * ADM1032-2, ADT7461-2, LM89-1, LM99-1 and MAX6646 have address 0x4d. | 93 | * ADM1032-2, ADT7461-2, ADT7461A-2, LM89-1, LM99-1, MAX6646, and NCT1008D |
94 | * have address 0x4d. | ||
94 | * MAX6647 has address 0x4e. | 95 | * MAX6647 has address 0x4e. |
95 | * MAX6659 can have address 0x4c, 0x4d or 0x4e. | 96 | * MAX6659 can have address 0x4c, 0x4d or 0x4e. |
96 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, | 97 | * MAX6680 and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, |
@@ -174,6 +175,7 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, | |||
174 | static const struct i2c_device_id lm90_id[] = { | 175 | static const struct i2c_device_id lm90_id[] = { |
175 | { "adm1032", adm1032 }, | 176 | { "adm1032", adm1032 }, |
176 | { "adt7461", adt7461 }, | 177 | { "adt7461", adt7461 }, |
178 | { "adt7461a", adt7461 }, | ||
177 | { "lm90", lm90 }, | 179 | { "lm90", lm90 }, |
178 | { "lm86", lm86 }, | 180 | { "lm86", lm86 }, |
179 | { "lm89", lm86 }, | 181 | { "lm89", lm86 }, |
@@ -188,6 +190,7 @@ static const struct i2c_device_id lm90_id[] = { | |||
188 | { "max6681", max6680 }, | 190 | { "max6681", max6680 }, |
189 | { "max6695", max6696 }, | 191 | { "max6695", max6696 }, |
190 | { "max6696", max6696 }, | 192 | { "max6696", max6696 }, |
193 | { "nct1008", adt7461 }, | ||
191 | { "w83l771", w83l771 }, | 194 | { "w83l771", w83l771 }, |
192 | { } | 195 | { } |
193 | }; | 196 | }; |
@@ -1153,6 +1156,11 @@ static int lm90_detect(struct i2c_client *new_client, | |||
1153 | && (reg_config1 & 0x1B) == 0x00 | 1156 | && (reg_config1 & 0x1B) == 0x00 |
1154 | && reg_convrate <= 0x0A) { | 1157 | && reg_convrate <= 0x0A) { |
1155 | name = "adt7461"; | 1158 | name = "adt7461"; |
1159 | } else | ||
1160 | if (chip_id == 0x57 /* ADT7461A, NCT1008 */ | ||
1161 | && (reg_config1 & 0x1B) == 0x00 | ||
1162 | && reg_convrate <= 0x0A) { | ||
1163 | name = "adt7461a"; | ||
1156 | } | 1164 | } |
1157 | } else | 1165 | } else |
1158 | if (man_id == 0x4D) { /* Maxim */ | 1166 | if (man_id == 0x4D) { /* Maxim */ |
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c index edfb92e41735..196ffafafd88 100644 --- a/drivers/hwmon/pmbus_core.c +++ b/drivers/hwmon/pmbus_core.c | |||
@@ -139,7 +139,6 @@ struct pmbus_data { | |||
139 | * A single status register covers multiple attributes, | 139 | * A single status register covers multiple attributes, |
140 | * so we keep them all together. | 140 | * so we keep them all together. |
141 | */ | 141 | */ |
142 | u8 status_bits; | ||
143 | u8 status[PB_NUM_STATUS_REG]; | 142 | u8 status[PB_NUM_STATUS_REG]; |
144 | 143 | ||
145 | u8 currpage; | 144 | u8 currpage; |
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index de5819199e2e..57240740b161 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c | |||
@@ -98,7 +98,6 @@ static const struct attribute_group twl4030_madc_group = { | |||
98 | static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev) | 98 | static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev) |
99 | { | 99 | { |
100 | int ret; | 100 | int ret; |
101 | int status; | ||
102 | struct device *hwmon; | 101 | struct device *hwmon; |
103 | 102 | ||
104 | ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group); | 103 | ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group); |
@@ -107,7 +106,7 @@ static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev) | |||
107 | hwmon = hwmon_device_register(&pdev->dev); | 106 | hwmon = hwmon_device_register(&pdev->dev); |
108 | if (IS_ERR(hwmon)) { | 107 | if (IS_ERR(hwmon)) { |
109 | dev_err(&pdev->dev, "hwmon_device_register failed.\n"); | 108 | dev_err(&pdev->dev, "hwmon_device_register failed.\n"); |
110 | status = PTR_ERR(hwmon); | 109 | ret = PTR_ERR(hwmon); |
111 | goto err_reg; | 110 | goto err_reg; |
112 | } | 111 | } |
113 | 112 | ||
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 38319a69bd0a..d6d58684712b 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c | |||
@@ -232,9 +232,17 @@ static int i2c_inb(struct i2c_adapter *i2c_adap) | |||
232 | * Sanity check for the adapter hardware - check the reaction of | 232 | * Sanity check for the adapter hardware - check the reaction of |
233 | * the bus lines only if it seems to be idle. | 233 | * the bus lines only if it seems to be idle. |
234 | */ | 234 | */ |
235 | static int test_bus(struct i2c_algo_bit_data *adap, char *name) | 235 | static int test_bus(struct i2c_adapter *i2c_adap) |
236 | { | 236 | { |
237 | int scl, sda; | 237 | struct i2c_algo_bit_data *adap = i2c_adap->algo_data; |
238 | const char *name = i2c_adap->name; | ||
239 | int scl, sda, ret; | ||
240 | |||
241 | if (adap->pre_xfer) { | ||
242 | ret = adap->pre_xfer(i2c_adap); | ||
243 | if (ret < 0) | ||
244 | return -ENODEV; | ||
245 | } | ||
238 | 246 | ||
239 | if (adap->getscl == NULL) | 247 | if (adap->getscl == NULL) |
240 | pr_info("%s: Testing SDA only, SCL is not readable\n", name); | 248 | pr_info("%s: Testing SDA only, SCL is not readable\n", name); |
@@ -297,11 +305,19 @@ static int test_bus(struct i2c_algo_bit_data *adap, char *name) | |||
297 | "while pulling SCL high!\n", name); | 305 | "while pulling SCL high!\n", name); |
298 | goto bailout; | 306 | goto bailout; |
299 | } | 307 | } |
308 | |||
309 | if (adap->post_xfer) | ||
310 | adap->post_xfer(i2c_adap); | ||
311 | |||
300 | pr_info("%s: Test OK\n", name); | 312 | pr_info("%s: Test OK\n", name); |
301 | return 0; | 313 | return 0; |
302 | bailout: | 314 | bailout: |
303 | sdahi(adap); | 315 | sdahi(adap); |
304 | sclhi(adap); | 316 | sclhi(adap); |
317 | |||
318 | if (adap->post_xfer) | ||
319 | adap->post_xfer(i2c_adap); | ||
320 | |||
305 | return -ENODEV; | 321 | return -ENODEV; |
306 | } | 322 | } |
307 | 323 | ||
@@ -607,7 +623,7 @@ static int __i2c_bit_add_bus(struct i2c_adapter *adap, | |||
607 | int ret; | 623 | int ret; |
608 | 624 | ||
609 | if (bit_test) { | 625 | if (bit_test) { |
610 | ret = test_bus(bit_adap, adap->name); | 626 | ret = test_bus(adap); |
611 | if (ret < 0) | 627 | if (ret < 0) |
612 | return -ENODEV; | 628 | return -ENODEV; |
613 | } | 629 | } |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 72c0415f6f94..455e909bc768 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -134,10 +134,15 @@ | |||
134 | SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ | 134 | SMBHSTSTS_BUS_ERR | SMBHSTSTS_DEV_ERR | \ |
135 | SMBHSTSTS_INTR) | 135 | SMBHSTSTS_INTR) |
136 | 136 | ||
137 | /* Older devices have their ID defined in <linux/pci_ids.h> */ | ||
138 | #define PCI_DEVICE_ID_INTEL_COUGARPOINT_SMBUS 0x1c22 | ||
139 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 | ||
137 | /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ | 140 | /* Patsburg also has three 'Integrated Device Function' SMBus controllers */ |
138 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70 | 141 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0 0x1d70 |
139 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 | 142 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1 0x1d71 |
140 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 | 143 | #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2 0x1d72 |
144 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 | ||
145 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 | ||
141 | 146 | ||
142 | struct i801_priv { | 147 | struct i801_priv { |
143 | struct i2c_adapter adapter; | 148 | struct i2c_adapter adapter; |
diff --git a/drivers/i2c/busses/i2c-parport.c b/drivers/i2c/busses/i2c-parport.c index 0eb1515541e7..2dbba163b102 100644 --- a/drivers/i2c/busses/i2c-parport.c +++ b/drivers/i2c/busses/i2c-parport.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* ------------------------------------------------------------------------ * | 1 | /* ------------------------------------------------------------------------ * |
2 | * i2c-parport.c I2C bus over parallel port * | 2 | * i2c-parport.c I2C bus over parallel port * |
3 | * ------------------------------------------------------------------------ * | 3 | * ------------------------------------------------------------------------ * |
4 | Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org> | 4 | Copyright (C) 2003-2011 Jean Delvare <khali@linux-fr.org> |
5 | 5 | ||
6 | Based on older i2c-philips-par.c driver | 6 | Based on older i2c-philips-par.c driver |
7 | Copyright (C) 1995-2000 Simon G. Vogl | 7 | Copyright (C) 1995-2000 Simon G. Vogl |
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/i2c-algo-bit.h> | 33 | #include <linux/i2c-algo-bit.h> |
34 | #include <linux/i2c-smbus.h> | 34 | #include <linux/i2c-smbus.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/list.h> | ||
37 | #include <linux/mutex.h> | ||
36 | #include "i2c-parport.h" | 38 | #include "i2c-parport.h" |
37 | 39 | ||
38 | /* ----- Device list ------------------------------------------------------ */ | 40 | /* ----- Device list ------------------------------------------------------ */ |
@@ -43,10 +45,11 @@ struct i2c_par { | |||
43 | struct i2c_algo_bit_data algo_data; | 45 | struct i2c_algo_bit_data algo_data; |
44 | struct i2c_smbus_alert_setup alert_data; | 46 | struct i2c_smbus_alert_setup alert_data; |
45 | struct i2c_client *ara; | 47 | struct i2c_client *ara; |
46 | struct i2c_par *next; | 48 | struct list_head node; |
47 | }; | 49 | }; |
48 | 50 | ||
49 | static struct i2c_par *adapter_list; | 51 | static LIST_HEAD(adapter_list); |
52 | static DEFINE_MUTEX(adapter_list_lock); | ||
50 | 53 | ||
51 | /* ----- Low-level parallel port access ----------------------------------- */ | 54 | /* ----- Low-level parallel port access ----------------------------------- */ |
52 | 55 | ||
@@ -228,8 +231,9 @@ static void i2c_parport_attach (struct parport *port) | |||
228 | } | 231 | } |
229 | 232 | ||
230 | /* Add the new adapter to the list */ | 233 | /* Add the new adapter to the list */ |
231 | adapter->next = adapter_list; | 234 | mutex_lock(&adapter_list_lock); |
232 | adapter_list = adapter; | 235 | list_add_tail(&adapter->node, &adapter_list); |
236 | mutex_unlock(&adapter_list_lock); | ||
233 | return; | 237 | return; |
234 | 238 | ||
235 | ERROR1: | 239 | ERROR1: |
@@ -241,11 +245,11 @@ ERROR0: | |||
241 | 245 | ||
242 | static void i2c_parport_detach (struct parport *port) | 246 | static void i2c_parport_detach (struct parport *port) |
243 | { | 247 | { |
244 | struct i2c_par *adapter, *prev; | 248 | struct i2c_par *adapter, *_n; |
245 | 249 | ||
246 | /* Walk the list */ | 250 | /* Walk the list */ |
247 | for (prev = NULL, adapter = adapter_list; adapter; | 251 | mutex_lock(&adapter_list_lock); |
248 | prev = adapter, adapter = adapter->next) { | 252 | list_for_each_entry_safe(adapter, _n, &adapter_list, node) { |
249 | if (adapter->pdev->port == port) { | 253 | if (adapter->pdev->port == port) { |
250 | if (adapter->ara) { | 254 | if (adapter->ara) { |
251 | parport_disable_irq(port); | 255 | parport_disable_irq(port); |
@@ -259,14 +263,11 @@ static void i2c_parport_detach (struct parport *port) | |||
259 | 263 | ||
260 | parport_release(adapter->pdev); | 264 | parport_release(adapter->pdev); |
261 | parport_unregister_device(adapter->pdev); | 265 | parport_unregister_device(adapter->pdev); |
262 | if (prev) | 266 | list_del(&adapter->node); |
263 | prev->next = adapter->next; | ||
264 | else | ||
265 | adapter_list = adapter->next; | ||
266 | kfree(adapter); | 267 | kfree(adapter); |
267 | return; | ||
268 | } | 268 | } |
269 | } | 269 | } |
270 | mutex_unlock(&adapter_list_lock); | ||
270 | } | 271 | } |
271 | 272 | ||
272 | static struct parport_driver i2c_parport_driver = { | 273 | static struct parport_driver i2c_parport_driver = { |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 70c30e6bce0b..9a58994ff7ea 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -797,7 +797,8 @@ static int i2c_do_add_adapter(struct i2c_driver *driver, | |||
797 | 797 | ||
798 | /* Let legacy drivers scan this bus for matching devices */ | 798 | /* Let legacy drivers scan this bus for matching devices */ |
799 | if (driver->attach_adapter) { | 799 | if (driver->attach_adapter) { |
800 | dev_warn(&adap->dev, "attach_adapter method is deprecated\n"); | 800 | dev_warn(&adap->dev, "%s: attach_adapter method is deprecated\n", |
801 | driver->driver.name); | ||
801 | dev_warn(&adap->dev, "Please use another way to instantiate " | 802 | dev_warn(&adap->dev, "Please use another way to instantiate " |
802 | "your i2c_client\n"); | 803 | "your i2c_client\n"); |
803 | /* We ignore the return code; if it fails, too bad */ | 804 | /* We ignore the return code; if it fails, too bad */ |
@@ -984,7 +985,8 @@ static int i2c_do_del_adapter(struct i2c_driver *driver, | |||
984 | 985 | ||
985 | if (!driver->detach_adapter) | 986 | if (!driver->detach_adapter) |
986 | return 0; | 987 | return 0; |
987 | dev_warn(&adapter->dev, "detach_adapter method is deprecated\n"); | 988 | dev_warn(&adapter->dev, "%s: detach_adapter method is deprecated\n", |
989 | driver->driver.name); | ||
988 | res = driver->detach_adapter(adapter); | 990 | res = driver->detach_adapter(adapter); |
989 | if (res) | 991 | if (res) |
990 | dev_err(&adapter->dev, "detach_adapter failed (%d) " | 992 | dev_err(&adapter->dev, "detach_adapter failed (%d) " |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index fd1e11799137..a5ec5a7cb381 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -1782,7 +1782,6 @@ static int ide_cd_probe(ide_drive_t *drive) | |||
1782 | ide_cd_read_toc(drive, &sense); | 1782 | ide_cd_read_toc(drive, &sense); |
1783 | g->fops = &idecd_ops; | 1783 | g->fops = &idecd_ops; |
1784 | g->flags |= GENHD_FL_REMOVABLE; | 1784 | g->flags |= GENHD_FL_REMOVABLE; |
1785 | g->events = DISK_EVENT_MEDIA_CHANGE; | ||
1786 | add_disk(g); | 1785 | add_disk(g); |
1787 | return 0; | 1786 | return 0; |
1788 | 1787 | ||
diff --git a/drivers/ide/ide-cd_ioctl.c b/drivers/ide/ide-cd_ioctl.c index 2a6bc50e8a41..02caa7dd51c8 100644 --- a/drivers/ide/ide-cd_ioctl.c +++ b/drivers/ide/ide-cd_ioctl.c | |||
@@ -79,6 +79,12 @@ int ide_cdrom_drive_status(struct cdrom_device_info *cdi, int slot_nr) | |||
79 | return CDS_DRIVE_NOT_READY; | 79 | return CDS_DRIVE_NOT_READY; |
80 | } | 80 | } |
81 | 81 | ||
82 | /* | ||
83 | * ide-cd always generates media changed event if media is missing, which | ||
84 | * makes it impossible to use for proper event reporting, so disk->events | ||
85 | * is cleared to 0 and the following function is used only to trigger | ||
86 | * revalidation and never propagated to userland. | ||
87 | */ | ||
82 | unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi, | 88 | unsigned int ide_cdrom_check_events_real(struct cdrom_device_info *cdi, |
83 | unsigned int clearing, int slot_nr) | 89 | unsigned int clearing, int slot_nr) |
84 | { | 90 | { |
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c index c4ffd4888939..70ea8763567d 100644 --- a/drivers/ide/ide-gd.c +++ b/drivers/ide/ide-gd.c | |||
@@ -298,6 +298,12 @@ static unsigned int ide_gd_check_events(struct gendisk *disk, | |||
298 | return 0; | 298 | return 0; |
299 | } | 299 | } |
300 | 300 | ||
301 | /* | ||
302 | * The following is used to force revalidation on the first open on | ||
303 | * removeable devices, and never gets reported to userland as | ||
304 | * genhd->events is 0. This is intended as removeable ide disk | ||
305 | * can't really detect MEDIA_CHANGE events. | ||
306 | */ | ||
301 | ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED; | 307 | ret = drive->dev_flags & IDE_DFLAG_MEDIA_CHANGED; |
302 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; | 308 | drive->dev_flags &= ~IDE_DFLAG_MEDIA_CHANGED; |
303 | 309 | ||
@@ -413,7 +419,6 @@ static int ide_gd_probe(ide_drive_t *drive) | |||
413 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) | 419 | if (drive->dev_flags & IDE_DFLAG_REMOVABLE) |
414 | g->flags = GENHD_FL_REMOVABLE; | 420 | g->flags = GENHD_FL_REMOVABLE; |
415 | g->fops = &ide_gd_ops; | 421 | g->fops = &ide_gd_ops; |
416 | g->events = DISK_EVENT_MEDIA_CHANGE; | ||
417 | add_disk(g); | 422 | add_disk(g); |
418 | return 0; | 423 | return 0; |
419 | 424 | ||
diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 7de4b7ebffc5..d8ca0a0b970d 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c | |||
@@ -1799,7 +1799,7 @@ static int qib_6120_setup_reset(struct qib_devdata *dd) | |||
1799 | /* | 1799 | /* |
1800 | * Keep chip from being accessed until we are ready. Use | 1800 | * Keep chip from being accessed until we are ready. Use |
1801 | * writeq() directly, to allow the write even though QIB_PRESENT | 1801 | * writeq() directly, to allow the write even though QIB_PRESENT |
1802 | * isn't' set. | 1802 | * isn't set. |
1803 | */ | 1803 | */ |
1804 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT); | 1804 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT); |
1805 | dd->int_counter = 0; /* so we check interrupts work again */ | 1805 | dd->int_counter = 0; /* so we check interrupts work again */ |
diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index 74fe0360bec7..c765a2eb04cf 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c | |||
@@ -2111,7 +2111,7 @@ static int qib_setup_7220_reset(struct qib_devdata *dd) | |||
2111 | /* | 2111 | /* |
2112 | * Keep chip from being accessed until we are ready. Use | 2112 | * Keep chip from being accessed until we are ready. Use |
2113 | * writeq() directly, to allow the write even though QIB_PRESENT | 2113 | * writeq() directly, to allow the write even though QIB_PRESENT |
2114 | * isn't' set. | 2114 | * isn't set. |
2115 | */ | 2115 | */ |
2116 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT); | 2116 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT); |
2117 | dd->int_counter = 0; /* so we check interrupts work again */ | 2117 | dd->int_counter = 0; /* so we check interrupts work again */ |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 55de3cf3441c..6bab3eaea70f 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -3299,7 +3299,7 @@ static int qib_do_7322_reset(struct qib_devdata *dd) | |||
3299 | /* | 3299 | /* |
3300 | * Keep chip from being accessed until we are ready. Use | 3300 | * Keep chip from being accessed until we are ready. Use |
3301 | * writeq() directly, to allow the write even though QIB_PRESENT | 3301 | * writeq() directly, to allow the write even though QIB_PRESENT |
3302 | * isn't' set. | 3302 | * isn't set. |
3303 | */ | 3303 | */ |
3304 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT | QIB_BADINTR); | 3304 | dd->flags &= ~(QIB_INITTED | QIB_PRESENT | QIB_BADINTR); |
3305 | dd->flags |= QIB_DOING_RESET; | 3305 | dd->flags |= QIB_DOING_RESET; |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 7f42d3a454d2..88d8e4cb419a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -39,13 +39,13 @@ struct evdev { | |||
39 | }; | 39 | }; |
40 | 40 | ||
41 | struct evdev_client { | 41 | struct evdev_client { |
42 | int head; | 42 | unsigned int head; |
43 | int tail; | 43 | unsigned int tail; |
44 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ | 44 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ |
45 | struct fasync_struct *fasync; | 45 | struct fasync_struct *fasync; |
46 | struct evdev *evdev; | 46 | struct evdev *evdev; |
47 | struct list_head node; | 47 | struct list_head node; |
48 | int bufsize; | 48 | unsigned int bufsize; |
49 | struct input_event buffer[]; | 49 | struct input_event buffer[]; |
50 | }; | 50 | }; |
51 | 51 | ||
@@ -55,16 +55,25 @@ static DEFINE_MUTEX(evdev_table_mutex); | |||
55 | static void evdev_pass_event(struct evdev_client *client, | 55 | static void evdev_pass_event(struct evdev_client *client, |
56 | struct input_event *event) | 56 | struct input_event *event) |
57 | { | 57 | { |
58 | /* | 58 | /* Interrupts are disabled, just acquire the lock. */ |
59 | * Interrupts are disabled, just acquire the lock. | ||
60 | * Make sure we don't leave with the client buffer | ||
61 | * "empty" by having client->head == client->tail. | ||
62 | */ | ||
63 | spin_lock(&client->buffer_lock); | 59 | spin_lock(&client->buffer_lock); |
64 | do { | 60 | |
65 | client->buffer[client->head++] = *event; | 61 | client->buffer[client->head++] = *event; |
66 | client->head &= client->bufsize - 1; | 62 | client->head &= client->bufsize - 1; |
67 | } while (client->head == client->tail); | 63 | |
64 | if (unlikely(client->head == client->tail)) { | ||
65 | /* | ||
66 | * This effectively "drops" all unconsumed events, leaving | ||
67 | * EV_SYN/SYN_DROPPED plus the newest event in the queue. | ||
68 | */ | ||
69 | client->tail = (client->head - 2) & (client->bufsize - 1); | ||
70 | |||
71 | client->buffer[client->tail].time = event->time; | ||
72 | client->buffer[client->tail].type = EV_SYN; | ||
73 | client->buffer[client->tail].code = SYN_DROPPED; | ||
74 | client->buffer[client->tail].value = 0; | ||
75 | } | ||
76 | |||
68 | spin_unlock(&client->buffer_lock); | 77 | spin_unlock(&client->buffer_lock); |
69 | 78 | ||
70 | if (event->type == EV_SYN) | 79 | if (event->type == EV_SYN) |
diff --git a/drivers/input/input.c b/drivers/input/input.c index d6e8bd8a851c..ebbceedc92f4 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -1746,6 +1746,42 @@ void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int | |||
1746 | } | 1746 | } |
1747 | EXPORT_SYMBOL(input_set_capability); | 1747 | EXPORT_SYMBOL(input_set_capability); |
1748 | 1748 | ||
1749 | static unsigned int input_estimate_events_per_packet(struct input_dev *dev) | ||
1750 | { | ||
1751 | int mt_slots; | ||
1752 | int i; | ||
1753 | unsigned int events; | ||
1754 | |||
1755 | if (dev->mtsize) { | ||
1756 | mt_slots = dev->mtsize; | ||
1757 | } else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) { | ||
1758 | mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum - | ||
1759 | dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1, | ||
1760 | clamp(mt_slots, 2, 32); | ||
1761 | } else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) { | ||
1762 | mt_slots = 2; | ||
1763 | } else { | ||
1764 | mt_slots = 0; | ||
1765 | } | ||
1766 | |||
1767 | events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */ | ||
1768 | |||
1769 | for (i = 0; i < ABS_CNT; i++) { | ||
1770 | if (test_bit(i, dev->absbit)) { | ||
1771 | if (input_is_mt_axis(i)) | ||
1772 | events += mt_slots; | ||
1773 | else | ||
1774 | events++; | ||
1775 | } | ||
1776 | } | ||
1777 | |||
1778 | for (i = 0; i < REL_CNT; i++) | ||
1779 | if (test_bit(i, dev->relbit)) | ||
1780 | events++; | ||
1781 | |||
1782 | return events; | ||
1783 | } | ||
1784 | |||
1749 | #define INPUT_CLEANSE_BITMASK(dev, type, bits) \ | 1785 | #define INPUT_CLEANSE_BITMASK(dev, type, bits) \ |
1750 | do { \ | 1786 | do { \ |
1751 | if (!test_bit(EV_##type, dev->evbit)) \ | 1787 | if (!test_bit(EV_##type, dev->evbit)) \ |
@@ -1793,6 +1829,10 @@ int input_register_device(struct input_dev *dev) | |||
1793 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ | 1829 | /* Make sure that bitmasks not mentioned in dev->evbit are clean. */ |
1794 | input_cleanse_bitmasks(dev); | 1830 | input_cleanse_bitmasks(dev); |
1795 | 1831 | ||
1832 | if (!dev->hint_events_per_packet) | ||
1833 | dev->hint_events_per_packet = | ||
1834 | input_estimate_events_per_packet(dev); | ||
1835 | |||
1796 | /* | 1836 | /* |
1797 | * If delay and period are pre-set by the driver, then autorepeating | 1837 | * If delay and period are pre-set by the driver, then autorepeating |
1798 | * is handled by the driver itself and we don't do it in input.c. | 1838 | * is handled by the driver itself and we don't do it in input.c. |
diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 09bef79d9da1..a26922cf0e84 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c | |||
@@ -332,18 +332,20 @@ static int __devinit twl4030_kp_program(struct twl4030_keypad *kp) | |||
332 | static int __devinit twl4030_kp_probe(struct platform_device *pdev) | 332 | static int __devinit twl4030_kp_probe(struct platform_device *pdev) |
333 | { | 333 | { |
334 | struct twl4030_keypad_data *pdata = pdev->dev.platform_data; | 334 | struct twl4030_keypad_data *pdata = pdev->dev.platform_data; |
335 | const struct matrix_keymap_data *keymap_data = pdata->keymap_data; | 335 | const struct matrix_keymap_data *keymap_data; |
336 | struct twl4030_keypad *kp; | 336 | struct twl4030_keypad *kp; |
337 | struct input_dev *input; | 337 | struct input_dev *input; |
338 | u8 reg; | 338 | u8 reg; |
339 | int error; | 339 | int error; |
340 | 340 | ||
341 | if (!pdata || !pdata->rows || !pdata->cols || | 341 | if (!pdata || !pdata->rows || !pdata->cols || !pdata->keymap_data || |
342 | pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) { | 342 | pdata->rows > TWL4030_MAX_ROWS || pdata->cols > TWL4030_MAX_COLS) { |
343 | dev_err(&pdev->dev, "Invalid platform_data\n"); | 343 | dev_err(&pdev->dev, "Invalid platform_data\n"); |
344 | return -EINVAL; | 344 | return -EINVAL; |
345 | } | 345 | } |
346 | 346 | ||
347 | keymap_data = pdata->keymap_data; | ||
348 | |||
347 | kp = kzalloc(sizeof(*kp), GFP_KERNEL); | 349 | kp = kzalloc(sizeof(*kp), GFP_KERNEL); |
348 | input = input_allocate_device(); | 350 | input = input_allocate_device(); |
349 | if (!kp || !input) { | 351 | if (!kp || !input) { |
diff --git a/drivers/input/misc/xen-kbdfront.c b/drivers/input/misc/xen-kbdfront.c index 7077f9bf5ead..62bae99424e6 100644 --- a/drivers/input/misc/xen-kbdfront.c +++ b/drivers/input/misc/xen-kbdfront.c | |||
@@ -303,7 +303,7 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, | |||
303 | enum xenbus_state backend_state) | 303 | enum xenbus_state backend_state) |
304 | { | 304 | { |
305 | struct xenkbd_info *info = dev_get_drvdata(&dev->dev); | 305 | struct xenkbd_info *info = dev_get_drvdata(&dev->dev); |
306 | int val; | 306 | int ret, val; |
307 | 307 | ||
308 | switch (backend_state) { | 308 | switch (backend_state) { |
309 | case XenbusStateInitialising: | 309 | case XenbusStateInitialising: |
@@ -316,6 +316,17 @@ static void xenkbd_backend_changed(struct xenbus_device *dev, | |||
316 | 316 | ||
317 | case XenbusStateInitWait: | 317 | case XenbusStateInitWait: |
318 | InitWait: | 318 | InitWait: |
319 | ret = xenbus_scanf(XBT_NIL, info->xbdev->otherend, | ||
320 | "feature-abs-pointer", "%d", &val); | ||
321 | if (ret < 0) | ||
322 | val = 0; | ||
323 | if (val) { | ||
324 | ret = xenbus_printf(XBT_NIL, info->xbdev->nodename, | ||
325 | "request-abs-pointer", "1"); | ||
326 | if (ret) | ||
327 | pr_warning("xenkbd: can't request abs-pointer"); | ||
328 | } | ||
329 | |||
319 | xenbus_switch_state(dev, XenbusStateConnected); | 330 | xenbus_switch_state(dev, XenbusStateConnected); |
320 | break; | 331 | break; |
321 | 332 | ||
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index efa06882de00..45f93d0f5592 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -399,31 +399,34 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) | |||
399 | IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) { | 399 | IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) { |
400 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); | 400 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); |
401 | err = -EBUSY; | 401 | err = -EBUSY; |
402 | goto fail2; | 402 | goto fail1; |
403 | } | 403 | } |
404 | 404 | ||
405 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, | 405 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, |
406 | IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) { | 406 | IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) { |
407 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); | 407 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); |
408 | err = -EBUSY; | 408 | err = -EBUSY; |
409 | goto fail3; | 409 | goto fail2; |
410 | } | 410 | } |
411 | 411 | ||
412 | serio_set_drvdata(serio, ts); | 412 | serio_set_drvdata(serio, ts); |
413 | 413 | ||
414 | err = serio_open(serio, drv); | 414 | err = serio_open(serio, drv); |
415 | if (err) | 415 | if (err) |
416 | return err; | 416 | goto fail3; |
417 | 417 | ||
418 | //h3600_flite_control(1, 25); /* default brightness */ | 418 | //h3600_flite_control(1, 25); /* default brightness */ |
419 | input_register_device(ts->dev); | 419 | err = input_register_device(ts->dev); |
420 | if (err) | ||
421 | goto fail4; | ||
420 | 422 | ||
421 | return 0; | 423 | return 0; |
422 | 424 | ||
423 | fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | 425 | fail4: serio_close(serio); |
426 | fail3: serio_set_drvdata(serio, NULL); | ||
427 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | ||
424 | fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); | 428 | fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); |
425 | fail1: serio_set_drvdata(serio, NULL); | 429 | fail1: input_free_device(input_dev); |
426 | input_free_device(input_dev); | ||
427 | kfree(ts); | 430 | kfree(ts); |
428 | return err; | 431 | return err; |
429 | } | 432 | } |
diff --git a/drivers/input/touchscreen/wm831x-ts.c b/drivers/input/touchscreen/wm831x-ts.c index 6ae054f8e0aa..9175d49d2546 100644 --- a/drivers/input/touchscreen/wm831x-ts.c +++ b/drivers/input/touchscreen/wm831x-ts.c | |||
@@ -68,8 +68,23 @@ struct wm831x_ts { | |||
68 | unsigned int pd_irq; | 68 | unsigned int pd_irq; |
69 | bool pressure; | 69 | bool pressure; |
70 | bool pen_down; | 70 | bool pen_down; |
71 | struct work_struct pd_data_work; | ||
71 | }; | 72 | }; |
72 | 73 | ||
74 | static void wm831x_pd_data_work(struct work_struct *work) | ||
75 | { | ||
76 | struct wm831x_ts *wm831x_ts = | ||
77 | container_of(work, struct wm831x_ts, pd_data_work); | ||
78 | |||
79 | if (wm831x_ts->pen_down) { | ||
80 | enable_irq(wm831x_ts->data_irq); | ||
81 | dev_dbg(wm831x_ts->wm831x->dev, "IRQ PD->DATA done\n"); | ||
82 | } else { | ||
83 | enable_irq(wm831x_ts->pd_irq); | ||
84 | dev_dbg(wm831x_ts->wm831x->dev, "IRQ DATA->PD done\n"); | ||
85 | } | ||
86 | } | ||
87 | |||
73 | static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) | 88 | static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) |
74 | { | 89 | { |
75 | struct wm831x_ts *wm831x_ts = irq_data; | 90 | struct wm831x_ts *wm831x_ts = irq_data; |
@@ -110,6 +125,9 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) | |||
110 | } | 125 | } |
111 | 126 | ||
112 | if (!wm831x_ts->pen_down) { | 127 | if (!wm831x_ts->pen_down) { |
128 | /* Switch from data to pen down */ | ||
129 | dev_dbg(wm831x->dev, "IRQ DATA->PD\n"); | ||
130 | |||
113 | disable_irq_nosync(wm831x_ts->data_irq); | 131 | disable_irq_nosync(wm831x_ts->data_irq); |
114 | 132 | ||
115 | /* Don't need data any more */ | 133 | /* Don't need data any more */ |
@@ -128,6 +146,10 @@ static irqreturn_t wm831x_ts_data_irq(int irq, void *irq_data) | |||
128 | ABS_PRESSURE, 0); | 146 | ABS_PRESSURE, 0); |
129 | 147 | ||
130 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0); | 148 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 0); |
149 | |||
150 | schedule_work(&wm831x_ts->pd_data_work); | ||
151 | } else { | ||
152 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1); | ||
131 | } | 153 | } |
132 | 154 | ||
133 | input_sync(wm831x_ts->input_dev); | 155 | input_sync(wm831x_ts->input_dev); |
@@ -141,6 +163,11 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data) | |||
141 | struct wm831x *wm831x = wm831x_ts->wm831x; | 163 | struct wm831x *wm831x = wm831x_ts->wm831x; |
142 | int ena = 0; | 164 | int ena = 0; |
143 | 165 | ||
166 | if (wm831x_ts->pen_down) | ||
167 | return IRQ_HANDLED; | ||
168 | |||
169 | disable_irq_nosync(wm831x_ts->pd_irq); | ||
170 | |||
144 | /* Start collecting data */ | 171 | /* Start collecting data */ |
145 | if (wm831x_ts->pressure) | 172 | if (wm831x_ts->pressure) |
146 | ena |= WM831X_TCH_Z_ENA; | 173 | ena |= WM831X_TCH_Z_ENA; |
@@ -149,14 +176,14 @@ static irqreturn_t wm831x_ts_pen_down_irq(int irq, void *irq_data) | |||
149 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, | 176 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, |
150 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena); | 177 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | ena); |
151 | 178 | ||
152 | input_report_key(wm831x_ts->input_dev, BTN_TOUCH, 1); | ||
153 | input_sync(wm831x_ts->input_dev); | ||
154 | |||
155 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, | 179 | wm831x_set_bits(wm831x, WM831X_INTERRUPT_STATUS_1, |
156 | WM831X_TCHPD_EINT, WM831X_TCHPD_EINT); | 180 | WM831X_TCHPD_EINT, WM831X_TCHPD_EINT); |
157 | 181 | ||
158 | wm831x_ts->pen_down = true; | 182 | wm831x_ts->pen_down = true; |
159 | enable_irq(wm831x_ts->data_irq); | 183 | |
184 | /* Switch from pen down to data */ | ||
185 | dev_dbg(wm831x->dev, "IRQ PD->DATA\n"); | ||
186 | schedule_work(&wm831x_ts->pd_data_work); | ||
160 | 187 | ||
161 | return IRQ_HANDLED; | 188 | return IRQ_HANDLED; |
162 | } | 189 | } |
@@ -182,13 +209,28 @@ static void wm831x_ts_input_close(struct input_dev *idev) | |||
182 | struct wm831x_ts *wm831x_ts = input_get_drvdata(idev); | 209 | struct wm831x_ts *wm831x_ts = input_get_drvdata(idev); |
183 | struct wm831x *wm831x = wm831x_ts->wm831x; | 210 | struct wm831x *wm831x = wm831x_ts->wm831x; |
184 | 211 | ||
212 | /* Shut the controller down, disabling all other functionality too */ | ||
185 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | 213 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, |
186 | WM831X_TCH_ENA | WM831X_TCH_CVT_ENA | | 214 | WM831X_TCH_ENA | WM831X_TCH_X_ENA | |
187 | WM831X_TCH_X_ENA | WM831X_TCH_Y_ENA | | 215 | WM831X_TCH_Y_ENA | WM831X_TCH_Z_ENA, 0); |
188 | WM831X_TCH_Z_ENA, 0); | ||
189 | 216 | ||
190 | if (wm831x_ts->pen_down) | 217 | /* Make sure any pending IRQs are done, the above will prevent |
218 | * new ones firing. | ||
219 | */ | ||
220 | synchronize_irq(wm831x_ts->data_irq); | ||
221 | synchronize_irq(wm831x_ts->pd_irq); | ||
222 | |||
223 | /* Make sure the IRQ completion work is quiesced */ | ||
224 | flush_work_sync(&wm831x_ts->pd_data_work); | ||
225 | |||
226 | /* If we ended up with the pen down then make sure we revert back | ||
227 | * to pen detection state for the next time we start up. | ||
228 | */ | ||
229 | if (wm831x_ts->pen_down) { | ||
191 | disable_irq(wm831x_ts->data_irq); | 230 | disable_irq(wm831x_ts->data_irq); |
231 | enable_irq(wm831x_ts->pd_irq); | ||
232 | wm831x_ts->pen_down = false; | ||
233 | } | ||
192 | } | 234 | } |
193 | 235 | ||
194 | static __devinit int wm831x_ts_probe(struct platform_device *pdev) | 236 | static __devinit int wm831x_ts_probe(struct platform_device *pdev) |
@@ -198,7 +240,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) | |||
198 | struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent); | 240 | struct wm831x_pdata *core_pdata = dev_get_platdata(pdev->dev.parent); |
199 | struct wm831x_touch_pdata *pdata = NULL; | 241 | struct wm831x_touch_pdata *pdata = NULL; |
200 | struct input_dev *input_dev; | 242 | struct input_dev *input_dev; |
201 | int error; | 243 | int error, irqf; |
202 | 244 | ||
203 | if (core_pdata) | 245 | if (core_pdata) |
204 | pdata = core_pdata->touch; | 246 | pdata = core_pdata->touch; |
@@ -212,6 +254,7 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) | |||
212 | 254 | ||
213 | wm831x_ts->wm831x = wm831x; | 255 | wm831x_ts->wm831x = wm831x; |
214 | wm831x_ts->input_dev = input_dev; | 256 | wm831x_ts->input_dev = input_dev; |
257 | INIT_WORK(&wm831x_ts->pd_data_work, wm831x_pd_data_work); | ||
215 | 258 | ||
216 | /* | 259 | /* |
217 | * If we have a direct IRQ use it, otherwise use the interrupt | 260 | * If we have a direct IRQ use it, otherwise use the interrupt |
@@ -270,9 +313,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) | |||
270 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, | 313 | wm831x_set_bits(wm831x, WM831X_TOUCH_CONTROL_1, |
271 | WM831X_TCH_RATE_MASK, 6); | 314 | WM831X_TCH_RATE_MASK, 6); |
272 | 315 | ||
316 | if (pdata && pdata->data_irqf) | ||
317 | irqf = pdata->data_irqf; | ||
318 | else | ||
319 | irqf = IRQF_TRIGGER_HIGH; | ||
320 | |||
273 | error = request_threaded_irq(wm831x_ts->data_irq, | 321 | error = request_threaded_irq(wm831x_ts->data_irq, |
274 | NULL, wm831x_ts_data_irq, | 322 | NULL, wm831x_ts_data_irq, |
275 | IRQF_ONESHOT, | 323 | irqf | IRQF_ONESHOT, |
276 | "Touchscreen data", wm831x_ts); | 324 | "Touchscreen data", wm831x_ts); |
277 | if (error) { | 325 | if (error) { |
278 | dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n", | 326 | dev_err(&pdev->dev, "Failed to request data IRQ %d: %d\n", |
@@ -281,9 +329,14 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) | |||
281 | } | 329 | } |
282 | disable_irq(wm831x_ts->data_irq); | 330 | disable_irq(wm831x_ts->data_irq); |
283 | 331 | ||
332 | if (pdata && pdata->pd_irqf) | ||
333 | irqf = pdata->pd_irqf; | ||
334 | else | ||
335 | irqf = IRQF_TRIGGER_HIGH; | ||
336 | |||
284 | error = request_threaded_irq(wm831x_ts->pd_irq, | 337 | error = request_threaded_irq(wm831x_ts->pd_irq, |
285 | NULL, wm831x_ts_pen_down_irq, | 338 | NULL, wm831x_ts_pen_down_irq, |
286 | IRQF_ONESHOT, | 339 | irqf | IRQF_ONESHOT, |
287 | "Touchscreen pen down", wm831x_ts); | 340 | "Touchscreen pen down", wm831x_ts); |
288 | if (error) { | 341 | if (error) { |
289 | dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n", | 342 | dev_err(&pdev->dev, "Failed to request pen down IRQ %d: %d\n", |
diff --git a/drivers/leds/leds-regulator.c b/drivers/leds/leds-regulator.c index 3790816643be..8497f56f8e46 100644 --- a/drivers/leds/leds-regulator.c +++ b/drivers/leds/leds-regulator.c | |||
@@ -178,6 +178,10 @@ static int __devinit regulator_led_probe(struct platform_device *pdev) | |||
178 | led->cdev.flags |= LED_CORE_SUSPENDRESUME; | 178 | led->cdev.flags |= LED_CORE_SUSPENDRESUME; |
179 | led->vcc = vcc; | 179 | led->vcc = vcc; |
180 | 180 | ||
181 | /* to handle correctly an already enabled regulator */ | ||
182 | if (regulator_is_enabled(led->vcc)) | ||
183 | led->enabled = 1; | ||
184 | |||
181 | mutex_init(&led->mutex); | 185 | mutex_init(&led->mutex); |
182 | INIT_WORK(&led->work, led_work); | 186 | INIT_WORK(&led->work, led_work); |
183 | 187 | ||
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 5ef136cdba91..e5d8904fc8f6 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -390,13 +390,6 @@ static int raid_is_congested(struct dm_target_callbacks *cb, int bits) | |||
390 | return md_raid5_congested(&rs->md, bits); | 390 | return md_raid5_congested(&rs->md, bits); |
391 | } | 391 | } |
392 | 392 | ||
393 | static void raid_unplug(struct dm_target_callbacks *cb) | ||
394 | { | ||
395 | struct raid_set *rs = container_of(cb, struct raid_set, callbacks); | ||
396 | |||
397 | md_raid5_kick_device(rs->md.private); | ||
398 | } | ||
399 | |||
400 | /* | 393 | /* |
401 | * Construct a RAID4/5/6 mapping: | 394 | * Construct a RAID4/5/6 mapping: |
402 | * Args: | 395 | * Args: |
@@ -487,7 +480,6 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
487 | } | 480 | } |
488 | 481 | ||
489 | rs->callbacks.congested_fn = raid_is_congested; | 482 | rs->callbacks.congested_fn = raid_is_congested; |
490 | rs->callbacks.unplug_fn = raid_unplug; | ||
491 | dm_table_add_target_callbacks(ti->table, &rs->callbacks); | 483 | dm_table_add_target_callbacks(ti->table, &rs->callbacks); |
492 | 484 | ||
493 | return 0; | 485 | return 0; |
diff --git a/drivers/md/md.c b/drivers/md/md.c index b12b3776c0c0..7d6f7f18a920 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -447,48 +447,59 @@ EXPORT_SYMBOL(md_flush_request); | |||
447 | 447 | ||
448 | /* Support for plugging. | 448 | /* Support for plugging. |
449 | * This mirrors the plugging support in request_queue, but does not | 449 | * This mirrors the plugging support in request_queue, but does not |
450 | * require having a whole queue | 450 | * require having a whole queue or request structures. |
451 | * We allocate an md_plug_cb for each md device and each thread it gets | ||
452 | * plugged on. This links tot the private plug_handle structure in the | ||
453 | * personality data where we keep a count of the number of outstanding | ||
454 | * plugs so other code can see if a plug is active. | ||
451 | */ | 455 | */ |
452 | static void plugger_work(struct work_struct *work) | 456 | struct md_plug_cb { |
453 | { | 457 | struct blk_plug_cb cb; |
454 | struct plug_handle *plug = | 458 | mddev_t *mddev; |
455 | container_of(work, struct plug_handle, unplug_work); | 459 | }; |
456 | plug->unplug_fn(plug); | ||
457 | } | ||
458 | static void plugger_timeout(unsigned long data) | ||
459 | { | ||
460 | struct plug_handle *plug = (void *)data; | ||
461 | kblockd_schedule_work(NULL, &plug->unplug_work); | ||
462 | } | ||
463 | void plugger_init(struct plug_handle *plug, | ||
464 | void (*unplug_fn)(struct plug_handle *)) | ||
465 | { | ||
466 | plug->unplug_flag = 0; | ||
467 | plug->unplug_fn = unplug_fn; | ||
468 | init_timer(&plug->unplug_timer); | ||
469 | plug->unplug_timer.function = plugger_timeout; | ||
470 | plug->unplug_timer.data = (unsigned long)plug; | ||
471 | INIT_WORK(&plug->unplug_work, plugger_work); | ||
472 | } | ||
473 | EXPORT_SYMBOL_GPL(plugger_init); | ||
474 | 460 | ||
475 | void plugger_set_plug(struct plug_handle *plug) | 461 | static void plugger_unplug(struct blk_plug_cb *cb) |
476 | { | 462 | { |
477 | if (!test_and_set_bit(PLUGGED_FLAG, &plug->unplug_flag)) | 463 | struct md_plug_cb *mdcb = container_of(cb, struct md_plug_cb, cb); |
478 | mod_timer(&plug->unplug_timer, jiffies + msecs_to_jiffies(3)+1); | 464 | if (atomic_dec_and_test(&mdcb->mddev->plug_cnt)) |
465 | md_wakeup_thread(mdcb->mddev->thread); | ||
466 | kfree(mdcb); | ||
479 | } | 467 | } |
480 | EXPORT_SYMBOL_GPL(plugger_set_plug); | ||
481 | 468 | ||
482 | int plugger_remove_plug(struct plug_handle *plug) | 469 | /* Check that an unplug wakeup will come shortly. |
470 | * If not, wakeup the md thread immediately | ||
471 | */ | ||
472 | int mddev_check_plugged(mddev_t *mddev) | ||
483 | { | 473 | { |
484 | if (test_and_clear_bit(PLUGGED_FLAG, &plug->unplug_flag)) { | 474 | struct blk_plug *plug = current->plug; |
485 | del_timer(&plug->unplug_timer); | 475 | struct md_plug_cb *mdcb; |
486 | return 1; | 476 | |
487 | } else | 477 | if (!plug) |
488 | return 0; | 478 | return 0; |
489 | } | ||
490 | EXPORT_SYMBOL_GPL(plugger_remove_plug); | ||
491 | 479 | ||
480 | list_for_each_entry(mdcb, &plug->cb_list, cb.list) { | ||
481 | if (mdcb->cb.callback == plugger_unplug && | ||
482 | mdcb->mddev == mddev) { | ||
483 | /* Already on the list, move to top */ | ||
484 | if (mdcb != list_first_entry(&plug->cb_list, | ||
485 | struct md_plug_cb, | ||
486 | cb.list)) | ||
487 | list_move(&mdcb->cb.list, &plug->cb_list); | ||
488 | return 1; | ||
489 | } | ||
490 | } | ||
491 | /* Not currently on the callback list */ | ||
492 | mdcb = kmalloc(sizeof(*mdcb), GFP_ATOMIC); | ||
493 | if (!mdcb) | ||
494 | return 0; | ||
495 | |||
496 | mdcb->mddev = mddev; | ||
497 | mdcb->cb.callback = plugger_unplug; | ||
498 | atomic_inc(&mddev->plug_cnt); | ||
499 | list_add(&mdcb->cb.list, &plug->cb_list); | ||
500 | return 1; | ||
501 | } | ||
502 | EXPORT_SYMBOL_GPL(mddev_check_plugged); | ||
492 | 503 | ||
493 | static inline mddev_t *mddev_get(mddev_t *mddev) | 504 | static inline mddev_t *mddev_get(mddev_t *mddev) |
494 | { | 505 | { |
@@ -538,6 +549,7 @@ void mddev_init(mddev_t *mddev) | |||
538 | atomic_set(&mddev->active, 1); | 549 | atomic_set(&mddev->active, 1); |
539 | atomic_set(&mddev->openers, 0); | 550 | atomic_set(&mddev->openers, 0); |
540 | atomic_set(&mddev->active_io, 0); | 551 | atomic_set(&mddev->active_io, 0); |
552 | atomic_set(&mddev->plug_cnt, 0); | ||
541 | spin_lock_init(&mddev->write_lock); | 553 | spin_lock_init(&mddev->write_lock); |
542 | atomic_set(&mddev->flush_pending, 0); | 554 | atomic_set(&mddev->flush_pending, 0); |
543 | init_waitqueue_head(&mddev->sb_wait); | 555 | init_waitqueue_head(&mddev->sb_wait); |
@@ -3158,6 +3170,7 @@ level_store(mddev_t *mddev, const char *buf, size_t len) | |||
3158 | mddev->layout = mddev->new_layout; | 3170 | mddev->layout = mddev->new_layout; |
3159 | mddev->chunk_sectors = mddev->new_chunk_sectors; | 3171 | mddev->chunk_sectors = mddev->new_chunk_sectors; |
3160 | mddev->delta_disks = 0; | 3172 | mddev->delta_disks = 0; |
3173 | mddev->degraded = 0; | ||
3161 | if (mddev->pers->sync_request == NULL) { | 3174 | if (mddev->pers->sync_request == NULL) { |
3162 | /* this is now an array without redundancy, so | 3175 | /* this is now an array without redundancy, so |
3163 | * it must always be in_sync | 3176 | * it must always be in_sync |
@@ -4723,7 +4736,6 @@ static void md_clean(mddev_t *mddev) | |||
4723 | mddev->bitmap_info.chunksize = 0; | 4736 | mddev->bitmap_info.chunksize = 0; |
4724 | mddev->bitmap_info.daemon_sleep = 0; | 4737 | mddev->bitmap_info.daemon_sleep = 0; |
4725 | mddev->bitmap_info.max_write_behind = 0; | 4738 | mddev->bitmap_info.max_write_behind = 0; |
4726 | mddev->plug = NULL; | ||
4727 | } | 4739 | } |
4728 | 4740 | ||
4729 | static void __md_stop_writes(mddev_t *mddev) | 4741 | static void __md_stop_writes(mddev_t *mddev) |
@@ -6688,12 +6700,6 @@ int md_allow_write(mddev_t *mddev) | |||
6688 | } | 6700 | } |
6689 | EXPORT_SYMBOL_GPL(md_allow_write); | 6701 | EXPORT_SYMBOL_GPL(md_allow_write); |
6690 | 6702 | ||
6691 | void md_unplug(mddev_t *mddev) | ||
6692 | { | ||
6693 | if (mddev->plug) | ||
6694 | mddev->plug->unplug_fn(mddev->plug); | ||
6695 | } | ||
6696 | |||
6697 | #define SYNC_MARKS 10 | 6703 | #define SYNC_MARKS 10 |
6698 | #define SYNC_MARK_STEP (3*HZ) | 6704 | #define SYNC_MARK_STEP (3*HZ) |
6699 | void md_do_sync(mddev_t *mddev) | 6705 | void md_do_sync(mddev_t *mddev) |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 52b407369e13..0b1fd3f1d85b 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -29,26 +29,6 @@ | |||
29 | typedef struct mddev_s mddev_t; | 29 | typedef struct mddev_s mddev_t; |
30 | typedef struct mdk_rdev_s mdk_rdev_t; | 30 | typedef struct mdk_rdev_s mdk_rdev_t; |
31 | 31 | ||
32 | /* generic plugging support - like that provided with request_queue, | ||
33 | * but does not require a request_queue | ||
34 | */ | ||
35 | struct plug_handle { | ||
36 | void (*unplug_fn)(struct plug_handle *); | ||
37 | struct timer_list unplug_timer; | ||
38 | struct work_struct unplug_work; | ||
39 | unsigned long unplug_flag; | ||
40 | }; | ||
41 | #define PLUGGED_FLAG 1 | ||
42 | void plugger_init(struct plug_handle *plug, | ||
43 | void (*unplug_fn)(struct plug_handle *)); | ||
44 | void plugger_set_plug(struct plug_handle *plug); | ||
45 | int plugger_remove_plug(struct plug_handle *plug); | ||
46 | static inline void plugger_flush(struct plug_handle *plug) | ||
47 | { | ||
48 | del_timer_sync(&plug->unplug_timer); | ||
49 | cancel_work_sync(&plug->unplug_work); | ||
50 | } | ||
51 | |||
52 | /* | 32 | /* |
53 | * MD's 'extended' device | 33 | * MD's 'extended' device |
54 | */ | 34 | */ |
@@ -199,6 +179,9 @@ struct mddev_s | |||
199 | int delta_disks, new_level, new_layout; | 179 | int delta_disks, new_level, new_layout; |
200 | int new_chunk_sectors; | 180 | int new_chunk_sectors; |
201 | 181 | ||
182 | atomic_t plug_cnt; /* If device is expecting | ||
183 | * more bios soon. | ||
184 | */ | ||
202 | struct mdk_thread_s *thread; /* management thread */ | 185 | struct mdk_thread_s *thread; /* management thread */ |
203 | struct mdk_thread_s *sync_thread; /* doing resync or reconstruct */ | 186 | struct mdk_thread_s *sync_thread; /* doing resync or reconstruct */ |
204 | sector_t curr_resync; /* last block scheduled */ | 187 | sector_t curr_resync; /* last block scheduled */ |
@@ -336,7 +319,6 @@ struct mddev_s | |||
336 | struct list_head all_mddevs; | 319 | struct list_head all_mddevs; |
337 | 320 | ||
338 | struct attribute_group *to_remove; | 321 | struct attribute_group *to_remove; |
339 | struct plug_handle *plug; /* if used by personality */ | ||
340 | 322 | ||
341 | struct bio_set *bio_set; | 323 | struct bio_set *bio_set; |
342 | 324 | ||
@@ -516,7 +498,6 @@ extern int md_integrity_register(mddev_t *mddev); | |||
516 | extern void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); | 498 | extern void md_integrity_add_rdev(mdk_rdev_t *rdev, mddev_t *mddev); |
517 | extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); | 499 | extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale); |
518 | extern void restore_bitmap_write_access(struct file *file); | 500 | extern void restore_bitmap_write_access(struct file *file); |
519 | extern void md_unplug(mddev_t *mddev); | ||
520 | 501 | ||
521 | extern void mddev_init(mddev_t *mddev); | 502 | extern void mddev_init(mddev_t *mddev); |
522 | extern int md_run(mddev_t *mddev); | 503 | extern int md_run(mddev_t *mddev); |
@@ -530,4 +511,5 @@ extern struct bio *bio_clone_mddev(struct bio *bio, gfp_t gfp_mask, | |||
530 | mddev_t *mddev); | 511 | mddev_t *mddev); |
531 | extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, | 512 | extern struct bio *bio_alloc_mddev(gfp_t gfp_mask, int nr_iovecs, |
532 | mddev_t *mddev); | 513 | mddev_t *mddev); |
514 | extern int mddev_check_plugged(mddev_t *mddev); | ||
533 | #endif /* _MD_MD_H */ | 515 | #endif /* _MD_MD_H */ |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index c2a21ae56d97..2b7a7ff401dc 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -565,12 +565,6 @@ static void flush_pending_writes(conf_t *conf) | |||
565 | spin_unlock_irq(&conf->device_lock); | 565 | spin_unlock_irq(&conf->device_lock); |
566 | } | 566 | } |
567 | 567 | ||
568 | static void md_kick_device(mddev_t *mddev) | ||
569 | { | ||
570 | blk_flush_plug(current); | ||
571 | md_wakeup_thread(mddev->thread); | ||
572 | } | ||
573 | |||
574 | /* Barriers.... | 568 | /* Barriers.... |
575 | * Sometimes we need to suspend IO while we do something else, | 569 | * Sometimes we need to suspend IO while we do something else, |
576 | * either some resync/recovery, or reconfigure the array. | 570 | * either some resync/recovery, or reconfigure the array. |
@@ -600,7 +594,7 @@ static void raise_barrier(conf_t *conf) | |||
600 | 594 | ||
601 | /* Wait until no block IO is waiting */ | 595 | /* Wait until no block IO is waiting */ |
602 | wait_event_lock_irq(conf->wait_barrier, !conf->nr_waiting, | 596 | wait_event_lock_irq(conf->wait_barrier, !conf->nr_waiting, |
603 | conf->resync_lock, md_kick_device(conf->mddev)); | 597 | conf->resync_lock, ); |
604 | 598 | ||
605 | /* block any new IO from starting */ | 599 | /* block any new IO from starting */ |
606 | conf->barrier++; | 600 | conf->barrier++; |
@@ -608,7 +602,7 @@ static void raise_barrier(conf_t *conf) | |||
608 | /* Now wait for all pending IO to complete */ | 602 | /* Now wait for all pending IO to complete */ |
609 | wait_event_lock_irq(conf->wait_barrier, | 603 | wait_event_lock_irq(conf->wait_barrier, |
610 | !conf->nr_pending && conf->barrier < RESYNC_DEPTH, | 604 | !conf->nr_pending && conf->barrier < RESYNC_DEPTH, |
611 | conf->resync_lock, md_kick_device(conf->mddev)); | 605 | conf->resync_lock, ); |
612 | 606 | ||
613 | spin_unlock_irq(&conf->resync_lock); | 607 | spin_unlock_irq(&conf->resync_lock); |
614 | } | 608 | } |
@@ -630,7 +624,7 @@ static void wait_barrier(conf_t *conf) | |||
630 | conf->nr_waiting++; | 624 | conf->nr_waiting++; |
631 | wait_event_lock_irq(conf->wait_barrier, !conf->barrier, | 625 | wait_event_lock_irq(conf->wait_barrier, !conf->barrier, |
632 | conf->resync_lock, | 626 | conf->resync_lock, |
633 | md_kick_device(conf->mddev)); | 627 | ); |
634 | conf->nr_waiting--; | 628 | conf->nr_waiting--; |
635 | } | 629 | } |
636 | conf->nr_pending++; | 630 | conf->nr_pending++; |
@@ -666,8 +660,7 @@ static void freeze_array(conf_t *conf) | |||
666 | wait_event_lock_irq(conf->wait_barrier, | 660 | wait_event_lock_irq(conf->wait_barrier, |
667 | conf->nr_pending == conf->nr_queued+1, | 661 | conf->nr_pending == conf->nr_queued+1, |
668 | conf->resync_lock, | 662 | conf->resync_lock, |
669 | ({ flush_pending_writes(conf); | 663 | flush_pending_writes(conf)); |
670 | md_kick_device(conf->mddev); })); | ||
671 | spin_unlock_irq(&conf->resync_lock); | 664 | spin_unlock_irq(&conf->resync_lock); |
672 | } | 665 | } |
673 | static void unfreeze_array(conf_t *conf) | 666 | static void unfreeze_array(conf_t *conf) |
@@ -729,6 +722,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
729 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); | 722 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); |
730 | const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); | 723 | const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); |
731 | mdk_rdev_t *blocked_rdev; | 724 | mdk_rdev_t *blocked_rdev; |
725 | int plugged; | ||
732 | 726 | ||
733 | /* | 727 | /* |
734 | * Register the new request and wait if the reconstruction | 728 | * Register the new request and wait if the reconstruction |
@@ -820,6 +814,8 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
820 | * inc refcount on their rdev. Record them by setting | 814 | * inc refcount on their rdev. Record them by setting |
821 | * bios[x] to bio | 815 | * bios[x] to bio |
822 | */ | 816 | */ |
817 | plugged = mddev_check_plugged(mddev); | ||
818 | |||
823 | disks = conf->raid_disks; | 819 | disks = conf->raid_disks; |
824 | retry_write: | 820 | retry_write: |
825 | blocked_rdev = NULL; | 821 | blocked_rdev = NULL; |
@@ -925,7 +921,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
925 | /* In case raid1d snuck in to freeze_array */ | 921 | /* In case raid1d snuck in to freeze_array */ |
926 | wake_up(&conf->wait_barrier); | 922 | wake_up(&conf->wait_barrier); |
927 | 923 | ||
928 | if (do_sync || !bitmap) | 924 | if (do_sync || !bitmap || !plugged) |
929 | md_wakeup_thread(mddev->thread); | 925 | md_wakeup_thread(mddev->thread); |
930 | 926 | ||
931 | return 0; | 927 | return 0; |
@@ -1516,13 +1512,16 @@ static void raid1d(mddev_t *mddev) | |||
1516 | conf_t *conf = mddev->private; | 1512 | conf_t *conf = mddev->private; |
1517 | struct list_head *head = &conf->retry_list; | 1513 | struct list_head *head = &conf->retry_list; |
1518 | mdk_rdev_t *rdev; | 1514 | mdk_rdev_t *rdev; |
1515 | struct blk_plug plug; | ||
1519 | 1516 | ||
1520 | md_check_recovery(mddev); | 1517 | md_check_recovery(mddev); |
1521 | 1518 | ||
1519 | blk_start_plug(&plug); | ||
1522 | for (;;) { | 1520 | for (;;) { |
1523 | char b[BDEVNAME_SIZE]; | 1521 | char b[BDEVNAME_SIZE]; |
1524 | 1522 | ||
1525 | flush_pending_writes(conf); | 1523 | if (atomic_read(&mddev->plug_cnt) == 0) |
1524 | flush_pending_writes(conf); | ||
1526 | 1525 | ||
1527 | spin_lock_irqsave(&conf->device_lock, flags); | 1526 | spin_lock_irqsave(&conf->device_lock, flags); |
1528 | if (list_empty(head)) { | 1527 | if (list_empty(head)) { |
@@ -1593,6 +1592,7 @@ static void raid1d(mddev_t *mddev) | |||
1593 | } | 1592 | } |
1594 | cond_resched(); | 1593 | cond_resched(); |
1595 | } | 1594 | } |
1595 | blk_finish_plug(&plug); | ||
1596 | } | 1596 | } |
1597 | 1597 | ||
1598 | 1598 | ||
@@ -2039,7 +2039,6 @@ static int stop(mddev_t *mddev) | |||
2039 | 2039 | ||
2040 | md_unregister_thread(mddev->thread); | 2040 | md_unregister_thread(mddev->thread); |
2041 | mddev->thread = NULL; | 2041 | mddev->thread = NULL; |
2042 | blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ | ||
2043 | if (conf->r1bio_pool) | 2042 | if (conf->r1bio_pool) |
2044 | mempool_destroy(conf->r1bio_pool); | 2043 | mempool_destroy(conf->r1bio_pool); |
2045 | kfree(conf->mirrors); | 2044 | kfree(conf->mirrors); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 2da83d566592..8e9462626ec5 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -634,12 +634,6 @@ static void flush_pending_writes(conf_t *conf) | |||
634 | spin_unlock_irq(&conf->device_lock); | 634 | spin_unlock_irq(&conf->device_lock); |
635 | } | 635 | } |
636 | 636 | ||
637 | static void md_kick_device(mddev_t *mddev) | ||
638 | { | ||
639 | blk_flush_plug(current); | ||
640 | md_wakeup_thread(mddev->thread); | ||
641 | } | ||
642 | |||
643 | /* Barriers.... | 637 | /* Barriers.... |
644 | * Sometimes we need to suspend IO while we do something else, | 638 | * Sometimes we need to suspend IO while we do something else, |
645 | * either some resync/recovery, or reconfigure the array. | 639 | * either some resync/recovery, or reconfigure the array. |
@@ -669,15 +663,15 @@ static void raise_barrier(conf_t *conf, int force) | |||
669 | 663 | ||
670 | /* Wait until no block IO is waiting (unless 'force') */ | 664 | /* Wait until no block IO is waiting (unless 'force') */ |
671 | wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting, | 665 | wait_event_lock_irq(conf->wait_barrier, force || !conf->nr_waiting, |
672 | conf->resync_lock, md_kick_device(conf->mddev)); | 666 | conf->resync_lock, ); |
673 | 667 | ||
674 | /* block any new IO from starting */ | 668 | /* block any new IO from starting */ |
675 | conf->barrier++; | 669 | conf->barrier++; |
676 | 670 | ||
677 | /* No wait for all pending IO to complete */ | 671 | /* Now wait for all pending IO to complete */ |
678 | wait_event_lock_irq(conf->wait_barrier, | 672 | wait_event_lock_irq(conf->wait_barrier, |
679 | !conf->nr_pending && conf->barrier < RESYNC_DEPTH, | 673 | !conf->nr_pending && conf->barrier < RESYNC_DEPTH, |
680 | conf->resync_lock, md_kick_device(conf->mddev)); | 674 | conf->resync_lock, ); |
681 | 675 | ||
682 | spin_unlock_irq(&conf->resync_lock); | 676 | spin_unlock_irq(&conf->resync_lock); |
683 | } | 677 | } |
@@ -698,7 +692,7 @@ static void wait_barrier(conf_t *conf) | |||
698 | conf->nr_waiting++; | 692 | conf->nr_waiting++; |
699 | wait_event_lock_irq(conf->wait_barrier, !conf->barrier, | 693 | wait_event_lock_irq(conf->wait_barrier, !conf->barrier, |
700 | conf->resync_lock, | 694 | conf->resync_lock, |
701 | md_kick_device(conf->mddev)); | 695 | ); |
702 | conf->nr_waiting--; | 696 | conf->nr_waiting--; |
703 | } | 697 | } |
704 | conf->nr_pending++; | 698 | conf->nr_pending++; |
@@ -734,8 +728,8 @@ static void freeze_array(conf_t *conf) | |||
734 | wait_event_lock_irq(conf->wait_barrier, | 728 | wait_event_lock_irq(conf->wait_barrier, |
735 | conf->nr_pending == conf->nr_queued+1, | 729 | conf->nr_pending == conf->nr_queued+1, |
736 | conf->resync_lock, | 730 | conf->resync_lock, |
737 | ({ flush_pending_writes(conf); | 731 | flush_pending_writes(conf)); |
738 | md_kick_device(conf->mddev); })); | 732 | |
739 | spin_unlock_irq(&conf->resync_lock); | 733 | spin_unlock_irq(&conf->resync_lock); |
740 | } | 734 | } |
741 | 735 | ||
@@ -762,6 +756,7 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
762 | const unsigned long do_fua = (bio->bi_rw & REQ_FUA); | 756 | const unsigned long do_fua = (bio->bi_rw & REQ_FUA); |
763 | unsigned long flags; | 757 | unsigned long flags; |
764 | mdk_rdev_t *blocked_rdev; | 758 | mdk_rdev_t *blocked_rdev; |
759 | int plugged; | ||
765 | 760 | ||
766 | if (unlikely(bio->bi_rw & REQ_FLUSH)) { | 761 | if (unlikely(bio->bi_rw & REQ_FLUSH)) { |
767 | md_flush_request(mddev, bio); | 762 | md_flush_request(mddev, bio); |
@@ -870,6 +865,8 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
870 | * inc refcount on their rdev. Record them by setting | 865 | * inc refcount on their rdev. Record them by setting |
871 | * bios[x] to bio | 866 | * bios[x] to bio |
872 | */ | 867 | */ |
868 | plugged = mddev_check_plugged(mddev); | ||
869 | |||
873 | raid10_find_phys(conf, r10_bio); | 870 | raid10_find_phys(conf, r10_bio); |
874 | retry_write: | 871 | retry_write: |
875 | blocked_rdev = NULL; | 872 | blocked_rdev = NULL; |
@@ -946,9 +943,8 @@ static int make_request(mddev_t *mddev, struct bio * bio) | |||
946 | /* In case raid10d snuck in to freeze_array */ | 943 | /* In case raid10d snuck in to freeze_array */ |
947 | wake_up(&conf->wait_barrier); | 944 | wake_up(&conf->wait_barrier); |
948 | 945 | ||
949 | if (do_sync || !mddev->bitmap) | 946 | if (do_sync || !mddev->bitmap || !plugged) |
950 | md_wakeup_thread(mddev->thread); | 947 | md_wakeup_thread(mddev->thread); |
951 | |||
952 | return 0; | 948 | return 0; |
953 | } | 949 | } |
954 | 950 | ||
@@ -1640,9 +1636,11 @@ static void raid10d(mddev_t *mddev) | |||
1640 | conf_t *conf = mddev->private; | 1636 | conf_t *conf = mddev->private; |
1641 | struct list_head *head = &conf->retry_list; | 1637 | struct list_head *head = &conf->retry_list; |
1642 | mdk_rdev_t *rdev; | 1638 | mdk_rdev_t *rdev; |
1639 | struct blk_plug plug; | ||
1643 | 1640 | ||
1644 | md_check_recovery(mddev); | 1641 | md_check_recovery(mddev); |
1645 | 1642 | ||
1643 | blk_start_plug(&plug); | ||
1646 | for (;;) { | 1644 | for (;;) { |
1647 | char b[BDEVNAME_SIZE]; | 1645 | char b[BDEVNAME_SIZE]; |
1648 | 1646 | ||
@@ -1716,6 +1714,7 @@ static void raid10d(mddev_t *mddev) | |||
1716 | } | 1714 | } |
1717 | cond_resched(); | 1715 | cond_resched(); |
1718 | } | 1716 | } |
1717 | blk_finish_plug(&plug); | ||
1719 | } | 1718 | } |
1720 | 1719 | ||
1721 | 1720 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e867ee42b152..49bf5f891435 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -27,12 +27,12 @@ | |||
27 | * | 27 | * |
28 | * We group bitmap updates into batches. Each batch has a number. | 28 | * We group bitmap updates into batches. Each batch has a number. |
29 | * We may write out several batches at once, but that isn't very important. | 29 | * We may write out several batches at once, but that isn't very important. |
30 | * conf->bm_write is the number of the last batch successfully written. | 30 | * conf->seq_write is the number of the last batch successfully written. |
31 | * conf->bm_flush is the number of the last batch that was closed to | 31 | * conf->seq_flush is the number of the last batch that was closed to |
32 | * new additions. | 32 | * new additions. |
33 | * When we discover that we will need to write to any block in a stripe | 33 | * When we discover that we will need to write to any block in a stripe |
34 | * (in add_stripe_bio) we update the in-memory bitmap and record in sh->bm_seq | 34 | * (in add_stripe_bio) we update the in-memory bitmap and record in sh->bm_seq |
35 | * the number of the batch it will be in. This is bm_flush+1. | 35 | * the number of the batch it will be in. This is seq_flush+1. |
36 | * When we are ready to do a write, if that batch hasn't been written yet, | 36 | * When we are ready to do a write, if that batch hasn't been written yet, |
37 | * we plug the array and queue the stripe for later. | 37 | * we plug the array and queue the stripe for later. |
38 | * When an unplug happens, we increment bm_flush, thus closing the current | 38 | * When an unplug happens, we increment bm_flush, thus closing the current |
@@ -199,14 +199,12 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh) | |||
199 | BUG_ON(!list_empty(&sh->lru)); | 199 | BUG_ON(!list_empty(&sh->lru)); |
200 | BUG_ON(atomic_read(&conf->active_stripes)==0); | 200 | BUG_ON(atomic_read(&conf->active_stripes)==0); |
201 | if (test_bit(STRIPE_HANDLE, &sh->state)) { | 201 | if (test_bit(STRIPE_HANDLE, &sh->state)) { |
202 | if (test_bit(STRIPE_DELAYED, &sh->state)) { | 202 | if (test_bit(STRIPE_DELAYED, &sh->state)) |
203 | list_add_tail(&sh->lru, &conf->delayed_list); | 203 | list_add_tail(&sh->lru, &conf->delayed_list); |
204 | plugger_set_plug(&conf->plug); | 204 | else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && |
205 | } else if (test_bit(STRIPE_BIT_DELAY, &sh->state) && | 205 | sh->bm_seq - conf->seq_write > 0) |
206 | sh->bm_seq - conf->seq_write > 0) { | ||
207 | list_add_tail(&sh->lru, &conf->bitmap_list); | 206 | list_add_tail(&sh->lru, &conf->bitmap_list); |
208 | plugger_set_plug(&conf->plug); | 207 | else { |
209 | } else { | ||
210 | clear_bit(STRIPE_BIT_DELAY, &sh->state); | 208 | clear_bit(STRIPE_BIT_DELAY, &sh->state); |
211 | list_add_tail(&sh->lru, &conf->handle_list); | 209 | list_add_tail(&sh->lru, &conf->handle_list); |
212 | } | 210 | } |
@@ -461,7 +459,7 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector, | |||
461 | < (conf->max_nr_stripes *3/4) | 459 | < (conf->max_nr_stripes *3/4) |
462 | || !conf->inactive_blocked), | 460 | || !conf->inactive_blocked), |
463 | conf->device_lock, | 461 | conf->device_lock, |
464 | md_raid5_kick_device(conf)); | 462 | ); |
465 | conf->inactive_blocked = 0; | 463 | conf->inactive_blocked = 0; |
466 | } else | 464 | } else |
467 | init_stripe(sh, sector, previous); | 465 | init_stripe(sh, sector, previous); |
@@ -1470,7 +1468,7 @@ static int resize_stripes(raid5_conf_t *conf, int newsize) | |||
1470 | wait_event_lock_irq(conf->wait_for_stripe, | 1468 | wait_event_lock_irq(conf->wait_for_stripe, |
1471 | !list_empty(&conf->inactive_list), | 1469 | !list_empty(&conf->inactive_list), |
1472 | conf->device_lock, | 1470 | conf->device_lock, |
1473 | blk_flush_plug(current)); | 1471 | ); |
1474 | osh = get_free_stripe(conf); | 1472 | osh = get_free_stripe(conf); |
1475 | spin_unlock_irq(&conf->device_lock); | 1473 | spin_unlock_irq(&conf->device_lock); |
1476 | atomic_set(&nsh->count, 1); | 1474 | atomic_set(&nsh->count, 1); |
@@ -3623,8 +3621,7 @@ static void raid5_activate_delayed(raid5_conf_t *conf) | |||
3623 | atomic_inc(&conf->preread_active_stripes); | 3621 | atomic_inc(&conf->preread_active_stripes); |
3624 | list_add_tail(&sh->lru, &conf->hold_list); | 3622 | list_add_tail(&sh->lru, &conf->hold_list); |
3625 | } | 3623 | } |
3626 | } else | 3624 | } |
3627 | plugger_set_plug(&conf->plug); | ||
3628 | } | 3625 | } |
3629 | 3626 | ||
3630 | static void activate_bit_delay(raid5_conf_t *conf) | 3627 | static void activate_bit_delay(raid5_conf_t *conf) |
@@ -3641,21 +3638,6 @@ static void activate_bit_delay(raid5_conf_t *conf) | |||
3641 | } | 3638 | } |
3642 | } | 3639 | } |
3643 | 3640 | ||
3644 | void md_raid5_kick_device(raid5_conf_t *conf) | ||
3645 | { | ||
3646 | blk_flush_plug(current); | ||
3647 | raid5_activate_delayed(conf); | ||
3648 | md_wakeup_thread(conf->mddev->thread); | ||
3649 | } | ||
3650 | EXPORT_SYMBOL_GPL(md_raid5_kick_device); | ||
3651 | |||
3652 | static void raid5_unplug(struct plug_handle *plug) | ||
3653 | { | ||
3654 | raid5_conf_t *conf = container_of(plug, raid5_conf_t, plug); | ||
3655 | |||
3656 | md_raid5_kick_device(conf); | ||
3657 | } | ||
3658 | |||
3659 | int md_raid5_congested(mddev_t *mddev, int bits) | 3641 | int md_raid5_congested(mddev_t *mddev, int bits) |
3660 | { | 3642 | { |
3661 | raid5_conf_t *conf = mddev->private; | 3643 | raid5_conf_t *conf = mddev->private; |
@@ -3945,6 +3927,7 @@ static int make_request(mddev_t *mddev, struct bio * bi) | |||
3945 | struct stripe_head *sh; | 3927 | struct stripe_head *sh; |
3946 | const int rw = bio_data_dir(bi); | 3928 | const int rw = bio_data_dir(bi); |
3947 | int remaining; | 3929 | int remaining; |
3930 | int plugged; | ||
3948 | 3931 | ||
3949 | if (unlikely(bi->bi_rw & REQ_FLUSH)) { | 3932 | if (unlikely(bi->bi_rw & REQ_FLUSH)) { |
3950 | md_flush_request(mddev, bi); | 3933 | md_flush_request(mddev, bi); |
@@ -3963,6 +3946,7 @@ static int make_request(mddev_t *mddev, struct bio * bi) | |||
3963 | bi->bi_next = NULL; | 3946 | bi->bi_next = NULL; |
3964 | bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ | 3947 | bi->bi_phys_segments = 1; /* over-loaded to count active stripes */ |
3965 | 3948 | ||
3949 | plugged = mddev_check_plugged(mddev); | ||
3966 | for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { | 3950 | for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) { |
3967 | DEFINE_WAIT(w); | 3951 | DEFINE_WAIT(w); |
3968 | int disks, data_disks; | 3952 | int disks, data_disks; |
@@ -4057,7 +4041,7 @@ static int make_request(mddev_t *mddev, struct bio * bi) | |||
4057 | * add failed due to overlap. Flush everything | 4041 | * add failed due to overlap. Flush everything |
4058 | * and wait a while | 4042 | * and wait a while |
4059 | */ | 4043 | */ |
4060 | md_raid5_kick_device(conf); | 4044 | md_wakeup_thread(mddev->thread); |
4061 | release_stripe(sh); | 4045 | release_stripe(sh); |
4062 | schedule(); | 4046 | schedule(); |
4063 | goto retry; | 4047 | goto retry; |
@@ -4077,6 +4061,9 @@ static int make_request(mddev_t *mddev, struct bio * bi) | |||
4077 | } | 4061 | } |
4078 | 4062 | ||
4079 | } | 4063 | } |
4064 | if (!plugged) | ||
4065 | md_wakeup_thread(mddev->thread); | ||
4066 | |||
4080 | spin_lock_irq(&conf->device_lock); | 4067 | spin_lock_irq(&conf->device_lock); |
4081 | remaining = raid5_dec_bi_phys_segments(bi); | 4068 | remaining = raid5_dec_bi_phys_segments(bi); |
4082 | spin_unlock_irq(&conf->device_lock); | 4069 | spin_unlock_irq(&conf->device_lock); |
@@ -4478,24 +4465,30 @@ static void raid5d(mddev_t *mddev) | |||
4478 | struct stripe_head *sh; | 4465 | struct stripe_head *sh; |
4479 | raid5_conf_t *conf = mddev->private; | 4466 | raid5_conf_t *conf = mddev->private; |
4480 | int handled; | 4467 | int handled; |
4468 | struct blk_plug plug; | ||
4481 | 4469 | ||
4482 | pr_debug("+++ raid5d active\n"); | 4470 | pr_debug("+++ raid5d active\n"); |
4483 | 4471 | ||
4484 | md_check_recovery(mddev); | 4472 | md_check_recovery(mddev); |
4485 | 4473 | ||
4474 | blk_start_plug(&plug); | ||
4486 | handled = 0; | 4475 | handled = 0; |
4487 | spin_lock_irq(&conf->device_lock); | 4476 | spin_lock_irq(&conf->device_lock); |
4488 | while (1) { | 4477 | while (1) { |
4489 | struct bio *bio; | 4478 | struct bio *bio; |
4490 | 4479 | ||
4491 | if (conf->seq_flush != conf->seq_write) { | 4480 | if (atomic_read(&mddev->plug_cnt) == 0 && |
4492 | int seq = conf->seq_flush; | 4481 | !list_empty(&conf->bitmap_list)) { |
4482 | /* Now is a good time to flush some bitmap updates */ | ||
4483 | conf->seq_flush++; | ||
4493 | spin_unlock_irq(&conf->device_lock); | 4484 | spin_unlock_irq(&conf->device_lock); |
4494 | bitmap_unplug(mddev->bitmap); | 4485 | bitmap_unplug(mddev->bitmap); |
4495 | spin_lock_irq(&conf->device_lock); | 4486 | spin_lock_irq(&conf->device_lock); |
4496 | conf->seq_write = seq; | 4487 | conf->seq_write = conf->seq_flush; |
4497 | activate_bit_delay(conf); | 4488 | activate_bit_delay(conf); |
4498 | } | 4489 | } |
4490 | if (atomic_read(&mddev->plug_cnt) == 0) | ||
4491 | raid5_activate_delayed(conf); | ||
4499 | 4492 | ||
4500 | while ((bio = remove_bio_from_retry(conf))) { | 4493 | while ((bio = remove_bio_from_retry(conf))) { |
4501 | int ok; | 4494 | int ok; |
@@ -4525,6 +4518,7 @@ static void raid5d(mddev_t *mddev) | |||
4525 | spin_unlock_irq(&conf->device_lock); | 4518 | spin_unlock_irq(&conf->device_lock); |
4526 | 4519 | ||
4527 | async_tx_issue_pending_all(); | 4520 | async_tx_issue_pending_all(); |
4521 | blk_finish_plug(&plug); | ||
4528 | 4522 | ||
4529 | pr_debug("--- raid5d inactive\n"); | 4523 | pr_debug("--- raid5d inactive\n"); |
4530 | } | 4524 | } |
@@ -5141,8 +5135,6 @@ static int run(mddev_t *mddev) | |||
5141 | mdname(mddev)); | 5135 | mdname(mddev)); |
5142 | md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); | 5136 | md_set_array_sectors(mddev, raid5_size(mddev, 0, 0)); |
5143 | 5137 | ||
5144 | plugger_init(&conf->plug, raid5_unplug); | ||
5145 | mddev->plug = &conf->plug; | ||
5146 | if (mddev->queue) { | 5138 | if (mddev->queue) { |
5147 | int chunk_size; | 5139 | int chunk_size; |
5148 | /* read-ahead size must cover two whole stripes, which | 5140 | /* read-ahead size must cover two whole stripes, which |
@@ -5159,7 +5151,6 @@ static int run(mddev_t *mddev) | |||
5159 | 5151 | ||
5160 | mddev->queue->backing_dev_info.congested_data = mddev; | 5152 | mddev->queue->backing_dev_info.congested_data = mddev; |
5161 | mddev->queue->backing_dev_info.congested_fn = raid5_congested; | 5153 | mddev->queue->backing_dev_info.congested_fn = raid5_congested; |
5162 | mddev->queue->queue_lock = &conf->device_lock; | ||
5163 | 5154 | ||
5164 | chunk_size = mddev->chunk_sectors << 9; | 5155 | chunk_size = mddev->chunk_sectors << 9; |
5165 | blk_queue_io_min(mddev->queue, chunk_size); | 5156 | blk_queue_io_min(mddev->queue, chunk_size); |
@@ -5192,7 +5183,6 @@ static int stop(mddev_t *mddev) | |||
5192 | mddev->thread = NULL; | 5183 | mddev->thread = NULL; |
5193 | if (mddev->queue) | 5184 | if (mddev->queue) |
5194 | mddev->queue->backing_dev_info.congested_fn = NULL; | 5185 | mddev->queue->backing_dev_info.congested_fn = NULL; |
5195 | plugger_flush(&conf->plug); /* the unplug fn references 'conf'*/ | ||
5196 | free_conf(conf); | 5186 | free_conf(conf); |
5197 | mddev->private = NULL; | 5187 | mddev->private = NULL; |
5198 | mddev->to_remove = &raid5_attrs_group; | 5188 | mddev->to_remove = &raid5_attrs_group; |
@@ -5688,6 +5678,7 @@ static void raid5_quiesce(mddev_t *mddev, int state) | |||
5688 | static void *raid45_takeover_raid0(mddev_t *mddev, int level) | 5678 | static void *raid45_takeover_raid0(mddev_t *mddev, int level) |
5689 | { | 5679 | { |
5690 | struct raid0_private_data *raid0_priv = mddev->private; | 5680 | struct raid0_private_data *raid0_priv = mddev->private; |
5681 | sector_t sectors; | ||
5691 | 5682 | ||
5692 | /* for raid0 takeover only one zone is supported */ | 5683 | /* for raid0 takeover only one zone is supported */ |
5693 | if (raid0_priv->nr_strip_zones > 1) { | 5684 | if (raid0_priv->nr_strip_zones > 1) { |
@@ -5696,6 +5687,9 @@ static void *raid45_takeover_raid0(mddev_t *mddev, int level) | |||
5696 | return ERR_PTR(-EINVAL); | 5687 | return ERR_PTR(-EINVAL); |
5697 | } | 5688 | } |
5698 | 5689 | ||
5690 | sectors = raid0_priv->strip_zone[0].zone_end; | ||
5691 | sector_div(sectors, raid0_priv->strip_zone[0].nb_dev); | ||
5692 | mddev->dev_sectors = sectors; | ||
5699 | mddev->new_level = level; | 5693 | mddev->new_level = level; |
5700 | mddev->new_layout = ALGORITHM_PARITY_N; | 5694 | mddev->new_layout = ALGORITHM_PARITY_N; |
5701 | mddev->new_chunk_sectors = mddev->chunk_sectors; | 5695 | mddev->new_chunk_sectors = mddev->chunk_sectors; |
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 8d563a4f022a..3ca77a2613ba 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h | |||
@@ -400,8 +400,6 @@ struct raid5_private_data { | |||
400 | * Cleared when a sync completes. | 400 | * Cleared when a sync completes. |
401 | */ | 401 | */ |
402 | 402 | ||
403 | struct plug_handle plug; | ||
404 | |||
405 | /* per cpu variables */ | 403 | /* per cpu variables */ |
406 | struct raid5_percpu { | 404 | struct raid5_percpu { |
407 | struct page *spare_page; /* Used when checking P/Q in raid6 */ | 405 | struct page *spare_page; /* Used when checking P/Q in raid6 */ |
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c index 5466d47db899..aae40e52af5b 100644 --- a/drivers/media/common/tuners/tda18271-common.c +++ b/drivers/media/common/tuners/tda18271-common.c | |||
@@ -533,16 +533,7 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) | |||
533 | if (tda_fail(ret)) | 533 | if (tda_fail(ret)) |
534 | goto fail; | 534 | goto fail; |
535 | 535 | ||
536 | regs[R_MPD] = (0x77 & pd); | 536 | regs[R_MPD] = (0x7f & pd); |
537 | |||
538 | switch (priv->mode) { | ||
539 | case TDA18271_ANALOG: | ||
540 | regs[R_MPD] &= ~0x08; | ||
541 | break; | ||
542 | case TDA18271_DIGITAL: | ||
543 | regs[R_MPD] |= 0x08; | ||
544 | break; | ||
545 | } | ||
546 | 537 | ||
547 | div = ((d * (freq / 1000)) << 7) / 125; | 538 | div = ((d * (freq / 1000)) << 7) / 125; |
548 | 539 | ||
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c index 9ad4454a148d..d884f5eee73c 100644 --- a/drivers/media/common/tuners/tda18271-fe.c +++ b/drivers/media/common/tuners/tda18271-fe.c | |||
@@ -579,8 +579,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) | |||
579 | #define RF3 2 | 579 | #define RF3 2 |
580 | u32 rf_default[3]; | 580 | u32 rf_default[3]; |
581 | u32 rf_freq[3]; | 581 | u32 rf_freq[3]; |
582 | u8 prog_cal[3]; | 582 | s32 prog_cal[3]; |
583 | u8 prog_tab[3]; | 583 | s32 prog_tab[3]; |
584 | 584 | ||
585 | i = tda18271_lookup_rf_band(fe, &freq, NULL); | 585 | i = tda18271_lookup_rf_band(fe, &freq, NULL); |
586 | 586 | ||
@@ -602,32 +602,33 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) | |||
602 | return bcal; | 602 | return bcal; |
603 | 603 | ||
604 | tda18271_calc_rf_cal(fe, &rf_freq[rf]); | 604 | tda18271_calc_rf_cal(fe, &rf_freq[rf]); |
605 | prog_tab[rf] = regs[R_EB14]; | 605 | prog_tab[rf] = (s32)regs[R_EB14]; |
606 | 606 | ||
607 | if (1 == bcal) | 607 | if (1 == bcal) |
608 | prog_cal[rf] = tda18271_calibrate_rf(fe, rf_freq[rf]); | 608 | prog_cal[rf] = |
609 | (s32)tda18271_calibrate_rf(fe, rf_freq[rf]); | ||
609 | else | 610 | else |
610 | prog_cal[rf] = prog_tab[rf]; | 611 | prog_cal[rf] = prog_tab[rf]; |
611 | 612 | ||
612 | switch (rf) { | 613 | switch (rf) { |
613 | case RF1: | 614 | case RF1: |
614 | map[i].rf_a1 = 0; | 615 | map[i].rf_a1 = 0; |
615 | map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]); | 616 | map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]); |
616 | map[i].rf1 = rf_freq[RF1] / 1000; | 617 | map[i].rf1 = rf_freq[RF1] / 1000; |
617 | break; | 618 | break; |
618 | case RF2: | 619 | case RF2: |
619 | dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) - | 620 | dividend = (prog_cal[RF2] - prog_tab[RF2] - |
620 | (s32)(prog_cal[RF1] + prog_tab[RF1]); | 621 | prog_cal[RF1] + prog_tab[RF1]); |
621 | divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000; | 622 | divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000; |
622 | map[i].rf_a1 = (dividend / divisor); | 623 | map[i].rf_a1 = (dividend / divisor); |
623 | map[i].rf2 = rf_freq[RF2] / 1000; | 624 | map[i].rf2 = rf_freq[RF2] / 1000; |
624 | break; | 625 | break; |
625 | case RF3: | 626 | case RF3: |
626 | dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) - | 627 | dividend = (prog_cal[RF3] - prog_tab[RF3] - |
627 | (s32)(prog_cal[RF2] + prog_tab[RF2]); | 628 | prog_cal[RF2] + prog_tab[RF2]); |
628 | divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000; | 629 | divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000; |
629 | map[i].rf_a2 = (dividend / divisor); | 630 | map[i].rf_a2 = (dividend / divisor); |
630 | map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]); | 631 | map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]); |
631 | map[i].rf3 = rf_freq[RF3] / 1000; | 632 | map[i].rf3 = rf_freq[RF3] / 1000; |
632 | break; | 633 | break; |
633 | default: | 634 | default: |
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c index e7f84c705da8..3d5b6ab7e332 100644 --- a/drivers/media/common/tuners/tda18271-maps.c +++ b/drivers/media/common/tuners/tda18271-maps.c | |||
@@ -229,8 +229,7 @@ static struct tda18271_map tda18271c2_km[] = { | |||
229 | static struct tda18271_map tda18271_rf_band[] = { | 229 | static struct tda18271_map tda18271_rf_band[] = { |
230 | { .rfmax = 47900, .val = 0x00 }, | 230 | { .rfmax = 47900, .val = 0x00 }, |
231 | { .rfmax = 61100, .val = 0x01 }, | 231 | { .rfmax = 61100, .val = 0x01 }, |
232 | /* { .rfmax = 152600, .val = 0x02 }, */ | 232 | { .rfmax = 152600, .val = 0x02 }, |
233 | { .rfmax = 121200, .val = 0x02 }, | ||
234 | { .rfmax = 164700, .val = 0x03 }, | 233 | { .rfmax = 164700, .val = 0x03 }, |
235 | { .rfmax = 203500, .val = 0x04 }, | 234 | { .rfmax = 203500, .val = 0x04 }, |
236 | { .rfmax = 457800, .val = 0x05 }, | 235 | { .rfmax = 457800, .val = 0x05 }, |
@@ -448,7 +447,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { | |||
448 | { .rfmax = 150000, .val = 0xb0 }, | 447 | { .rfmax = 150000, .val = 0xb0 }, |
449 | { .rfmax = 151000, .val = 0xb1 }, | 448 | { .rfmax = 151000, .val = 0xb1 }, |
450 | { .rfmax = 152000, .val = 0xb7 }, | 449 | { .rfmax = 152000, .val = 0xb7 }, |
451 | { .rfmax = 153000, .val = 0xbd }, | 450 | { .rfmax = 152600, .val = 0xbd }, |
452 | { .rfmax = 154000, .val = 0x20 }, | 451 | { .rfmax = 154000, .val = 0x20 }, |
453 | { .rfmax = 155000, .val = 0x22 }, | 452 | { .rfmax = 155000, .val = 0x22 }, |
454 | { .rfmax = 156000, .val = 0x24 }, | 453 | { .rfmax = 156000, .val = 0x24 }, |
@@ -459,7 +458,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { | |||
459 | { .rfmax = 161000, .val = 0x2d }, | 458 | { .rfmax = 161000, .val = 0x2d }, |
460 | { .rfmax = 163000, .val = 0x2e }, | 459 | { .rfmax = 163000, .val = 0x2e }, |
461 | { .rfmax = 164000, .val = 0x2f }, | 460 | { .rfmax = 164000, .val = 0x2f }, |
462 | { .rfmax = 165000, .val = 0x30 }, | 461 | { .rfmax = 164700, .val = 0x30 }, |
463 | { .rfmax = 166000, .val = 0x11 }, | 462 | { .rfmax = 166000, .val = 0x11 }, |
464 | { .rfmax = 167000, .val = 0x12 }, | 463 | { .rfmax = 167000, .val = 0x12 }, |
465 | { .rfmax = 168000, .val = 0x13 }, | 464 | { .rfmax = 168000, .val = 0x13 }, |
@@ -510,7 +509,8 @@ static struct tda18271_map tda18271c2_rf_cal[] = { | |||
510 | { .rfmax = 236000, .val = 0x1b }, | 509 | { .rfmax = 236000, .val = 0x1b }, |
511 | { .rfmax = 237000, .val = 0x1c }, | 510 | { .rfmax = 237000, .val = 0x1c }, |
512 | { .rfmax = 240000, .val = 0x1d }, | 511 | { .rfmax = 240000, .val = 0x1d }, |
513 | { .rfmax = 242000, .val = 0x1f }, | 512 | { .rfmax = 242000, .val = 0x1e }, |
513 | { .rfmax = 244000, .val = 0x1f }, | ||
514 | { .rfmax = 247000, .val = 0x20 }, | 514 | { .rfmax = 247000, .val = 0x20 }, |
515 | { .rfmax = 249000, .val = 0x21 }, | 515 | { .rfmax = 249000, .val = 0x21 }, |
516 | { .rfmax = 252000, .val = 0x22 }, | 516 | { .rfmax = 252000, .val = 0x22 }, |
@@ -624,7 +624,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { | |||
624 | { .rfmax = 453000, .val = 0x93 }, | 624 | { .rfmax = 453000, .val = 0x93 }, |
625 | { .rfmax = 454000, .val = 0x94 }, | 625 | { .rfmax = 454000, .val = 0x94 }, |
626 | { .rfmax = 456000, .val = 0x96 }, | 626 | { .rfmax = 456000, .val = 0x96 }, |
627 | { .rfmax = 457000, .val = 0x98 }, | 627 | { .rfmax = 457800, .val = 0x98 }, |
628 | { .rfmax = 461000, .val = 0x11 }, | 628 | { .rfmax = 461000, .val = 0x11 }, |
629 | { .rfmax = 468000, .val = 0x12 }, | 629 | { .rfmax = 468000, .val = 0x12 }, |
630 | { .rfmax = 472000, .val = 0x13 }, | 630 | { .rfmax = 472000, .val = 0x13 }, |
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c index 955254090a0e..03f96d6ca894 100644 --- a/drivers/media/dvb/b2c2/flexcop-pci.c +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -38,7 +38,7 @@ MODULE_PARM_DESC(debug, | |||
38 | DEBSTATUS); | 38 | DEBSTATUS); |
39 | 39 | ||
40 | #define DRIVER_VERSION "0.1" | 40 | #define DRIVER_VERSION "0.1" |
41 | #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" | 41 | #define DRIVER_NAME "flexcop-pci" |
42 | #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" | 42 | #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" |
43 | 43 | ||
44 | struct flexcop_pci { | 44 | struct flexcop_pci { |
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index fe4f894183ff..c545039287ad 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig | |||
@@ -356,13 +356,15 @@ config DVB_USB_LME2510 | |||
356 | select DVB_TDA826X if !DVB_FE_CUSTOMISE | 356 | select DVB_TDA826X if !DVB_FE_CUSTOMISE |
357 | select DVB_STV0288 if !DVB_FE_CUSTOMISE | 357 | select DVB_STV0288 if !DVB_FE_CUSTOMISE |
358 | select DVB_IX2505V if !DVB_FE_CUSTOMISE | 358 | select DVB_IX2505V if !DVB_FE_CUSTOMISE |
359 | select DVB_STV0299 if !DVB_FE_CUSTOMISE | ||
360 | select DVB_PLL if !DVB_FE_CUSTOMISE | ||
359 | help | 361 | help |
360 | Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . | 362 | Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . |
361 | 363 | ||
362 | config DVB_USB_TECHNISAT_USB2 | 364 | config DVB_USB_TECHNISAT_USB2 |
363 | tristate "Technisat DVB-S/S2 USB2.0 support" | 365 | tristate "Technisat DVB-S/S2 USB2.0 support" |
364 | depends on DVB_USB | 366 | depends on DVB_USB |
365 | select DVB_STB0899 if !DVB_FE_CUSTOMISE | 367 | select DVB_STV090x if !DVB_FE_CUSTOMISE |
366 | select DVB_STB6100 if !DVB_FE_CUSTOMISE | 368 | select DVB_STV6110x if !DVB_FE_CUSTOMISE |
367 | help | 369 | help |
368 | Say Y here to support the Technisat USB2 DVB-S/S2 device | 370 | Say Y here to support the Technisat USB2 DVB-S/S2 device |
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index 97af266d7f1d..65214af5cd74 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c | |||
@@ -2162,7 +2162,7 @@ struct dibx000_agc_config dib7090_agc_config[2] = { | |||
2162 | .agc1_pt3 = 98, | 2162 | .agc1_pt3 = 98, |
2163 | .agc1_slope1 = 0, | 2163 | .agc1_slope1 = 0, |
2164 | .agc1_slope2 = 167, | 2164 | .agc1_slope2 = 167, |
2165 | .agc1_pt1 = 98, | 2165 | .agc2_pt1 = 98, |
2166 | .agc2_pt2 = 255, | 2166 | .agc2_pt2 = 255, |
2167 | .agc2_slope1 = 104, | 2167 | .agc2_slope1 = 104, |
2168 | .agc2_slope2 = 0, | 2168 | .agc2_slope2 = 0, |
@@ -2440,11 +2440,11 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) | |||
2440 | dib0700_set_i2c_speed(adap->dev, 340); | 2440 | dib0700_set_i2c_speed(adap->dev, 340); |
2441 | adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); | 2441 | adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); |
2442 | 2442 | ||
2443 | dib7090_slave_reset(adap->fe); | ||
2444 | |||
2445 | if (adap->fe == NULL) | 2443 | if (adap->fe == NULL) |
2446 | return -ENODEV; | 2444 | return -ENODEV; |
2447 | 2445 | ||
2446 | dib7090_slave_reset(adap->fe); | ||
2447 | |||
2448 | return 0; | 2448 | return 0; |
2449 | } | 2449 | } |
2450 | 2450 | ||
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index ccc2d1af49d4..6927c726ce35 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c | |||
@@ -1520,6 +1520,7 @@ static int init_channel(struct ngene_channel *chan) | |||
1520 | if (dev->ci.en && (io & NGENE_IO_TSOUT)) { | 1520 | if (dev->ci.en && (io & NGENE_IO_TSOUT)) { |
1521 | dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); | 1521 | dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1); |
1522 | set_transfer(chan, 1); | 1522 | set_transfer(chan, 1); |
1523 | chan->dev->channel[2].DataFormatFlags = DF_SWAP32; | ||
1523 | set_transfer(&chan->dev->channel[2], 1); | 1524 | set_transfer(&chan->dev->channel[2], 1); |
1524 | dvb_register_device(adapter, &chan->ci_dev, | 1525 | dvb_register_device(adapter, &chan->ci_dev, |
1525 | &ngene_dvbdev_ci, (void *) chan, | 1526 | &ngene_dvbdev_ci, (void *) chan, |
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c index 23640ed44d85..056138f63c7d 100644 --- a/drivers/media/media-entity.c +++ b/drivers/media/media-entity.c | |||
@@ -378,7 +378,6 @@ EXPORT_SYMBOL_GPL(media_entity_create_link); | |||
378 | 378 | ||
379 | static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) | 379 | static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) |
380 | { | 380 | { |
381 | const u32 mask = MEDIA_LNK_FL_ENABLED; | ||
382 | int ret; | 381 | int ret; |
383 | 382 | ||
384 | /* Notify both entities. */ | 383 | /* Notify both entities. */ |
@@ -395,7 +394,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) | |||
395 | return ret; | 394 | return ret; |
396 | } | 395 | } |
397 | 396 | ||
398 | link->flags = (link->flags & ~mask) | (flags & mask); | 397 | link->flags = flags; |
399 | link->reverse->flags = link->flags; | 398 | link->reverse->flags = link->flags; |
400 | 399 | ||
401 | return 0; | 400 | return 0; |
@@ -417,6 +416,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) | |||
417 | */ | 416 | */ |
418 | int __media_entity_setup_link(struct media_link *link, u32 flags) | 417 | int __media_entity_setup_link(struct media_link *link, u32 flags) |
419 | { | 418 | { |
419 | const u32 mask = MEDIA_LNK_FL_ENABLED; | ||
420 | struct media_device *mdev; | 420 | struct media_device *mdev; |
421 | struct media_entity *source, *sink; | 421 | struct media_entity *source, *sink; |
422 | int ret = -EBUSY; | 422 | int ret = -EBUSY; |
@@ -424,6 +424,10 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) | |||
424 | if (link == NULL) | 424 | if (link == NULL) |
425 | return -EINVAL; | 425 | return -EINVAL; |
426 | 426 | ||
427 | /* The non-modifiable link flags must not be modified. */ | ||
428 | if ((link->flags & ~mask) != (flags & ~mask)) | ||
429 | return -EINVAL; | ||
430 | |||
427 | if (link->flags & MEDIA_LNK_FL_IMMUTABLE) | 431 | if (link->flags & MEDIA_LNK_FL_IMMUTABLE) |
428 | return link->flags == flags ? 0 : -EINVAL; | 432 | return link->flags == flags ? 0 : -EINVAL; |
429 | 433 | ||
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index dc3f04c52d5e..87bad7678d92 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
@@ -170,7 +170,7 @@ static int fmr2_setfreq(struct fmr2 *dev) | |||
170 | return 0; | 170 | return 0; |
171 | } | 171 | } |
172 | 172 | ||
173 | /* !!! not tested, in my card this does't work !!! */ | 173 | /* !!! not tested, in my card this doesn't work !!! */ |
174 | static int fmr2_setvolume(struct fmr2 *dev) | 174 | static int fmr2_setvolume(struct fmr2 *dev) |
175 | { | 175 | { |
176 | int vol[16] = { 0x021, 0x084, 0x090, 0x104, | 176 | int vol[16] = { 0x021, 0x084, 0x090, 0x104, |
diff --git a/drivers/media/radio/saa7706h.c b/drivers/media/radio/saa7706h.c index 585680ffbfb6..b1193dfc5087 100644 --- a/drivers/media/radio/saa7706h.c +++ b/drivers/media/radio/saa7706h.c | |||
@@ -376,7 +376,7 @@ static int __devinit saa7706h_probe(struct i2c_client *client, | |||
376 | v4l_info(client, "chip found @ 0x%02x (%s)\n", | 376 | v4l_info(client, "chip found @ 0x%02x (%s)\n", |
377 | client->addr << 1, client->adapter->name); | 377 | client->addr << 1, client->adapter->name); |
378 | 378 | ||
379 | state = kmalloc(sizeof(struct saa7706h_state), GFP_KERNEL); | 379 | state = kzalloc(sizeof(struct saa7706h_state), GFP_KERNEL); |
380 | if (state == NULL) | 380 | if (state == NULL) |
381 | return -ENOMEM; | 381 | return -ENOMEM; |
382 | sd = &state->sd; | 382 | sd = &state->sd; |
diff --git a/drivers/media/radio/tef6862.c b/drivers/media/radio/tef6862.c index 7c0d77751f6e..0991e1973678 100644 --- a/drivers/media/radio/tef6862.c +++ b/drivers/media/radio/tef6862.c | |||
@@ -176,7 +176,7 @@ static int __devinit tef6862_probe(struct i2c_client *client, | |||
176 | v4l_info(client, "chip found @ 0x%02x (%s)\n", | 176 | v4l_info(client, "chip found @ 0x%02x (%s)\n", |
177 | client->addr << 1, client->adapter->name); | 177 | client->addr << 1, client->adapter->name); |
178 | 178 | ||
179 | state = kmalloc(sizeof(struct tef6862_state), GFP_KERNEL); | 179 | state = kzalloc(sizeof(struct tef6862_state), GFP_KERNEL); |
180 | if (state == NULL) | 180 | if (state == NULL) |
181 | return -ENOMEM; | 181 | return -ENOMEM; |
182 | state->freq = TEF6862_LO_FREQ; | 182 | state->freq = TEF6862_LO_FREQ; |
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index ebd68edf5b24..8fc0f081b470 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" | 46 | #define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" |
47 | #define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" | 47 | #define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display" |
48 | #define MOD_NAME "imon" | 48 | #define MOD_NAME "imon" |
49 | #define MOD_VERSION "0.9.2" | 49 | #define MOD_VERSION "0.9.3" |
50 | 50 | ||
51 | #define DISPLAY_MINOR_BASE 144 | 51 | #define DISPLAY_MINOR_BASE 144 |
52 | #define DEVICE_NAME "lcd%d" | 52 | #define DEVICE_NAME "lcd%d" |
@@ -460,8 +460,9 @@ static int display_close(struct inode *inode, struct file *file) | |||
460 | } | 460 | } |
461 | 461 | ||
462 | /** | 462 | /** |
463 | * Sends a packet to the device -- this function must be called | 463 | * Sends a packet to the device -- this function must be called with |
464 | * with ictx->lock held. | 464 | * ictx->lock held, or its unlock/lock sequence while waiting for tx |
465 | * to complete can/will lead to a deadlock. | ||
465 | */ | 466 | */ |
466 | static int send_packet(struct imon_context *ictx) | 467 | static int send_packet(struct imon_context *ictx) |
467 | { | 468 | { |
@@ -991,12 +992,21 @@ static void imon_touch_display_timeout(unsigned long data) | |||
991 | * the iMON remotes, and those used by the Windows MCE remotes (which is | 992 | * the iMON remotes, and those used by the Windows MCE remotes (which is |
992 | * really just RC-6), but only one or the other at a time, as the signals | 993 | * really just RC-6), but only one or the other at a time, as the signals |
993 | * are decoded onboard the receiver. | 994 | * are decoded onboard the receiver. |
995 | * | ||
996 | * This function gets called two different ways, one way is from | ||
997 | * rc_register_device, for initial protocol selection/setup, and the other is | ||
998 | * via a userspace-initiated protocol change request, either by direct sysfs | ||
999 | * prodding or by something like ir-keytable. In the rc_register_device case, | ||
1000 | * the imon context lock is already held, but when initiated from userspace, | ||
1001 | * it is not, so we must acquire it prior to calling send_packet, which | ||
1002 | * requires that the lock is held. | ||
994 | */ | 1003 | */ |
995 | static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) | 1004 | static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) |
996 | { | 1005 | { |
997 | int retval; | 1006 | int retval; |
998 | struct imon_context *ictx = rc->priv; | 1007 | struct imon_context *ictx = rc->priv; |
999 | struct device *dev = ictx->dev; | 1008 | struct device *dev = ictx->dev; |
1009 | bool unlock = false; | ||
1000 | unsigned char ir_proto_packet[] = { | 1010 | unsigned char ir_proto_packet[] = { |
1001 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; | 1011 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; |
1002 | 1012 | ||
@@ -1029,6 +1039,11 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) | |||
1029 | 1039 | ||
1030 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); | 1040 | memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); |
1031 | 1041 | ||
1042 | if (!mutex_is_locked(&ictx->lock)) { | ||
1043 | unlock = true; | ||
1044 | mutex_lock(&ictx->lock); | ||
1045 | } | ||
1046 | |||
1032 | retval = send_packet(ictx); | 1047 | retval = send_packet(ictx); |
1033 | if (retval) | 1048 | if (retval) |
1034 | goto out; | 1049 | goto out; |
@@ -1037,6 +1052,9 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 rc_type) | |||
1037 | ictx->pad_mouse = false; | 1052 | ictx->pad_mouse = false; |
1038 | 1053 | ||
1039 | out: | 1054 | out: |
1055 | if (unlock) | ||
1056 | mutex_unlock(&ictx->lock); | ||
1057 | |||
1040 | return retval; | 1058 | return retval; |
1041 | } | 1059 | } |
1042 | 1060 | ||
@@ -2134,6 +2152,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf) | |||
2134 | goto rdev_setup_failed; | 2152 | goto rdev_setup_failed; |
2135 | } | 2153 | } |
2136 | 2154 | ||
2155 | mutex_unlock(&ictx->lock); | ||
2137 | return ictx; | 2156 | return ictx; |
2138 | 2157 | ||
2139 | rdev_setup_failed: | 2158 | rdev_setup_failed: |
@@ -2205,6 +2224,7 @@ static struct imon_context *imon_init_intf1(struct usb_interface *intf, | |||
2205 | goto urb_submit_failed; | 2224 | goto urb_submit_failed; |
2206 | } | 2225 | } |
2207 | 2226 | ||
2227 | mutex_unlock(&ictx->lock); | ||
2208 | return ictx; | 2228 | return ictx; |
2209 | 2229 | ||
2210 | urb_submit_failed: | 2230 | urb_submit_failed: |
@@ -2299,6 +2319,8 @@ static int __devinit imon_probe(struct usb_interface *interface, | |||
2299 | usb_set_intfdata(interface, ictx); | 2319 | usb_set_intfdata(interface, ictx); |
2300 | 2320 | ||
2301 | if (ifnum == 0) { | 2321 | if (ifnum == 0) { |
2322 | mutex_lock(&ictx->lock); | ||
2323 | |||
2302 | if (product == 0xffdc && ictx->rf_device) { | 2324 | if (product == 0xffdc && ictx->rf_device) { |
2303 | sysfs_err = sysfs_create_group(&interface->dev.kobj, | 2325 | sysfs_err = sysfs_create_group(&interface->dev.kobj, |
2304 | &imon_rf_attr_group); | 2326 | &imon_rf_attr_group); |
@@ -2309,13 +2331,14 @@ static int __devinit imon_probe(struct usb_interface *interface, | |||
2309 | 2331 | ||
2310 | if (ictx->display_supported) | 2332 | if (ictx->display_supported) |
2311 | imon_init_display(ictx, interface); | 2333 | imon_init_display(ictx, interface); |
2334 | |||
2335 | mutex_unlock(&ictx->lock); | ||
2312 | } | 2336 | } |
2313 | 2337 | ||
2314 | dev_info(dev, "iMON device (%04x:%04x, intf%d) on " | 2338 | dev_info(dev, "iMON device (%04x:%04x, intf%d) on " |
2315 | "usb<%d:%d> initialized\n", vendor, product, ifnum, | 2339 | "usb<%d:%d> initialized\n", vendor, product, ifnum, |
2316 | usbdev->bus->busnum, usbdev->devnum); | 2340 | usbdev->bus->busnum, usbdev->devnum); |
2317 | 2341 | ||
2318 | mutex_unlock(&ictx->lock); | ||
2319 | mutex_unlock(&driver_lock); | 2342 | mutex_unlock(&driver_lock); |
2320 | 2343 | ||
2321 | return 0; | 2344 | return 0; |
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index accaf6c9789a..43908a70bd8b 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/io.h> | 36 | #include <linux/io.h> |
37 | #include <linux/interrupt.h> | 37 | #include <linux/interrupt.h> |
38 | #include <linux/sched.h> | 38 | #include <linux/sched.h> |
39 | #include <linux/delay.h> | ||
39 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
40 | #include <linux/input.h> | 41 | #include <linux/input.h> |
41 | #include <linux/bitops.h> | 42 | #include <linux/bitops.h> |
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 044fb7a382d6..0c273ec465c9 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c | |||
@@ -220,6 +220,8 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
220 | { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, | 220 | { USB_DEVICE(VENDOR_PHILIPS, 0x206c) }, |
221 | /* Philips/Spinel plus IR transceiver for ASUS */ | 221 | /* Philips/Spinel plus IR transceiver for ASUS */ |
222 | { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, | 222 | { USB_DEVICE(VENDOR_PHILIPS, 0x2088) }, |
223 | /* Philips IR transceiver (Dell branded) */ | ||
224 | { USB_DEVICE(VENDOR_PHILIPS, 0x2093) }, | ||
223 | /* Realtek MCE IR Receiver and card reader */ | 225 | /* Realtek MCE IR Receiver and card reader */ |
224 | { USB_DEVICE(VENDOR_REALTEK, 0x0161), | 226 | { USB_DEVICE(VENDOR_REALTEK, 0x0161), |
225 | .driver_info = MULTIFUNCTION }, | 227 | .driver_info = MULTIFUNCTION }, |
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index f53f9c68d38d..a2706648e365 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
@@ -707,7 +707,8 @@ static void ir_close(struct input_dev *idev) | |||
707 | { | 707 | { |
708 | struct rc_dev *rdev = input_get_drvdata(idev); | 708 | struct rc_dev *rdev = input_get_drvdata(idev); |
709 | 709 | ||
710 | rdev->close(rdev); | 710 | if (rdev) |
711 | rdev->close(rdev); | ||
711 | } | 712 | } |
712 | 713 | ||
713 | /* class for /sys/class/rc */ | 714 | /* class for /sys/class/rc */ |
@@ -733,6 +734,7 @@ static struct { | |||
733 | { RC_TYPE_SONY, "sony" }, | 734 | { RC_TYPE_SONY, "sony" }, |
734 | { RC_TYPE_RC5_SZ, "rc-5-sz" }, | 735 | { RC_TYPE_RC5_SZ, "rc-5-sz" }, |
735 | { RC_TYPE_LIRC, "lirc" }, | 736 | { RC_TYPE_LIRC, "lirc" }, |
737 | { RC_TYPE_OTHER, "other" }, | ||
736 | }; | 738 | }; |
737 | 739 | ||
738 | #define PROTO_NONE "none" | 740 | #define PROTO_NONE "none" |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 4498b944dec8..00f51dd121f3 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -875,7 +875,7 @@ config MX3_VIDEO | |||
875 | config VIDEO_MX3 | 875 | config VIDEO_MX3 |
876 | tristate "i.MX3x Camera Sensor Interface driver" | 876 | tristate "i.MX3x Camera Sensor Interface driver" |
877 | depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA | 877 | depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA |
878 | select VIDEOBUF_DMA_CONTIG | 878 | select VIDEOBUF2_DMA_CONTIG |
879 | select MX3_VIDEO | 879 | select MX3_VIDEO |
880 | ---help--- | 880 | ---help--- |
881 | This is a v4l2 driver for the i.MX3x Camera Sensor Interface | 881 | This is a v4l2 driver for the i.MX3x Camera Sensor Interface |
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index c6e2ca3b1149..6fbc356113c1 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -350,9 +350,17 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) | |||
350 | 350 | ||
351 | /* No struct video_device, but can have buffers allocated */ | 351 | /* No struct video_device, but can have buffers allocated */ |
352 | if (type == CX18_ENC_STREAM_TYPE_IDX) { | 352 | if (type == CX18_ENC_STREAM_TYPE_IDX) { |
353 | /* If the module params didn't inhibit IDX ... */ | ||
353 | if (cx->stream_buffers[type] != 0) { | 354 | if (cx->stream_buffers[type] != 0) { |
354 | cx->stream_buffers[type] = 0; | 355 | cx->stream_buffers[type] = 0; |
355 | cx18_stream_free(&cx->streams[type]); | 356 | /* |
357 | * Before calling cx18_stream_free(), | ||
358 | * check if the IDX stream was actually set up. | ||
359 | * Needed, since the cx18_probe() error path | ||
360 | * exits through here as well as normal clean up | ||
361 | */ | ||
362 | if (cx->streams[type].buffers != 0) | ||
363 | cx18_stream_free(&cx->streams[type]); | ||
356 | } | 364 | } |
357 | continue; | 365 | continue; |
358 | } | 366 | } |
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig index 3b6e7f28568e..caab1bfb79e2 100644 --- a/drivers/media/video/cx23885/Kconfig +++ b/drivers/media/video/cx23885/Kconfig | |||
@@ -22,6 +22,7 @@ config VIDEO_CX23885 | |||
22 | select DVB_CX24116 if !DVB_FE_CUSTOMISE | 22 | select DVB_CX24116 if !DVB_FE_CUSTOMISE |
23 | select DVB_STV0900 if !DVB_FE_CUSTOMISE | 23 | select DVB_STV0900 if !DVB_FE_CUSTOMISE |
24 | select DVB_DS3000 if !DVB_FE_CUSTOMISE | 24 | select DVB_DS3000 if !DVB_FE_CUSTOMISE |
25 | select DVB_STV0367 if !DVB_FE_CUSTOMISE | ||
25 | select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE | 26 | select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE |
26 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE | 27 | select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE |
27 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE | 28 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE |
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c index 1a1169115716..0382ea752e6f 100644 --- a/drivers/media/video/imx074.c +++ b/drivers/media/video/imx074.c | |||
@@ -298,7 +298,7 @@ static unsigned long imx074_query_bus_param(struct soc_camera_device *icd) | |||
298 | static int imx074_set_bus_param(struct soc_camera_device *icd, | 298 | static int imx074_set_bus_param(struct soc_camera_device *icd, |
299 | unsigned long flags) | 299 | unsigned long flags) |
300 | { | 300 | { |
301 | return -1; | 301 | return -EINVAL; |
302 | } | 302 | } |
303 | 303 | ||
304 | static struct soc_camera_ops imx074_ops = { | 304 | static struct soc_camera_ops imx074_ops = { |
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c index 5e1c9a81984c..303ffa7df4ac 100644 --- a/drivers/media/video/m52790.c +++ b/drivers/media/video/m52790.c | |||
@@ -174,7 +174,7 @@ static int m52790_probe(struct i2c_client *client, | |||
174 | v4l_info(client, "chip found @ 0x%x (%s)\n", | 174 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
175 | client->addr << 1, client->adapter->name); | 175 | client->addr << 1, client->adapter->name); |
176 | 176 | ||
177 | state = kmalloc(sizeof(struct m52790_state), GFP_KERNEL); | 177 | state = kzalloc(sizeof(struct m52790_state), GFP_KERNEL); |
178 | if (state == NULL) | 178 | if (state == NULL) |
179 | return -ENOMEM; | 179 | return -ENOMEM; |
180 | 180 | ||
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index 503bd7922bd6..472a69359e60 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c | |||
@@ -215,20 +215,21 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel) | |||
215 | } | 215 | } |
216 | 216 | ||
217 | switch (xclksel) { | 217 | switch (xclksel) { |
218 | case 0: | 218 | case ISP_XCLK_A: |
219 | isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, | 219 | isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, |
220 | ISPTCTRL_CTRL_DIVA_MASK, | 220 | ISPTCTRL_CTRL_DIVA_MASK, |
221 | divisor << ISPTCTRL_CTRL_DIVA_SHIFT); | 221 | divisor << ISPTCTRL_CTRL_DIVA_SHIFT); |
222 | dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n", | 222 | dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n", |
223 | currentxclk); | 223 | currentxclk); |
224 | break; | 224 | break; |
225 | case 1: | 225 | case ISP_XCLK_B: |
226 | isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, | 226 | isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, |
227 | ISPTCTRL_CTRL_DIVB_MASK, | 227 | ISPTCTRL_CTRL_DIVB_MASK, |
228 | divisor << ISPTCTRL_CTRL_DIVB_SHIFT); | 228 | divisor << ISPTCTRL_CTRL_DIVB_SHIFT); |
229 | dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n", | 229 | dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n", |
230 | currentxclk); | 230 | currentxclk); |
231 | break; | 231 | break; |
232 | case ISP_XCLK_NONE: | ||
232 | default: | 233 | default: |
233 | omap3isp_put(isp); | 234 | omap3isp_put(isp); |
234 | dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested " | 235 | dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested " |
@@ -237,13 +238,13 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel) | |||
237 | } | 238 | } |
238 | 239 | ||
239 | /* Do we go from stable whatever to clock? */ | 240 | /* Do we go from stable whatever to clock? */ |
240 | if (divisor >= 2 && isp->xclk_divisor[xclksel] < 2) | 241 | if (divisor >= 2 && isp->xclk_divisor[xclksel - 1] < 2) |
241 | omap3isp_get(isp); | 242 | omap3isp_get(isp); |
242 | /* Stopping the clock. */ | 243 | /* Stopping the clock. */ |
243 | else if (divisor < 2 && isp->xclk_divisor[xclksel] >= 2) | 244 | else if (divisor < 2 && isp->xclk_divisor[xclksel - 1] >= 2) |
244 | omap3isp_put(isp); | 245 | omap3isp_put(isp); |
245 | 246 | ||
246 | isp->xclk_divisor[xclksel] = divisor; | 247 | isp->xclk_divisor[xclksel - 1] = divisor; |
247 | 248 | ||
248 | omap3isp_put(isp); | 249 | omap3isp_put(isp); |
249 | 250 | ||
@@ -285,7 +286,8 @@ static void isp_power_settings(struct isp_device *isp, int idle) | |||
285 | */ | 286 | */ |
286 | void omap3isp_configure_bridge(struct isp_device *isp, | 287 | void omap3isp_configure_bridge(struct isp_device *isp, |
287 | enum ccdc_input_entity input, | 288 | enum ccdc_input_entity input, |
288 | const struct isp_parallel_platform_data *pdata) | 289 | const struct isp_parallel_platform_data *pdata, |
290 | unsigned int shift) | ||
289 | { | 291 | { |
290 | u32 ispctrl_val; | 292 | u32 ispctrl_val; |
291 | 293 | ||
@@ -298,9 +300,9 @@ void omap3isp_configure_bridge(struct isp_device *isp, | |||
298 | switch (input) { | 300 | switch (input) { |
299 | case CCDC_INPUT_PARALLEL: | 301 | case CCDC_INPUT_PARALLEL: |
300 | ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; | 302 | ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL; |
301 | ispctrl_val |= pdata->data_lane_shift << ISPCTRL_SHIFT_SHIFT; | ||
302 | ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; | 303 | ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT; |
303 | ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT; | 304 | ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT; |
305 | shift += pdata->data_lane_shift * 2; | ||
304 | break; | 306 | break; |
305 | 307 | ||
306 | case CCDC_INPUT_CSI2A: | 308 | case CCDC_INPUT_CSI2A: |
@@ -319,6 +321,8 @@ void omap3isp_configure_bridge(struct isp_device *isp, | |||
319 | return; | 321 | return; |
320 | } | 322 | } |
321 | 323 | ||
324 | ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK; | ||
325 | |||
322 | ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK; | 326 | ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK; |
323 | ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE; | 327 | ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE; |
324 | 328 | ||
@@ -658,6 +662,8 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) | |||
658 | 662 | ||
659 | /* Apply power change to connected non-nodes. */ | 663 | /* Apply power change to connected non-nodes. */ |
660 | ret = isp_pipeline_pm_power(entity, change); | 664 | ret = isp_pipeline_pm_power(entity, change); |
665 | if (ret < 0) | ||
666 | entity->use_count -= change; | ||
661 | 667 | ||
662 | mutex_unlock(&entity->parent->graph_mutex); | 668 | mutex_unlock(&entity->parent->graph_mutex); |
663 | 669 | ||
@@ -872,6 +878,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) | |||
872 | } | 878 | } |
873 | } | 879 | } |
874 | 880 | ||
881 | if (failure < 0) | ||
882 | isp->needs_reset = true; | ||
883 | |||
875 | return failure; | 884 | return failure; |
876 | } | 885 | } |
877 | 886 | ||
@@ -884,7 +893,8 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) | |||
884 | * single-shot or continuous mode. | 893 | * single-shot or continuous mode. |
885 | * | 894 | * |
886 | * Return 0 if successful, or the return value of the failed video::s_stream | 895 | * Return 0 if successful, or the return value of the failed video::s_stream |
887 | * operation otherwise. | 896 | * operation otherwise. The pipeline state is not updated when the operation |
897 | * fails, except when stopping the pipeline. | ||
888 | */ | 898 | */ |
889 | int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, | 899 | int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, |
890 | enum isp_pipeline_stream_state state) | 900 | enum isp_pipeline_stream_state state) |
@@ -895,7 +905,9 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, | |||
895 | ret = isp_pipeline_disable(pipe); | 905 | ret = isp_pipeline_disable(pipe); |
896 | else | 906 | else |
897 | ret = isp_pipeline_enable(pipe, state); | 907 | ret = isp_pipeline_enable(pipe, state); |
898 | pipe->stream_state = state; | 908 | |
909 | if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED) | ||
910 | pipe->stream_state = state; | ||
899 | 911 | ||
900 | return ret; | 912 | return ret; |
901 | } | 913 | } |
@@ -1481,6 +1493,10 @@ void omap3isp_put(struct isp_device *isp) | |||
1481 | if (--isp->ref_count == 0) { | 1493 | if (--isp->ref_count == 0) { |
1482 | isp_disable_interrupts(isp); | 1494 | isp_disable_interrupts(isp); |
1483 | isp_save_ctx(isp); | 1495 | isp_save_ctx(isp); |
1496 | if (isp->needs_reset) { | ||
1497 | isp_reset(isp); | ||
1498 | isp->needs_reset = false; | ||
1499 | } | ||
1484 | isp_disable_clocks(isp); | 1500 | isp_disable_clocks(isp); |
1485 | } | 1501 | } |
1486 | mutex_unlock(&isp->isp_mutex); | 1502 | mutex_unlock(&isp->isp_mutex); |
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h index cf5214e95a92..2620c405f5e4 100644 --- a/drivers/media/video/omap3isp/isp.h +++ b/drivers/media/video/omap3isp/isp.h | |||
@@ -132,7 +132,6 @@ struct isp_reg { | |||
132 | 132 | ||
133 | /** | 133 | /** |
134 | * struct isp_parallel_platform_data - Parallel interface platform data | 134 | * struct isp_parallel_platform_data - Parallel interface platform data |
135 | * @width: Parallel bus width in bits (8, 10, 11 or 12) | ||
136 | * @data_lane_shift: Data lane shifter | 135 | * @data_lane_shift: Data lane shifter |
137 | * 0 - CAMEXT[13:0] -> CAM[13:0] | 136 | * 0 - CAMEXT[13:0] -> CAM[13:0] |
138 | * 1 - CAMEXT[13:2] -> CAM[11:0] | 137 | * 1 - CAMEXT[13:2] -> CAM[11:0] |
@@ -146,7 +145,6 @@ struct isp_reg { | |||
146 | * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian | 145 | * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian |
147 | */ | 146 | */ |
148 | struct isp_parallel_platform_data { | 147 | struct isp_parallel_platform_data { |
149 | unsigned int width; | ||
150 | unsigned int data_lane_shift:2; | 148 | unsigned int data_lane_shift:2; |
151 | unsigned int clk_pol:1; | 149 | unsigned int clk_pol:1; |
152 | unsigned int bridge:4; | 150 | unsigned int bridge:4; |
@@ -262,6 +260,7 @@ struct isp_device { | |||
262 | /* ISP Obj */ | 260 | /* ISP Obj */ |
263 | spinlock_t stat_lock; /* common lock for statistic drivers */ | 261 | spinlock_t stat_lock; /* common lock for statistic drivers */ |
264 | struct mutex isp_mutex; /* For handling ref_count field */ | 262 | struct mutex isp_mutex; /* For handling ref_count field */ |
263 | bool needs_reset; | ||
265 | int has_context; | 264 | int has_context; |
266 | int ref_count; | 265 | int ref_count; |
267 | unsigned int autoidle; | 266 | unsigned int autoidle; |
@@ -311,11 +310,12 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, | |||
311 | enum isp_pipeline_stream_state state); | 310 | enum isp_pipeline_stream_state state); |
312 | void omap3isp_configure_bridge(struct isp_device *isp, | 311 | void omap3isp_configure_bridge(struct isp_device *isp, |
313 | enum ccdc_input_entity input, | 312 | enum ccdc_input_entity input, |
314 | const struct isp_parallel_platform_data *pdata); | 313 | const struct isp_parallel_platform_data *pdata, |
314 | unsigned int shift); | ||
315 | 315 | ||
316 | #define ISP_XCLK_NONE -1 | 316 | #define ISP_XCLK_NONE 0 |
317 | #define ISP_XCLK_A 0 | 317 | #define ISP_XCLK_A 1 |
318 | #define ISP_XCLK_B 1 | 318 | #define ISP_XCLK_B 2 |
319 | 319 | ||
320 | struct isp_device *omap3isp_get(struct isp_device *isp); | 320 | struct isp_device *omap3isp_get(struct isp_device *isp); |
321 | void omap3isp_put(struct isp_device *isp); | 321 | void omap3isp_put(struct isp_device *isp); |
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c index 5ff9d14ce710..39d501bda636 100644 --- a/drivers/media/video/omap3isp/ispccdc.c +++ b/drivers/media/video/omap3isp/ispccdc.c | |||
@@ -43,6 +43,12 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, | |||
43 | 43 | ||
44 | static const unsigned int ccdc_fmts[] = { | 44 | static const unsigned int ccdc_fmts[] = { |
45 | V4L2_MBUS_FMT_Y8_1X8, | 45 | V4L2_MBUS_FMT_Y8_1X8, |
46 | V4L2_MBUS_FMT_Y10_1X10, | ||
47 | V4L2_MBUS_FMT_Y12_1X12, | ||
48 | V4L2_MBUS_FMT_SGRBG8_1X8, | ||
49 | V4L2_MBUS_FMT_SRGGB8_1X8, | ||
50 | V4L2_MBUS_FMT_SBGGR8_1X8, | ||
51 | V4L2_MBUS_FMT_SGBRG8_1X8, | ||
46 | V4L2_MBUS_FMT_SGRBG10_1X10, | 52 | V4L2_MBUS_FMT_SGRBG10_1X10, |
47 | V4L2_MBUS_FMT_SRGGB10_1X10, | 53 | V4L2_MBUS_FMT_SRGGB10_1X10, |
48 | V4L2_MBUS_FMT_SBGGR10_1X10, | 54 | V4L2_MBUS_FMT_SBGGR10_1X10, |
@@ -1110,21 +1116,38 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) | |||
1110 | struct isp_parallel_platform_data *pdata = NULL; | 1116 | struct isp_parallel_platform_data *pdata = NULL; |
1111 | struct v4l2_subdev *sensor; | 1117 | struct v4l2_subdev *sensor; |
1112 | struct v4l2_mbus_framefmt *format; | 1118 | struct v4l2_mbus_framefmt *format; |
1119 | const struct isp_format_info *fmt_info; | ||
1120 | struct v4l2_subdev_format fmt_src; | ||
1121 | unsigned int depth_out; | ||
1122 | unsigned int depth_in = 0; | ||
1113 | struct media_pad *pad; | 1123 | struct media_pad *pad; |
1114 | unsigned long flags; | 1124 | unsigned long flags; |
1125 | unsigned int shift; | ||
1115 | u32 syn_mode; | 1126 | u32 syn_mode; |
1116 | u32 ccdc_pattern; | 1127 | u32 ccdc_pattern; |
1117 | 1128 | ||
1118 | if (ccdc->input == CCDC_INPUT_PARALLEL) { | 1129 | pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); |
1119 | pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); | 1130 | sensor = media_entity_to_v4l2_subdev(pad->entity); |
1120 | sensor = media_entity_to_v4l2_subdev(pad->entity); | 1131 | if (ccdc->input == CCDC_INPUT_PARALLEL) |
1121 | pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) | 1132 | pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) |
1122 | ->bus.parallel; | 1133 | ->bus.parallel; |
1134 | |||
1135 | /* Compute shift value for lane shifter to configure the bridge. */ | ||
1136 | fmt_src.pad = pad->index; | ||
1137 | fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE; | ||
1138 | if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) { | ||
1139 | fmt_info = omap3isp_video_format_info(fmt_src.format.code); | ||
1140 | depth_in = fmt_info->bpp; | ||
1123 | } | 1141 | } |
1124 | 1142 | ||
1125 | omap3isp_configure_bridge(isp, ccdc->input, pdata); | 1143 | fmt_info = omap3isp_video_format_info |
1144 | (isp->isp_ccdc.formats[CCDC_PAD_SINK].code); | ||
1145 | depth_out = fmt_info->bpp; | ||
1146 | |||
1147 | shift = depth_in - depth_out; | ||
1148 | omap3isp_configure_bridge(isp, ccdc->input, pdata, shift); | ||
1126 | 1149 | ||
1127 | ccdc->syncif.datsz = pdata ? pdata->width : 10; | 1150 | ccdc->syncif.datsz = depth_out; |
1128 | ccdc_config_sync_if(ccdc, &ccdc->syncif); | 1151 | ccdc_config_sync_if(ccdc, &ccdc->syncif); |
1129 | 1152 | ||
1130 | /* CCDC_PAD_SINK */ | 1153 | /* CCDC_PAD_SINK */ |
@@ -1338,7 +1361,7 @@ static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc, | |||
1338 | * @ccdc: Pointer to ISP CCDC device. | 1361 | * @ccdc: Pointer to ISP CCDC device. |
1339 | * @event: Pointing which event trigger handler | 1362 | * @event: Pointing which event trigger handler |
1340 | * | 1363 | * |
1341 | * Return 1 when the event and stopping request combination is satisfyied, | 1364 | * Return 1 when the event and stopping request combination is satisfied, |
1342 | * zero otherwise. | 1365 | * zero otherwise. |
1343 | */ | 1366 | */ |
1344 | static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event) | 1367 | static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event) |
@@ -1618,7 +1641,7 @@ static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer) | |||
1618 | 1641 | ||
1619 | ccdc_set_outaddr(ccdc, buffer->isp_addr); | 1642 | ccdc_set_outaddr(ccdc, buffer->isp_addr); |
1620 | 1643 | ||
1621 | /* We now have a buffer queued on the output, restart the pipeline in | 1644 | /* We now have a buffer queued on the output, restart the pipeline |
1622 | * on the next CCDC interrupt if running in continuous mode (or when | 1645 | * on the next CCDC interrupt if running in continuous mode (or when |
1623 | * starting the stream). | 1646 | * starting the stream). |
1624 | */ | 1647 | */ |
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c index 2b16988a501d..aba537af87e4 100644 --- a/drivers/media/video/omap3isp/isppreview.c +++ b/drivers/media/video/omap3isp/isppreview.c | |||
@@ -755,7 +755,7 @@ static struct preview_update update_attrs[] = { | |||
755 | * @configs - pointer to update config structure. | 755 | * @configs - pointer to update config structure. |
756 | * @config - return pointer to appropriate structure field. | 756 | * @config - return pointer to appropriate structure field. |
757 | * @bit - for which feature to return pointers. | 757 | * @bit - for which feature to return pointers. |
758 | * Return size of coresponding prev_params member | 758 | * Return size of corresponding prev_params member |
759 | */ | 759 | */ |
760 | static u32 | 760 | static u32 |
761 | __preview_get_ptrs(struct prev_params *params, void **param, | 761 | __preview_get_ptrs(struct prev_params *params, void **param, |
diff --git a/drivers/media/video/omap3isp/ispqueue.c b/drivers/media/video/omap3isp/ispqueue.c index 8fddc5806b0d..9c317148205f 100644 --- a/drivers/media/video/omap3isp/ispqueue.c +++ b/drivers/media/video/omap3isp/ispqueue.c | |||
@@ -339,7 +339,7 @@ static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf) | |||
339 | up_read(¤t->mm->mmap_sem); | 339 | up_read(¤t->mm->mmap_sem); |
340 | 340 | ||
341 | if (ret != buf->npages) { | 341 | if (ret != buf->npages) { |
342 | buf->npages = ret; | 342 | buf->npages = ret < 0 ? 0 : ret; |
343 | isp_video_buffer_cleanup(buf); | 343 | isp_video_buffer_cleanup(buf); |
344 | return -EFAULT; | 344 | return -EFAULT; |
345 | } | 345 | } |
@@ -408,8 +408,8 @@ done: | |||
408 | * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address | 408 | * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address |
409 | * | 409 | * |
410 | * This function locates the VMAs for the buffer's userspace address and checks | 410 | * This function locates the VMAs for the buffer's userspace address and checks |
411 | * that their flags match. The onlflag that we need to care for at the moment is | 411 | * that their flags match. The only flag that we need to care for at the moment |
412 | * VM_PFNMAP. | 412 | * is VM_PFNMAP. |
413 | * | 413 | * |
414 | * The buffer vm_flags field is set to the first VMA flags. | 414 | * The buffer vm_flags field is set to the first VMA flags. |
415 | * | 415 | * |
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c index 653f88ba56db..0bb0f8cd36f5 100644 --- a/drivers/media/video/omap3isp/ispresizer.c +++ b/drivers/media/video/omap3isp/ispresizer.c | |||
@@ -714,19 +714,50 @@ static void resizer_print_status(struct isp_res_device *res) | |||
714 | * iw and ih are the input width and height after cropping. Those equations need | 714 | * iw and ih are the input width and height after cropping. Those equations need |
715 | * to be satisfied exactly for the resizer to work correctly. | 715 | * to be satisfied exactly for the resizer to work correctly. |
716 | * | 716 | * |
717 | * Reverting the equations, we can compute the resizing ratios with | 717 | * The equations can't be easily reverted, as the >> 8 operation is not linear. |
718 | * In addition, not all input sizes can be achieved for a given output size. To | ||
719 | * get the highest input size lower than or equal to the requested input size, | ||
720 | * we need to compute the highest resizing ratio that satisfies the following | ||
721 | * inequality (taking the 4-tap mode width equation as an example) | ||
722 | * | ||
723 | * iw >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - 7 | ||
724 | * | ||
725 | * (where iw is the requested input width) which can be rewritten as | ||
726 | * | ||
727 | * iw - 7 >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 | ||
728 | * (iw - 7) << 8 >= 32 * sph + (ow - 1) * hrsz + 16 - b | ||
729 | * ((iw - 7) << 8) + b >= 32 * sph + (ow - 1) * hrsz + 16 | ||
730 | * | ||
731 | * where b is the value of the 8 least significant bits of the right hand side | ||
732 | * expression of the last inequality. The highest resizing ratio value will be | ||
733 | * achieved when b is equal to its maximum value of 255. That resizing ratio | ||
734 | * value will still satisfy the original inequality, as b will disappear when | ||
735 | * the expression will be shifted right by 8. | ||
736 | * | ||
737 | * The reverted the equations thus become | ||
718 | * | 738 | * |
719 | * - 8-phase, 4-tap mode | 739 | * - 8-phase, 4-tap mode |
720 | * hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1) | 740 | * hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1) |
721 | * vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1) | 741 | * vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1) |
722 | * - 4-phase, 7-tap mode | 742 | * - 4-phase, 7-tap mode |
723 | * hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1) | 743 | * hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1) |
724 | * vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 1) | 744 | * vrsz = ((ih - 7) * 256 + 255 - 32 - 64 * spv) / (oh - 1) |
725 | * | 745 | * |
726 | * The ratios are integer values, and must be rounded down to ensure that the | 746 | * The ratios are integer values, and are rounded down to ensure that the |
727 | * cropped input size is not bigger than the uncropped input size. As the ratio | 747 | * cropped input size is not bigger than the uncropped input size. |
728 | * in 7-tap mode is always smaller than the ratio in 4-tap mode, we can use the | 748 | * |
729 | * 7-tap mode equations to compute a ratio approximation. | 749 | * As the number of phases/taps, used to select the correct equations to compute |
750 | * the ratio, depends on the ratio, we start with the 4-tap mode equations to | ||
751 | * compute an approximation of the ratio, and switch to the 7-tap mode equations | ||
752 | * if the approximation is higher than the ratio threshold. | ||
753 | * | ||
754 | * As the 7-tap mode equations will return a ratio smaller than or equal to the | ||
755 | * 4-tap mode equations, the resulting ratio could become lower than or equal to | ||
756 | * the ratio threshold. This 'equations loop' isn't an issue as long as the | ||
757 | * correct equations are used to compute the final input size. Starting with the | ||
758 | * 4-tap mode equations ensure that, in case of values resulting in a 'ratio | ||
759 | * loop', the smallest of the ratio values will be used, never exceeding the | ||
760 | * requested input size. | ||
730 | * | 761 | * |
731 | * We first clamp the output size according to the hardware capabilitie to avoid | 762 | * We first clamp the output size according to the hardware capabilitie to avoid |
732 | * auto-cropping the input more than required to satisfy the TRM equations. The | 763 | * auto-cropping the input more than required to satisfy the TRM equations. The |
@@ -775,6 +806,8 @@ static void resizer_calc_ratios(struct isp_res_device *res, | |||
775 | unsigned int max_width; | 806 | unsigned int max_width; |
776 | unsigned int max_height; | 807 | unsigned int max_height; |
777 | unsigned int width_alignment; | 808 | unsigned int width_alignment; |
809 | unsigned int width; | ||
810 | unsigned int height; | ||
778 | 811 | ||
779 | /* | 812 | /* |
780 | * Clamp the output height based on the hardware capabilities and | 813 | * Clamp the output height based on the hardware capabilities and |
@@ -786,19 +819,22 @@ static void resizer_calc_ratios(struct isp_res_device *res, | |||
786 | max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT); | 819 | max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT); |
787 | output->height = clamp(output->height, min_height, max_height); | 820 | output->height = clamp(output->height, min_height, max_height); |
788 | 821 | ||
789 | ratio->vert = ((input->height - 7) * 256 - 32 - 64 * spv) | 822 | ratio->vert = ((input->height - 4) * 256 + 255 - 16 - 32 * spv) |
790 | / (output->height - 1); | 823 | / (output->height - 1); |
824 | if (ratio->vert > MID_RESIZE_VALUE) | ||
825 | ratio->vert = ((input->height - 7) * 256 + 255 - 32 - 64 * spv) | ||
826 | / (output->height - 1); | ||
791 | ratio->vert = clamp_t(unsigned int, ratio->vert, | 827 | ratio->vert = clamp_t(unsigned int, ratio->vert, |
792 | MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); | 828 | MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); |
793 | 829 | ||
794 | if (ratio->vert <= MID_RESIZE_VALUE) { | 830 | if (ratio->vert <= MID_RESIZE_VALUE) { |
795 | upscaled_height = (output->height - 1) * ratio->vert | 831 | upscaled_height = (output->height - 1) * ratio->vert |
796 | + 32 * spv + 16; | 832 | + 32 * spv + 16; |
797 | input->height = (upscaled_height >> 8) + 4; | 833 | height = (upscaled_height >> 8) + 4; |
798 | } else { | 834 | } else { |
799 | upscaled_height = (output->height - 1) * ratio->vert | 835 | upscaled_height = (output->height - 1) * ratio->vert |
800 | + 64 * spv + 32; | 836 | + 64 * spv + 32; |
801 | input->height = (upscaled_height >> 8) + 7; | 837 | height = (upscaled_height >> 8) + 7; |
802 | } | 838 | } |
803 | 839 | ||
804 | /* | 840 | /* |
@@ -854,20 +890,29 @@ static void resizer_calc_ratios(struct isp_res_device *res, | |||
854 | max_width & ~(width_alignment - 1)); | 890 | max_width & ~(width_alignment - 1)); |
855 | output->width = ALIGN(output->width, width_alignment); | 891 | output->width = ALIGN(output->width, width_alignment); |
856 | 892 | ||
857 | ratio->horz = ((input->width - 7) * 256 - 32 - 64 * sph) | 893 | ratio->horz = ((input->width - 7) * 256 + 255 - 16 - 32 * sph) |
858 | / (output->width - 1); | 894 | / (output->width - 1); |
895 | if (ratio->horz > MID_RESIZE_VALUE) | ||
896 | ratio->horz = ((input->width - 7) * 256 + 255 - 32 - 64 * sph) | ||
897 | / (output->width - 1); | ||
859 | ratio->horz = clamp_t(unsigned int, ratio->horz, | 898 | ratio->horz = clamp_t(unsigned int, ratio->horz, |
860 | MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); | 899 | MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); |
861 | 900 | ||
862 | if (ratio->horz <= MID_RESIZE_VALUE) { | 901 | if (ratio->horz <= MID_RESIZE_VALUE) { |
863 | upscaled_width = (output->width - 1) * ratio->horz | 902 | upscaled_width = (output->width - 1) * ratio->horz |
864 | + 32 * sph + 16; | 903 | + 32 * sph + 16; |
865 | input->width = (upscaled_width >> 8) + 7; | 904 | width = (upscaled_width >> 8) + 7; |
866 | } else { | 905 | } else { |
867 | upscaled_width = (output->width - 1) * ratio->horz | 906 | upscaled_width = (output->width - 1) * ratio->horz |
868 | + 64 * sph + 32; | 907 | + 64 * sph + 32; |
869 | input->width = (upscaled_width >> 8) + 7; | 908 | width = (upscaled_width >> 8) + 7; |
870 | } | 909 | } |
910 | |||
911 | /* Center the new crop rectangle. */ | ||
912 | input->left += (input->width - width) / 2; | ||
913 | input->top += (input->height - height) / 2; | ||
914 | input->width = width; | ||
915 | input->height = height; | ||
871 | } | 916 | } |
872 | 917 | ||
873 | /* | 918 | /* |
diff --git a/drivers/media/video/omap3isp/ispstat.h b/drivers/media/video/omap3isp/ispstat.h index 820950c9ef46..d86da94fa50d 100644 --- a/drivers/media/video/omap3isp/ispstat.h +++ b/drivers/media/video/omap3isp/ispstat.h | |||
@@ -131,9 +131,9 @@ struct ispstat { | |||
131 | struct ispstat_generic_config { | 131 | struct ispstat_generic_config { |
132 | /* | 132 | /* |
133 | * Fields must be in the same order as in: | 133 | * Fields must be in the same order as in: |
134 | * - isph3a_aewb_config | 134 | * - omap3isp_h3a_aewb_config |
135 | * - isph3a_af_config | 135 | * - omap3isp_h3a_af_config |
136 | * - isphist_config | 136 | * - omap3isp_hist_config |
137 | */ | 137 | */ |
138 | u32 buf_size; | 138 | u32 buf_size; |
139 | u16 config_counter; | 139 | u16 config_counter; |
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c index 208a7ec739d7..9cd8f1aa567b 100644 --- a/drivers/media/video/omap3isp/ispvideo.c +++ b/drivers/media/video/omap3isp/ispvideo.c | |||
@@ -47,29 +47,59 @@ | |||
47 | 47 | ||
48 | static struct isp_format_info formats[] = { | 48 | static struct isp_format_info formats[] = { |
49 | { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, | 49 | { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, |
50 | V4L2_MBUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, }, | 50 | V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, |
51 | V4L2_PIX_FMT_GREY, 8, }, | ||
52 | { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10, | ||
53 | V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8, | ||
54 | V4L2_PIX_FMT_Y10, 10, }, | ||
55 | { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10, | ||
56 | V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8, | ||
57 | V4L2_PIX_FMT_Y12, 12, }, | ||
58 | { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, | ||
59 | V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8, | ||
60 | V4L2_PIX_FMT_SBGGR8, 8, }, | ||
61 | { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, | ||
62 | V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8, | ||
63 | V4L2_PIX_FMT_SGBRG8, 8, }, | ||
64 | { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, | ||
65 | V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8, | ||
66 | V4L2_PIX_FMT_SGRBG8, 8, }, | ||
67 | { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, | ||
68 | V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8, | ||
69 | V4L2_PIX_FMT_SRGGB8, 8, }, | ||
51 | { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, | 70 | { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, |
52 | V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, | 71 | V4L2_MBUS_FMT_SGRBG10_1X10, 0, |
72 | V4L2_PIX_FMT_SGRBG10DPCM8, 8, }, | ||
53 | { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, | 73 | { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10, |
54 | V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 10, }, | 74 | V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8, |
75 | V4L2_PIX_FMT_SBGGR10, 10, }, | ||
55 | { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, | 76 | { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10, |
56 | V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 10, }, | 77 | V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8, |
78 | V4L2_PIX_FMT_SGBRG10, 10, }, | ||
57 | { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, | 79 | { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10, |
58 | V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 10, }, | 80 | V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8, |
81 | V4L2_PIX_FMT_SGRBG10, 10, }, | ||
59 | { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, | 82 | { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10, |
60 | V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 10, }, | 83 | V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8, |
84 | V4L2_PIX_FMT_SRGGB10, 10, }, | ||
61 | { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, | 85 | { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10, |
62 | V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 12, }, | 86 | V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8, |
87 | V4L2_PIX_FMT_SBGGR12, 12, }, | ||
63 | { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, | 88 | { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10, |
64 | V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 12, }, | 89 | V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8, |
90 | V4L2_PIX_FMT_SGBRG12, 12, }, | ||
65 | { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, | 91 | { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10, |
66 | V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 12, }, | 92 | V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8, |
93 | V4L2_PIX_FMT_SGRBG12, 12, }, | ||
67 | { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, | 94 | { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10, |
68 | V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 12, }, | 95 | V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8, |
96 | V4L2_PIX_FMT_SRGGB12, 12, }, | ||
69 | { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, | 97 | { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16, |
70 | V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 16, }, | 98 | V4L2_MBUS_FMT_UYVY8_1X16, 0, |
99 | V4L2_PIX_FMT_UYVY, 16, }, | ||
71 | { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, | 100 | { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16, |
72 | V4L2_MBUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 16, }, | 101 | V4L2_MBUS_FMT_YUYV8_1X16, 0, |
102 | V4L2_PIX_FMT_YUYV, 16, }, | ||
73 | }; | 103 | }; |
74 | 104 | ||
75 | const struct isp_format_info * | 105 | const struct isp_format_info * |
@@ -86,6 +116,37 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code) | |||
86 | } | 116 | } |
87 | 117 | ||
88 | /* | 118 | /* |
119 | * Decide whether desired output pixel code can be obtained with | ||
120 | * the lane shifter by shifting the input pixel code. | ||
121 | * @in: input pixelcode to shifter | ||
122 | * @out: output pixelcode from shifter | ||
123 | * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0] | ||
124 | * | ||
125 | * return true if the combination is possible | ||
126 | * return false otherwise | ||
127 | */ | ||
128 | static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in, | ||
129 | enum v4l2_mbus_pixelcode out, | ||
130 | unsigned int additional_shift) | ||
131 | { | ||
132 | const struct isp_format_info *in_info, *out_info; | ||
133 | |||
134 | if (in == out) | ||
135 | return true; | ||
136 | |||
137 | in_info = omap3isp_video_format_info(in); | ||
138 | out_info = omap3isp_video_format_info(out); | ||
139 | |||
140 | if ((in_info->flavor == 0) || (out_info->flavor == 0)) | ||
141 | return false; | ||
142 | |||
143 | if (in_info->flavor != out_info->flavor) | ||
144 | return false; | ||
145 | |||
146 | return in_info->bpp - out_info->bpp + additional_shift <= 6; | ||
147 | } | ||
148 | |||
149 | /* | ||
89 | * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format | 150 | * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format |
90 | * @video: ISP video instance | 151 | * @video: ISP video instance |
91 | * @mbus: v4l2_mbus_framefmt format (input) | 152 | * @mbus: v4l2_mbus_framefmt format (input) |
@@ -235,6 +296,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) | |||
235 | return -EPIPE; | 296 | return -EPIPE; |
236 | 297 | ||
237 | while (1) { | 298 | while (1) { |
299 | unsigned int shifter_link; | ||
238 | /* Retrieve the sink format */ | 300 | /* Retrieve the sink format */ |
239 | pad = &subdev->entity.pads[0]; | 301 | pad = &subdev->entity.pads[0]; |
240 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) | 302 | if (!(pad->flags & MEDIA_PAD_FL_SINK)) |
@@ -263,6 +325,10 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) | |||
263 | return -ENOSPC; | 325 | return -ENOSPC; |
264 | } | 326 | } |
265 | 327 | ||
328 | /* If sink pad is on CCDC, the link has the lane shifter | ||
329 | * in the middle of it. */ | ||
330 | shifter_link = subdev == &isp->isp_ccdc.subdev; | ||
331 | |||
266 | /* Retrieve the source format */ | 332 | /* Retrieve the source format */ |
267 | pad = media_entity_remote_source(pad); | 333 | pad = media_entity_remote_source(pad); |
268 | if (pad == NULL || | 334 | if (pad == NULL || |
@@ -278,10 +344,24 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) | |||
278 | return -EPIPE; | 344 | return -EPIPE; |
279 | 345 | ||
280 | /* Check if the two ends match */ | 346 | /* Check if the two ends match */ |
281 | if (fmt_source.format.code != fmt_sink.format.code || | 347 | if (fmt_source.format.width != fmt_sink.format.width || |
282 | fmt_source.format.width != fmt_sink.format.width || | ||
283 | fmt_source.format.height != fmt_sink.format.height) | 348 | fmt_source.format.height != fmt_sink.format.height) |
284 | return -EPIPE; | 349 | return -EPIPE; |
350 | |||
351 | if (shifter_link) { | ||
352 | unsigned int parallel_shift = 0; | ||
353 | if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) { | ||
354 | struct isp_parallel_platform_data *pdata = | ||
355 | &((struct isp_v4l2_subdevs_group *) | ||
356 | subdev->host_priv)->bus.parallel; | ||
357 | parallel_shift = pdata->data_lane_shift * 2; | ||
358 | } | ||
359 | if (!isp_video_is_shiftable(fmt_source.format.code, | ||
360 | fmt_sink.format.code, | ||
361 | parallel_shift)) | ||
362 | return -EPIPE; | ||
363 | } else if (fmt_source.format.code != fmt_sink.format.code) | ||
364 | return -EPIPE; | ||
285 | } | 365 | } |
286 | 366 | ||
287 | return 0; | 367 | return 0; |
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h index 524a1acd0906..911bea64e78a 100644 --- a/drivers/media/video/omap3isp/ispvideo.h +++ b/drivers/media/video/omap3isp/ispvideo.h | |||
@@ -49,6 +49,8 @@ struct v4l2_pix_format; | |||
49 | * bits. Identical to @code if the format is 10 bits wide or less. | 49 | * bits. Identical to @code if the format is 10 bits wide or less. |
50 | * @uncompressed: V4L2 media bus format code for the corresponding uncompressed | 50 | * @uncompressed: V4L2 media bus format code for the corresponding uncompressed |
51 | * format. Identical to @code if the format is not DPCM compressed. | 51 | * format. Identical to @code if the format is not DPCM compressed. |
52 | * @flavor: V4L2 media bus format code for the same pixel layout but | ||
53 | * shifted to be 8 bits per pixel. =0 if format is not shiftable. | ||
52 | * @pixelformat: V4L2 pixel format FCC identifier | 54 | * @pixelformat: V4L2 pixel format FCC identifier |
53 | * @bpp: Bits per pixel | 55 | * @bpp: Bits per pixel |
54 | */ | 56 | */ |
@@ -56,6 +58,7 @@ struct isp_format_info { | |||
56 | enum v4l2_mbus_pixelcode code; | 58 | enum v4l2_mbus_pixelcode code; |
57 | enum v4l2_mbus_pixelcode truncated; | 59 | enum v4l2_mbus_pixelcode truncated; |
58 | enum v4l2_mbus_pixelcode uncompressed; | 60 | enum v4l2_mbus_pixelcode uncompressed; |
61 | enum v4l2_mbus_pixelcode flavor; | ||
59 | u32 pixelformat; | 62 | u32 pixelformat; |
60 | unsigned int bpp; | 63 | unsigned int bpp; |
61 | }; | 64 | }; |
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 95f8b4e11e46..d142b40ea64e 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -527,7 +527,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, | |||
527 | if (ret) | 527 | if (ret) |
528 | return ret; | 528 | return ret; |
529 | 529 | ||
530 | if (vb2_is_streaming(&fimc->vid_cap.vbq) || fimc_capture_active(fimc)) | 530 | if (vb2_is_busy(&fimc->vid_cap.vbq) || fimc_capture_active(fimc)) |
531 | return -EBUSY; | 531 | return -EBUSY; |
532 | 532 | ||
533 | frame = &ctx->d_frame; | 533 | frame = &ctx->d_frame; |
@@ -539,8 +539,10 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, | |||
539 | return -EINVAL; | 539 | return -EINVAL; |
540 | } | 540 | } |
541 | 541 | ||
542 | for (i = 0; i < frame->fmt->colplanes; i++) | 542 | for (i = 0; i < frame->fmt->colplanes; i++) { |
543 | frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; | 543 | frame->payload[i] = |
544 | (pix->width * pix->height * frame->fmt->depth[i]) >> 3; | ||
545 | } | ||
544 | 546 | ||
545 | /* Output DMA frame pixel size and offsets. */ | 547 | /* Output DMA frame pixel size and offsets. */ |
546 | frame->f_width = pix->plane_fmt[0].bytesperline * 8 | 548 | frame->f_width = pix->plane_fmt[0].bytesperline * 8 |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 6c919b38a3d8..dc91a8511af6 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -361,10 +361,20 @@ static void fimc_capture_irq_handler(struct fimc_dev *fimc) | |||
361 | { | 361 | { |
362 | struct fimc_vid_cap *cap = &fimc->vid_cap; | 362 | struct fimc_vid_cap *cap = &fimc->vid_cap; |
363 | struct fimc_vid_buffer *v_buf; | 363 | struct fimc_vid_buffer *v_buf; |
364 | struct timeval *tv; | ||
365 | struct timespec ts; | ||
364 | 366 | ||
365 | if (!list_empty(&cap->active_buf_q) && | 367 | if (!list_empty(&cap->active_buf_q) && |
366 | test_bit(ST_CAPT_RUN, &fimc->state)) { | 368 | test_bit(ST_CAPT_RUN, &fimc->state)) { |
369 | ktime_get_real_ts(&ts); | ||
370 | |||
367 | v_buf = active_queue_pop(cap); | 371 | v_buf = active_queue_pop(cap); |
372 | |||
373 | tv = &v_buf->vb.v4l2_buf.timestamp; | ||
374 | tv->tv_sec = ts.tv_sec; | ||
375 | tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC; | ||
376 | v_buf->vb.v4l2_buf.sequence = cap->frame_count++; | ||
377 | |||
368 | vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE); | 378 | vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE); |
369 | } | 379 | } |
370 | 380 | ||
@@ -758,7 +768,7 @@ static void fimc_unlock(struct vb2_queue *vq) | |||
758 | mutex_unlock(&ctx->fimc_dev->lock); | 768 | mutex_unlock(&ctx->fimc_dev->lock); |
759 | } | 769 | } |
760 | 770 | ||
761 | struct vb2_ops fimc_qops = { | 771 | static struct vb2_ops fimc_qops = { |
762 | .queue_setup = fimc_queue_setup, | 772 | .queue_setup = fimc_queue_setup, |
763 | .buf_prepare = fimc_buf_prepare, | 773 | .buf_prepare = fimc_buf_prepare, |
764 | .buf_queue = fimc_buf_queue, | 774 | .buf_queue = fimc_buf_queue, |
@@ -927,23 +937,23 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv, | |||
927 | pix->num_planes = fmt->memplanes; | 937 | pix->num_planes = fmt->memplanes; |
928 | pix->colorspace = V4L2_COLORSPACE_JPEG; | 938 | pix->colorspace = V4L2_COLORSPACE_JPEG; |
929 | 939 | ||
930 | for (i = 0; i < pix->num_planes; ++i) { | ||
931 | int bpl = pix->plane_fmt[i].bytesperline; | ||
932 | 940 | ||
933 | dbg("[%d] bpl: %d, depth: %d, w: %d, h: %d", | 941 | for (i = 0; i < pix->num_planes; ++i) { |
934 | i, bpl, fmt->depth[i], pix->width, pix->height); | 942 | u32 bpl = pix->plane_fmt[i].bytesperline; |
943 | u32 *sizeimage = &pix->plane_fmt[i].sizeimage; | ||
935 | 944 | ||
936 | if (!bpl || (bpl * 8 / fmt->depth[i]) > pix->width) | 945 | if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width)) |
937 | bpl = (pix->width * fmt->depth[0]) >> 3; | 946 | bpl = pix->width; /* Planar */ |
938 | 947 | ||
939 | if (!pix->plane_fmt[i].sizeimage) | 948 | if (fmt->colplanes == 1 && /* Packed */ |
940 | pix->plane_fmt[i].sizeimage = pix->height * bpl; | 949 | (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width)) |
950 | bpl = (pix->width * fmt->depth[0]) / 8; | ||
941 | 951 | ||
942 | pix->plane_fmt[i].bytesperline = bpl; | 952 | if (i == 0) /* Same bytesperline for each plane. */ |
953 | mod_x = bpl; | ||
943 | 954 | ||
944 | dbg("[%d]: bpl: %d, sizeimage: %d", | 955 | pix->plane_fmt[i].bytesperline = mod_x; |
945 | i, pix->plane_fmt[i].bytesperline, | 956 | *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8; |
946 | pix->plane_fmt[i].sizeimage); | ||
947 | } | 957 | } |
948 | 958 | ||
949 | return 0; | 959 | return 0; |
@@ -965,7 +975,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, | |||
965 | 975 | ||
966 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); | 976 | vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); |
967 | 977 | ||
968 | if (vb2_is_streaming(vq)) { | 978 | if (vb2_is_busy(vq)) { |
969 | v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type); | 979 | v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type); |
970 | return -EBUSY; | 980 | return -EBUSY; |
971 | } | 981 | } |
@@ -985,8 +995,10 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, | |||
985 | if (!frame->fmt) | 995 | if (!frame->fmt) |
986 | return -EINVAL; | 996 | return -EINVAL; |
987 | 997 | ||
988 | for (i = 0; i < frame->fmt->colplanes; i++) | 998 | for (i = 0; i < frame->fmt->colplanes; i++) { |
989 | frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; | 999 | frame->payload[i] = |
1000 | (pix->width * pix->height * frame->fmt->depth[i]) / 8; | ||
1001 | } | ||
990 | 1002 | ||
991 | frame->f_width = pix->plane_fmt[0].bytesperline * 8 / | 1003 | frame->f_width = pix->plane_fmt[0].bytesperline * 8 / |
992 | frame->fmt->depth[0]; | 1004 | frame->fmt->depth[0]; |
@@ -1750,7 +1762,7 @@ static int __devexit fimc_remove(struct platform_device *pdev) | |||
1750 | } | 1762 | } |
1751 | 1763 | ||
1752 | /* Image pixel limits, similar across several FIMC HW revisions. */ | 1764 | /* Image pixel limits, similar across several FIMC HW revisions. */ |
1753 | static struct fimc_pix_limit s5p_pix_limit[3] = { | 1765 | static struct fimc_pix_limit s5p_pix_limit[4] = { |
1754 | [0] = { | 1766 | [0] = { |
1755 | .scaler_en_w = 3264, | 1767 | .scaler_en_w = 3264, |
1756 | .scaler_dis_w = 8192, | 1768 | .scaler_dis_w = 8192, |
@@ -1775,6 +1787,14 @@ static struct fimc_pix_limit s5p_pix_limit[3] = { | |||
1775 | .out_rot_en_w = 1280, | 1787 | .out_rot_en_w = 1280, |
1776 | .out_rot_dis_w = 1920, | 1788 | .out_rot_dis_w = 1920, |
1777 | }, | 1789 | }, |
1790 | [3] = { | ||
1791 | .scaler_en_w = 1920, | ||
1792 | .scaler_dis_w = 8192, | ||
1793 | .in_rot_en_h = 1366, | ||
1794 | .in_rot_dis_w = 8192, | ||
1795 | .out_rot_en_w = 1366, | ||
1796 | .out_rot_dis_w = 1920, | ||
1797 | }, | ||
1778 | }; | 1798 | }; |
1779 | 1799 | ||
1780 | static struct samsung_fimc_variant fimc0_variant_s5p = { | 1800 | static struct samsung_fimc_variant fimc0_variant_s5p = { |
@@ -1827,7 +1847,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = { | |||
1827 | .pix_limit = &s5p_pix_limit[2], | 1847 | .pix_limit = &s5p_pix_limit[2], |
1828 | }; | 1848 | }; |
1829 | 1849 | ||
1830 | static struct samsung_fimc_variant fimc0_variant_s5pv310 = { | 1850 | static struct samsung_fimc_variant fimc0_variant_exynos4 = { |
1831 | .pix_hoff = 1, | 1851 | .pix_hoff = 1, |
1832 | .has_inp_rot = 1, | 1852 | .has_inp_rot = 1, |
1833 | .has_out_rot = 1, | 1853 | .has_out_rot = 1, |
@@ -1840,7 +1860,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { | |||
1840 | .pix_limit = &s5p_pix_limit[1], | 1860 | .pix_limit = &s5p_pix_limit[1], |
1841 | }; | 1861 | }; |
1842 | 1862 | ||
1843 | static struct samsung_fimc_variant fimc2_variant_s5pv310 = { | 1863 | static struct samsung_fimc_variant fimc2_variant_exynos4 = { |
1844 | .pix_hoff = 1, | 1864 | .pix_hoff = 1, |
1845 | .has_cistatus2 = 1, | 1865 | .has_cistatus2 = 1, |
1846 | .has_mainscaler_ext = 1, | 1866 | .has_mainscaler_ext = 1, |
@@ -1848,7 +1868,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv310 = { | |||
1848 | .min_out_pixsize = 16, | 1868 | .min_out_pixsize = 16, |
1849 | .hor_offs_align = 1, | 1869 | .hor_offs_align = 1, |
1850 | .out_buf_count = 32, | 1870 | .out_buf_count = 32, |
1851 | .pix_limit = &s5p_pix_limit[2], | 1871 | .pix_limit = &s5p_pix_limit[3], |
1852 | }; | 1872 | }; |
1853 | 1873 | ||
1854 | /* S5PC100 */ | 1874 | /* S5PC100 */ |
@@ -1874,12 +1894,12 @@ static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = { | |||
1874 | }; | 1894 | }; |
1875 | 1895 | ||
1876 | /* S5PV310, S5PC210 */ | 1896 | /* S5PV310, S5PC210 */ |
1877 | static struct samsung_fimc_driverdata fimc_drvdata_s5pv310 = { | 1897 | static struct samsung_fimc_driverdata fimc_drvdata_exynos4 = { |
1878 | .variant = { | 1898 | .variant = { |
1879 | [0] = &fimc0_variant_s5pv310, | 1899 | [0] = &fimc0_variant_exynos4, |
1880 | [1] = &fimc0_variant_s5pv310, | 1900 | [1] = &fimc0_variant_exynos4, |
1881 | [2] = &fimc0_variant_s5pv310, | 1901 | [2] = &fimc0_variant_exynos4, |
1882 | [3] = &fimc2_variant_s5pv310, | 1902 | [3] = &fimc2_variant_exynos4, |
1883 | }, | 1903 | }, |
1884 | .num_entities = 4, | 1904 | .num_entities = 4, |
1885 | .lclk_frequency = 166000000UL, | 1905 | .lclk_frequency = 166000000UL, |
@@ -1893,8 +1913,8 @@ static struct platform_device_id fimc_driver_ids[] = { | |||
1893 | .name = "s5pv210-fimc", | 1913 | .name = "s5pv210-fimc", |
1894 | .driver_data = (unsigned long)&fimc_drvdata_s5pv210, | 1914 | .driver_data = (unsigned long)&fimc_drvdata_s5pv210, |
1895 | }, { | 1915 | }, { |
1896 | .name = "s5pv310-fimc", | 1916 | .name = "exynos4-fimc", |
1897 | .driver_data = (unsigned long)&fimc_drvdata_s5pv310, | 1917 | .driver_data = (unsigned long)&fimc_drvdata_exynos4, |
1898 | }, | 1918 | }, |
1899 | {}, | 1919 | {}, |
1900 | }; | 1920 | }; |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 3fe54bf41142..134e86bf6d97 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -922,7 +922,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int | |||
922 | /* Try 2560x1920, 1280x960, 640x480, 320x240 */ | 922 | /* Try 2560x1920, 1280x960, 640x480, 320x240 */ |
923 | mf.width = 2560 >> shift; | 923 | mf.width = 2560 >> shift; |
924 | mf.height = 1920 >> shift; | 924 | mf.height = 1920 >> shift; |
925 | ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, | 925 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, |
926 | s_mbus_fmt, &mf); | 926 | s_mbus_fmt, &mf); |
927 | if (ret < 0) | 927 | if (ret < 0) |
928 | return ret; | 928 | return ret; |
@@ -1224,7 +1224,7 @@ static int client_s_fmt(struct soc_camera_device *icd, | |||
1224 | struct v4l2_cropcap cap; | 1224 | struct v4l2_cropcap cap; |
1225 | int ret; | 1225 | int ret; |
1226 | 1226 | ||
1227 | ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, | 1227 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, |
1228 | s_mbus_fmt, mf); | 1228 | s_mbus_fmt, mf); |
1229 | if (ret < 0) | 1229 | if (ret < 0) |
1230 | return ret; | 1230 | return ret; |
@@ -1254,7 +1254,7 @@ static int client_s_fmt(struct soc_camera_device *icd, | |||
1254 | tmp_h = min(2 * tmp_h, max_height); | 1254 | tmp_h = min(2 * tmp_h, max_height); |
1255 | mf->width = tmp_w; | 1255 | mf->width = tmp_w; |
1256 | mf->height = tmp_h; | 1256 | mf->height = tmp_h; |
1257 | ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, | 1257 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, |
1258 | s_mbus_fmt, mf); | 1258 | s_mbus_fmt, mf); |
1259 | dev_geo(dev, "Camera scaled to %ux%u\n", | 1259 | dev_geo(dev, "Camera scaled to %ux%u\n", |
1260 | mf->width, mf->height); | 1260 | mf->width, mf->height); |
@@ -1658,7 +1658,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
1658 | mf.code = xlate->code; | 1658 | mf.code = xlate->code; |
1659 | mf.colorspace = pix->colorspace; | 1659 | mf.colorspace = pix->colorspace; |
1660 | 1660 | ||
1661 | ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, try_mbus_fmt, &mf); | 1661 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, try_mbus_fmt, &mf); |
1662 | if (ret < 0) | 1662 | if (ret < 0) |
1663 | return ret; | 1663 | return ret; |
1664 | 1664 | ||
@@ -1682,7 +1682,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, | |||
1682 | */ | 1682 | */ |
1683 | mf.width = 2560; | 1683 | mf.width = 2560; |
1684 | mf.height = 1920; | 1684 | mf.height = 1920; |
1685 | ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, | 1685 | ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, |
1686 | try_mbus_fmt, &mf); | 1686 | try_mbus_fmt, &mf); |
1687 | if (ret < 0) { | 1687 | if (ret < 0) { |
1688 | /* Shouldn't actually happen... */ | 1688 | /* Shouldn't actually happen... */ |
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c index dd1b81b1442b..98b87481fa94 100644 --- a/drivers/media/video/sh_mobile_csi2.c +++ b/drivers/media/video/sh_mobile_csi2.c | |||
@@ -38,6 +38,8 @@ struct sh_csi2 { | |||
38 | void __iomem *base; | 38 | void __iomem *base; |
39 | struct platform_device *pdev; | 39 | struct platform_device *pdev; |
40 | struct sh_csi2_client_config *client; | 40 | struct sh_csi2_client_config *client; |
41 | unsigned long (*query_bus_param)(struct soc_camera_device *); | ||
42 | int (*set_bus_param)(struct soc_camera_device *, unsigned long); | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | static int sh_csi2_try_fmt(struct v4l2_subdev *sd, | 45 | static int sh_csi2_try_fmt(struct v4l2_subdev *sd, |
@@ -208,6 +210,7 @@ static int sh_csi2_notify(struct notifier_block *nb, | |||
208 | case BUS_NOTIFY_BOUND_DRIVER: | 210 | case BUS_NOTIFY_BOUND_DRIVER: |
209 | snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s%s", | 211 | snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s%s", |
210 | dev_name(v4l2_dev->dev), ".mipi-csi"); | 212 | dev_name(v4l2_dev->dev), ".mipi-csi"); |
213 | priv->subdev.grp_id = (long)icd; | ||
211 | ret = v4l2_device_register_subdev(v4l2_dev, &priv->subdev); | 214 | ret = v4l2_device_register_subdev(v4l2_dev, &priv->subdev); |
212 | dev_dbg(dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret); | 215 | dev_dbg(dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret); |
213 | if (ret < 0) | 216 | if (ret < 0) |
@@ -215,6 +218,8 @@ static int sh_csi2_notify(struct notifier_block *nb, | |||
215 | 218 | ||
216 | priv->client = pdata->clients + i; | 219 | priv->client = pdata->clients + i; |
217 | 220 | ||
221 | priv->set_bus_param = icd->ops->set_bus_param; | ||
222 | priv->query_bus_param = icd->ops->query_bus_param; | ||
218 | icd->ops->set_bus_param = sh_csi2_set_bus_param; | 223 | icd->ops->set_bus_param = sh_csi2_set_bus_param; |
219 | icd->ops->query_bus_param = sh_csi2_query_bus_param; | 224 | icd->ops->query_bus_param = sh_csi2_query_bus_param; |
220 | 225 | ||
@@ -226,8 +231,10 @@ static int sh_csi2_notify(struct notifier_block *nb, | |||
226 | priv->client = NULL; | 231 | priv->client = NULL; |
227 | 232 | ||
228 | /* Driver is about to be unbound */ | 233 | /* Driver is about to be unbound */ |
229 | icd->ops->set_bus_param = NULL; | 234 | icd->ops->set_bus_param = priv->set_bus_param; |
230 | icd->ops->query_bus_param = NULL; | 235 | icd->ops->query_bus_param = priv->query_bus_param; |
236 | priv->set_bus_param = NULL; | ||
237 | priv->query_bus_param = NULL; | ||
231 | 238 | ||
232 | v4l2_device_unregister_subdev(&priv->subdev); | 239 | v4l2_device_unregister_subdev(&priv->subdev); |
233 | 240 | ||
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 46284489e4eb..3973f9a94753 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -996,10 +996,11 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd) | |||
996 | { | 996 | { |
997 | struct i2c_client *client = | 997 | struct i2c_client *client = |
998 | to_i2c_client(to_soc_camera_control(icd)); | 998 | to_i2c_client(to_soc_camera_control(icd)); |
999 | struct i2c_adapter *adap = client->adapter; | ||
999 | dev_set_drvdata(&icd->dev, NULL); | 1000 | dev_set_drvdata(&icd->dev, NULL); |
1000 | v4l2_device_unregister_subdev(i2c_get_clientdata(client)); | 1001 | v4l2_device_unregister_subdev(i2c_get_clientdata(client)); |
1001 | i2c_unregister_device(client); | 1002 | i2c_unregister_device(client); |
1002 | i2c_put_adapter(client->adapter); | 1003 | i2c_put_adapter(adap); |
1003 | } | 1004 | } |
1004 | #else | 1005 | #else |
1005 | #define soc_camera_init_i2c(icd, icl) (-ENODEV) | 1006 | #define soc_camera_init_i2c(icd, icl) (-ENODEV) |
@@ -1071,6 +1072,9 @@ static int soc_camera_probe(struct device *dev) | |||
1071 | } | 1072 | } |
1072 | } | 1073 | } |
1073 | 1074 | ||
1075 | sd = soc_camera_to_subdev(icd); | ||
1076 | sd->grp_id = (long)icd; | ||
1077 | |||
1074 | /* At this point client .probe() should have run already */ | 1078 | /* At this point client .probe() should have run already */ |
1075 | ret = soc_camera_init_user_formats(icd); | 1079 | ret = soc_camera_init_user_formats(icd); |
1076 | if (ret < 0) | 1080 | if (ret < 0) |
@@ -1092,7 +1096,6 @@ static int soc_camera_probe(struct device *dev) | |||
1092 | goto evidstart; | 1096 | goto evidstart; |
1093 | 1097 | ||
1094 | /* Try to improve our guess of a reasonable window format */ | 1098 | /* Try to improve our guess of a reasonable window format */ |
1095 | sd = soc_camera_to_subdev(icd); | ||
1096 | if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { | 1099 | if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { |
1097 | icd->user_width = mf.width; | 1100 | icd->user_width = mf.width; |
1098 | icd->user_height = mf.height; | 1101 | icd->user_height = mf.height; |
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c index 5d4cf3b3d435..22fa8202d5ca 100644 --- a/drivers/media/video/tda9840.c +++ b/drivers/media/video/tda9840.c | |||
@@ -171,7 +171,7 @@ static int tda9840_probe(struct i2c_client *client, | |||
171 | v4l_info(client, "chip found @ 0x%x (%s)\n", | 171 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
172 | client->addr << 1, client->adapter->name); | 172 | client->addr << 1, client->adapter->name); |
173 | 173 | ||
174 | sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | 174 | sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); |
175 | if (sd == NULL) | 175 | if (sd == NULL) |
176 | return -ENOMEM; | 176 | return -ENOMEM; |
177 | v4l2_i2c_subdev_init(sd, client, &tda9840_ops); | 177 | v4l2_i2c_subdev_init(sd, client, &tda9840_ops); |
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c index 19621ed523ec..827425c5b866 100644 --- a/drivers/media/video/tea6415c.c +++ b/drivers/media/video/tea6415c.c | |||
@@ -152,7 +152,7 @@ static int tea6415c_probe(struct i2c_client *client, | |||
152 | 152 | ||
153 | v4l_info(client, "chip found @ 0x%x (%s)\n", | 153 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
154 | client->addr << 1, client->adapter->name); | 154 | client->addr << 1, client->adapter->name); |
155 | sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | 155 | sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); |
156 | if (sd == NULL) | 156 | if (sd == NULL) |
157 | return -ENOMEM; | 157 | return -ENOMEM; |
158 | v4l2_i2c_subdev_init(sd, client, &tea6415c_ops); | 158 | v4l2_i2c_subdev_init(sd, client, &tea6415c_ops); |
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c index 5ea840401f21..f350b6c24500 100644 --- a/drivers/media/video/tea6420.c +++ b/drivers/media/video/tea6420.c | |||
@@ -125,7 +125,7 @@ static int tea6420_probe(struct i2c_client *client, | |||
125 | v4l_info(client, "chip found @ 0x%x (%s)\n", | 125 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
126 | client->addr << 1, client->adapter->name); | 126 | client->addr << 1, client->adapter->name); |
127 | 127 | ||
128 | sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); | 128 | sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); |
129 | if (sd == NULL) | 129 | if (sd == NULL) |
130 | return -ENOMEM; | 130 | return -ENOMEM; |
131 | v4l2_i2c_subdev_init(sd, client, &tea6420_ops); | 131 | v4l2_i2c_subdev_init(sd, client, &tea6420_ops); |
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c index f8138c75be8b..1aab96a88203 100644 --- a/drivers/media/video/upd64031a.c +++ b/drivers/media/video/upd64031a.c | |||
@@ -230,7 +230,7 @@ static int upd64031a_probe(struct i2c_client *client, | |||
230 | v4l_info(client, "chip found @ 0x%x (%s)\n", | 230 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
231 | client->addr << 1, client->adapter->name); | 231 | client->addr << 1, client->adapter->name); |
232 | 232 | ||
233 | state = kmalloc(sizeof(struct upd64031a_state), GFP_KERNEL); | 233 | state = kzalloc(sizeof(struct upd64031a_state), GFP_KERNEL); |
234 | if (state == NULL) | 234 | if (state == NULL) |
235 | return -ENOMEM; | 235 | return -ENOMEM; |
236 | sd = &state->sd; | 236 | sd = &state->sd; |
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c index 28e0e6b6ca84..9bbe61700fd5 100644 --- a/drivers/media/video/upd64083.c +++ b/drivers/media/video/upd64083.c | |||
@@ -202,7 +202,7 @@ static int upd64083_probe(struct i2c_client *client, | |||
202 | v4l_info(client, "chip found @ 0x%x (%s)\n", | 202 | v4l_info(client, "chip found @ 0x%x (%s)\n", |
203 | client->addr << 1, client->adapter->name); | 203 | client->addr << 1, client->adapter->name); |
204 | 204 | ||
205 | state = kmalloc(sizeof(struct upd64083_state), GFP_KERNEL); | 205 | state = kzalloc(sizeof(struct upd64083_state), GFP_KERNEL); |
206 | if (state == NULL) | 206 | if (state == NULL) |
207 | return -ENOMEM; | 207 | return -ENOMEM; |
208 | sd = &state->sd; | 208 | sd = &state->sd; |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 498e6742579e..6dc7196296b3 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -389,7 +389,8 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
389 | video_get(vdev); | 389 | video_get(vdev); |
390 | mutex_unlock(&videodev_lock); | 390 | mutex_unlock(&videodev_lock); |
391 | #if defined(CONFIG_MEDIA_CONTROLLER) | 391 | #if defined(CONFIG_MEDIA_CONTROLLER) |
392 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) { | 392 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && |
393 | vdev->vfl_type != VFL_TYPE_SUBDEV) { | ||
393 | entity = media_entity_get(&vdev->entity); | 394 | entity = media_entity_get(&vdev->entity); |
394 | if (!entity) { | 395 | if (!entity) { |
395 | ret = -EBUSY; | 396 | ret = -EBUSY; |
@@ -415,7 +416,8 @@ err: | |||
415 | /* decrease the refcount in case of an error */ | 416 | /* decrease the refcount in case of an error */ |
416 | if (ret) { | 417 | if (ret) { |
417 | #if defined(CONFIG_MEDIA_CONTROLLER) | 418 | #if defined(CONFIG_MEDIA_CONTROLLER) |
418 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) | 419 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && |
420 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
419 | media_entity_put(entity); | 421 | media_entity_put(entity); |
420 | #endif | 422 | #endif |
421 | video_put(vdev); | 423 | video_put(vdev); |
@@ -437,7 +439,8 @@ static int v4l2_release(struct inode *inode, struct file *filp) | |||
437 | mutex_unlock(vdev->lock); | 439 | mutex_unlock(vdev->lock); |
438 | } | 440 | } |
439 | #if defined(CONFIG_MEDIA_CONTROLLER) | 441 | #if defined(CONFIG_MEDIA_CONTROLLER) |
440 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) | 442 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && |
443 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
441 | media_entity_put(&vdev->entity); | 444 | media_entity_put(&vdev->entity); |
442 | #endif | 445 | #endif |
443 | /* decrease the refcount unconditionally since the release() | 446 | /* decrease the refcount unconditionally since the release() |
@@ -686,7 +689,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr, | |||
686 | 689 | ||
687 | #if defined(CONFIG_MEDIA_CONTROLLER) | 690 | #if defined(CONFIG_MEDIA_CONTROLLER) |
688 | /* Part 5: Register the entity. */ | 691 | /* Part 5: Register the entity. */ |
689 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) { | 692 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && |
693 | vdev->vfl_type != VFL_TYPE_SUBDEV) { | ||
690 | vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; | 694 | vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; |
691 | vdev->entity.name = vdev->name; | 695 | vdev->entity.name = vdev->name; |
692 | vdev->entity.v4l.major = VIDEO_MAJOR; | 696 | vdev->entity.v4l.major = VIDEO_MAJOR; |
@@ -733,7 +737,8 @@ void video_unregister_device(struct video_device *vdev) | |||
733 | return; | 737 | return; |
734 | 738 | ||
735 | #if defined(CONFIG_MEDIA_CONTROLLER) | 739 | #if defined(CONFIG_MEDIA_CONTROLLER) |
736 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) | 740 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && |
741 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
737 | media_device_unregister_entity(&vdev->entity); | 742 | media_device_unregister_entity(&vdev->entity); |
738 | #endif | 743 | #endif |
739 | 744 | ||
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index c4742fc15529..c9691115f2d2 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -300,7 +300,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q, | |||
300 | 300 | ||
301 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 301 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
302 | retval = remap_pfn_range(vma, vma->vm_start, | 302 | retval = remap_pfn_range(vma, vma->vm_start, |
303 | PFN_DOWN(virt_to_phys(mem->vaddr)), | 303 | mem->dma_handle >> PAGE_SHIFT, |
304 | size, vma->vm_page_prot); | 304 | size, vma->vm_page_prot); |
305 | if (retval) { | 305 | if (retval) { |
306 | dev_err(q->dev, "mmap: remap failed with error %d. ", retval); | 306 | dev_err(q->dev, "mmap: remap failed with error %d. ", retval); |
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 6698c77e0f64..6ba1461d51ef 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c | |||
@@ -37,6 +37,9 @@ module_param(debug, int, 0644); | |||
37 | #define call_qop(q, op, args...) \ | 37 | #define call_qop(q, op, args...) \ |
38 | (((q)->ops->op) ? ((q)->ops->op(args)) : 0) | 38 | (((q)->ops->op) ? ((q)->ops->op(args)) : 0) |
39 | 39 | ||
40 | #define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ | ||
41 | V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR) | ||
42 | |||
40 | /** | 43 | /** |
41 | * __vb2_buf_mem_alloc() - allocate video memory for the given buffer | 44 | * __vb2_buf_mem_alloc() - allocate video memory for the given buffer |
42 | */ | 45 | */ |
@@ -51,7 +54,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb, | |||
51 | for (plane = 0; plane < vb->num_planes; ++plane) { | 54 | for (plane = 0; plane < vb->num_planes; ++plane) { |
52 | mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane], | 55 | mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane], |
53 | plane_sizes[plane]); | 56 | plane_sizes[plane]); |
54 | if (!mem_priv) | 57 | if (IS_ERR_OR_NULL(mem_priv)) |
55 | goto free; | 58 | goto free; |
56 | 59 | ||
57 | /* Associate allocator private data with this plane */ | 60 | /* Associate allocator private data with this plane */ |
@@ -284,7 +287,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) | |||
284 | struct vb2_queue *q = vb->vb2_queue; | 287 | struct vb2_queue *q = vb->vb2_queue; |
285 | int ret = 0; | 288 | int ret = 0; |
286 | 289 | ||
287 | /* Copy back data such as timestamp, input, etc. */ | 290 | /* Copy back data such as timestamp, flags, input, etc. */ |
288 | memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); | 291 | memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); |
289 | b->input = vb->v4l2_buf.input; | 292 | b->input = vb->v4l2_buf.input; |
290 | b->reserved = vb->v4l2_buf.reserved; | 293 | b->reserved = vb->v4l2_buf.reserved; |
@@ -313,7 +316,10 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) | |||
313 | b->m.userptr = vb->v4l2_planes[0].m.userptr; | 316 | b->m.userptr = vb->v4l2_planes[0].m.userptr; |
314 | } | 317 | } |
315 | 318 | ||
316 | b->flags = 0; | 319 | /* |
320 | * Clear any buffer state related flags. | ||
321 | */ | ||
322 | b->flags &= ~V4L2_BUFFER_STATE_FLAGS; | ||
317 | 323 | ||
318 | switch (vb->state) { | 324 | switch (vb->state) { |
319 | case VB2_BUF_STATE_QUEUED: | 325 | case VB2_BUF_STATE_QUEUED: |
@@ -519,6 +525,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
519 | num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME); | 525 | num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME); |
520 | memset(plane_sizes, 0, sizeof(plane_sizes)); | 526 | memset(plane_sizes, 0, sizeof(plane_sizes)); |
521 | memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); | 527 | memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); |
528 | q->memory = req->memory; | ||
522 | 529 | ||
523 | /* | 530 | /* |
524 | * Ask the driver how many buffers and planes per buffer it requires. | 531 | * Ask the driver how many buffers and planes per buffer it requires. |
@@ -560,8 +567,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
560 | ret = num_buffers; | 567 | ret = num_buffers; |
561 | } | 568 | } |
562 | 569 | ||
563 | q->memory = req->memory; | ||
564 | |||
565 | /* | 570 | /* |
566 | * Return the number of successfully allocated buffers | 571 | * Return the number of successfully allocated buffers |
567 | * to the userspace. | 572 | * to the userspace. |
@@ -715,6 +720,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, | |||
715 | 720 | ||
716 | vb->v4l2_buf.field = b->field; | 721 | vb->v4l2_buf.field = b->field; |
717 | vb->v4l2_buf.timestamp = b->timestamp; | 722 | vb->v4l2_buf.timestamp = b->timestamp; |
723 | vb->v4l2_buf.input = b->input; | ||
724 | vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS; | ||
718 | 725 | ||
719 | return 0; | 726 | return 0; |
720 | } | 727 | } |
diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c index 58205d596138..a790a5f8c06f 100644 --- a/drivers/media/video/videobuf2-dma-contig.c +++ b/drivers/media/video/videobuf2-dma-contig.c | |||
@@ -46,7 +46,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) | |||
46 | GFP_KERNEL); | 46 | GFP_KERNEL); |
47 | if (!buf->vaddr) { | 47 | if (!buf->vaddr) { |
48 | dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n", | 48 | dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n", |
49 | buf->size); | 49 | size); |
50 | kfree(buf); | 50 | kfree(buf); |
51 | return ERR_PTR(-ENOMEM); | 51 | return ERR_PTR(-ENOMEM); |
52 | } | 52 | } |
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index d01574d98870..f4c8c844b913 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -55,6 +55,19 @@ int mfd_cell_disable(struct platform_device *pdev) | |||
55 | } | 55 | } |
56 | EXPORT_SYMBOL(mfd_cell_disable); | 56 | EXPORT_SYMBOL(mfd_cell_disable); |
57 | 57 | ||
58 | static int mfd_platform_add_cell(struct platform_device *pdev, | ||
59 | const struct mfd_cell *cell) | ||
60 | { | ||
61 | if (!cell) | ||
62 | return 0; | ||
63 | |||
64 | pdev->mfd_cell = kmemdup(cell, sizeof(*cell), GFP_KERNEL); | ||
65 | if (!pdev->mfd_cell) | ||
66 | return -ENOMEM; | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
58 | static int mfd_add_device(struct device *parent, int id, | 71 | static int mfd_add_device(struct device *parent, int id, |
59 | const struct mfd_cell *cell, | 72 | const struct mfd_cell *cell, |
60 | struct resource *mem_base, | 73 | struct resource *mem_base, |
@@ -75,7 +88,7 @@ static int mfd_add_device(struct device *parent, int id, | |||
75 | 88 | ||
76 | pdev->dev.parent = parent; | 89 | pdev->dev.parent = parent; |
77 | 90 | ||
78 | ret = platform_device_add_data(pdev, cell, sizeof(*cell)); | 91 | ret = mfd_platform_add_cell(pdev, cell); |
79 | if (ret) | 92 | if (ret) |
80 | goto fail_res; | 93 | goto fail_res; |
81 | 94 | ||
@@ -123,7 +136,6 @@ static int mfd_add_device(struct device *parent, int id, | |||
123 | 136 | ||
124 | return 0; | 137 | return 0; |
125 | 138 | ||
126 | /* platform_device_del(pdev); */ | ||
127 | fail_res: | 139 | fail_res: |
128 | kfree(res); | 140 | kfree(res); |
129 | fail_device: | 141 | fail_device: |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 53450f433f10..2e165117457b 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <linux/regulator/consumer.h> | ||
29 | #include <plat/usb.h> | 28 | #include <plat/usb.h> |
30 | 29 | ||
31 | #define USBHS_DRIVER_NAME "usbhs-omap" | 30 | #define USBHS_DRIVER_NAME "usbhs-omap" |
@@ -700,8 +699,7 @@ static int usbhs_enable(struct device *dev) | |||
700 | dev_dbg(dev, "starting TI HSUSB Controller\n"); | 699 | dev_dbg(dev, "starting TI HSUSB Controller\n"); |
701 | if (!pdata) { | 700 | if (!pdata) { |
702 | dev_dbg(dev, "missing platform_data\n"); | 701 | dev_dbg(dev, "missing platform_data\n"); |
703 | ret = -ENODEV; | 702 | return -ENODEV; |
704 | goto end_enable; | ||
705 | } | 703 | } |
706 | 704 | ||
707 | spin_lock_irqsave(&omap->lock, flags); | 705 | spin_lock_irqsave(&omap->lock, flags); |
@@ -915,7 +913,8 @@ static int usbhs_enable(struct device *dev) | |||
915 | 913 | ||
916 | end_count: | 914 | end_count: |
917 | omap->count++; | 915 | omap->count++; |
918 | goto end_enable; | 916 | spin_unlock_irqrestore(&omap->lock, flags); |
917 | return 0; | ||
919 | 918 | ||
920 | err_tll: | 919 | err_tll: |
921 | if (pdata->ehci_data->phy_reset) { | 920 | if (pdata->ehci_data->phy_reset) { |
@@ -931,8 +930,6 @@ err_tll: | |||
931 | clk_disable(omap->usbhost_fs_fck); | 930 | clk_disable(omap->usbhost_fs_fck); |
932 | clk_disable(omap->usbhost_hs_fck); | 931 | clk_disable(omap->usbhost_hs_fck); |
933 | clk_disable(omap->usbhost_ick); | 932 | clk_disable(omap->usbhost_ick); |
934 | |||
935 | end_enable: | ||
936 | spin_unlock_irqrestore(&omap->lock, flags); | 933 | spin_unlock_irqrestore(&omap->lock, flags); |
937 | return ret; | 934 | return ret; |
938 | } | 935 | } |
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index 20e4e9395b61..ecafa4ba238b 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c | |||
@@ -348,15 +348,15 @@ static unsigned long gru_chiplet_cpu_to_mmr(int chiplet, int cpu, int *corep) | |||
348 | 348 | ||
349 | static int gru_irq_count[GRU_CHIPLETS_PER_BLADE]; | 349 | static int gru_irq_count[GRU_CHIPLETS_PER_BLADE]; |
350 | 350 | ||
351 | static void gru_noop(unsigned int irq) | 351 | static void gru_noop(struct irq_data *d) |
352 | { | 352 | { |
353 | } | 353 | } |
354 | 354 | ||
355 | static struct irq_chip gru_chip[GRU_CHIPLETS_PER_BLADE] = { | 355 | static struct irq_chip gru_chip[GRU_CHIPLETS_PER_BLADE] = { |
356 | [0 ... GRU_CHIPLETS_PER_BLADE - 1] { | 356 | [0 ... GRU_CHIPLETS_PER_BLADE - 1] { |
357 | .mask = gru_noop, | 357 | .irq_mask = gru_noop, |
358 | .unmask = gru_noop, | 358 | .irq_unmask = gru_noop, |
359 | .ack = gru_noop | 359 | .irq_ack = gru_noop |
360 | } | 360 | } |
361 | }; | 361 | }; |
362 | 362 | ||
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 63667a8f140c..d6d62fd07ee9 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -284,6 +284,7 @@ int mmc_add_card(struct mmc_card *card) | |||
284 | type = "SD-combo"; | 284 | type = "SD-combo"; |
285 | if (mmc_card_blockaddr(card)) | 285 | if (mmc_card_blockaddr(card)) |
286 | type = "SDHC-combo"; | 286 | type = "SDHC-combo"; |
287 | break; | ||
287 | default: | 288 | default: |
288 | type = "?"; | 289 | type = "?"; |
289 | break; | 290 | break; |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 461e6a17fb90..2b200c1cfbba 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -94,7 +94,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) | |||
94 | spin_unlock_irqrestore(&host->clk_lock, flags); | 94 | spin_unlock_irqrestore(&host->clk_lock, flags); |
95 | return; | 95 | return; |
96 | } | 96 | } |
97 | mutex_lock(&host->clk_gate_mutex); | 97 | mmc_claim_host(host); |
98 | spin_lock_irqsave(&host->clk_lock, flags); | 98 | spin_lock_irqsave(&host->clk_lock, flags); |
99 | if (!host->clk_requests) { | 99 | if (!host->clk_requests) { |
100 | spin_unlock_irqrestore(&host->clk_lock, flags); | 100 | spin_unlock_irqrestore(&host->clk_lock, flags); |
@@ -104,7 +104,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) | |||
104 | pr_debug("%s: gated MCI clock\n", mmc_hostname(host)); | 104 | pr_debug("%s: gated MCI clock\n", mmc_hostname(host)); |
105 | } | 105 | } |
106 | spin_unlock_irqrestore(&host->clk_lock, flags); | 106 | spin_unlock_irqrestore(&host->clk_lock, flags); |
107 | mutex_unlock(&host->clk_gate_mutex); | 107 | mmc_release_host(host); |
108 | } | 108 | } |
109 | 109 | ||
110 | /* | 110 | /* |
@@ -130,7 +130,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) | |||
130 | { | 130 | { |
131 | unsigned long flags; | 131 | unsigned long flags; |
132 | 132 | ||
133 | mutex_lock(&host->clk_gate_mutex); | 133 | mmc_claim_host(host); |
134 | spin_lock_irqsave(&host->clk_lock, flags); | 134 | spin_lock_irqsave(&host->clk_lock, flags); |
135 | if (host->clk_gated) { | 135 | if (host->clk_gated) { |
136 | spin_unlock_irqrestore(&host->clk_lock, flags); | 136 | spin_unlock_irqrestore(&host->clk_lock, flags); |
@@ -140,7 +140,7 @@ void mmc_host_clk_ungate(struct mmc_host *host) | |||
140 | } | 140 | } |
141 | host->clk_requests++; | 141 | host->clk_requests++; |
142 | spin_unlock_irqrestore(&host->clk_lock, flags); | 142 | spin_unlock_irqrestore(&host->clk_lock, flags); |
143 | mutex_unlock(&host->clk_gate_mutex); | 143 | mmc_release_host(host); |
144 | } | 144 | } |
145 | 145 | ||
146 | /** | 146 | /** |
@@ -215,7 +215,6 @@ static inline void mmc_host_clk_init(struct mmc_host *host) | |||
215 | host->clk_gated = false; | 215 | host->clk_gated = false; |
216 | INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); | 216 | INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); |
217 | spin_lock_init(&host->clk_lock); | 217 | spin_lock_init(&host->clk_lock); |
218 | mutex_init(&host->clk_gate_mutex); | ||
219 | } | 218 | } |
220 | 219 | ||
221 | /** | 220 | /** |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index 2e032f0e8cf4..a6c329040140 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -832,7 +832,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) | |||
832 | return IRQ_HANDLED; | 832 | return IRQ_HANDLED; |
833 | } | 833 | } |
834 | 834 | ||
835 | if (end_command) | 835 | if (end_command && host->cmd) |
836 | mmc_omap_cmd_done(host, host->cmd); | 836 | mmc_omap_cmd_done(host, host->cmd); |
837 | if (host->data != NULL) { | 837 | if (host->data != NULL) { |
838 | if (transfer_error) | 838 | if (transfer_error) |
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index a136be706347..f8b5f37007b2 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -957,6 +957,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
957 | host->ioaddr = pci_ioremap_bar(pdev, bar); | 957 | host->ioaddr = pci_ioremap_bar(pdev, bar); |
958 | if (!host->ioaddr) { | 958 | if (!host->ioaddr) { |
959 | dev_err(&pdev->dev, "failed to remap registers\n"); | 959 | dev_err(&pdev->dev, "failed to remap registers\n"); |
960 | ret = -ENOMEM; | ||
960 | goto release; | 961 | goto release; |
961 | } | 962 | } |
962 | 963 | ||
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 9e15f41f87be..5d20661bc357 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -1334,6 +1334,13 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
1334 | 1334 | ||
1335 | host = (struct sdhci_host*)param; | 1335 | host = (struct sdhci_host*)param; |
1336 | 1336 | ||
1337 | /* | ||
1338 | * If this tasklet gets rescheduled while running, it will | ||
1339 | * be run again afterwards but without any active request. | ||
1340 | */ | ||
1341 | if (!host->mrq) | ||
1342 | return; | ||
1343 | |||
1337 | spin_lock_irqsave(&host->lock, flags); | 1344 | spin_lock_irqsave(&host->lock, flags); |
1338 | 1345 | ||
1339 | del_timer(&host->timer); | 1346 | del_timer(&host->timer); |
@@ -1345,7 +1352,7 @@ static void sdhci_tasklet_finish(unsigned long param) | |||
1345 | * upon error conditions. | 1352 | * upon error conditions. |
1346 | */ | 1353 | */ |
1347 | if (!(host->flags & SDHCI_DEVICE_DEAD) && | 1354 | if (!(host->flags & SDHCI_DEVICE_DEAD) && |
1348 | (mrq->cmd->error || | 1355 | ((mrq->cmd && mrq->cmd->error) || |
1349 | (mrq->data && (mrq->data->error || | 1356 | (mrq->data && (mrq->data->error || |
1350 | (mrq->data->stop && mrq->data->stop->error))) || | 1357 | (mrq->data->stop && mrq->data->stop->error))) || |
1351 | (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { | 1358 | (host->quirks & SDHCI_QUIRK_RESET_AFTER_REQUEST))) { |
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 62d37de6de76..710339a85c84 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
@@ -728,15 +728,15 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
728 | tmio_mmc_set_clock(host, ios->clock); | 728 | tmio_mmc_set_clock(host, ios->clock); |
729 | 729 | ||
730 | /* Power sequence - OFF -> UP -> ON */ | 730 | /* Power sequence - OFF -> UP -> ON */ |
731 | if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { | 731 | if (ios->power_mode == MMC_POWER_UP) { |
732 | /* power up SD bus */ | ||
733 | if (host->set_pwr) | ||
734 | host->set_pwr(host->pdev, 1); | ||
735 | } else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) { | ||
732 | /* power down SD bus */ | 736 | /* power down SD bus */ |
733 | if (ios->power_mode == MMC_POWER_OFF && host->set_pwr) | 737 | if (ios->power_mode == MMC_POWER_OFF && host->set_pwr) |
734 | host->set_pwr(host->pdev, 0); | 738 | host->set_pwr(host->pdev, 0); |
735 | tmio_mmc_clk_stop(host); | 739 | tmio_mmc_clk_stop(host); |
736 | } else if (ios->power_mode == MMC_POWER_UP) { | ||
737 | /* power up SD bus */ | ||
738 | if (host->set_pwr) | ||
739 | host->set_pwr(host->pdev, 1); | ||
740 | } else { | 740 | } else { |
741 | /* start bus clock */ | 741 | /* start bus clock */ |
742 | tmio_mmc_clk_start(host); | 742 | tmio_mmc_clk_start(host); |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 96c0b34ba8db..657b9f4b6f9b 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -400,7 +400,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) | |||
400 | doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); | 400 | doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); |
401 | doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); | 401 | doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); |
402 | 402 | ||
403 | /* We can't' use dev_ready here, but at least we wait for the | 403 | /* We can't use dev_ready here, but at least we wait for the |
404 | * command to complete | 404 | * command to complete |
405 | */ | 405 | */ |
406 | udelay(50); | 406 | udelay(50); |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index a3755ffc03d4..bc8ce48f0778 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -2550,7 +2550,6 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, | |||
2550 | const struct parport_pc_via_data *via) | 2550 | const struct parport_pc_via_data *via) |
2551 | { | 2551 | { |
2552 | short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 }; | 2552 | short inta_addr[6] = { 0x2A0, 0x2C0, 0x220, 0x240, 0x1E0 }; |
2553 | struct resource *base_res; | ||
2554 | u32 ite8872set; | 2553 | u32 ite8872set; |
2555 | u32 ite8872_lpt, ite8872_lpthi; | 2554 | u32 ite8872_lpt, ite8872_lpthi; |
2556 | u8 ite8872_irq, type; | 2555 | u8 ite8872_irq, type; |
@@ -2561,8 +2560,7 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, | |||
2561 | 2560 | ||
2562 | /* make sure which one chip */ | 2561 | /* make sure which one chip */ |
2563 | for (i = 0; i < 5; i++) { | 2562 | for (i = 0; i < 5; i++) { |
2564 | base_res = request_region(inta_addr[i], 32, "it887x"); | 2563 | if (request_region(inta_addr[i], 32, "it887x")) { |
2565 | if (base_res) { | ||
2566 | int test; | 2564 | int test; |
2567 | pci_write_config_dword(pdev, 0x60, | 2565 | pci_write_config_dword(pdev, 0x60, |
2568 | 0xe5000000 | inta_addr[i]); | 2566 | 0xe5000000 | inta_addr[i]); |
@@ -2571,7 +2569,7 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, | |||
2571 | test = inb(inta_addr[i]); | 2569 | test = inb(inta_addr[i]); |
2572 | if (test != 0xff) | 2570 | if (test != 0xff) |
2573 | break; | 2571 | break; |
2574 | release_region(inta_addr[i], 0x8); | 2572 | release_region(inta_addr[i], 32); |
2575 | } | 2573 | } |
2576 | } | 2574 | } |
2577 | if (i >= 5) { | 2575 | if (i >= 5) { |
@@ -2635,7 +2633,7 @@ static int __devinit sio_ite_8872_probe(struct pci_dev *pdev, int autoirq, | |||
2635 | /* | 2633 | /* |
2636 | * Release the resource so that parport_pc_probe_port can get it. | 2634 | * Release the resource so that parport_pc_probe_port can get it. |
2637 | */ | 2635 | */ |
2638 | release_resource(base_res); | 2636 | release_region(inta_addr[i], 32); |
2639 | if (parport_pc_probe_port(ite8872_lpt, ite8872_lpthi, | 2637 | if (parport_pc_probe_port(ite8872_lpt, ite8872_lpthi, |
2640 | irq, PARPORT_DMA_NONE, &pdev->dev, 0)) { | 2638 | irq, PARPORT_DMA_NONE, &pdev->dev, 0)) { |
2641 | printk(KERN_INFO | 2639 | printk(KERN_INFO |
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index c8ff646c0b05..0fa466a91bf4 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -88,4 +88,6 @@ config PCI_IOAPIC | |||
88 | depends on HOTPLUG | 88 | depends on HOTPLUG |
89 | default y | 89 | default y |
90 | 90 | ||
91 | select NLS if (DMI || ACPI) | 91 | config PCI_LABEL |
92 | def_bool y if (DMI || ACPI) | ||
93 | select NLS | ||
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 98d61c8e984b..c85f744270a5 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -56,10 +56,10 @@ obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o | |||
56 | # ACPI Related PCI FW Functions | 56 | # ACPI Related PCI FW Functions |
57 | # ACPI _DSM provided firmware instance and string name | 57 | # ACPI _DSM provided firmware instance and string name |
58 | # | 58 | # |
59 | obj-$(CONFIG_ACPI) += pci-acpi.o pci-label.o | 59 | obj-$(CONFIG_ACPI) += pci-acpi.o |
60 | 60 | ||
61 | # SMBIOS provided firmware instance and labels | 61 | # SMBIOS provided firmware instance and labels |
62 | obj-$(CONFIG_DMI) += pci-label.o | 62 | obj-$(CONFIG_PCI_LABEL) += pci-label.o |
63 | 63 | ||
64 | # Cardbus & CompactPCI use setup-bus | 64 | # Cardbus & CompactPCI use setup-bus |
65 | obj-$(CONFIG_HOTPLUG) += setup-bus.o | 65 | obj-$(CONFIG_HOTPLUG) += setup-bus.o |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 505c1c7075f0..d552d2c77844 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -1299,7 +1299,7 @@ static void iommu_detach_domain(struct dmar_domain *domain, | |||
1299 | static struct iova_domain reserved_iova_list; | 1299 | static struct iova_domain reserved_iova_list; |
1300 | static struct lock_class_key reserved_rbtree_key; | 1300 | static struct lock_class_key reserved_rbtree_key; |
1301 | 1301 | ||
1302 | static void dmar_init_reserved_ranges(void) | 1302 | static int dmar_init_reserved_ranges(void) |
1303 | { | 1303 | { |
1304 | struct pci_dev *pdev = NULL; | 1304 | struct pci_dev *pdev = NULL; |
1305 | struct iova *iova; | 1305 | struct iova *iova; |
@@ -1313,8 +1313,10 @@ static void dmar_init_reserved_ranges(void) | |||
1313 | /* IOAPIC ranges shouldn't be accessed by DMA */ | 1313 | /* IOAPIC ranges shouldn't be accessed by DMA */ |
1314 | iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START), | 1314 | iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START), |
1315 | IOVA_PFN(IOAPIC_RANGE_END)); | 1315 | IOVA_PFN(IOAPIC_RANGE_END)); |
1316 | if (!iova) | 1316 | if (!iova) { |
1317 | printk(KERN_ERR "Reserve IOAPIC range failed\n"); | 1317 | printk(KERN_ERR "Reserve IOAPIC range failed\n"); |
1318 | return -ENODEV; | ||
1319 | } | ||
1318 | 1320 | ||
1319 | /* Reserve all PCI MMIO to avoid peer-to-peer access */ | 1321 | /* Reserve all PCI MMIO to avoid peer-to-peer access */ |
1320 | for_each_pci_dev(pdev) { | 1322 | for_each_pci_dev(pdev) { |
@@ -1327,11 +1329,13 @@ static void dmar_init_reserved_ranges(void) | |||
1327 | iova = reserve_iova(&reserved_iova_list, | 1329 | iova = reserve_iova(&reserved_iova_list, |
1328 | IOVA_PFN(r->start), | 1330 | IOVA_PFN(r->start), |
1329 | IOVA_PFN(r->end)); | 1331 | IOVA_PFN(r->end)); |
1330 | if (!iova) | 1332 | if (!iova) { |
1331 | printk(KERN_ERR "Reserve iova failed\n"); | 1333 | printk(KERN_ERR "Reserve iova failed\n"); |
1334 | return -ENODEV; | ||
1335 | } | ||
1332 | } | 1336 | } |
1333 | } | 1337 | } |
1334 | 1338 | return 0; | |
1335 | } | 1339 | } |
1336 | 1340 | ||
1337 | static void domain_reserve_special_ranges(struct dmar_domain *domain) | 1341 | static void domain_reserve_special_ranges(struct dmar_domain *domain) |
@@ -1835,7 +1839,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
1835 | 1839 | ||
1836 | ret = iommu_attach_domain(domain, iommu); | 1840 | ret = iommu_attach_domain(domain, iommu); |
1837 | if (ret) { | 1841 | if (ret) { |
1838 | domain_exit(domain); | 1842 | free_domain_mem(domain); |
1839 | goto error; | 1843 | goto error; |
1840 | } | 1844 | } |
1841 | 1845 | ||
@@ -2213,7 +2217,7 @@ static int __init iommu_prepare_static_identity_mapping(int hw) | |||
2213 | return 0; | 2217 | return 0; |
2214 | } | 2218 | } |
2215 | 2219 | ||
2216 | int __init init_dmars(void) | 2220 | static int __init init_dmars(int force_on) |
2217 | { | 2221 | { |
2218 | struct dmar_drhd_unit *drhd; | 2222 | struct dmar_drhd_unit *drhd; |
2219 | struct dmar_rmrr_unit *rmrr; | 2223 | struct dmar_rmrr_unit *rmrr; |
@@ -2393,8 +2397,15 @@ int __init init_dmars(void) | |||
2393 | * enable translation | 2397 | * enable translation |
2394 | */ | 2398 | */ |
2395 | for_each_drhd_unit(drhd) { | 2399 | for_each_drhd_unit(drhd) { |
2396 | if (drhd->ignored) | 2400 | if (drhd->ignored) { |
2401 | /* | ||
2402 | * we always have to disable PMRs or DMA may fail on | ||
2403 | * this device | ||
2404 | */ | ||
2405 | if (force_on) | ||
2406 | iommu_disable_protect_mem_regions(drhd->iommu); | ||
2397 | continue; | 2407 | continue; |
2408 | } | ||
2398 | iommu = drhd->iommu; | 2409 | iommu = drhd->iommu; |
2399 | 2410 | ||
2400 | iommu_flush_write_buffer(iommu); | 2411 | iommu_flush_write_buffer(iommu); |
@@ -3240,9 +3251,15 @@ static int device_notifier(struct notifier_block *nb, | |||
3240 | if (!domain) | 3251 | if (!domain) |
3241 | return 0; | 3252 | return 0; |
3242 | 3253 | ||
3243 | if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) | 3254 | if (action == BUS_NOTIFY_UNBOUND_DRIVER && !iommu_pass_through) { |
3244 | domain_remove_one_dev_info(domain, pdev); | 3255 | domain_remove_one_dev_info(domain, pdev); |
3245 | 3256 | ||
3257 | if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) && | ||
3258 | !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY) && | ||
3259 | list_empty(&domain->devices)) | ||
3260 | domain_exit(domain); | ||
3261 | } | ||
3262 | |||
3246 | return 0; | 3263 | return 0; |
3247 | } | 3264 | } |
3248 | 3265 | ||
@@ -3277,12 +3294,21 @@ int __init intel_iommu_init(void) | |||
3277 | if (no_iommu || dmar_disabled) | 3294 | if (no_iommu || dmar_disabled) |
3278 | return -ENODEV; | 3295 | return -ENODEV; |
3279 | 3296 | ||
3280 | iommu_init_mempool(); | 3297 | if (iommu_init_mempool()) { |
3281 | dmar_init_reserved_ranges(); | 3298 | if (force_on) |
3299 | panic("tboot: Failed to initialize iommu memory\n"); | ||
3300 | return -ENODEV; | ||
3301 | } | ||
3302 | |||
3303 | if (dmar_init_reserved_ranges()) { | ||
3304 | if (force_on) | ||
3305 | panic("tboot: Failed to reserve iommu ranges\n"); | ||
3306 | return -ENODEV; | ||
3307 | } | ||
3282 | 3308 | ||
3283 | init_no_remapping_devices(); | 3309 | init_no_remapping_devices(); |
3284 | 3310 | ||
3285 | ret = init_dmars(); | 3311 | ret = init_dmars(force_on); |
3286 | if (ret) { | 3312 | if (ret) { |
3287 | if (force_on) | 3313 | if (force_on) |
3288 | panic("tboot: Failed to initialize DMARs\n"); | 3314 | panic("tboot: Failed to initialize DMARs\n"); |
@@ -3391,6 +3417,11 @@ static void domain_remove_one_dev_info(struct dmar_domain *domain, | |||
3391 | domain->iommu_count--; | 3417 | domain->iommu_count--; |
3392 | domain_update_iommu_cap(domain); | 3418 | domain_update_iommu_cap(domain); |
3393 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); | 3419 | spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags); |
3420 | |||
3421 | spin_lock_irqsave(&iommu->lock, tmp_flags); | ||
3422 | clear_bit(domain->id, iommu->domain_ids); | ||
3423 | iommu->domains[domain->id] = NULL; | ||
3424 | spin_unlock_irqrestore(&iommu->lock, tmp_flags); | ||
3394 | } | 3425 | } |
3395 | 3426 | ||
3396 | spin_unlock_irqrestore(&device_domain_lock, flags); | 3427 | spin_unlock_irqrestore(&device_domain_lock, flags); |
@@ -3607,9 +3638,9 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, | |||
3607 | 3638 | ||
3608 | pte = dmar_domain->pgd; | 3639 | pte = dmar_domain->pgd; |
3609 | if (dma_pte_present(pte)) { | 3640 | if (dma_pte_present(pte)) { |
3610 | free_pgtable_page(dmar_domain->pgd); | ||
3611 | dmar_domain->pgd = (struct dma_pte *) | 3641 | dmar_domain->pgd = (struct dma_pte *) |
3612 | phys_to_virt(dma_pte_addr(pte)); | 3642 | phys_to_virt(dma_pte_addr(pte)); |
3643 | free_pgtable_page(pte); | ||
3613 | } | 3644 | } |
3614 | dmar_domain->agaw--; | 3645 | dmar_domain->agaw--; |
3615 | } | 3646 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index d86ea8b01137..135df164a4c1 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -781,7 +781,7 @@ static int pci_pm_resume(struct device *dev) | |||
781 | 781 | ||
782 | #endif /* !CONFIG_SUSPEND */ | 782 | #endif /* !CONFIG_SUSPEND */ |
783 | 783 | ||
784 | #ifdef CONFIG_HIBERNATION | 784 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
785 | 785 | ||
786 | static int pci_pm_freeze(struct device *dev) | 786 | static int pci_pm_freeze(struct device *dev) |
787 | { | 787 | { |
@@ -970,7 +970,7 @@ static int pci_pm_restore(struct device *dev) | |||
970 | return error; | 970 | return error; |
971 | } | 971 | } |
972 | 972 | ||
973 | #else /* !CONFIG_HIBERNATION */ | 973 | #else /* !CONFIG_HIBERNATE_CALLBACKS */ |
974 | 974 | ||
975 | #define pci_pm_freeze NULL | 975 | #define pci_pm_freeze NULL |
976 | #define pci_pm_freeze_noirq NULL | 976 | #define pci_pm_freeze_noirq NULL |
@@ -981,7 +981,7 @@ static int pci_pm_restore(struct device *dev) | |||
981 | #define pci_pm_restore NULL | 981 | #define pci_pm_restore NULL |
982 | #define pci_pm_restore_noirq NULL | 982 | #define pci_pm_restore_noirq NULL |
983 | 983 | ||
984 | #endif /* !CONFIG_HIBERNATION */ | 984 | #endif /* !CONFIG_HIBERNATE_CALLBACKS */ |
985 | 985 | ||
986 | #ifdef CONFIG_PM_RUNTIME | 986 | #ifdef CONFIG_PM_RUNTIME |
987 | 987 | ||
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index fe77e8223841..e8c19def1b0f 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -173,7 +173,7 @@ static int pcmcia_access_config(struct pcmcia_device *p_dev, | |||
173 | c = p_dev->function_config; | 173 | c = p_dev->function_config; |
174 | 174 | ||
175 | if (!(c->state & CONFIG_LOCKED)) { | 175 | if (!(c->state & CONFIG_LOCKED)) { |
176 | dev_dbg(&p_dev->dev, "Configuration isn't't locked\n"); | 176 | dev_dbg(&p_dev->dev, "Configuration isn't locked\n"); |
177 | mutex_unlock(&s->ops_mutex); | 177 | mutex_unlock(&s->ops_mutex); |
178 | return -EACCES; | 178 | return -EACCES; |
179 | } | 179 | } |
diff --git a/drivers/pcmcia/pxa2xx_balloon3.c b/drivers/pcmcia/pxa2xx_balloon3.c index 453c54c97612..4c3e94c0ae85 100644 --- a/drivers/pcmcia/pxa2xx_balloon3.c +++ b/drivers/pcmcia/pxa2xx_balloon3.c | |||
@@ -25,6 +25,8 @@ | |||
25 | 25 | ||
26 | #include <mach/balloon3.h> | 26 | #include <mach/balloon3.h> |
27 | 27 | ||
28 | #include <asm/mach-types.h> | ||
29 | |||
28 | #include "soc_common.h" | 30 | #include "soc_common.h" |
29 | 31 | ||
30 | /* | 32 | /* |
@@ -127,6 +129,9 @@ static int __init balloon3_pcmcia_init(void) | |||
127 | { | 129 | { |
128 | int ret; | 130 | int ret; |
129 | 131 | ||
132 | if (!machine_is_balloon3()) | ||
133 | return -ENODEV; | ||
134 | |||
130 | balloon3_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | 135 | balloon3_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); |
131 | if (!balloon3_pcmcia_device) | 136 | if (!balloon3_pcmcia_device) |
132 | return -ENOMEM; | 137 | return -ENOMEM; |
diff --git a/drivers/pcmcia/pxa2xx_trizeps4.c b/drivers/pcmcia/pxa2xx_trizeps4.c index b7e596620db1..b829e655457b 100644 --- a/drivers/pcmcia/pxa2xx_trizeps4.c +++ b/drivers/pcmcia/pxa2xx_trizeps4.c | |||
@@ -69,15 +69,15 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
69 | for (i = 0; i < ARRAY_SIZE(irqs); i++) { | 69 | for (i = 0; i < ARRAY_SIZE(irqs); i++) { |
70 | if (irqs[i].sock != skt->nr) | 70 | if (irqs[i].sock != skt->nr) |
71 | continue; | 71 | continue; |
72 | if (gpio_request(IRQ_TO_GPIO(irqs[i].irq), irqs[i].str) < 0) { | 72 | if (gpio_request(irq_to_gpio(irqs[i].irq), irqs[i].str) < 0) { |
73 | pr_err("%s: sock %d unable to request gpio %d\n", | 73 | pr_err("%s: sock %d unable to request gpio %d\n", |
74 | __func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq)); | 74 | __func__, skt->nr, irq_to_gpio(irqs[i].irq)); |
75 | ret = -EBUSY; | 75 | ret = -EBUSY; |
76 | goto error; | 76 | goto error; |
77 | } | 77 | } |
78 | if (gpio_direction_input(IRQ_TO_GPIO(irqs[i].irq)) < 0) { | 78 | if (gpio_direction_input(irq_to_gpio(irqs[i].irq)) < 0) { |
79 | pr_err("%s: sock %d unable to set input gpio %d\n", | 79 | pr_err("%s: sock %d unable to set input gpio %d\n", |
80 | __func__, skt->nr, IRQ_TO_GPIO(irqs[i].irq)); | 80 | __func__, skt->nr, irq_to_gpio(irqs[i].irq)); |
81 | ret = -EINVAL; | 81 | ret = -EINVAL; |
82 | goto error; | 82 | goto error; |
83 | } | 83 | } |
@@ -86,7 +86,7 @@ static int trizeps_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
86 | 86 | ||
87 | error: | 87 | error: |
88 | for (; i >= 0; i--) { | 88 | for (; i >= 0; i--) { |
89 | gpio_free(IRQ_TO_GPIO(irqs[i].irq)); | 89 | gpio_free(irq_to_gpio(irqs[i].irq)); |
90 | } | 90 | } |
91 | return (ret); | 91 | return (ret); |
92 | } | 92 | } |
@@ -97,7 +97,7 @@ static void trizeps_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | |||
97 | /* free allocated gpio's */ | 97 | /* free allocated gpio's */ |
98 | gpio_free(GPIO_PRDY); | 98 | gpio_free(GPIO_PRDY); |
99 | for (i = 0; i < ARRAY_SIZE(irqs); i++) | 99 | for (i = 0; i < ARRAY_SIZE(irqs); i++) |
100 | gpio_free(IRQ_TO_GPIO(irqs[i].irq)); | 100 | gpio_free(irq_to_gpio(irqs[i].irq)); |
101 | } | 101 | } |
102 | 102 | ||
103 | static unsigned long trizeps_pcmcia_status[2]; | 103 | static unsigned long trizeps_pcmcia_status[2]; |
@@ -226,6 +226,9 @@ static int __init trizeps_pcmcia_init(void) | |||
226 | { | 226 | { |
227 | int ret; | 227 | int ret; |
228 | 228 | ||
229 | if (!machine_is_trizeps4() && !machine_is_trizeps4wl()) | ||
230 | return -ENODEV; | ||
231 | |||
229 | trizeps_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); | 232 | trizeps_pcmcia_device = platform_device_alloc("pxa2xx-pcmcia", -1); |
230 | if (!trizeps_pcmcia_device) | 233 | if (!trizeps_pcmcia_device) |
231 | return -ENOMEM; | 234 | return -ENOMEM; |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 2ee442c2a5db..0485e394712a 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -187,7 +187,8 @@ config MSI_LAPTOP | |||
187 | depends on ACPI | 187 | depends on ACPI |
188 | depends on BACKLIGHT_CLASS_DEVICE | 188 | depends on BACKLIGHT_CLASS_DEVICE |
189 | depends on RFKILL | 189 | depends on RFKILL |
190 | depends on SERIO_I8042 | 190 | depends on INPUT && SERIO_I8042 |
191 | select INPUT_SPARSEKMAP | ||
191 | ---help--- | 192 | ---help--- |
192 | This is a driver for laptops built by MSI (MICRO-STAR | 193 | This is a driver for laptops built by MSI (MICRO-STAR |
193 | INTERNATIONAL): | 194 | INTERNATIONAL): |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 5ea6c3477d17..ac4e7f83ce6c 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -89,7 +89,7 @@ MODULE_LICENSE("GPL"); | |||
89 | #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026" | 89 | #define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026" |
90 | 90 | ||
91 | MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); | 91 | MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB"); |
92 | MODULE_ALIAS("wmi:6AF4F258-B401-42Fd-BE91-3D4AC2D7C0D3"); | 92 | MODULE_ALIAS("wmi:6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"); |
93 | MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); | 93 | MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026"); |
94 | 94 | ||
95 | enum acer_wmi_event_ids { | 95 | enum acer_wmi_event_ids { |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index efc776cb0c66..832a3fd7c1c8 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -201,8 +201,8 @@ static int asus_wmi_input_init(struct asus_wmi *asus) | |||
201 | if (!asus->inputdev) | 201 | if (!asus->inputdev) |
202 | return -ENOMEM; | 202 | return -ENOMEM; |
203 | 203 | ||
204 | asus->inputdev->name = asus->driver->input_phys; | 204 | asus->inputdev->name = asus->driver->input_name; |
205 | asus->inputdev->phys = asus->driver->input_name; | 205 | asus->inputdev->phys = asus->driver->input_phys; |
206 | asus->inputdev->id.bustype = BUS_HOST; | 206 | asus->inputdev->id.bustype = BUS_HOST; |
207 | asus->inputdev->dev.parent = &asus->platform_device->dev; | 207 | asus->inputdev->dev.parent = &asus->platform_device->dev; |
208 | 208 | ||
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 5f2dd386152b..2c1abf63957f 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -585,8 +585,9 @@ static bool eeepc_wlan_rfkill_blocked(struct eeepc_laptop *eeepc) | |||
585 | return true; | 585 | return true; |
586 | } | 586 | } |
587 | 587 | ||
588 | static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) | 588 | static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) |
589 | { | 589 | { |
590 | struct pci_dev *port; | ||
590 | struct pci_dev *dev; | 591 | struct pci_dev *dev; |
591 | struct pci_bus *bus; | 592 | struct pci_bus *bus; |
592 | bool blocked = eeepc_wlan_rfkill_blocked(eeepc); | 593 | bool blocked = eeepc_wlan_rfkill_blocked(eeepc); |
@@ -599,9 +600,16 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) | |||
599 | mutex_lock(&eeepc->hotplug_lock); | 600 | mutex_lock(&eeepc->hotplug_lock); |
600 | 601 | ||
601 | if (eeepc->hotplug_slot) { | 602 | if (eeepc->hotplug_slot) { |
602 | bus = pci_find_bus(0, 1); | 603 | port = acpi_get_pci_dev(handle); |
604 | if (!port) { | ||
605 | pr_warning("Unable to find port\n"); | ||
606 | goto out_unlock; | ||
607 | } | ||
608 | |||
609 | bus = port->subordinate; | ||
610 | |||
603 | if (!bus) { | 611 | if (!bus) { |
604 | pr_warning("Unable to find PCI bus 1?\n"); | 612 | pr_warning("Unable to find PCI bus?\n"); |
605 | goto out_unlock; | 613 | goto out_unlock; |
606 | } | 614 | } |
607 | 615 | ||
@@ -609,6 +617,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc) | |||
609 | pr_err("Unable to read PCI config space?\n"); | 617 | pr_err("Unable to read PCI config space?\n"); |
610 | goto out_unlock; | 618 | goto out_unlock; |
611 | } | 619 | } |
620 | |||
612 | absent = (l == 0xffffffff); | 621 | absent = (l == 0xffffffff); |
613 | 622 | ||
614 | if (blocked != absent) { | 623 | if (blocked != absent) { |
@@ -647,6 +656,17 @@ out_unlock: | |||
647 | mutex_unlock(&eeepc->hotplug_lock); | 656 | mutex_unlock(&eeepc->hotplug_lock); |
648 | } | 657 | } |
649 | 658 | ||
659 | static void eeepc_rfkill_hotplug_update(struct eeepc_laptop *eeepc, char *node) | ||
660 | { | ||
661 | acpi_status status = AE_OK; | ||
662 | acpi_handle handle; | ||
663 | |||
664 | status = acpi_get_handle(NULL, node, &handle); | ||
665 | |||
666 | if (ACPI_SUCCESS(status)) | ||
667 | eeepc_rfkill_hotplug(eeepc, handle); | ||
668 | } | ||
669 | |||
650 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 670 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
651 | { | 671 | { |
652 | struct eeepc_laptop *eeepc = data; | 672 | struct eeepc_laptop *eeepc = data; |
@@ -654,7 +674,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | |||
654 | if (event != ACPI_NOTIFY_BUS_CHECK) | 674 | if (event != ACPI_NOTIFY_BUS_CHECK) |
655 | return; | 675 | return; |
656 | 676 | ||
657 | eeepc_rfkill_hotplug(eeepc); | 677 | eeepc_rfkill_hotplug(eeepc, handle); |
658 | } | 678 | } |
659 | 679 | ||
660 | static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, | 680 | static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, |
@@ -672,6 +692,11 @@ static int eeepc_register_rfkill_notifier(struct eeepc_laptop *eeepc, | |||
672 | eeepc); | 692 | eeepc); |
673 | if (ACPI_FAILURE(status)) | 693 | if (ACPI_FAILURE(status)) |
674 | pr_warning("Failed to register notify on %s\n", node); | 694 | pr_warning("Failed to register notify on %s\n", node); |
695 | /* | ||
696 | * Refresh pci hotplug in case the rfkill state was | ||
697 | * changed during setup. | ||
698 | */ | ||
699 | eeepc_rfkill_hotplug(eeepc, handle); | ||
675 | } else | 700 | } else |
676 | return -ENODEV; | 701 | return -ENODEV; |
677 | 702 | ||
@@ -693,6 +718,12 @@ static void eeepc_unregister_rfkill_notifier(struct eeepc_laptop *eeepc, | |||
693 | if (ACPI_FAILURE(status)) | 718 | if (ACPI_FAILURE(status)) |
694 | pr_err("Error removing rfkill notify handler %s\n", | 719 | pr_err("Error removing rfkill notify handler %s\n", |
695 | node); | 720 | node); |
721 | /* | ||
722 | * Refresh pci hotplug in case the rfkill | ||
723 | * state was changed after | ||
724 | * eeepc_unregister_rfkill_notifier() | ||
725 | */ | ||
726 | eeepc_rfkill_hotplug(eeepc, handle); | ||
696 | } | 727 | } |
697 | } | 728 | } |
698 | 729 | ||
@@ -816,11 +847,7 @@ static void eeepc_rfkill_exit(struct eeepc_laptop *eeepc) | |||
816 | rfkill_destroy(eeepc->wlan_rfkill); | 847 | rfkill_destroy(eeepc->wlan_rfkill); |
817 | eeepc->wlan_rfkill = NULL; | 848 | eeepc->wlan_rfkill = NULL; |
818 | } | 849 | } |
819 | /* | 850 | |
820 | * Refresh pci hotplug in case the rfkill state was changed after | ||
821 | * eeepc_unregister_rfkill_notifier() | ||
822 | */ | ||
823 | eeepc_rfkill_hotplug(eeepc); | ||
824 | if (eeepc->hotplug_slot) | 851 | if (eeepc->hotplug_slot) |
825 | pci_hp_deregister(eeepc->hotplug_slot); | 852 | pci_hp_deregister(eeepc->hotplug_slot); |
826 | 853 | ||
@@ -889,11 +916,6 @@ static int eeepc_rfkill_init(struct eeepc_laptop *eeepc) | |||
889 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); | 916 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P5"); |
890 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); | 917 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P6"); |
891 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); | 918 | eeepc_register_rfkill_notifier(eeepc, "\\_SB.PCI0.P0P7"); |
892 | /* | ||
893 | * Refresh pci hotplug in case the rfkill state was changed during | ||
894 | * setup. | ||
895 | */ | ||
896 | eeepc_rfkill_hotplug(eeepc); | ||
897 | 919 | ||
898 | exit: | 920 | exit: |
899 | if (result && result != -ENODEV) | 921 | if (result && result != -ENODEV) |
@@ -928,8 +950,11 @@ static int eeepc_hotk_restore(struct device *device) | |||
928 | struct eeepc_laptop *eeepc = dev_get_drvdata(device); | 950 | struct eeepc_laptop *eeepc = dev_get_drvdata(device); |
929 | 951 | ||
930 | /* Refresh both wlan rfkill state and pci hotplug */ | 952 | /* Refresh both wlan rfkill state and pci hotplug */ |
931 | if (eeepc->wlan_rfkill) | 953 | if (eeepc->wlan_rfkill) { |
932 | eeepc_rfkill_hotplug(eeepc); | 954 | eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P5"); |
955 | eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P6"); | ||
956 | eeepc_rfkill_hotplug_update(eeepc, "\\_SB.PCI0.P0P7"); | ||
957 | } | ||
933 | 958 | ||
934 | if (eeepc->bluetooth_rfkill) | 959 | if (eeepc->bluetooth_rfkill) |
935 | rfkill_set_sw_state(eeepc->bluetooth_rfkill, | 960 | rfkill_set_sw_state(eeepc->bluetooth_rfkill, |
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 0ddc434fb93b..649dcadd8ea3 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -67,9 +67,11 @@ static const struct key_entry eeepc_wmi_keymap[] = { | |||
67 | { KE_KEY, 0x82, { KEY_CAMERA } }, | 67 | { KE_KEY, 0x82, { KEY_CAMERA } }, |
68 | { KE_KEY, 0x83, { KEY_CAMERA_ZOOMIN } }, | 68 | { KE_KEY, 0x83, { KEY_CAMERA_ZOOMIN } }, |
69 | { KE_KEY, 0x88, { KEY_WLAN } }, | 69 | { KE_KEY, 0x88, { KEY_WLAN } }, |
70 | { KE_KEY, 0xbd, { KEY_CAMERA } }, | ||
70 | { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } }, | 71 | { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } }, |
71 | { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */ | 72 | { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */ |
72 | { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */ | 73 | { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */ |
74 | { KE_KEY, 0xe8, { KEY_SCREENLOCK } }, | ||
73 | { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } }, | 75 | { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } }, |
74 | { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } }, | 76 | { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } }, |
75 | { KE_KEY, 0xec, { KEY_CAMERA_UP } }, | 77 | { KE_KEY, 0xec, { KEY_CAMERA_UP } }, |
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c index d653104b59cb..464bb3fc4d88 100644 --- a/drivers/platform/x86/intel_pmic_gpio.c +++ b/drivers/platform/x86/intel_pmic_gpio.c | |||
@@ -74,6 +74,19 @@ struct pmic_gpio { | |||
74 | u32 trigger_type; | 74 | u32 trigger_type; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static void pmic_program_irqtype(int gpio, int type) | ||
78 | { | ||
79 | if (type & IRQ_TYPE_EDGE_RISING) | ||
80 | intel_scu_ipc_update_register(GPIO0 + gpio, 0x20, 0x20); | ||
81 | else | ||
82 | intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x20); | ||
83 | |||
84 | if (type & IRQ_TYPE_EDGE_FALLING) | ||
85 | intel_scu_ipc_update_register(GPIO0 + gpio, 0x10, 0x10); | ||
86 | else | ||
87 | intel_scu_ipc_update_register(GPIO0 + gpio, 0x00, 0x10); | ||
88 | }; | ||
89 | |||
77 | static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 90 | static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
78 | { | 91 | { |
79 | if (offset > 8) { | 92 | if (offset > 8) { |
@@ -166,16 +179,38 @@ static int pmic_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | |||
166 | return pg->irq_base + offset; | 179 | return pg->irq_base + offset; |
167 | } | 180 | } |
168 | 181 | ||
182 | static void pmic_bus_lock(struct irq_data *data) | ||
183 | { | ||
184 | struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); | ||
185 | |||
186 | mutex_lock(&pg->buslock); | ||
187 | } | ||
188 | |||
189 | static void pmic_bus_sync_unlock(struct irq_data *data) | ||
190 | { | ||
191 | struct pmic_gpio *pg = irq_data_get_irq_chip_data(data); | ||
192 | |||
193 | if (pg->update_type) { | ||
194 | unsigned int gpio = pg->update_type & ~GPIO_UPDATE_TYPE; | ||
195 | |||
196 | pmic_program_irqtype(gpio, pg->trigger_type); | ||
197 | pg->update_type = 0; | ||
198 | } | ||
199 | mutex_unlock(&pg->buslock); | ||
200 | } | ||
201 | |||
169 | /* the gpiointr register is read-clear, so just do nothing. */ | 202 | /* the gpiointr register is read-clear, so just do nothing. */ |
170 | static void pmic_irq_unmask(struct irq_data *data) { } | 203 | static void pmic_irq_unmask(struct irq_data *data) { } |
171 | 204 | ||
172 | static void pmic_irq_mask(struct irq_data *data) { } | 205 | static void pmic_irq_mask(struct irq_data *data) { } |
173 | 206 | ||
174 | static struct irq_chip pmic_irqchip = { | 207 | static struct irq_chip pmic_irqchip = { |
175 | .name = "PMIC-GPIO", | 208 | .name = "PMIC-GPIO", |
176 | .irq_mask = pmic_irq_mask, | 209 | .irq_mask = pmic_irq_mask, |
177 | .irq_unmask = pmic_irq_unmask, | 210 | .irq_unmask = pmic_irq_unmask, |
178 | .irq_set_type = pmic_irq_type, | 211 | .irq_set_type = pmic_irq_type, |
212 | .irq_bus_lock = pmic_bus_lock, | ||
213 | .irq_bus_sync_unlock = pmic_bus_sync_unlock, | ||
179 | }; | 214 | }; |
180 | 215 | ||
181 | static irqreturn_t pmic_irq_handler(int irq, void *data) | 216 | static irqreturn_t pmic_irq_handler(int irq, void *data) |
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index de434c6dc2d6..d347116d150e 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c | |||
@@ -571,6 +571,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { | |||
571 | .callback = dmi_check_cb, | 571 | .callback = dmi_check_cb, |
572 | }, | 572 | }, |
573 | { | 573 | { |
574 | .ident = "R410 Plus", | ||
575 | .matches = { | ||
576 | DMI_MATCH(DMI_SYS_VENDOR, | ||
577 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
578 | DMI_MATCH(DMI_PRODUCT_NAME, "R410P"), | ||
579 | DMI_MATCH(DMI_BOARD_NAME, "R460"), | ||
580 | }, | ||
581 | .callback = dmi_check_cb, | ||
582 | }, | ||
583 | { | ||
574 | .ident = "R518", | 584 | .ident = "R518", |
575 | .matches = { | 585 | .matches = { |
576 | DMI_MATCH(DMI_SYS_VENDOR, | 586 | DMI_MATCH(DMI_SYS_VENDOR, |
@@ -591,12 +601,12 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { | |||
591 | .callback = dmi_check_cb, | 601 | .callback = dmi_check_cb, |
592 | }, | 602 | }, |
593 | { | 603 | { |
594 | .ident = "N150/N210/N220", | 604 | .ident = "N150/N210/N220/N230", |
595 | .matches = { | 605 | .matches = { |
596 | DMI_MATCH(DMI_SYS_VENDOR, | 606 | DMI_MATCH(DMI_SYS_VENDOR, |
597 | "SAMSUNG ELECTRONICS CO., LTD."), | 607 | "SAMSUNG ELECTRONICS CO., LTD."), |
598 | DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), | 608 | DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"), |
599 | DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), | 609 | DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"), |
600 | }, | 610 | }, |
601 | .callback = dmi_check_cb, | 611 | .callback = dmi_check_cb, |
602 | }, | 612 | }, |
@@ -771,6 +781,7 @@ static int __init samsung_init(void) | |||
771 | 781 | ||
772 | /* create a backlight device to talk to this one */ | 782 | /* create a backlight device to talk to this one */ |
773 | memset(&props, 0, sizeof(struct backlight_properties)); | 783 | memset(&props, 0, sizeof(struct backlight_properties)); |
784 | props.type = BACKLIGHT_PLATFORM; | ||
774 | props.max_brightness = sabi_config->max_brightness; | 785 | props.max_brightness = sabi_config->max_brightness; |
775 | backlight_device = backlight_device_register("samsung", &sdev->dev, | 786 | backlight_device = backlight_device_register("samsung", &sdev->dev, |
776 | NULL, &backlight_ops, | 787 | NULL, &backlight_ops, |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index e642f5f29504..6fe8cd6e23b5 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -138,6 +138,8 @@ MODULE_PARM_DESC(kbd_backlight_timeout, | |||
138 | "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " | 138 | "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " |
139 | "(default: 0)"); | 139 | "(default: 0)"); |
140 | 140 | ||
141 | static void sony_nc_kbd_backlight_resume(void); | ||
142 | |||
141 | enum sony_nc_rfkill { | 143 | enum sony_nc_rfkill { |
142 | SONY_WIFI, | 144 | SONY_WIFI, |
143 | SONY_BLUETOOTH, | 145 | SONY_BLUETOOTH, |
@@ -771,11 +773,6 @@ static int sony_nc_handles_setup(struct platform_device *pd) | |||
771 | if (!handles) | 773 | if (!handles) |
772 | return -ENOMEM; | 774 | return -ENOMEM; |
773 | 775 | ||
774 | sysfs_attr_init(&handles->devattr.attr); | ||
775 | handles->devattr.attr.name = "handles"; | ||
776 | handles->devattr.attr.mode = S_IRUGO; | ||
777 | handles->devattr.show = sony_nc_handles_show; | ||
778 | |||
779 | for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { | 776 | for (i = 0; i < ARRAY_SIZE(handles->cap); i++) { |
780 | if (!acpi_callsetfunc(sony_nc_acpi_handle, | 777 | if (!acpi_callsetfunc(sony_nc_acpi_handle, |
781 | "SN00", i + 0x20, &result)) { | 778 | "SN00", i + 0x20, &result)) { |
@@ -785,11 +782,18 @@ static int sony_nc_handles_setup(struct platform_device *pd) | |||
785 | } | 782 | } |
786 | } | 783 | } |
787 | 784 | ||
788 | /* allow reading capabilities via sysfs */ | 785 | if (debug) { |
789 | if (device_create_file(&pd->dev, &handles->devattr)) { | 786 | sysfs_attr_init(&handles->devattr.attr); |
790 | kfree(handles); | 787 | handles->devattr.attr.name = "handles"; |
791 | handles = NULL; | 788 | handles->devattr.attr.mode = S_IRUGO; |
792 | return -1; | 789 | handles->devattr.show = sony_nc_handles_show; |
790 | |||
791 | /* allow reading capabilities via sysfs */ | ||
792 | if (device_create_file(&pd->dev, &handles->devattr)) { | ||
793 | kfree(handles); | ||
794 | handles = NULL; | ||
795 | return -1; | ||
796 | } | ||
793 | } | 797 | } |
794 | 798 | ||
795 | return 0; | 799 | return 0; |
@@ -798,7 +802,8 @@ static int sony_nc_handles_setup(struct platform_device *pd) | |||
798 | static int sony_nc_handles_cleanup(struct platform_device *pd) | 802 | static int sony_nc_handles_cleanup(struct platform_device *pd) |
799 | { | 803 | { |
800 | if (handles) { | 804 | if (handles) { |
801 | device_remove_file(&pd->dev, &handles->devattr); | 805 | if (debug) |
806 | device_remove_file(&pd->dev, &handles->devattr); | ||
802 | kfree(handles); | 807 | kfree(handles); |
803 | handles = NULL; | 808 | handles = NULL; |
804 | } | 809 | } |
@@ -808,6 +813,11 @@ static int sony_nc_handles_cleanup(struct platform_device *pd) | |||
808 | static int sony_find_snc_handle(int handle) | 813 | static int sony_find_snc_handle(int handle) |
809 | { | 814 | { |
810 | int i; | 815 | int i; |
816 | |||
817 | /* not initialized yet, return early */ | ||
818 | if (!handles) | ||
819 | return -1; | ||
820 | |||
811 | for (i = 0; i < 0x10; i++) { | 821 | for (i = 0; i < 0x10; i++) { |
812 | if (handles->cap[i] == handle) { | 822 | if (handles->cap[i] == handle) { |
813 | dprintk("found handle 0x%.4x (offset: 0x%.2x)\n", | 823 | dprintk("found handle 0x%.4x (offset: 0x%.2x)\n", |
@@ -924,6 +934,14 @@ static ssize_t sony_nc_sysfs_store(struct device *dev, | |||
924 | /* | 934 | /* |
925 | * Backlight device | 935 | * Backlight device |
926 | */ | 936 | */ |
937 | struct sony_backlight_props { | ||
938 | struct backlight_device *dev; | ||
939 | int handle; | ||
940 | u8 offset; | ||
941 | u8 maxlvl; | ||
942 | }; | ||
943 | struct sony_backlight_props sony_bl_props; | ||
944 | |||
927 | static int sony_backlight_update_status(struct backlight_device *bd) | 945 | static int sony_backlight_update_status(struct backlight_device *bd) |
928 | { | 946 | { |
929 | return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT", | 947 | return acpi_callsetfunc(sony_nc_acpi_handle, "SBRT", |
@@ -944,21 +962,26 @@ static int sony_nc_get_brightness_ng(struct backlight_device *bd) | |||
944 | { | 962 | { |
945 | int result; | 963 | int result; |
946 | int *handle = (int *)bl_get_data(bd); | 964 | int *handle = (int *)bl_get_data(bd); |
965 | struct sony_backlight_props *sdev = | ||
966 | (struct sony_backlight_props *)bl_get_data(bd); | ||
947 | 967 | ||
948 | sony_call_snc_handle(*handle, 0x0200, &result); | 968 | sony_call_snc_handle(sdev->handle, 0x0200, &result); |
949 | 969 | ||
950 | return result & 0xff; | 970 | return (result & 0xff) - sdev->offset; |
951 | } | 971 | } |
952 | 972 | ||
953 | static int sony_nc_update_status_ng(struct backlight_device *bd) | 973 | static int sony_nc_update_status_ng(struct backlight_device *bd) |
954 | { | 974 | { |
955 | int value, result; | 975 | int value, result; |
956 | int *handle = (int *)bl_get_data(bd); | 976 | int *handle = (int *)bl_get_data(bd); |
977 | struct sony_backlight_props *sdev = | ||
978 | (struct sony_backlight_props *)bl_get_data(bd); | ||
957 | 979 | ||
958 | value = bd->props.brightness; | 980 | value = bd->props.brightness + sdev->offset; |
959 | sony_call_snc_handle(*handle, 0x0100 | (value << 16), &result); | 981 | if (sony_call_snc_handle(sdev->handle, 0x0100 | (value << 16), &result)) |
982 | return -EIO; | ||
960 | 983 | ||
961 | return sony_nc_get_brightness_ng(bd); | 984 | return value; |
962 | } | 985 | } |
963 | 986 | ||
964 | static const struct backlight_ops sony_backlight_ops = { | 987 | static const struct backlight_ops sony_backlight_ops = { |
@@ -971,8 +994,6 @@ static const struct backlight_ops sony_backlight_ng_ops = { | |||
971 | .update_status = sony_nc_update_status_ng, | 994 | .update_status = sony_nc_update_status_ng, |
972 | .get_brightness = sony_nc_get_brightness_ng, | 995 | .get_brightness = sony_nc_get_brightness_ng, |
973 | }; | 996 | }; |
974 | static int backlight_ng_handle; | ||
975 | static struct backlight_device *sony_backlight_device; | ||
976 | 997 | ||
977 | /* | 998 | /* |
978 | * New SNC-only Vaios event mapping to driver known keys | 999 | * New SNC-only Vaios event mapping to driver known keys |
@@ -1168,6 +1189,9 @@ static int sony_nc_resume(struct acpi_device *device) | |||
1168 | /* re-read rfkill state */ | 1189 | /* re-read rfkill state */ |
1169 | sony_nc_rfkill_update(); | 1190 | sony_nc_rfkill_update(); |
1170 | 1191 | ||
1192 | /* restore kbd backlight states */ | ||
1193 | sony_nc_kbd_backlight_resume(); | ||
1194 | |||
1171 | return 0; | 1195 | return 0; |
1172 | } | 1196 | } |
1173 | 1197 | ||
@@ -1355,6 +1379,7 @@ out_no_enum: | |||
1355 | #define KBDBL_HANDLER 0x137 | 1379 | #define KBDBL_HANDLER 0x137 |
1356 | #define KBDBL_PRESENT 0xB00 | 1380 | #define KBDBL_PRESENT 0xB00 |
1357 | #define SET_MODE 0xC00 | 1381 | #define SET_MODE 0xC00 |
1382 | #define SET_STATE 0xD00 | ||
1358 | #define SET_TIMEOUT 0xE00 | 1383 | #define SET_TIMEOUT 0xE00 |
1359 | 1384 | ||
1360 | struct kbd_backlight { | 1385 | struct kbd_backlight { |
@@ -1377,6 +1402,10 @@ static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value) | |||
1377 | (value << 0x10) | SET_MODE, &result)) | 1402 | (value << 0x10) | SET_MODE, &result)) |
1378 | return -EIO; | 1403 | return -EIO; |
1379 | 1404 | ||
1405 | /* Try to turn the light on/off immediately */ | ||
1406 | sony_call_snc_handle(KBDBL_HANDLER, (value << 0x10) | SET_STATE, | ||
1407 | &result); | ||
1408 | |||
1380 | kbdbl_handle->mode = value; | 1409 | kbdbl_handle->mode = value; |
1381 | 1410 | ||
1382 | return 0; | 1411 | return 0; |
@@ -1458,7 +1487,7 @@ static int sony_nc_kbd_backlight_setup(struct platform_device *pd) | |||
1458 | { | 1487 | { |
1459 | int result; | 1488 | int result; |
1460 | 1489 | ||
1461 | if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result)) | 1490 | if (sony_call_snc_handle(KBDBL_HANDLER, KBDBL_PRESENT, &result)) |
1462 | return 0; | 1491 | return 0; |
1463 | if (!(result & 0x02)) | 1492 | if (!(result & 0x02)) |
1464 | return 0; | 1493 | return 0; |
@@ -1501,13 +1530,105 @@ outkzalloc: | |||
1501 | static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd) | 1530 | static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd) |
1502 | { | 1531 | { |
1503 | if (kbdbl_handle) { | 1532 | if (kbdbl_handle) { |
1533 | int result; | ||
1534 | |||
1504 | device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); | 1535 | device_remove_file(&pd->dev, &kbdbl_handle->mode_attr); |
1505 | device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr); | 1536 | device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr); |
1537 | |||
1538 | /* restore the default hw behaviour */ | ||
1539 | sony_call_snc_handle(KBDBL_HANDLER, 0x1000 | SET_MODE, &result); | ||
1540 | sony_call_snc_handle(KBDBL_HANDLER, SET_TIMEOUT, &result); | ||
1541 | |||
1506 | kfree(kbdbl_handle); | 1542 | kfree(kbdbl_handle); |
1507 | } | 1543 | } |
1508 | return 0; | 1544 | return 0; |
1509 | } | 1545 | } |
1510 | 1546 | ||
1547 | static void sony_nc_kbd_backlight_resume(void) | ||
1548 | { | ||
1549 | int ignore = 0; | ||
1550 | |||
1551 | if (!kbdbl_handle) | ||
1552 | return; | ||
1553 | |||
1554 | if (kbdbl_handle->mode == 0) | ||
1555 | sony_call_snc_handle(KBDBL_HANDLER, SET_MODE, &ignore); | ||
1556 | |||
1557 | if (kbdbl_handle->timeout != 0) | ||
1558 | sony_call_snc_handle(KBDBL_HANDLER, | ||
1559 | (kbdbl_handle->timeout << 0x10) | SET_TIMEOUT, | ||
1560 | &ignore); | ||
1561 | } | ||
1562 | |||
1563 | static void sony_nc_backlight_ng_read_limits(int handle, | ||
1564 | struct sony_backlight_props *props) | ||
1565 | { | ||
1566 | int offset; | ||
1567 | acpi_status status; | ||
1568 | u8 brlvl, i; | ||
1569 | u8 min = 0xff, max = 0x00; | ||
1570 | struct acpi_object_list params; | ||
1571 | union acpi_object in_obj; | ||
1572 | union acpi_object *lvl_enum; | ||
1573 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
1574 | |||
1575 | props->handle = handle; | ||
1576 | props->offset = 0; | ||
1577 | props->maxlvl = 0xff; | ||
1578 | |||
1579 | offset = sony_find_snc_handle(handle); | ||
1580 | if (offset < 0) | ||
1581 | return; | ||
1582 | |||
1583 | /* try to read the boundaries from ACPI tables, if we fail the above | ||
1584 | * defaults should be reasonable | ||
1585 | */ | ||
1586 | params.count = 1; | ||
1587 | params.pointer = &in_obj; | ||
1588 | in_obj.type = ACPI_TYPE_INTEGER; | ||
1589 | in_obj.integer.value = offset; | ||
1590 | status = acpi_evaluate_object(sony_nc_acpi_handle, "SN06", ¶ms, | ||
1591 | &buffer); | ||
1592 | if (ACPI_FAILURE(status)) | ||
1593 | return; | ||
1594 | |||
1595 | lvl_enum = (union acpi_object *) buffer.pointer; | ||
1596 | if (!lvl_enum) { | ||
1597 | pr_err("No SN06 return object."); | ||
1598 | return; | ||
1599 | } | ||
1600 | if (lvl_enum->type != ACPI_TYPE_BUFFER) { | ||
1601 | pr_err("Invalid SN06 return object 0x%.2x\n", | ||
1602 | lvl_enum->type); | ||
1603 | goto out_invalid; | ||
1604 | } | ||
1605 | |||
1606 | /* the buffer lists brightness levels available, brightness levels are | ||
1607 | * from 0 to 8 in the array, other values are used by ALS control. | ||
1608 | */ | ||
1609 | for (i = 0; i < 9 && i < lvl_enum->buffer.length; i++) { | ||
1610 | |||
1611 | brlvl = *(lvl_enum->buffer.pointer + i); | ||
1612 | dprintk("Brightness level: %d\n", brlvl); | ||
1613 | |||
1614 | if (!brlvl) | ||
1615 | break; | ||
1616 | |||
1617 | if (brlvl > max) | ||
1618 | max = brlvl; | ||
1619 | if (brlvl < min) | ||
1620 | min = brlvl; | ||
1621 | } | ||
1622 | props->offset = min; | ||
1623 | props->maxlvl = max; | ||
1624 | dprintk("Brightness levels: min=%d max=%d\n", props->offset, | ||
1625 | props->maxlvl); | ||
1626 | |||
1627 | out_invalid: | ||
1628 | kfree(buffer.pointer); | ||
1629 | return; | ||
1630 | } | ||
1631 | |||
1511 | static void sony_nc_backlight_setup(void) | 1632 | static void sony_nc_backlight_setup(void) |
1512 | { | 1633 | { |
1513 | acpi_handle unused; | 1634 | acpi_handle unused; |
@@ -1516,14 +1637,14 @@ static void sony_nc_backlight_setup(void) | |||
1516 | struct backlight_properties props; | 1637 | struct backlight_properties props; |
1517 | 1638 | ||
1518 | if (sony_find_snc_handle(0x12f) != -1) { | 1639 | if (sony_find_snc_handle(0x12f) != -1) { |
1519 | backlight_ng_handle = 0x12f; | ||
1520 | ops = &sony_backlight_ng_ops; | 1640 | ops = &sony_backlight_ng_ops; |
1521 | max_brightness = 0xff; | 1641 | sony_nc_backlight_ng_read_limits(0x12f, &sony_bl_props); |
1642 | max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; | ||
1522 | 1643 | ||
1523 | } else if (sony_find_snc_handle(0x137) != -1) { | 1644 | } else if (sony_find_snc_handle(0x137) != -1) { |
1524 | backlight_ng_handle = 0x137; | ||
1525 | ops = &sony_backlight_ng_ops; | 1645 | ops = &sony_backlight_ng_ops; |
1526 | max_brightness = 0xff; | 1646 | sony_nc_backlight_ng_read_limits(0x137, &sony_bl_props); |
1647 | max_brightness = sony_bl_props.maxlvl - sony_bl_props.offset; | ||
1527 | 1648 | ||
1528 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", | 1649 | } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT", |
1529 | &unused))) { | 1650 | &unused))) { |
@@ -1536,22 +1657,22 @@ static void sony_nc_backlight_setup(void) | |||
1536 | memset(&props, 0, sizeof(struct backlight_properties)); | 1657 | memset(&props, 0, sizeof(struct backlight_properties)); |
1537 | props.type = BACKLIGHT_PLATFORM; | 1658 | props.type = BACKLIGHT_PLATFORM; |
1538 | props.max_brightness = max_brightness; | 1659 | props.max_brightness = max_brightness; |
1539 | sony_backlight_device = backlight_device_register("sony", NULL, | 1660 | sony_bl_props.dev = backlight_device_register("sony", NULL, |
1540 | &backlight_ng_handle, | 1661 | &sony_bl_props, |
1541 | ops, &props); | 1662 | ops, &props); |
1542 | 1663 | ||
1543 | if (IS_ERR(sony_backlight_device)) { | 1664 | if (IS_ERR(sony_bl_props.dev)) { |
1544 | pr_warning(DRV_PFX "unable to register backlight device\n"); | 1665 | pr_warn(DRV_PFX "unable to register backlight device\n"); |
1545 | sony_backlight_device = NULL; | 1666 | sony_bl_props.dev = NULL; |
1546 | } else | 1667 | } else |
1547 | sony_backlight_device->props.brightness = | 1668 | sony_bl_props.dev->props.brightness = |
1548 | ops->get_brightness(sony_backlight_device); | 1669 | ops->get_brightness(sony_bl_props.dev); |
1549 | } | 1670 | } |
1550 | 1671 | ||
1551 | static void sony_nc_backlight_cleanup(void) | 1672 | static void sony_nc_backlight_cleanup(void) |
1552 | { | 1673 | { |
1553 | if (sony_backlight_device) | 1674 | if (sony_bl_props.dev) |
1554 | backlight_device_unregister(sony_backlight_device); | 1675 | backlight_device_unregister(sony_bl_props.dev); |
1555 | } | 1676 | } |
1556 | 1677 | ||
1557 | static int sony_nc_add(struct acpi_device *device) | 1678 | static int sony_nc_add(struct acpi_device *device) |
@@ -2549,7 +2670,7 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, | |||
2549 | mutex_lock(&spic_dev.lock); | 2670 | mutex_lock(&spic_dev.lock); |
2550 | switch (cmd) { | 2671 | switch (cmd) { |
2551 | case SONYPI_IOCGBRT: | 2672 | case SONYPI_IOCGBRT: |
2552 | if (sony_backlight_device == NULL) { | 2673 | if (sony_bl_props.dev == NULL) { |
2553 | ret = -EIO; | 2674 | ret = -EIO; |
2554 | break; | 2675 | break; |
2555 | } | 2676 | } |
@@ -2562,7 +2683,7 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, | |||
2562 | ret = -EFAULT; | 2683 | ret = -EFAULT; |
2563 | break; | 2684 | break; |
2564 | case SONYPI_IOCSBRT: | 2685 | case SONYPI_IOCSBRT: |
2565 | if (sony_backlight_device == NULL) { | 2686 | if (sony_bl_props.dev == NULL) { |
2566 | ret = -EIO; | 2687 | ret = -EIO; |
2567 | break; | 2688 | break; |
2568 | } | 2689 | } |
@@ -2576,8 +2697,8 @@ static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd, | |||
2576 | break; | 2697 | break; |
2577 | } | 2698 | } |
2578 | /* sync the backlight device status */ | 2699 | /* sync the backlight device status */ |
2579 | sony_backlight_device->props.brightness = | 2700 | sony_bl_props.dev->props.brightness = |
2580 | sony_backlight_get_brightness(sony_backlight_device); | 2701 | sony_backlight_get_brightness(sony_bl_props.dev); |
2581 | break; | 2702 | break; |
2582 | case SONYPI_IOCGBAT1CAP: | 2703 | case SONYPI_IOCGBAT1CAP: |
2583 | if (ec_read16(SONYPI_BAT1_FULL, &val16)) { | 2704 | if (ec_read16(SONYPI_BAT1_FULL, &val16)) { |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index a08561f5349e..562fcf0dd2b5 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -128,7 +128,8 @@ enum { | |||
128 | }; | 128 | }; |
129 | 129 | ||
130 | /* ACPI HIDs */ | 130 | /* ACPI HIDs */ |
131 | #define TPACPI_ACPI_HKEY_HID "IBM0068" | 131 | #define TPACPI_ACPI_IBM_HKEY_HID "IBM0068" |
132 | #define TPACPI_ACPI_LENOVO_HKEY_HID "LEN0068" | ||
132 | #define TPACPI_ACPI_EC_HID "PNP0C09" | 133 | #define TPACPI_ACPI_EC_HID "PNP0C09" |
133 | 134 | ||
134 | /* Input IDs */ | 135 | /* Input IDs */ |
@@ -3879,7 +3880,8 @@ errexit: | |||
3879 | } | 3880 | } |
3880 | 3881 | ||
3881 | static const struct acpi_device_id ibm_htk_device_ids[] = { | 3882 | static const struct acpi_device_id ibm_htk_device_ids[] = { |
3882 | {TPACPI_ACPI_HKEY_HID, 0}, | 3883 | {TPACPI_ACPI_IBM_HKEY_HID, 0}, |
3884 | {TPACPI_ACPI_LENOVO_HKEY_HID, 0}, | ||
3883 | {"", 0}, | 3885 | {"", 0}, |
3884 | }; | 3886 | }; |
3885 | 3887 | ||
@@ -8618,8 +8620,7 @@ static bool __pure __init tpacpi_is_valid_fw_id(const char* const s, | |||
8618 | tpacpi_is_fw_digit(s[1]) && | 8620 | tpacpi_is_fw_digit(s[1]) && |
8619 | s[2] == t && s[3] == 'T' && | 8621 | s[2] == t && s[3] == 'T' && |
8620 | tpacpi_is_fw_digit(s[4]) && | 8622 | tpacpi_is_fw_digit(s[4]) && |
8621 | tpacpi_is_fw_digit(s[5]) && | 8623 | tpacpi_is_fw_digit(s[5]); |
8622 | s[6] == 'W' && s[7] == 'W'; | ||
8623 | } | 8624 | } |
8624 | 8625 | ||
8625 | /* returns 0 - probe ok, or < 0 - probe error. | 8626 | /* returns 0 - probe ok, or < 0 - probe error. |
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index c29719cacbca..86c9a091a2ff 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -1171,16 +1171,17 @@ static int rio_hdid_setup(char *str) | |||
1171 | 1171 | ||
1172 | __setup("riohdid=", rio_hdid_setup); | 1172 | __setup("riohdid=", rio_hdid_setup); |
1173 | 1173 | ||
1174 | void rio_register_mport(struct rio_mport *port) | 1174 | int rio_register_mport(struct rio_mport *port) |
1175 | { | 1175 | { |
1176 | if (next_portid >= RIO_MAX_MPORTS) { | 1176 | if (next_portid >= RIO_MAX_MPORTS) { |
1177 | pr_err("RIO: reached specified max number of mports\n"); | 1177 | pr_err("RIO: reached specified max number of mports\n"); |
1178 | return; | 1178 | return 1; |
1179 | } | 1179 | } |
1180 | 1180 | ||
1181 | port->id = next_portid++; | 1181 | port->id = next_portid++; |
1182 | port->host_deviceid = rio_get_hdid(port->id); | 1182 | port->host_deviceid = rio_get_hdid(port->id); |
1183 | list_add_tail(&port->node, &rio_mports); | 1183 | list_add_tail(&port->node, &rio_mports); |
1184 | return 0; | ||
1184 | } | 1185 | } |
1185 | 1186 | ||
1186 | EXPORT_SYMBOL_GPL(rio_local_get_device_id); | 1187 | EXPORT_SYMBOL_GPL(rio_local_get_device_id); |
diff --git a/drivers/rapidio/switches/idt_gen2.c b/drivers/rapidio/switches/idt_gen2.c index 095016a9dec1..ac2701b22e71 100644 --- a/drivers/rapidio/switches/idt_gen2.c +++ b/drivers/rapidio/switches/idt_gen2.c | |||
@@ -418,3 +418,4 @@ DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1848, idtg2_switch_init); | |||
418 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init); | 418 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1616, idtg2_switch_init); |
419 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTVPS1616, idtg2_switch_init); | 419 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTVPS1616, idtg2_switch_init); |
420 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTSPS1616, idtg2_switch_init); | 420 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTSPS1616, idtg2_switch_init); |
421 | DECLARE_RIO_SWITCH_INIT(RIO_VID_IDT, RIO_DID_IDTCPS1432, idtg2_switch_init); | ||
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 09b4437b3e61..39013867cbd6 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c | |||
@@ -171,7 +171,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, | |||
171 | err = __rtc_read_alarm(rtc, &alrm); | 171 | err = __rtc_read_alarm(rtc, &alrm); |
172 | 172 | ||
173 | if (!err && !rtc_valid_tm(&alrm.time)) | 173 | if (!err && !rtc_valid_tm(&alrm.time)) |
174 | rtc_set_alarm(rtc, &alrm); | 174 | rtc_initialize_alarm(rtc, &alrm); |
175 | 175 | ||
176 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); | 176 | strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); |
177 | dev_set_name(&rtc->dev, "rtc%d", id); | 177 | dev_set_name(&rtc->dev, "rtc%d", id); |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 23719f0acbf6..ef6316acec43 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -375,6 +375,32 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | |||
375 | } | 375 | } |
376 | EXPORT_SYMBOL_GPL(rtc_set_alarm); | 376 | EXPORT_SYMBOL_GPL(rtc_set_alarm); |
377 | 377 | ||
378 | /* Called once per device from rtc_device_register */ | ||
379 | int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) | ||
380 | { | ||
381 | int err; | ||
382 | |||
383 | err = rtc_valid_tm(&alarm->time); | ||
384 | if (err != 0) | ||
385 | return err; | ||
386 | |||
387 | err = mutex_lock_interruptible(&rtc->ops_lock); | ||
388 | if (err) | ||
389 | return err; | ||
390 | |||
391 | rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); | ||
392 | rtc->aie_timer.period = ktime_set(0, 0); | ||
393 | if (alarm->enabled) { | ||
394 | rtc->aie_timer.enabled = 1; | ||
395 | timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); | ||
396 | } | ||
397 | mutex_unlock(&rtc->ops_lock); | ||
398 | return err; | ||
399 | } | ||
400 | EXPORT_SYMBOL_GPL(rtc_initialize_alarm); | ||
401 | |||
402 | |||
403 | |||
378 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) | 404 | int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) |
379 | { | 405 | { |
380 | int err = mutex_lock_interruptible(&rtc->ops_lock); | 406 | int err = mutex_lock_interruptible(&rtc->ops_lock); |
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index a0fc4cf42abf..90d866272c8e 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -250,6 +250,8 @@ static int bfin_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) | |||
250 | bfin_rtc_int_set_alarm(rtc); | 250 | bfin_rtc_int_set_alarm(rtc); |
251 | else | 251 | else |
252 | bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | 252 | bfin_rtc_int_clear(~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); |
253 | |||
254 | return 0; | ||
253 | } | 255 | } |
254 | 256 | ||
255 | static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) | 257 | static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) |
diff --git a/drivers/rtc/rtc-coh901331.c b/drivers/rtc/rtc-coh901331.c index 316f484999b5..80f9c88214c5 100644 --- a/drivers/rtc/rtc-coh901331.c +++ b/drivers/rtc/rtc-coh901331.c | |||
@@ -220,6 +220,7 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
220 | } | 220 | } |
221 | clk_disable(rtap->clk); | 221 | clk_disable(rtap->clk); |
222 | 222 | ||
223 | platform_set_drvdata(pdev, rtap); | ||
223 | rtap->rtc = rtc_device_register("coh901331", &pdev->dev, &coh901331_ops, | 224 | rtap->rtc = rtc_device_register("coh901331", &pdev->dev, &coh901331_ops, |
224 | THIS_MODULE); | 225 | THIS_MODULE); |
225 | if (IS_ERR(rtap->rtc)) { | 226 | if (IS_ERR(rtap->rtc)) { |
@@ -227,11 +228,10 @@ static int __init coh901331_probe(struct platform_device *pdev) | |||
227 | goto out_no_rtc; | 228 | goto out_no_rtc; |
228 | } | 229 | } |
229 | 230 | ||
230 | platform_set_drvdata(pdev, rtap); | ||
231 | |||
232 | return 0; | 231 | return 0; |
233 | 232 | ||
234 | out_no_rtc: | 233 | out_no_rtc: |
234 | platform_set_drvdata(pdev, NULL); | ||
235 | out_no_clk_enable: | 235 | out_no_clk_enable: |
236 | clk_put(rtap->clk); | 236 | clk_put(rtap->clk); |
237 | out_no_clk: | 237 | out_no_clk: |
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index 174036dda786..20494b5edc3c 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c | |||
@@ -257,6 +257,8 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) | |||
257 | goto out_irq; | 257 | goto out_irq; |
258 | } | 258 | } |
259 | 259 | ||
260 | dev_set_drvdata(&pdev->dev, info); | ||
261 | |||
260 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, | 262 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, |
261 | &max8925_rtc_ops, THIS_MODULE); | 263 | &max8925_rtc_ops, THIS_MODULE); |
262 | ret = PTR_ERR(info->rtc_dev); | 264 | ret = PTR_ERR(info->rtc_dev); |
@@ -265,7 +267,6 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) | |||
265 | goto out_rtc; | 267 | goto out_rtc; |
266 | } | 268 | } |
267 | 269 | ||
268 | dev_set_drvdata(&pdev->dev, info); | ||
269 | platform_set_drvdata(pdev, info); | 270 | platform_set_drvdata(pdev, info); |
270 | 271 | ||
271 | return 0; | 272 | return 0; |
diff --git a/drivers/rtc/rtc-mc13xxx.c b/drivers/rtc/rtc-mc13xxx.c index c42006469559..c5ac03793e79 100644 --- a/drivers/rtc/rtc-mc13xxx.c +++ b/drivers/rtc/rtc-mc13xxx.c | |||
@@ -401,6 +401,7 @@ const struct platform_device_id mc13xxx_rtc_idtable[] = { | |||
401 | }, { | 401 | }, { |
402 | .name = "mc13892-rtc", | 402 | .name = "mc13892-rtc", |
403 | }, | 403 | }, |
404 | { } | ||
404 | }; | 405 | }; |
405 | 406 | ||
406 | static struct platform_driver mc13xxx_rtc_driver = { | 407 | static struct platform_driver mc13xxx_rtc_driver = { |
diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c index de0dd7b1f146..bcae8dd41496 100644 --- a/drivers/rtc/rtc-omap.c +++ b/drivers/rtc/rtc-omap.c | |||
@@ -394,7 +394,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) | |||
394 | return 0; | 394 | return 0; |
395 | 395 | ||
396 | fail2: | 396 | fail2: |
397 | free_irq(omap_rtc_timer, NULL); | 397 | free_irq(omap_rtc_timer, rtc); |
398 | fail1: | 398 | fail1: |
399 | rtc_device_unregister(rtc); | 399 | rtc_device_unregister(rtc); |
400 | fail0: | 400 | fail0: |
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index 714964913e5e..b3466c491cd3 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -336,7 +336,6 @@ static void s3c_rtc_release(struct device *dev) | |||
336 | 336 | ||
337 | /* do not clear AIE here, it may be needed for wake */ | 337 | /* do not clear AIE here, it may be needed for wake */ |
338 | 338 | ||
339 | s3c_rtc_setpie(dev, 0); | ||
340 | free_irq(s3c_rtc_alarmno, rtc_dev); | 339 | free_irq(s3c_rtc_alarmno, rtc_dev); |
341 | free_irq(s3c_rtc_tickno, rtc_dev); | 340 | free_irq(s3c_rtc_tickno, rtc_dev); |
342 | } | 341 | } |
@@ -408,7 +407,6 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev) | |||
408 | platform_set_drvdata(dev, NULL); | 407 | platform_set_drvdata(dev, NULL); |
409 | rtc_device_unregister(rtc); | 408 | rtc_device_unregister(rtc); |
410 | 409 | ||
411 | s3c_rtc_setpie(&dev->dev, 0); | ||
412 | s3c_rtc_setaie(&dev->dev, 0); | 410 | s3c_rtc_setaie(&dev->dev, 0); |
413 | 411 | ||
414 | clk_disable(rtc_clk); | 412 | clk_disable(rtc_clk); |
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 4d2df2f76ea0..475e603fc584 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2314,15 +2314,14 @@ static void dasd_flush_request_queue(struct dasd_block *block) | |||
2314 | 2314 | ||
2315 | static int dasd_open(struct block_device *bdev, fmode_t mode) | 2315 | static int dasd_open(struct block_device *bdev, fmode_t mode) |
2316 | { | 2316 | { |
2317 | struct dasd_block *block = bdev->bd_disk->private_data; | ||
2318 | struct dasd_device *base; | 2317 | struct dasd_device *base; |
2319 | int rc; | 2318 | int rc; |
2320 | 2319 | ||
2321 | if (!block) | 2320 | base = dasd_device_from_gendisk(bdev->bd_disk); |
2321 | if (!base) | ||
2322 | return -ENODEV; | 2322 | return -ENODEV; |
2323 | 2323 | ||
2324 | base = block->base; | 2324 | atomic_inc(&base->block->open_count); |
2325 | atomic_inc(&block->open_count); | ||
2326 | if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { | 2325 | if (test_bit(DASD_FLAG_OFFLINE, &base->flags)) { |
2327 | rc = -ENODEV; | 2326 | rc = -ENODEV; |
2328 | goto unlock; | 2327 | goto unlock; |
@@ -2355,21 +2354,28 @@ static int dasd_open(struct block_device *bdev, fmode_t mode) | |||
2355 | goto out; | 2354 | goto out; |
2356 | } | 2355 | } |
2357 | 2356 | ||
2357 | dasd_put_device(base); | ||
2358 | return 0; | 2358 | return 0; |
2359 | 2359 | ||
2360 | out: | 2360 | out: |
2361 | module_put(base->discipline->owner); | 2361 | module_put(base->discipline->owner); |
2362 | unlock: | 2362 | unlock: |
2363 | atomic_dec(&block->open_count); | 2363 | atomic_dec(&base->block->open_count); |
2364 | dasd_put_device(base); | ||
2364 | return rc; | 2365 | return rc; |
2365 | } | 2366 | } |
2366 | 2367 | ||
2367 | static int dasd_release(struct gendisk *disk, fmode_t mode) | 2368 | static int dasd_release(struct gendisk *disk, fmode_t mode) |
2368 | { | 2369 | { |
2369 | struct dasd_block *block = disk->private_data; | 2370 | struct dasd_device *base; |
2370 | 2371 | ||
2371 | atomic_dec(&block->open_count); | 2372 | base = dasd_device_from_gendisk(disk); |
2372 | module_put(block->base->discipline->owner); | 2373 | if (!base) |
2374 | return -ENODEV; | ||
2375 | |||
2376 | atomic_dec(&base->block->open_count); | ||
2377 | module_put(base->discipline->owner); | ||
2378 | dasd_put_device(base); | ||
2373 | return 0; | 2379 | return 0; |
2374 | } | 2380 | } |
2375 | 2381 | ||
@@ -2378,20 +2384,20 @@ static int dasd_release(struct gendisk *disk, fmode_t mode) | |||
2378 | */ | 2384 | */ |
2379 | static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | 2385 | static int dasd_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
2380 | { | 2386 | { |
2381 | struct dasd_block *block; | ||
2382 | struct dasd_device *base; | 2387 | struct dasd_device *base; |
2383 | 2388 | ||
2384 | block = bdev->bd_disk->private_data; | 2389 | base = dasd_device_from_gendisk(bdev->bd_disk); |
2385 | if (!block) | 2390 | if (!base) |
2386 | return -ENODEV; | 2391 | return -ENODEV; |
2387 | base = block->base; | ||
2388 | 2392 | ||
2389 | if (!base->discipline || | 2393 | if (!base->discipline || |
2390 | !base->discipline->fill_geometry) | 2394 | !base->discipline->fill_geometry) { |
2395 | dasd_put_device(base); | ||
2391 | return -EINVAL; | 2396 | return -EINVAL; |
2392 | 2397 | } | |
2393 | base->discipline->fill_geometry(block, geo); | 2398 | base->discipline->fill_geometry(base->block, geo); |
2394 | geo->start = get_start_sect(bdev) >> block->s2b_shift; | 2399 | geo->start = get_start_sect(bdev) >> base->block->s2b_shift; |
2400 | dasd_put_device(base); | ||
2395 | return 0; | 2401 | return 0; |
2396 | } | 2402 | } |
2397 | 2403 | ||
@@ -2528,7 +2534,6 @@ void dasd_generic_remove(struct ccw_device *cdev) | |||
2528 | dasd_set_target_state(device, DASD_STATE_NEW); | 2534 | dasd_set_target_state(device, DASD_STATE_NEW); |
2529 | /* dasd_delete_device destroys the device reference. */ | 2535 | /* dasd_delete_device destroys the device reference. */ |
2530 | block = device->block; | 2536 | block = device->block; |
2531 | device->block = NULL; | ||
2532 | dasd_delete_device(device); | 2537 | dasd_delete_device(device); |
2533 | /* | 2538 | /* |
2534 | * life cycle of block is bound to device, so delete it after | 2539 | * life cycle of block is bound to device, so delete it after |
@@ -2650,7 +2655,6 @@ int dasd_generic_set_offline(struct ccw_device *cdev) | |||
2650 | dasd_set_target_state(device, DASD_STATE_NEW); | 2655 | dasd_set_target_state(device, DASD_STATE_NEW); |
2651 | /* dasd_delete_device destroys the device reference. */ | 2656 | /* dasd_delete_device destroys the device reference. */ |
2652 | block = device->block; | 2657 | block = device->block; |
2653 | device->block = NULL; | ||
2654 | dasd_delete_device(device); | 2658 | dasd_delete_device(device); |
2655 | /* | 2659 | /* |
2656 | * life cycle of block is bound to device, so delete it after | 2660 | * life cycle of block is bound to device, so delete it after |
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c index 42e1bf35f689..d71511c7850a 100644 --- a/drivers/s390/block/dasd_devmap.c +++ b/drivers/s390/block/dasd_devmap.c | |||
@@ -674,6 +674,36 @@ dasd_device_from_cdev(struct ccw_device *cdev) | |||
674 | return device; | 674 | return device; |
675 | } | 675 | } |
676 | 676 | ||
677 | void dasd_add_link_to_gendisk(struct gendisk *gdp, struct dasd_device *device) | ||
678 | { | ||
679 | struct dasd_devmap *devmap; | ||
680 | |||
681 | devmap = dasd_find_busid(dev_name(&device->cdev->dev)); | ||
682 | if (IS_ERR(devmap)) | ||
683 | return; | ||
684 | spin_lock(&dasd_devmap_lock); | ||
685 | gdp->private_data = devmap; | ||
686 | spin_unlock(&dasd_devmap_lock); | ||
687 | } | ||
688 | |||
689 | struct dasd_device *dasd_device_from_gendisk(struct gendisk *gdp) | ||
690 | { | ||
691 | struct dasd_device *device; | ||
692 | struct dasd_devmap *devmap; | ||
693 | |||
694 | if (!gdp->private_data) | ||
695 | return NULL; | ||
696 | device = NULL; | ||
697 | spin_lock(&dasd_devmap_lock); | ||
698 | devmap = gdp->private_data; | ||
699 | if (devmap && devmap->device) { | ||
700 | device = devmap->device; | ||
701 | dasd_get_device(device); | ||
702 | } | ||
703 | spin_unlock(&dasd_devmap_lock); | ||
704 | return device; | ||
705 | } | ||
706 | |||
677 | /* | 707 | /* |
678 | * SECTION: files in sysfs | 708 | * SECTION: files in sysfs |
679 | */ | 709 | */ |
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index 29143eda9dd9..85dddb1e4126 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -239,7 +239,6 @@ static void dasd_ext_handler(unsigned int ext_int_code, | |||
239 | addr_t ip; | 239 | addr_t ip; |
240 | int rc; | 240 | int rc; |
241 | 241 | ||
242 | kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; | ||
243 | switch (ext_int_code >> 24) { | 242 | switch (ext_int_code >> 24) { |
244 | case DASD_DIAG_CODE_31BIT: | 243 | case DASD_DIAG_CODE_31BIT: |
245 | ip = (addr_t) param32; | 244 | ip = (addr_t) param32; |
@@ -250,6 +249,7 @@ static void dasd_ext_handler(unsigned int ext_int_code, | |||
250 | default: | 249 | default: |
251 | return; | 250 | return; |
252 | } | 251 | } |
252 | kstat_cpu(smp_processor_id()).irqs[EXTINT_DSD]++; | ||
253 | if (!ip) { /* no intparm: unsolicited interrupt */ | 253 | if (!ip) { /* no intparm: unsolicited interrupt */ |
254 | DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited " | 254 | DBF_EVENT(DBF_NOTICE, "%s", "caught unsolicited " |
255 | "interrupt"); | 255 | "interrupt"); |
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index db8005d9f2fd..3ebdf5f92f8f 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -2037,7 +2037,7 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device, | |||
2037 | return; | 2037 | return; |
2038 | 2038 | ||
2039 | /* summary unit check */ | 2039 | /* summary unit check */ |
2040 | if ((sense[7] == 0x0D) && | 2040 | if ((sense[27] & DASD_SENSE_BIT_0) && (sense[7] == 0x0D) && |
2041 | (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) { | 2041 | (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK)) { |
2042 | dasd_alias_handle_summary_unit_check(device, irb); | 2042 | dasd_alias_handle_summary_unit_check(device, irb); |
2043 | return; | 2043 | return; |
@@ -2053,7 +2053,8 @@ static void dasd_eckd_check_for_device_change(struct dasd_device *device, | |||
2053 | /* loss of device reservation is handled via base devices only | 2053 | /* loss of device reservation is handled via base devices only |
2054 | * as alias devices may be used with several bases | 2054 | * as alias devices may be used with several bases |
2055 | */ | 2055 | */ |
2056 | if (device->block && (sense[7] == 0x3F) && | 2056 | if (device->block && (sense[27] & DASD_SENSE_BIT_0) && |
2057 | (sense[7] == 0x3F) && | ||
2057 | (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) && | 2058 | (scsw_dstat(&irb->scsw) & DEV_STAT_UNIT_CHECK) && |
2058 | test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) { | 2059 | test_bit(DASD_FLAG_IS_RESERVED, &device->flags)) { |
2059 | if (device->features & DASD_FEATURE_FAILONSLCK) | 2060 | if (device->features & DASD_FEATURE_FAILONSLCK) |
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 5505bc07e1e7..19a1ff03d65e 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c | |||
@@ -73,7 +73,7 @@ int dasd_gendisk_alloc(struct dasd_block *block) | |||
73 | if (base->features & DASD_FEATURE_READONLY || | 73 | if (base->features & DASD_FEATURE_READONLY || |
74 | test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) | 74 | test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) |
75 | set_disk_ro(gdp, 1); | 75 | set_disk_ro(gdp, 1); |
76 | gdp->private_data = block; | 76 | dasd_add_link_to_gendisk(gdp, base); |
77 | gdp->queue = block->request_queue; | 77 | gdp->queue = block->request_queue; |
78 | block->gdp = gdp; | 78 | block->gdp = gdp; |
79 | set_capacity(block->gdp, 0); | 79 | set_capacity(block->gdp, 0); |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index df9f6999411d..d1e4f2c1264c 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -686,6 +686,9 @@ struct dasd_device *dasd_device_from_cdev(struct ccw_device *); | |||
686 | struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *); | 686 | struct dasd_device *dasd_device_from_cdev_locked(struct ccw_device *); |
687 | struct dasd_device *dasd_device_from_devindex(int); | 687 | struct dasd_device *dasd_device_from_devindex(int); |
688 | 688 | ||
689 | void dasd_add_link_to_gendisk(struct gendisk *, struct dasd_device *); | ||
690 | struct dasd_device *dasd_device_from_gendisk(struct gendisk *); | ||
691 | |||
689 | int dasd_parse(void); | 692 | int dasd_parse(void); |
690 | int dasd_busid_known(const char *); | 693 | int dasd_busid_known(const char *); |
691 | 694 | ||
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index 26075e95b1ba..72261e4c516d 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -42,16 +42,22 @@ dasd_ioctl_api_version(void __user *argp) | |||
42 | static int | 42 | static int |
43 | dasd_ioctl_enable(struct block_device *bdev) | 43 | dasd_ioctl_enable(struct block_device *bdev) |
44 | { | 44 | { |
45 | struct dasd_block *block = bdev->bd_disk->private_data; | 45 | struct dasd_device *base; |
46 | 46 | ||
47 | if (!capable(CAP_SYS_ADMIN)) | 47 | if (!capable(CAP_SYS_ADMIN)) |
48 | return -EACCES; | 48 | return -EACCES; |
49 | 49 | ||
50 | dasd_enable_device(block->base); | 50 | base = dasd_device_from_gendisk(bdev->bd_disk); |
51 | if (!base) | ||
52 | return -ENODEV; | ||
53 | |||
54 | dasd_enable_device(base); | ||
51 | /* Formatting the dasd device can change the capacity. */ | 55 | /* Formatting the dasd device can change the capacity. */ |
52 | mutex_lock(&bdev->bd_mutex); | 56 | mutex_lock(&bdev->bd_mutex); |
53 | i_size_write(bdev->bd_inode, (loff_t)get_capacity(block->gdp) << 9); | 57 | i_size_write(bdev->bd_inode, |
58 | (loff_t)get_capacity(base->block->gdp) << 9); | ||
54 | mutex_unlock(&bdev->bd_mutex); | 59 | mutex_unlock(&bdev->bd_mutex); |
60 | dasd_put_device(base); | ||
55 | return 0; | 61 | return 0; |
56 | } | 62 | } |
57 | 63 | ||
@@ -62,11 +68,14 @@ dasd_ioctl_enable(struct block_device *bdev) | |||
62 | static int | 68 | static int |
63 | dasd_ioctl_disable(struct block_device *bdev) | 69 | dasd_ioctl_disable(struct block_device *bdev) |
64 | { | 70 | { |
65 | struct dasd_block *block = bdev->bd_disk->private_data; | 71 | struct dasd_device *base; |
66 | 72 | ||
67 | if (!capable(CAP_SYS_ADMIN)) | 73 | if (!capable(CAP_SYS_ADMIN)) |
68 | return -EACCES; | 74 | return -EACCES; |
69 | 75 | ||
76 | base = dasd_device_from_gendisk(bdev->bd_disk); | ||
77 | if (!base) | ||
78 | return -ENODEV; | ||
70 | /* | 79 | /* |
71 | * Man this is sick. We don't do a real disable but only downgrade | 80 | * Man this is sick. We don't do a real disable but only downgrade |
72 | * the device to DASD_STATE_BASIC. The reason is that dasdfmt uses | 81 | * the device to DASD_STATE_BASIC. The reason is that dasdfmt uses |
@@ -75,7 +84,7 @@ dasd_ioctl_disable(struct block_device *bdev) | |||
75 | * using the BIODASDFMT ioctl. Therefore the correct state for the | 84 | * using the BIODASDFMT ioctl. Therefore the correct state for the |
76 | * device is DASD_STATE_BASIC that allows to do basic i/o. | 85 | * device is DASD_STATE_BASIC that allows to do basic i/o. |
77 | */ | 86 | */ |
78 | dasd_set_target_state(block->base, DASD_STATE_BASIC); | 87 | dasd_set_target_state(base, DASD_STATE_BASIC); |
79 | /* | 88 | /* |
80 | * Set i_size to zero, since read, write, etc. check against this | 89 | * Set i_size to zero, since read, write, etc. check against this |
81 | * value. | 90 | * value. |
@@ -83,6 +92,7 @@ dasd_ioctl_disable(struct block_device *bdev) | |||
83 | mutex_lock(&bdev->bd_mutex); | 92 | mutex_lock(&bdev->bd_mutex); |
84 | i_size_write(bdev->bd_inode, 0); | 93 | i_size_write(bdev->bd_inode, 0); |
85 | mutex_unlock(&bdev->bd_mutex); | 94 | mutex_unlock(&bdev->bd_mutex); |
95 | dasd_put_device(base); | ||
86 | return 0; | 96 | return 0; |
87 | } | 97 | } |
88 | 98 | ||
@@ -191,26 +201,36 @@ static int dasd_format(struct dasd_block *block, struct format_data_t *fdata) | |||
191 | static int | 201 | static int |
192 | dasd_ioctl_format(struct block_device *bdev, void __user *argp) | 202 | dasd_ioctl_format(struct block_device *bdev, void __user *argp) |
193 | { | 203 | { |
194 | struct dasd_block *block = bdev->bd_disk->private_data; | 204 | struct dasd_device *base; |
195 | struct format_data_t fdata; | 205 | struct format_data_t fdata; |
206 | int rc; | ||
196 | 207 | ||
197 | if (!capable(CAP_SYS_ADMIN)) | 208 | if (!capable(CAP_SYS_ADMIN)) |
198 | return -EACCES; | 209 | return -EACCES; |
199 | if (!argp) | 210 | if (!argp) |
200 | return -EINVAL; | 211 | return -EINVAL; |
201 | 212 | base = dasd_device_from_gendisk(bdev->bd_disk); | |
202 | if (block->base->features & DASD_FEATURE_READONLY || | 213 | if (!base) |
203 | test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) | 214 | return -ENODEV; |
215 | if (base->features & DASD_FEATURE_READONLY || | ||
216 | test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) { | ||
217 | dasd_put_device(base); | ||
204 | return -EROFS; | 218 | return -EROFS; |
205 | if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) | 219 | } |
220 | if (copy_from_user(&fdata, argp, sizeof(struct format_data_t))) { | ||
221 | dasd_put_device(base); | ||
206 | return -EFAULT; | 222 | return -EFAULT; |
223 | } | ||
207 | if (bdev != bdev->bd_contains) { | 224 | if (bdev != bdev->bd_contains) { |
208 | pr_warning("%s: The specified DASD is a partition and cannot " | 225 | pr_warning("%s: The specified DASD is a partition and cannot " |
209 | "be formatted\n", | 226 | "be formatted\n", |
210 | dev_name(&block->base->cdev->dev)); | 227 | dev_name(&base->cdev->dev)); |
228 | dasd_put_device(base); | ||
211 | return -EINVAL; | 229 | return -EINVAL; |
212 | } | 230 | } |
213 | return dasd_format(block, &fdata); | 231 | rc = dasd_format(base->block, &fdata); |
232 | dasd_put_device(base); | ||
233 | return rc; | ||
214 | } | 234 | } |
215 | 235 | ||
216 | #ifdef CONFIG_DASD_PROFILE | 236 | #ifdef CONFIG_DASD_PROFILE |
@@ -340,8 +360,8 @@ static int dasd_ioctl_information(struct dasd_block *block, | |||
340 | static int | 360 | static int |
341 | dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) | 361 | dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) |
342 | { | 362 | { |
343 | struct dasd_block *block = bdev->bd_disk->private_data; | 363 | struct dasd_device *base; |
344 | int intval; | 364 | int intval, rc; |
345 | 365 | ||
346 | if (!capable(CAP_SYS_ADMIN)) | 366 | if (!capable(CAP_SYS_ADMIN)) |
347 | return -EACCES; | 367 | return -EACCES; |
@@ -350,10 +370,17 @@ dasd_ioctl_set_ro(struct block_device *bdev, void __user *argp) | |||
350 | return -EINVAL; | 370 | return -EINVAL; |
351 | if (get_user(intval, (int __user *)argp)) | 371 | if (get_user(intval, (int __user *)argp)) |
352 | return -EFAULT; | 372 | return -EFAULT; |
353 | if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &block->base->flags)) | 373 | base = dasd_device_from_gendisk(bdev->bd_disk); |
374 | if (!base) | ||
375 | return -ENODEV; | ||
376 | if (!intval && test_bit(DASD_FLAG_DEVICE_RO, &base->flags)) { | ||
377 | dasd_put_device(base); | ||
354 | return -EROFS; | 378 | return -EROFS; |
379 | } | ||
355 | set_disk_ro(bdev->bd_disk, intval); | 380 | set_disk_ro(bdev->bd_disk, intval); |
356 | return dasd_set_feature(block->base->cdev, DASD_FEATURE_READONLY, intval); | 381 | rc = dasd_set_feature(base->cdev, DASD_FEATURE_READONLY, intval); |
382 | dasd_put_device(base); | ||
383 | return rc; | ||
357 | } | 384 | } |
358 | 385 | ||
359 | static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, | 386 | static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, |
@@ -372,59 +399,78 @@ static int dasd_ioctl_readall_cmb(struct dasd_block *block, unsigned int cmd, | |||
372 | int dasd_ioctl(struct block_device *bdev, fmode_t mode, | 399 | int dasd_ioctl(struct block_device *bdev, fmode_t mode, |
373 | unsigned int cmd, unsigned long arg) | 400 | unsigned int cmd, unsigned long arg) |
374 | { | 401 | { |
375 | struct dasd_block *block = bdev->bd_disk->private_data; | 402 | struct dasd_block *block; |
403 | struct dasd_device *base; | ||
376 | void __user *argp; | 404 | void __user *argp; |
405 | int rc; | ||
377 | 406 | ||
378 | if (is_compat_task()) | 407 | if (is_compat_task()) |
379 | argp = compat_ptr(arg); | 408 | argp = compat_ptr(arg); |
380 | else | 409 | else |
381 | argp = (void __user *)arg; | 410 | argp = (void __user *)arg; |
382 | 411 | ||
383 | if (!block) | ||
384 | return -ENODEV; | ||
385 | |||
386 | if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { | 412 | if ((_IOC_DIR(cmd) != _IOC_NONE) && !arg) { |
387 | PRINT_DEBUG("empty data ptr"); | 413 | PRINT_DEBUG("empty data ptr"); |
388 | return -EINVAL; | 414 | return -EINVAL; |
389 | } | 415 | } |
390 | 416 | ||
417 | base = dasd_device_from_gendisk(bdev->bd_disk); | ||
418 | if (!base) | ||
419 | return -ENODEV; | ||
420 | block = base->block; | ||
421 | rc = 0; | ||
391 | switch (cmd) { | 422 | switch (cmd) { |
392 | case BIODASDDISABLE: | 423 | case BIODASDDISABLE: |
393 | return dasd_ioctl_disable(bdev); | 424 | rc = dasd_ioctl_disable(bdev); |
425 | break; | ||
394 | case BIODASDENABLE: | 426 | case BIODASDENABLE: |
395 | return dasd_ioctl_enable(bdev); | 427 | rc = dasd_ioctl_enable(bdev); |
428 | break; | ||
396 | case BIODASDQUIESCE: | 429 | case BIODASDQUIESCE: |
397 | return dasd_ioctl_quiesce(block); | 430 | rc = dasd_ioctl_quiesce(block); |
431 | break; | ||
398 | case BIODASDRESUME: | 432 | case BIODASDRESUME: |
399 | return dasd_ioctl_resume(block); | 433 | rc = dasd_ioctl_resume(block); |
434 | break; | ||
400 | case BIODASDFMT: | 435 | case BIODASDFMT: |
401 | return dasd_ioctl_format(bdev, argp); | 436 | rc = dasd_ioctl_format(bdev, argp); |
437 | break; | ||
402 | case BIODASDINFO: | 438 | case BIODASDINFO: |
403 | return dasd_ioctl_information(block, cmd, argp); | 439 | rc = dasd_ioctl_information(block, cmd, argp); |
440 | break; | ||
404 | case BIODASDINFO2: | 441 | case BIODASDINFO2: |
405 | return dasd_ioctl_information(block, cmd, argp); | 442 | rc = dasd_ioctl_information(block, cmd, argp); |
443 | break; | ||
406 | case BIODASDPRRD: | 444 | case BIODASDPRRD: |
407 | return dasd_ioctl_read_profile(block, argp); | 445 | rc = dasd_ioctl_read_profile(block, argp); |
446 | break; | ||
408 | case BIODASDPRRST: | 447 | case BIODASDPRRST: |
409 | return dasd_ioctl_reset_profile(block); | 448 | rc = dasd_ioctl_reset_profile(block); |
449 | break; | ||
410 | case BLKROSET: | 450 | case BLKROSET: |
411 | return dasd_ioctl_set_ro(bdev, argp); | 451 | rc = dasd_ioctl_set_ro(bdev, argp); |
452 | break; | ||
412 | case DASDAPIVER: | 453 | case DASDAPIVER: |
413 | return dasd_ioctl_api_version(argp); | 454 | rc = dasd_ioctl_api_version(argp); |
455 | break; | ||
414 | case BIODASDCMFENABLE: | 456 | case BIODASDCMFENABLE: |
415 | return enable_cmf(block->base->cdev); | 457 | rc = enable_cmf(base->cdev); |
458 | break; | ||
416 | case BIODASDCMFDISABLE: | 459 | case BIODASDCMFDISABLE: |
417 | return disable_cmf(block->base->cdev); | 460 | rc = disable_cmf(base->cdev); |
461 | break; | ||
418 | case BIODASDREADALLCMB: | 462 | case BIODASDREADALLCMB: |
419 | return dasd_ioctl_readall_cmb(block, cmd, argp); | 463 | rc = dasd_ioctl_readall_cmb(block, cmd, argp); |
464 | break; | ||
420 | default: | 465 | default: |
421 | /* if the discipline has an ioctl method try it. */ | 466 | /* if the discipline has an ioctl method try it. */ |
422 | if (block->base->discipline->ioctl) { | 467 | if (base->discipline->ioctl) { |
423 | int rval = block->base->discipline->ioctl(block, cmd, argp); | 468 | rc = base->discipline->ioctl(block, cmd, argp); |
424 | if (rval != -ENOIOCTLCMD) | 469 | if (rc == -ENOIOCTLCMD) |
425 | return rval; | 470 | rc = -EINVAL; |
426 | } | 471 | } else |
427 | 472 | rc = -EINVAL; | |
428 | return -EINVAL; | ||
429 | } | 473 | } |
474 | dasd_put_device(base); | ||
475 | return rc; | ||
430 | } | 476 | } |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index c532ba929ccd..e8f267eb8887 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -407,8 +407,11 @@ static inline void account_sbals(struct qdio_q *q, int count) | |||
407 | q->q_stats.nr_sbals[pos]++; | 407 | q->q_stats.nr_sbals[pos]++; |
408 | } | 408 | } |
409 | 409 | ||
410 | static void announce_buffer_error(struct qdio_q *q, int count) | 410 | static void process_buffer_error(struct qdio_q *q, int count) |
411 | { | 411 | { |
412 | unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : | ||
413 | SLSB_P_OUTPUT_NOT_INIT; | ||
414 | |||
412 | q->qdio_error |= QDIO_ERROR_SLSB_STATE; | 415 | q->qdio_error |= QDIO_ERROR_SLSB_STATE; |
413 | 416 | ||
414 | /* special handling for no target buffer empty */ | 417 | /* special handling for no target buffer empty */ |
@@ -426,6 +429,12 @@ static void announce_buffer_error(struct qdio_q *q, int count) | |||
426 | DBF_ERROR("F14:%2x F15:%2x", | 429 | DBF_ERROR("F14:%2x F15:%2x", |
427 | q->sbal[q->first_to_check]->element[14].flags & 0xff, | 430 | q->sbal[q->first_to_check]->element[14].flags & 0xff, |
428 | q->sbal[q->first_to_check]->element[15].flags & 0xff); | 431 | q->sbal[q->first_to_check]->element[15].flags & 0xff); |
432 | |||
433 | /* | ||
434 | * Interrupts may be avoided as long as the error is present | ||
435 | * so change the buffer state immediately to avoid starvation. | ||
436 | */ | ||
437 | set_buf_states(q, q->first_to_check, state, count); | ||
429 | } | 438 | } |
430 | 439 | ||
431 | static inline void inbound_primed(struct qdio_q *q, int count) | 440 | static inline void inbound_primed(struct qdio_q *q, int count) |
@@ -506,8 +515,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) | |||
506 | account_sbals(q, count); | 515 | account_sbals(q, count); |
507 | break; | 516 | break; |
508 | case SLSB_P_INPUT_ERROR: | 517 | case SLSB_P_INPUT_ERROR: |
509 | announce_buffer_error(q, count); | 518 | process_buffer_error(q, count); |
510 | /* process the buffer, the upper layer will take care of it */ | ||
511 | q->first_to_check = add_buf(q->first_to_check, count); | 519 | q->first_to_check = add_buf(q->first_to_check, count); |
512 | atomic_sub(count, &q->nr_buf_used); | 520 | atomic_sub(count, &q->nr_buf_used); |
513 | if (q->irq_ptr->perf_stat_enabled) | 521 | if (q->irq_ptr->perf_stat_enabled) |
@@ -677,8 +685,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q) | |||
677 | account_sbals(q, count); | 685 | account_sbals(q, count); |
678 | break; | 686 | break; |
679 | case SLSB_P_OUTPUT_ERROR: | 687 | case SLSB_P_OUTPUT_ERROR: |
680 | announce_buffer_error(q, count); | 688 | process_buffer_error(q, count); |
681 | /* process the buffer, the upper layer will take care of it */ | ||
682 | q->first_to_check = add_buf(q->first_to_check, count); | 689 | q->first_to_check = add_buf(q->first_to_check, count); |
683 | atomic_sub(count, &q->nr_buf_used); | 690 | atomic_sub(count, &q->nr_buf_used); |
684 | if (q->irq_ptr->perf_stat_enabled) | 691 | if (q->irq_ptr->perf_stat_enabled) |
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c index 414427d64a8f..607998f0b7d8 100644 --- a/drivers/s390/kvm/kvm_virtio.c +++ b/drivers/s390/kvm/kvm_virtio.c | |||
@@ -381,10 +381,10 @@ static void kvm_extint_handler(unsigned int ext_int_code, | |||
381 | u16 subcode; | 381 | u16 subcode; |
382 | u32 param; | 382 | u32 param; |
383 | 383 | ||
384 | kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; | ||
385 | subcode = ext_int_code >> 16; | 384 | subcode = ext_int_code >> 16; |
386 | if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) | 385 | if ((subcode & 0xff00) != VIRTIO_SUBCODE_64) |
387 | return; | 386 | return; |
387 | kstat_cpu(smp_processor_id()).irqs[EXTINT_VRT]++; | ||
388 | 388 | ||
389 | /* The LSB might be overloaded, we have to mask it */ | 389 | /* The LSB might be overloaded, we have to mask it */ |
390 | vq = (struct virtqueue *)(param64 & ~1UL); | 390 | vq = (struct virtqueue *)(param64 & ~1UL); |
diff --git a/drivers/scsi/device_handler/scsi_dh.c b/drivers/scsi/device_handler/scsi_dh.c index 564e6ecd17c2..0119b8147797 100644 --- a/drivers/scsi/device_handler/scsi_dh.c +++ b/drivers/scsi/device_handler/scsi_dh.c | |||
@@ -394,12 +394,14 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) | |||
394 | unsigned long flags; | 394 | unsigned long flags; |
395 | struct scsi_device *sdev; | 395 | struct scsi_device *sdev; |
396 | struct scsi_device_handler *scsi_dh = NULL; | 396 | struct scsi_device_handler *scsi_dh = NULL; |
397 | struct device *dev = NULL; | ||
397 | 398 | ||
398 | spin_lock_irqsave(q->queue_lock, flags); | 399 | spin_lock_irqsave(q->queue_lock, flags); |
399 | sdev = q->queuedata; | 400 | sdev = q->queuedata; |
400 | if (sdev && sdev->scsi_dh_data) | 401 | if (sdev && sdev->scsi_dh_data) |
401 | scsi_dh = sdev->scsi_dh_data->scsi_dh; | 402 | scsi_dh = sdev->scsi_dh_data->scsi_dh; |
402 | if (!scsi_dh || !get_device(&sdev->sdev_gendev) || | 403 | dev = get_device(&sdev->sdev_gendev); |
404 | if (!scsi_dh || !dev || | ||
403 | sdev->sdev_state == SDEV_CANCEL || | 405 | sdev->sdev_state == SDEV_CANCEL || |
404 | sdev->sdev_state == SDEV_DEL) | 406 | sdev->sdev_state == SDEV_DEL) |
405 | err = SCSI_DH_NOSYS; | 407 | err = SCSI_DH_NOSYS; |
@@ -410,12 +412,13 @@ int scsi_dh_activate(struct request_queue *q, activate_complete fn, void *data) | |||
410 | if (err) { | 412 | if (err) { |
411 | if (fn) | 413 | if (fn) |
412 | fn(data, err); | 414 | fn(data, err); |
413 | return err; | 415 | goto out; |
414 | } | 416 | } |
415 | 417 | ||
416 | if (scsi_dh->activate) | 418 | if (scsi_dh->activate) |
417 | err = scsi_dh->activate(sdev, fn, data); | 419 | err = scsi_dh->activate(sdev, fn, data); |
418 | put_device(&sdev->sdev_gendev); | 420 | out: |
421 | put_device(dev); | ||
419 | return err; | 422 | return err; |
420 | } | 423 | } |
421 | EXPORT_SYMBOL_GPL(scsi_dh_activate); | 424 | EXPORT_SYMBOL_GPL(scsi_dh_activate); |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c index 1c6d2b405eef..d72f1f2b1392 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c +++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c | |||
@@ -688,6 +688,13 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, | |||
688 | goto out; | 688 | goto out; |
689 | } | 689 | } |
690 | 690 | ||
691 | /* Check for overflow and wraparound */ | ||
692 | if (karg.data_sge_offset * 4 > ioc->request_sz || | ||
693 | karg.data_sge_offset > (UINT_MAX / 4)) { | ||
694 | ret = -EINVAL; | ||
695 | goto out; | ||
696 | } | ||
697 | |||
691 | /* copy in request message frame from user */ | 698 | /* copy in request message frame from user */ |
692 | if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { | 699 | if (copy_from_user(mpi_request, mf, karg.data_sge_offset*4)) { |
693 | printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, | 700 | printk(KERN_ERR "failure at %s:%d/%s()!\n", __FILE__, __LINE__, |
@@ -1963,7 +1970,7 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
1963 | Mpi2DiagBufferPostReply_t *mpi_reply; | 1970 | Mpi2DiagBufferPostReply_t *mpi_reply; |
1964 | int rc, i; | 1971 | int rc, i; |
1965 | u8 buffer_type; | 1972 | u8 buffer_type; |
1966 | unsigned long timeleft; | 1973 | unsigned long timeleft, request_size, copy_size; |
1967 | u16 smid; | 1974 | u16 smid; |
1968 | u16 ioc_status; | 1975 | u16 ioc_status; |
1969 | u8 issue_reset = 0; | 1976 | u8 issue_reset = 0; |
@@ -1999,6 +2006,8 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
1999 | return -ENOMEM; | 2006 | return -ENOMEM; |
2000 | } | 2007 | } |
2001 | 2008 | ||
2009 | request_size = ioc->diag_buffer_sz[buffer_type]; | ||
2010 | |||
2002 | if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) { | 2011 | if ((karg.starting_offset % 4) || (karg.bytes_to_read % 4)) { |
2003 | printk(MPT2SAS_ERR_FMT "%s: either the starting_offset " | 2012 | printk(MPT2SAS_ERR_FMT "%s: either the starting_offset " |
2004 | "or bytes_to_read are not 4 byte aligned\n", ioc->name, | 2013 | "or bytes_to_read are not 4 byte aligned\n", ioc->name, |
@@ -2006,13 +2015,23 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state) | |||
2006 | return -EINVAL; | 2015 | return -EINVAL; |
2007 | } | 2016 | } |
2008 | 2017 | ||
2018 | if (karg.starting_offset > request_size) | ||
2019 | return -EINVAL; | ||
2020 | |||
2009 | diag_data = (void *)(request_data + karg.starting_offset); | 2021 | diag_data = (void *)(request_data + karg.starting_offset); |
2010 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), " | 2022 | dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: diag_buffer(%p), " |
2011 | "offset(%d), sz(%d)\n", ioc->name, __func__, | 2023 | "offset(%d), sz(%d)\n", ioc->name, __func__, |
2012 | diag_data, karg.starting_offset, karg.bytes_to_read)); | 2024 | diag_data, karg.starting_offset, karg.bytes_to_read)); |
2013 | 2025 | ||
2026 | /* Truncate data on requests that are too large */ | ||
2027 | if ((diag_data + karg.bytes_to_read < diag_data) || | ||
2028 | (diag_data + karg.bytes_to_read > request_data + request_size)) | ||
2029 | copy_size = request_size - karg.starting_offset; | ||
2030 | else | ||
2031 | copy_size = karg.bytes_to_read; | ||
2032 | |||
2014 | if (copy_to_user((void __user *)uarg->diagnostic_data, | 2033 | if (copy_to_user((void __user *)uarg->diagnostic_data, |
2015 | diag_data, karg.bytes_to_read)) { | 2034 | diag_data, copy_size)) { |
2016 | printk(MPT2SAS_ERR_FMT "%s: Unable to write " | 2035 | printk(MPT2SAS_ERR_FMT "%s: Unable to write " |
2017 | "mpt_diag_read_buffer_t data @ %p\n", ioc->name, | 2036 | "mpt_diag_read_buffer_t data @ %p\n", ioc->name, |
2018 | __func__, diag_data); | 2037 | __func__, diag_data); |
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 96d5ad0c1e42..7f636b118287 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
@@ -3814,6 +3814,9 @@ static long pmcraid_ioctl_passthrough( | |||
3814 | rc = -EFAULT; | 3814 | rc = -EFAULT; |
3815 | goto out_free_buffer; | 3815 | goto out_free_buffer; |
3816 | } | 3816 | } |
3817 | } else if (request_size < 0) { | ||
3818 | rc = -EINVAL; | ||
3819 | goto out_free_buffer; | ||
3817 | } | 3820 | } |
3818 | 3821 | ||
3819 | /* check if we have any additional command parameters */ | 3822 | /* check if we have any additional command parameters */ |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 6d5c7ff43f5b..0bac91e72370 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -400,10 +400,15 @@ static inline int scsi_host_is_busy(struct Scsi_Host *shost) | |||
400 | static void scsi_run_queue(struct request_queue *q) | 400 | static void scsi_run_queue(struct request_queue *q) |
401 | { | 401 | { |
402 | struct scsi_device *sdev = q->queuedata; | 402 | struct scsi_device *sdev = q->queuedata; |
403 | struct Scsi_Host *shost = sdev->host; | 403 | struct Scsi_Host *shost; |
404 | LIST_HEAD(starved_list); | 404 | LIST_HEAD(starved_list); |
405 | unsigned long flags; | 405 | unsigned long flags; |
406 | 406 | ||
407 | /* if the device is dead, sdev will be NULL, so no queue to run */ | ||
408 | if (!sdev) | ||
409 | return; | ||
410 | |||
411 | shost = sdev->host; | ||
407 | if (scsi_target(sdev)->single_lun) | 412 | if (scsi_target(sdev)->single_lun) |
408 | scsi_single_lun_run(sdev); | 413 | scsi_single_lun_run(sdev); |
409 | 414 | ||
@@ -411,8 +416,6 @@ static void scsi_run_queue(struct request_queue *q) | |||
411 | list_splice_init(&shost->starved_list, &starved_list); | 416 | list_splice_init(&shost->starved_list, &starved_list); |
412 | 417 | ||
413 | while (!list_empty(&starved_list)) { | 418 | while (!list_empty(&starved_list)) { |
414 | int flagset; | ||
415 | |||
416 | /* | 419 | /* |
417 | * As long as shost is accepting commands and we have | 420 | * As long as shost is accepting commands and we have |
418 | * starved queues, call blk_run_queue. scsi_request_fn | 421 | * starved queues, call blk_run_queue. scsi_request_fn |
@@ -435,20 +438,7 @@ static void scsi_run_queue(struct request_queue *q) | |||
435 | continue; | 438 | continue; |
436 | } | 439 | } |
437 | 440 | ||
438 | spin_unlock(shost->host_lock); | 441 | blk_run_queue_async(sdev->request_queue); |
439 | |||
440 | spin_lock(sdev->request_queue->queue_lock); | ||
441 | flagset = test_bit(QUEUE_FLAG_REENTER, &q->queue_flags) && | ||
442 | !test_bit(QUEUE_FLAG_REENTER, | ||
443 | &sdev->request_queue->queue_flags); | ||
444 | if (flagset) | ||
445 | queue_flag_set(QUEUE_FLAG_REENTER, sdev->request_queue); | ||
446 | __blk_run_queue(sdev->request_queue, false); | ||
447 | if (flagset) | ||
448 | queue_flag_clear(QUEUE_FLAG_REENTER, sdev->request_queue); | ||
449 | spin_unlock(sdev->request_queue->queue_lock); | ||
450 | |||
451 | spin_lock(shost->host_lock); | ||
452 | } | 442 | } |
453 | /* put any unprocessed entries back */ | 443 | /* put any unprocessed entries back */ |
454 | list_splice(&starved_list, &shost->starved_list); | 444 | list_splice(&starved_list, &shost->starved_list); |
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index e44ff64233fd..e63912510fb9 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -322,14 +322,8 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work) | |||
322 | kfree(evt); | 322 | kfree(evt); |
323 | } | 323 | } |
324 | 324 | ||
325 | if (sdev->request_queue) { | 325 | /* NULL queue means the device can't be used */ |
326 | sdev->request_queue->queuedata = NULL; | 326 | sdev->request_queue = NULL; |
327 | /* user context needed to free queue */ | ||
328 | scsi_free_queue(sdev->request_queue); | ||
329 | /* temporary expedient, try to catch use of queue lock | ||
330 | * after free of sdev */ | ||
331 | sdev->request_queue = NULL; | ||
332 | } | ||
333 | 327 | ||
334 | scsi_target_reap(scsi_target(sdev)); | 328 | scsi_target_reap(scsi_target(sdev)); |
335 | 329 | ||
@@ -937,6 +931,12 @@ void __scsi_remove_device(struct scsi_device *sdev) | |||
937 | if (sdev->host->hostt->slave_destroy) | 931 | if (sdev->host->hostt->slave_destroy) |
938 | sdev->host->hostt->slave_destroy(sdev); | 932 | sdev->host->hostt->slave_destroy(sdev); |
939 | transport_destroy_device(dev); | 933 | transport_destroy_device(dev); |
934 | |||
935 | /* cause the request function to reject all I/O requests */ | ||
936 | sdev->request_queue->queuedata = NULL; | ||
937 | |||
938 | /* Freeing the queue signals to block that we're done */ | ||
939 | scsi_free_queue(sdev->request_queue); | ||
940 | put_device(dev); | 940 | put_device(dev); |
941 | } | 941 | } |
942 | 942 | ||
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index fdf3fa639056..815069d13f9b 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -3816,28 +3816,17 @@ fail_host_msg: | |||
3816 | static void | 3816 | static void |
3817 | fc_bsg_goose_queue(struct fc_rport *rport) | 3817 | fc_bsg_goose_queue(struct fc_rport *rport) |
3818 | { | 3818 | { |
3819 | int flagset; | ||
3820 | unsigned long flags; | ||
3821 | |||
3822 | if (!rport->rqst_q) | 3819 | if (!rport->rqst_q) |
3823 | return; | 3820 | return; |
3824 | 3821 | ||
3822 | /* | ||
3823 | * This get/put dance makes no sense | ||
3824 | */ | ||
3825 | get_device(&rport->dev); | 3825 | get_device(&rport->dev); |
3826 | 3826 | blk_run_queue_async(rport->rqst_q); | |
3827 | spin_lock_irqsave(rport->rqst_q->queue_lock, flags); | ||
3828 | flagset = test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags) && | ||
3829 | !test_bit(QUEUE_FLAG_REENTER, &rport->rqst_q->queue_flags); | ||
3830 | if (flagset) | ||
3831 | queue_flag_set(QUEUE_FLAG_REENTER, rport->rqst_q); | ||
3832 | __blk_run_queue(rport->rqst_q, false); | ||
3833 | if (flagset) | ||
3834 | queue_flag_clear(QUEUE_FLAG_REENTER, rport->rqst_q); | ||
3835 | spin_unlock_irqrestore(rport->rqst_q->queue_lock, flags); | ||
3836 | |||
3837 | put_device(&rport->dev); | 3827 | put_device(&rport->dev); |
3838 | } | 3828 | } |
3839 | 3829 | ||
3840 | |||
3841 | /** | 3830 | /** |
3842 | * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD | 3831 | * fc_bsg_rport_dispatch - process rport bsg requests and dispatch to LLDD |
3843 | * @q: rport request queue | 3832 | * @q: rport request queue |
diff --git a/drivers/spi/amba-pl022.c b/drivers/spi/amba-pl022.c index 5825370bad25..08de58e7f59f 100644 --- a/drivers/spi/amba-pl022.c +++ b/drivers/spi/amba-pl022.c | |||
@@ -1555,7 +1555,7 @@ static int stop_queue(struct pl022 *pl022) | |||
1555 | * A wait_queue on the pl022->busy could be used, but then the common | 1555 | * A wait_queue on the pl022->busy could be used, but then the common |
1556 | * execution path (pump_messages) would be required to call wake_up or | 1556 | * execution path (pump_messages) would be required to call wake_up or |
1557 | * friends on every SPI message. Do this instead */ | 1557 | * friends on every SPI message. Do this instead */ |
1558 | while (!list_empty(&pl022->queue) && pl022->busy && limit--) { | 1558 | while ((!list_empty(&pl022->queue) || pl022->busy) && limit--) { |
1559 | spin_unlock_irqrestore(&pl022->queue_lock, flags); | 1559 | spin_unlock_irqrestore(&pl022->queue_lock, flags); |
1560 | msleep(10); | 1560 | msleep(10); |
1561 | spin_lock_irqsave(&pl022->queue_lock, flags); | 1561 | spin_lock_irqsave(&pl022->queue_lock, flags); |
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index b1a4b9f503ae..871e337c917f 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
@@ -821,7 +821,7 @@ static int stop_queue(struct dw_spi *dws) | |||
821 | 821 | ||
822 | spin_lock_irqsave(&dws->lock, flags); | 822 | spin_lock_irqsave(&dws->lock, flags); |
823 | dws->run = QUEUE_STOPPED; | 823 | dws->run = QUEUE_STOPPED; |
824 | while (!list_empty(&dws->queue) && dws->busy && limit--) { | 824 | while ((!list_empty(&dws->queue) || dws->busy) && limit--) { |
825 | spin_unlock_irqrestore(&dws->lock, flags); | 825 | spin_unlock_irqrestore(&dws->lock, flags); |
826 | msleep(10); | 826 | msleep(10); |
827 | spin_lock_irqsave(&dws->lock, flags); | 827 | spin_lock_irqsave(&dws->lock, flags); |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 9c74aad6be93..dc25bee8d33f 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -1493,7 +1493,7 @@ static int stop_queue(struct driver_data *drv_data) | |||
1493 | * execution path (pump_messages) would be required to call wake_up or | 1493 | * execution path (pump_messages) would be required to call wake_up or |
1494 | * friends on every SPI message. Do this instead */ | 1494 | * friends on every SPI message. Do this instead */ |
1495 | drv_data->run = QUEUE_STOPPED; | 1495 | drv_data->run = QUEUE_STOPPED; |
1496 | while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { | 1496 | while ((!list_empty(&drv_data->queue) || drv_data->busy) && limit--) { |
1497 | spin_unlock_irqrestore(&drv_data->lock, flags); | 1497 | spin_unlock_irqrestore(&drv_data->lock, flags); |
1498 | msleep(10); | 1498 | msleep(10); |
1499 | spin_lock_irqsave(&drv_data->lock, flags); | 1499 | spin_lock_irqsave(&drv_data->lock, flags); |
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index bdb7289a1d22..f706dba165cf 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -1284,7 +1284,7 @@ static inline int bfin_spi_stop_queue(struct bfin_spi_master_data *drv_data) | |||
1284 | * friends on every SPI message. Do this instead | 1284 | * friends on every SPI message. Do this instead |
1285 | */ | 1285 | */ |
1286 | drv_data->running = false; | 1286 | drv_data->running = false; |
1287 | while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) { | 1287 | while ((!list_empty(&drv_data->queue) || drv_data->busy) && limit--) { |
1288 | spin_unlock_irqrestore(&drv_data->lock, flags); | 1288 | spin_unlock_irqrestore(&drv_data->lock, flags); |
1289 | msleep(10); | 1289 | msleep(10); |
1290 | spin_lock_irqsave(&drv_data->lock, flags); | 1290 | spin_lock_irqsave(&drv_data->lock, flags); |
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index dca4a0bb6ca9..e3786f161bc3 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -131,8 +131,6 @@ source "drivers/staging/wlags49_h2/Kconfig" | |||
131 | 131 | ||
132 | source "drivers/staging/wlags49_h25/Kconfig" | 132 | source "drivers/staging/wlags49_h25/Kconfig" |
133 | 133 | ||
134 | source "drivers/staging/samsung-laptop/Kconfig" | ||
135 | |||
136 | source "drivers/staging/sm7xx/Kconfig" | 134 | source "drivers/staging/sm7xx/Kconfig" |
137 | 135 | ||
138 | source "drivers/staging/dt3155v4l/Kconfig" | 136 | source "drivers/staging/dt3155v4l/Kconfig" |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index eb93012b6f59..f0d5c5315612 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -48,7 +48,6 @@ obj-$(CONFIG_XVMALLOC) += zram/ | |||
48 | obj-$(CONFIG_ZCACHE) += zcache/ | 48 | obj-$(CONFIG_ZCACHE) += zcache/ |
49 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ | 49 | obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ |
50 | obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ | 50 | obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ |
51 | obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ | ||
52 | obj-$(CONFIG_FB_SM7XX) += sm7xx/ | 51 | obj-$(CONFIG_FB_SM7XX) += sm7xx/ |
53 | obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ | 52 | obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ |
54 | obj-$(CONFIG_CRYSTALHD) += crystalhd/ | 53 | obj-$(CONFIG_CRYSTALHD) += crystalhd/ |
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index eeb7dd43f9a8..830822f86e41 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | |||
@@ -2288,7 +2288,3 @@ err_dev: | |||
2288 | free_netdev(dev); | 2288 | free_netdev(dev); |
2289 | return NULL; | 2289 | return NULL; |
2290 | } | 2290 | } |
2291 | |||
2292 | EXPORT_SYMBOL(init_ft1000_card); | ||
2293 | EXPORT_SYMBOL(stop_ft1000_card); | ||
2294 | EXPORT_SYMBOL(flarion_ft1000_cnt); | ||
diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c index 935608e72007..bdfb1aec58df 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c | |||
@@ -214,6 +214,3 @@ void ft1000CleanupProc(struct net_device *dev) | |||
214 | remove_proc_entry(FT1000_PROC, init_net.proc_net); | 214 | remove_proc_entry(FT1000_PROC, init_net.proc_net); |
215 | unregister_netdevice_notifier(&ft1000_netdev_notifier); | 215 | unregister_netdevice_notifier(&ft1000_netdev_notifier); |
216 | } | 216 | } |
217 | |||
218 | EXPORT_SYMBOL(ft1000InitProc); | ||
219 | EXPORT_SYMBOL(ft1000CleanupProc); | ||
diff --git a/drivers/staging/gma500/Kconfig b/drivers/staging/gma500/Kconfig index 5501eb9b3355..ce8bedaeaac2 100644 --- a/drivers/staging/gma500/Kconfig +++ b/drivers/staging/gma500/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config DRM_PSB | 1 | config DRM_PSB |
2 | tristate "Intel GMA500 KMS Framebuffer" | 2 | tristate "Intel GMA500 KMS Framebuffer" |
3 | depends on DRM && PCI | 3 | depends on DRM && PCI && X86 |
4 | select FB_CFB_COPYAREA | 4 | select FB_CFB_COPYAREA |
5 | select FB_CFB_FILLRECT | 5 | select FB_CFB_FILLRECT |
6 | select FB_CFB_IMAGEBLIT | 6 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/staging/intel_sst/intelmid_v1_control.c b/drivers/staging/intel_sst/intelmid_v1_control.c index 9cc15c1c18d4..1ea814218059 100644 --- a/drivers/staging/intel_sst/intelmid_v1_control.c +++ b/drivers/staging/intel_sst/intelmid_v1_control.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 28 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
29 | 29 | ||
30 | #include <linux/pci.h> | 30 | #include <linux/pci.h> |
31 | #include <linux/delay.h> | ||
31 | #include <linux/file.h> | 32 | #include <linux/file.h> |
32 | #include <asm/mrst.h> | 33 | #include <asm/mrst.h> |
33 | #include <sound/pcm.h> | 34 | #include <sound/pcm.h> |
diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c b/drivers/staging/intel_sst/intelmid_v2_control.c index 26d815a67eb8..3c6b3abff3c3 100644 --- a/drivers/staging/intel_sst/intelmid_v2_control.c +++ b/drivers/staging/intel_sst/intelmid_v2_control.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 29 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
30 | 30 | ||
31 | #include <linux/pci.h> | 31 | #include <linux/pci.h> |
32 | #include <linux/delay.h> | ||
32 | #include <linux/file.h> | 33 | #include <linux/file.h> |
33 | #include "intel_sst.h" | 34 | #include "intel_sst.h" |
34 | #include "intelmid_snd_control.h" | 35 | #include "intelmid_snd_control.h" |
diff --git a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c index b5d21f6497f9..22c04eabed41 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c +++ b/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c | |||
@@ -12,6 +12,7 @@ | |||
12 | */ | 12 | */ |
13 | #include <linux/cs5535.h> | 13 | #include <linux/cs5535.h> |
14 | #include <linux/gpio.h> | 14 | #include <linux/gpio.h> |
15 | #include <linux/delay.h> | ||
15 | #include <asm/olpc.h> | 16 | #include <asm/olpc.h> |
16 | 17 | ||
17 | #include "olpc_dcon.h" | 18 | #include "olpc_dcon.h" |
diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c index bef0bbd8cef7..f01a51c381f1 100644 --- a/drivers/staging/rt2860/common/cmm_data_pci.c +++ b/drivers/staging/rt2860/common/cmm_data_pci.c | |||
@@ -444,7 +444,7 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, | |||
444 | return (NDIS_STATUS_FAILURE); | 444 | return (NDIS_STATUS_FAILURE); |
445 | } | 445 | } |
446 | } | 446 | } |
447 | /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ | 447 | /* Drop not U2M frames, can't drop here because we will drop beacon in this case */ |
448 | /* I am kind of doubting the U2M bit operation */ | 448 | /* I am kind of doubting the U2M bit operation */ |
449 | /* if (pRxD->U2M == 0) */ | 449 | /* if (pRxD->U2M == 0) */ |
450 | /* return(NDIS_STATUS_FAILURE); */ | 450 | /* return(NDIS_STATUS_FAILURE); */ |
diff --git a/drivers/staging/rt2860/common/cmm_data_usb.c b/drivers/staging/rt2860/common/cmm_data_usb.c index 5637857ae9eb..83a62faa7e57 100644 --- a/drivers/staging/rt2860/common/cmm_data_usb.c +++ b/drivers/staging/rt2860/common/cmm_data_usb.c | |||
@@ -860,7 +860,7 @@ int RTMPCheckRxError(struct rt_rtmp_adapter *pAd, | |||
860 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); | 860 | DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n")); |
861 | return NDIS_STATUS_FAILURE; | 861 | return NDIS_STATUS_FAILURE; |
862 | } | 862 | } |
863 | /* Drop not U2M frames, can't's drop here because we will drop beacon in this case */ | 863 | /* Drop not U2M frames, can't drop here because we will drop beacon in this case */ |
864 | /* I am kind of doubting the U2M bit operation */ | 864 | /* I am kind of doubting the U2M bit operation */ |
865 | /* if (pRxD->U2M == 0) */ | 865 | /* if (pRxD->U2M == 0) */ |
866 | /* return(NDIS_STATUS_FAILURE); */ | 866 | /* return(NDIS_STATUS_FAILURE); */ |
diff --git a/drivers/staging/rts_pstor/debug.h b/drivers/staging/rts_pstor/debug.h index e1408b0e7ae4..ab305be96fb5 100644 --- a/drivers/staging/rts_pstor/debug.h +++ b/drivers/staging/rts_pstor/debug.h | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #define RTSX_STOR "rts_pstor: " | 29 | #define RTSX_STOR "rts_pstor: " |
30 | 30 | ||
31 | #if CONFIG_RTS_PSTOR_DEBUG | 31 | #ifdef CONFIG_RTS_PSTOR_DEBUG |
32 | #define RTSX_DEBUGP(x...) printk(KERN_DEBUG RTSX_STOR x) | 32 | #define RTSX_DEBUGP(x...) printk(KERN_DEBUG RTSX_STOR x) |
33 | #define RTSX_DEBUGPN(x...) printk(KERN_DEBUG x) | 33 | #define RTSX_DEBUGPN(x...) printk(KERN_DEBUG x) |
34 | #define RTSX_DEBUGPX(x...) printk(x) | 34 | #define RTSX_DEBUGPX(x...) printk(x) |
diff --git a/drivers/staging/rts_pstor/ms.c b/drivers/staging/rts_pstor/ms.c index 810e170894f5..d89795c6a3ac 100644 --- a/drivers/staging/rts_pstor/ms.c +++ b/drivers/staging/rts_pstor/ms.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/vmalloc.h> | ||
26 | 27 | ||
27 | #include "rtsx.h" | 28 | #include "rtsx.h" |
28 | #include "rtsx_transport.h" | 29 | #include "rtsx_transport.h" |
diff --git a/drivers/staging/rts_pstor/rtsx_chip.c b/drivers/staging/rts_pstor/rtsx_chip.c index d2f1c715a684..4e60780ea804 100644 --- a/drivers/staging/rts_pstor/rtsx_chip.c +++ b/drivers/staging/rts_pstor/rtsx_chip.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
27 | #include <linux/vmalloc.h> | ||
27 | 28 | ||
28 | #include "rtsx.h" | 29 | #include "rtsx.h" |
29 | #include "rtsx_transport.h" | 30 | #include "rtsx_transport.h" |
@@ -1311,11 +1312,11 @@ void rtsx_polling_func(struct rtsx_chip *chip) | |||
1311 | 1312 | ||
1312 | #ifdef SUPPORT_OCP | 1313 | #ifdef SUPPORT_OCP |
1313 | if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { | 1314 | if (CHECK_LUN_MODE(chip, SD_MS_2LUN)) { |
1314 | #if CONFIG_RTS_PSTOR_DEBUG | 1315 | #ifdef CONFIG_RTS_PSTOR_DEBUG |
1315 | if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER)) { | 1316 | if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER | MS_OC_NOW | MS_OC_EVER)) { |
1316 | RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); | 1317 | RTSX_DEBUGP("Over current, OCPSTAT is 0x%x\n", chip->ocp_stat); |
1317 | } | 1318 | } |
1318 | #endif | 1319 | #endif |
1319 | 1320 | ||
1320 | if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { | 1321 | if (chip->ocp_stat & (SD_OC_NOW | SD_OC_EVER)) { |
1321 | if (chip->card_exist & SD_CARD) { | 1322 | if (chip->card_exist & SD_CARD) { |
diff --git a/drivers/staging/rts_pstor/rtsx_scsi.c b/drivers/staging/rts_pstor/rtsx_scsi.c index 20c2464a20f9..7de1fae443fc 100644 --- a/drivers/staging/rts_pstor/rtsx_scsi.c +++ b/drivers/staging/rts_pstor/rtsx_scsi.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/vmalloc.h> | ||
26 | 27 | ||
27 | #include "rtsx.h" | 28 | #include "rtsx.h" |
28 | #include "rtsx_transport.h" | 29 | #include "rtsx_transport.h" |
diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 8d066bd428c4..b1277a6c7a8b 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c | |||
@@ -909,7 +909,7 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) | |||
909 | RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); | 909 | RTSX_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, PHASE_NOT_RESET); |
910 | RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); | 910 | RTSX_WRITE_REG(chip, CLK_CTL, CHANGE_CLK, 0); |
911 | } else { | 911 | } else { |
912 | #if CONFIG_RTS_PSTOR_DEBUG | 912 | #ifdef CONFIG_RTS_PSTOR_DEBUG |
913 | rtsx_read_register(chip, SD_VP_CTL, &val); | 913 | rtsx_read_register(chip, SD_VP_CTL, &val); |
914 | RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); | 914 | RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); |
915 | rtsx_read_register(chip, SD_DCMPS_CTL, &val); | 915 | rtsx_read_register(chip, SD_DCMPS_CTL, &val); |
@@ -958,7 +958,7 @@ static int sd_change_phase(struct rtsx_chip *chip, u8 sample_point, u8 tune_dir) | |||
958 | return STATUS_SUCCESS; | 958 | return STATUS_SUCCESS; |
959 | 959 | ||
960 | Fail: | 960 | Fail: |
961 | #if CONFIG_RTS_PSTOR_DEBUG | 961 | #ifdef CONFIG_RTS_PSTOR_DEBUG |
962 | rtsx_read_register(chip, SD_VP_CTL, &val); | 962 | rtsx_read_register(chip, SD_VP_CTL, &val); |
963 | RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); | 963 | RTSX_DEBUGP("SD_VP_CTL: 0x%x\n", val); |
964 | rtsx_read_register(chip, SD_DCMPS_CTL, &val); | 964 | rtsx_read_register(chip, SD_DCMPS_CTL, &val); |
diff --git a/drivers/staging/rts_pstor/trace.h b/drivers/staging/rts_pstor/trace.h index 2c668bae6ff4..bc83b49a4eb4 100644 --- a/drivers/staging/rts_pstor/trace.h +++ b/drivers/staging/rts_pstor/trace.h | |||
@@ -82,7 +82,7 @@ do { \ | |||
82 | #define TRACE_GOTO(chip, label) goto label | 82 | #define TRACE_GOTO(chip, label) goto label |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | #if CONFIG_RTS_PSTOR_DEBUG | 85 | #ifdef CONFIG_RTS_PSTOR_DEBUG |
86 | static inline void rtsx_dump(u8 *buf, int buf_len) | 86 | static inline void rtsx_dump(u8 *buf, int buf_len) |
87 | { | 87 | { |
88 | int i; | 88 | int i; |
diff --git a/drivers/staging/rts_pstor/xd.c b/drivers/staging/rts_pstor/xd.c index 7bcd468b8f2c..9f3add1e8f59 100644 --- a/drivers/staging/rts_pstor/xd.c +++ b/drivers/staging/rts_pstor/xd.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/blkdev.h> | 23 | #include <linux/blkdev.h> |
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
26 | #include <linux/vmalloc.h> | ||
26 | 27 | ||
27 | #include "rtsx.h" | 28 | #include "rtsx.h" |
28 | #include "rtsx_transport.h" | 29 | #include "rtsx_transport.h" |
diff --git a/drivers/staging/samsung-laptop/Kconfig b/drivers/staging/samsung-laptop/Kconfig deleted file mode 100644 index f27c60864c26..000000000000 --- a/drivers/staging/samsung-laptop/Kconfig +++ /dev/null | |||
@@ -1,10 +0,0 @@ | |||
1 | config SAMSUNG_LAPTOP | ||
2 | tristate "Samsung Laptop driver" | ||
3 | default n | ||
4 | depends on RFKILL && BACKLIGHT_CLASS_DEVICE && X86 | ||
5 | help | ||
6 | This module implements a driver for the N128 Samsung Laptop | ||
7 | providing control over the Wireless LED and the LCD backlight | ||
8 | |||
9 | To compile this driver as a module, choose | ||
10 | M here: the module will be called samsung-laptop. | ||
diff --git a/drivers/staging/samsung-laptop/Makefile b/drivers/staging/samsung-laptop/Makefile deleted file mode 100644 index 3c6f42045211..000000000000 --- a/drivers/staging/samsung-laptop/Makefile +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o | ||
diff --git a/drivers/staging/samsung-laptop/TODO b/drivers/staging/samsung-laptop/TODO deleted file mode 100644 index f7a6d589916e..000000000000 --- a/drivers/staging/samsung-laptop/TODO +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | TODO: | ||
2 | - review from other developers | ||
3 | - figure out ACPI video issues | ||
4 | |||
5 | Please send patches to Greg Kroah-Hartman <gregkh@suse.de> | ||
diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c deleted file mode 100644 index 25294462b8b6..000000000000 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ /dev/null | |||
@@ -1,843 +0,0 @@ | |||
1 | /* | ||
2 | * Samsung Laptop driver | ||
3 | * | ||
4 | * Copyright (C) 2009,2011 Greg Kroah-Hartman (gregkh@suse.de) | ||
5 | * Copyright (C) 2009,2011 Novell Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/backlight.h> | ||
20 | #include <linux/fb.h> | ||
21 | #include <linux/dmi.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/rfkill.h> | ||
24 | |||
25 | /* | ||
26 | * This driver is needed because a number of Samsung laptops do not hook | ||
27 | * their control settings through ACPI. So we have to poke around in the | ||
28 | * BIOS to do things like brightness values, and "special" key controls. | ||
29 | */ | ||
30 | |||
31 | /* | ||
32 | * We have 0 - 8 as valid brightness levels. The specs say that level 0 should | ||
33 | * be reserved by the BIOS (which really doesn't make much sense), we tell | ||
34 | * userspace that the value is 0 - 7 and then just tell the hardware 1 - 8 | ||
35 | */ | ||
36 | #define MAX_BRIGHT 0x07 | ||
37 | |||
38 | |||
39 | #define SABI_IFACE_MAIN 0x00 | ||
40 | #define SABI_IFACE_SUB 0x02 | ||
41 | #define SABI_IFACE_COMPLETE 0x04 | ||
42 | #define SABI_IFACE_DATA 0x05 | ||
43 | |||
44 | /* Structure to get data back to the calling function */ | ||
45 | struct sabi_retval { | ||
46 | u8 retval[20]; | ||
47 | }; | ||
48 | |||
49 | struct sabi_header_offsets { | ||
50 | u8 port; | ||
51 | u8 re_mem; | ||
52 | u8 iface_func; | ||
53 | u8 en_mem; | ||
54 | u8 data_offset; | ||
55 | u8 data_segment; | ||
56 | }; | ||
57 | |||
58 | struct sabi_commands { | ||
59 | /* | ||
60 | * Brightness is 0 - 8, as described above. | ||
61 | * Value 0 is for the BIOS to use | ||
62 | */ | ||
63 | u8 get_brightness; | ||
64 | u8 set_brightness; | ||
65 | |||
66 | /* | ||
67 | * first byte: | ||
68 | * 0x00 - wireless is off | ||
69 | * 0x01 - wireless is on | ||
70 | * second byte: | ||
71 | * 0x02 - 3G is off | ||
72 | * 0x03 - 3G is on | ||
73 | * TODO, verify 3G is correct, that doesn't seem right... | ||
74 | */ | ||
75 | u8 get_wireless_button; | ||
76 | u8 set_wireless_button; | ||
77 | |||
78 | /* 0 is off, 1 is on */ | ||
79 | u8 get_backlight; | ||
80 | u8 set_backlight; | ||
81 | |||
82 | /* | ||
83 | * 0x80 or 0x00 - no action | ||
84 | * 0x81 - recovery key pressed | ||
85 | */ | ||
86 | u8 get_recovery_mode; | ||
87 | u8 set_recovery_mode; | ||
88 | |||
89 | /* | ||
90 | * on seclinux: 0 is low, 1 is high, | ||
91 | * on swsmi: 0 is normal, 1 is silent, 2 is turbo | ||
92 | */ | ||
93 | u8 get_performance_level; | ||
94 | u8 set_performance_level; | ||
95 | |||
96 | /* | ||
97 | * Tell the BIOS that Linux is running on this machine. | ||
98 | * 81 is on, 80 is off | ||
99 | */ | ||
100 | u8 set_linux; | ||
101 | }; | ||
102 | |||
103 | struct sabi_performance_level { | ||
104 | const char *name; | ||
105 | u8 value; | ||
106 | }; | ||
107 | |||
108 | struct sabi_config { | ||
109 | const char *test_string; | ||
110 | u16 main_function; | ||
111 | const struct sabi_header_offsets header_offsets; | ||
112 | const struct sabi_commands commands; | ||
113 | const struct sabi_performance_level performance_levels[4]; | ||
114 | u8 min_brightness; | ||
115 | u8 max_brightness; | ||
116 | }; | ||
117 | |||
118 | static const struct sabi_config sabi_configs[] = { | ||
119 | { | ||
120 | .test_string = "SECLINUX", | ||
121 | |||
122 | .main_function = 0x4c49, | ||
123 | |||
124 | .header_offsets = { | ||
125 | .port = 0x00, | ||
126 | .re_mem = 0x02, | ||
127 | .iface_func = 0x03, | ||
128 | .en_mem = 0x04, | ||
129 | .data_offset = 0x05, | ||
130 | .data_segment = 0x07, | ||
131 | }, | ||
132 | |||
133 | .commands = { | ||
134 | .get_brightness = 0x00, | ||
135 | .set_brightness = 0x01, | ||
136 | |||
137 | .get_wireless_button = 0x02, | ||
138 | .set_wireless_button = 0x03, | ||
139 | |||
140 | .get_backlight = 0x04, | ||
141 | .set_backlight = 0x05, | ||
142 | |||
143 | .get_recovery_mode = 0x06, | ||
144 | .set_recovery_mode = 0x07, | ||
145 | |||
146 | .get_performance_level = 0x08, | ||
147 | .set_performance_level = 0x09, | ||
148 | |||
149 | .set_linux = 0x0a, | ||
150 | }, | ||
151 | |||
152 | .performance_levels = { | ||
153 | { | ||
154 | .name = "silent", | ||
155 | .value = 0, | ||
156 | }, | ||
157 | { | ||
158 | .name = "normal", | ||
159 | .value = 1, | ||
160 | }, | ||
161 | { }, | ||
162 | }, | ||
163 | .min_brightness = 1, | ||
164 | .max_brightness = 8, | ||
165 | }, | ||
166 | { | ||
167 | .test_string = "SwSmi@", | ||
168 | |||
169 | .main_function = 0x5843, | ||
170 | |||
171 | .header_offsets = { | ||
172 | .port = 0x00, | ||
173 | .re_mem = 0x04, | ||
174 | .iface_func = 0x02, | ||
175 | .en_mem = 0x03, | ||
176 | .data_offset = 0x05, | ||
177 | .data_segment = 0x07, | ||
178 | }, | ||
179 | |||
180 | .commands = { | ||
181 | .get_brightness = 0x10, | ||
182 | .set_brightness = 0x11, | ||
183 | |||
184 | .get_wireless_button = 0x12, | ||
185 | .set_wireless_button = 0x13, | ||
186 | |||
187 | .get_backlight = 0x2d, | ||
188 | .set_backlight = 0x2e, | ||
189 | |||
190 | .get_recovery_mode = 0xff, | ||
191 | .set_recovery_mode = 0xff, | ||
192 | |||
193 | .get_performance_level = 0x31, | ||
194 | .set_performance_level = 0x32, | ||
195 | |||
196 | .set_linux = 0xff, | ||
197 | }, | ||
198 | |||
199 | .performance_levels = { | ||
200 | { | ||
201 | .name = "normal", | ||
202 | .value = 0, | ||
203 | }, | ||
204 | { | ||
205 | .name = "silent", | ||
206 | .value = 1, | ||
207 | }, | ||
208 | { | ||
209 | .name = "overclock", | ||
210 | .value = 2, | ||
211 | }, | ||
212 | { }, | ||
213 | }, | ||
214 | .min_brightness = 0, | ||
215 | .max_brightness = 8, | ||
216 | }, | ||
217 | { }, | ||
218 | }; | ||
219 | |||
220 | static const struct sabi_config *sabi_config; | ||
221 | |||
222 | static void __iomem *sabi; | ||
223 | static void __iomem *sabi_iface; | ||
224 | static void __iomem *f0000_segment; | ||
225 | static struct backlight_device *backlight_device; | ||
226 | static struct mutex sabi_mutex; | ||
227 | static struct platform_device *sdev; | ||
228 | static struct rfkill *rfk; | ||
229 | |||
230 | static int force; | ||
231 | module_param(force, bool, 0); | ||
232 | MODULE_PARM_DESC(force, | ||
233 | "Disable the DMI check and forces the driver to be loaded"); | ||
234 | |||
235 | static int debug; | ||
236 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
237 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
238 | |||
239 | static int sabi_get_command(u8 command, struct sabi_retval *sretval) | ||
240 | { | ||
241 | int retval = 0; | ||
242 | u16 port = readw(sabi + sabi_config->header_offsets.port); | ||
243 | u8 complete, iface_data; | ||
244 | |||
245 | mutex_lock(&sabi_mutex); | ||
246 | |||
247 | /* enable memory to be able to write to it */ | ||
248 | outb(readb(sabi + sabi_config->header_offsets.en_mem), port); | ||
249 | |||
250 | /* write out the command */ | ||
251 | writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN); | ||
252 | writew(command, sabi_iface + SABI_IFACE_SUB); | ||
253 | writeb(0, sabi_iface + SABI_IFACE_COMPLETE); | ||
254 | outb(readb(sabi + sabi_config->header_offsets.iface_func), port); | ||
255 | |||
256 | /* write protect memory to make it safe */ | ||
257 | outb(readb(sabi + sabi_config->header_offsets.re_mem), port); | ||
258 | |||
259 | /* see if the command actually succeeded */ | ||
260 | complete = readb(sabi_iface + SABI_IFACE_COMPLETE); | ||
261 | iface_data = readb(sabi_iface + SABI_IFACE_DATA); | ||
262 | if (complete != 0xaa || iface_data == 0xff) { | ||
263 | pr_warn("SABI get command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n", | ||
264 | command, complete, iface_data); | ||
265 | retval = -EINVAL; | ||
266 | goto exit; | ||
267 | } | ||
268 | /* | ||
269 | * Save off the data into a structure so the caller use it. | ||
270 | * Right now we only want the first 4 bytes, | ||
271 | * There are commands that need more, but not for the ones we | ||
272 | * currently care about. | ||
273 | */ | ||
274 | sretval->retval[0] = readb(sabi_iface + SABI_IFACE_DATA); | ||
275 | sretval->retval[1] = readb(sabi_iface + SABI_IFACE_DATA + 1); | ||
276 | sretval->retval[2] = readb(sabi_iface + SABI_IFACE_DATA + 2); | ||
277 | sretval->retval[3] = readb(sabi_iface + SABI_IFACE_DATA + 3); | ||
278 | |||
279 | exit: | ||
280 | mutex_unlock(&sabi_mutex); | ||
281 | return retval; | ||
282 | |||
283 | } | ||
284 | |||
285 | static int sabi_set_command(u8 command, u8 data) | ||
286 | { | ||
287 | int retval = 0; | ||
288 | u16 port = readw(sabi + sabi_config->header_offsets.port); | ||
289 | u8 complete, iface_data; | ||
290 | |||
291 | mutex_lock(&sabi_mutex); | ||
292 | |||
293 | /* enable memory to be able to write to it */ | ||
294 | outb(readb(sabi + sabi_config->header_offsets.en_mem), port); | ||
295 | |||
296 | /* write out the command */ | ||
297 | writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN); | ||
298 | writew(command, sabi_iface + SABI_IFACE_SUB); | ||
299 | writeb(0, sabi_iface + SABI_IFACE_COMPLETE); | ||
300 | writeb(data, sabi_iface + SABI_IFACE_DATA); | ||
301 | outb(readb(sabi + sabi_config->header_offsets.iface_func), port); | ||
302 | |||
303 | /* write protect memory to make it safe */ | ||
304 | outb(readb(sabi + sabi_config->header_offsets.re_mem), port); | ||
305 | |||
306 | /* see if the command actually succeeded */ | ||
307 | complete = readb(sabi_iface + SABI_IFACE_COMPLETE); | ||
308 | iface_data = readb(sabi_iface + SABI_IFACE_DATA); | ||
309 | if (complete != 0xaa || iface_data == 0xff) { | ||
310 | pr_warn("SABI set command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n", | ||
311 | command, complete, iface_data); | ||
312 | retval = -EINVAL; | ||
313 | } | ||
314 | |||
315 | mutex_unlock(&sabi_mutex); | ||
316 | return retval; | ||
317 | } | ||
318 | |||
319 | static void test_backlight(void) | ||
320 | { | ||
321 | struct sabi_retval sretval; | ||
322 | |||
323 | sabi_get_command(sabi_config->commands.get_backlight, &sretval); | ||
324 | printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); | ||
325 | |||
326 | sabi_set_command(sabi_config->commands.set_backlight, 0); | ||
327 | printk(KERN_DEBUG "backlight should be off\n"); | ||
328 | |||
329 | sabi_get_command(sabi_config->commands.get_backlight, &sretval); | ||
330 | printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); | ||
331 | |||
332 | msleep(1000); | ||
333 | |||
334 | sabi_set_command(sabi_config->commands.set_backlight, 1); | ||
335 | printk(KERN_DEBUG "backlight should be on\n"); | ||
336 | |||
337 | sabi_get_command(sabi_config->commands.get_backlight, &sretval); | ||
338 | printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]); | ||
339 | } | ||
340 | |||
341 | static void test_wireless(void) | ||
342 | { | ||
343 | struct sabi_retval sretval; | ||
344 | |||
345 | sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); | ||
346 | printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); | ||
347 | |||
348 | sabi_set_command(sabi_config->commands.set_wireless_button, 0); | ||
349 | printk(KERN_DEBUG "wireless led should be off\n"); | ||
350 | |||
351 | sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); | ||
352 | printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); | ||
353 | |||
354 | msleep(1000); | ||
355 | |||
356 | sabi_set_command(sabi_config->commands.set_wireless_button, 1); | ||
357 | printk(KERN_DEBUG "wireless led should be on\n"); | ||
358 | |||
359 | sabi_get_command(sabi_config->commands.get_wireless_button, &sretval); | ||
360 | printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]); | ||
361 | } | ||
362 | |||
363 | static u8 read_brightness(void) | ||
364 | { | ||
365 | struct sabi_retval sretval; | ||
366 | int user_brightness = 0; | ||
367 | int retval; | ||
368 | |||
369 | retval = sabi_get_command(sabi_config->commands.get_brightness, | ||
370 | &sretval); | ||
371 | if (!retval) { | ||
372 | user_brightness = sretval.retval[0]; | ||
373 | if (user_brightness != 0) | ||
374 | user_brightness -= sabi_config->min_brightness; | ||
375 | } | ||
376 | return user_brightness; | ||
377 | } | ||
378 | |||
379 | static void set_brightness(u8 user_brightness) | ||
380 | { | ||
381 | u8 user_level = user_brightness - sabi_config->min_brightness; | ||
382 | |||
383 | sabi_set_command(sabi_config->commands.set_brightness, user_level); | ||
384 | } | ||
385 | |||
386 | static int get_brightness(struct backlight_device *bd) | ||
387 | { | ||
388 | return (int)read_brightness(); | ||
389 | } | ||
390 | |||
391 | static int update_status(struct backlight_device *bd) | ||
392 | { | ||
393 | set_brightness(bd->props.brightness); | ||
394 | |||
395 | if (bd->props.power == FB_BLANK_UNBLANK) | ||
396 | sabi_set_command(sabi_config->commands.set_backlight, 1); | ||
397 | else | ||
398 | sabi_set_command(sabi_config->commands.set_backlight, 0); | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static const struct backlight_ops backlight_ops = { | ||
403 | .get_brightness = get_brightness, | ||
404 | .update_status = update_status, | ||
405 | }; | ||
406 | |||
407 | static int rfkill_set(void *data, bool blocked) | ||
408 | { | ||
409 | /* Do something with blocked...*/ | ||
410 | /* | ||
411 | * blocked == false is on | ||
412 | * blocked == true is off | ||
413 | */ | ||
414 | if (blocked) | ||
415 | sabi_set_command(sabi_config->commands.set_wireless_button, 0); | ||
416 | else | ||
417 | sabi_set_command(sabi_config->commands.set_wireless_button, 1); | ||
418 | |||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static struct rfkill_ops rfkill_ops = { | ||
423 | .set_block = rfkill_set, | ||
424 | }; | ||
425 | |||
426 | static int init_wireless(struct platform_device *sdev) | ||
427 | { | ||
428 | int retval; | ||
429 | |||
430 | rfk = rfkill_alloc("samsung-wifi", &sdev->dev, RFKILL_TYPE_WLAN, | ||
431 | &rfkill_ops, NULL); | ||
432 | if (!rfk) | ||
433 | return -ENOMEM; | ||
434 | |||
435 | retval = rfkill_register(rfk); | ||
436 | if (retval) { | ||
437 | rfkill_destroy(rfk); | ||
438 | return -ENODEV; | ||
439 | } | ||
440 | |||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | static void destroy_wireless(void) | ||
445 | { | ||
446 | rfkill_unregister(rfk); | ||
447 | rfkill_destroy(rfk); | ||
448 | } | ||
449 | |||
450 | static ssize_t get_performance_level(struct device *dev, | ||
451 | struct device_attribute *attr, char *buf) | ||
452 | { | ||
453 | struct sabi_retval sretval; | ||
454 | int retval; | ||
455 | int i; | ||
456 | |||
457 | /* Read the state */ | ||
458 | retval = sabi_get_command(sabi_config->commands.get_performance_level, | ||
459 | &sretval); | ||
460 | if (retval) | ||
461 | return retval; | ||
462 | |||
463 | /* The logic is backwards, yeah, lots of fun... */ | ||
464 | for (i = 0; sabi_config->performance_levels[i].name; ++i) { | ||
465 | if (sretval.retval[0] == sabi_config->performance_levels[i].value) | ||
466 | return sprintf(buf, "%s\n", sabi_config->performance_levels[i].name); | ||
467 | } | ||
468 | return sprintf(buf, "%s\n", "unknown"); | ||
469 | } | ||
470 | |||
471 | static ssize_t set_performance_level(struct device *dev, | ||
472 | struct device_attribute *attr, const char *buf, | ||
473 | size_t count) | ||
474 | { | ||
475 | if (count >= 1) { | ||
476 | int i; | ||
477 | for (i = 0; sabi_config->performance_levels[i].name; ++i) { | ||
478 | const struct sabi_performance_level *level = | ||
479 | &sabi_config->performance_levels[i]; | ||
480 | if (!strncasecmp(level->name, buf, strlen(level->name))) { | ||
481 | sabi_set_command(sabi_config->commands.set_performance_level, | ||
482 | level->value); | ||
483 | break; | ||
484 | } | ||
485 | } | ||
486 | if (!sabi_config->performance_levels[i].name) | ||
487 | return -EINVAL; | ||
488 | } | ||
489 | return count; | ||
490 | } | ||
491 | static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO, | ||
492 | get_performance_level, set_performance_level); | ||
493 | |||
494 | |||
495 | static int __init dmi_check_cb(const struct dmi_system_id *id) | ||
496 | { | ||
497 | pr_info("found laptop model '%s'\n", | ||
498 | id->ident); | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static struct dmi_system_id __initdata samsung_dmi_table[] = { | ||
503 | { | ||
504 | .ident = "N128", | ||
505 | .matches = { | ||
506 | DMI_MATCH(DMI_SYS_VENDOR, | ||
507 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
508 | DMI_MATCH(DMI_PRODUCT_NAME, "N128"), | ||
509 | DMI_MATCH(DMI_BOARD_NAME, "N128"), | ||
510 | }, | ||
511 | .callback = dmi_check_cb, | ||
512 | }, | ||
513 | { | ||
514 | .ident = "N130", | ||
515 | .matches = { | ||
516 | DMI_MATCH(DMI_SYS_VENDOR, | ||
517 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
518 | DMI_MATCH(DMI_PRODUCT_NAME, "N130"), | ||
519 | DMI_MATCH(DMI_BOARD_NAME, "N130"), | ||
520 | }, | ||
521 | .callback = dmi_check_cb, | ||
522 | }, | ||
523 | { | ||
524 | .ident = "X125", | ||
525 | .matches = { | ||
526 | DMI_MATCH(DMI_SYS_VENDOR, | ||
527 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
528 | DMI_MATCH(DMI_PRODUCT_NAME, "X125"), | ||
529 | DMI_MATCH(DMI_BOARD_NAME, "X125"), | ||
530 | }, | ||
531 | .callback = dmi_check_cb, | ||
532 | }, | ||
533 | { | ||
534 | .ident = "X120/X170", | ||
535 | .matches = { | ||
536 | DMI_MATCH(DMI_SYS_VENDOR, | ||
537 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
538 | DMI_MATCH(DMI_PRODUCT_NAME, "X120/X170"), | ||
539 | DMI_MATCH(DMI_BOARD_NAME, "X120/X170"), | ||
540 | }, | ||
541 | .callback = dmi_check_cb, | ||
542 | }, | ||
543 | { | ||
544 | .ident = "NC10", | ||
545 | .matches = { | ||
546 | DMI_MATCH(DMI_SYS_VENDOR, | ||
547 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
548 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), | ||
549 | DMI_MATCH(DMI_BOARD_NAME, "NC10"), | ||
550 | }, | ||
551 | .callback = dmi_check_cb, | ||
552 | }, | ||
553 | { | ||
554 | .ident = "NP-Q45", | ||
555 | .matches = { | ||
556 | DMI_MATCH(DMI_SYS_VENDOR, | ||
557 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
558 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), | ||
559 | DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"), | ||
560 | }, | ||
561 | .callback = dmi_check_cb, | ||
562 | }, | ||
563 | { | ||
564 | .ident = "X360", | ||
565 | .matches = { | ||
566 | DMI_MATCH(DMI_SYS_VENDOR, | ||
567 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
568 | DMI_MATCH(DMI_PRODUCT_NAME, "X360"), | ||
569 | DMI_MATCH(DMI_BOARD_NAME, "X360"), | ||
570 | }, | ||
571 | .callback = dmi_check_cb, | ||
572 | }, | ||
573 | { | ||
574 | .ident = "R410 Plus", | ||
575 | .matches = { | ||
576 | DMI_MATCH(DMI_SYS_VENDOR, | ||
577 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
578 | DMI_MATCH(DMI_PRODUCT_NAME, "R410P"), | ||
579 | DMI_MATCH(DMI_BOARD_NAME, "R460"), | ||
580 | }, | ||
581 | .callback = dmi_check_cb, | ||
582 | }, | ||
583 | { | ||
584 | .ident = "R518", | ||
585 | .matches = { | ||
586 | DMI_MATCH(DMI_SYS_VENDOR, | ||
587 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
588 | DMI_MATCH(DMI_PRODUCT_NAME, "R518"), | ||
589 | DMI_MATCH(DMI_BOARD_NAME, "R518"), | ||
590 | }, | ||
591 | .callback = dmi_check_cb, | ||
592 | }, | ||
593 | { | ||
594 | .ident = "R519/R719", | ||
595 | .matches = { | ||
596 | DMI_MATCH(DMI_SYS_VENDOR, | ||
597 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
598 | DMI_MATCH(DMI_PRODUCT_NAME, "R519/R719"), | ||
599 | DMI_MATCH(DMI_BOARD_NAME, "R519/R719"), | ||
600 | }, | ||
601 | .callback = dmi_check_cb, | ||
602 | }, | ||
603 | { | ||
604 | .ident = "N150/N210/N220/N230", | ||
605 | .matches = { | ||
606 | DMI_MATCH(DMI_SYS_VENDOR, | ||
607 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
608 | DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220/N230"), | ||
609 | DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220/N230"), | ||
610 | }, | ||
611 | .callback = dmi_check_cb, | ||
612 | }, | ||
613 | { | ||
614 | .ident = "N150P/N210P/N220P", | ||
615 | .matches = { | ||
616 | DMI_MATCH(DMI_SYS_VENDOR, | ||
617 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
618 | DMI_MATCH(DMI_PRODUCT_NAME, "N150P/N210P/N220P"), | ||
619 | DMI_MATCH(DMI_BOARD_NAME, "N150P/N210P/N220P"), | ||
620 | }, | ||
621 | .callback = dmi_check_cb, | ||
622 | }, | ||
623 | { | ||
624 | .ident = "R530/R730", | ||
625 | .matches = { | ||
626 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
627 | DMI_MATCH(DMI_PRODUCT_NAME, "R530/R730"), | ||
628 | DMI_MATCH(DMI_BOARD_NAME, "R530/R730"), | ||
629 | }, | ||
630 | .callback = dmi_check_cb, | ||
631 | }, | ||
632 | { | ||
633 | .ident = "NF110/NF210/NF310", | ||
634 | .matches = { | ||
635 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
636 | DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"), | ||
637 | DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"), | ||
638 | }, | ||
639 | .callback = dmi_check_cb, | ||
640 | }, | ||
641 | { | ||
642 | .ident = "N145P/N250P/N260P", | ||
643 | .matches = { | ||
644 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
645 | DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"), | ||
646 | DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"), | ||
647 | }, | ||
648 | .callback = dmi_check_cb, | ||
649 | }, | ||
650 | { | ||
651 | .ident = "R70/R71", | ||
652 | .matches = { | ||
653 | DMI_MATCH(DMI_SYS_VENDOR, | ||
654 | "SAMSUNG ELECTRONICS CO., LTD."), | ||
655 | DMI_MATCH(DMI_PRODUCT_NAME, "R70/R71"), | ||
656 | DMI_MATCH(DMI_BOARD_NAME, "R70/R71"), | ||
657 | }, | ||
658 | .callback = dmi_check_cb, | ||
659 | }, | ||
660 | { | ||
661 | .ident = "P460", | ||
662 | .matches = { | ||
663 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | ||
664 | DMI_MATCH(DMI_PRODUCT_NAME, "P460"), | ||
665 | DMI_MATCH(DMI_BOARD_NAME, "P460"), | ||
666 | }, | ||
667 | .callback = dmi_check_cb, | ||
668 | }, | ||
669 | { }, | ||
670 | }; | ||
671 | MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); | ||
672 | |||
673 | static int find_signature(void __iomem *memcheck, const char *testStr) | ||
674 | { | ||
675 | int i = 0; | ||
676 | int loca; | ||
677 | |||
678 | for (loca = 0; loca < 0xffff; loca++) { | ||
679 | char temp = readb(memcheck + loca); | ||
680 | |||
681 | if (temp == testStr[i]) { | ||
682 | if (i == strlen(testStr)-1) | ||
683 | break; | ||
684 | ++i; | ||
685 | } else { | ||
686 | i = 0; | ||
687 | } | ||
688 | } | ||
689 | return loca; | ||
690 | } | ||
691 | |||
692 | static int __init samsung_init(void) | ||
693 | { | ||
694 | struct backlight_properties props; | ||
695 | struct sabi_retval sretval; | ||
696 | unsigned int ifaceP; | ||
697 | int i; | ||
698 | int loca; | ||
699 | int retval; | ||
700 | |||
701 | mutex_init(&sabi_mutex); | ||
702 | |||
703 | if (!force && !dmi_check_system(samsung_dmi_table)) | ||
704 | return -ENODEV; | ||
705 | |||
706 | f0000_segment = ioremap_nocache(0xf0000, 0xffff); | ||
707 | if (!f0000_segment) { | ||
708 | pr_err("Can't map the segment at 0xf0000\n"); | ||
709 | return -EINVAL; | ||
710 | } | ||
711 | |||
712 | /* Try to find one of the signatures in memory to find the header */ | ||
713 | for (i = 0; sabi_configs[i].test_string != 0; ++i) { | ||
714 | sabi_config = &sabi_configs[i]; | ||
715 | loca = find_signature(f0000_segment, sabi_config->test_string); | ||
716 | if (loca != 0xffff) | ||
717 | break; | ||
718 | } | ||
719 | |||
720 | if (loca == 0xffff) { | ||
721 | pr_err("This computer does not support SABI\n"); | ||
722 | goto error_no_signature; | ||
723 | } | ||
724 | |||
725 | /* point to the SMI port Number */ | ||
726 | loca += 1; | ||
727 | sabi = (f0000_segment + loca); | ||
728 | |||
729 | if (debug) { | ||
730 | printk(KERN_DEBUG "This computer supports SABI==%x\n", | ||
731 | loca + 0xf0000 - 6); | ||
732 | printk(KERN_DEBUG "SABI header:\n"); | ||
733 | printk(KERN_DEBUG " SMI Port Number = 0x%04x\n", | ||
734 | readw(sabi + sabi_config->header_offsets.port)); | ||
735 | printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n", | ||
736 | readb(sabi + sabi_config->header_offsets.iface_func)); | ||
737 | printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n", | ||
738 | readb(sabi + sabi_config->header_offsets.en_mem)); | ||
739 | printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n", | ||
740 | readb(sabi + sabi_config->header_offsets.re_mem)); | ||
741 | printk(KERN_DEBUG " SABI data offset = 0x%04x\n", | ||
742 | readw(sabi + sabi_config->header_offsets.data_offset)); | ||
743 | printk(KERN_DEBUG " SABI data segment = 0x%04x\n", | ||
744 | readw(sabi + sabi_config->header_offsets.data_segment)); | ||
745 | } | ||
746 | |||
747 | /* Get a pointer to the SABI Interface */ | ||
748 | ifaceP = (readw(sabi + sabi_config->header_offsets.data_segment) & 0x0ffff) << 4; | ||
749 | ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff; | ||
750 | sabi_iface = ioremap_nocache(ifaceP, 16); | ||
751 | if (!sabi_iface) { | ||
752 | pr_err("Can't remap %x\n", ifaceP); | ||
753 | goto exit; | ||
754 | } | ||
755 | if (debug) { | ||
756 | printk(KERN_DEBUG "ifaceP = 0x%08x\n", ifaceP); | ||
757 | printk(KERN_DEBUG "sabi_iface = %p\n", sabi_iface); | ||
758 | |||
759 | test_backlight(); | ||
760 | test_wireless(); | ||
761 | |||
762 | retval = sabi_get_command(sabi_config->commands.get_brightness, | ||
763 | &sretval); | ||
764 | printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]); | ||
765 | } | ||
766 | |||
767 | /* Turn on "Linux" mode in the BIOS */ | ||
768 | if (sabi_config->commands.set_linux != 0xff) { | ||
769 | retval = sabi_set_command(sabi_config->commands.set_linux, | ||
770 | 0x81); | ||
771 | if (retval) { | ||
772 | pr_warn("Linux mode was not set!\n"); | ||
773 | goto error_no_platform; | ||
774 | } | ||
775 | } | ||
776 | |||
777 | /* knock up a platform device to hang stuff off of */ | ||
778 | sdev = platform_device_register_simple("samsung", -1, NULL, 0); | ||
779 | if (IS_ERR(sdev)) | ||
780 | goto error_no_platform; | ||
781 | |||
782 | /* create a backlight device to talk to this one */ | ||
783 | memset(&props, 0, sizeof(struct backlight_properties)); | ||
784 | props.type = BACKLIGHT_PLATFORM; | ||
785 | props.max_brightness = sabi_config->max_brightness; | ||
786 | backlight_device = backlight_device_register("samsung", &sdev->dev, | ||
787 | NULL, &backlight_ops, | ||
788 | &props); | ||
789 | if (IS_ERR(backlight_device)) | ||
790 | goto error_no_backlight; | ||
791 | |||
792 | backlight_device->props.brightness = read_brightness(); | ||
793 | backlight_device->props.power = FB_BLANK_UNBLANK; | ||
794 | backlight_update_status(backlight_device); | ||
795 | |||
796 | retval = init_wireless(sdev); | ||
797 | if (retval) | ||
798 | goto error_no_rfk; | ||
799 | |||
800 | retval = device_create_file(&sdev->dev, &dev_attr_performance_level); | ||
801 | if (retval) | ||
802 | goto error_file_create; | ||
803 | |||
804 | exit: | ||
805 | return 0; | ||
806 | |||
807 | error_file_create: | ||
808 | destroy_wireless(); | ||
809 | |||
810 | error_no_rfk: | ||
811 | backlight_device_unregister(backlight_device); | ||
812 | |||
813 | error_no_backlight: | ||
814 | platform_device_unregister(sdev); | ||
815 | |||
816 | error_no_platform: | ||
817 | iounmap(sabi_iface); | ||
818 | |||
819 | error_no_signature: | ||
820 | iounmap(f0000_segment); | ||
821 | return -EINVAL; | ||
822 | } | ||
823 | |||
824 | static void __exit samsung_exit(void) | ||
825 | { | ||
826 | /* Turn off "Linux" mode in the BIOS */ | ||
827 | if (sabi_config->commands.set_linux != 0xff) | ||
828 | sabi_set_command(sabi_config->commands.set_linux, 0x80); | ||
829 | |||
830 | device_remove_file(&sdev->dev, &dev_attr_performance_level); | ||
831 | backlight_device_unregister(backlight_device); | ||
832 | destroy_wireless(); | ||
833 | iounmap(sabi_iface); | ||
834 | iounmap(f0000_segment); | ||
835 | platform_device_unregister(sdev); | ||
836 | } | ||
837 | |||
838 | module_init(samsung_init); | ||
839 | module_exit(samsung_exit); | ||
840 | |||
841 | MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>"); | ||
842 | MODULE_DESCRIPTION("Samsung Backlight driver"); | ||
843 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/staging/solo6x10/Kconfig b/drivers/staging/solo6x10/Kconfig index 2cf77c940860..03dcac4ea4d0 100644 --- a/drivers/staging/solo6x10/Kconfig +++ b/drivers/staging/solo6x10/Kconfig | |||
@@ -2,6 +2,7 @@ config SOLO6X10 | |||
2 | tristate "Softlogic 6x10 MPEG codec cards" | 2 | tristate "Softlogic 6x10 MPEG codec cards" |
3 | depends on PCI && VIDEO_DEV && SND && I2C | 3 | depends on PCI && VIDEO_DEV && SND && I2C |
4 | select VIDEOBUF_DMA_SG | 4 | select VIDEOBUF_DMA_SG |
5 | select SND_PCM | ||
5 | ---help--- | 6 | ---help--- |
6 | This driver supports the Softlogic based MPEG-4 and h.264 codec | 7 | This driver supports the Softlogic based MPEG-4 and h.264 codec |
7 | codec cards. | 8 | codec cards. |
diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index 20dae73d3b78..506547b603e1 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c | |||
@@ -653,7 +653,7 @@ static int SBD_setup_device(struct spectra_nand_dev *dev, int which) | |||
653 | } | 653 | } |
654 | dev->queue->queuedata = dev; | 654 | dev->queue->queuedata = dev; |
655 | 655 | ||
656 | /* As Linux block layer does't support >4KB hardware sector, */ | 656 | /* As Linux block layer doesn't support >4KB hardware sector, */ |
657 | /* Here we force report 512 byte hardware sector size to Kernel */ | 657 | /* Here we force report 512 byte hardware sector size to Kernel */ |
658 | blk_queue_logical_block_size(dev->queue, 512); | 658 | blk_queue_logical_block_size(dev->queue, 512); |
659 | 659 | ||
diff --git a/drivers/staging/tidspbridge/dynload/cload.c b/drivers/staging/tidspbridge/dynload/cload.c index 5cecd237e3f6..fe1ef0addb09 100644 --- a/drivers/staging/tidspbridge/dynload/cload.c +++ b/drivers/staging/tidspbridge/dynload/cload.c | |||
@@ -718,7 +718,7 @@ static void dload_symbols(struct dload_state *dlthis) | |||
718 | * as a temporary for .dllview record construction. | 718 | * as a temporary for .dllview record construction. |
719 | * Allocate storage for the whole table. Add 1 to the section count | 719 | * Allocate storage for the whole table. Add 1 to the section count |
720 | * in case a trampoline section is auto-generated as well as the | 720 | * in case a trampoline section is auto-generated as well as the |
721 | * size of the trampoline section name so DLLView does't get lost. | 721 | * size of the trampoline section name so DLLView doesn't get lost. |
722 | */ | 722 | */ |
723 | 723 | ||
724 | siz = sym_count * sizeof(struct local_symbol); | 724 | siz = sym_count * sizeof(struct local_symbol); |
diff --git a/drivers/staging/tty/specialix.c b/drivers/staging/tty/specialix.c index cb24c6d999db..5c3598ec7456 100644 --- a/drivers/staging/tty/specialix.c +++ b/drivers/staging/tty/specialix.c | |||
@@ -978,7 +978,7 @@ static void sx_change_speed(struct specialix_board *bp, | |||
978 | spin_lock_irqsave(&bp->lock, flags); | 978 | spin_lock_irqsave(&bp->lock, flags); |
979 | sx_out(bp, CD186x_CAR, port_No(port)); | 979 | sx_out(bp, CD186x_CAR, port_No(port)); |
980 | 980 | ||
981 | /* The Specialix board does't implement the RTS lines. | 981 | /* The Specialix board doesn't implement the RTS lines. |
982 | They are used to set the IRQ level. Don't touch them. */ | 982 | They are used to set the IRQ level. Don't touch them. */ |
983 | if (sx_crtscts(tty)) | 983 | if (sx_crtscts(tty)) |
984 | port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); | 984 | port->MSVR = MSVR_DTR | (sx_in(bp, CD186x_MSVR) & MSVR_RTS); |
diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index 0f02a4b12ae4..4f4f13321f40 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c | |||
@@ -876,8 +876,10 @@ static void vhci_shutdown_connection(struct usbip_device *ud) | |||
876 | } | 876 | } |
877 | 877 | ||
878 | /* kill threads related to this sdev, if v.c. exists */ | 878 | /* kill threads related to this sdev, if v.c. exists */ |
879 | kthread_stop(vdev->ud.tcp_rx); | 879 | if (vdev->ud.tcp_rx) |
880 | kthread_stop(vdev->ud.tcp_tx); | 880 | kthread_stop(vdev->ud.tcp_rx); |
881 | if (vdev->ud.tcp_tx) | ||
882 | kthread_stop(vdev->ud.tcp_tx); | ||
881 | 883 | ||
882 | usbip_uinfo("stop threads\n"); | 884 | usbip_uinfo("stop threads\n"); |
883 | 885 | ||
@@ -949,9 +951,6 @@ static void vhci_device_init(struct vhci_device *vdev) | |||
949 | { | 951 | { |
950 | memset(vdev, 0, sizeof(*vdev)); | 952 | memset(vdev, 0, sizeof(*vdev)); |
951 | 953 | ||
952 | vdev->ud.tcp_rx = kthread_create(vhci_rx_loop, &vdev->ud, "vhci_rx"); | ||
953 | vdev->ud.tcp_tx = kthread_create(vhci_tx_loop, &vdev->ud, "vhci_tx"); | ||
954 | |||
955 | vdev->ud.side = USBIP_VHCI; | 954 | vdev->ud.side = USBIP_VHCI; |
956 | vdev->ud.status = VDEV_ST_NULL; | 955 | vdev->ud.status = VDEV_ST_NULL; |
957 | /* vdev->ud.lock = SPIN_LOCK_UNLOCKED; */ | 956 | /* vdev->ud.lock = SPIN_LOCK_UNLOCKED; */ |
@@ -1139,7 +1138,7 @@ static int vhci_hcd_probe(struct platform_device *pdev) | |||
1139 | usbip_uerr("create hcd failed\n"); | 1138 | usbip_uerr("create hcd failed\n"); |
1140 | return -ENOMEM; | 1139 | return -ENOMEM; |
1141 | } | 1140 | } |
1142 | 1141 | hcd->has_tt = 1; | |
1143 | 1142 | ||
1144 | /* this is private data for vhci_hcd */ | 1143 | /* this is private data for vhci_hcd */ |
1145 | the_controller = hcd_to_vhci(hcd); | 1144 | the_controller = hcd_to_vhci(hcd); |
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c index 3f2459f30415..e2dadbd5ef1e 100644 --- a/drivers/staging/usbip/vhci_sysfs.c +++ b/drivers/staging/usbip/vhci_sysfs.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "vhci.h" | 21 | #include "vhci.h" |
22 | 22 | ||
23 | #include <linux/in.h> | 23 | #include <linux/in.h> |
24 | #include <linux/kthread.h> | ||
24 | 25 | ||
25 | /* TODO: refine locking ?*/ | 26 | /* TODO: refine locking ?*/ |
26 | 27 | ||
@@ -220,13 +221,13 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr, | |||
220 | vdev->ud.tcp_socket = socket; | 221 | vdev->ud.tcp_socket = socket; |
221 | vdev->ud.status = VDEV_ST_NOTASSIGNED; | 222 | vdev->ud.status = VDEV_ST_NOTASSIGNED; |
222 | 223 | ||
223 | wake_up_process(vdev->ud.tcp_rx); | ||
224 | wake_up_process(vdev->ud.tcp_tx); | ||
225 | |||
226 | spin_unlock(&vdev->ud.lock); | 224 | spin_unlock(&vdev->ud.lock); |
227 | spin_unlock(&the_controller->lock); | 225 | spin_unlock(&the_controller->lock); |
228 | /* end the lock */ | 226 | /* end the lock */ |
229 | 227 | ||
228 | vdev->ud.tcp_rx = kthread_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); | ||
229 | vdev->ud.tcp_tx = kthread_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); | ||
230 | |||
230 | rh_port_connect(rhport, speed); | 231 | rh_port_connect(rhport, speed); |
231 | 232 | ||
232 | return count; | 233 | return count; |
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index 6a71f52c59b1..76378397b763 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -273,7 +273,7 @@ exit: | |||
273 | } | 273 | } |
274 | 274 | ||
275 | int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev, | 275 | int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev, |
276 | u8 key_index) | 276 | u8 key_index, bool unicast, bool multicast) |
277 | { | 277 | { |
278 | wlandevice_t *wlandev = dev->ml_priv; | 278 | wlandevice_t *wlandev = dev->ml_priv; |
279 | 279 | ||
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 47f8cdb207f1..74273e638c0d 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -1658,8 +1658,12 @@ static void gsm_queue(struct gsm_mux *gsm) | |||
1658 | 1658 | ||
1659 | if ((gsm->control & ~PF) == UI) | 1659 | if ((gsm->control & ~PF) == UI) |
1660 | gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len); | 1660 | gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len); |
1661 | /* generate final CRC with received FCS */ | 1661 | if (gsm->encoding == 0){ |
1662 | gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs); | 1662 | /* WARNING: gsm->received_fcs is used for gsm->encoding = 0 only. |
1663 | In this case it contain the last piece of data | ||
1664 | required to generate final CRC */ | ||
1665 | gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs); | ||
1666 | } | ||
1663 | if (gsm->fcs != GOOD_FCS) { | 1667 | if (gsm->fcs != GOOD_FCS) { |
1664 | gsm->bad_fcs++; | 1668 | gsm->bad_fcs++; |
1665 | if (debug & 4) | 1669 | if (debug & 4) |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index cb36b0d4ef3c..62df72d9f0aa 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -382,12 +382,13 @@ static void imx_start_tx(struct uart_port *port) | |||
382 | static irqreturn_t imx_rtsint(int irq, void *dev_id) | 382 | static irqreturn_t imx_rtsint(int irq, void *dev_id) |
383 | { | 383 | { |
384 | struct imx_port *sport = dev_id; | 384 | struct imx_port *sport = dev_id; |
385 | unsigned int val = readl(sport->port.membase + USR1) & USR1_RTSS; | 385 | unsigned int val; |
386 | unsigned long flags; | 386 | unsigned long flags; |
387 | 387 | ||
388 | spin_lock_irqsave(&sport->port.lock, flags); | 388 | spin_lock_irqsave(&sport->port.lock, flags); |
389 | 389 | ||
390 | writel(USR1_RTSD, sport->port.membase + USR1); | 390 | writel(USR1_RTSD, sport->port.membase + USR1); |
391 | val = readl(sport->port.membase + USR1) & USR1_RTSS; | ||
391 | uart_handle_cts_change(&sport->port, !!val); | 392 | uart_handle_cts_change(&sport->port, !!val); |
392 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); | 393 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
393 | 394 | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 41b6e51188e4..006489d82dc3 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -66,6 +66,7 @@ config USB_ARCH_HAS_EHCI | |||
66 | default y if ARCH_VT8500 | 66 | default y if ARCH_VT8500 |
67 | default y if PLAT_SPEAR | 67 | default y if PLAT_SPEAR |
68 | default y if ARCH_MSM | 68 | default y if ARCH_MSM |
69 | default y if MICROBLAZE | ||
69 | default PCI | 70 | default PCI |
70 | 71 | ||
71 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. | 72 | # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface. |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index a3d2e2399655..96fdfb815f89 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -221,7 +221,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end, | |||
221 | break; | 221 | break; |
222 | case USB_ENDPOINT_XFER_INT: | 222 | case USB_ENDPOINT_XFER_INT: |
223 | type = "Int."; | 223 | type = "Int."; |
224 | if (speed == USB_SPEED_HIGH) | 224 | if (speed == USB_SPEED_HIGH || speed == USB_SPEED_SUPER) |
225 | interval = 1 << (desc->bInterval - 1); | 225 | interval = 1 << (desc->bInterval - 1); |
226 | else | 226 | else |
227 | interval = desc->bInterval; | 227 | interval = desc->bInterval; |
@@ -229,7 +229,8 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end, | |||
229 | default: /* "can't happen" */ | 229 | default: /* "can't happen" */ |
230 | return start; | 230 | return start; |
231 | } | 231 | } |
232 | interval *= (speed == USB_SPEED_HIGH) ? 125 : 1000; | 232 | interval *= (speed == USB_SPEED_HIGH || |
233 | speed == USB_SPEED_SUPER) ? 125 : 1000; | ||
233 | if (interval % 1000) | 234 | if (interval % 1000) |
234 | unit = 'u'; | 235 | unit = 'u'; |
235 | else { | 236 | else { |
@@ -542,8 +543,9 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, | |||
542 | if (level == 0) { | 543 | if (level == 0) { |
543 | int max; | 544 | int max; |
544 | 545 | ||
545 | /* high speed reserves 80%, full/low reserves 90% */ | 546 | /* super/high speed reserves 80%, full/low reserves 90% */ |
546 | if (usbdev->speed == USB_SPEED_HIGH) | 547 | if (usbdev->speed == USB_SPEED_HIGH || |
548 | usbdev->speed == USB_SPEED_SUPER) | ||
547 | max = 800; | 549 | max = 800; |
548 | else | 550 | else |
549 | max = FRAME_TIME_MAX_USECS_ALLOC; | 551 | max = FRAME_TIME_MAX_USECS_ALLOC; |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8eed05d23838..77a7faec8d78 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1908,7 +1908,7 @@ void usb_free_streams(struct usb_interface *interface, | |||
1908 | 1908 | ||
1909 | /* Streams only apply to bulk endpoints. */ | 1909 | /* Streams only apply to bulk endpoints. */ |
1910 | for (i = 0; i < num_eps; i++) | 1910 | for (i = 0; i < num_eps; i++) |
1911 | if (!usb_endpoint_xfer_bulk(&eps[i]->desc)) | 1911 | if (!eps[i] || !usb_endpoint_xfer_bulk(&eps[i]->desc)) |
1912 | return; | 1912 | return; |
1913 | 1913 | ||
1914 | hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); | 1914 | hcd->driver->free_streams(hcd, dev, eps, num_eps, mem_flags); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 8fb754916c67..93720bdc9efd 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -2285,7 +2285,17 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2285 | } | 2285 | } |
2286 | 2286 | ||
2287 | /* see 7.1.7.6 */ | 2287 | /* see 7.1.7.6 */ |
2288 | status = set_port_feature(hub->hdev, port1, USB_PORT_FEAT_SUSPEND); | 2288 | /* Clear PORT_POWER if it's a USB3.0 device connected to USB 3.0 |
2289 | * external hub. | ||
2290 | * FIXME: this is a temporary workaround to make the system able | ||
2291 | * to suspend/resume. | ||
2292 | */ | ||
2293 | if ((hub->hdev->parent != NULL) && hub_is_superspeed(hub->hdev)) | ||
2294 | status = clear_port_feature(hub->hdev, port1, | ||
2295 | USB_PORT_FEAT_POWER); | ||
2296 | else | ||
2297 | status = set_port_feature(hub->hdev, port1, | ||
2298 | USB_PORT_FEAT_SUSPEND); | ||
2289 | if (status) { | 2299 | if (status) { |
2290 | dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", | 2300 | dev_dbg(hub->intfdev, "can't suspend port %d, status %d\n", |
2291 | port1, status); | 2301 | port1, status); |
diff --git a/drivers/usb/gadget/f_audio.c b/drivers/usb/gadget/f_audio.c index 9abecfddb27d..0111f8a9cf7f 100644 --- a/drivers/usb/gadget/f_audio.c +++ b/drivers/usb/gadget/f_audio.c | |||
@@ -706,6 +706,7 @@ f_audio_unbind(struct usb_configuration *c, struct usb_function *f) | |||
706 | struct f_audio *audio = func_to_audio(f); | 706 | struct f_audio *audio = func_to_audio(f); |
707 | 707 | ||
708 | usb_free_descriptors(f->descriptors); | 708 | usb_free_descriptors(f->descriptors); |
709 | usb_free_descriptors(f->hs_descriptors); | ||
709 | kfree(audio); | 710 | kfree(audio); |
710 | } | 711 | } |
711 | 712 | ||
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c index 95dd4662d6a8..b3c304290150 100644 --- a/drivers/usb/gadget/f_eem.c +++ b/drivers/usb/gadget/f_eem.c | |||
@@ -314,6 +314,9 @@ eem_unbind(struct usb_configuration *c, struct usb_function *f) | |||
314 | 314 | ||
315 | static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req) | 315 | static void eem_cmd_complete(struct usb_ep *ep, struct usb_request *req) |
316 | { | 316 | { |
317 | struct sk_buff *skb = (struct sk_buff *)req->context; | ||
318 | |||
319 | dev_kfree_skb_any(skb); | ||
317 | } | 320 | } |
318 | 321 | ||
319 | /* | 322 | /* |
@@ -428,10 +431,11 @@ static int eem_unwrap(struct gether *port, | |||
428 | skb_trim(skb2, len); | 431 | skb_trim(skb2, len); |
429 | put_unaligned_le16(BIT(15) | BIT(11) | len, | 432 | put_unaligned_le16(BIT(15) | BIT(11) | len, |
430 | skb_push(skb2, 2)); | 433 | skb_push(skb2, 2)); |
431 | skb_copy_bits(skb, 0, req->buf, skb->len); | 434 | skb_copy_bits(skb2, 0, req->buf, skb2->len); |
432 | req->length = skb->len; | 435 | req->length = skb2->len; |
433 | req->complete = eem_cmd_complete; | 436 | req->complete = eem_cmd_complete; |
434 | req->zero = 1; | 437 | req->zero = 1; |
438 | req->context = skb2; | ||
435 | if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) | 439 | if (usb_ep_queue(port->in_ep, req, GFP_ATOMIC)) |
436 | DBG(cdev, "echo response queue fail\n"); | 440 | DBG(cdev, "echo response queue fail\n"); |
437 | break; | 441 | break; |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index aee7e3c53c38..36613b37c504 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -1148,6 +1148,12 @@ static int qe_ep_tx(struct qe_ep *ep, struct qe_frame *frame) | |||
1148 | static int txcomplete(struct qe_ep *ep, unsigned char restart) | 1148 | static int txcomplete(struct qe_ep *ep, unsigned char restart) |
1149 | { | 1149 | { |
1150 | if (ep->tx_req != NULL) { | 1150 | if (ep->tx_req != NULL) { |
1151 | struct qe_req *req = ep->tx_req; | ||
1152 | unsigned zlp = 0, last_len = 0; | ||
1153 | |||
1154 | last_len = min_t(unsigned, req->req.length - ep->sent, | ||
1155 | ep->ep.maxpacket); | ||
1156 | |||
1151 | if (!restart) { | 1157 | if (!restart) { |
1152 | int asent = ep->last; | 1158 | int asent = ep->last; |
1153 | ep->sent += asent; | 1159 | ep->sent += asent; |
@@ -1156,9 +1162,18 @@ static int txcomplete(struct qe_ep *ep, unsigned char restart) | |||
1156 | ep->last = 0; | 1162 | ep->last = 0; |
1157 | } | 1163 | } |
1158 | 1164 | ||
1165 | /* zlp needed when req->re.zero is set */ | ||
1166 | if (req->req.zero) { | ||
1167 | if (last_len == 0 || | ||
1168 | (req->req.length % ep->ep.maxpacket) != 0) | ||
1169 | zlp = 0; | ||
1170 | else | ||
1171 | zlp = 1; | ||
1172 | } else | ||
1173 | zlp = 0; | ||
1174 | |||
1159 | /* a request already were transmitted completely */ | 1175 | /* a request already were transmitted completely */ |
1160 | if ((ep->tx_req->req.length - ep->sent) <= 0) { | 1176 | if (((ep->tx_req->req.length - ep->sent) <= 0) && !zlp) { |
1161 | ep->tx_req->req.actual = (unsigned int)ep->sent; | ||
1162 | done(ep, ep->tx_req, 0); | 1177 | done(ep, ep->tx_req, 0); |
1163 | ep->tx_req = NULL; | 1178 | ep->tx_req = NULL; |
1164 | ep->last = 0; | 1179 | ep->last = 0; |
@@ -1191,6 +1206,7 @@ static int qe_usb_senddata(struct qe_ep *ep, struct qe_frame *frame) | |||
1191 | buf = (u8 *)ep->tx_req->req.buf + ep->sent; | 1206 | buf = (u8 *)ep->tx_req->req.buf + ep->sent; |
1192 | if (buf && size) { | 1207 | if (buf && size) { |
1193 | ep->last = size; | 1208 | ep->last = size; |
1209 | ep->tx_req->req.actual += size; | ||
1194 | frame_set_data(frame, buf); | 1210 | frame_set_data(frame, buf); |
1195 | frame_set_length(frame, size); | 1211 | frame_set_length(frame, size); |
1196 | frame_set_status(frame, FRAME_OK); | 1212 | frame_set_status(frame, FRAME_OK); |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 3ed73f49cf18..a01383f71f38 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -386,8 +386,10 @@ ep_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
386 | 386 | ||
387 | /* halt any endpoint by doing a "wrong direction" i/o call */ | 387 | /* halt any endpoint by doing a "wrong direction" i/o call */ |
388 | if (usb_endpoint_dir_in(&data->desc)) { | 388 | if (usb_endpoint_dir_in(&data->desc)) { |
389 | if (usb_endpoint_xfer_isoc(&data->desc)) | 389 | if (usb_endpoint_xfer_isoc(&data->desc)) { |
390 | mutex_unlock(&data->lock); | ||
390 | return -EINVAL; | 391 | return -EINVAL; |
392 | } | ||
391 | DBG (data->dev, "%s halt\n", data->name); | 393 | DBG (data->dev, "%s halt\n", data->name); |
392 | spin_lock_irq (&data->dev->lock); | 394 | spin_lock_irq (&data->dev->lock); |
393 | if (likely (data->ep != NULL)) | 395 | if (likely (data->ep != NULL)) |
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 3e4b35e50c24..68dbcc3e4cc2 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c | |||
@@ -1608,7 +1608,7 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq, | |||
1608 | return -EINVAL; | 1608 | return -EINVAL; |
1609 | if (!dev->driver || (dev->gadget.speed == USB_SPEED_UNKNOWN)) | 1609 | if (!dev->driver || (dev->gadget.speed == USB_SPEED_UNKNOWN)) |
1610 | return -ESHUTDOWN; | 1610 | return -ESHUTDOWN; |
1611 | spin_lock_irqsave(&ep->dev->lock, iflags); | 1611 | spin_lock_irqsave(&dev->lock, iflags); |
1612 | /* map the buffer for dma */ | 1612 | /* map the buffer for dma */ |
1613 | if (usbreq->length && | 1613 | if (usbreq->length && |
1614 | ((usbreq->dma == DMA_ADDR_INVALID) || !usbreq->dma)) { | 1614 | ((usbreq->dma == DMA_ADDR_INVALID) || !usbreq->dma)) { |
@@ -1625,8 +1625,10 @@ static int pch_udc_pcd_queue(struct usb_ep *usbep, struct usb_request *usbreq, | |||
1625 | DMA_FROM_DEVICE); | 1625 | DMA_FROM_DEVICE); |
1626 | } else { | 1626 | } else { |
1627 | req->buf = kzalloc(usbreq->length, GFP_ATOMIC); | 1627 | req->buf = kzalloc(usbreq->length, GFP_ATOMIC); |
1628 | if (!req->buf) | 1628 | if (!req->buf) { |
1629 | return -ENOMEM; | 1629 | retval = -ENOMEM; |
1630 | goto probe_end; | ||
1631 | } | ||
1630 | if (ep->in) { | 1632 | if (ep->in) { |
1631 | memcpy(req->buf, usbreq->buf, usbreq->length); | 1633 | memcpy(req->buf, usbreq->buf, usbreq->length); |
1632 | req->dma = dma_map_single(&dev->pdev->dev, | 1634 | req->dma = dma_map_single(&dev->pdev->dev, |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index 015118535f77..6dcc1f68fa60 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1083,7 +1083,9 @@ static void irq_device_state(struct r8a66597 *r8a66597) | |||
1083 | 1083 | ||
1084 | if (dvsq == DS_DFLT) { | 1084 | if (dvsq == DS_DFLT) { |
1085 | /* bus reset */ | 1085 | /* bus reset */ |
1086 | spin_unlock(&r8a66597->lock); | ||
1086 | r8a66597->driver->disconnect(&r8a66597->gadget); | 1087 | r8a66597->driver->disconnect(&r8a66597->gadget); |
1088 | spin_lock(&r8a66597->lock); | ||
1087 | r8a66597_update_usb_speed(r8a66597); | 1089 | r8a66597_update_usb_speed(r8a66597); |
1088 | } | 1090 | } |
1089 | if (r8a66597->old_dvsq == DS_CNFG && dvsq != DS_CNFG) | 1091 | if (r8a66597->old_dvsq == DS_CNFG && dvsq != DS_CNFG) |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index 7e41a95c5ceb..627f3a678759 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | #include <linux/usb/ulpi.h> | 41 | #include <linux/usb/ulpi.h> |
42 | #include <plat/usb.h> | 42 | #include <plat/usb.h> |
43 | #include <linux/regulator/consumer.h> | ||
43 | 44 | ||
44 | /* EHCI Register Set */ | 45 | /* EHCI Register Set */ |
45 | #define EHCI_INSNREG04 (0xA0) | 46 | #define EHCI_INSNREG04 (0xA0) |
@@ -118,6 +119,8 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
118 | struct ehci_hcd *omap_ehci; | 119 | struct ehci_hcd *omap_ehci; |
119 | int ret = -ENODEV; | 120 | int ret = -ENODEV; |
120 | int irq; | 121 | int irq; |
122 | int i; | ||
123 | char supply[7]; | ||
121 | 124 | ||
122 | if (usb_disabled()) | 125 | if (usb_disabled()) |
123 | return -ENODEV; | 126 | return -ENODEV; |
@@ -158,6 +161,23 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
158 | hcd->rsrc_len = resource_size(res); | 161 | hcd->rsrc_len = resource_size(res); |
159 | hcd->regs = regs; | 162 | hcd->regs = regs; |
160 | 163 | ||
164 | /* get ehci regulator and enable */ | ||
165 | for (i = 0 ; i < OMAP3_HS_USB_PORTS ; i++) { | ||
166 | if (pdata->port_mode[i] != OMAP_EHCI_PORT_MODE_PHY) { | ||
167 | pdata->regulator[i] = NULL; | ||
168 | continue; | ||
169 | } | ||
170 | snprintf(supply, sizeof(supply), "hsusb%d", i); | ||
171 | pdata->regulator[i] = regulator_get(dev, supply); | ||
172 | if (IS_ERR(pdata->regulator[i])) { | ||
173 | pdata->regulator[i] = NULL; | ||
174 | dev_dbg(dev, | ||
175 | "failed to get ehci port%d regulator\n", i); | ||
176 | } else { | ||
177 | regulator_enable(pdata->regulator[i]); | ||
178 | } | ||
179 | } | ||
180 | |||
161 | ret = omap_usbhs_enable(dev); | 181 | ret = omap_usbhs_enable(dev); |
162 | if (ret) { | 182 | if (ret) { |
163 | dev_err(dev, "failed to start usbhs with err %d\n", ret); | 183 | dev_err(dev, "failed to start usbhs with err %d\n", ret); |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 98ded66e8d3f..42abd0f603bf 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -1247,24 +1247,27 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1247 | 1247 | ||
1248 | static void scan_async (struct ehci_hcd *ehci) | 1248 | static void scan_async (struct ehci_hcd *ehci) |
1249 | { | 1249 | { |
1250 | bool stopped; | ||
1250 | struct ehci_qh *qh; | 1251 | struct ehci_qh *qh; |
1251 | enum ehci_timer_action action = TIMER_IO_WATCHDOG; | 1252 | enum ehci_timer_action action = TIMER_IO_WATCHDOG; |
1252 | 1253 | ||
1253 | ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); | 1254 | ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index); |
1254 | timer_action_done (ehci, TIMER_ASYNC_SHRINK); | 1255 | timer_action_done (ehci, TIMER_ASYNC_SHRINK); |
1255 | rescan: | 1256 | rescan: |
1257 | stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state); | ||
1256 | qh = ehci->async->qh_next.qh; | 1258 | qh = ehci->async->qh_next.qh; |
1257 | if (likely (qh != NULL)) { | 1259 | if (likely (qh != NULL)) { |
1258 | do { | 1260 | do { |
1259 | /* clean any finished work for this qh */ | 1261 | /* clean any finished work for this qh */ |
1260 | if (!list_empty (&qh->qtd_list) | 1262 | if (!list_empty(&qh->qtd_list) && (stopped || |
1261 | && qh->stamp != ehci->stamp) { | 1263 | qh->stamp != ehci->stamp)) { |
1262 | int temp; | 1264 | int temp; |
1263 | 1265 | ||
1264 | /* unlinks could happen here; completion | 1266 | /* unlinks could happen here; completion |
1265 | * reporting drops the lock. rescan using | 1267 | * reporting drops the lock. rescan using |
1266 | * the latest schedule, but don't rescan | 1268 | * the latest schedule, but don't rescan |
1267 | * qhs we already finished (no looping). | 1269 | * qhs we already finished (no looping) |
1270 | * unless the controller is stopped. | ||
1268 | */ | 1271 | */ |
1269 | qh = qh_get (qh); | 1272 | qh = qh_get (qh); |
1270 | qh->stamp = ehci->stamp; | 1273 | qh->stamp = ehci->stamp; |
@@ -1285,9 +1288,9 @@ rescan: | |||
1285 | */ | 1288 | */ |
1286 | if (list_empty(&qh->qtd_list) | 1289 | if (list_empty(&qh->qtd_list) |
1287 | && qh->qh_state == QH_STATE_LINKED) { | 1290 | && qh->qh_state == QH_STATE_LINKED) { |
1288 | if (!ehci->reclaim | 1291 | if (!ehci->reclaim && (stopped || |
1289 | && ((ehci->stamp - qh->stamp) & 0x1fff) | 1292 | ((ehci->stamp - qh->stamp) & 0x1fff) |
1290 | >= (EHCI_SHRINK_FRAMES * 8)) | 1293 | >= EHCI_SHRINK_FRAMES * 8)) |
1291 | start_unlink_async(ehci, qh); | 1294 | start_unlink_async(ehci, qh); |
1292 | else | 1295 | else |
1293 | action = TIMER_ASYNC_SHRINK; | 1296 | action = TIMER_ASYNC_SHRINK; |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index f50e84ac570a..7b2e69aa2e98 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
@@ -295,7 +295,7 @@ static void alloc_mem(struct usb_hcd *hcd, struct isp1760_qtd *qtd) | |||
295 | } | 295 | } |
296 | 296 | ||
297 | dev_err(hcd->self.controller, | 297 | dev_err(hcd->self.controller, |
298 | "%s: Can not allocate %lu bytes of memory\n" | 298 | "%s: Cannot allocate %zu bytes of memory\n" |
299 | "Current memory map:\n", | 299 | "Current memory map:\n", |
300 | __func__, qtd->length); | 300 | __func__, qtd->length); |
301 | for (i = 0; i < BLOCKS; i++) { | 301 | for (i = 0; i < BLOCKS; i++) { |
@@ -1633,6 +1633,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1633 | ints[i].qh = NULL; | 1633 | ints[i].qh = NULL; |
1634 | ints[i].qtd = NULL; | 1634 | ints[i].qtd = NULL; |
1635 | 1635 | ||
1636 | urb->status = status; | ||
1636 | isp1760_urb_done(hcd, urb); | 1637 | isp1760_urb_done(hcd, urb); |
1637 | if (qtd) | 1638 | if (qtd) |
1638 | pe(hcd, qh, qtd); | 1639 | pe(hcd, qh, qtd); |
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 17a6043c1fa0..958d985f2951 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | #ifdef __LITTLE_ENDIAN | 34 | #ifdef __LITTLE_ENDIAN |
35 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C) | 35 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C) |
36 | #elif __BIG_ENDIAN | 36 | #elif defined(__BIG_ENDIAN) |
37 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | \ | 37 | #define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | \ |
38 | USBH_ENABLE_BE) | 38 | USBH_ENABLE_BE) |
39 | #else | 39 | #else |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 1d586d4f7b56..9b166d70ae91 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -84,65 +84,92 @@ int usb_amd_find_chipset_info(void) | |||
84 | { | 84 | { |
85 | u8 rev = 0; | 85 | u8 rev = 0; |
86 | unsigned long flags; | 86 | unsigned long flags; |
87 | struct amd_chipset_info info; | ||
88 | int ret; | ||
87 | 89 | ||
88 | spin_lock_irqsave(&amd_lock, flags); | 90 | spin_lock_irqsave(&amd_lock, flags); |
89 | 91 | ||
90 | amd_chipset.probe_count++; | ||
91 | /* probe only once */ | 92 | /* probe only once */ |
92 | if (amd_chipset.probe_count > 1) { | 93 | if (amd_chipset.probe_count > 0) { |
94 | amd_chipset.probe_count++; | ||
93 | spin_unlock_irqrestore(&amd_lock, flags); | 95 | spin_unlock_irqrestore(&amd_lock, flags); |
94 | return amd_chipset.probe_result; | 96 | return amd_chipset.probe_result; |
95 | } | 97 | } |
98 | memset(&info, 0, sizeof(info)); | ||
99 | spin_unlock_irqrestore(&amd_lock, flags); | ||
96 | 100 | ||
97 | amd_chipset.smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); | 101 | info.smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI, 0x4385, NULL); |
98 | if (amd_chipset.smbus_dev) { | 102 | if (info.smbus_dev) { |
99 | rev = amd_chipset.smbus_dev->revision; | 103 | rev = info.smbus_dev->revision; |
100 | if (rev >= 0x40) | 104 | if (rev >= 0x40) |
101 | amd_chipset.sb_type = 1; | 105 | info.sb_type = 1; |
102 | else if (rev >= 0x30 && rev <= 0x3b) | 106 | else if (rev >= 0x30 && rev <= 0x3b) |
103 | amd_chipset.sb_type = 3; | 107 | info.sb_type = 3; |
104 | } else { | 108 | } else { |
105 | amd_chipset.smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, | 109 | info.smbus_dev = pci_get_device(PCI_VENDOR_ID_AMD, |
106 | 0x780b, NULL); | 110 | 0x780b, NULL); |
107 | if (!amd_chipset.smbus_dev) { | 111 | if (!info.smbus_dev) { |
108 | spin_unlock_irqrestore(&amd_lock, flags); | 112 | ret = 0; |
109 | return 0; | 113 | goto commit; |
110 | } | 114 | } |
111 | rev = amd_chipset.smbus_dev->revision; | 115 | |
116 | rev = info.smbus_dev->revision; | ||
112 | if (rev >= 0x11 && rev <= 0x18) | 117 | if (rev >= 0x11 && rev <= 0x18) |
113 | amd_chipset.sb_type = 2; | 118 | info.sb_type = 2; |
114 | } | 119 | } |
115 | 120 | ||
116 | if (amd_chipset.sb_type == 0) { | 121 | if (info.sb_type == 0) { |
117 | if (amd_chipset.smbus_dev) { | 122 | if (info.smbus_dev) { |
118 | pci_dev_put(amd_chipset.smbus_dev); | 123 | pci_dev_put(info.smbus_dev); |
119 | amd_chipset.smbus_dev = NULL; | 124 | info.smbus_dev = NULL; |
120 | } | 125 | } |
121 | spin_unlock_irqrestore(&amd_lock, flags); | 126 | ret = 0; |
122 | return 0; | 127 | goto commit; |
123 | } | 128 | } |
124 | 129 | ||
125 | amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9601, NULL); | 130 | info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9601, NULL); |
126 | if (amd_chipset.nb_dev) { | 131 | if (info.nb_dev) { |
127 | amd_chipset.nb_type = 1; | 132 | info.nb_type = 1; |
128 | } else { | 133 | } else { |
129 | amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, | 134 | info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x1510, NULL); |
130 | 0x1510, NULL); | 135 | if (info.nb_dev) { |
131 | if (amd_chipset.nb_dev) { | 136 | info.nb_type = 2; |
132 | amd_chipset.nb_type = 2; | 137 | } else { |
133 | } else { | 138 | info.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, |
134 | amd_chipset.nb_dev = pci_get_device(PCI_VENDOR_ID_AMD, | 139 | 0x9600, NULL); |
135 | 0x9600, NULL); | 140 | if (info.nb_dev) |
136 | if (amd_chipset.nb_dev) | 141 | info.nb_type = 3; |
137 | amd_chipset.nb_type = 3; | ||
138 | } | 142 | } |
139 | } | 143 | } |
140 | 144 | ||
141 | amd_chipset.probe_result = 1; | 145 | ret = info.probe_result = 1; |
142 | printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n"); | 146 | printk(KERN_DEBUG "QUIRK: Enable AMD PLL fix\n"); |
143 | 147 | ||
144 | spin_unlock_irqrestore(&amd_lock, flags); | 148 | commit: |
145 | return amd_chipset.probe_result; | 149 | |
150 | spin_lock_irqsave(&amd_lock, flags); | ||
151 | if (amd_chipset.probe_count > 0) { | ||
152 | /* race - someone else was faster - drop devices */ | ||
153 | |||
154 | /* Mark that we where here */ | ||
155 | amd_chipset.probe_count++; | ||
156 | ret = amd_chipset.probe_result; | ||
157 | |||
158 | spin_unlock_irqrestore(&amd_lock, flags); | ||
159 | |||
160 | if (info.nb_dev) | ||
161 | pci_dev_put(info.nb_dev); | ||
162 | if (info.smbus_dev) | ||
163 | pci_dev_put(info.smbus_dev); | ||
164 | |||
165 | } else { | ||
166 | /* no race - commit the result */ | ||
167 | info.probe_count++; | ||
168 | amd_chipset = info; | ||
169 | spin_unlock_irqrestore(&amd_lock, flags); | ||
170 | } | ||
171 | |||
172 | return ret; | ||
146 | } | 173 | } |
147 | EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); | 174 | EXPORT_SYMBOL_GPL(usb_amd_find_chipset_info); |
148 | 175 | ||
@@ -284,6 +311,7 @@ EXPORT_SYMBOL_GPL(usb_amd_quirk_pll_enable); | |||
284 | 311 | ||
285 | void usb_amd_dev_put(void) | 312 | void usb_amd_dev_put(void) |
286 | { | 313 | { |
314 | struct pci_dev *nb, *smbus; | ||
287 | unsigned long flags; | 315 | unsigned long flags; |
288 | 316 | ||
289 | spin_lock_irqsave(&amd_lock, flags); | 317 | spin_lock_irqsave(&amd_lock, flags); |
@@ -294,20 +322,23 @@ void usb_amd_dev_put(void) | |||
294 | return; | 322 | return; |
295 | } | 323 | } |
296 | 324 | ||
297 | if (amd_chipset.nb_dev) { | 325 | /* save them to pci_dev_put outside of spinlock */ |
298 | pci_dev_put(amd_chipset.nb_dev); | 326 | nb = amd_chipset.nb_dev; |
299 | amd_chipset.nb_dev = NULL; | 327 | smbus = amd_chipset.smbus_dev; |
300 | } | 328 | |
301 | if (amd_chipset.smbus_dev) { | 329 | amd_chipset.nb_dev = NULL; |
302 | pci_dev_put(amd_chipset.smbus_dev); | 330 | amd_chipset.smbus_dev = NULL; |
303 | amd_chipset.smbus_dev = NULL; | ||
304 | } | ||
305 | amd_chipset.nb_type = 0; | 331 | amd_chipset.nb_type = 0; |
306 | amd_chipset.sb_type = 0; | 332 | amd_chipset.sb_type = 0; |
307 | amd_chipset.isoc_reqs = 0; | 333 | amd_chipset.isoc_reqs = 0; |
308 | amd_chipset.probe_result = 0; | 334 | amd_chipset.probe_result = 0; |
309 | 335 | ||
310 | spin_unlock_irqrestore(&amd_lock, flags); | 336 | spin_unlock_irqrestore(&amd_lock, flags); |
337 | |||
338 | if (nb) | ||
339 | pci_dev_put(nb); | ||
340 | if (smbus) | ||
341 | pci_dev_put(smbus); | ||
311 | } | 342 | } |
312 | EXPORT_SYMBOL_GPL(usb_amd_dev_put); | 343 | EXPORT_SYMBOL_GPL(usb_amd_dev_put); |
313 | 344 | ||
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index a78f2ebd11b7..73f75d26436c 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -777,7 +777,7 @@ int xhci_bus_suspend(struct usb_hcd *hcd) | |||
777 | if (t1 != t2) | 777 | if (t1 != t2) |
778 | xhci_writel(xhci, t2, port_array[port_index]); | 778 | xhci_writel(xhci, t2, port_array[port_index]); |
779 | 779 | ||
780 | if (DEV_HIGHSPEED(t1)) { | 780 | if (hcd->speed != HCD_USB3) { |
781 | /* enable remote wake up for USB 2.0 */ | 781 | /* enable remote wake up for USB 2.0 */ |
782 | u32 __iomem *addr; | 782 | u32 __iomem *addr; |
783 | u32 tmp; | 783 | u32 tmp; |
@@ -866,6 +866,21 @@ int xhci_bus_resume(struct usb_hcd *hcd) | |||
866 | temp |= PORT_LINK_STROBE | XDEV_U0; | 866 | temp |= PORT_LINK_STROBE | XDEV_U0; |
867 | xhci_writel(xhci, temp, port_array[port_index]); | 867 | xhci_writel(xhci, temp, port_array[port_index]); |
868 | } | 868 | } |
869 | /* wait for the port to enter U0 and report port link | ||
870 | * state change. | ||
871 | */ | ||
872 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
873 | msleep(20); | ||
874 | spin_lock_irqsave(&xhci->lock, flags); | ||
875 | |||
876 | /* Clear PLC */ | ||
877 | temp = xhci_readl(xhci, port_array[port_index]); | ||
878 | if (temp & PORT_PLC) { | ||
879 | temp = xhci_port_state_to_neutral(temp); | ||
880 | temp |= PORT_PLC; | ||
881 | xhci_writel(xhci, temp, port_array[port_index]); | ||
882 | } | ||
883 | |||
869 | slot_id = xhci_find_slot_id_by_port(hcd, | 884 | slot_id = xhci_find_slot_id_by_port(hcd, |
870 | xhci, port_index + 1); | 885 | xhci, port_index + 1); |
871 | if (slot_id) | 886 | if (slot_id) |
@@ -873,7 +888,7 @@ int xhci_bus_resume(struct usb_hcd *hcd) | |||
873 | } else | 888 | } else |
874 | xhci_writel(xhci, temp, port_array[port_index]); | 889 | xhci_writel(xhci, temp, port_array[port_index]); |
875 | 890 | ||
876 | if (DEV_HIGHSPEED(temp)) { | 891 | if (hcd->speed != HCD_USB3) { |
877 | /* disable remote wake up for USB 2.0 */ | 892 | /* disable remote wake up for USB 2.0 */ |
878 | u32 __iomem *addr; | 893 | u32 __iomem *addr; |
879 | u32 tmp; | 894 | u32 tmp; |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index a003e79aacdc..627f3438028c 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -846,7 +846,7 @@ static u32 xhci_find_real_port_number(struct xhci_hcd *xhci, | |||
846 | * Skip ports that don't have known speeds, or have duplicate | 846 | * Skip ports that don't have known speeds, or have duplicate |
847 | * Extended Capabilities port speed entries. | 847 | * Extended Capabilities port speed entries. |
848 | */ | 848 | */ |
849 | if (port_speed == 0 || port_speed == -1) | 849 | if (port_speed == 0 || port_speed == DUPLICATE_ENTRY) |
850 | continue; | 850 | continue; |
851 | 851 | ||
852 | /* | 852 | /* |
@@ -974,6 +974,47 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
974 | return 0; | 974 | return 0; |
975 | } | 975 | } |
976 | 976 | ||
977 | /* | ||
978 | * Convert interval expressed as 2^(bInterval - 1) == interval into | ||
979 | * straight exponent value 2^n == interval. | ||
980 | * | ||
981 | */ | ||
982 | static unsigned int xhci_parse_exponent_interval(struct usb_device *udev, | ||
983 | struct usb_host_endpoint *ep) | ||
984 | { | ||
985 | unsigned int interval; | ||
986 | |||
987 | interval = clamp_val(ep->desc.bInterval, 1, 16) - 1; | ||
988 | if (interval != ep->desc.bInterval - 1) | ||
989 | dev_warn(&udev->dev, | ||
990 | "ep %#x - rounding interval to %d microframes\n", | ||
991 | ep->desc.bEndpointAddress, | ||
992 | 1 << interval); | ||
993 | |||
994 | return interval; | ||
995 | } | ||
996 | |||
997 | /* | ||
998 | * Convert bInterval expressed in frames (in 1-255 range) to exponent of | ||
999 | * microframes, rounded down to nearest power of 2. | ||
1000 | */ | ||
1001 | static unsigned int xhci_parse_frame_interval(struct usb_device *udev, | ||
1002 | struct usb_host_endpoint *ep) | ||
1003 | { | ||
1004 | unsigned int interval; | ||
1005 | |||
1006 | interval = fls(8 * ep->desc.bInterval) - 1; | ||
1007 | interval = clamp_val(interval, 3, 10); | ||
1008 | if ((1 << interval) != 8 * ep->desc.bInterval) | ||
1009 | dev_warn(&udev->dev, | ||
1010 | "ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n", | ||
1011 | ep->desc.bEndpointAddress, | ||
1012 | 1 << interval, | ||
1013 | 8 * ep->desc.bInterval); | ||
1014 | |||
1015 | return interval; | ||
1016 | } | ||
1017 | |||
977 | /* Return the polling or NAK interval. | 1018 | /* Return the polling or NAK interval. |
978 | * | 1019 | * |
979 | * The polling interval is expressed in "microframes". If xHCI's Interval field | 1020 | * The polling interval is expressed in "microframes". If xHCI's Interval field |
@@ -982,7 +1023,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud | |||
982 | * The NAK interval is one NAK per 1 to 255 microframes, or no NAKs if interval | 1023 | * The NAK interval is one NAK per 1 to 255 microframes, or no NAKs if interval |
983 | * is set to 0. | 1024 | * is set to 0. |
984 | */ | 1025 | */ |
985 | static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, | 1026 | static unsigned int xhci_get_endpoint_interval(struct usb_device *udev, |
986 | struct usb_host_endpoint *ep) | 1027 | struct usb_host_endpoint *ep) |
987 | { | 1028 | { |
988 | unsigned int interval = 0; | 1029 | unsigned int interval = 0; |
@@ -991,45 +1032,38 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, | |||
991 | case USB_SPEED_HIGH: | 1032 | case USB_SPEED_HIGH: |
992 | /* Max NAK rate */ | 1033 | /* Max NAK rate */ |
993 | if (usb_endpoint_xfer_control(&ep->desc) || | 1034 | if (usb_endpoint_xfer_control(&ep->desc) || |
994 | usb_endpoint_xfer_bulk(&ep->desc)) | 1035 | usb_endpoint_xfer_bulk(&ep->desc)) { |
995 | interval = ep->desc.bInterval; | 1036 | interval = ep->desc.bInterval; |
1037 | break; | ||
1038 | } | ||
996 | /* Fall through - SS and HS isoc/int have same decoding */ | 1039 | /* Fall through - SS and HS isoc/int have same decoding */ |
1040 | |||
997 | case USB_SPEED_SUPER: | 1041 | case USB_SPEED_SUPER: |
998 | if (usb_endpoint_xfer_int(&ep->desc) || | 1042 | if (usb_endpoint_xfer_int(&ep->desc) || |
999 | usb_endpoint_xfer_isoc(&ep->desc)) { | 1043 | usb_endpoint_xfer_isoc(&ep->desc)) { |
1000 | if (ep->desc.bInterval == 0) | 1044 | interval = xhci_parse_exponent_interval(udev, ep); |
1001 | interval = 0; | ||
1002 | else | ||
1003 | interval = ep->desc.bInterval - 1; | ||
1004 | if (interval > 15) | ||
1005 | interval = 15; | ||
1006 | if (interval != ep->desc.bInterval + 1) | ||
1007 | dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n", | ||
1008 | ep->desc.bEndpointAddress, 1 << interval); | ||
1009 | } | 1045 | } |
1010 | break; | 1046 | break; |
1011 | /* Convert bInterval (in 1-255 frames) to microframes and round down to | 1047 | |
1012 | * nearest power of 2. | ||
1013 | */ | ||
1014 | case USB_SPEED_FULL: | 1048 | case USB_SPEED_FULL: |
1049 | if (usb_endpoint_xfer_int(&ep->desc)) { | ||
1050 | interval = xhci_parse_exponent_interval(udev, ep); | ||
1051 | break; | ||
1052 | } | ||
1053 | /* | ||
1054 | * Fall through for isochronous endpoint interval decoding | ||
1055 | * since it uses the same rules as low speed interrupt | ||
1056 | * endpoints. | ||
1057 | */ | ||
1058 | |||
1015 | case USB_SPEED_LOW: | 1059 | case USB_SPEED_LOW: |
1016 | if (usb_endpoint_xfer_int(&ep->desc) || | 1060 | if (usb_endpoint_xfer_int(&ep->desc) || |
1017 | usb_endpoint_xfer_isoc(&ep->desc)) { | 1061 | usb_endpoint_xfer_isoc(&ep->desc)) { |
1018 | interval = fls(8*ep->desc.bInterval) - 1; | 1062 | |
1019 | if (interval > 10) | 1063 | interval = xhci_parse_frame_interval(udev, ep); |
1020 | interval = 10; | ||
1021 | if (interval < 3) | ||
1022 | interval = 3; | ||
1023 | if ((1 << interval) != 8*ep->desc.bInterval) | ||
1024 | dev_warn(&udev->dev, | ||
1025 | "ep %#x - rounding interval" | ||
1026 | " to %d microframes, " | ||
1027 | "ep desc says %d microframes\n", | ||
1028 | ep->desc.bEndpointAddress, | ||
1029 | 1 << interval, | ||
1030 | 8*ep->desc.bInterval); | ||
1031 | } | 1064 | } |
1032 | break; | 1065 | break; |
1066 | |||
1033 | default: | 1067 | default: |
1034 | BUG(); | 1068 | BUG(); |
1035 | } | 1069 | } |
@@ -1041,7 +1075,7 @@ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, | |||
1041 | * transaction opportunities per microframe", but that goes in the Max Burst | 1075 | * transaction opportunities per microframe", but that goes in the Max Burst |
1042 | * endpoint context field. | 1076 | * endpoint context field. |
1043 | */ | 1077 | */ |
1044 | static inline u32 xhci_get_endpoint_mult(struct usb_device *udev, | 1078 | static u32 xhci_get_endpoint_mult(struct usb_device *udev, |
1045 | struct usb_host_endpoint *ep) | 1079 | struct usb_host_endpoint *ep) |
1046 | { | 1080 | { |
1047 | if (udev->speed != USB_SPEED_SUPER || | 1081 | if (udev->speed != USB_SPEED_SUPER || |
@@ -1050,7 +1084,7 @@ static inline u32 xhci_get_endpoint_mult(struct usb_device *udev, | |||
1050 | return ep->ss_ep_comp.bmAttributes; | 1084 | return ep->ss_ep_comp.bmAttributes; |
1051 | } | 1085 | } |
1052 | 1086 | ||
1053 | static inline u32 xhci_get_endpoint_type(struct usb_device *udev, | 1087 | static u32 xhci_get_endpoint_type(struct usb_device *udev, |
1054 | struct usb_host_endpoint *ep) | 1088 | struct usb_host_endpoint *ep) |
1055 | { | 1089 | { |
1056 | int in; | 1090 | int in; |
@@ -1084,7 +1118,7 @@ static inline u32 xhci_get_endpoint_type(struct usb_device *udev, | |||
1084 | * Basically, this is the maxpacket size, multiplied by the burst size | 1118 | * Basically, this is the maxpacket size, multiplied by the burst size |
1085 | * and mult size. | 1119 | * and mult size. |
1086 | */ | 1120 | */ |
1087 | static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, | 1121 | static u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, |
1088 | struct usb_device *udev, | 1122 | struct usb_device *udev, |
1089 | struct usb_host_endpoint *ep) | 1123 | struct usb_host_endpoint *ep) |
1090 | { | 1124 | { |
@@ -1727,12 +1761,12 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, | |||
1727 | * found a similar duplicate. | 1761 | * found a similar duplicate. |
1728 | */ | 1762 | */ |
1729 | if (xhci->port_array[i] != major_revision && | 1763 | if (xhci->port_array[i] != major_revision && |
1730 | xhci->port_array[i] != (u8) -1) { | 1764 | xhci->port_array[i] != DUPLICATE_ENTRY) { |
1731 | if (xhci->port_array[i] == 0x03) | 1765 | if (xhci->port_array[i] == 0x03) |
1732 | xhci->num_usb3_ports--; | 1766 | xhci->num_usb3_ports--; |
1733 | else | 1767 | else |
1734 | xhci->num_usb2_ports--; | 1768 | xhci->num_usb2_ports--; |
1735 | xhci->port_array[i] = (u8) -1; | 1769 | xhci->port_array[i] = DUPLICATE_ENTRY; |
1736 | } | 1770 | } |
1737 | /* FIXME: Should we disable the port? */ | 1771 | /* FIXME: Should we disable the port? */ |
1738 | continue; | 1772 | continue; |
@@ -1831,7 +1865,7 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) | |||
1831 | for (i = 0; i < num_ports; i++) { | 1865 | for (i = 0; i < num_ports; i++) { |
1832 | if (xhci->port_array[i] == 0x03 || | 1866 | if (xhci->port_array[i] == 0x03 || |
1833 | xhci->port_array[i] == 0 || | 1867 | xhci->port_array[i] == 0 || |
1834 | xhci->port_array[i] == -1) | 1868 | xhci->port_array[i] == DUPLICATE_ENTRY) |
1835 | continue; | 1869 | continue; |
1836 | 1870 | ||
1837 | xhci->usb2_ports[port_index] = | 1871 | xhci->usb2_ports[port_index] = |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index ceea9f33491c..a10494c2f3c7 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -114,6 +114,10 @@ static int xhci_pci_setup(struct usb_hcd *hcd) | |||
114 | if (pdev->vendor == PCI_VENDOR_ID_NEC) | 114 | if (pdev->vendor == PCI_VENDOR_ID_NEC) |
115 | xhci->quirks |= XHCI_NEC_HOST; | 115 | xhci->quirks |= XHCI_NEC_HOST; |
116 | 116 | ||
117 | /* AMD PLL quirk */ | ||
118 | if (pdev->vendor == PCI_VENDOR_ID_AMD && usb_amd_find_chipset_info()) | ||
119 | xhci->quirks |= XHCI_AMD_PLL_FIX; | ||
120 | |||
117 | /* Make sure the HC is halted. */ | 121 | /* Make sure the HC is halted. */ |
118 | retval = xhci_halt(xhci); | 122 | retval = xhci_halt(xhci); |
119 | if (retval) | 123 | if (retval) |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index cfc1ad92473f..7437386a9a50 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -93,7 +93,7 @@ dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, | |||
93 | /* Does this link TRB point to the first segment in a ring, | 93 | /* Does this link TRB point to the first segment in a ring, |
94 | * or was the previous TRB the last TRB on the last segment in the ERST? | 94 | * or was the previous TRB the last TRB on the last segment in the ERST? |
95 | */ | 95 | */ |
96 | static inline bool last_trb_on_last_seg(struct xhci_hcd *xhci, struct xhci_ring *ring, | 96 | static bool last_trb_on_last_seg(struct xhci_hcd *xhci, struct xhci_ring *ring, |
97 | struct xhci_segment *seg, union xhci_trb *trb) | 97 | struct xhci_segment *seg, union xhci_trb *trb) |
98 | { | 98 | { |
99 | if (ring == xhci->event_ring) | 99 | if (ring == xhci->event_ring) |
@@ -107,7 +107,7 @@ static inline bool last_trb_on_last_seg(struct xhci_hcd *xhci, struct xhci_ring | |||
107 | * segment? I.e. would the updated event TRB pointer step off the end of the | 107 | * segment? I.e. would the updated event TRB pointer step off the end of the |
108 | * event seg? | 108 | * event seg? |
109 | */ | 109 | */ |
110 | static inline int last_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, | 110 | static int last_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, |
111 | struct xhci_segment *seg, union xhci_trb *trb) | 111 | struct xhci_segment *seg, union xhci_trb *trb) |
112 | { | 112 | { |
113 | if (ring == xhci->event_ring) | 113 | if (ring == xhci->event_ring) |
@@ -116,7 +116,7 @@ static inline int last_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, | |||
116 | return (trb->link.control & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK); | 116 | return (trb->link.control & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK); |
117 | } | 117 | } |
118 | 118 | ||
119 | static inline int enqueue_is_link_trb(struct xhci_ring *ring) | 119 | static int enqueue_is_link_trb(struct xhci_ring *ring) |
120 | { | 120 | { |
121 | struct xhci_link_trb *link = &ring->enqueue->link; | 121 | struct xhci_link_trb *link = &ring->enqueue->link; |
122 | return ((link->control & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK)); | 122 | return ((link->control & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK)); |
@@ -592,7 +592,7 @@ void xhci_queue_new_dequeue_state(struct xhci_hcd *xhci, | |||
592 | ep->ep_state |= SET_DEQ_PENDING; | 592 | ep->ep_state |= SET_DEQ_PENDING; |
593 | } | 593 | } |
594 | 594 | ||
595 | static inline void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd *xhci, | 595 | static void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd *xhci, |
596 | struct xhci_virt_ep *ep) | 596 | struct xhci_virt_ep *ep) |
597 | { | 597 | { |
598 | ep->ep_state &= ~EP_HALT_PENDING; | 598 | ep->ep_state &= ~EP_HALT_PENDING; |
@@ -619,6 +619,13 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, | |||
619 | 619 | ||
620 | /* Only giveback urb when this is the last td in urb */ | 620 | /* Only giveback urb when this is the last td in urb */ |
621 | if (urb_priv->td_cnt == urb_priv->length) { | 621 | if (urb_priv->td_cnt == urb_priv->length) { |
622 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
623 | xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; | ||
624 | if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { | ||
625 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | ||
626 | usb_amd_quirk_pll_enable(); | ||
627 | } | ||
628 | } | ||
622 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 629 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
623 | xhci_dbg(xhci, "Giveback %s URB %p\n", adjective, urb); | 630 | xhci_dbg(xhci, "Giveback %s URB %p\n", adjective, urb); |
624 | 631 | ||
@@ -1209,7 +1216,7 @@ static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd, | |||
1209 | * Skip ports that don't have known speeds, or have duplicate | 1216 | * Skip ports that don't have known speeds, or have duplicate |
1210 | * Extended Capabilities port speed entries. | 1217 | * Extended Capabilities port speed entries. |
1211 | */ | 1218 | */ |
1212 | if (port_speed == 0 || port_speed == -1) | 1219 | if (port_speed == 0 || port_speed == DUPLICATE_ENTRY) |
1213 | continue; | 1220 | continue; |
1214 | 1221 | ||
1215 | /* | 1222 | /* |
@@ -1235,6 +1242,7 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1235 | u8 major_revision; | 1242 | u8 major_revision; |
1236 | struct xhci_bus_state *bus_state; | 1243 | struct xhci_bus_state *bus_state; |
1237 | u32 __iomem **port_array; | 1244 | u32 __iomem **port_array; |
1245 | bool bogus_port_status = false; | ||
1238 | 1246 | ||
1239 | /* Port status change events always have a successful completion code */ | 1247 | /* Port status change events always have a successful completion code */ |
1240 | if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { | 1248 | if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) { |
@@ -1247,6 +1255,7 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1247 | max_ports = HCS_MAX_PORTS(xhci->hcs_params1); | 1255 | max_ports = HCS_MAX_PORTS(xhci->hcs_params1); |
1248 | if ((port_id <= 0) || (port_id > max_ports)) { | 1256 | if ((port_id <= 0) || (port_id > max_ports)) { |
1249 | xhci_warn(xhci, "Invalid port id %d\n", port_id); | 1257 | xhci_warn(xhci, "Invalid port id %d\n", port_id); |
1258 | bogus_port_status = true; | ||
1250 | goto cleanup; | 1259 | goto cleanup; |
1251 | } | 1260 | } |
1252 | 1261 | ||
@@ -1258,12 +1267,14 @@ static void handle_port_status(struct xhci_hcd *xhci, | |||
1258 | xhci_warn(xhci, "Event for port %u not in " | 1267 | xhci_warn(xhci, "Event for port %u not in " |
1259 | "Extended Capabilities, ignoring.\n", | 1268 | "Extended Capabilities, ignoring.\n", |
1260 | port_id); | 1269 | port_id); |
1270 | bogus_port_status = true; | ||
1261 | goto cleanup; | 1271 | goto cleanup; |
1262 | } | 1272 | } |
1263 | if (major_revision == (u8) -1) { | 1273 | if (major_revision == DUPLICATE_ENTRY) { |
1264 | xhci_warn(xhci, "Event for port %u duplicated in" | 1274 | xhci_warn(xhci, "Event for port %u duplicated in" |
1265 | "Extended Capabilities, ignoring.\n", | 1275 | "Extended Capabilities, ignoring.\n", |
1266 | port_id); | 1276 | port_id); |
1277 | bogus_port_status = true; | ||
1267 | goto cleanup; | 1278 | goto cleanup; |
1268 | } | 1279 | } |
1269 | 1280 | ||
@@ -1335,6 +1346,13 @@ cleanup: | |||
1335 | /* Update event ring dequeue pointer before dropping the lock */ | 1346 | /* Update event ring dequeue pointer before dropping the lock */ |
1336 | inc_deq(xhci, xhci->event_ring, true); | 1347 | inc_deq(xhci, xhci->event_ring, true); |
1337 | 1348 | ||
1349 | /* Don't make the USB core poll the roothub if we got a bad port status | ||
1350 | * change event. Besides, at that point we can't tell which roothub | ||
1351 | * (USB 2.0 or USB 3.0) to kick. | ||
1352 | */ | ||
1353 | if (bogus_port_status) | ||
1354 | return; | ||
1355 | |||
1338 | spin_unlock(&xhci->lock); | 1356 | spin_unlock(&xhci->lock); |
1339 | /* Pass this up to the core */ | 1357 | /* Pass this up to the core */ |
1340 | usb_hcd_poll_rh_status(hcd); | 1358 | usb_hcd_poll_rh_status(hcd); |
@@ -1554,8 +1572,17 @@ td_cleanup: | |||
1554 | 1572 | ||
1555 | urb_priv->td_cnt++; | 1573 | urb_priv->td_cnt++; |
1556 | /* Giveback the urb when all the tds are completed */ | 1574 | /* Giveback the urb when all the tds are completed */ |
1557 | if (urb_priv->td_cnt == urb_priv->length) | 1575 | if (urb_priv->td_cnt == urb_priv->length) { |
1558 | ret = 1; | 1576 | ret = 1; |
1577 | if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | ||
1578 | xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs--; | ||
1579 | if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs | ||
1580 | == 0) { | ||
1581 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | ||
1582 | usb_amd_quirk_pll_enable(); | ||
1583 | } | ||
1584 | } | ||
1585 | } | ||
1559 | } | 1586 | } |
1560 | 1587 | ||
1561 | return ret; | 1588 | return ret; |
@@ -1675,71 +1702,52 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1675 | struct urb_priv *urb_priv; | 1702 | struct urb_priv *urb_priv; |
1676 | int idx; | 1703 | int idx; |
1677 | int len = 0; | 1704 | int len = 0; |
1678 | int skip_td = 0; | ||
1679 | union xhci_trb *cur_trb; | 1705 | union xhci_trb *cur_trb; |
1680 | struct xhci_segment *cur_seg; | 1706 | struct xhci_segment *cur_seg; |
1707 | struct usb_iso_packet_descriptor *frame; | ||
1681 | u32 trb_comp_code; | 1708 | u32 trb_comp_code; |
1709 | bool skip_td = false; | ||
1682 | 1710 | ||
1683 | ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer); | 1711 | ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer); |
1684 | trb_comp_code = GET_COMP_CODE(event->transfer_len); | 1712 | trb_comp_code = GET_COMP_CODE(event->transfer_len); |
1685 | urb_priv = td->urb->hcpriv; | 1713 | urb_priv = td->urb->hcpriv; |
1686 | idx = urb_priv->td_cnt; | 1714 | idx = urb_priv->td_cnt; |
1715 | frame = &td->urb->iso_frame_desc[idx]; | ||
1687 | 1716 | ||
1688 | if (ep->skip) { | 1717 | /* handle completion code */ |
1689 | /* The transfer is partly done */ | 1718 | switch (trb_comp_code) { |
1690 | *status = -EXDEV; | 1719 | case COMP_SUCCESS: |
1691 | td->urb->iso_frame_desc[idx].status = -EXDEV; | 1720 | frame->status = 0; |
1692 | } else { | 1721 | xhci_dbg(xhci, "Successful isoc transfer!\n"); |
1693 | /* handle completion code */ | 1722 | break; |
1694 | switch (trb_comp_code) { | 1723 | case COMP_SHORT_TX: |
1695 | case COMP_SUCCESS: | 1724 | frame->status = td->urb->transfer_flags & URB_SHORT_NOT_OK ? |
1696 | td->urb->iso_frame_desc[idx].status = 0; | 1725 | -EREMOTEIO : 0; |
1697 | xhci_dbg(xhci, "Successful isoc transfer!\n"); | 1726 | break; |
1698 | break; | 1727 | case COMP_BW_OVER: |
1699 | case COMP_SHORT_TX: | 1728 | frame->status = -ECOMM; |
1700 | if (td->urb->transfer_flags & URB_SHORT_NOT_OK) | 1729 | skip_td = true; |
1701 | td->urb->iso_frame_desc[idx].status = | 1730 | break; |
1702 | -EREMOTEIO; | 1731 | case COMP_BUFF_OVER: |
1703 | else | 1732 | case COMP_BABBLE: |
1704 | td->urb->iso_frame_desc[idx].status = 0; | 1733 | frame->status = -EOVERFLOW; |
1705 | break; | 1734 | skip_td = true; |
1706 | case COMP_BW_OVER: | 1735 | break; |
1707 | td->urb->iso_frame_desc[idx].status = -ECOMM; | 1736 | case COMP_STALL: |
1708 | skip_td = 1; | 1737 | frame->status = -EPROTO; |
1709 | break; | 1738 | skip_td = true; |
1710 | case COMP_BUFF_OVER: | 1739 | break; |
1711 | case COMP_BABBLE: | 1740 | case COMP_STOP: |
1712 | td->urb->iso_frame_desc[idx].status = -EOVERFLOW; | 1741 | case COMP_STOP_INVAL: |
1713 | skip_td = 1; | 1742 | break; |
1714 | break; | 1743 | default: |
1715 | case COMP_STALL: | 1744 | frame->status = -1; |
1716 | td->urb->iso_frame_desc[idx].status = -EPROTO; | 1745 | break; |
1717 | skip_td = 1; | ||
1718 | break; | ||
1719 | case COMP_STOP: | ||
1720 | case COMP_STOP_INVAL: | ||
1721 | break; | ||
1722 | default: | ||
1723 | td->urb->iso_frame_desc[idx].status = -1; | ||
1724 | break; | ||
1725 | } | ||
1726 | } | ||
1727 | |||
1728 | /* calc actual length */ | ||
1729 | if (ep->skip) { | ||
1730 | td->urb->iso_frame_desc[idx].actual_length = 0; | ||
1731 | /* Update ring dequeue pointer */ | ||
1732 | while (ep_ring->dequeue != td->last_trb) | ||
1733 | inc_deq(xhci, ep_ring, false); | ||
1734 | inc_deq(xhci, ep_ring, false); | ||
1735 | return finish_td(xhci, td, event_trb, event, ep, status, true); | ||
1736 | } | 1746 | } |
1737 | 1747 | ||
1738 | if (trb_comp_code == COMP_SUCCESS || skip_td == 1) { | 1748 | if (trb_comp_code == COMP_SUCCESS || skip_td) { |
1739 | td->urb->iso_frame_desc[idx].actual_length = | 1749 | frame->actual_length = frame->length; |
1740 | td->urb->iso_frame_desc[idx].length; | 1750 | td->urb->actual_length += frame->length; |
1741 | td->urb->actual_length += | ||
1742 | td->urb->iso_frame_desc[idx].length; | ||
1743 | } else { | 1751 | } else { |
1744 | for (cur_trb = ep_ring->dequeue, | 1752 | for (cur_trb = ep_ring->dequeue, |
1745 | cur_seg = ep_ring->deq_seg; cur_trb != event_trb; | 1753 | cur_seg = ep_ring->deq_seg; cur_trb != event_trb; |
@@ -1755,7 +1763,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1755 | TRB_LEN(event->transfer_len); | 1763 | TRB_LEN(event->transfer_len); |
1756 | 1764 | ||
1757 | if (trb_comp_code != COMP_STOP_INVAL) { | 1765 | if (trb_comp_code != COMP_STOP_INVAL) { |
1758 | td->urb->iso_frame_desc[idx].actual_length = len; | 1766 | frame->actual_length = len; |
1759 | td->urb->actual_length += len; | 1767 | td->urb->actual_length += len; |
1760 | } | 1768 | } |
1761 | } | 1769 | } |
@@ -1766,6 +1774,35 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | |||
1766 | return finish_td(xhci, td, event_trb, event, ep, status, false); | 1774 | return finish_td(xhci, td, event_trb, event, ep, status, false); |
1767 | } | 1775 | } |
1768 | 1776 | ||
1777 | static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, | ||
1778 | struct xhci_transfer_event *event, | ||
1779 | struct xhci_virt_ep *ep, int *status) | ||
1780 | { | ||
1781 | struct xhci_ring *ep_ring; | ||
1782 | struct urb_priv *urb_priv; | ||
1783 | struct usb_iso_packet_descriptor *frame; | ||
1784 | int idx; | ||
1785 | |||
1786 | ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer); | ||
1787 | urb_priv = td->urb->hcpriv; | ||
1788 | idx = urb_priv->td_cnt; | ||
1789 | frame = &td->urb->iso_frame_desc[idx]; | ||
1790 | |||
1791 | /* The transfer is partly done */ | ||
1792 | *status = -EXDEV; | ||
1793 | frame->status = -EXDEV; | ||
1794 | |||
1795 | /* calc actual length */ | ||
1796 | frame->actual_length = 0; | ||
1797 | |||
1798 | /* Update ring dequeue pointer */ | ||
1799 | while (ep_ring->dequeue != td->last_trb) | ||
1800 | inc_deq(xhci, ep_ring, false); | ||
1801 | inc_deq(xhci, ep_ring, false); | ||
1802 | |||
1803 | return finish_td(xhci, td, NULL, event, ep, status, true); | ||
1804 | } | ||
1805 | |||
1769 | /* | 1806 | /* |
1770 | * Process bulk and interrupt tds, update urb status and actual_length. | 1807 | * Process bulk and interrupt tds, update urb status and actual_length. |
1771 | */ | 1808 | */ |
@@ -2024,36 +2061,42 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2024 | } | 2061 | } |
2025 | 2062 | ||
2026 | td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); | 2063 | td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); |
2064 | |||
2027 | /* Is this a TRB in the currently executing TD? */ | 2065 | /* Is this a TRB in the currently executing TD? */ |
2028 | event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, | 2066 | event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, |
2029 | td->last_trb, event_dma); | 2067 | td->last_trb, event_dma); |
2030 | if (event_seg && ep->skip) { | 2068 | if (!event_seg) { |
2069 | if (!ep->skip || | ||
2070 | !usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { | ||
2071 | /* HC is busted, give up! */ | ||
2072 | xhci_err(xhci, | ||
2073 | "ERROR Transfer event TRB DMA ptr not " | ||
2074 | "part of current TD\n"); | ||
2075 | return -ESHUTDOWN; | ||
2076 | } | ||
2077 | |||
2078 | ret = skip_isoc_td(xhci, td, event, ep, &status); | ||
2079 | goto cleanup; | ||
2080 | } | ||
2081 | |||
2082 | if (ep->skip) { | ||
2031 | xhci_dbg(xhci, "Found td. Clear skip flag.\n"); | 2083 | xhci_dbg(xhci, "Found td. Clear skip flag.\n"); |
2032 | ep->skip = false; | 2084 | ep->skip = false; |
2033 | } | 2085 | } |
2034 | if (!event_seg && | ||
2035 | (!ep->skip || !usb_endpoint_xfer_isoc(&td->urb->ep->desc))) { | ||
2036 | /* HC is busted, give up! */ | ||
2037 | xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not " | ||
2038 | "part of current TD\n"); | ||
2039 | return -ESHUTDOWN; | ||
2040 | } | ||
2041 | 2086 | ||
2042 | if (event_seg) { | 2087 | event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / |
2043 | event_trb = &event_seg->trbs[(event_dma - | 2088 | sizeof(*event_trb)]; |
2044 | event_seg->dma) / sizeof(*event_trb)]; | 2089 | /* |
2045 | /* | 2090 | * No-op TRB should not trigger interrupts. |
2046 | * No-op TRB should not trigger interrupts. | 2091 | * If event_trb is a no-op TRB, it means the |
2047 | * If event_trb is a no-op TRB, it means the | 2092 | * corresponding TD has been cancelled. Just ignore |
2048 | * corresponding TD has been cancelled. Just ignore | 2093 | * the TD. |
2049 | * the TD. | 2094 | */ |
2050 | */ | 2095 | if ((event_trb->generic.field[3] & TRB_TYPE_BITMASK) |
2051 | if ((event_trb->generic.field[3] & TRB_TYPE_BITMASK) | 2096 | == TRB_TYPE(TRB_TR_NOOP)) { |
2052 | == TRB_TYPE(TRB_TR_NOOP)) { | 2097 | xhci_dbg(xhci, |
2053 | xhci_dbg(xhci, "event_trb is a no-op TRB. " | 2098 | "event_trb is a no-op TRB. Skip it\n"); |
2054 | "Skip it\n"); | 2099 | goto cleanup; |
2055 | goto cleanup; | ||
2056 | } | ||
2057 | } | 2100 | } |
2058 | 2101 | ||
2059 | /* Now update the urb's actual_length and give back to | 2102 | /* Now update the urb's actual_length and give back to |
@@ -3126,6 +3169,12 @@ static int xhci_queue_isoc_tx(struct xhci_hcd *xhci, gfp_t mem_flags, | |||
3126 | } | 3169 | } |
3127 | } | 3170 | } |
3128 | 3171 | ||
3172 | if (xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs == 0) { | ||
3173 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | ||
3174 | usb_amd_quirk_pll_disable(); | ||
3175 | } | ||
3176 | xhci_to_hcd(xhci)->self.bandwidth_isoc_reqs++; | ||
3177 | |||
3129 | giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, | 3178 | giveback_first_trb(xhci, slot_id, ep_index, urb->stream_id, |
3130 | start_cycle, start_trb); | 3179 | start_cycle, start_trb); |
3131 | return 0; | 3180 | return 0; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 196e0181b2ed..81b976e45880 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -550,6 +550,9 @@ void xhci_stop(struct usb_hcd *hcd) | |||
550 | del_timer_sync(&xhci->event_ring_timer); | 550 | del_timer_sync(&xhci->event_ring_timer); |
551 | #endif | 551 | #endif |
552 | 552 | ||
553 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | ||
554 | usb_amd_dev_put(); | ||
555 | |||
553 | xhci_dbg(xhci, "// Disabling event ring interrupts\n"); | 556 | xhci_dbg(xhci, "// Disabling event ring interrupts\n"); |
554 | temp = xhci_readl(xhci, &xhci->op_regs->status); | 557 | temp = xhci_readl(xhci, &xhci->op_regs->status); |
555 | xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); | 558 | xhci_writel(xhci, temp & ~STS_EINT, &xhci->op_regs->status); |
@@ -771,7 +774,9 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
771 | 774 | ||
772 | /* If restore operation fails, re-initialize the HC during resume */ | 775 | /* If restore operation fails, re-initialize the HC during resume */ |
773 | if ((temp & STS_SRE) || hibernated) { | 776 | if ((temp & STS_SRE) || hibernated) { |
774 | usb_root_hub_lost_power(hcd->self.root_hub); | 777 | /* Let the USB core know _both_ roothubs lost power. */ |
778 | usb_root_hub_lost_power(xhci->main_hcd->self.root_hub); | ||
779 | usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub); | ||
775 | 780 | ||
776 | xhci_dbg(xhci, "Stop HCD\n"); | 781 | xhci_dbg(xhci, "Stop HCD\n"); |
777 | xhci_halt(xhci); | 782 | xhci_halt(xhci); |
@@ -2386,10 +2391,18 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
2386 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ | 2391 | /* Everything but endpoint 0 is disabled, so free or cache the rings. */ |
2387 | last_freed_endpoint = 1; | 2392 | last_freed_endpoint = 1; |
2388 | for (i = 1; i < 31; ++i) { | 2393 | for (i = 1; i < 31; ++i) { |
2389 | if (!virt_dev->eps[i].ring) | 2394 | struct xhci_virt_ep *ep = &virt_dev->eps[i]; |
2390 | continue; | 2395 | |
2391 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | 2396 | if (ep->ep_state & EP_HAS_STREAMS) { |
2392 | last_freed_endpoint = i; | 2397 | xhci_free_stream_info(xhci, ep->stream_info); |
2398 | ep->stream_info = NULL; | ||
2399 | ep->ep_state &= ~EP_HAS_STREAMS; | ||
2400 | } | ||
2401 | |||
2402 | if (ep->ring) { | ||
2403 | xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); | ||
2404 | last_freed_endpoint = i; | ||
2405 | } | ||
2393 | } | 2406 | } |
2394 | xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); | 2407 | xhci_dbg(xhci, "Output context after successful reset device cmd:\n"); |
2395 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); | 2408 | xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint); |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 07e263063e37..ba1be6b7cc6d 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | /* Code sharing between pci-quirks and xhci hcd */ | 31 | /* Code sharing between pci-quirks and xhci hcd */ |
32 | #include "xhci-ext-caps.h" | 32 | #include "xhci-ext-caps.h" |
33 | #include "pci-quirks.h" | ||
33 | 34 | ||
34 | /* xHCI PCI Configuration Registers */ | 35 | /* xHCI PCI Configuration Registers */ |
35 | #define XHCI_SBRN_OFFSET (0x60) | 36 | #define XHCI_SBRN_OFFSET (0x60) |
@@ -232,7 +233,7 @@ struct xhci_op_regs { | |||
232 | * notification type that matches a bit set in this bit field. | 233 | * notification type that matches a bit set in this bit field. |
233 | */ | 234 | */ |
234 | #define DEV_NOTE_MASK (0xffff) | 235 | #define DEV_NOTE_MASK (0xffff) |
235 | #define ENABLE_DEV_NOTE(x) (1 << x) | 236 | #define ENABLE_DEV_NOTE(x) (1 << (x)) |
236 | /* Most of the device notification types should only be used for debug. | 237 | /* Most of the device notification types should only be used for debug. |
237 | * SW does need to pay attention to function wake notifications. | 238 | * SW does need to pay attention to function wake notifications. |
238 | */ | 239 | */ |
@@ -348,6 +349,9 @@ struct xhci_op_regs { | |||
348 | /* Initiate a warm port reset - complete when PORT_WRC is '1' */ | 349 | /* Initiate a warm port reset - complete when PORT_WRC is '1' */ |
349 | #define PORT_WR (1 << 31) | 350 | #define PORT_WR (1 << 31) |
350 | 351 | ||
352 | /* We mark duplicate entries with -1 */ | ||
353 | #define DUPLICATE_ENTRY ((u8)(-1)) | ||
354 | |||
351 | /* Port Power Management Status and Control - port_power_base bitmasks */ | 355 | /* Port Power Management Status and Control - port_power_base bitmasks */ |
352 | /* Inactivity timer value for transitions into U1, in microseconds. | 356 | /* Inactivity timer value for transitions into U1, in microseconds. |
353 | * Timeout can be up to 127us. 0xFF means an infinite timeout. | 357 | * Timeout can be up to 127us. 0xFF means an infinite timeout. |
@@ -601,11 +605,11 @@ struct xhci_ep_ctx { | |||
601 | #define EP_STATE_STOPPED 3 | 605 | #define EP_STATE_STOPPED 3 |
602 | #define EP_STATE_ERROR 4 | 606 | #define EP_STATE_ERROR 4 |
603 | /* Mult - Max number of burtst within an interval, in EP companion desc. */ | 607 | /* Mult - Max number of burtst within an interval, in EP companion desc. */ |
604 | #define EP_MULT(p) ((p & 0x3) << 8) | 608 | #define EP_MULT(p) (((p) & 0x3) << 8) |
605 | /* bits 10:14 are Max Primary Streams */ | 609 | /* bits 10:14 are Max Primary Streams */ |
606 | /* bit 15 is Linear Stream Array */ | 610 | /* bit 15 is Linear Stream Array */ |
607 | /* Interval - period between requests to an endpoint - 125u increments. */ | 611 | /* Interval - period between requests to an endpoint - 125u increments. */ |
608 | #define EP_INTERVAL(p) ((p & 0xff) << 16) | 612 | #define EP_INTERVAL(p) (((p) & 0xff) << 16) |
609 | #define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff)) | 613 | #define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff)) |
610 | #define EP_MAXPSTREAMS_MASK (0x1f << 10) | 614 | #define EP_MAXPSTREAMS_MASK (0x1f << 10) |
611 | #define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK) | 615 | #define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK) |
@@ -1276,6 +1280,7 @@ struct xhci_hcd { | |||
1276 | #define XHCI_LINK_TRB_QUIRK (1 << 0) | 1280 | #define XHCI_LINK_TRB_QUIRK (1 << 0) |
1277 | #define XHCI_RESET_EP_QUIRK (1 << 1) | 1281 | #define XHCI_RESET_EP_QUIRK (1 << 1) |
1278 | #define XHCI_NEC_HOST (1 << 2) | 1282 | #define XHCI_NEC_HOST (1 << 2) |
1283 | #define XHCI_AMD_PLL_FIX (1 << 3) | ||
1279 | /* There are two roothubs to keep track of bus suspend info for */ | 1284 | /* There are two roothubs to keep track of bus suspend info for */ |
1280 | struct xhci_bus_state bus_state[2]; | 1285 | struct xhci_bus_state bus_state[2]; |
1281 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ | 1286 | /* Is each xHCI roothub port a USB 3.0, USB 2.0, or USB 1.1 port? */ |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 4cbb7e4b368d..74073b363c30 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -14,7 +14,7 @@ config USB_MUSB_HDRC | |||
14 | select TWL4030_USB if MACH_OMAP_3430SDP | 14 | select TWL4030_USB if MACH_OMAP_3430SDP |
15 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA | 15 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA |
16 | select USB_OTG_UTILS | 16 | select USB_OTG_UTILS |
17 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' | 17 | bool 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
18 | help | 18 | help |
19 | Say Y here if your system has a dual role high speed USB | 19 | Say Y here if your system has a dual role high speed USB |
20 | controller based on the Mentor Graphics silicon IP. Then | 20 | controller based on the Mentor Graphics silicon IP. Then |
@@ -30,8 +30,8 @@ config USB_MUSB_HDRC | |||
30 | 30 | ||
31 | If you do not know what this is, please say N. | 31 | If you do not know what this is, please say N. |
32 | 32 | ||
33 | To compile this driver as a module, choose M here; the | 33 | # To compile this driver as a module, choose M here; the |
34 | module will be called "musb-hdrc". | 34 | # module will be called "musb-hdrc". |
35 | 35 | ||
36 | choice | 36 | choice |
37 | prompt "Platform Glue Layer" | 37 | prompt "Platform Glue Layer" |
diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 52312e8af213..8e2a1ff8a35a 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
22 | 22 | ||
23 | #include "musb_core.h" | 23 | #include "musb_core.h" |
24 | #include "musbhsdma.h" | ||
24 | #include "blackfin.h" | 25 | #include "blackfin.h" |
25 | 26 | ||
26 | struct bfin_glue { | 27 | struct bfin_glue { |
@@ -332,6 +333,27 @@ static int bfin_musb_set_mode(struct musb *musb, u8 musb_mode) | |||
332 | return -EIO; | 333 | return -EIO; |
333 | } | 334 | } |
334 | 335 | ||
336 | static int bfin_musb_adjust_channel_params(struct dma_channel *channel, | ||
337 | u16 packet_sz, u8 *mode, | ||
338 | dma_addr_t *dma_addr, u32 *len) | ||
339 | { | ||
340 | struct musb_dma_channel *musb_channel = channel->private_data; | ||
341 | |||
342 | /* | ||
343 | * Anomaly 05000450 might cause data corruption when using DMA | ||
344 | * MODE 1 transmits with short packet. So to work around this, | ||
345 | * we truncate all MODE 1 transfers down to a multiple of the | ||
346 | * max packet size, and then do the last short packet transfer | ||
347 | * (if there is any) using MODE 0. | ||
348 | */ | ||
349 | if (ANOMALY_05000450) { | ||
350 | if (musb_channel->transmit && *mode == 1) | ||
351 | *len = *len - (*len % packet_sz); | ||
352 | } | ||
353 | |||
354 | return 0; | ||
355 | } | ||
356 | |||
335 | static void bfin_musb_reg_init(struct musb *musb) | 357 | static void bfin_musb_reg_init(struct musb *musb) |
336 | { | 358 | { |
337 | if (ANOMALY_05000346) { | 359 | if (ANOMALY_05000346) { |
@@ -430,6 +452,8 @@ static const struct musb_platform_ops bfin_ops = { | |||
430 | 452 | ||
431 | .vbus_status = bfin_musb_vbus_status, | 453 | .vbus_status = bfin_musb_vbus_status, |
432 | .set_vbus = bfin_musb_set_vbus, | 454 | .set_vbus = bfin_musb_set_vbus, |
455 | |||
456 | .adjust_channel_params = bfin_musb_adjust_channel_params, | ||
433 | }; | 457 | }; |
434 | 458 | ||
435 | static u64 bfin_dmamask = DMA_BIT_MASK(32); | 459 | static u64 bfin_dmamask = DMA_BIT_MASK(32); |
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index de55a3c3259a..ab434fbd8c35 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -597,12 +597,12 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx) | |||
597 | length = min(n_bds * maxpacket, length); | 597 | length = min(n_bds * maxpacket, length); |
598 | } | 598 | } |
599 | 599 | ||
600 | DBG(4, "TX DMA%d, pktSz %d %s bds %d dma 0x%x len %u\n", | 600 | DBG(4, "TX DMA%d, pktSz %d %s bds %d dma 0x%llx len %u\n", |
601 | tx->index, | 601 | tx->index, |
602 | maxpacket, | 602 | maxpacket, |
603 | rndis ? "rndis" : "transparent", | 603 | rndis ? "rndis" : "transparent", |
604 | n_bds, | 604 | n_bds, |
605 | addr, length); | 605 | (unsigned long long)addr, length); |
606 | 606 | ||
607 | cppi_rndis_update(tx, 0, musb->ctrl_base, rndis); | 607 | cppi_rndis_update(tx, 0, musb->ctrl_base, rndis); |
608 | 608 | ||
@@ -820,7 +820,7 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket) | |||
820 | length = min(n_bds * maxpacket, length); | 820 | length = min(n_bds * maxpacket, length); |
821 | 821 | ||
822 | DBG(4, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) " | 822 | DBG(4, "RX DMA%d seg, maxp %d %s bds %d (cnt %d) " |
823 | "dma 0x%x len %u %u/%u\n", | 823 | "dma 0x%llx len %u %u/%u\n", |
824 | rx->index, maxpacket, | 824 | rx->index, maxpacket, |
825 | onepacket | 825 | onepacket |
826 | ? (is_rndis ? "rndis" : "onepacket") | 826 | ? (is_rndis ? "rndis" : "onepacket") |
@@ -829,7 +829,8 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket) | |||
829 | musb_readl(tibase, | 829 | musb_readl(tibase, |
830 | DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4)) | 830 | DAVINCI_RXCPPI_BUFCNT0_REG + (rx->index * 4)) |
831 | & 0xffff, | 831 | & 0xffff, |
832 | addr, length, rx->channel.actual_len, rx->buf_len); | 832 | (unsigned long long)addr, length, |
833 | rx->channel.actual_len, rx->buf_len); | ||
833 | 834 | ||
834 | /* only queue one segment at a time, since the hardware prevents | 835 | /* only queue one segment at a time, since the hardware prevents |
835 | * correct queue shutdown after unexpected short packets | 836 | * correct queue shutdown after unexpected short packets |
@@ -1039,9 +1040,9 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) | |||
1039 | if (!completed && (bd->hw_options & CPPI_OWN_SET)) | 1040 | if (!completed && (bd->hw_options & CPPI_OWN_SET)) |
1040 | break; | 1041 | break; |
1041 | 1042 | ||
1042 | DBG(5, "C/RXBD %08x: nxt %08x buf %08x " | 1043 | DBG(5, "C/RXBD %llx: nxt %08x buf %08x " |
1043 | "off.len %08x opt.len %08x (%d)\n", | 1044 | "off.len %08x opt.len %08x (%d)\n", |
1044 | bd->dma, bd->hw_next, bd->hw_bufp, | 1045 | (unsigned long long)bd->dma, bd->hw_next, bd->hw_bufp, |
1045 | bd->hw_off_len, bd->hw_options, | 1046 | bd->hw_off_len, bd->hw_options, |
1046 | rx->channel.actual_len); | 1047 | rx->channel.actual_len); |
1047 | 1048 | ||
@@ -1111,11 +1112,12 @@ static bool cppi_rx_scan(struct cppi *cppi, unsigned ch) | |||
1111 | musb_ep_select(cppi->mregs, rx->index + 1); | 1112 | musb_ep_select(cppi->mregs, rx->index + 1); |
1112 | csr = musb_readw(regs, MUSB_RXCSR); | 1113 | csr = musb_readw(regs, MUSB_RXCSR); |
1113 | if (csr & MUSB_RXCSR_DMAENAB) { | 1114 | if (csr & MUSB_RXCSR_DMAENAB) { |
1114 | DBG(4, "list%d %p/%p, last %08x%s, csr %04x\n", | 1115 | DBG(4, "list%d %p/%p, last %llx%s, csr %04x\n", |
1115 | rx->index, | 1116 | rx->index, |
1116 | rx->head, rx->tail, | 1117 | rx->head, rx->tail, |
1117 | rx->last_processed | 1118 | rx->last_processed |
1118 | ? rx->last_processed->dma | 1119 | ? (unsigned long long) |
1120 | rx->last_processed->dma | ||
1119 | : 0, | 1121 | : 0, |
1120 | completed ? ", completed" : "", | 1122 | completed ? ", completed" : "", |
1121 | csr); | 1123 | csr); |
@@ -1167,8 +1169,11 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | |||
1167 | tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); | 1169 | tx = musb_readl(tibase, DAVINCI_TXCPPI_MASKED_REG); |
1168 | rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); | 1170 | rx = musb_readl(tibase, DAVINCI_RXCPPI_MASKED_REG); |
1169 | 1171 | ||
1170 | if (!tx && !rx) | 1172 | if (!tx && !rx) { |
1173 | if (cppi->irq) | ||
1174 | spin_unlock_irqrestore(&musb->lock, flags); | ||
1171 | return IRQ_NONE; | 1175 | return IRQ_NONE; |
1176 | } | ||
1172 | 1177 | ||
1173 | DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx); | 1178 | DBG(4, "CPPI IRQ Tx%x Rx%x\n", tx, rx); |
1174 | 1179 | ||
@@ -1199,7 +1204,7 @@ irqreturn_t cppi_interrupt(int irq, void *dev_id) | |||
1199 | */ | 1204 | */ |
1200 | if (NULL == bd) { | 1205 | if (NULL == bd) { |
1201 | DBG(1, "null BD\n"); | 1206 | DBG(1, "null BD\n"); |
1202 | tx_ram->tx_complete = 0; | 1207 | musb_writel(&tx_ram->tx_complete, 0, 0); |
1203 | continue; | 1208 | continue; |
1204 | } | 1209 | } |
1205 | 1210 | ||
@@ -1452,7 +1457,7 @@ static int cppi_channel_abort(struct dma_channel *channel) | |||
1452 | * compare mode by writing 1 to the tx_complete register. | 1457 | * compare mode by writing 1 to the tx_complete register. |
1453 | */ | 1458 | */ |
1454 | cppi_reset_tx(tx_ram, 1); | 1459 | cppi_reset_tx(tx_ram, 1); |
1455 | cppi_ch->head = 0; | 1460 | cppi_ch->head = NULL; |
1456 | musb_writel(&tx_ram->tx_complete, 0, 1); | 1461 | musb_writel(&tx_ram->tx_complete, 0, 1); |
1457 | cppi_dump_tx(5, cppi_ch, " (done teardown)"); | 1462 | cppi_dump_tx(5, cppi_ch, " (done teardown)"); |
1458 | 1463 | ||
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 630ae7f3cd4c..f10ff00ca09e 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -1030,6 +1030,7 @@ static void musb_shutdown(struct platform_device *pdev) | |||
1030 | struct musb *musb = dev_to_musb(&pdev->dev); | 1030 | struct musb *musb = dev_to_musb(&pdev->dev); |
1031 | unsigned long flags; | 1031 | unsigned long flags; |
1032 | 1032 | ||
1033 | pm_runtime_get_sync(musb->controller); | ||
1033 | spin_lock_irqsave(&musb->lock, flags); | 1034 | spin_lock_irqsave(&musb->lock, flags); |
1034 | musb_platform_disable(musb); | 1035 | musb_platform_disable(musb); |
1035 | musb_generic_disable(musb); | 1036 | musb_generic_disable(musb); |
@@ -1040,6 +1041,7 @@ static void musb_shutdown(struct platform_device *pdev) | |||
1040 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); | 1041 | musb_writeb(musb->mregs, MUSB_DEVCTL, 0); |
1041 | musb_platform_exit(musb); | 1042 | musb_platform_exit(musb); |
1042 | 1043 | ||
1044 | pm_runtime_put(musb->controller); | ||
1043 | /* FIXME power down */ | 1045 | /* FIXME power down */ |
1044 | } | 1046 | } |
1045 | 1047 | ||
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 4bd9e2145ee4..0e053b587960 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
@@ -261,6 +261,7 @@ enum musb_g_ep0_state { | |||
261 | * @try_ilde: tries to idle the IP | 261 | * @try_ilde: tries to idle the IP |
262 | * @vbus_status: returns vbus status if possible | 262 | * @vbus_status: returns vbus status if possible |
263 | * @set_vbus: forces vbus status | 263 | * @set_vbus: forces vbus status |
264 | * @channel_program: pre check for standard dma channel_program func | ||
264 | */ | 265 | */ |
265 | struct musb_platform_ops { | 266 | struct musb_platform_ops { |
266 | int (*init)(struct musb *musb); | 267 | int (*init)(struct musb *musb); |
@@ -274,6 +275,10 @@ struct musb_platform_ops { | |||
274 | 275 | ||
275 | int (*vbus_status)(struct musb *musb); | 276 | int (*vbus_status)(struct musb *musb); |
276 | void (*set_vbus)(struct musb *musb, int on); | 277 | void (*set_vbus)(struct musb *musb, int on); |
278 | |||
279 | int (*adjust_channel_params)(struct dma_channel *channel, | ||
280 | u16 packet_sz, u8 *mode, | ||
281 | dma_addr_t *dma_addr, u32 *len); | ||
277 | }; | 282 | }; |
278 | 283 | ||
279 | /* | 284 | /* |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 98519c5d8b5c..f47c20197c61 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -535,7 +535,7 @@ void musb_g_tx(struct musb *musb, u8 epnum) | |||
535 | is_dma = 1; | 535 | is_dma = 1; |
536 | csr |= MUSB_TXCSR_P_WZC_BITS; | 536 | csr |= MUSB_TXCSR_P_WZC_BITS; |
537 | csr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_P_UNDERRUN | | 537 | csr &= ~(MUSB_TXCSR_DMAENAB | MUSB_TXCSR_P_UNDERRUN | |
538 | MUSB_TXCSR_TXPKTRDY); | 538 | MUSB_TXCSR_TXPKTRDY | MUSB_TXCSR_AUTOSET); |
539 | musb_writew(epio, MUSB_TXCSR, csr); | 539 | musb_writew(epio, MUSB_TXCSR, csr); |
540 | /* Ensure writebuffer is empty. */ | 540 | /* Ensure writebuffer is empty. */ |
541 | csr = musb_readw(epio, MUSB_TXCSR); | 541 | csr = musb_readw(epio, MUSB_TXCSR); |
@@ -1296,7 +1296,7 @@ static int musb_gadget_dequeue(struct usb_ep *ep, struct usb_request *request) | |||
1296 | } | 1296 | } |
1297 | 1297 | ||
1298 | /* if the hardware doesn't have the request, easy ... */ | 1298 | /* if the hardware doesn't have the request, easy ... */ |
1299 | if (musb_ep->req_list.next != &request->list || musb_ep->busy) | 1299 | if (musb_ep->req_list.next != &req->list || musb_ep->busy) |
1300 | musb_g_giveback(musb_ep, request, -ECONNRESET); | 1300 | musb_g_giveback(musb_ep, request, -ECONNRESET); |
1301 | 1301 | ||
1302 | /* ... else abort the dma transfer ... */ | 1302 | /* ... else abort the dma transfer ... */ |
@@ -1887,11 +1887,9 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | |||
1887 | otg_set_vbus(musb->xceiv, 1); | 1887 | otg_set_vbus(musb->xceiv, 1); |
1888 | 1888 | ||
1889 | hcd->self.uses_pio_for_control = 1; | 1889 | hcd->self.uses_pio_for_control = 1; |
1890 | |||
1891 | if (musb->xceiv->last_event == USB_EVENT_NONE) | ||
1892 | pm_runtime_put(musb->controller); | ||
1893 | |||
1894 | } | 1890 | } |
1891 | if (musb->xceiv->last_event == USB_EVENT_NONE) | ||
1892 | pm_runtime_put(musb->controller); | ||
1895 | 1893 | ||
1896 | return 0; | 1894 | return 0; |
1897 | 1895 | ||
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 0144a2d481fd..d281792db05c 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -169,6 +169,14 @@ static int dma_channel_program(struct dma_channel *channel, | |||
169 | BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || | 169 | BUG_ON(channel->status == MUSB_DMA_STATUS_UNKNOWN || |
170 | channel->status == MUSB_DMA_STATUS_BUSY); | 170 | channel->status == MUSB_DMA_STATUS_BUSY); |
171 | 171 | ||
172 | /* Let targets check/tweak the arguments */ | ||
173 | if (musb->ops->adjust_channel_params) { | ||
174 | int ret = musb->ops->adjust_channel_params(channel, | ||
175 | packet_sz, &mode, &dma_addr, &len); | ||
176 | if (ret) | ||
177 | return ret; | ||
178 | } | ||
179 | |||
172 | /* | 180 | /* |
173 | * The DMA engine in RTL1.8 and above cannot handle | 181 | * The DMA engine in RTL1.8 and above cannot handle |
174 | * DMA addresses that are not aligned to a 4 byte boundary. | 182 | * DMA addresses that are not aligned to a 4 byte boundary. |
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 25cb8b0003b1..e9e60b6e0583 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c | |||
@@ -259,9 +259,10 @@ static int musb_otg_notifications(struct notifier_block *nb, | |||
259 | case USB_EVENT_VBUS: | 259 | case USB_EVENT_VBUS: |
260 | DBG(4, "VBUS Connect\n"); | 260 | DBG(4, "VBUS Connect\n"); |
261 | 261 | ||
262 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | ||
262 | if (musb->gadget_driver) | 263 | if (musb->gadget_driver) |
263 | pm_runtime_get_sync(musb->controller); | 264 | pm_runtime_get_sync(musb->controller); |
264 | 265 | #endif | |
265 | otg_init(musb->xceiv); | 266 | otg_init(musb->xceiv); |
266 | break; | 267 | break; |
267 | 268 | ||
@@ -269,7 +270,7 @@ static int musb_otg_notifications(struct notifier_block *nb, | |||
269 | DBG(4, "VBUS Disconnect\n"); | 270 | DBG(4, "VBUS Disconnect\n"); |
270 | 271 | ||
271 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC | 272 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
272 | if (is_otg_enabled(musb)) | 273 | if (is_otg_enabled(musb) || is_peripheral_enabled(musb)) |
273 | if (musb->gadget_driver) | 274 | if (musb->gadget_driver) |
274 | #endif | 275 | #endif |
275 | { | 276 | { |
diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index d6384e4aeef9..f7e04bf34a13 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c | |||
@@ -93,6 +93,8 @@ static int __init ux500_probe(struct platform_device *pdev) | |||
93 | } | 93 | } |
94 | 94 | ||
95 | musb->dev.parent = &pdev->dev; | 95 | musb->dev.parent = &pdev->dev; |
96 | musb->dev.dma_mask = pdev->dev.dma_mask; | ||
97 | musb->dev.coherent_dma_mask = pdev->dev.coherent_dma_mask; | ||
96 | 98 | ||
97 | glue->dev = &pdev->dev; | 99 | glue->dev = &pdev->dev; |
98 | glue->musb = musb; | 100 | glue->musb = musb; |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index a973c7a29d6e..4de6ef0ae52a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -151,6 +151,8 @@ static struct ftdi_sio_quirk ftdi_stmclite_quirk = { | |||
151 | * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! | 151 | * /sys/bus/usb/ftdi_sio/new_id, then send patch/report! |
152 | */ | 152 | */ |
153 | static struct usb_device_id id_table_combined [] = { | 153 | static struct usb_device_id id_table_combined [] = { |
154 | { USB_DEVICE(FTDI_VID, FTDI_CTI_MINI_PID) }, | ||
155 | { USB_DEVICE(FTDI_VID, FTDI_CTI_NANO_PID) }, | ||
154 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, | 156 | { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, |
155 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, | 157 | { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, |
156 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, | 158 | { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, |
@@ -525,6 +527,7 @@ static struct usb_device_id id_table_combined [] = { | |||
525 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) }, | 527 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) }, |
526 | { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) }, | 528 | { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) }, |
527 | { USB_DEVICE(OCT_VID, OCT_US101_PID) }, | 529 | { USB_DEVICE(OCT_VID, OCT_US101_PID) }, |
530 | { USB_DEVICE(OCT_VID, OCT_DK201_PID) }, | ||
528 | { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID), | 531 | { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID), |
529 | .driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk }, | 532 | .driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk }, |
530 | { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID), | 533 | { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID), |
@@ -787,6 +790,8 @@ static struct usb_device_id id_table_combined [] = { | |||
787 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | 790 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), |
788 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 791 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
789 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, | 792 | { USB_DEVICE(FTDI_VID, HAMEG_HO820_PID) }, |
793 | { USB_DEVICE(FTDI_VID, HAMEG_HO720_PID) }, | ||
794 | { USB_DEVICE(FTDI_VID, HAMEG_HO730_PID) }, | ||
790 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, | 795 | { USB_DEVICE(FTDI_VID, HAMEG_HO870_PID) }, |
791 | { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, | 796 | { USB_DEVICE(FTDI_VID, MJSG_GENERIC_PID) }, |
792 | { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, | 797 | { USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index c543e55bafba..efffc23723bd 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -300,6 +300,8 @@ | |||
300 | * Hameg HO820 and HO870 interface (using VID 0x0403) | 300 | * Hameg HO820 and HO870 interface (using VID 0x0403) |
301 | */ | 301 | */ |
302 | #define HAMEG_HO820_PID 0xed74 | 302 | #define HAMEG_HO820_PID 0xed74 |
303 | #define HAMEG_HO730_PID 0xed73 | ||
304 | #define HAMEG_HO720_PID 0xed72 | ||
303 | #define HAMEG_HO870_PID 0xed71 | 305 | #define HAMEG_HO870_PID 0xed71 |
304 | 306 | ||
305 | /* | 307 | /* |
@@ -572,6 +574,7 @@ | |||
572 | /* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ | 574 | /* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */ |
573 | /* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ | 575 | /* Also rebadged as Dick Smith Electronics (Aus) XH6451 */ |
574 | /* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ | 576 | /* Also rebadged as SIIG Inc. model US2308 hardware version 1 */ |
577 | #define OCT_DK201_PID 0x0103 /* OCT DK201 USB docking station */ | ||
575 | #define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ | 578 | #define OCT_US101_PID 0x0421 /* OCT US101 USB to RS-232 */ |
576 | 579 | ||
577 | /* | 580 | /* |
@@ -1141,3 +1144,12 @@ | |||
1141 | #define QIHARDWARE_VID 0x20B7 | 1144 | #define QIHARDWARE_VID 0x20B7 |
1142 | #define MILKYMISTONE_JTAGSERIAL_PID 0x0713 | 1145 | #define MILKYMISTONE_JTAGSERIAL_PID 0x0713 |
1143 | 1146 | ||
1147 | /* | ||
1148 | * CTI GmbH RS485 Converter http://www.cti-lean.com/ | ||
1149 | */ | ||
1150 | /* USB-485-Mini*/ | ||
1151 | #define FTDI_CTI_MINI_PID 0xF608 | ||
1152 | /* USB-Nano-485*/ | ||
1153 | #define FTDI_CTI_NANO_PID 0xF60B | ||
1154 | |||
1155 | |||
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 75c7f456eed5..d77ff0435896 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -407,6 +407,10 @@ static void option_instat_callback(struct urb *urb); | |||
407 | /* ONDA MT825UP HSDPA 14.2 modem */ | 407 | /* ONDA MT825UP HSDPA 14.2 modem */ |
408 | #define ONDA_MT825UP 0x000b | 408 | #define ONDA_MT825UP 0x000b |
409 | 409 | ||
410 | /* Samsung products */ | ||
411 | #define SAMSUNG_VENDOR_ID 0x04e8 | ||
412 | #define SAMSUNG_PRODUCT_GT_B3730 0x6889 | ||
413 | |||
410 | /* some devices interfaces need special handling due to a number of reasons */ | 414 | /* some devices interfaces need special handling due to a number of reasons */ |
411 | enum option_blacklist_reason { | 415 | enum option_blacklist_reason { |
412 | OPTION_BLACKLIST_NONE = 0, | 416 | OPTION_BLACKLIST_NONE = 0, |
@@ -968,6 +972,7 @@ static const struct usb_device_id option_ids[] = { | |||
968 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, | 972 | { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) }, |
969 | { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ | 973 | { USB_DEVICE(CELOT_VENDOR_ID, CELOT_PRODUCT_CT680M) }, /* CT-650 CDMA 450 1xEVDO modem */ |
970 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ | 974 | { USB_DEVICE(ONDA_VENDOR_ID, ONDA_MT825UP) }, /* ONDA MT825UP modem */ |
975 | { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_GT_B3730, USB_CLASS_CDC_DATA, 0x00, 0x00) }, /* Samsung GT-B3730/GT-B3710 LTE USB modem.*/ | ||
971 | { } /* Terminating entry */ | 976 | { } /* Terminating entry */ |
972 | }; | 977 | }; |
973 | MODULE_DEVICE_TABLE(usb, option_ids); | 978 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 8858201eb1d3..54a9dab1f33b 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -111,7 +111,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
111 | ifnum = intf->desc.bInterfaceNumber; | 111 | ifnum = intf->desc.bInterfaceNumber; |
112 | dbg("This Interface = %d", ifnum); | 112 | dbg("This Interface = %d", ifnum); |
113 | 113 | ||
114 | data = serial->private = kzalloc(sizeof(struct usb_wwan_intf_private), | 114 | data = kzalloc(sizeof(struct usb_wwan_intf_private), |
115 | GFP_KERNEL); | 115 | GFP_KERNEL); |
116 | if (!data) | 116 | if (!data) |
117 | return -ENOMEM; | 117 | return -ENOMEM; |
@@ -134,8 +134,10 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
134 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { | 134 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { |
135 | dbg("QDL port found"); | 135 | dbg("QDL port found"); |
136 | 136 | ||
137 | if (serial->interface->num_altsetting == 1) | 137 | if (serial->interface->num_altsetting == 1) { |
138 | return 0; | 138 | retval = 0; /* Success */ |
139 | break; | ||
140 | } | ||
139 | 141 | ||
140 | retval = usb_set_interface(serial->dev, ifnum, 1); | 142 | retval = usb_set_interface(serial->dev, ifnum, 1); |
141 | if (retval < 0) { | 143 | if (retval < 0) { |
@@ -145,7 +147,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
145 | retval = -ENODEV; | 147 | retval = -ENODEV; |
146 | kfree(data); | 148 | kfree(data); |
147 | } | 149 | } |
148 | return retval; | ||
149 | } | 150 | } |
150 | break; | 151 | break; |
151 | 152 | ||
@@ -166,6 +167,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
166 | "Could not set interface, error %d\n", | 167 | "Could not set interface, error %d\n", |
167 | retval); | 168 | retval); |
168 | retval = -ENODEV; | 169 | retval = -ENODEV; |
170 | kfree(data); | ||
169 | } | 171 | } |
170 | } else if (ifnum == 2) { | 172 | } else if (ifnum == 2) { |
171 | dbg("Modem port found"); | 173 | dbg("Modem port found"); |
@@ -177,7 +179,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
177 | retval = -ENODEV; | 179 | retval = -ENODEV; |
178 | kfree(data); | 180 | kfree(data); |
179 | } | 181 | } |
180 | return retval; | ||
181 | } else if (ifnum==3) { | 182 | } else if (ifnum==3) { |
182 | /* | 183 | /* |
183 | * NMEA (serial line 9600 8N1) | 184 | * NMEA (serial line 9600 8N1) |
@@ -191,6 +192,7 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
191 | "Could not set interface, error %d\n", | 192 | "Could not set interface, error %d\n", |
192 | retval); | 193 | retval); |
193 | retval = -ENODEV; | 194 | retval = -ENODEV; |
195 | kfree(data); | ||
194 | } | 196 | } |
195 | } | 197 | } |
196 | break; | 198 | break; |
@@ -199,12 +201,27 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
199 | dev_err(&serial->dev->dev, | 201 | dev_err(&serial->dev->dev, |
200 | "unknown number of interfaces: %d\n", nintf); | 202 | "unknown number of interfaces: %d\n", nintf); |
201 | kfree(data); | 203 | kfree(data); |
202 | return -ENODEV; | 204 | retval = -ENODEV; |
203 | } | 205 | } |
204 | 206 | ||
207 | /* Set serial->private if not returning -ENODEV */ | ||
208 | if (retval != -ENODEV) | ||
209 | usb_set_serial_data(serial, data); | ||
205 | return retval; | 210 | return retval; |
206 | } | 211 | } |
207 | 212 | ||
213 | static void qc_release(struct usb_serial *serial) | ||
214 | { | ||
215 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | ||
216 | |||
217 | dbg("%s", __func__); | ||
218 | |||
219 | /* Call usb_wwan release & free the private data allocated in qcprobe */ | ||
220 | usb_wwan_release(serial); | ||
221 | usb_set_serial_data(serial, NULL); | ||
222 | kfree(priv); | ||
223 | } | ||
224 | |||
208 | static struct usb_serial_driver qcdevice = { | 225 | static struct usb_serial_driver qcdevice = { |
209 | .driver = { | 226 | .driver = { |
210 | .owner = THIS_MODULE, | 227 | .owner = THIS_MODULE, |
@@ -222,7 +239,7 @@ static struct usb_serial_driver qcdevice = { | |||
222 | .chars_in_buffer = usb_wwan_chars_in_buffer, | 239 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
223 | .attach = usb_wwan_startup, | 240 | .attach = usb_wwan_startup, |
224 | .disconnect = usb_wwan_disconnect, | 241 | .disconnect = usb_wwan_disconnect, |
225 | .release = usb_wwan_release, | 242 | .release = qc_release, |
226 | #ifdef CONFIG_PM | 243 | #ifdef CONFIG_PM |
227 | .suspend = usb_wwan_suspend, | 244 | .suspend = usb_wwan_suspend, |
228 | .resume = usb_wwan_resume, | 245 | .resume = usb_wwan_resume, |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index a2e5b5100ab4..0f4e8c942f9e 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -1648,7 +1648,9 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data) | |||
1648 | 1648 | ||
1649 | switch (val) { | 1649 | switch (val) { |
1650 | case CPUFREQ_PRECHANGE: | 1650 | case CPUFREQ_PRECHANGE: |
1651 | if (!fbi->overlay[0].usage && !fbi->overlay[1].usage) | 1651 | #ifdef CONFIG_FB_PXA_OVERLAY |
1652 | if (!(fbi->overlay[0].usage || fbi->overlay[1].usage)) | ||
1653 | #endif | ||
1652 | set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); | 1654 | set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE); |
1653 | break; | 1655 | break; |
1654 | 1656 | ||
diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 4fb5b2bf2348..4bcc8b82640b 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c | |||
@@ -590,15 +590,10 @@ static struct virtio_config_ops virtio_pci_config_ops = { | |||
590 | 590 | ||
591 | static void virtio_pci_release_dev(struct device *_d) | 591 | static void virtio_pci_release_dev(struct device *_d) |
592 | { | 592 | { |
593 | struct virtio_device *dev = container_of(_d, struct virtio_device, dev); | 593 | struct virtio_device *dev = container_of(_d, struct virtio_device, |
594 | dev); | ||
594 | struct virtio_pci_device *vp_dev = to_vp_device(dev); | 595 | struct virtio_pci_device *vp_dev = to_vp_device(dev); |
595 | struct pci_dev *pci_dev = vp_dev->pci_dev; | ||
596 | 596 | ||
597 | vp_del_vqs(dev); | ||
598 | pci_set_drvdata(pci_dev, NULL); | ||
599 | pci_iounmap(pci_dev, vp_dev->ioaddr); | ||
600 | pci_release_regions(pci_dev); | ||
601 | pci_disable_device(pci_dev); | ||
602 | kfree(vp_dev); | 597 | kfree(vp_dev); |
603 | } | 598 | } |
604 | 599 | ||
@@ -681,6 +676,12 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev) | |||
681 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); | 676 | struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev); |
682 | 677 | ||
683 | unregister_virtio_device(&vp_dev->vdev); | 678 | unregister_virtio_device(&vp_dev->vdev); |
679 | |||
680 | vp_del_vqs(&vp_dev->vdev); | ||
681 | pci_set_drvdata(pci_dev, NULL); | ||
682 | pci_iounmap(pci_dev, vp_dev->ioaddr); | ||
683 | pci_release_regions(pci_dev); | ||
684 | pci_disable_device(pci_dev); | ||
684 | } | 685 | } |
685 | 686 | ||
686 | #ifdef CONFIG_PM | 687 | #ifdef CONFIG_PM |
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index cc2f73e03475..b0043fb26a4d 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -371,6 +371,7 @@ void *virtqueue_detach_unused_buf(struct virtqueue *_vq) | |||
371 | /* detach_buf clears data, so grab it now. */ | 371 | /* detach_buf clears data, so grab it now. */ |
372 | buf = vq->data[i]; | 372 | buf = vq->data[i]; |
373 | detach_buf(vq, i); | 373 | detach_buf(vq, i); |
374 | vq->vring.avail->idx--; | ||
374 | END_USE(vq); | 375 | END_USE(vq); |
375 | return buf; | 376 | return buf; |
376 | } | 377 | } |
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 35a0d12dad73..5fd020da7c55 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c | |||
@@ -35,6 +35,7 @@ | |||
35 | * document number 324645-001, 324646-001: Cougar Point (CPT) | 35 | * document number 324645-001, 324646-001: Cougar Point (CPT) |
36 | * document number TBD : Patsburg (PBG) | 36 | * document number TBD : Patsburg (PBG) |
37 | * document number TBD : DH89xxCC | 37 | * document number TBD : DH89xxCC |
38 | * document number TBD : Panther Point | ||
38 | */ | 39 | */ |
39 | 40 | ||
40 | /* | 41 | /* |
@@ -153,6 +154,38 @@ enum iTCO_chipsets { | |||
153 | TCO_PBG1, /* Patsburg */ | 154 | TCO_PBG1, /* Patsburg */ |
154 | TCO_PBG2, /* Patsburg */ | 155 | TCO_PBG2, /* Patsburg */ |
155 | TCO_DH89XXCC, /* DH89xxCC */ | 156 | TCO_DH89XXCC, /* DH89xxCC */ |
157 | TCO_PPT0, /* Panther Point */ | ||
158 | TCO_PPT1, /* Panther Point */ | ||
159 | TCO_PPT2, /* Panther Point */ | ||
160 | TCO_PPT3, /* Panther Point */ | ||
161 | TCO_PPT4, /* Panther Point */ | ||
162 | TCO_PPT5, /* Panther Point */ | ||
163 | TCO_PPT6, /* Panther Point */ | ||
164 | TCO_PPT7, /* Panther Point */ | ||
165 | TCO_PPT8, /* Panther Point */ | ||
166 | TCO_PPT9, /* Panther Point */ | ||
167 | TCO_PPT10, /* Panther Point */ | ||
168 | TCO_PPT11, /* Panther Point */ | ||
169 | TCO_PPT12, /* Panther Point */ | ||
170 | TCO_PPT13, /* Panther Point */ | ||
171 | TCO_PPT14, /* Panther Point */ | ||
172 | TCO_PPT15, /* Panther Point */ | ||
173 | TCO_PPT16, /* Panther Point */ | ||
174 | TCO_PPT17, /* Panther Point */ | ||
175 | TCO_PPT18, /* Panther Point */ | ||
176 | TCO_PPT19, /* Panther Point */ | ||
177 | TCO_PPT20, /* Panther Point */ | ||
178 | TCO_PPT21, /* Panther Point */ | ||
179 | TCO_PPT22, /* Panther Point */ | ||
180 | TCO_PPT23, /* Panther Point */ | ||
181 | TCO_PPT24, /* Panther Point */ | ||
182 | TCO_PPT25, /* Panther Point */ | ||
183 | TCO_PPT26, /* Panther Point */ | ||
184 | TCO_PPT27, /* Panther Point */ | ||
185 | TCO_PPT28, /* Panther Point */ | ||
186 | TCO_PPT29, /* Panther Point */ | ||
187 | TCO_PPT30, /* Panther Point */ | ||
188 | TCO_PPT31, /* Panther Point */ | ||
156 | }; | 189 | }; |
157 | 190 | ||
158 | static struct { | 191 | static struct { |
@@ -244,6 +277,38 @@ static struct { | |||
244 | {"Patsburg", 2}, | 277 | {"Patsburg", 2}, |
245 | {"Patsburg", 2}, | 278 | {"Patsburg", 2}, |
246 | {"DH89xxCC", 2}, | 279 | {"DH89xxCC", 2}, |
280 | {"Panther Point", 2}, | ||
281 | {"Panther Point", 2}, | ||
282 | {"Panther Point", 2}, | ||
283 | {"Panther Point", 2}, | ||
284 | {"Panther Point", 2}, | ||
285 | {"Panther Point", 2}, | ||
286 | {"Panther Point", 2}, | ||
287 | {"Panther Point", 2}, | ||
288 | {"Panther Point", 2}, | ||
289 | {"Panther Point", 2}, | ||
290 | {"Panther Point", 2}, | ||
291 | {"Panther Point", 2}, | ||
292 | {"Panther Point", 2}, | ||
293 | {"Panther Point", 2}, | ||
294 | {"Panther Point", 2}, | ||
295 | {"Panther Point", 2}, | ||
296 | {"Panther Point", 2}, | ||
297 | {"Panther Point", 2}, | ||
298 | {"Panther Point", 2}, | ||
299 | {"Panther Point", 2}, | ||
300 | {"Panther Point", 2}, | ||
301 | {"Panther Point", 2}, | ||
302 | {"Panther Point", 2}, | ||
303 | {"Panther Point", 2}, | ||
304 | {"Panther Point", 2}, | ||
305 | {"Panther Point", 2}, | ||
306 | {"Panther Point", 2}, | ||
307 | {"Panther Point", 2}, | ||
308 | {"Panther Point", 2}, | ||
309 | {"Panther Point", 2}, | ||
310 | {"Panther Point", 2}, | ||
311 | {"Panther Point", 2}, | ||
247 | {NULL, 0} | 312 | {NULL, 0} |
248 | }; | 313 | }; |
249 | 314 | ||
@@ -363,6 +428,38 @@ static DEFINE_PCI_DEVICE_TABLE(iTCO_wdt_pci_tbl) = { | |||
363 | { ITCO_PCI_DEVICE(0x1d40, TCO_PBG1)}, | 428 | { ITCO_PCI_DEVICE(0x1d40, TCO_PBG1)}, |
364 | { ITCO_PCI_DEVICE(0x1d41, TCO_PBG2)}, | 429 | { ITCO_PCI_DEVICE(0x1d41, TCO_PBG2)}, |
365 | { ITCO_PCI_DEVICE(0x2310, TCO_DH89XXCC)}, | 430 | { ITCO_PCI_DEVICE(0x2310, TCO_DH89XXCC)}, |
431 | { ITCO_PCI_DEVICE(0x1e40, TCO_PPT0)}, | ||
432 | { ITCO_PCI_DEVICE(0x1e41, TCO_PPT1)}, | ||
433 | { ITCO_PCI_DEVICE(0x1e42, TCO_PPT2)}, | ||
434 | { ITCO_PCI_DEVICE(0x1e43, TCO_PPT3)}, | ||
435 | { ITCO_PCI_DEVICE(0x1e44, TCO_PPT4)}, | ||
436 | { ITCO_PCI_DEVICE(0x1e45, TCO_PPT5)}, | ||
437 | { ITCO_PCI_DEVICE(0x1e46, TCO_PPT6)}, | ||
438 | { ITCO_PCI_DEVICE(0x1e47, TCO_PPT7)}, | ||
439 | { ITCO_PCI_DEVICE(0x1e48, TCO_PPT8)}, | ||
440 | { ITCO_PCI_DEVICE(0x1e49, TCO_PPT9)}, | ||
441 | { ITCO_PCI_DEVICE(0x1e4a, TCO_PPT10)}, | ||
442 | { ITCO_PCI_DEVICE(0x1e4b, TCO_PPT11)}, | ||
443 | { ITCO_PCI_DEVICE(0x1e4c, TCO_PPT12)}, | ||
444 | { ITCO_PCI_DEVICE(0x1e4d, TCO_PPT13)}, | ||
445 | { ITCO_PCI_DEVICE(0x1e4e, TCO_PPT14)}, | ||
446 | { ITCO_PCI_DEVICE(0x1e4f, TCO_PPT15)}, | ||
447 | { ITCO_PCI_DEVICE(0x1e50, TCO_PPT16)}, | ||
448 | { ITCO_PCI_DEVICE(0x1e51, TCO_PPT17)}, | ||
449 | { ITCO_PCI_DEVICE(0x1e52, TCO_PPT18)}, | ||
450 | { ITCO_PCI_DEVICE(0x1e53, TCO_PPT19)}, | ||
451 | { ITCO_PCI_DEVICE(0x1e54, TCO_PPT20)}, | ||
452 | { ITCO_PCI_DEVICE(0x1e55, TCO_PPT21)}, | ||
453 | { ITCO_PCI_DEVICE(0x1e56, TCO_PPT22)}, | ||
454 | { ITCO_PCI_DEVICE(0x1e57, TCO_PPT23)}, | ||
455 | { ITCO_PCI_DEVICE(0x1e58, TCO_PPT24)}, | ||
456 | { ITCO_PCI_DEVICE(0x1e59, TCO_PPT25)}, | ||
457 | { ITCO_PCI_DEVICE(0x1e5a, TCO_PPT26)}, | ||
458 | { ITCO_PCI_DEVICE(0x1e5b, TCO_PPT27)}, | ||
459 | { ITCO_PCI_DEVICE(0x1e5c, TCO_PPT28)}, | ||
460 | { ITCO_PCI_DEVICE(0x1e5d, TCO_PPT29)}, | ||
461 | { ITCO_PCI_DEVICE(0x1e5e, TCO_PPT30)}, | ||
462 | { ITCO_PCI_DEVICE(0x1e5f, TCO_PPT31)}, | ||
366 | { 0, }, /* End of list */ | 463 | { 0, }, /* End of list */ |
367 | }; | 464 | }; |
368 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); | 465 | MODULE_DEVICE_TABLE(pci, iTCO_wdt_pci_tbl); |
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 42d6c930cc87..33167b43ac7e 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -912,8 +912,7 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn, | |||
912 | unsigned long irqflags, | 912 | unsigned long irqflags, |
913 | const char *devname, void *dev_id) | 913 | const char *devname, void *dev_id) |
914 | { | 914 | { |
915 | unsigned int irq; | 915 | int irq, retval; |
916 | int retval; | ||
917 | 916 | ||
918 | irq = bind_evtchn_to_irq(evtchn); | 917 | irq = bind_evtchn_to_irq(evtchn); |
919 | if (irq < 0) | 918 | if (irq < 0) |
@@ -955,8 +954,7 @@ int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu, | |||
955 | irq_handler_t handler, | 954 | irq_handler_t handler, |
956 | unsigned long irqflags, const char *devname, void *dev_id) | 955 | unsigned long irqflags, const char *devname, void *dev_id) |
957 | { | 956 | { |
958 | unsigned int irq; | 957 | int irq, retval; |
959 | int retval; | ||
960 | 958 | ||
961 | irq = bind_virq_to_irq(virq, cpu); | 959 | irq = bind_virq_to_irq(virq, cpu); |
962 | if (irq < 0) | 960 | if (irq < 0) |
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 95143dd6904d..a2eee574784e 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/sysrq.h> | 8 | #include <linux/sysrq.h> |
9 | #include <linux/stop_machine.h> | 9 | #include <linux/stop_machine.h> |
10 | #include <linux/freezer.h> | 10 | #include <linux/freezer.h> |
11 | #include <linux/syscore_ops.h> | ||
11 | 12 | ||
12 | #include <xen/xen.h> | 13 | #include <xen/xen.h> |
13 | #include <xen/xenbus.h> | 14 | #include <xen/xenbus.h> |
@@ -61,7 +62,7 @@ static void xen_post_suspend(int cancelled) | |||
61 | xen_mm_unpin_all(); | 62 | xen_mm_unpin_all(); |
62 | } | 63 | } |
63 | 64 | ||
64 | #ifdef CONFIG_HIBERNATION | 65 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
65 | static int xen_suspend(void *data) | 66 | static int xen_suspend(void *data) |
66 | { | 67 | { |
67 | struct suspend_info *si = data; | 68 | struct suspend_info *si = data; |
@@ -70,8 +71,13 @@ static int xen_suspend(void *data) | |||
70 | BUG_ON(!irqs_disabled()); | 71 | BUG_ON(!irqs_disabled()); |
71 | 72 | ||
72 | err = sysdev_suspend(PMSG_FREEZE); | 73 | err = sysdev_suspend(PMSG_FREEZE); |
74 | if (!err) { | ||
75 | err = syscore_suspend(); | ||
76 | if (err) | ||
77 | sysdev_resume(); | ||
78 | } | ||
73 | if (err) { | 79 | if (err) { |
74 | printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n", | 80 | printk(KERN_ERR "xen_suspend: system core suspend failed: %d\n", |
75 | err); | 81 | err); |
76 | return err; | 82 | return err; |
77 | } | 83 | } |
@@ -95,6 +101,7 @@ static int xen_suspend(void *data) | |||
95 | xen_timer_resume(); | 101 | xen_timer_resume(); |
96 | } | 102 | } |
97 | 103 | ||
104 | syscore_resume(); | ||
98 | sysdev_resume(); | 105 | sysdev_resume(); |
99 | 106 | ||
100 | return 0; | 107 | return 0; |
@@ -173,7 +180,7 @@ out: | |||
173 | #endif | 180 | #endif |
174 | shutting_down = SHUTDOWN_INVALID; | 181 | shutting_down = SHUTDOWN_INVALID; |
175 | } | 182 | } |
176 | #endif /* CONFIG_HIBERNATION */ | 183 | #endif /* CONFIG_HIBERNATE_CALLBACKS */ |
177 | 184 | ||
178 | struct shutdown_handler { | 185 | struct shutdown_handler { |
179 | const char *command; | 186 | const char *command; |
@@ -202,7 +209,7 @@ static void shutdown_handler(struct xenbus_watch *watch, | |||
202 | { "poweroff", do_poweroff }, | 209 | { "poweroff", do_poweroff }, |
203 | { "halt", do_poweroff }, | 210 | { "halt", do_poweroff }, |
204 | { "reboot", do_reboot }, | 211 | { "reboot", do_reboot }, |
205 | #ifdef CONFIG_HIBERNATION | 212 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
206 | { "suspend", do_suspend }, | 213 | { "suspend", do_suspend }, |
207 | #endif | 214 | #endif |
208 | {NULL, NULL}, | 215 | {NULL, NULL}, |