diff options
Diffstat (limited to 'drivers')
33 files changed, 765 insertions, 174 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 544b7d6c617c..966ab401e523 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -89,6 +89,7 @@ enum { | |||
89 | board_ahci_sb600 = 3, | 89 | board_ahci_sb600 = 3, |
90 | board_ahci_mv = 4, | 90 | board_ahci_mv = 4, |
91 | board_ahci_sb700 = 5, | 91 | board_ahci_sb700 = 5, |
92 | board_ahci_mcp65 = 6, | ||
92 | 93 | ||
93 | /* global controller registers */ | 94 | /* global controller registers */ |
94 | HOST_CAP = 0x00, /* host capabilities */ | 95 | HOST_CAP = 0x00, /* host capabilities */ |
@@ -190,6 +191,7 @@ enum { | |||
190 | AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ | 191 | AHCI_HFLAG_NO_PMP = (1 << 6), /* no PMP */ |
191 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ | 192 | AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ |
192 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ | 193 | AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ |
194 | AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ | ||
193 | 195 | ||
194 | /* ap->flags bits */ | 196 | /* ap->flags bits */ |
195 | 197 | ||
@@ -253,6 +255,8 @@ static void ahci_pmp_attach(struct ata_port *ap); | |||
253 | static void ahci_pmp_detach(struct ata_port *ap); | 255 | static void ahci_pmp_detach(struct ata_port *ap); |
254 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | 256 | static int ahci_softreset(struct ata_link *link, unsigned int *class, |
255 | unsigned long deadline); | 257 | unsigned long deadline); |
258 | static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class, | ||
259 | unsigned long deadline); | ||
256 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, | 260 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, |
257 | unsigned long deadline); | 261 | unsigned long deadline); |
258 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, | 262 | static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class, |
@@ -329,6 +333,12 @@ static struct ata_port_operations ahci_p5wdh_ops = { | |||
329 | .hardreset = ahci_p5wdh_hardreset, | 333 | .hardreset = ahci_p5wdh_hardreset, |
330 | }; | 334 | }; |
331 | 335 | ||
336 | static struct ata_port_operations ahci_sb600_ops = { | ||
337 | .inherits = &ahci_ops, | ||
338 | .softreset = ahci_sb600_softreset, | ||
339 | .pmp_softreset = ahci_sb600_softreset, | ||
340 | }; | ||
341 | |||
332 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) | 342 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) |
333 | 343 | ||
334 | static const struct ata_port_info ahci_port_info[] = { | 344 | static const struct ata_port_info ahci_port_info[] = { |
@@ -359,11 +369,11 @@ static const struct ata_port_info ahci_port_info[] = { | |||
359 | { | 369 | { |
360 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 370 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | |
361 | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | | 371 | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | |
362 | AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP), | 372 | AHCI_HFLAG_SECT255), |
363 | .flags = AHCI_FLAG_COMMON, | 373 | .flags = AHCI_FLAG_COMMON, |
364 | .pio_mask = 0x1f, /* pio0-4 */ | 374 | .pio_mask = 0x1f, /* pio0-4 */ |
365 | .udma_mask = ATA_UDMA6, | 375 | .udma_mask = ATA_UDMA6, |
366 | .port_ops = &ahci_ops, | 376 | .port_ops = &ahci_sb600_ops, |
367 | }, | 377 | }, |
368 | /* board_ahci_mv */ | 378 | /* board_ahci_mv */ |
369 | { | 379 | { |
@@ -377,8 +387,15 @@ static const struct ata_port_info ahci_port_info[] = { | |||
377 | }, | 387 | }, |
378 | /* board_ahci_sb700 */ | 388 | /* board_ahci_sb700 */ |
379 | { | 389 | { |
380 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 390 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), |
381 | AHCI_HFLAG_NO_PMP), | 391 | .flags = AHCI_FLAG_COMMON, |
392 | .pio_mask = 0x1f, /* pio0-4 */ | ||
393 | .udma_mask = ATA_UDMA6, | ||
394 | .port_ops = &ahci_sb600_ops, | ||
395 | }, | ||
396 | /* board_ahci_mcp65 */ | ||
397 | { | ||
398 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), | ||
382 | .flags = AHCI_FLAG_COMMON, | 399 | .flags = AHCI_FLAG_COMMON, |
383 | .pio_mask = 0x1f, /* pio0-4 */ | 400 | .pio_mask = 0x1f, /* pio0-4 */ |
384 | .udma_mask = ATA_UDMA6, | 401 | .udma_mask = ATA_UDMA6, |
@@ -438,14 +455,14 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
438 | { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */ | 455 | { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */ |
439 | 456 | ||
440 | /* NVIDIA */ | 457 | /* NVIDIA */ |
441 | { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci }, /* MCP65 */ | 458 | { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci_mcp65 }, /* MCP65 */ |
442 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci }, /* MCP65 */ | 459 | { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci_mcp65 }, /* MCP65 */ |
443 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci }, /* MCP65 */ | 460 | { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci_mcp65 }, /* MCP65 */ |
444 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci }, /* MCP65 */ | 461 | { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci_mcp65 }, /* MCP65 */ |
445 | { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci }, /* MCP65 */ | 462 | { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci_mcp65 }, /* MCP65 */ |
446 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci }, /* MCP65 */ | 463 | { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */ |
447 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci }, /* MCP65 */ | 464 | { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */ |
448 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci }, /* MCP65 */ | 465 | { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */ |
449 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ | 466 | { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci }, /* MCP67 */ |
450 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ | 467 | { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci }, /* MCP67 */ |
451 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ | 468 | { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci }, /* MCP67 */ |
@@ -624,6 +641,12 @@ static void ahci_save_initial_config(struct pci_dev *pdev, | |||
624 | cap &= ~HOST_CAP_NCQ; | 641 | cap &= ~HOST_CAP_NCQ; |
625 | } | 642 | } |
626 | 643 | ||
644 | if (!(cap & HOST_CAP_NCQ) && (hpriv->flags & AHCI_HFLAG_YES_NCQ)) { | ||
645 | dev_printk(KERN_INFO, &pdev->dev, | ||
646 | "controller can do NCQ, turning on CAP_NCQ\n"); | ||
647 | cap |= HOST_CAP_NCQ; | ||
648 | } | ||
649 | |||
627 | if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { | 650 | if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) { |
628 | dev_printk(KERN_INFO, &pdev->dev, | 651 | dev_printk(KERN_INFO, &pdev->dev, |
629 | "controller can't do PMP, turning off CAP_PMP\n"); | 652 | "controller can't do PMP, turning off CAP_PMP\n"); |
@@ -1262,19 +1285,11 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, | |||
1262 | return 0; | 1285 | return 0; |
1263 | } | 1286 | } |
1264 | 1287 | ||
1265 | static int ahci_check_ready(struct ata_link *link) | 1288 | static int ahci_do_softreset(struct ata_link *link, unsigned int *class, |
1266 | { | 1289 | int pmp, unsigned long deadline, |
1267 | void __iomem *port_mmio = ahci_port_base(link->ap); | 1290 | int (*check_ready)(struct ata_link *link)) |
1268 | u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
1269 | |||
1270 | return ata_check_ready(status); | ||
1271 | } | ||
1272 | |||
1273 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | ||
1274 | unsigned long deadline) | ||
1275 | { | 1291 | { |
1276 | struct ata_port *ap = link->ap; | 1292 | struct ata_port *ap = link->ap; |
1277 | int pmp = sata_srst_pmp(link); | ||
1278 | const char *reason = NULL; | 1293 | const char *reason = NULL; |
1279 | unsigned long now, msecs; | 1294 | unsigned long now, msecs; |
1280 | struct ata_taskfile tf; | 1295 | struct ata_taskfile tf; |
@@ -1312,7 +1327,7 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class, | |||
1312 | ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); | 1327 | ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0); |
1313 | 1328 | ||
1314 | /* wait for link to become ready */ | 1329 | /* wait for link to become ready */ |
1315 | rc = ata_wait_after_reset(link, deadline, ahci_check_ready); | 1330 | rc = ata_wait_after_reset(link, deadline, check_ready); |
1316 | /* link occupied, -ENODEV too is an error */ | 1331 | /* link occupied, -ENODEV too is an error */ |
1317 | if (rc) { | 1332 | if (rc) { |
1318 | reason = "device not ready"; | 1333 | reason = "device not ready"; |
@@ -1328,6 +1343,72 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class, | |||
1328 | return rc; | 1343 | return rc; |
1329 | } | 1344 | } |
1330 | 1345 | ||
1346 | static int ahci_check_ready(struct ata_link *link) | ||
1347 | { | ||
1348 | void __iomem *port_mmio = ahci_port_base(link->ap); | ||
1349 | u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
1350 | |||
1351 | return ata_check_ready(status); | ||
1352 | } | ||
1353 | |||
1354 | static int ahci_softreset(struct ata_link *link, unsigned int *class, | ||
1355 | unsigned long deadline) | ||
1356 | { | ||
1357 | int pmp = sata_srst_pmp(link); | ||
1358 | |||
1359 | DPRINTK("ENTER\n"); | ||
1360 | |||
1361 | return ahci_do_softreset(link, class, pmp, deadline, ahci_check_ready); | ||
1362 | } | ||
1363 | |||
1364 | static int ahci_sb600_check_ready(struct ata_link *link) | ||
1365 | { | ||
1366 | void __iomem *port_mmio = ahci_port_base(link->ap); | ||
1367 | u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF; | ||
1368 | u32 irq_status = readl(port_mmio + PORT_IRQ_STAT); | ||
1369 | |||
1370 | /* | ||
1371 | * There is no need to check TFDATA if BAD PMP is found due to HW bug, | ||
1372 | * which can save timeout delay. | ||
1373 | */ | ||
1374 | if (irq_status & PORT_IRQ_BAD_PMP) | ||
1375 | return -EIO; | ||
1376 | |||
1377 | return ata_check_ready(status); | ||
1378 | } | ||
1379 | |||
1380 | static int ahci_sb600_softreset(struct ata_link *link, unsigned int *class, | ||
1381 | unsigned long deadline) | ||
1382 | { | ||
1383 | struct ata_port *ap = link->ap; | ||
1384 | void __iomem *port_mmio = ahci_port_base(ap); | ||
1385 | int pmp = sata_srst_pmp(link); | ||
1386 | int rc; | ||
1387 | u32 irq_sts; | ||
1388 | |||
1389 | DPRINTK("ENTER\n"); | ||
1390 | |||
1391 | rc = ahci_do_softreset(link, class, pmp, deadline, | ||
1392 | ahci_sb600_check_ready); | ||
1393 | |||
1394 | /* | ||
1395 | * Soft reset fails on some ATI chips with IPMS set when PMP | ||
1396 | * is enabled but SATA HDD/ODD is connected to SATA port, | ||
1397 | * do soft reset again to port 0. | ||
1398 | */ | ||
1399 | if (rc == -EIO) { | ||
1400 | irq_sts = readl(port_mmio + PORT_IRQ_STAT); | ||
1401 | if (irq_sts & PORT_IRQ_BAD_PMP) { | ||
1402 | ata_link_printk(link, KERN_WARNING, | ||
1403 | "failed due to HW bug, retry pmp=0\n"); | ||
1404 | rc = ahci_do_softreset(link, class, 0, deadline, | ||
1405 | ahci_check_ready); | ||
1406 | } | ||
1407 | } | ||
1408 | |||
1409 | return rc; | ||
1410 | } | ||
1411 | |||
1331 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, | 1412 | static int ahci_hardreset(struct ata_link *link, unsigned int *class, |
1332 | unsigned long deadline) | 1413 | unsigned long deadline) |
1333 | { | 1414 | { |
@@ -2118,7 +2199,8 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2118 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 2199 | static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
2119 | { | 2200 | { |
2120 | static int printed_version; | 2201 | static int printed_version; |
2121 | struct ata_port_info pi = ahci_port_info[ent->driver_data]; | 2202 | unsigned int board_id = ent->driver_data; |
2203 | struct ata_port_info pi = ahci_port_info[board_id]; | ||
2122 | const struct ata_port_info *ppi[] = { &pi, NULL }; | 2204 | const struct ata_port_info *ppi[] = { &pi, NULL }; |
2123 | struct device *dev = &pdev->dev; | 2205 | struct device *dev = &pdev->dev; |
2124 | struct ahci_host_priv *hpriv; | 2206 | struct ahci_host_priv *hpriv; |
@@ -2167,6 +2249,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2167 | return -ENOMEM; | 2249 | return -ENOMEM; |
2168 | hpriv->flags |= (unsigned long)pi.private_data; | 2250 | hpriv->flags |= (unsigned long)pi.private_data; |
2169 | 2251 | ||
2252 | /* MCP65 revision A1 and A2 can't do MSI */ | ||
2253 | if (board_id == board_ahci_mcp65 && | ||
2254 | (pdev->revision == 0xa1 || pdev->revision == 0xa2)) | ||
2255 | hpriv->flags |= AHCI_HFLAG_NO_MSI; | ||
2256 | |||
2170 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) | 2257 | if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev)) |
2171 | pci_intx(pdev, 1); | 2258 | pci_intx(pdev, 1); |
2172 | 2259 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index e336b05fe4a7..5f1e1cc6165a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -53,15 +53,16 @@ | |||
53 | #include <linux/scatterlist.h> | 53 | #include <linux/scatterlist.h> |
54 | 54 | ||
55 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) | 55 | #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin)) |
56 | #define DRIVER_NAME "HP CISS Driver (v 3.6.14)" | 56 | #define DRIVER_NAME "HP CISS Driver (v 3.6.20)" |
57 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(3,6,14) | 57 | #define DRIVER_VERSION CCISS_DRIVER_VERSION(3, 6, 20) |
58 | 58 | ||
59 | /* Embedded module documentation macros - see modules.h */ | 59 | /* Embedded module documentation macros - see modules.h */ |
60 | MODULE_AUTHOR("Hewlett-Packard Company"); | 60 | MODULE_AUTHOR("Hewlett-Packard Company"); |
61 | MODULE_DESCRIPTION("Driver for HP Controller SA5xxx SA6xxx version 3.6.14"); | 61 | MODULE_DESCRIPTION("Driver for HP Smart Array Controllers"); |
62 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" | 62 | MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400" |
63 | " SA6i P600 P800 P400 P400i E200 E200i E500"); | 63 | " SA6i P600 P800 P400 P400i E200 E200i E500 P700m" |
64 | MODULE_VERSION("3.6.14"); | 64 | " Smart Array G2 Series SAS/SATA Controllers"); |
65 | MODULE_VERSION("3.6.20"); | ||
65 | MODULE_LICENSE("GPL"); | 66 | MODULE_LICENSE("GPL"); |
66 | 67 | ||
67 | #include "cciss_cmd.h" | 68 | #include "cciss_cmd.h" |
@@ -90,6 +91,11 @@ static const struct pci_device_id cciss_pci_device_id[] = { | |||
90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, | 91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSD, 0x103C, 0x3215}, |
91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, | 92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x3237}, |
92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, | 93 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSC, 0x103C, 0x323D}, |
94 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3241}, | ||
95 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3243}, | ||
96 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3245}, | ||
97 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3247}, | ||
98 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3249}, | ||
93 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 99 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
94 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | 100 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, |
95 | {0,} | 101 | {0,} |
@@ -123,6 +129,11 @@ static struct board_type products[] = { | |||
123 | {0x3215103C, "Smart Array E200i", &SA5_access, 120}, | 129 | {0x3215103C, "Smart Array E200i", &SA5_access, 120}, |
124 | {0x3237103C, "Smart Array E500", &SA5_access, 512}, | 130 | {0x3237103C, "Smart Array E500", &SA5_access, 512}, |
125 | {0x323D103C, "Smart Array P700m", &SA5_access, 512}, | 131 | {0x323D103C, "Smart Array P700m", &SA5_access, 512}, |
132 | {0x3241103C, "Smart Array P212", &SA5_access, 384}, | ||
133 | {0x3243103C, "Smart Array P410", &SA5_access, 384}, | ||
134 | {0x3245103C, "Smart Array P410i", &SA5_access, 384}, | ||
135 | {0x3247103C, "Smart Array P411", &SA5_access, 384}, | ||
136 | {0x3249103C, "Smart Array P812", &SA5_access, 384}, | ||
126 | {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, | 137 | {0xFFFF103C, "Unknown Smart Array", &SA5_access, 120}, |
127 | }; | 138 | }; |
128 | 139 | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index d307bf26af58..2d854bb9373e 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -749,7 +749,7 @@ config NVRAM | |||
749 | if RTC_LIB=n | 749 | if RTC_LIB=n |
750 | 750 | ||
751 | config RTC | 751 | config RTC |
752 | tristate "Enhanced Real Time Clock Support" | 752 | tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)" |
753 | depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV \ | 753 | depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV \ |
754 | && !ARM && !SUPERH && !S390 && !AVR32 | 754 | && !ARM && !SUPERH && !S390 && !AVR32 |
755 | ---help--- | 755 | ---help--- |
@@ -1036,9 +1036,9 @@ config HPET | |||
1036 | non-periodic and/or periodic. | 1036 | non-periodic and/or periodic. |
1037 | 1037 | ||
1038 | config HPET_RTC_IRQ | 1038 | config HPET_RTC_IRQ |
1039 | bool "HPET Control RTC IRQ" if !HPET_EMULATE_RTC | 1039 | bool |
1040 | default n | 1040 | default HPET_EMULATE_RTC |
1041 | depends on HPET | 1041 | depends on RTC && HPET |
1042 | help | 1042 | help |
1043 | If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It | 1043 | If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It |
1044 | is assumed the platform called hpet_alloc with the RTC IRQ values for | 1044 | is assumed the platform called hpet_alloc with the RTC IRQ values for |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index 55c97f623242..07b4d8ff56e5 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
@@ -458,6 +458,10 @@ static struct agp_device_ids ati_agp_device_ids[] __devinitdata = | |||
458 | .chipset_name = "IGP9100/M", | 458 | .chipset_name = "IGP9100/M", |
459 | }, | 459 | }, |
460 | { | 460 | { |
461 | .device_id = PCI_DEVICE_ID_ATI_RS350_133, | ||
462 | .chipset_name = "IGP9000/M", | ||
463 | }, | ||
464 | { | ||
461 | .device_id = PCI_DEVICE_ID_ATI_RS350_200, | 465 | .device_id = PCI_DEVICE_ID_ATI_RS350_200, |
462 | .chipset_name = "IGP9100/M", | 466 | .chipset_name = "IGP9100/M", |
463 | }, | 467 | }, |
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c index 2398e864c28d..a00869c650d5 100644 --- a/drivers/char/generic_nvram.c +++ b/drivers/char/generic_nvram.c | |||
@@ -133,7 +133,7 @@ static struct miscdevice nvram_dev = { | |||
133 | 133 | ||
134 | int __init nvram_init(void) | 134 | int __init nvram_init(void) |
135 | { | 135 | { |
136 | printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n", | 136 | printk(KERN_INFO "Generic non-volatile memory driver v%s\n", |
137 | NVRAM_VERSION); | 137 | NVRAM_VERSION); |
138 | return misc_register(&nvram_dev); | 138 | return misc_register(&nvram_dev); |
139 | } | 139 | } |
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 5cc651ef75eb..27fdc0866496 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c | |||
@@ -273,7 +273,7 @@ static int __init intel_rng_hw_init(void *_intel_rng_hw) | |||
273 | if (mfc != INTEL_FWH_MANUFACTURER_CODE || | 273 | if (mfc != INTEL_FWH_MANUFACTURER_CODE || |
274 | (dvc != INTEL_FWH_DEVICE_CODE_8M && | 274 | (dvc != INTEL_FWH_DEVICE_CODE_8M && |
275 | dvc != INTEL_FWH_DEVICE_CODE_4M)) { | 275 | dvc != INTEL_FWH_DEVICE_CODE_4M)) { |
276 | printk(KERN_ERR PFX "FWH not detected\n"); | 276 | printk(KERN_NOTICE PFX "FWH not detected\n"); |
277 | return -ENODEV; | 277 | return -ENODEV; |
278 | } | 278 | } |
279 | 279 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 7f7e798c1384..d9a0a53c842d 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -677,12 +677,7 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag) | |||
677 | 677 | ||
678 | static void k_self(struct vc_data *vc, unsigned char value, char up_flag) | 678 | static void k_self(struct vc_data *vc, unsigned char value, char up_flag) |
679 | { | 679 | { |
680 | unsigned int uni; | 680 | k_unicode(vc, conv_8bit_to_uni(value), up_flag); |
681 | if (kbd->kbdmode == VC_UNICODE) | ||
682 | uni = value; | ||
683 | else | ||
684 | uni = conv_8bit_to_uni(value); | ||
685 | k_unicode(vc, uni, up_flag); | ||
686 | } | 681 | } |
687 | 682 | ||
688 | static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) | 683 | static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) |
diff --git a/drivers/isdn/sc/ioctl.c b/drivers/isdn/sc/ioctl.c index 7817d2244921..1081091bbfaf 100644 --- a/drivers/isdn/sc/ioctl.c +++ b/drivers/isdn/sc/ioctl.c | |||
@@ -226,6 +226,7 @@ int sc_ioctl(int card, scs_ioctl *data) | |||
226 | */ | 226 | */ |
227 | if (copy_from_user(spid, data->dataptr, SCIOC_SPIDSIZE)) { | 227 | if (copy_from_user(spid, data->dataptr, SCIOC_SPIDSIZE)) { |
228 | kfree(rcvmsg); | 228 | kfree(rcvmsg); |
229 | kfree(spid); | ||
229 | return -EFAULT; | 230 | return -EFAULT; |
230 | } | 231 | } |
231 | 232 | ||
diff --git a/drivers/mmc/host/wbsd.c b/drivers/mmc/host/wbsd.c index be624a049c67..c303e7f57ab4 100644 --- a/drivers/mmc/host/wbsd.c +++ b/drivers/mmc/host/wbsd.c | |||
@@ -1457,17 +1457,7 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) | |||
1457 | int ret; | 1457 | int ret; |
1458 | 1458 | ||
1459 | /* | 1459 | /* |
1460 | * Allocate interrupt. | 1460 | * Set up tasklets. Must be done before requesting interrupt. |
1461 | */ | ||
1462 | |||
1463 | ret = request_irq(irq, wbsd_irq, IRQF_SHARED, DRIVER_NAME, host); | ||
1464 | if (ret) | ||
1465 | return ret; | ||
1466 | |||
1467 | host->irq = irq; | ||
1468 | |||
1469 | /* | ||
1470 | * Set up tasklets. | ||
1471 | */ | 1461 | */ |
1472 | tasklet_init(&host->card_tasklet, wbsd_tasklet_card, | 1462 | tasklet_init(&host->card_tasklet, wbsd_tasklet_card, |
1473 | (unsigned long)host); | 1463 | (unsigned long)host); |
@@ -1480,6 +1470,15 @@ static int __devinit wbsd_request_irq(struct wbsd_host *host, int irq) | |||
1480 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, | 1470 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, |
1481 | (unsigned long)host); | 1471 | (unsigned long)host); |
1482 | 1472 | ||
1473 | /* | ||
1474 | * Allocate interrupt. | ||
1475 | */ | ||
1476 | ret = request_irq(irq, wbsd_irq, IRQF_SHARED, DRIVER_NAME, host); | ||
1477 | if (ret) | ||
1478 | return ret; | ||
1479 | |||
1480 | host->irq = irq; | ||
1481 | |||
1483 | return 0; | 1482 | return 0; |
1484 | } | 1483 | } |
1485 | 1484 | ||
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 4b46e68183e0..367b6d462708 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -5724,14 +5724,12 @@ bnx2_reset_task(struct work_struct *work) | |||
5724 | if (!netif_running(bp->dev)) | 5724 | if (!netif_running(bp->dev)) |
5725 | return; | 5725 | return; |
5726 | 5726 | ||
5727 | bp->in_reset_task = 1; | ||
5728 | bnx2_netif_stop(bp); | 5727 | bnx2_netif_stop(bp); |
5729 | 5728 | ||
5730 | bnx2_init_nic(bp); | 5729 | bnx2_init_nic(bp); |
5731 | 5730 | ||
5732 | atomic_set(&bp->intr_sem, 1); | 5731 | atomic_set(&bp->intr_sem, 1); |
5733 | bnx2_netif_start(bp); | 5732 | bnx2_netif_start(bp); |
5734 | bp->in_reset_task = 0; | ||
5735 | } | 5733 | } |
5736 | 5734 | ||
5737 | static void | 5735 | static void |
@@ -5907,12 +5905,7 @@ bnx2_close(struct net_device *dev) | |||
5907 | struct bnx2 *bp = netdev_priv(dev); | 5905 | struct bnx2 *bp = netdev_priv(dev); |
5908 | u32 reset_code; | 5906 | u32 reset_code; |
5909 | 5907 | ||
5910 | /* Calling flush_scheduled_work() may deadlock because | 5908 | cancel_work_sync(&bp->reset_task); |
5911 | * linkwatch_event() may be on the workqueue and it will try to get | ||
5912 | * the rtnl_lock which we are holding. | ||
5913 | */ | ||
5914 | while (bp->in_reset_task) | ||
5915 | msleep(1); | ||
5916 | 5909 | ||
5917 | bnx2_disable_int_sync(bp); | 5910 | bnx2_disable_int_sync(bp); |
5918 | bnx2_napi_disable(bp); | 5911 | bnx2_napi_disable(bp); |
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 1eaf5bb3d9c2..2377cc13bf61 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h | |||
@@ -6656,7 +6656,6 @@ struct bnx2 { | |||
6656 | int current_interval; | 6656 | int current_interval; |
6657 | struct timer_list timer; | 6657 | struct timer_list timer; |
6658 | struct work_struct reset_task; | 6658 | struct work_struct reset_task; |
6659 | int in_reset_task; | ||
6660 | 6659 | ||
6661 | /* Used to synchronize phy accesses. */ | 6660 | /* Used to synchronize phy accesses. */ |
6662 | spinlock_t phy_lock; | 6661 | spinlock_t phy_lock; |
diff --git a/drivers/net/bnx2x.c b/drivers/net/bnx2x.c index 7bdb5af35951..70cba64732ca 100644 --- a/drivers/net/bnx2x.c +++ b/drivers/net/bnx2x.c | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | * Based on code from Michael Chan's bnx2 driver | 11 | * Based on code from Michael Chan's bnx2 driver |
11 | * UDP CSUM errata workaround by Arik Gendelman | 12 | * UDP CSUM errata workaround by Arik Gendelman |
12 | * Slowpath rework by Vladislav Zolotarov | 13 | * Slowpath rework by Vladislav Zolotarov |
@@ -74,7 +75,7 @@ static char version[] __devinitdata = | |||
74 | "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " | 75 | "Broadcom NetXtreme II 5771X 10Gigabit Ethernet Driver " |
75 | DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 76 | DRV_MODULE_NAME " " DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
76 | 77 | ||
77 | MODULE_AUTHOR("Eliezer Tamir <eliezert@broadcom.com>"); | 78 | MODULE_AUTHOR("Eliezer Tamir"); |
78 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); | 79 | MODULE_DESCRIPTION("Broadcom NetXtreme II BCM57710 Driver"); |
79 | MODULE_LICENSE("GPL"); | 80 | MODULE_LICENSE("GPL"); |
80 | MODULE_VERSION(DRV_MODULE_VERSION); | 81 | MODULE_VERSION(DRV_MODULE_VERSION); |
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 4f0c0d31e7c1..8e68d06510a6 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | * Based on code from Michael Chan's bnx2 driver | 11 | * Based on code from Michael Chan's bnx2 driver |
11 | */ | 12 | */ |
12 | 13 | ||
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index dcaecc53bdb1..370686eef97c 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h | |||
@@ -6,7 +6,8 @@ | |||
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation. | 7 | * the Free Software Foundation. |
8 | * | 8 | * |
9 | * Written by: Eliezer Tamir <eliezert@broadcom.com> | 9 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> |
10 | * Written by: Eliezer Tamir | ||
10 | */ | 11 | */ |
11 | 12 | ||
12 | #ifndef BNX2X_INIT_H | 13 | #ifndef BNX2X_INIT_H |
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index faae01dc1c4b..075fd547421e 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -2605,7 +2605,8 @@ static int ehea_stop(struct net_device *dev) | |||
2605 | if (netif_msg_ifdown(port)) | 2605 | if (netif_msg_ifdown(port)) |
2606 | ehea_info("disabling port %s", dev->name); | 2606 | ehea_info("disabling port %s", dev->name); |
2607 | 2607 | ||
2608 | flush_scheduled_work(); | 2608 | cancel_work_sync(&port->reset_task); |
2609 | |||
2609 | mutex_lock(&port->port_lock); | 2610 | mutex_lock(&port->port_lock); |
2610 | netif_stop_queue(dev); | 2611 | netif_stop_queue(dev); |
2611 | port_napi_disable(port); | 2612 | port_napi_disable(port); |
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c index 5f9c42e7a7f1..329edd9c08fc 100644 --- a/drivers/net/fec_mpc52xx.c +++ b/drivers/net/fec_mpc52xx.c | |||
@@ -78,7 +78,7 @@ module_param_array_named(mac, mpc52xx_fec_mac_addr, byte, NULL, 0); | |||
78 | MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe"); | 78 | MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe"); |
79 | 79 | ||
80 | #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \ | 80 | #define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \ |
81 | NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFDOWN ) | 81 | NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFUP) |
82 | static int debug = -1; /* the above default */ | 82 | static int debug = -1; /* the above default */ |
83 | module_param(debug, int, 0); | 83 | module_param(debug, int, 0); |
84 | MODULE_PARM_DESC(debug, "debugging messages level"); | 84 | MODULE_PARM_DESC(debug, "debugging messages level"); |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index dde9c7e6408a..00bc7fbb6b37 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -959,7 +959,7 @@ static int epp_close(struct net_device *dev) | |||
959 | unsigned char tmp[1]; | 959 | unsigned char tmp[1]; |
960 | 960 | ||
961 | bc->work_running = 0; | 961 | bc->work_running = 0; |
962 | flush_scheduled_work(); | 962 | cancel_delayed_work_sync(&bc->run_work); |
963 | bc->stat = EPP_DCDBIT; | 963 | bc->stat = EPP_DCDBIT; |
964 | tmp[0] = 0; | 964 | tmp[0] = 0; |
965 | pp->ops->epp_write_addr(pp, tmp, 1, 0); | 965 | pp->ops->epp_write_addr(pp, tmp, 1, 0); |
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c index 9b358f61ed7f..679a0826780e 100644 --- a/drivers/net/ipg.c +++ b/drivers/net/ipg.c | |||
@@ -577,12 +577,12 @@ static void ipg_nic_set_multicast_list(struct net_device *dev) | |||
577 | /* NIC to be configured in promiscuous mode. */ | 577 | /* NIC to be configured in promiscuous mode. */ |
578 | receivemode = IPG_RM_RECEIVEALLFRAMES; | 578 | receivemode = IPG_RM_RECEIVEALLFRAMES; |
579 | } else if ((dev->flags & IFF_ALLMULTI) || | 579 | } else if ((dev->flags & IFF_ALLMULTI) || |
580 | (dev->flags & IFF_MULTICAST & | 580 | ((dev->flags & IFF_MULTICAST) && |
581 | (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { | 581 | (dev->mc_count > IPG_MULTICAST_HASHTABLE_SIZE))) { |
582 | /* NIC to be configured to receive all multicast | 582 | /* NIC to be configured to receive all multicast |
583 | * frames. */ | 583 | * frames. */ |
584 | receivemode |= IPG_RM_RECEIVEMULTICAST; | 584 | receivemode |= IPG_RM_RECEIVEMULTICAST; |
585 | } else if (dev->flags & IFF_MULTICAST & (dev->mc_count > 0)) { | 585 | } else if ((dev->flags & IFF_MULTICAST) && (dev->mc_count > 0)) { |
586 | /* NIC to be configured to receive selected | 586 | /* NIC to be configured to receive selected |
587 | * multicast addresses. */ | 587 | * multicast addresses. */ |
588 | receivemode |= IPG_RM_RECEIVEMULTICASTHASH; | 588 | receivemode |= IPG_RM_RECEIVEMULTICASTHASH; |
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 169edc154928..858b191517b3 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -733,7 +733,7 @@ static void r6040_timer(unsigned long data) | |||
733 | } | 733 | } |
734 | 734 | ||
735 | /* Timer active again */ | 735 | /* Timer active again */ |
736 | mod_timer(&lp->timer, jiffies + round_jiffies(HZ)); | 736 | mod_timer(&lp->timer, round_jiffies(jiffies + HZ)); |
737 | } | 737 | } |
738 | 738 | ||
739 | /* Read/set MAC address routines */ | 739 | /* Read/set MAC address routines */ |
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 4e2800205189..e2ee91a6ae7e 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c | |||
@@ -136,7 +136,6 @@ struct smc911x_local { | |||
136 | 136 | ||
137 | /* work queue */ | 137 | /* work queue */ |
138 | struct work_struct phy_configure; | 138 | struct work_struct phy_configure; |
139 | int work_pending; | ||
140 | 139 | ||
141 | int tx_throttle; | 140 | int tx_throttle; |
142 | spinlock_t lock; | 141 | spinlock_t lock; |
@@ -960,11 +959,11 @@ static void smc911x_phy_configure(struct work_struct *work) | |||
960 | * We should not be called if phy_type is zero. | 959 | * We should not be called if phy_type is zero. |
961 | */ | 960 | */ |
962 | if (lp->phy_type == 0) | 961 | if (lp->phy_type == 0) |
963 | goto smc911x_phy_configure_exit_nolock; | 962 | return; |
964 | 963 | ||
965 | if (smc911x_phy_reset(dev, phyaddr)) { | 964 | if (smc911x_phy_reset(dev, phyaddr)) { |
966 | printk("%s: PHY reset timed out\n", dev->name); | 965 | printk("%s: PHY reset timed out\n", dev->name); |
967 | goto smc911x_phy_configure_exit_nolock; | 966 | return; |
968 | } | 967 | } |
969 | spin_lock_irqsave(&lp->lock, flags); | 968 | spin_lock_irqsave(&lp->lock, flags); |
970 | 969 | ||
@@ -1033,8 +1032,6 @@ static void smc911x_phy_configure(struct work_struct *work) | |||
1033 | 1032 | ||
1034 | smc911x_phy_configure_exit: | 1033 | smc911x_phy_configure_exit: |
1035 | spin_unlock_irqrestore(&lp->lock, flags); | 1034 | spin_unlock_irqrestore(&lp->lock, flags); |
1036 | smc911x_phy_configure_exit_nolock: | ||
1037 | lp->work_pending = 0; | ||
1038 | } | 1035 | } |
1039 | 1036 | ||
1040 | /* | 1037 | /* |
@@ -1356,11 +1353,8 @@ static void smc911x_timeout(struct net_device *dev) | |||
1356 | * smc911x_phy_configure() calls msleep() which calls schedule_timeout() | 1353 | * smc911x_phy_configure() calls msleep() which calls schedule_timeout() |
1357 | * which calls schedule(). Hence we use a work queue. | 1354 | * which calls schedule(). Hence we use a work queue. |
1358 | */ | 1355 | */ |
1359 | if (lp->phy_type != 0) { | 1356 | if (lp->phy_type != 0) |
1360 | if (schedule_work(&lp->phy_configure)) { | 1357 | schedule_work(&lp->phy_configure); |
1361 | lp->work_pending = 1; | ||
1362 | } | ||
1363 | } | ||
1364 | 1358 | ||
1365 | /* We can accept TX packets again */ | 1359 | /* We can accept TX packets again */ |
1366 | dev->trans_start = jiffies; | 1360 | dev->trans_start = jiffies; |
@@ -1531,16 +1525,8 @@ static int smc911x_close(struct net_device *dev) | |||
1531 | if (lp->phy_type != 0) { | 1525 | if (lp->phy_type != 0) { |
1532 | /* We need to ensure that no calls to | 1526 | /* We need to ensure that no calls to |
1533 | * smc911x_phy_configure are pending. | 1527 | * smc911x_phy_configure are pending. |
1534 | |||
1535 | * flush_scheduled_work() cannot be called because we | ||
1536 | * are running with the netlink semaphore held (from | ||
1537 | * devinet_ioctl()) and the pending work queue | ||
1538 | * contains linkwatch_event() (scheduled by | ||
1539 | * netif_carrier_off() above). linkwatch_event() also | ||
1540 | * wants the netlink semaphore. | ||
1541 | */ | 1528 | */ |
1542 | while (lp->work_pending) | 1529 | cancel_work_sync(&lp->phy_configure); |
1543 | schedule(); | ||
1544 | smc911x_phy_powerdown(dev, lp->mii.phy_id); | 1530 | smc911x_phy_powerdown(dev, lp->mii.phy_id); |
1545 | } | 1531 | } |
1546 | 1532 | ||
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index a188e33484e6..f2051b209da2 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -1016,15 +1016,8 @@ static void smc_phy_powerdown(struct net_device *dev) | |||
1016 | 1016 | ||
1017 | /* We need to ensure that no calls to smc_phy_configure are | 1017 | /* We need to ensure that no calls to smc_phy_configure are |
1018 | pending. | 1018 | pending. |
1019 | |||
1020 | flush_scheduled_work() cannot be called because we are | ||
1021 | running with the netlink semaphore held (from | ||
1022 | devinet_ioctl()) and the pending work queue contains | ||
1023 | linkwatch_event() (scheduled by netif_carrier_off() | ||
1024 | above). linkwatch_event() also wants the netlink semaphore. | ||
1025 | */ | 1019 | */ |
1026 | while(lp->work_pending) | 1020 | cancel_work_sync(&lp->phy_configure); |
1027 | yield(); | ||
1028 | 1021 | ||
1029 | bmcr = smc_phy_read(dev, phy, MII_BMCR); | 1022 | bmcr = smc_phy_read(dev, phy, MII_BMCR); |
1030 | smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); | 1023 | smc_phy_write(dev, phy, MII_BMCR, bmcr | BMCR_PDOWN); |
@@ -1161,7 +1154,6 @@ static void smc_phy_configure(struct work_struct *work) | |||
1161 | smc_phy_configure_exit: | 1154 | smc_phy_configure_exit: |
1162 | SMC_SELECT_BANK(lp, 2); | 1155 | SMC_SELECT_BANK(lp, 2); |
1163 | spin_unlock_irq(&lp->lock); | 1156 | spin_unlock_irq(&lp->lock); |
1164 | lp->work_pending = 0; | ||
1165 | } | 1157 | } |
1166 | 1158 | ||
1167 | /* | 1159 | /* |
@@ -1389,11 +1381,8 @@ static void smc_timeout(struct net_device *dev) | |||
1389 | * smc_phy_configure() calls msleep() which calls schedule_timeout() | 1381 | * smc_phy_configure() calls msleep() which calls schedule_timeout() |
1390 | * which calls schedule(). Hence we use a work queue. | 1382 | * which calls schedule(). Hence we use a work queue. |
1391 | */ | 1383 | */ |
1392 | if (lp->phy_type != 0) { | 1384 | if (lp->phy_type != 0) |
1393 | if (schedule_work(&lp->phy_configure)) { | 1385 | schedule_work(&lp->phy_configure); |
1394 | lp->work_pending = 1; | ||
1395 | } | ||
1396 | } | ||
1397 | 1386 | ||
1398 | /* We can accept TX packets again */ | 1387 | /* We can accept TX packets again */ |
1399 | dev->trans_start = jiffies; | 1388 | dev->trans_start = jiffies; |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 55670b5eb611..af8d2c436efd 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -731,7 +731,7 @@ static void tulip_down (struct net_device *dev) | |||
731 | void __iomem *ioaddr = tp->base_addr; | 731 | void __iomem *ioaddr = tp->base_addr; |
732 | unsigned long flags; | 732 | unsigned long flags; |
733 | 733 | ||
734 | flush_scheduled_work(); | 734 | cancel_work_sync(&tp->media_work); |
735 | 735 | ||
736 | #ifdef CONFIG_TULIP_NAPI | 736 | #ifdef CONFIG_TULIP_NAPI |
737 | napi_disable(&tp->napi); | 737 | napi_disable(&tp->napi); |
diff --git a/drivers/net/usb/kaweth.c b/drivers/net/usb/kaweth.c index 0dcfc0310264..7c66b052f55a 100644 --- a/drivers/net/usb/kaweth.c +++ b/drivers/net/usb/kaweth.c | |||
@@ -706,7 +706,7 @@ static void kaweth_kill_urbs(struct kaweth_device *kaweth) | |||
706 | usb_kill_urb(kaweth->rx_urb); | 706 | usb_kill_urb(kaweth->rx_urb); |
707 | usb_kill_urb(kaweth->tx_urb); | 707 | usb_kill_urb(kaweth->tx_urb); |
708 | 708 | ||
709 | flush_scheduled_work(); | 709 | cancel_delayed_work_sync(&kaweth->lowmem_work); |
710 | 710 | ||
711 | /* a scheduled work may have resubmitted, | 711 | /* a scheduled work may have resubmitted, |
712 | we hit them again */ | 712 | we hit them again */ |
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 20d387f6658c..f7aec9309d04 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c | |||
@@ -682,7 +682,13 @@ static int prism2_close(struct net_device *dev) | |||
682 | netif_device_detach(dev); | 682 | netif_device_detach(dev); |
683 | } | 683 | } |
684 | 684 | ||
685 | flush_scheduled_work(); | 685 | cancel_work_sync(&local->reset_queue); |
686 | cancel_work_sync(&local->set_multicast_list_queue); | ||
687 | cancel_work_sync(&local->set_tim_queue); | ||
688 | #ifndef PRISM2_NO_STATION_MODES | ||
689 | cancel_work_sync(&local->info_queue); | ||
690 | #endif | ||
691 | cancel_work_sync(&local->comms_qual_update); | ||
686 | 692 | ||
687 | module_put(local->hw_module); | 693 | module_put(local->hw_module); |
688 | 694 | ||
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 60f8afc7a56e..4949dc4859be 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -256,6 +256,17 @@ config RTC_DRV_S35390A | |||
256 | This driver can also be built as a module. If so the module | 256 | This driver can also be built as a module. If so the module |
257 | will be called rtc-s35390a. | 257 | will be called rtc-s35390a. |
258 | 258 | ||
259 | config RTC_DRV_FM3130 | ||
260 | tristate "Ramtron FM3130" | ||
261 | help | ||
262 | If you say Y here you will get support for the | ||
263 | Ramtron FM3130 RTC chips. | ||
264 | Ramtron FM3130 is a chip with two separate devices inside, | ||
265 | RTC clock and FRAM. This driver provides only RTC functionality. | ||
266 | |||
267 | This driver can also be built as a module. If so the module | ||
268 | will be called rtc-fm3130. | ||
269 | |||
259 | endif # I2C | 270 | endif # I2C |
260 | 271 | ||
261 | comment "SPI RTC drivers" | 272 | comment "SPI RTC drivers" |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index ebe871cf16c1..b6e14d51670b 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | |||
31 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 31 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
32 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | 32 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o |
33 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o | 33 | obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o |
34 | obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o | ||
34 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o | 35 | obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o |
35 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o | 36 | obj-$(CONFIG_RTC_DRV_M41T80) += rtc-m41t80.o |
36 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o | 37 | obj-$(CONFIG_RTC_DRV_M48T59) += rtc-m48t59.o |
@@ -41,6 +42,7 @@ obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | |||
41 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 42 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
42 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 43 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
43 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 44 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
45 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o | ||
44 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | 46 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o |
45 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 47 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
46 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 48 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
@@ -54,4 +56,3 @@ obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o | |||
54 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o | 56 | obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o |
55 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o | 57 | obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o |
56 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o | 58 | obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o |
57 | obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o | ||
diff --git a/drivers/rtc/rtc-at32ap700x.c b/drivers/rtc/rtc-at32ap700x.c index 42244f14b41c..2ef8cdfda4a7 100644 --- a/drivers/rtc/rtc-at32ap700x.c +++ b/drivers/rtc/rtc-at32ap700x.c | |||
@@ -94,8 +94,11 @@ static int at32_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
94 | { | 94 | { |
95 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); | 95 | struct rtc_at32ap700x *rtc = dev_get_drvdata(dev); |
96 | 96 | ||
97 | spin_lock_irq(&rtc->lock); | ||
97 | rtc_time_to_tm(rtc->alarm_time, &alrm->time); | 98 | rtc_time_to_tm(rtc->alarm_time, &alrm->time); |
98 | alrm->pending = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; | 99 | alrm->enabled = rtc_readl(rtc, IMR) & RTC_BIT(IMR_TOPI) ? 1 : 0; |
100 | alrm->pending = rtc_readl(rtc, ISR) & RTC_BIT(ISR_TOPI) ? 1 : 0; | ||
101 | spin_unlock_irq(&rtc->lock); | ||
99 | 102 | ||
100 | return 0; | 103 | return 0; |
101 | } | 104 | } |
@@ -119,7 +122,7 @@ static int at32_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | |||
119 | spin_lock_irq(&rtc->lock); | 122 | spin_lock_irq(&rtc->lock); |
120 | rtc->alarm_time = alarm_unix_time; | 123 | rtc->alarm_time = alarm_unix_time; |
121 | rtc_writel(rtc, TOP, rtc->alarm_time); | 124 | rtc_writel(rtc, TOP, rtc->alarm_time); |
122 | if (alrm->pending) | 125 | if (alrm->enabled) |
123 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) | 126 | rtc_writel(rtc, CTRL, rtc_readl(rtc, CTRL) |
124 | | RTC_BIT(CTRL_TOPEN)); | 127 | | RTC_BIT(CTRL_TOPEN)); |
125 | else | 128 | else |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index d060a06ce05b..d7bb9bac71df 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -905,19 +905,7 @@ static struct pnp_driver cmos_pnp_driver = { | |||
905 | .resume = cmos_pnp_resume, | 905 | .resume = cmos_pnp_resume, |
906 | }; | 906 | }; |
907 | 907 | ||
908 | static int __init cmos_init(void) | 908 | #endif /* CONFIG_PNP */ |
909 | { | ||
910 | return pnp_register_driver(&cmos_pnp_driver); | ||
911 | } | ||
912 | module_init(cmos_init); | ||
913 | |||
914 | static void __exit cmos_exit(void) | ||
915 | { | ||
916 | pnp_unregister_driver(&cmos_pnp_driver); | ||
917 | } | ||
918 | module_exit(cmos_exit); | ||
919 | |||
920 | #else /* no PNP */ | ||
921 | 909 | ||
922 | /*----------------------------------------------------------------*/ | 910 | /*----------------------------------------------------------------*/ |
923 | 911 | ||
@@ -958,20 +946,33 @@ static struct platform_driver cmos_platform_driver = { | |||
958 | 946 | ||
959 | static int __init cmos_init(void) | 947 | static int __init cmos_init(void) |
960 | { | 948 | { |
949 | #ifdef CONFIG_PNP | ||
950 | if (pnp_platform_devices) | ||
951 | return pnp_register_driver(&cmos_pnp_driver); | ||
952 | else | ||
953 | return platform_driver_probe(&cmos_platform_driver, | ||
954 | cmos_platform_probe); | ||
955 | #else | ||
961 | return platform_driver_probe(&cmos_platform_driver, | 956 | return platform_driver_probe(&cmos_platform_driver, |
962 | cmos_platform_probe); | 957 | cmos_platform_probe); |
958 | #endif /* CONFIG_PNP */ | ||
963 | } | 959 | } |
964 | module_init(cmos_init); | 960 | module_init(cmos_init); |
965 | 961 | ||
966 | static void __exit cmos_exit(void) | 962 | static void __exit cmos_exit(void) |
967 | { | 963 | { |
964 | #ifdef CONFIG_PNP | ||
965 | if (pnp_platform_devices) | ||
966 | pnp_unregister_driver(&cmos_pnp_driver); | ||
967 | else | ||
968 | platform_driver_unregister(&cmos_platform_driver); | ||
969 | #else | ||
968 | platform_driver_unregister(&cmos_platform_driver); | 970 | platform_driver_unregister(&cmos_platform_driver); |
971 | #endif /* CONFIG_PNP */ | ||
969 | } | 972 | } |
970 | module_exit(cmos_exit); | 973 | module_exit(cmos_exit); |
971 | 974 | ||
972 | 975 | ||
973 | #endif /* !PNP */ | ||
974 | |||
975 | MODULE_AUTHOR("David Brownell"); | 976 | MODULE_AUTHOR("David Brownell"); |
976 | MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); | 977 | MODULE_DESCRIPTION("Driver for PC-style 'CMOS' RTCs"); |
977 | MODULE_LICENSE("GPL"); | 978 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/rtc/rtc-fm3130.c b/drivers/rtc/rtc-fm3130.c new file mode 100644 index 000000000000..11644c8fca82 --- /dev/null +++ b/drivers/rtc/rtc-fm3130.c | |||
@@ -0,0 +1,501 @@ | |||
1 | /* | ||
2 | * rtc-fm3130.c - RTC driver for Ramtron FM3130 I2C chip. | ||
3 | * | ||
4 | * Copyright (C) 2008 Sergey Lapin | ||
5 | * Based on ds1307 driver by James Chapman and David Brownell | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/rtc.h> | ||
15 | #include <linux/bcd.h> | ||
16 | |||
17 | #define FM3130_RTC_CONTROL (0x0) | ||
18 | #define FM3130_CAL_CONTROL (0x1) | ||
19 | #define FM3130_RTC_SECONDS (0x2) | ||
20 | #define FM3130_RTC_MINUTES (0x3) | ||
21 | #define FM3130_RTC_HOURS (0x4) | ||
22 | #define FM3130_RTC_DAY (0x5) | ||
23 | #define FM3130_RTC_DATE (0x6) | ||
24 | #define FM3130_RTC_MONTHS (0x7) | ||
25 | #define FM3130_RTC_YEARS (0x8) | ||
26 | |||
27 | #define FM3130_ALARM_SECONDS (0x9) | ||
28 | #define FM3130_ALARM_MINUTES (0xa) | ||
29 | #define FM3130_ALARM_HOURS (0xb) | ||
30 | #define FM3130_ALARM_DATE (0xc) | ||
31 | #define FM3130_ALARM_MONTHS (0xd) | ||
32 | #define FM3130_ALARM_WP_CONTROL (0xe) | ||
33 | |||
34 | #define FM3130_CAL_CONTROL_BIT_nOSCEN (1 << 7) /* Osciallator enabled */ | ||
35 | #define FM3130_RTC_CONTROL_BIT_LB (1 << 7) /* Low battery */ | ||
36 | #define FM3130_RTC_CONTROL_BIT_AF (1 << 6) /* Alarm flag */ | ||
37 | #define FM3130_RTC_CONTROL_BIT_CF (1 << 5) /* Century overflow */ | ||
38 | #define FM3130_RTC_CONTROL_BIT_POR (1 << 4) /* Power on reset */ | ||
39 | #define FM3130_RTC_CONTROL_BIT_AEN (1 << 3) /* Alarm enable */ | ||
40 | #define FM3130_RTC_CONTROL_BIT_CAL (1 << 2) /* Calibration mode */ | ||
41 | #define FM3130_RTC_CONTROL_BIT_WRITE (1 << 1) /* W=1 -> write mode W=0 normal */ | ||
42 | #define FM3130_RTC_CONTROL_BIT_READ (1 << 0) /* R=1 -> read mode R=0 normal */ | ||
43 | |||
44 | #define FM3130_CLOCK_REGS 7 | ||
45 | #define FM3130_ALARM_REGS 5 | ||
46 | |||
47 | struct fm3130 { | ||
48 | u8 reg_addr_time; | ||
49 | u8 reg_addr_alarm; | ||
50 | u8 regs[15]; | ||
51 | struct i2c_msg msg[4]; | ||
52 | struct i2c_client *client; | ||
53 | struct rtc_device *rtc; | ||
54 | int data_valid; | ||
55 | int alarm; | ||
56 | }; | ||
57 | static const struct i2c_device_id fm3130_id[] = { | ||
58 | { "fm3130-rtc", 0 }, | ||
59 | { } | ||
60 | }; | ||
61 | MODULE_DEVICE_TABLE(i2c, fm3130_id); | ||
62 | |||
63 | #define FM3130_MODE_NORMAL 0 | ||
64 | #define FM3130_MODE_WRITE 1 | ||
65 | #define FM3130_MODE_READ 2 | ||
66 | |||
67 | static void fm3130_rtc_mode(struct device *dev, int mode) | ||
68 | { | ||
69 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
70 | |||
71 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
72 | i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL); | ||
73 | switch (mode) { | ||
74 | case FM3130_MODE_NORMAL: | ||
75 | fm3130->regs[FM3130_RTC_CONTROL] &= | ||
76 | ~(FM3130_RTC_CONTROL_BIT_WRITE | | ||
77 | FM3130_RTC_CONTROL_BIT_READ); | ||
78 | break; | ||
79 | case FM3130_MODE_WRITE: | ||
80 | fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_WRITE; | ||
81 | break; | ||
82 | case FM3130_MODE_READ: | ||
83 | fm3130->regs[FM3130_RTC_CONTROL] |= FM3130_RTC_CONTROL_BIT_READ; | ||
84 | break; | ||
85 | default: | ||
86 | dev_dbg(dev, "invalid mode %d\n", mode); | ||
87 | break; | ||
88 | } | ||
89 | /* Checking for alarm */ | ||
90 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
91 | fm3130->alarm = 1; | ||
92 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
93 | } | ||
94 | i2c_smbus_write_byte_data(fm3130->client, | ||
95 | FM3130_RTC_CONTROL, fm3130->regs[FM3130_RTC_CONTROL]); | ||
96 | } | ||
97 | |||
98 | static int fm3130_get_time(struct device *dev, struct rtc_time *t) | ||
99 | { | ||
100 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
101 | int tmp; | ||
102 | |||
103 | if (!fm3130->data_valid) { | ||
104 | /* We have invalid data in RTC, probably due | ||
105 | to battery faults or other problems. Return EIO | ||
106 | for now, it will allow us to set data later insted | ||
107 | of error during probing which disables device */ | ||
108 | return -EIO; | ||
109 | } | ||
110 | fm3130_rtc_mode(dev, FM3130_MODE_READ); | ||
111 | |||
112 | /* read the RTC date and time registers all at once */ | ||
113 | tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), | ||
114 | fm3130->msg, 2); | ||
115 | if (tmp != 2) { | ||
116 | dev_err(dev, "%s error %d\n", "read", tmp); | ||
117 | return -EIO; | ||
118 | } | ||
119 | |||
120 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | ||
121 | |||
122 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | ||
123 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
124 | "read", | ||
125 | fm3130->regs[0], fm3130->regs[1], | ||
126 | fm3130->regs[2], fm3130->regs[3], | ||
127 | fm3130->regs[4], fm3130->regs[5], | ||
128 | fm3130->regs[6], fm3130->regs[7], | ||
129 | fm3130->regs[8], fm3130->regs[9], | ||
130 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
131 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
132 | fm3130->regs[0xe]); | ||
133 | |||
134 | t->tm_sec = BCD2BIN(fm3130->regs[FM3130_RTC_SECONDS] & 0x7f); | ||
135 | t->tm_min = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | ||
136 | tmp = fm3130->regs[FM3130_RTC_HOURS] & 0x3f; | ||
137 | t->tm_hour = BCD2BIN(tmp); | ||
138 | t->tm_wday = BCD2BIN(fm3130->regs[FM3130_RTC_DAY] & 0x07) - 1; | ||
139 | t->tm_mday = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); | ||
140 | tmp = fm3130->regs[FM3130_RTC_MONTHS] & 0x1f; | ||
141 | t->tm_mon = BCD2BIN(tmp) - 1; | ||
142 | |||
143 | /* assume 20YY not 19YY, and ignore CF bit */ | ||
144 | t->tm_year = BCD2BIN(fm3130->regs[FM3130_RTC_YEARS]) + 100; | ||
145 | |||
146 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
147 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
148 | "read", t->tm_sec, t->tm_min, | ||
149 | t->tm_hour, t->tm_mday, | ||
150 | t->tm_mon, t->tm_year, t->tm_wday); | ||
151 | |||
152 | /* initial clock setting can be undefined */ | ||
153 | return rtc_valid_tm(t); | ||
154 | } | ||
155 | |||
156 | |||
157 | static int fm3130_set_time(struct device *dev, struct rtc_time *t) | ||
158 | { | ||
159 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
160 | int tmp, i; | ||
161 | u8 *buf = fm3130->regs; | ||
162 | |||
163 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
164 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
165 | "write", t->tm_sec, t->tm_min, | ||
166 | t->tm_hour, t->tm_mday, | ||
167 | t->tm_mon, t->tm_year, t->tm_wday); | ||
168 | |||
169 | /* first register addr */ | ||
170 | buf[FM3130_RTC_SECONDS] = BIN2BCD(t->tm_sec); | ||
171 | buf[FM3130_RTC_MINUTES] = BIN2BCD(t->tm_min); | ||
172 | buf[FM3130_RTC_HOURS] = BIN2BCD(t->tm_hour); | ||
173 | buf[FM3130_RTC_DAY] = BIN2BCD(t->tm_wday + 1); | ||
174 | buf[FM3130_RTC_DATE] = BIN2BCD(t->tm_mday); | ||
175 | buf[FM3130_RTC_MONTHS] = BIN2BCD(t->tm_mon + 1); | ||
176 | |||
177 | /* assume 20YY not 19YY */ | ||
178 | tmp = t->tm_year - 100; | ||
179 | buf[FM3130_RTC_YEARS] = BIN2BCD(tmp); | ||
180 | |||
181 | dev_dbg(dev, "%s: %02x %02x %02x %02x %02x %02x %02x" | ||
182 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", | ||
183 | "write", buf[0], buf[1], buf[2], buf[3], | ||
184 | buf[4], buf[5], buf[6], buf[7], | ||
185 | buf[8], buf[9], buf[0xa], buf[0xb], | ||
186 | buf[0xc], buf[0xd], buf[0xe]); | ||
187 | |||
188 | fm3130_rtc_mode(dev, FM3130_MODE_WRITE); | ||
189 | |||
190 | /* Writing time registers, we don't support multibyte transfers */ | ||
191 | for (i = 0; i < FM3130_CLOCK_REGS; i++) { | ||
192 | i2c_smbus_write_byte_data(fm3130->client, | ||
193 | FM3130_RTC_SECONDS + i, | ||
194 | fm3130->regs[FM3130_RTC_SECONDS + i]); | ||
195 | } | ||
196 | |||
197 | fm3130_rtc_mode(dev, FM3130_MODE_NORMAL); | ||
198 | |||
199 | /* We assume here that data are valid once written */ | ||
200 | if (!fm3130->data_valid) | ||
201 | fm3130->data_valid = 1; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int fm3130_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
206 | { | ||
207 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
208 | int tmp; | ||
209 | struct rtc_time *tm = &alrm->time; | ||
210 | /* read the RTC alarm registers all at once */ | ||
211 | tmp = i2c_transfer(to_i2c_adapter(fm3130->client->dev.parent), | ||
212 | &fm3130->msg[2], 2); | ||
213 | if (tmp != 2) { | ||
214 | dev_err(dev, "%s error %d\n", "read", tmp); | ||
215 | return -EIO; | ||
216 | } | ||
217 | dev_dbg(dev, "alarm read %02x %02x %02x %02x %02x\n", | ||
218 | fm3130->regs[FM3130_ALARM_SECONDS], | ||
219 | fm3130->regs[FM3130_ALARM_MINUTES], | ||
220 | fm3130->regs[FM3130_ALARM_HOURS], | ||
221 | fm3130->regs[FM3130_ALARM_DATE], | ||
222 | fm3130->regs[FM3130_ALARM_MONTHS]); | ||
223 | |||
224 | |||
225 | tm->tm_sec = BCD2BIN(fm3130->regs[FM3130_ALARM_SECONDS] & 0x7F); | ||
226 | tm->tm_min = BCD2BIN(fm3130->regs[FM3130_ALARM_MINUTES] & 0x7F); | ||
227 | tm->tm_hour = BCD2BIN(fm3130->regs[FM3130_ALARM_HOURS] & 0x3F); | ||
228 | tm->tm_mday = BCD2BIN(fm3130->regs[FM3130_ALARM_DATE] & 0x3F); | ||
229 | tm->tm_mon = BCD2BIN(fm3130->regs[FM3130_ALARM_MONTHS] & 0x1F); | ||
230 | if (tm->tm_mon > 0) | ||
231 | tm->tm_mon -= 1; /* RTC is 1-12, tm_mon is 0-11 */ | ||
232 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
233 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
234 | "read alarm", tm->tm_sec, tm->tm_min, | ||
235 | tm->tm_hour, tm->tm_mday, | ||
236 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | static int fm3130_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
242 | { | ||
243 | struct fm3130 *fm3130 = dev_get_drvdata(dev); | ||
244 | struct rtc_time *tm = &alrm->time; | ||
245 | int i; | ||
246 | |||
247 | dev_dbg(dev, "%s secs=%d, mins=%d, " | ||
248 | "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n", | ||
249 | "write alarm", tm->tm_sec, tm->tm_min, | ||
250 | tm->tm_hour, tm->tm_mday, | ||
251 | tm->tm_mon, tm->tm_year, tm->tm_wday); | ||
252 | |||
253 | if (tm->tm_sec != -1) | ||
254 | fm3130->regs[FM3130_ALARM_SECONDS] = | ||
255 | BIN2BCD(tm->tm_sec) | 0x80; | ||
256 | |||
257 | if (tm->tm_min != -1) | ||
258 | fm3130->regs[FM3130_ALARM_MINUTES] = | ||
259 | BIN2BCD(tm->tm_min) | 0x80; | ||
260 | |||
261 | if (tm->tm_hour != -1) | ||
262 | fm3130->regs[FM3130_ALARM_HOURS] = | ||
263 | BIN2BCD(tm->tm_hour) | 0x80; | ||
264 | |||
265 | if (tm->tm_mday != -1) | ||
266 | fm3130->regs[FM3130_ALARM_DATE] = | ||
267 | BIN2BCD(tm->tm_mday) | 0x80; | ||
268 | |||
269 | if (tm->tm_mon != -1) | ||
270 | fm3130->regs[FM3130_ALARM_MONTHS] = | ||
271 | BIN2BCD(tm->tm_mon + 1) | 0x80; | ||
272 | |||
273 | dev_dbg(dev, "alarm write %02x %02x %02x %02x %02x\n", | ||
274 | fm3130->regs[FM3130_ALARM_SECONDS], | ||
275 | fm3130->regs[FM3130_ALARM_MINUTES], | ||
276 | fm3130->regs[FM3130_ALARM_HOURS], | ||
277 | fm3130->regs[FM3130_ALARM_DATE], | ||
278 | fm3130->regs[FM3130_ALARM_MONTHS]); | ||
279 | /* Writing time registers, we don't support multibyte transfers */ | ||
280 | for (i = 0; i < FM3130_ALARM_REGS; i++) { | ||
281 | i2c_smbus_write_byte_data(fm3130->client, | ||
282 | FM3130_ALARM_SECONDS + i, | ||
283 | fm3130->regs[FM3130_ALARM_SECONDS + i]); | ||
284 | } | ||
285 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
286 | i2c_smbus_read_byte_data(fm3130->client, FM3130_RTC_CONTROL); | ||
287 | /* Checking for alarm */ | ||
288 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
289 | fm3130->alarm = 1; | ||
290 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
291 | } | ||
292 | if (alrm->enabled) { | ||
293 | i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL, | ||
294 | (fm3130->regs[FM3130_RTC_CONTROL] & | ||
295 | ~(FM3130_RTC_CONTROL_BIT_CAL)) | | ||
296 | FM3130_RTC_CONTROL_BIT_AEN); | ||
297 | } else { | ||
298 | i2c_smbus_write_byte_data(fm3130->client, FM3130_RTC_CONTROL, | ||
299 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
300 | ~(FM3130_RTC_CONTROL_BIT_AEN)); | ||
301 | } | ||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static const struct rtc_class_ops fm3130_rtc_ops = { | ||
306 | .read_time = fm3130_get_time, | ||
307 | .set_time = fm3130_set_time, | ||
308 | .read_alarm = fm3130_read_alarm, | ||
309 | .set_alarm = fm3130_set_alarm, | ||
310 | }; | ||
311 | |||
312 | static struct i2c_driver fm3130_driver; | ||
313 | |||
314 | static int __devinit fm3130_probe(struct i2c_client *client, | ||
315 | const struct i2c_device_id *id) | ||
316 | { | ||
317 | struct fm3130 *fm3130; | ||
318 | int err = -ENODEV; | ||
319 | int tmp; | ||
320 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | ||
321 | |||
322 | if (!i2c_check_functionality(adapter, | ||
323 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) | ||
324 | return -EIO; | ||
325 | |||
326 | fm3130 = kzalloc(sizeof(struct fm3130), GFP_KERNEL); | ||
327 | |||
328 | if (!fm3130) | ||
329 | return -ENOMEM; | ||
330 | |||
331 | fm3130->client = client; | ||
332 | i2c_set_clientdata(client, fm3130); | ||
333 | fm3130->reg_addr_time = FM3130_RTC_SECONDS; | ||
334 | fm3130->reg_addr_alarm = FM3130_ALARM_SECONDS; | ||
335 | |||
336 | /* Messages to read time */ | ||
337 | fm3130->msg[0].addr = client->addr; | ||
338 | fm3130->msg[0].flags = 0; | ||
339 | fm3130->msg[0].len = 1; | ||
340 | fm3130->msg[0].buf = &fm3130->reg_addr_time; | ||
341 | |||
342 | fm3130->msg[1].addr = client->addr; | ||
343 | fm3130->msg[1].flags = I2C_M_RD; | ||
344 | fm3130->msg[1].len = FM3130_CLOCK_REGS; | ||
345 | fm3130->msg[1].buf = &fm3130->regs[FM3130_RTC_SECONDS]; | ||
346 | |||
347 | /* Messages to read alarm */ | ||
348 | fm3130->msg[2].addr = client->addr; | ||
349 | fm3130->msg[2].flags = 0; | ||
350 | fm3130->msg[2].len = 1; | ||
351 | fm3130->msg[2].buf = &fm3130->reg_addr_alarm; | ||
352 | |||
353 | fm3130->msg[3].addr = client->addr; | ||
354 | fm3130->msg[3].flags = I2C_M_RD; | ||
355 | fm3130->msg[3].len = FM3130_ALARM_REGS; | ||
356 | fm3130->msg[3].buf = &fm3130->regs[FM3130_ALARM_SECONDS]; | ||
357 | |||
358 | fm3130->data_valid = 0; | ||
359 | |||
360 | tmp = i2c_transfer(adapter, fm3130->msg, 4); | ||
361 | if (tmp != 4) { | ||
362 | pr_debug("read error %d\n", tmp); | ||
363 | err = -EIO; | ||
364 | goto exit_free; | ||
365 | } | ||
366 | |||
367 | fm3130->regs[FM3130_RTC_CONTROL] = | ||
368 | i2c_smbus_read_byte_data(client, FM3130_RTC_CONTROL); | ||
369 | fm3130->regs[FM3130_CAL_CONTROL] = | ||
370 | i2c_smbus_read_byte_data(client, FM3130_CAL_CONTROL); | ||
371 | |||
372 | /* Checking for alarm */ | ||
373 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_AF) { | ||
374 | fm3130->alarm = 1; | ||
375 | fm3130->regs[FM3130_RTC_CONTROL] &= ~FM3130_RTC_CONTROL_BIT_AF; | ||
376 | } | ||
377 | |||
378 | /* Disabling calibration mode */ | ||
379 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_CAL) | ||
380 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
381 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
382 | ~(FM3130_RTC_CONTROL_BIT_CAL)); | ||
383 | dev_warn(&client->dev, "Disabling calibration mode!\n"); | ||
384 | |||
385 | /* Disabling read and write modes */ | ||
386 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_WRITE || | ||
387 | fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_READ) | ||
388 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
389 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
390 | ~(FM3130_RTC_CONTROL_BIT_READ | | ||
391 | FM3130_RTC_CONTROL_BIT_WRITE)); | ||
392 | dev_warn(&client->dev, "Disabling READ or WRITE mode!\n"); | ||
393 | |||
394 | /* oscillator off? turn it on, so clock can tick. */ | ||
395 | if (fm3130->regs[FM3130_CAL_CONTROL] & FM3130_CAL_CONTROL_BIT_nOSCEN) | ||
396 | i2c_smbus_write_byte_data(client, FM3130_CAL_CONTROL, | ||
397 | fm3130->regs[FM3130_CAL_CONTROL] & | ||
398 | ~(FM3130_CAL_CONTROL_BIT_nOSCEN)); | ||
399 | |||
400 | /* oscillator fault? clear flag, and warn */ | ||
401 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_LB) | ||
402 | dev_warn(&client->dev, "Low battery!\n"); | ||
403 | |||
404 | /* oscillator fault? clear flag, and warn */ | ||
405 | if (fm3130->regs[FM3130_RTC_CONTROL] & FM3130_RTC_CONTROL_BIT_POR) { | ||
406 | i2c_smbus_write_byte_data(client, FM3130_RTC_CONTROL, | ||
407 | fm3130->regs[FM3130_RTC_CONTROL] & | ||
408 | ~FM3130_RTC_CONTROL_BIT_POR); | ||
409 | dev_warn(&client->dev, "SET TIME!\n"); | ||
410 | } | ||
411 | /* ACS is controlled by alarm */ | ||
412 | i2c_smbus_write_byte_data(client, FM3130_ALARM_WP_CONTROL, 0x80); | ||
413 | |||
414 | /* TODO */ | ||
415 | /* TODO need to sanity check alarm */ | ||
416 | tmp = fm3130->regs[FM3130_RTC_SECONDS]; | ||
417 | tmp = BCD2BIN(tmp & 0x7f); | ||
418 | if (tmp > 60) | ||
419 | goto exit_bad; | ||
420 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MINUTES] & 0x7f); | ||
421 | if (tmp > 60) | ||
422 | goto exit_bad; | ||
423 | |||
424 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_DATE] & 0x3f); | ||
425 | if (tmp == 0 || tmp > 31) | ||
426 | goto exit_bad; | ||
427 | |||
428 | tmp = BCD2BIN(fm3130->regs[FM3130_RTC_MONTHS] & 0x1f); | ||
429 | if (tmp == 0 || tmp > 12) | ||
430 | goto exit_bad; | ||
431 | |||
432 | tmp = fm3130->regs[FM3130_RTC_HOURS]; | ||
433 | |||
434 | fm3130->data_valid = 1; | ||
435 | |||
436 | exit_bad: | ||
437 | if (!fm3130->data_valid) | ||
438 | dev_dbg(&client->dev, | ||
439 | "%s: %02x %02x %02x %02x %02x %02x %02x %02x" | ||
440 | "%02x %02x %02x %02x %02x %02x %02x\n", | ||
441 | "bogus registers", | ||
442 | fm3130->regs[0], fm3130->regs[1], | ||
443 | fm3130->regs[2], fm3130->regs[3], | ||
444 | fm3130->regs[4], fm3130->regs[5], | ||
445 | fm3130->regs[6], fm3130->regs[7], | ||
446 | fm3130->regs[8], fm3130->regs[9], | ||
447 | fm3130->regs[0xa], fm3130->regs[0xb], | ||
448 | fm3130->regs[0xc], fm3130->regs[0xd], | ||
449 | fm3130->regs[0xe]); | ||
450 | |||
451 | /* We won't bail out here because we just got invalid data. | ||
452 | Time setting from u-boot doesn't work anyway */ | ||
453 | fm3130->rtc = rtc_device_register(client->name, &client->dev, | ||
454 | &fm3130_rtc_ops, THIS_MODULE); | ||
455 | if (IS_ERR(fm3130->rtc)) { | ||
456 | err = PTR_ERR(fm3130->rtc); | ||
457 | dev_err(&client->dev, | ||
458 | "unable to register the class device\n"); | ||
459 | goto exit_free; | ||
460 | } | ||
461 | return 0; | ||
462 | exit_free: | ||
463 | kfree(fm3130); | ||
464 | return err; | ||
465 | } | ||
466 | |||
467 | static int __devexit fm3130_remove(struct i2c_client *client) | ||
468 | { | ||
469 | struct fm3130 *fm3130 = i2c_get_clientdata(client); | ||
470 | |||
471 | rtc_device_unregister(fm3130->rtc); | ||
472 | kfree(fm3130); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static struct i2c_driver fm3130_driver = { | ||
477 | .driver = { | ||
478 | .name = "rtc-fm3130", | ||
479 | .owner = THIS_MODULE, | ||
480 | }, | ||
481 | .probe = fm3130_probe, | ||
482 | .remove = __devexit_p(fm3130_remove), | ||
483 | .id_table = fm3130_id, | ||
484 | }; | ||
485 | |||
486 | static int __init fm3130_init(void) | ||
487 | { | ||
488 | return i2c_add_driver(&fm3130_driver); | ||
489 | } | ||
490 | module_init(fm3130_init); | ||
491 | |||
492 | static void __exit fm3130_exit(void) | ||
493 | { | ||
494 | i2c_del_driver(&fm3130_driver); | ||
495 | } | ||
496 | module_exit(fm3130_exit); | ||
497 | |||
498 | MODULE_DESCRIPTION("RTC driver for FM3130"); | ||
499 | MODULE_AUTHOR("Sergey Lapin <slapin@ossfans.org>"); | ||
500 | MODULE_LICENSE("GPL"); | ||
501 | |||
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c index 35ac9d956b3d..c14b2435d23e 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/cirrusfb.c | |||
@@ -2432,9 +2432,9 @@ static int cirrusfb_pci_register(struct pci_dev *pdev, | |||
2432 | info->screen_size = board_size; | 2432 | info->screen_size = board_size; |
2433 | cinfo->unmap = cirrusfb_pci_unmap; | 2433 | cinfo->unmap = cirrusfb_pci_unmap; |
2434 | 2434 | ||
2435 | printk(KERN_INFO " RAM (%lu kB) at 0xx%lx, ", | 2435 | printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus " |
2436 | info->screen_size >> 10, board_addr); | 2436 | "Logic chipset on PCI bus\n", |
2437 | printk(KERN_INFO "Cirrus Logic chipset on PCI bus\n"); | 2437 | info->screen_size >> 10, board_addr); |
2438 | pci_set_drvdata(pdev, info); | 2438 | pci_set_drvdata(pdev, info); |
2439 | 2439 | ||
2440 | ret = cirrusfb_register(info); | 2440 | ret = cirrusfb_register(info); |
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c index fb9e67228543..c18880d9db1f 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/hgafb.c | |||
@@ -279,7 +279,7 @@ static void hga_blank(int blank_mode) | |||
279 | 279 | ||
280 | static int __init hga_card_detect(void) | 280 | static int __init hga_card_detect(void) |
281 | { | 281 | { |
282 | int count=0; | 282 | int count = 0; |
283 | void __iomem *p, *q; | 283 | void __iomem *p, *q; |
284 | unsigned short p_save, q_save; | 284 | unsigned short p_save, q_save; |
285 | 285 | ||
@@ -303,20 +303,18 @@ static int __init hga_card_detect(void) | |||
303 | writew(0x55aa, p); if (readw(p) == 0x55aa) count++; | 303 | writew(0x55aa, p); if (readw(p) == 0x55aa) count++; |
304 | writew(p_save, p); | 304 | writew(p_save, p); |
305 | 305 | ||
306 | if (count != 2) { | 306 | if (count != 2) |
307 | return 0; | 307 | goto error; |
308 | } | ||
309 | 308 | ||
310 | /* Ok, there is definitely a card registering at the correct | 309 | /* Ok, there is definitely a card registering at the correct |
311 | * memory location, so now we do an I/O port test. | 310 | * memory location, so now we do an I/O port test. |
312 | */ | 311 | */ |
313 | 312 | ||
314 | if (!test_hga_b(0x66, 0x0f)) { /* cursor low register */ | 313 | if (!test_hga_b(0x66, 0x0f)) /* cursor low register */ |
315 | return 0; | 314 | goto error; |
316 | } | 315 | |
317 | if (!test_hga_b(0x99, 0x0f)) { /* cursor low register */ | 316 | if (!test_hga_b(0x99, 0x0f)) /* cursor low register */ |
318 | return 0; | 317 | goto error; |
319 | } | ||
320 | 318 | ||
321 | /* See if the card is a Hercules, by checking whether the vsync | 319 | /* See if the card is a Hercules, by checking whether the vsync |
322 | * bit of the status register is changing. This test lasts for | 320 | * bit of the status register is changing. This test lasts for |
@@ -331,7 +329,7 @@ static int __init hga_card_detect(void) | |||
331 | } | 329 | } |
332 | 330 | ||
333 | if (p_save == q_save) | 331 | if (p_save == q_save) |
334 | return 0; | 332 | goto error; |
335 | 333 | ||
336 | switch (inb_p(HGA_STATUS_PORT) & 0x70) { | 334 | switch (inb_p(HGA_STATUS_PORT) & 0x70) { |
337 | case 0x10: | 335 | case 0x10: |
@@ -348,6 +346,12 @@ static int __init hga_card_detect(void) | |||
348 | break; | 346 | break; |
349 | } | 347 | } |
350 | return 1; | 348 | return 1; |
349 | error: | ||
350 | if (release_io_ports) | ||
351 | release_region(0x3b0, 12); | ||
352 | if (release_io_port) | ||
353 | release_region(0x3bf, 1); | ||
354 | return 0; | ||
351 | } | 355 | } |
352 | 356 | ||
353 | /** | 357 | /** |
diff --git a/drivers/video/leo.c b/drivers/video/leo.c index 8bc46e930340..13fea61d6ae4 100644 --- a/drivers/video/leo.c +++ b/drivers/video/leo.c | |||
@@ -17,8 +17,8 @@ | |||
17 | #include <linux/fb.h> | 17 | #include <linux/fb.h> |
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <linux/of_device.h> | 19 | #include <linux/of_device.h> |
20 | #include <linux/io.h> | ||
20 | 21 | ||
21 | #include <asm/io.h> | ||
22 | #include <asm/fbio.h> | 22 | #include <asm/fbio.h> |
23 | 23 | ||
24 | #include "sbuslib.h" | 24 | #include "sbuslib.h" |
@@ -33,7 +33,6 @@ static int leo_blank(int, struct fb_info *); | |||
33 | 33 | ||
34 | static int leo_mmap(struct fb_info *, struct vm_area_struct *); | 34 | static int leo_mmap(struct fb_info *, struct vm_area_struct *); |
35 | static int leo_ioctl(struct fb_info *, unsigned int, unsigned long); | 35 | static int leo_ioctl(struct fb_info *, unsigned int, unsigned long); |
36 | static int leo_pan_display(struct fb_var_screeninfo *, struct fb_info *); | ||
37 | 36 | ||
38 | /* | 37 | /* |
39 | * Frame buffer operations | 38 | * Frame buffer operations |
@@ -43,7 +42,6 @@ static struct fb_ops leo_ops = { | |||
43 | .owner = THIS_MODULE, | 42 | .owner = THIS_MODULE, |
44 | .fb_setcolreg = leo_setcolreg, | 43 | .fb_setcolreg = leo_setcolreg, |
45 | .fb_blank = leo_blank, | 44 | .fb_blank = leo_blank, |
46 | .fb_pan_display = leo_pan_display, | ||
47 | .fb_fillrect = cfb_fillrect, | 45 | .fb_fillrect = cfb_fillrect, |
48 | .fb_copyarea = cfb_copyarea, | 46 | .fb_copyarea = cfb_copyarea, |
49 | .fb_imageblit = cfb_imageblit, | 47 | .fb_imageblit = cfb_imageblit, |
@@ -78,7 +76,7 @@ static struct fb_ops leo_ops = { | |||
78 | #define LEO_CUR_TYPE_CMAP 0x00000050 | 76 | #define LEO_CUR_TYPE_CMAP 0x00000050 |
79 | 77 | ||
80 | struct leo_cursor { | 78 | struct leo_cursor { |
81 | u8 xxx0[16]; | 79 | u8 xxx0[16]; |
82 | u32 cur_type; | 80 | u32 cur_type; |
83 | u32 cur_misc; | 81 | u32 cur_misc; |
84 | u32 cur_cursxy; | 82 | u32 cur_cursxy; |
@@ -105,7 +103,7 @@ struct leo_lx_krn { | |||
105 | 103 | ||
106 | struct leo_lc_ss0_krn { | 104 | struct leo_lc_ss0_krn { |
107 | u32 misc; | 105 | u32 misc; |
108 | u8 xxx0[0x800-4]; | 106 | u8 xxx0[0x800-4]; |
109 | u32 rev; | 107 | u32 rev; |
110 | }; | 108 | }; |
111 | 109 | ||
@@ -116,7 +114,7 @@ struct leo_lc_ss0_usr { | |||
116 | u32 fontt; | 114 | u32 fontt; |
117 | u32 extent; | 115 | u32 extent; |
118 | u32 src; | 116 | u32 src; |
119 | u32 dst; | 117 | u32 dst; |
120 | u32 copy; | 118 | u32 copy; |
121 | u32 fill; | 119 | u32 fill; |
122 | }; | 120 | }; |
@@ -129,8 +127,8 @@ struct leo_lc_ss1_usr { | |||
129 | u8 unknown; | 127 | u8 unknown; |
130 | }; | 128 | }; |
131 | 129 | ||
132 | struct leo_ld { | 130 | struct leo_ld_ss0 { |
133 | u8 xxx0[0xe00]; | 131 | u8 xxx0[0xe00]; |
134 | u32 csr; | 132 | u32 csr; |
135 | u32 wid; | 133 | u32 wid; |
136 | u32 wmask; | 134 | u32 wmask; |
@@ -144,13 +142,13 @@ struct leo_ld { | |||
144 | u32 src; /* Copy/Scroll (SS0 only) */ | 142 | u32 src; /* Copy/Scroll (SS0 only) */ |
145 | u32 dst; /* Copy/Scroll/Fill (SS0 only) */ | 143 | u32 dst; /* Copy/Scroll/Fill (SS0 only) */ |
146 | u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ | 144 | u32 extent; /* Copy/Scroll/Fill size (SS0 only) */ |
147 | u32 xxx1[3]; | 145 | u32 xxx1[3]; |
148 | u32 setsem; /* SS1 only */ | 146 | u32 setsem; /* SS1 only */ |
149 | u32 clrsem; /* SS1 only */ | 147 | u32 clrsem; /* SS1 only */ |
150 | u32 clrpick; /* SS1 only */ | 148 | u32 clrpick; /* SS1 only */ |
151 | u32 clrdat; /* SS1 only */ | 149 | u32 clrdat; /* SS1 only */ |
152 | u32 alpha; /* SS1 only */ | 150 | u32 alpha; /* SS1 only */ |
153 | u8 xxx2[0x2c]; | 151 | u8 xxx2[0x2c]; |
154 | u32 winbg; | 152 | u32 winbg; |
155 | u32 planemask; | 153 | u32 planemask; |
156 | u32 rop; | 154 | u32 rop; |
@@ -199,11 +197,12 @@ struct leo_par { | |||
199 | static void leo_wait(struct leo_lx_krn __iomem *lx_krn) | 197 | static void leo_wait(struct leo_lx_krn __iomem *lx_krn) |
200 | { | 198 | { |
201 | int i; | 199 | int i; |
202 | 200 | ||
203 | for (i = 0; | 201 | for (i = 0; |
204 | (sbus_readl(&lx_krn->krn_csr) & LEO_KRN_CSR_PROGRESS) && i < 300000; | 202 | (sbus_readl(&lx_krn->krn_csr) & LEO_KRN_CSR_PROGRESS) && |
203 | i < 300000; | ||
205 | i++) | 204 | i++) |
206 | udelay (1); /* Busy wait at most 0.3 sec */ | 205 | udelay(1); /* Busy wait at most 0.3 sec */ |
207 | return; | 206 | return; |
208 | } | 207 | } |
209 | 208 | ||
@@ -221,7 +220,7 @@ static int leo_setcolreg(unsigned regno, | |||
221 | unsigned transp, struct fb_info *info) | 220 | unsigned transp, struct fb_info *info) |
222 | { | 221 | { |
223 | struct leo_par *par = (struct leo_par *) info->par; | 222 | struct leo_par *par = (struct leo_par *) info->par; |
224 | struct leo_lx_krn __iomem *lx_krn = par->lx_krn; | 223 | struct leo_lx_krn __iomem *lx_krn = par->lx_krn; |
225 | unsigned long flags; | 224 | unsigned long flags; |
226 | u32 val; | 225 | u32 val; |
227 | int i; | 226 | int i; |
@@ -408,7 +407,7 @@ static void leo_wid_put(struct fb_info *info, struct fb_wid_list *wl) | |||
408 | leo_wait(lx_krn); | 407 | leo_wait(lx_krn); |
409 | 408 | ||
410 | for (i = 0, wi = wl->wl_list; i < wl->wl_count; i++, wi++) { | 409 | for (i = 0, wi = wl->wl_list; i < wl->wl_count; i++, wi++) { |
411 | switch(wi->wi_type) { | 410 | switch (wi->wi_type) { |
412 | case FB_WID_DBL_8: | 411 | case FB_WID_DBL_8: |
413 | j = (wi->wi_index & 0xf) + 0x40; | 412 | j = (wi->wi_index & 0xf) + 0x40; |
414 | break; | 413 | break; |
@@ -453,13 +452,12 @@ static void leo_init_wids(struct fb_info *info) | |||
453 | wi.wi_index = 1; | 452 | wi.wi_index = 1; |
454 | wi.wi_values [0] = 0x30; | 453 | wi.wi_values [0] = 0x30; |
455 | leo_wid_put(info, &wl); | 454 | leo_wid_put(info, &wl); |
456 | |||
457 | } | 455 | } |
458 | 456 | ||
459 | static void leo_switch_from_graph(struct fb_info *info) | 457 | static void leo_switch_from_graph(struct fb_info *info) |
460 | { | 458 | { |
461 | struct leo_par *par = (struct leo_par *) info->par; | 459 | struct leo_par *par = (struct leo_par *) info->par; |
462 | struct leo_ld __iomem *ss = (struct leo_ld __iomem *) par->ld_ss0; | 460 | struct leo_ld_ss0 __iomem *ss = par->ld_ss0; |
463 | unsigned long flags; | 461 | unsigned long flags; |
464 | u32 val; | 462 | u32 val; |
465 | 463 | ||
@@ -485,19 +483,13 @@ static void leo_switch_from_graph(struct fb_info *info) | |||
485 | val = sbus_readl(&par->lc_ss0_usr->csr); | 483 | val = sbus_readl(&par->lc_ss0_usr->csr); |
486 | } while (val & 0x20000000); | 484 | } while (val & 0x20000000); |
487 | 485 | ||
488 | spin_unlock_irqrestore(&par->lock, flags); | 486 | /* setup screen buffer for cfb_* functions */ |
489 | } | 487 | sbus_writel(1, &ss->wid); |
490 | 488 | sbus_writel(0x00ffffff, &ss->planemask); | |
491 | static int leo_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) | 489 | sbus_writel(0x310b90, &ss->rop); |
492 | { | 490 | sbus_writel(0, &par->lc_ss0_usr->addrspace); |
493 | /* We just use this to catch switches out of | ||
494 | * graphics mode. | ||
495 | */ | ||
496 | leo_switch_from_graph(info); | ||
497 | 491 | ||
498 | if (var->xoffset || var->yoffset || var->vmode) | 492 | spin_unlock_irqrestore(&par->lock, flags); |
499 | return -EINVAL; | ||
500 | return 0; | ||
501 | } | 493 | } |
502 | 494 | ||
503 | static void leo_init_hw(struct fb_info *info) | 495 | static void leo_init_hw(struct fb_info *info) |
@@ -542,7 +534,8 @@ static void leo_unmap_regs(struct of_device *op, struct fb_info *info, | |||
542 | of_iounmap(&op->resource[0], info->screen_base, 0x800000); | 534 | of_iounmap(&op->resource[0], info->screen_base, 0x800000); |
543 | } | 535 | } |
544 | 536 | ||
545 | static int __devinit leo_probe(struct of_device *op, const struct of_device_id *match) | 537 | static int __devinit leo_probe(struct of_device *op, |
538 | const struct of_device_id *match) | ||
546 | { | 539 | { |
547 | struct device_node *dp = op->node; | 540 | struct device_node *dp = op->node; |
548 | struct fb_info *info; | 541 | struct fb_info *info; |
@@ -594,8 +587,9 @@ static int __devinit leo_probe(struct of_device *op, const struct of_device_id * | |||
594 | !info->screen_base) | 587 | !info->screen_base) |
595 | goto out_unmap_regs; | 588 | goto out_unmap_regs; |
596 | 589 | ||
597 | info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; | 590 | info->flags = FBINFO_DEFAULT; |
598 | info->fbops = &leo_ops; | 591 | info->fbops = &leo_ops; |
592 | info->pseudo_palette = par->clut_data; | ||
599 | 593 | ||
600 | leo_init_wids(info); | 594 | leo_init_wids(info); |
601 | leo_init_hw(info); | 595 | leo_init_hw(info); |
@@ -649,7 +643,7 @@ static int __devexit leo_remove(struct of_device *op) | |||
649 | 643 | ||
650 | static struct of_device_id leo_match[] = { | 644 | static struct of_device_id leo_match[] = { |
651 | { | 645 | { |
652 | .name = "leo", | 646 | .name = "SUNW,leo", |
653 | }, | 647 | }, |
654 | {}, | 648 | {}, |
655 | }; | 649 | }; |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 274bc93ab7d8..7dcda187d9ba 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -573,8 +573,8 @@ static int setup_frame_dma(struct pxafb_info *fbi, int dma, int pal, | |||
573 | dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; | 573 | dma_desc->fdadr = fbi->dma_buff_phys + dma_desc_off; |
574 | fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; | 574 | fbi->fdadr[dma] = fbi->dma_buff_phys + dma_desc_off; |
575 | } else { | 575 | } else { |
576 | pal_desc = &fbi->dma_buff->pal_desc[dma]; | 576 | pal_desc = &fbi->dma_buff->pal_desc[pal]; |
577 | pal_desc_off = offsetof(struct pxafb_dma_buff, dma_desc[pal]); | 577 | pal_desc_off = offsetof(struct pxafb_dma_buff, pal_desc[pal]); |
578 | 578 | ||
579 | pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; | 579 | pal_desc->fsadr = fbi->dma_buff_phys + pal * PALETTE_SIZE; |
580 | pal_desc->fidr = 0; | 580 | pal_desc->fidr = 0; |
@@ -1276,6 +1276,8 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi) | |||
1276 | fbi->dma_buff_phys = fbi->map_dma; | 1276 | fbi->dma_buff_phys = fbi->map_dma; |
1277 | fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; | 1277 | fbi->palette_cpu = (u16 *) fbi->dma_buff->palette; |
1278 | 1278 | ||
1279 | pr_debug("pxafb: palette_mem_size = 0x%08lx\n", fbi->palette_size*sizeof(u16)); | ||
1280 | |||
1279 | #ifdef CONFIG_FB_PXA_SMARTPANEL | 1281 | #ifdef CONFIG_FB_PXA_SMARTPANEL |
1280 | fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; | 1282 | fbi->smart_cmds = (uint16_t *) fbi->dma_buff->cmd_buff; |
1281 | fbi->n_smart_cmds = 0; | 1283 | fbi->n_smart_cmds = 0; |