diff options
Diffstat (limited to 'drivers')
534 files changed, 13615 insertions, 5935 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index ece958d3762e..36d3daa19a74 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig | |||
@@ -152,4 +152,6 @@ source "drivers/vme/Kconfig" | |||
152 | 152 | ||
153 | source "drivers/pwm/Kconfig" | 153 | source "drivers/pwm/Kconfig" |
154 | 154 | ||
155 | source "drivers/irqchip/Kconfig" | ||
156 | |||
155 | endmenu | 157 | endmenu |
diff --git a/drivers/Makefile b/drivers/Makefile index 5b421840c48d..8c30e73cd94c 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -5,6 +5,8 @@ | |||
5 | # Rewritten to use lists instead of if-statements. | 5 | # Rewritten to use lists instead of if-statements. |
6 | # | 6 | # |
7 | 7 | ||
8 | obj-y += irqchip/ | ||
9 | |||
8 | # GPIO must come after pinctrl as gpios may need to mux pins etc | 10 | # GPIO must come after pinctrl as gpios may need to mux pins etc |
9 | obj-y += pinctrl/ | 11 | obj-y += pinctrl/ |
10 | obj-y += gpio/ | 12 | obj-y += gpio/ |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 9628652e080c..e0596954290b 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -237,6 +237,16 @@ static int __acpi_bus_get_power(struct acpi_device *device, int *state) | |||
237 | } else if (result == ACPI_STATE_D3_HOT) { | 237 | } else if (result == ACPI_STATE_D3_HOT) { |
238 | result = ACPI_STATE_D3; | 238 | result = ACPI_STATE_D3; |
239 | } | 239 | } |
240 | |||
241 | /* | ||
242 | * If we were unsure about the device parent's power state up to this | ||
243 | * point, the fact that the device is in D0 implies that the parent has | ||
244 | * to be in D0 too. | ||
245 | */ | ||
246 | if (device->parent && device->parent->power.state == ACPI_STATE_UNKNOWN | ||
247 | && result == ACPI_STATE_D0) | ||
248 | device->parent->power.state = ACPI_STATE_D0; | ||
249 | |||
240 | *state = result; | 250 | *state = result; |
241 | 251 | ||
242 | out: | 252 | out: |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index fc1803414629..40e38a06ba85 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -107,6 +107,7 @@ struct acpi_power_resource { | |||
107 | 107 | ||
108 | /* List of devices relying on this power resource */ | 108 | /* List of devices relying on this power resource */ |
109 | struct acpi_power_resource_device *devices; | 109 | struct acpi_power_resource_device *devices; |
110 | struct mutex devices_lock; | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | static struct list_head acpi_power_resource_list; | 113 | static struct list_head acpi_power_resource_list; |
@@ -225,7 +226,6 @@ static void acpi_power_on_device(struct acpi_power_managed_device *device) | |||
225 | 226 | ||
226 | static int __acpi_power_on(struct acpi_power_resource *resource) | 227 | static int __acpi_power_on(struct acpi_power_resource *resource) |
227 | { | 228 | { |
228 | struct acpi_power_resource_device *device_list = resource->devices; | ||
229 | acpi_status status = AE_OK; | 229 | acpi_status status = AE_OK; |
230 | 230 | ||
231 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); | 231 | status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL); |
@@ -238,19 +238,15 @@ static int __acpi_power_on(struct acpi_power_resource *resource) | |||
238 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", | 238 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Power resource [%s] turned on\n", |
239 | resource->name)); | 239 | resource->name)); |
240 | 240 | ||
241 | while (device_list) { | ||
242 | acpi_power_on_device(device_list->device); | ||
243 | |||
244 | device_list = device_list->next; | ||
245 | } | ||
246 | |||
247 | return 0; | 241 | return 0; |
248 | } | 242 | } |
249 | 243 | ||
250 | static int acpi_power_on(acpi_handle handle) | 244 | static int acpi_power_on(acpi_handle handle) |
251 | { | 245 | { |
252 | int result = 0; | 246 | int result = 0; |
247 | bool resume_device = false; | ||
253 | struct acpi_power_resource *resource = NULL; | 248 | struct acpi_power_resource *resource = NULL; |
249 | struct acpi_power_resource_device *device_list; | ||
254 | 250 | ||
255 | result = acpi_power_get_context(handle, &resource); | 251 | result = acpi_power_get_context(handle, &resource); |
256 | if (result) | 252 | if (result) |
@@ -266,10 +262,25 @@ static int acpi_power_on(acpi_handle handle) | |||
266 | result = __acpi_power_on(resource); | 262 | result = __acpi_power_on(resource); |
267 | if (result) | 263 | if (result) |
268 | resource->ref_count--; | 264 | resource->ref_count--; |
265 | else | ||
266 | resume_device = true; | ||
269 | } | 267 | } |
270 | 268 | ||
271 | mutex_unlock(&resource->resource_lock); | 269 | mutex_unlock(&resource->resource_lock); |
272 | 270 | ||
271 | if (!resume_device) | ||
272 | return result; | ||
273 | |||
274 | mutex_lock(&resource->devices_lock); | ||
275 | |||
276 | device_list = resource->devices; | ||
277 | while (device_list) { | ||
278 | acpi_power_on_device(device_list->device); | ||
279 | device_list = device_list->next; | ||
280 | } | ||
281 | |||
282 | mutex_unlock(&resource->devices_lock); | ||
283 | |||
273 | return result; | 284 | return result; |
274 | } | 285 | } |
275 | 286 | ||
@@ -355,7 +366,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev, | |||
355 | if (acpi_power_get_context(res_handle, &resource)) | 366 | if (acpi_power_get_context(res_handle, &resource)) |
356 | return; | 367 | return; |
357 | 368 | ||
358 | mutex_lock(&resource->resource_lock); | 369 | mutex_lock(&resource->devices_lock); |
359 | prev = NULL; | 370 | prev = NULL; |
360 | curr = resource->devices; | 371 | curr = resource->devices; |
361 | while (curr) { | 372 | while (curr) { |
@@ -372,7 +383,7 @@ static void __acpi_power_resource_unregister_device(struct device *dev, | |||
372 | prev = curr; | 383 | prev = curr; |
373 | curr = curr->next; | 384 | curr = curr->next; |
374 | } | 385 | } |
375 | mutex_unlock(&resource->resource_lock); | 386 | mutex_unlock(&resource->devices_lock); |
376 | } | 387 | } |
377 | 388 | ||
378 | /* Unlink dev from all power resources in _PR0 */ | 389 | /* Unlink dev from all power resources in _PR0 */ |
@@ -414,10 +425,10 @@ static int __acpi_power_resource_register_device( | |||
414 | 425 | ||
415 | power_resource_device->device = powered_device; | 426 | power_resource_device->device = powered_device; |
416 | 427 | ||
417 | mutex_lock(&resource->resource_lock); | 428 | mutex_lock(&resource->devices_lock); |
418 | power_resource_device->next = resource->devices; | 429 | power_resource_device->next = resource->devices; |
419 | resource->devices = power_resource_device; | 430 | resource->devices = power_resource_device; |
420 | mutex_unlock(&resource->resource_lock); | 431 | mutex_unlock(&resource->devices_lock); |
421 | 432 | ||
422 | return 0; | 433 | return 0; |
423 | } | 434 | } |
@@ -462,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) | |||
462 | return ret; | 473 | return ret; |
463 | 474 | ||
464 | no_power_resource: | 475 | no_power_resource: |
465 | printk(KERN_WARNING PREFIX "Invalid Power Resource to register!"); | 476 | printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!"); |
466 | return -ENODEV; | 477 | return -ENODEV; |
467 | } | 478 | } |
468 | EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); | 479 | EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); |
@@ -721,6 +732,7 @@ static int acpi_power_add(struct acpi_device *device) | |||
721 | 732 | ||
722 | resource->device = device; | 733 | resource->device = device; |
723 | mutex_init(&resource->resource_lock); | 734 | mutex_init(&resource->resource_lock); |
735 | mutex_init(&resource->devices_lock); | ||
724 | strcpy(resource->name, device->pnp.bus_id); | 736 | strcpy(resource->name, device->pnp.bus_id); |
725 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); | 737 | strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); |
726 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); | 738 | strcpy(acpi_device_class(device), ACPI_POWER_CLASS); |
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 50d5dea0ff59..7862d17976b7 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -268,6 +268,9 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
268 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ | 268 | /* JMicron 360/1/3/5/6, match class to avoid IDE function */ |
269 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 269 | { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
270 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, | 270 | PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr }, |
271 | /* JMicron 362B and 362C have an AHCI function with IDE class code */ | ||
272 | { PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr }, | ||
273 | { PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr }, | ||
271 | 274 | ||
272 | /* ATI */ | 275 | /* ATI */ |
273 | { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ | 276 | { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */ |
@@ -393,6 +396,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
393 | .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ | 396 | .driver_data = board_ahci_yes_fbs }, /* 88se9125 */ |
394 | { PCI_DEVICE(0x1b4b, 0x917a), | 397 | { PCI_DEVICE(0x1b4b, 0x917a), |
395 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ | 398 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 */ |
399 | { PCI_DEVICE(0x1b4b, 0x9192), | ||
400 | .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */ | ||
396 | { PCI_DEVICE(0x1b4b, 0x91a3), | 401 | { PCI_DEVICE(0x1b4b, 0x91a3), |
397 | .driver_data = board_ahci_yes_fbs }, | 402 | .driver_data = board_ahci_yes_fbs }, |
398 | 403 | ||
@@ -400,7 +405,10 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
400 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ | 405 | { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */ |
401 | 406 | ||
402 | /* Asmedia */ | 407 | /* Asmedia */ |
403 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1061 */ | 408 | { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */ |
409 | { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */ | ||
410 | { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */ | ||
411 | { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */ | ||
404 | 412 | ||
405 | /* Generic, PCI class code for AHCI */ | 413 | /* Generic, PCI class code for AHCI */ |
406 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | 414 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
diff --git a/drivers/ata/pata_ep93xx.c b/drivers/ata/pata_ep93xx.c index 6ef2e3741f76..e056406d6a11 100644 --- a/drivers/ata/pata_ep93xx.c +++ b/drivers/ata/pata_ep93xx.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <linux/dmaengine.h> | 43 | #include <linux/dmaengine.h> |
44 | #include <linux/ktime.h> | 44 | #include <linux/ktime.h> |
45 | 45 | ||
46 | #include <mach/dma.h> | 46 | #include <linux/platform_data/dma-ep93xx.h> |
47 | #include <mach/platform.h> | 47 | #include <mach/platform.h> |
48 | 48 | ||
49 | #define DRV_NAME "ep93xx-ide" | 49 | #define DRV_NAME "ep93xx-ide" |
diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c index 0bb0fb7b26bc..4b8ba559fe24 100644 --- a/drivers/ata/pata_pxa.c +++ b/drivers/ata/pata_pxa.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <scsi/scsi_host.h> | 32 | #include <scsi/scsi_host.h> |
33 | 33 | ||
34 | #include <mach/pxa2xx-regs.h> | 34 | #include <mach/pxa2xx-regs.h> |
35 | #include <mach/pata_pxa.h> | 35 | #include <linux/platform_data/ata-pxa.h> |
36 | #include <mach/dma.h> | 36 | #include <mach/dma.h> |
37 | 37 | ||
38 | #define DRV_NAME "pata_pxa" | 38 | #define DRV_NAME "pata_pxa" |
diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index 1b372c297195..63ffb002ec67 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | 25 | ||
26 | #include <plat/ata.h> | 26 | #include <linux/platform_data/ata-samsung_cf.h> |
27 | #include <plat/regs-ata.h> | 27 | #include <plat/regs-ata.h> |
28 | 28 | ||
29 | #define DRV_NAME "pata_samsung_cf" | 29 | #define DRV_NAME "pata_samsung_cf" |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 11f36e502136..fc2de5528dcc 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -86,6 +86,7 @@ static struct usb_device_id ath3k_table[] = { | |||
86 | 86 | ||
87 | /* Atheros AR5BBU22 with sflash firmware */ | 87 | /* Atheros AR5BBU22 with sflash firmware */ |
88 | { USB_DEVICE(0x0489, 0xE03C) }, | 88 | { USB_DEVICE(0x0489, 0xE03C) }, |
89 | { USB_DEVICE(0x0489, 0xE036) }, | ||
89 | 90 | ||
90 | { } /* Terminating entry */ | 91 | { } /* Terminating entry */ |
91 | }; | 92 | }; |
@@ -109,6 +110,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { | |||
109 | 110 | ||
110 | /* Atheros AR5BBU22 with sflash firmware */ | 111 | /* Atheros AR5BBU22 with sflash firmware */ |
111 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, | 112 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, |
113 | { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 }, | ||
112 | 114 | ||
113 | { } /* Terminating entry */ | 115 | { } /* Terminating entry */ |
114 | }; | 116 | }; |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index cef3bac1a543..654e248763ef 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -52,6 +52,9 @@ static struct usb_device_id btusb_table[] = { | |||
52 | /* Generic Bluetooth USB device */ | 52 | /* Generic Bluetooth USB device */ |
53 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, | 53 | { USB_DEVICE_INFO(0xe0, 0x01, 0x01) }, |
54 | 54 | ||
55 | /* Apple-specific (Broadcom) devices */ | ||
56 | { USB_VENDOR_AND_INTERFACE_INFO(0x05ac, 0xff, 0x01, 0x01) }, | ||
57 | |||
55 | /* Broadcom SoftSailing reporting vendor specific */ | 58 | /* Broadcom SoftSailing reporting vendor specific */ |
56 | { USB_DEVICE(0x0a5c, 0x21e1) }, | 59 | { USB_DEVICE(0x0a5c, 0x21e1) }, |
57 | 60 | ||
@@ -94,16 +97,14 @@ static struct usb_device_id btusb_table[] = { | |||
94 | 97 | ||
95 | /* Broadcom BCM20702A0 */ | 98 | /* Broadcom BCM20702A0 */ |
96 | { USB_DEVICE(0x0489, 0xe042) }, | 99 | { USB_DEVICE(0x0489, 0xe042) }, |
97 | { USB_DEVICE(0x0a5c, 0x21e3) }, | ||
98 | { USB_DEVICE(0x0a5c, 0x21e6) }, | ||
99 | { USB_DEVICE(0x0a5c, 0x21e8) }, | ||
100 | { USB_DEVICE(0x0a5c, 0x21f3) }, | ||
101 | { USB_DEVICE(0x0a5c, 0x21f4) }, | ||
102 | { USB_DEVICE(0x413c, 0x8197) }, | 100 | { USB_DEVICE(0x413c, 0x8197) }, |
103 | 101 | ||
104 | /* Foxconn - Hon Hai */ | 102 | /* Foxconn - Hon Hai */ |
105 | { USB_DEVICE(0x0489, 0xe033) }, | 103 | { USB_DEVICE(0x0489, 0xe033) }, |
106 | 104 | ||
105 | /*Broadcom devices with vendor specific id */ | ||
106 | { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, | ||
107 | |||
107 | { } /* Terminating entry */ | 108 | { } /* Terminating entry */ |
108 | }; | 109 | }; |
109 | 110 | ||
@@ -141,6 +142,7 @@ static struct usb_device_id blacklist_table[] = { | |||
141 | 142 | ||
142 | /* Atheros AR5BBU12 with sflash firmware */ | 143 | /* Atheros AR5BBU12 with sflash firmware */ |
143 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, | 144 | { USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 }, |
145 | { USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 }, | ||
144 | 146 | ||
145 | /* Broadcom BCM2035 */ | 147 | /* Broadcom BCM2035 */ |
146 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 148 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index 12172a6a95c4..0bc8a6a6a148 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c | |||
@@ -58,7 +58,7 @@ static int ath_wakeup_ar3k(struct tty_struct *tty) | |||
58 | return status; | 58 | return status; |
59 | 59 | ||
60 | /* Disable Automatic RTSCTS */ | 60 | /* Disable Automatic RTSCTS */ |
61 | memcpy(&ktermios, tty->termios, sizeof(ktermios)); | 61 | ktermios = tty->termios; |
62 | ktermios.c_cflag &= ~CRTSCTS; | 62 | ktermios.c_cflag &= ~CRTSCTS; |
63 | tty_set_termios(tty, &ktermios); | 63 | tty_set_termios(tty, &ktermios); |
64 | 64 | ||
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c index 1d82d5838f0c..164544afd680 100644 --- a/drivers/char/mwave/mwavedd.c +++ b/drivers/char/mwave/mwavedd.c | |||
@@ -430,7 +430,7 @@ static ssize_t mwave_write(struct file *file, const char __user *buf, | |||
430 | 430 | ||
431 | static int register_serial_portandirq(unsigned int port, int irq) | 431 | static int register_serial_portandirq(unsigned int port, int irq) |
432 | { | 432 | { |
433 | struct uart_port uart; | 433 | struct uart_8250_port uart; |
434 | 434 | ||
435 | switch ( port ) { | 435 | switch ( port ) { |
436 | case 0x3f8: | 436 | case 0x3f8: |
@@ -462,14 +462,14 @@ static int register_serial_portandirq(unsigned int port, int irq) | |||
462 | } /* switch */ | 462 | } /* switch */ |
463 | /* irq is okay */ | 463 | /* irq is okay */ |
464 | 464 | ||
465 | memset(&uart, 0, sizeof(struct uart_port)); | 465 | memset(&uart, 0, sizeof(uart)); |
466 | 466 | ||
467 | uart.uartclk = 1843200; | 467 | uart.port.uartclk = 1843200; |
468 | uart.iobase = port; | 468 | uart.port.iobase = port; |
469 | uart.irq = irq; | 469 | uart.port.irq = irq; |
470 | uart.iotype = UPIO_PORT; | 470 | uart.port.iotype = UPIO_PORT; |
471 | uart.flags = UPF_SHARE_IRQ; | 471 | uart.port.flags = UPF_SHARE_IRQ; |
472 | return serial8250_register_port(&uart); | 472 | return serial8250_register_8250_port(&uart); |
473 | } | 473 | } |
474 | 474 | ||
475 | 475 | ||
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 0a484b4a1b02..3f57d5de3957 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -1050,7 +1050,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) | |||
1050 | wake_up_interruptible(&info->status_event_wait_q); | 1050 | wake_up_interruptible(&info->status_event_wait_q); |
1051 | wake_up_interruptible(&info->event_wait_q); | 1051 | wake_up_interruptible(&info->event_wait_q); |
1052 | 1052 | ||
1053 | if (info->port.flags & ASYNC_CTS_FLOW) { | 1053 | if (tty_port_cts_enabled(&info->port)) { |
1054 | if (tty->hw_stopped) { | 1054 | if (tty->hw_stopped) { |
1055 | if (info->serial_signals & SerialSignal_CTS) { | 1055 | if (info->serial_signals & SerialSignal_CTS) { |
1056 | if (debug_level >= DEBUG_LEVEL_ISR) | 1056 | if (debug_level >= DEBUG_LEVEL_ISR) |
@@ -1344,7 +1344,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) | |||
1344 | /* TODO:disable interrupts instead of reset to preserve signal states */ | 1344 | /* TODO:disable interrupts instead of reset to preserve signal states */ |
1345 | reset_device(info); | 1345 | reset_device(info); |
1346 | 1346 | ||
1347 | if (!tty || tty->termios->c_cflag & HUPCL) { | 1347 | if (!tty || tty->termios.c_cflag & HUPCL) { |
1348 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 1348 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); |
1349 | set_signals(info); | 1349 | set_signals(info); |
1350 | } | 1350 | } |
@@ -1385,7 +1385,7 @@ static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty) | |||
1385 | port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI); | 1385 | port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI); |
1386 | get_signals(info); | 1386 | get_signals(info); |
1387 | 1387 | ||
1388 | if (info->netcount || (tty && (tty->termios->c_cflag & CREAD))) | 1388 | if (info->netcount || (tty && (tty->termios.c_cflag & CREAD))) |
1389 | rx_start(info); | 1389 | rx_start(info); |
1390 | 1390 | ||
1391 | spin_unlock_irqrestore(&info->lock,flags); | 1391 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -1398,14 +1398,14 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty) | |||
1398 | unsigned cflag; | 1398 | unsigned cflag; |
1399 | int bits_per_char; | 1399 | int bits_per_char; |
1400 | 1400 | ||
1401 | if (!tty || !tty->termios) | 1401 | if (!tty) |
1402 | return; | 1402 | return; |
1403 | 1403 | ||
1404 | if (debug_level >= DEBUG_LEVEL_INFO) | 1404 | if (debug_level >= DEBUG_LEVEL_INFO) |
1405 | printk("%s(%d):mgslpc_change_params(%s)\n", | 1405 | printk("%s(%d):mgslpc_change_params(%s)\n", |
1406 | __FILE__,__LINE__, info->device_name ); | 1406 | __FILE__,__LINE__, info->device_name ); |
1407 | 1407 | ||
1408 | cflag = tty->termios->c_cflag; | 1408 | cflag = tty->termios.c_cflag; |
1409 | 1409 | ||
1410 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 1410 | /* if B0 rate (hangup) specified then negate DTR and RTS */ |
1411 | /* otherwise assert DTR and RTS */ | 1411 | /* otherwise assert DTR and RTS */ |
@@ -1728,7 +1728,7 @@ static void mgslpc_throttle(struct tty_struct * tty) | |||
1728 | if (I_IXOFF(tty)) | 1728 | if (I_IXOFF(tty)) |
1729 | mgslpc_send_xchar(tty, STOP_CHAR(tty)); | 1729 | mgslpc_send_xchar(tty, STOP_CHAR(tty)); |
1730 | 1730 | ||
1731 | if (tty->termios->c_cflag & CRTSCTS) { | 1731 | if (tty->termios.c_cflag & CRTSCTS) { |
1732 | spin_lock_irqsave(&info->lock,flags); | 1732 | spin_lock_irqsave(&info->lock,flags); |
1733 | info->serial_signals &= ~SerialSignal_RTS; | 1733 | info->serial_signals &= ~SerialSignal_RTS; |
1734 | set_signals(info); | 1734 | set_signals(info); |
@@ -1757,7 +1757,7 @@ static void mgslpc_unthrottle(struct tty_struct * tty) | |||
1757 | mgslpc_send_xchar(tty, START_CHAR(tty)); | 1757 | mgslpc_send_xchar(tty, START_CHAR(tty)); |
1758 | } | 1758 | } |
1759 | 1759 | ||
1760 | if (tty->termios->c_cflag & CRTSCTS) { | 1760 | if (tty->termios.c_cflag & CRTSCTS) { |
1761 | spin_lock_irqsave(&info->lock,flags); | 1761 | spin_lock_irqsave(&info->lock,flags); |
1762 | info->serial_signals |= SerialSignal_RTS; | 1762 | info->serial_signals |= SerialSignal_RTS; |
1763 | set_signals(info); | 1763 | set_signals(info); |
@@ -2293,8 +2293,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2293 | tty->driver->name ); | 2293 | tty->driver->name ); |
2294 | 2294 | ||
2295 | /* just return if nothing has changed */ | 2295 | /* just return if nothing has changed */ |
2296 | if ((tty->termios->c_cflag == old_termios->c_cflag) | 2296 | if ((tty->termios.c_cflag == old_termios->c_cflag) |
2297 | && (RELEVANT_IFLAG(tty->termios->c_iflag) | 2297 | && (RELEVANT_IFLAG(tty->termios.c_iflag) |
2298 | == RELEVANT_IFLAG(old_termios->c_iflag))) | 2298 | == RELEVANT_IFLAG(old_termios->c_iflag))) |
2299 | return; | 2299 | return; |
2300 | 2300 | ||
@@ -2302,7 +2302,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2302 | 2302 | ||
2303 | /* Handle transition to B0 status */ | 2303 | /* Handle transition to B0 status */ |
2304 | if (old_termios->c_cflag & CBAUD && | 2304 | if (old_termios->c_cflag & CBAUD && |
2305 | !(tty->termios->c_cflag & CBAUD)) { | 2305 | !(tty->termios.c_cflag & CBAUD)) { |
2306 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 2306 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); |
2307 | spin_lock_irqsave(&info->lock,flags); | 2307 | spin_lock_irqsave(&info->lock,flags); |
2308 | set_signals(info); | 2308 | set_signals(info); |
@@ -2311,9 +2311,9 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2311 | 2311 | ||
2312 | /* Handle transition away from B0 status */ | 2312 | /* Handle transition away from B0 status */ |
2313 | if (!(old_termios->c_cflag & CBAUD) && | 2313 | if (!(old_termios->c_cflag & CBAUD) && |
2314 | tty->termios->c_cflag & CBAUD) { | 2314 | tty->termios.c_cflag & CBAUD) { |
2315 | info->serial_signals |= SerialSignal_DTR; | 2315 | info->serial_signals |= SerialSignal_DTR; |
2316 | if (!(tty->termios->c_cflag & CRTSCTS) || | 2316 | if (!(tty->termios.c_cflag & CRTSCTS) || |
2317 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 2317 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
2318 | info->serial_signals |= SerialSignal_RTS; | 2318 | info->serial_signals |= SerialSignal_RTS; |
2319 | } | 2319 | } |
@@ -2324,7 +2324,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term | |||
2324 | 2324 | ||
2325 | /* Handle turning off CRTSCTS */ | 2325 | /* Handle turning off CRTSCTS */ |
2326 | if (old_termios->c_cflag & CRTSCTS && | 2326 | if (old_termios->c_cflag & CRTSCTS && |
2327 | !(tty->termios->c_cflag & CRTSCTS)) { | 2327 | !(tty->termios.c_cflag & CRTSCTS)) { |
2328 | tty->hw_stopped = 0; | 2328 | tty->hw_stopped = 0; |
2329 | tx_release(tty); | 2329 | tx_release(tty); |
2330 | } | 2330 | } |
@@ -2731,6 +2731,8 @@ static void mgslpc_add_device(MGSLPC_INFO *info) | |||
2731 | #if SYNCLINK_GENERIC_HDLC | 2731 | #if SYNCLINK_GENERIC_HDLC |
2732 | hdlcdev_init(info); | 2732 | hdlcdev_init(info); |
2733 | #endif | 2733 | #endif |
2734 | tty_port_register_device(&info->port, serial_driver, info->line, | ||
2735 | &info->p_dev->dev); | ||
2734 | } | 2736 | } |
2735 | 2737 | ||
2736 | static void mgslpc_remove_device(MGSLPC_INFO *remove_info) | 2738 | static void mgslpc_remove_device(MGSLPC_INFO *remove_info) |
@@ -2744,6 +2746,7 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info) | |||
2744 | last->next_device = info->next_device; | 2746 | last->next_device = info->next_device; |
2745 | else | 2747 | else |
2746 | mgslpc_device_list = info->next_device; | 2748 | mgslpc_device_list = info->next_device; |
2749 | tty_unregister_device(serial_driver, info->line); | ||
2747 | #if SYNCLINK_GENERIC_HDLC | 2750 | #if SYNCLINK_GENERIC_HDLC |
2748 | hdlcdev_exit(info); | 2751 | hdlcdev_exit(info); |
2749 | #endif | 2752 | #endif |
@@ -2798,77 +2801,63 @@ static const struct tty_operations mgslpc_ops = { | |||
2798 | .proc_fops = &mgslpc_proc_fops, | 2801 | .proc_fops = &mgslpc_proc_fops, |
2799 | }; | 2802 | }; |
2800 | 2803 | ||
2801 | static void synclink_cs_cleanup(void) | 2804 | static int __init synclink_cs_init(void) |
2802 | { | 2805 | { |
2803 | int rc; | 2806 | int rc; |
2804 | 2807 | ||
2805 | while(mgslpc_device_list) | 2808 | if (break_on_load) { |
2806 | mgslpc_remove_device(mgslpc_device_list); | 2809 | mgslpc_get_text_ptr(); |
2807 | 2810 | BREAKPOINT(); | |
2808 | if (serial_driver) { | ||
2809 | if ((rc = tty_unregister_driver(serial_driver))) | ||
2810 | printk("%s(%d) failed to unregister tty driver err=%d\n", | ||
2811 | __FILE__,__LINE__,rc); | ||
2812 | put_tty_driver(serial_driver); | ||
2813 | } | 2811 | } |
2814 | 2812 | ||
2815 | pcmcia_unregister_driver(&mgslpc_driver); | 2813 | serial_driver = tty_alloc_driver(MAX_DEVICE_COUNT, |
2816 | } | 2814 | TTY_DRIVER_REAL_RAW | |
2817 | 2815 | TTY_DRIVER_DYNAMIC_DEV); | |
2818 | static int __init synclink_cs_init(void) | 2816 | if (IS_ERR(serial_driver)) { |
2819 | { | 2817 | rc = PTR_ERR(serial_driver); |
2820 | int rc; | 2818 | goto err; |
2821 | 2819 | } | |
2822 | if (break_on_load) { | ||
2823 | mgslpc_get_text_ptr(); | ||
2824 | BREAKPOINT(); | ||
2825 | } | ||
2826 | |||
2827 | if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0) | ||
2828 | return rc; | ||
2829 | |||
2830 | serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT); | ||
2831 | if (!serial_driver) { | ||
2832 | rc = -ENOMEM; | ||
2833 | goto error; | ||
2834 | } | ||
2835 | 2820 | ||
2836 | /* Initialize the tty_driver structure */ | 2821 | /* Initialize the tty_driver structure */ |
2837 | 2822 | serial_driver->driver_name = "synclink_cs"; | |
2838 | serial_driver->driver_name = "synclink_cs"; | 2823 | serial_driver->name = "ttySLP"; |
2839 | serial_driver->name = "ttySLP"; | 2824 | serial_driver->major = ttymajor; |
2840 | serial_driver->major = ttymajor; | 2825 | serial_driver->minor_start = 64; |
2841 | serial_driver->minor_start = 64; | 2826 | serial_driver->type = TTY_DRIVER_TYPE_SERIAL; |
2842 | serial_driver->type = TTY_DRIVER_TYPE_SERIAL; | 2827 | serial_driver->subtype = SERIAL_TYPE_NORMAL; |
2843 | serial_driver->subtype = SERIAL_TYPE_NORMAL; | 2828 | serial_driver->init_termios = tty_std_termios; |
2844 | serial_driver->init_termios = tty_std_termios; | 2829 | serial_driver->init_termios.c_cflag = |
2845 | serial_driver->init_termios.c_cflag = | 2830 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
2846 | B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 2831 | tty_set_operations(serial_driver, &mgslpc_ops); |
2847 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 2832 | |
2848 | tty_set_operations(serial_driver, &mgslpc_ops); | 2833 | rc = tty_register_driver(serial_driver); |
2849 | 2834 | if (rc < 0) { | |
2850 | if ((rc = tty_register_driver(serial_driver)) < 0) { | 2835 | printk(KERN_ERR "%s(%d):Couldn't register serial driver\n", |
2851 | printk("%s(%d):Couldn't register serial driver\n", | 2836 | __FILE__, __LINE__); |
2852 | __FILE__,__LINE__); | 2837 | goto err_put_tty; |
2853 | put_tty_driver(serial_driver); | 2838 | } |
2854 | serial_driver = NULL; | ||
2855 | goto error; | ||
2856 | } | ||
2857 | 2839 | ||
2858 | printk("%s %s, tty major#%d\n", | 2840 | rc = pcmcia_register_driver(&mgslpc_driver); |
2859 | driver_name, driver_version, | 2841 | if (rc < 0) |
2860 | serial_driver->major); | 2842 | goto err_unreg_tty; |
2861 | 2843 | ||
2862 | return 0; | 2844 | printk(KERN_INFO "%s %s, tty major#%d\n", driver_name, driver_version, |
2845 | serial_driver->major); | ||
2863 | 2846 | ||
2864 | error: | 2847 | return 0; |
2865 | synclink_cs_cleanup(); | 2848 | err_unreg_tty: |
2866 | return rc; | 2849 | tty_unregister_driver(serial_driver); |
2850 | err_put_tty: | ||
2851 | put_tty_driver(serial_driver); | ||
2852 | err: | ||
2853 | return rc; | ||
2867 | } | 2854 | } |
2868 | 2855 | ||
2869 | static void __exit synclink_cs_exit(void) | 2856 | static void __exit synclink_cs_exit(void) |
2870 | { | 2857 | { |
2871 | synclink_cs_cleanup(); | 2858 | pcmcia_unregister_driver(&mgslpc_driver); |
2859 | tty_unregister_driver(serial_driver); | ||
2860 | put_tty_driver(serial_driver); | ||
2872 | } | 2861 | } |
2873 | 2862 | ||
2874 | module_init(synclink_cs_init); | 2863 | module_init(synclink_cs_init); |
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 46b77ede84c0..af98f6d6509b 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c | |||
@@ -67,7 +67,7 @@ static int tpk_printk(const unsigned char *buf, int count) | |||
67 | tmp[tpk_curr + 1] = '\0'; | 67 | tmp[tpk_curr + 1] = '\0'; |
68 | printk(KERN_INFO "%s%s", tpk_tag, tmp); | 68 | printk(KERN_INFO "%s%s", tpk_tag, tmp); |
69 | tpk_curr = 0; | 69 | tpk_curr = 0; |
70 | if (buf[i + 1] == '\n') | 70 | if ((i + 1) < count && buf[i + 1] == '\n') |
71 | i++; | 71 | i++; |
72 | break; | 72 | break; |
73 | case '\n': | 73 | case '\n': |
@@ -178,11 +178,17 @@ static struct tty_driver *ttyprintk_driver; | |||
178 | static int __init ttyprintk_init(void) | 178 | static int __init ttyprintk_init(void) |
179 | { | 179 | { |
180 | int ret = -ENOMEM; | 180 | int ret = -ENOMEM; |
181 | void *rp; | ||
182 | 181 | ||
183 | ttyprintk_driver = alloc_tty_driver(1); | 182 | tty_port_init(&tpk_port.port); |
184 | if (!ttyprintk_driver) | 183 | tpk_port.port.ops = &null_ops; |
185 | return ret; | 184 | mutex_init(&tpk_port.port_write_mutex); |
185 | |||
186 | ttyprintk_driver = tty_alloc_driver(1, | ||
187 | TTY_DRIVER_RESET_TERMIOS | | ||
188 | TTY_DRIVER_REAL_RAW | | ||
189 | TTY_DRIVER_UNNUMBERED_NODE); | ||
190 | if (IS_ERR(ttyprintk_driver)) | ||
191 | return PTR_ERR(ttyprintk_driver); | ||
186 | 192 | ||
187 | ttyprintk_driver->driver_name = "ttyprintk"; | 193 | ttyprintk_driver->driver_name = "ttyprintk"; |
188 | ttyprintk_driver->name = "ttyprintk"; | 194 | ttyprintk_driver->name = "ttyprintk"; |
@@ -191,9 +197,8 @@ static int __init ttyprintk_init(void) | |||
191 | ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; | 197 | ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; |
192 | ttyprintk_driver->init_termios = tty_std_termios; | 198 | ttyprintk_driver->init_termios = tty_std_termios; |
193 | ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; | 199 | ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; |
194 | ttyprintk_driver->flags = TTY_DRIVER_RESET_TERMIOS | | ||
195 | TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | ||
196 | tty_set_operations(ttyprintk_driver, &ttyprintk_ops); | 200 | tty_set_operations(ttyprintk_driver, &ttyprintk_ops); |
201 | tty_port_link_device(&tpk_port.port, ttyprintk_driver, 0); | ||
197 | 202 | ||
198 | ret = tty_register_driver(ttyprintk_driver); | 203 | ret = tty_register_driver(ttyprintk_driver); |
199 | if (ret < 0) { | 204 | if (ret < 0) { |
@@ -201,22 +206,10 @@ static int __init ttyprintk_init(void) | |||
201 | goto error; | 206 | goto error; |
202 | } | 207 | } |
203 | 208 | ||
204 | /* create our unnumbered device */ | ||
205 | rp = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 3), NULL, | ||
206 | ttyprintk_driver->name); | ||
207 | if (IS_ERR(rp)) { | ||
208 | printk(KERN_ERR "Couldn't create ttyprintk device\n"); | ||
209 | ret = PTR_ERR(rp); | ||
210 | goto error; | ||
211 | } | ||
212 | |||
213 | tty_port_init(&tpk_port.port); | ||
214 | tpk_port.port.ops = &null_ops; | ||
215 | mutex_init(&tpk_port.port_write_mutex); | ||
216 | |||
217 | return 0; | 209 | return 0; |
218 | 210 | ||
219 | error: | 211 | error: |
212 | tty_unregister_driver(ttyprintk_driver); | ||
220 | put_tty_driver(ttyprintk_driver); | 213 | put_tty_driver(ttyprintk_driver); |
221 | ttyprintk_driver = NULL; | 214 | ttyprintk_driver = NULL; |
222 | return ret; | 215 | return ret; |
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 7f0b5ca78516..bace9e98f75d 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -40,4 +40,17 @@ config COMMON_CLK_WM831X | |||
40 | Supports the clocking subsystem of the WM831x/2x series of | 40 | Supports the clocking subsystem of the WM831x/2x series of |
41 | PMICs from Wolfson Microlectronics. | 41 | PMICs from Wolfson Microlectronics. |
42 | 42 | ||
43 | config COMMON_CLK_VERSATILE | ||
44 | bool "Clock driver for ARM Reference designs" | ||
45 | depends on ARCH_INTEGRATOR || ARCH_REALVIEW | ||
46 | ---help--- | ||
47 | Supports clocking on ARM Reference designs Integrator/AP, | ||
48 | Integrator/CP, RealView PB1176, EB, PB11MP and PBX. | ||
49 | |||
50 | config COMMON_CLK_MAX77686 | ||
51 | tristate "Clock driver for Maxim 77686 MFD" | ||
52 | depends on MFD_MAX77686 | ||
53 | ---help--- | ||
54 | This driver supports Maxim 77686 crystal oscillator clock. | ||
55 | |||
43 | endmenu | 56 | endmenu |
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5869ea387054..9184b5e19edf 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile | |||
@@ -3,13 +3,21 @@ obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o | |||
3 | obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ | 3 | obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed-rate.o clk-gate.o \ |
4 | clk-mux.o clk-divider.o clk-fixed-factor.o | 4 | clk-mux.o clk-divider.o clk-fixed-factor.o |
5 | # SoCs specific | 5 | # SoCs specific |
6 | obj-$(CONFIG_ARCH_BCM2835) += clk-bcm2835.o | ||
6 | obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o | 7 | obj-$(CONFIG_ARCH_NOMADIK) += clk-nomadik.o |
7 | obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o | 8 | obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o |
8 | obj-$(CONFIG_ARCH_MXS) += mxs/ | 9 | obj-$(CONFIG_ARCH_MXS) += mxs/ |
9 | obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ | 10 | obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ |
10 | obj-$(CONFIG_PLAT_SPEAR) += spear/ | 11 | obj-$(CONFIG_PLAT_SPEAR) += spear/ |
11 | obj-$(CONFIG_ARCH_U300) += clk-u300.o | 12 | obj-$(CONFIG_ARCH_U300) += clk-u300.o |
12 | obj-$(CONFIG_ARCH_INTEGRATOR) += versatile/ | 13 | obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ |
14 | obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o | ||
15 | ifeq ($(CONFIG_COMMON_CLK), y) | ||
16 | obj-$(CONFIG_ARCH_MMP) += mmp/ | ||
17 | endif | ||
18 | obj-$(CONFIG_MACH_LOONGSON1) += clk-ls1x.o | ||
19 | obj-$(CONFIG_ARCH_U8500) += ux500/ | ||
13 | 20 | ||
14 | # Chip specific | 21 | # Chip specific |
15 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o | 22 | obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o |
23 | obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o | ||
diff --git a/drivers/clk/clk-bcm2835.c b/drivers/clk/clk-bcm2835.c new file mode 100644 index 000000000000..67ad16b20b81 --- /dev/null +++ b/drivers/clk/clk-bcm2835.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Broadcom | ||
3 | * Copyright (C) 2012 Stephen Warren | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/clk-provider.h> | ||
21 | #include <linux/clkdev.h> | ||
22 | #include <linux/clk/bcm2835.h> | ||
23 | |||
24 | /* | ||
25 | * These are fixed clocks. They're probably not all root clocks and it may | ||
26 | * be possible to turn them on and off but until this is mapped out better | ||
27 | * it's the only way they can be used. | ||
28 | */ | ||
29 | void __init bcm2835_init_clocks(void) | ||
30 | { | ||
31 | struct clk *clk; | ||
32 | int ret; | ||
33 | |||
34 | clk = clk_register_fixed_rate(NULL, "sys_pclk", NULL, CLK_IS_ROOT, | ||
35 | 250000000); | ||
36 | if (!clk) | ||
37 | pr_err("sys_pclk not registered\n"); | ||
38 | |||
39 | clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, | ||
40 | 126000000); | ||
41 | if (!clk) | ||
42 | pr_err("apb_pclk not registered\n"); | ||
43 | |||
44 | clk = clk_register_fixed_rate(NULL, "uart0_pclk", NULL, CLK_IS_ROOT, | ||
45 | 3000000); | ||
46 | if (!clk) | ||
47 | pr_err("uart0_pclk not registered\n"); | ||
48 | ret = clk_register_clkdev(clk, NULL, "20201000.uart"); | ||
49 | if (ret) | ||
50 | pr_err("uart0_pclk alias not registered\n"); | ||
51 | |||
52 | clk = clk_register_fixed_rate(NULL, "uart1_pclk", NULL, CLK_IS_ROOT, | ||
53 | 125000000); | ||
54 | if (!clk) | ||
55 | pr_err("uart1_pclk not registered\n"); | ||
56 | ret = clk_register_clkdev(clk, NULL, "20215000.uart"); | ||
57 | if (ret) | ||
58 | pr_err("uart0_pclk alias not registered\n"); | ||
59 | } | ||
diff --git a/drivers/clk/clk-ls1x.c b/drivers/clk/clk-ls1x.c new file mode 100644 index 000000000000..f20b750235f6 --- /dev/null +++ b/drivers/clk/clk-ls1x.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Zhang, Keguang <keguang.zhang@gmail.com> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/clkdev.h> | ||
11 | #include <linux/clk-provider.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/err.h> | ||
15 | |||
16 | #include <loongson1.h> | ||
17 | |||
18 | #define OSC 33 | ||
19 | |||
20 | static DEFINE_SPINLOCK(_lock); | ||
21 | |||
22 | static int ls1x_pll_clk_enable(struct clk_hw *hw) | ||
23 | { | ||
24 | return 0; | ||
25 | } | ||
26 | |||
27 | static void ls1x_pll_clk_disable(struct clk_hw *hw) | ||
28 | { | ||
29 | } | ||
30 | |||
31 | static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw, | ||
32 | unsigned long parent_rate) | ||
33 | { | ||
34 | u32 pll, rate; | ||
35 | |||
36 | pll = __raw_readl(LS1X_CLK_PLL_FREQ); | ||
37 | rate = ((12 + (pll & 0x3f)) * 1000000) + | ||
38 | ((((pll >> 8) & 0x3ff) * 1000000) >> 10); | ||
39 | rate *= OSC; | ||
40 | rate >>= 1; | ||
41 | |||
42 | return rate; | ||
43 | } | ||
44 | |||
45 | static const struct clk_ops ls1x_pll_clk_ops = { | ||
46 | .enable = ls1x_pll_clk_enable, | ||
47 | .disable = ls1x_pll_clk_disable, | ||
48 | .recalc_rate = ls1x_pll_recalc_rate, | ||
49 | }; | ||
50 | |||
51 | static struct clk * __init clk_register_pll(struct device *dev, | ||
52 | const char *name, const char *parent_name, unsigned long flags) | ||
53 | { | ||
54 | struct clk_hw *hw; | ||
55 | struct clk *clk; | ||
56 | struct clk_init_data init; | ||
57 | |||
58 | /* allocate the divider */ | ||
59 | hw = kzalloc(sizeof(struct clk_hw), GFP_KERNEL); | ||
60 | if (!hw) { | ||
61 | pr_err("%s: could not allocate clk_hw\n", __func__); | ||
62 | return ERR_PTR(-ENOMEM); | ||
63 | } | ||
64 | |||
65 | init.name = name; | ||
66 | init.ops = &ls1x_pll_clk_ops; | ||
67 | init.flags = flags | CLK_IS_BASIC; | ||
68 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
69 | init.num_parents = (parent_name ? 1 : 0); | ||
70 | hw->init = &init; | ||
71 | |||
72 | /* register the clock */ | ||
73 | clk = clk_register(dev, hw); | ||
74 | |||
75 | if (IS_ERR(clk)) | ||
76 | kfree(hw); | ||
77 | |||
78 | return clk; | ||
79 | } | ||
80 | |||
81 | void __init ls1x_clk_init(void) | ||
82 | { | ||
83 | struct clk *clk; | ||
84 | |||
85 | clk = clk_register_pll(NULL, "pll_clk", NULL, CLK_IS_ROOT); | ||
86 | clk_prepare_enable(clk); | ||
87 | |||
88 | clk = clk_register_divider(NULL, "cpu_clk", "pll_clk", | ||
89 | CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_CPU_SHIFT, | ||
90 | DIV_CPU_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); | ||
91 | clk_prepare_enable(clk); | ||
92 | clk_register_clkdev(clk, "cpu", NULL); | ||
93 | |||
94 | clk = clk_register_divider(NULL, "dc_clk", "pll_clk", | ||
95 | CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT, | ||
96 | DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); | ||
97 | clk_prepare_enable(clk); | ||
98 | clk_register_clkdev(clk, "dc", NULL); | ||
99 | |||
100 | clk = clk_register_divider(NULL, "ahb_clk", "pll_clk", | ||
101 | CLK_SET_RATE_PARENT, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT, | ||
102 | DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); | ||
103 | clk_prepare_enable(clk); | ||
104 | clk_register_clkdev(clk, "ahb", NULL); | ||
105 | clk_register_clkdev(clk, "stmmaceth", NULL); | ||
106 | |||
107 | clk = clk_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, 2); | ||
108 | clk_prepare_enable(clk); | ||
109 | clk_register_clkdev(clk, "apb", NULL); | ||
110 | clk_register_clkdev(clk, "serial8250", NULL); | ||
111 | } | ||
diff --git a/drivers/clk/clk-max77686.c b/drivers/clk/clk-max77686.c new file mode 100644 index 000000000000..ac5f5434cb9a --- /dev/null +++ b/drivers/clk/clk-max77686.c | |||
@@ -0,0 +1,244 @@ | |||
1 | /* | ||
2 | * clk-max77686.c - Clock driver for Maxim 77686 | ||
3 | * | ||
4 | * Copyright (C) 2012 Samsung Electornics | ||
5 | * Jonghwa Lee <jonghwa3.lee@samsung.com> | ||
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 as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/err.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/mfd/max77686.h> | ||
28 | #include <linux/mfd/max77686-private.h> | ||
29 | #include <linux/clk-provider.h> | ||
30 | #include <linux/mutex.h> | ||
31 | #include <linux/clkdev.h> | ||
32 | |||
33 | enum { | ||
34 | MAX77686_CLK_AP = 0, | ||
35 | MAX77686_CLK_CP, | ||
36 | MAX77686_CLK_PMIC, | ||
37 | MAX77686_CLKS_NUM, | ||
38 | }; | ||
39 | |||
40 | struct max77686_clk { | ||
41 | struct max77686_dev *iodev; | ||
42 | u32 mask; | ||
43 | struct clk_hw hw; | ||
44 | struct clk_lookup *lookup; | ||
45 | }; | ||
46 | |||
47 | static struct max77686_clk *get_max77686_clk(struct clk_hw *hw) | ||
48 | { | ||
49 | return container_of(hw, struct max77686_clk, hw); | ||
50 | } | ||
51 | |||
52 | static int max77686_clk_prepare(struct clk_hw *hw) | ||
53 | { | ||
54 | struct max77686_clk *max77686; | ||
55 | int ret; | ||
56 | |||
57 | max77686 = get_max77686_clk(hw); | ||
58 | if (!max77686) | ||
59 | return -ENOMEM; | ||
60 | |||
61 | ret = regmap_update_bits(max77686->iodev->regmap, | ||
62 | MAX77686_REG_32KHZ, max77686->mask, max77686->mask); | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | static void max77686_clk_unprepare(struct clk_hw *hw) | ||
68 | { | ||
69 | struct max77686_clk *max77686; | ||
70 | |||
71 | max77686 = get_max77686_clk(hw); | ||
72 | if (!max77686) | ||
73 | return; | ||
74 | |||
75 | regmap_update_bits(max77686->iodev->regmap, | ||
76 | MAX77686_REG_32KHZ, max77686->mask, ~max77686->mask); | ||
77 | } | ||
78 | |||
79 | static int max77686_clk_is_enabled(struct clk_hw *hw) | ||
80 | { | ||
81 | struct max77686_clk *max77686; | ||
82 | int ret; | ||
83 | u32 val; | ||
84 | |||
85 | max77686 = get_max77686_clk(hw); | ||
86 | if (!max77686) | ||
87 | return -ENOMEM; | ||
88 | |||
89 | ret = regmap_read(max77686->iodev->regmap, | ||
90 | MAX77686_REG_32KHZ, &val); | ||
91 | |||
92 | if (ret < 0) | ||
93 | return -EINVAL; | ||
94 | |||
95 | return val & max77686->mask; | ||
96 | } | ||
97 | |||
98 | static struct clk_ops max77686_clk_ops = { | ||
99 | .prepare = max77686_clk_prepare, | ||
100 | .unprepare = max77686_clk_unprepare, | ||
101 | .is_enabled = max77686_clk_is_enabled, | ||
102 | }; | ||
103 | |||
104 | static struct clk_init_data max77686_clks_init[MAX77686_CLKS_NUM] = { | ||
105 | [MAX77686_CLK_AP] = { | ||
106 | .name = "32khz_ap", | ||
107 | .ops = &max77686_clk_ops, | ||
108 | .flags = CLK_IS_ROOT, | ||
109 | }, | ||
110 | [MAX77686_CLK_CP] = { | ||
111 | .name = "32khz_cp", | ||
112 | .ops = &max77686_clk_ops, | ||
113 | .flags = CLK_IS_ROOT, | ||
114 | }, | ||
115 | [MAX77686_CLK_PMIC] = { | ||
116 | .name = "32khz_pmic", | ||
117 | .ops = &max77686_clk_ops, | ||
118 | .flags = CLK_IS_ROOT, | ||
119 | }, | ||
120 | }; | ||
121 | |||
122 | static int max77686_clk_register(struct device *dev, | ||
123 | struct max77686_clk *max77686) | ||
124 | { | ||
125 | struct clk *clk; | ||
126 | struct clk_hw *hw = &max77686->hw; | ||
127 | |||
128 | clk = clk_register(dev, hw); | ||
129 | |||
130 | if (IS_ERR(clk)) | ||
131 | return -ENOMEM; | ||
132 | |||
133 | max77686->lookup = devm_kzalloc(dev, sizeof(struct clk_lookup), | ||
134 | GFP_KERNEL); | ||
135 | if (IS_ERR(max77686->lookup)) | ||
136 | return -ENOMEM; | ||
137 | |||
138 | max77686->lookup->con_id = hw->init->name; | ||
139 | max77686->lookup->clk = clk; | ||
140 | |||
141 | clkdev_add(max77686->lookup); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static __devinit int max77686_clk_probe(struct platform_device *pdev) | ||
147 | { | ||
148 | struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
149 | struct max77686_clk **max77686_clks; | ||
150 | int i, ret; | ||
151 | |||
152 | max77686_clks = devm_kzalloc(&pdev->dev, sizeof(struct max77686_clk *) | ||
153 | * MAX77686_CLKS_NUM, GFP_KERNEL); | ||
154 | if (IS_ERR(max77686_clks)) | ||
155 | return -ENOMEM; | ||
156 | |||
157 | for (i = 0; i < MAX77686_CLKS_NUM; i++) { | ||
158 | max77686_clks[i] = devm_kzalloc(&pdev->dev, | ||
159 | sizeof(struct max77686_clk), GFP_KERNEL); | ||
160 | if (IS_ERR(max77686_clks[i])) | ||
161 | return -ENOMEM; | ||
162 | } | ||
163 | |||
164 | for (i = 0; i < MAX77686_CLKS_NUM; i++) { | ||
165 | max77686_clks[i]->iodev = iodev; | ||
166 | max77686_clks[i]->mask = 1 << i; | ||
167 | max77686_clks[i]->hw.init = &max77686_clks_init[i]; | ||
168 | |||
169 | ret = max77686_clk_register(&pdev->dev, max77686_clks[i]); | ||
170 | if (ret) { | ||
171 | switch (i) { | ||
172 | case MAX77686_CLK_AP: | ||
173 | dev_err(&pdev->dev, "Fail to register CLK_AP\n"); | ||
174 | goto err_clk_ap; | ||
175 | break; | ||
176 | case MAX77686_CLK_CP: | ||
177 | dev_err(&pdev->dev, "Fail to register CLK_CP\n"); | ||
178 | goto err_clk_cp; | ||
179 | break; | ||
180 | case MAX77686_CLK_PMIC: | ||
181 | dev_err(&pdev->dev, "Fail to register CLK_PMIC\n"); | ||
182 | goto err_clk_pmic; | ||
183 | } | ||
184 | } | ||
185 | } | ||
186 | |||
187 | platform_set_drvdata(pdev, max77686_clks); | ||
188 | |||
189 | goto out; | ||
190 | |||
191 | err_clk_pmic: | ||
192 | clkdev_drop(max77686_clks[MAX77686_CLK_CP]->lookup); | ||
193 | kfree(max77686_clks[MAX77686_CLK_CP]->hw.clk); | ||
194 | err_clk_cp: | ||
195 | clkdev_drop(max77686_clks[MAX77686_CLK_AP]->lookup); | ||
196 | kfree(max77686_clks[MAX77686_CLK_AP]->hw.clk); | ||
197 | err_clk_ap: | ||
198 | out: | ||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | static int __devexit max77686_clk_remove(struct platform_device *pdev) | ||
203 | { | ||
204 | struct max77686_clk **max77686_clks = platform_get_drvdata(pdev); | ||
205 | int i; | ||
206 | |||
207 | for (i = 0; i < MAX77686_CLKS_NUM; i++) { | ||
208 | clkdev_drop(max77686_clks[i]->lookup); | ||
209 | kfree(max77686_clks[i]->hw.clk); | ||
210 | } | ||
211 | return 0; | ||
212 | } | ||
213 | |||
214 | static const struct platform_device_id max77686_clk_id[] = { | ||
215 | { "max77686-clk", 0}, | ||
216 | { }, | ||
217 | }; | ||
218 | MODULE_DEVICE_TABLE(platform, max77686_clk_id); | ||
219 | |||
220 | static struct platform_driver max77686_clk_driver = { | ||
221 | .driver = { | ||
222 | .name = "max77686-clk", | ||
223 | .owner = THIS_MODULE, | ||
224 | }, | ||
225 | .probe = max77686_clk_probe, | ||
226 | .remove = __devexit_p(max77686_clk_remove), | ||
227 | .id_table = max77686_clk_id, | ||
228 | }; | ||
229 | |||
230 | static int __init max77686_clk_init(void) | ||
231 | { | ||
232 | return platform_driver_register(&max77686_clk_driver); | ||
233 | } | ||
234 | subsys_initcall(max77686_clk_init); | ||
235 | |||
236 | static void __init max77686_clk_cleanup(void) | ||
237 | { | ||
238 | platform_driver_unregister(&max77686_clk_driver); | ||
239 | } | ||
240 | module_exit(max77686_clk_cleanup); | ||
241 | |||
242 | MODULE_DESCRIPTION("MAXIM 77686 Clock Driver"); | ||
243 | MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>"); | ||
244 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/clk/clk-prima2.c b/drivers/clk/clk-prima2.c new file mode 100644 index 000000000000..517874fa6858 --- /dev/null +++ b/drivers/clk/clk-prima2.c | |||
@@ -0,0 +1,1171 @@ | |||
1 | /* | ||
2 | * Clock tree for CSR SiRFprimaII | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/module.h> | ||
10 | #include <linux/bitops.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/clk.h> | ||
13 | #include <linux/clkdev.h> | ||
14 | #include <linux/clk-provider.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/syscore_ops.h> | ||
17 | |||
18 | #define SIRFSOC_CLKC_CLK_EN0 0x0000 | ||
19 | #define SIRFSOC_CLKC_CLK_EN1 0x0004 | ||
20 | #define SIRFSOC_CLKC_REF_CFG 0x0014 | ||
21 | #define SIRFSOC_CLKC_CPU_CFG 0x0018 | ||
22 | #define SIRFSOC_CLKC_MEM_CFG 0x001c | ||
23 | #define SIRFSOC_CLKC_SYS_CFG 0x0020 | ||
24 | #define SIRFSOC_CLKC_IO_CFG 0x0024 | ||
25 | #define SIRFSOC_CLKC_DSP_CFG 0x0028 | ||
26 | #define SIRFSOC_CLKC_GFX_CFG 0x002c | ||
27 | #define SIRFSOC_CLKC_MM_CFG 0x0030 | ||
28 | #define SIRFSOC_CLKC_LCD_CFG 0x0034 | ||
29 | #define SIRFSOC_CLKC_MMC_CFG 0x0038 | ||
30 | #define SIRFSOC_CLKC_PLL1_CFG0 0x0040 | ||
31 | #define SIRFSOC_CLKC_PLL2_CFG0 0x0044 | ||
32 | #define SIRFSOC_CLKC_PLL3_CFG0 0x0048 | ||
33 | #define SIRFSOC_CLKC_PLL1_CFG1 0x004c | ||
34 | #define SIRFSOC_CLKC_PLL2_CFG1 0x0050 | ||
35 | #define SIRFSOC_CLKC_PLL3_CFG1 0x0054 | ||
36 | #define SIRFSOC_CLKC_PLL1_CFG2 0x0058 | ||
37 | #define SIRFSOC_CLKC_PLL2_CFG2 0x005c | ||
38 | #define SIRFSOC_CLKC_PLL3_CFG2 0x0060 | ||
39 | #define SIRFSOC_USBPHY_PLL_CTRL 0x0008 | ||
40 | #define SIRFSOC_USBPHY_PLL_POWERDOWN BIT(1) | ||
41 | #define SIRFSOC_USBPHY_PLL_BYPASS BIT(2) | ||
42 | #define SIRFSOC_USBPHY_PLL_LOCK BIT(3) | ||
43 | |||
44 | static void *sirfsoc_clk_vbase, *sirfsoc_rsc_vbase; | ||
45 | |||
46 | #define KHZ 1000 | ||
47 | #define MHZ (KHZ * KHZ) | ||
48 | |||
49 | /* | ||
50 | * SiRFprimaII clock controller | ||
51 | * - 2 oscillators: osc-26MHz, rtc-32.768KHz | ||
52 | * - 3 standard configurable plls: pll1, pll2 & pll3 | ||
53 | * - 2 exclusive plls: usb phy pll and sata phy pll | ||
54 | * - 8 clock domains: cpu/cpudiv, mem/memdiv, sys/io, dsp, graphic, multimedia, | ||
55 | * display and sdphy. | ||
56 | * Each clock domain can select its own clock source from five clock sources, | ||
57 | * X_XIN, X_XINW, PLL1, PLL2 and PLL3. The domain clock is used as the source | ||
58 | * clock of the group clock. | ||
59 | * - dsp domain: gps, mf | ||
60 | * - io domain: dmac, nand, audio, uart, i2c, spi, usp, pwm, pulse | ||
61 | * - sys domain: security | ||
62 | */ | ||
63 | |||
64 | struct clk_pll { | ||
65 | struct clk_hw hw; | ||
66 | unsigned short regofs; /* register offset */ | ||
67 | }; | ||
68 | |||
69 | #define to_pllclk(_hw) container_of(_hw, struct clk_pll, hw) | ||
70 | |||
71 | struct clk_dmn { | ||
72 | struct clk_hw hw; | ||
73 | signed char enable_bit; /* enable bit: 0 ~ 63 */ | ||
74 | unsigned short regofs; /* register offset */ | ||
75 | }; | ||
76 | |||
77 | #define to_dmnclk(_hw) container_of(_hw, struct clk_dmn, hw) | ||
78 | |||
79 | struct clk_std { | ||
80 | struct clk_hw hw; | ||
81 | signed char enable_bit; /* enable bit: 0 ~ 63 */ | ||
82 | }; | ||
83 | |||
84 | #define to_stdclk(_hw) container_of(_hw, struct clk_std, hw) | ||
85 | |||
86 | static int std_clk_is_enabled(struct clk_hw *hw); | ||
87 | static int std_clk_enable(struct clk_hw *hw); | ||
88 | static void std_clk_disable(struct clk_hw *hw); | ||
89 | |||
90 | static inline unsigned long clkc_readl(unsigned reg) | ||
91 | { | ||
92 | return readl(sirfsoc_clk_vbase + reg); | ||
93 | } | ||
94 | |||
95 | static inline void clkc_writel(u32 val, unsigned reg) | ||
96 | { | ||
97 | writel(val, sirfsoc_clk_vbase + reg); | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * std pll | ||
102 | */ | ||
103 | |||
104 | static unsigned long pll_clk_recalc_rate(struct clk_hw *hw, | ||
105 | unsigned long parent_rate) | ||
106 | { | ||
107 | unsigned long fin = parent_rate; | ||
108 | struct clk_pll *clk = to_pllclk(hw); | ||
109 | u32 regcfg2 = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - | ||
110 | SIRFSOC_CLKC_PLL1_CFG0; | ||
111 | |||
112 | if (clkc_readl(regcfg2) & BIT(2)) { | ||
113 | /* pll bypass mode */ | ||
114 | return fin; | ||
115 | } else { | ||
116 | /* fout = fin * nf / nr / od */ | ||
117 | u32 cfg0 = clkc_readl(clk->regofs); | ||
118 | u32 nf = (cfg0 & (BIT(13) - 1)) + 1; | ||
119 | u32 nr = ((cfg0 >> 13) & (BIT(6) - 1)) + 1; | ||
120 | u32 od = ((cfg0 >> 19) & (BIT(4) - 1)) + 1; | ||
121 | WARN_ON(fin % MHZ); | ||
122 | return fin / MHZ * nf / nr / od * MHZ; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | static long pll_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
127 | unsigned long *parent_rate) | ||
128 | { | ||
129 | unsigned long fin, nf, nr, od; | ||
130 | |||
131 | /* | ||
132 | * fout = fin * nf / (nr * od); | ||
133 | * set od = 1, nr = fin/MHz, so fout = nf * MHz | ||
134 | */ | ||
135 | rate = rate - rate % MHZ; | ||
136 | |||
137 | nf = rate / MHZ; | ||
138 | if (nf > BIT(13)) | ||
139 | nf = BIT(13); | ||
140 | if (nf < 1) | ||
141 | nf = 1; | ||
142 | |||
143 | fin = *parent_rate; | ||
144 | |||
145 | nr = fin / MHZ; | ||
146 | if (nr > BIT(6)) | ||
147 | nr = BIT(6); | ||
148 | od = 1; | ||
149 | |||
150 | return fin * nf / (nr * od); | ||
151 | } | ||
152 | |||
153 | static int pll_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
154 | unsigned long parent_rate) | ||
155 | { | ||
156 | struct clk_pll *clk = to_pllclk(hw); | ||
157 | unsigned long fin, nf, nr, od, reg; | ||
158 | |||
159 | /* | ||
160 | * fout = fin * nf / (nr * od); | ||
161 | * set od = 1, nr = fin/MHz, so fout = nf * MHz | ||
162 | */ | ||
163 | |||
164 | nf = rate / MHZ; | ||
165 | if (unlikely((rate % MHZ) || nf > BIT(13) || nf < 1)) | ||
166 | return -EINVAL; | ||
167 | |||
168 | fin = parent_rate; | ||
169 | BUG_ON(fin < MHZ); | ||
170 | |||
171 | nr = fin / MHZ; | ||
172 | BUG_ON((fin % MHZ) || nr > BIT(6)); | ||
173 | |||
174 | od = 1; | ||
175 | |||
176 | reg = (nf - 1) | ((nr - 1) << 13) | ((od - 1) << 19); | ||
177 | clkc_writel(reg, clk->regofs); | ||
178 | |||
179 | reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG1 - SIRFSOC_CLKC_PLL1_CFG0; | ||
180 | clkc_writel((nf >> 1) - 1, reg); | ||
181 | |||
182 | reg = clk->regofs + SIRFSOC_CLKC_PLL1_CFG2 - SIRFSOC_CLKC_PLL1_CFG0; | ||
183 | while (!(clkc_readl(reg) & BIT(6))) | ||
184 | cpu_relax(); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | static struct clk_ops std_pll_ops = { | ||
190 | .recalc_rate = pll_clk_recalc_rate, | ||
191 | .round_rate = pll_clk_round_rate, | ||
192 | .set_rate = pll_clk_set_rate, | ||
193 | }; | ||
194 | |||
195 | static const char *pll_clk_parents[] = { | ||
196 | "osc", | ||
197 | }; | ||
198 | |||
199 | static struct clk_init_data clk_pll1_init = { | ||
200 | .name = "pll1", | ||
201 | .ops = &std_pll_ops, | ||
202 | .parent_names = pll_clk_parents, | ||
203 | .num_parents = ARRAY_SIZE(pll_clk_parents), | ||
204 | }; | ||
205 | |||
206 | static struct clk_init_data clk_pll2_init = { | ||
207 | .name = "pll2", | ||
208 | .ops = &std_pll_ops, | ||
209 | .parent_names = pll_clk_parents, | ||
210 | .num_parents = ARRAY_SIZE(pll_clk_parents), | ||
211 | }; | ||
212 | |||
213 | static struct clk_init_data clk_pll3_init = { | ||
214 | .name = "pll3", | ||
215 | .ops = &std_pll_ops, | ||
216 | .parent_names = pll_clk_parents, | ||
217 | .num_parents = ARRAY_SIZE(pll_clk_parents), | ||
218 | }; | ||
219 | |||
220 | static struct clk_pll clk_pll1 = { | ||
221 | .regofs = SIRFSOC_CLKC_PLL1_CFG0, | ||
222 | .hw = { | ||
223 | .init = &clk_pll1_init, | ||
224 | }, | ||
225 | }; | ||
226 | |||
227 | static struct clk_pll clk_pll2 = { | ||
228 | .regofs = SIRFSOC_CLKC_PLL2_CFG0, | ||
229 | .hw = { | ||
230 | .init = &clk_pll2_init, | ||
231 | }, | ||
232 | }; | ||
233 | |||
234 | static struct clk_pll clk_pll3 = { | ||
235 | .regofs = SIRFSOC_CLKC_PLL3_CFG0, | ||
236 | .hw = { | ||
237 | .init = &clk_pll3_init, | ||
238 | }, | ||
239 | }; | ||
240 | |||
241 | /* | ||
242 | * usb uses specified pll | ||
243 | */ | ||
244 | |||
245 | static int usb_pll_clk_enable(struct clk_hw *hw) | ||
246 | { | ||
247 | u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL); | ||
248 | reg &= ~(SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS); | ||
249 | writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL); | ||
250 | while (!(readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL) & | ||
251 | SIRFSOC_USBPHY_PLL_LOCK)) | ||
252 | cpu_relax(); | ||
253 | |||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static void usb_pll_clk_disable(struct clk_hw *clk) | ||
258 | { | ||
259 | u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL); | ||
260 | reg |= (SIRFSOC_USBPHY_PLL_POWERDOWN | SIRFSOC_USBPHY_PLL_BYPASS); | ||
261 | writel(reg, sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL); | ||
262 | } | ||
263 | |||
264 | static unsigned long usb_pll_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) | ||
265 | { | ||
266 | u32 reg = readl(sirfsoc_rsc_vbase + SIRFSOC_USBPHY_PLL_CTRL); | ||
267 | return (reg & SIRFSOC_USBPHY_PLL_BYPASS) ? parent_rate : 48*MHZ; | ||
268 | } | ||
269 | |||
270 | static struct clk_ops usb_pll_ops = { | ||
271 | .enable = usb_pll_clk_enable, | ||
272 | .disable = usb_pll_clk_disable, | ||
273 | .recalc_rate = usb_pll_clk_recalc_rate, | ||
274 | }; | ||
275 | |||
276 | static struct clk_init_data clk_usb_pll_init = { | ||
277 | .name = "usb_pll", | ||
278 | .ops = &usb_pll_ops, | ||
279 | .parent_names = pll_clk_parents, | ||
280 | .num_parents = ARRAY_SIZE(pll_clk_parents), | ||
281 | }; | ||
282 | |||
283 | static struct clk_hw usb_pll_clk_hw = { | ||
284 | .init = &clk_usb_pll_init, | ||
285 | }; | ||
286 | |||
287 | /* | ||
288 | * clock domains - cpu, mem, sys/io, dsp, gfx | ||
289 | */ | ||
290 | |||
291 | static const char *dmn_clk_parents[] = { | ||
292 | "rtc", | ||
293 | "osc", | ||
294 | "pll1", | ||
295 | "pll2", | ||
296 | "pll3", | ||
297 | }; | ||
298 | |||
299 | static u8 dmn_clk_get_parent(struct clk_hw *hw) | ||
300 | { | ||
301 | struct clk_dmn *clk = to_dmnclk(hw); | ||
302 | u32 cfg = clkc_readl(clk->regofs); | ||
303 | |||
304 | /* parent of io domain can only be pll3 */ | ||
305 | if (strcmp(hw->init->name, "io") == 0) | ||
306 | return 4; | ||
307 | |||
308 | WARN_ON((cfg & (BIT(3) - 1)) > 4); | ||
309 | |||
310 | return cfg & (BIT(3) - 1); | ||
311 | } | ||
312 | |||
313 | static int dmn_clk_set_parent(struct clk_hw *hw, u8 parent) | ||
314 | { | ||
315 | struct clk_dmn *clk = to_dmnclk(hw); | ||
316 | u32 cfg = clkc_readl(clk->regofs); | ||
317 | |||
318 | /* parent of io domain can only be pll3 */ | ||
319 | if (strcmp(hw->init->name, "io") == 0) | ||
320 | return -EINVAL; | ||
321 | |||
322 | cfg &= ~(BIT(3) - 1); | ||
323 | clkc_writel(cfg | parent, clk->regofs); | ||
324 | /* BIT(3) - switching status: 1 - busy, 0 - done */ | ||
325 | while (clkc_readl(clk->regofs) & BIT(3)) | ||
326 | cpu_relax(); | ||
327 | |||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | static unsigned long dmn_clk_recalc_rate(struct clk_hw *hw, | ||
332 | unsigned long parent_rate) | ||
333 | |||
334 | { | ||
335 | unsigned long fin = parent_rate; | ||
336 | struct clk_dmn *clk = to_dmnclk(hw); | ||
337 | |||
338 | u32 cfg = clkc_readl(clk->regofs); | ||
339 | |||
340 | if (cfg & BIT(24)) { | ||
341 | /* fcd bypass mode */ | ||
342 | return fin; | ||
343 | } else { | ||
344 | /* | ||
345 | * wait count: bit[19:16], hold count: bit[23:20] | ||
346 | */ | ||
347 | u32 wait = (cfg >> 16) & (BIT(4) - 1); | ||
348 | u32 hold = (cfg >> 20) & (BIT(4) - 1); | ||
349 | |||
350 | return fin / (wait + hold + 2); | ||
351 | } | ||
352 | } | ||
353 | |||
354 | static long dmn_clk_round_rate(struct clk_hw *hw, unsigned long rate, | ||
355 | unsigned long *parent_rate) | ||
356 | { | ||
357 | unsigned long fin; | ||
358 | unsigned ratio, wait, hold; | ||
359 | unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4; | ||
360 | |||
361 | fin = *parent_rate; | ||
362 | ratio = fin / rate; | ||
363 | |||
364 | if (ratio < 2) | ||
365 | ratio = 2; | ||
366 | if (ratio > BIT(bits + 1)) | ||
367 | ratio = BIT(bits + 1); | ||
368 | |||
369 | wait = (ratio >> 1) - 1; | ||
370 | hold = ratio - wait - 2; | ||
371 | |||
372 | return fin / (wait + hold + 2); | ||
373 | } | ||
374 | |||
375 | static int dmn_clk_set_rate(struct clk_hw *hw, unsigned long rate, | ||
376 | unsigned long parent_rate) | ||
377 | { | ||
378 | struct clk_dmn *clk = to_dmnclk(hw); | ||
379 | unsigned long fin; | ||
380 | unsigned ratio, wait, hold, reg; | ||
381 | unsigned bits = (strcmp(hw->init->name, "mem") == 0) ? 3 : 4; | ||
382 | |||
383 | fin = parent_rate; | ||
384 | ratio = fin / rate; | ||
385 | |||
386 | if (unlikely(ratio < 2 || ratio > BIT(bits + 1))) | ||
387 | return -EINVAL; | ||
388 | |||
389 | WARN_ON(fin % rate); | ||
390 | |||
391 | wait = (ratio >> 1) - 1; | ||
392 | hold = ratio - wait - 2; | ||
393 | |||
394 | reg = clkc_readl(clk->regofs); | ||
395 | reg &= ~(((BIT(bits) - 1) << 16) | ((BIT(bits) - 1) << 20)); | ||
396 | reg |= (wait << 16) | (hold << 20) | BIT(25); | ||
397 | clkc_writel(reg, clk->regofs); | ||
398 | |||
399 | /* waiting FCD been effective */ | ||
400 | while (clkc_readl(clk->regofs) & BIT(25)) | ||
401 | cpu_relax(); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static struct clk_ops msi_ops = { | ||
407 | .set_rate = dmn_clk_set_rate, | ||
408 | .round_rate = dmn_clk_round_rate, | ||
409 | .recalc_rate = dmn_clk_recalc_rate, | ||
410 | .set_parent = dmn_clk_set_parent, | ||
411 | .get_parent = dmn_clk_get_parent, | ||
412 | }; | ||
413 | |||
414 | static struct clk_init_data clk_mem_init = { | ||
415 | .name = "mem", | ||
416 | .ops = &msi_ops, | ||
417 | .parent_names = dmn_clk_parents, | ||
418 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
419 | }; | ||
420 | |||
421 | static struct clk_dmn clk_mem = { | ||
422 | .regofs = SIRFSOC_CLKC_MEM_CFG, | ||
423 | .hw = { | ||
424 | .init = &clk_mem_init, | ||
425 | }, | ||
426 | }; | ||
427 | |||
428 | static struct clk_init_data clk_sys_init = { | ||
429 | .name = "sys", | ||
430 | .ops = &msi_ops, | ||
431 | .parent_names = dmn_clk_parents, | ||
432 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
433 | .flags = CLK_SET_RATE_GATE, | ||
434 | }; | ||
435 | |||
436 | static struct clk_dmn clk_sys = { | ||
437 | .regofs = SIRFSOC_CLKC_SYS_CFG, | ||
438 | .hw = { | ||
439 | .init = &clk_sys_init, | ||
440 | }, | ||
441 | }; | ||
442 | |||
443 | static struct clk_init_data clk_io_init = { | ||
444 | .name = "io", | ||
445 | .ops = &msi_ops, | ||
446 | .parent_names = dmn_clk_parents, | ||
447 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
448 | }; | ||
449 | |||
450 | static struct clk_dmn clk_io = { | ||
451 | .regofs = SIRFSOC_CLKC_IO_CFG, | ||
452 | .hw = { | ||
453 | .init = &clk_io_init, | ||
454 | }, | ||
455 | }; | ||
456 | |||
457 | static struct clk_ops cpu_ops = { | ||
458 | .set_parent = dmn_clk_set_parent, | ||
459 | .get_parent = dmn_clk_get_parent, | ||
460 | }; | ||
461 | |||
462 | static struct clk_init_data clk_cpu_init = { | ||
463 | .name = "cpu", | ||
464 | .ops = &cpu_ops, | ||
465 | .parent_names = dmn_clk_parents, | ||
466 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
467 | .flags = CLK_SET_RATE_PARENT, | ||
468 | }; | ||
469 | |||
470 | static struct clk_dmn clk_cpu = { | ||
471 | .regofs = SIRFSOC_CLKC_CPU_CFG, | ||
472 | .hw = { | ||
473 | .init = &clk_cpu_init, | ||
474 | }, | ||
475 | }; | ||
476 | |||
477 | static struct clk_ops dmn_ops = { | ||
478 | .is_enabled = std_clk_is_enabled, | ||
479 | .enable = std_clk_enable, | ||
480 | .disable = std_clk_disable, | ||
481 | .set_rate = dmn_clk_set_rate, | ||
482 | .round_rate = dmn_clk_round_rate, | ||
483 | .recalc_rate = dmn_clk_recalc_rate, | ||
484 | .set_parent = dmn_clk_set_parent, | ||
485 | .get_parent = dmn_clk_get_parent, | ||
486 | }; | ||
487 | |||
488 | /* dsp, gfx, mm, lcd and vpp domain */ | ||
489 | |||
490 | static struct clk_init_data clk_dsp_init = { | ||
491 | .name = "dsp", | ||
492 | .ops = &dmn_ops, | ||
493 | .parent_names = dmn_clk_parents, | ||
494 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
495 | }; | ||
496 | |||
497 | static struct clk_dmn clk_dsp = { | ||
498 | .regofs = SIRFSOC_CLKC_DSP_CFG, | ||
499 | .enable_bit = 0, | ||
500 | .hw = { | ||
501 | .init = &clk_dsp_init, | ||
502 | }, | ||
503 | }; | ||
504 | |||
505 | static struct clk_init_data clk_gfx_init = { | ||
506 | .name = "gfx", | ||
507 | .ops = &dmn_ops, | ||
508 | .parent_names = dmn_clk_parents, | ||
509 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
510 | }; | ||
511 | |||
512 | static struct clk_dmn clk_gfx = { | ||
513 | .regofs = SIRFSOC_CLKC_GFX_CFG, | ||
514 | .enable_bit = 8, | ||
515 | .hw = { | ||
516 | .init = &clk_gfx_init, | ||
517 | }, | ||
518 | }; | ||
519 | |||
520 | static struct clk_init_data clk_mm_init = { | ||
521 | .name = "mm", | ||
522 | .ops = &dmn_ops, | ||
523 | .parent_names = dmn_clk_parents, | ||
524 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
525 | }; | ||
526 | |||
527 | static struct clk_dmn clk_mm = { | ||
528 | .regofs = SIRFSOC_CLKC_MM_CFG, | ||
529 | .enable_bit = 9, | ||
530 | .hw = { | ||
531 | .init = &clk_mm_init, | ||
532 | }, | ||
533 | }; | ||
534 | |||
535 | static struct clk_init_data clk_lcd_init = { | ||
536 | .name = "lcd", | ||
537 | .ops = &dmn_ops, | ||
538 | .parent_names = dmn_clk_parents, | ||
539 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
540 | }; | ||
541 | |||
542 | static struct clk_dmn clk_lcd = { | ||
543 | .regofs = SIRFSOC_CLKC_LCD_CFG, | ||
544 | .enable_bit = 10, | ||
545 | .hw = { | ||
546 | .init = &clk_lcd_init, | ||
547 | }, | ||
548 | }; | ||
549 | |||
550 | static struct clk_init_data clk_vpp_init = { | ||
551 | .name = "vpp", | ||
552 | .ops = &dmn_ops, | ||
553 | .parent_names = dmn_clk_parents, | ||
554 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
555 | }; | ||
556 | |||
557 | static struct clk_dmn clk_vpp = { | ||
558 | .regofs = SIRFSOC_CLKC_LCD_CFG, | ||
559 | .enable_bit = 11, | ||
560 | .hw = { | ||
561 | .init = &clk_vpp_init, | ||
562 | }, | ||
563 | }; | ||
564 | |||
565 | static struct clk_init_data clk_mmc01_init = { | ||
566 | .name = "mmc01", | ||
567 | .ops = &dmn_ops, | ||
568 | .parent_names = dmn_clk_parents, | ||
569 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
570 | }; | ||
571 | |||
572 | static struct clk_dmn clk_mmc01 = { | ||
573 | .regofs = SIRFSOC_CLKC_MMC_CFG, | ||
574 | .enable_bit = 59, | ||
575 | .hw = { | ||
576 | .init = &clk_mmc01_init, | ||
577 | }, | ||
578 | }; | ||
579 | |||
580 | static struct clk_init_data clk_mmc23_init = { | ||
581 | .name = "mmc23", | ||
582 | .ops = &dmn_ops, | ||
583 | .parent_names = dmn_clk_parents, | ||
584 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
585 | }; | ||
586 | |||
587 | static struct clk_dmn clk_mmc23 = { | ||
588 | .regofs = SIRFSOC_CLKC_MMC_CFG, | ||
589 | .enable_bit = 60, | ||
590 | .hw = { | ||
591 | .init = &clk_mmc23_init, | ||
592 | }, | ||
593 | }; | ||
594 | |||
595 | static struct clk_init_data clk_mmc45_init = { | ||
596 | .name = "mmc45", | ||
597 | .ops = &dmn_ops, | ||
598 | .parent_names = dmn_clk_parents, | ||
599 | .num_parents = ARRAY_SIZE(dmn_clk_parents), | ||
600 | }; | ||
601 | |||
602 | static struct clk_dmn clk_mmc45 = { | ||
603 | .regofs = SIRFSOC_CLKC_MMC_CFG, | ||
604 | .enable_bit = 61, | ||
605 | .hw = { | ||
606 | .init = &clk_mmc45_init, | ||
607 | }, | ||
608 | }; | ||
609 | |||
610 | /* | ||
611 | * peripheral controllers in io domain | ||
612 | */ | ||
613 | |||
614 | static int std_clk_is_enabled(struct clk_hw *hw) | ||
615 | { | ||
616 | u32 reg; | ||
617 | int bit; | ||
618 | struct clk_std *clk = to_stdclk(hw); | ||
619 | |||
620 | bit = clk->enable_bit % 32; | ||
621 | reg = clk->enable_bit / 32; | ||
622 | reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg); | ||
623 | |||
624 | return !!(clkc_readl(reg) & BIT(bit)); | ||
625 | } | ||
626 | |||
627 | static int std_clk_enable(struct clk_hw *hw) | ||
628 | { | ||
629 | u32 val, reg; | ||
630 | int bit; | ||
631 | struct clk_std *clk = to_stdclk(hw); | ||
632 | |||
633 | BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63); | ||
634 | |||
635 | bit = clk->enable_bit % 32; | ||
636 | reg = clk->enable_bit / 32; | ||
637 | reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg); | ||
638 | |||
639 | val = clkc_readl(reg) | BIT(bit); | ||
640 | clkc_writel(val, reg); | ||
641 | return 0; | ||
642 | } | ||
643 | |||
644 | static void std_clk_disable(struct clk_hw *hw) | ||
645 | { | ||
646 | u32 val, reg; | ||
647 | int bit; | ||
648 | struct clk_std *clk = to_stdclk(hw); | ||
649 | |||
650 | BUG_ON(clk->enable_bit < 0 || clk->enable_bit > 63); | ||
651 | |||
652 | bit = clk->enable_bit % 32; | ||
653 | reg = clk->enable_bit / 32; | ||
654 | reg = SIRFSOC_CLKC_CLK_EN0 + reg * sizeof(reg); | ||
655 | |||
656 | val = clkc_readl(reg) & ~BIT(bit); | ||
657 | clkc_writel(val, reg); | ||
658 | } | ||
659 | |||
660 | static const char *std_clk_io_parents[] = { | ||
661 | "io", | ||
662 | }; | ||
663 | |||
664 | static struct clk_ops ios_ops = { | ||
665 | .is_enabled = std_clk_is_enabled, | ||
666 | .enable = std_clk_enable, | ||
667 | .disable = std_clk_disable, | ||
668 | }; | ||
669 | |||
670 | static struct clk_init_data clk_dmac0_init = { | ||
671 | .name = "dmac0", | ||
672 | .ops = &ios_ops, | ||
673 | .parent_names = std_clk_io_parents, | ||
674 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
675 | }; | ||
676 | |||
677 | static struct clk_std clk_dmac0 = { | ||
678 | .enable_bit = 32, | ||
679 | .hw = { | ||
680 | .init = &clk_dmac0_init, | ||
681 | }, | ||
682 | }; | ||
683 | |||
684 | static struct clk_init_data clk_dmac1_init = { | ||
685 | .name = "dmac1", | ||
686 | .ops = &ios_ops, | ||
687 | .parent_names = std_clk_io_parents, | ||
688 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
689 | }; | ||
690 | |||
691 | static struct clk_std clk_dmac1 = { | ||
692 | .enable_bit = 33, | ||
693 | .hw = { | ||
694 | .init = &clk_dmac1_init, | ||
695 | }, | ||
696 | }; | ||
697 | |||
698 | static struct clk_init_data clk_nand_init = { | ||
699 | .name = "nand", | ||
700 | .ops = &ios_ops, | ||
701 | .parent_names = std_clk_io_parents, | ||
702 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
703 | }; | ||
704 | |||
705 | static struct clk_std clk_nand = { | ||
706 | .enable_bit = 34, | ||
707 | .hw = { | ||
708 | .init = &clk_nand_init, | ||
709 | }, | ||
710 | }; | ||
711 | |||
712 | static struct clk_init_data clk_audio_init = { | ||
713 | .name = "audio", | ||
714 | .ops = &ios_ops, | ||
715 | .parent_names = std_clk_io_parents, | ||
716 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
717 | }; | ||
718 | |||
719 | static struct clk_std clk_audio = { | ||
720 | .enable_bit = 35, | ||
721 | .hw = { | ||
722 | .init = &clk_audio_init, | ||
723 | }, | ||
724 | }; | ||
725 | |||
726 | static struct clk_init_data clk_uart0_init = { | ||
727 | .name = "uart0", | ||
728 | .ops = &ios_ops, | ||
729 | .parent_names = std_clk_io_parents, | ||
730 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
731 | }; | ||
732 | |||
733 | static struct clk_std clk_uart0 = { | ||
734 | .enable_bit = 36, | ||
735 | .hw = { | ||
736 | .init = &clk_uart0_init, | ||
737 | }, | ||
738 | }; | ||
739 | |||
740 | static struct clk_init_data clk_uart1_init = { | ||
741 | .name = "uart1", | ||
742 | .ops = &ios_ops, | ||
743 | .parent_names = std_clk_io_parents, | ||
744 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
745 | }; | ||
746 | |||
747 | static struct clk_std clk_uart1 = { | ||
748 | .enable_bit = 37, | ||
749 | .hw = { | ||
750 | .init = &clk_uart1_init, | ||
751 | }, | ||
752 | }; | ||
753 | |||
754 | static struct clk_init_data clk_uart2_init = { | ||
755 | .name = "uart2", | ||
756 | .ops = &ios_ops, | ||
757 | .parent_names = std_clk_io_parents, | ||
758 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
759 | }; | ||
760 | |||
761 | static struct clk_std clk_uart2 = { | ||
762 | .enable_bit = 38, | ||
763 | .hw = { | ||
764 | .init = &clk_uart2_init, | ||
765 | }, | ||
766 | }; | ||
767 | |||
768 | static struct clk_init_data clk_usp0_init = { | ||
769 | .name = "usp0", | ||
770 | .ops = &ios_ops, | ||
771 | .parent_names = std_clk_io_parents, | ||
772 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
773 | }; | ||
774 | |||
775 | static struct clk_std clk_usp0 = { | ||
776 | .enable_bit = 39, | ||
777 | .hw = { | ||
778 | .init = &clk_usp0_init, | ||
779 | }, | ||
780 | }; | ||
781 | |||
782 | static struct clk_init_data clk_usp1_init = { | ||
783 | .name = "usp1", | ||
784 | .ops = &ios_ops, | ||
785 | .parent_names = std_clk_io_parents, | ||
786 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
787 | }; | ||
788 | |||
789 | static struct clk_std clk_usp1 = { | ||
790 | .enable_bit = 40, | ||
791 | .hw = { | ||
792 | .init = &clk_usp1_init, | ||
793 | }, | ||
794 | }; | ||
795 | |||
796 | static struct clk_init_data clk_usp2_init = { | ||
797 | .name = "usp2", | ||
798 | .ops = &ios_ops, | ||
799 | .parent_names = std_clk_io_parents, | ||
800 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
801 | }; | ||
802 | |||
803 | static struct clk_std clk_usp2 = { | ||
804 | .enable_bit = 41, | ||
805 | .hw = { | ||
806 | .init = &clk_usp2_init, | ||
807 | }, | ||
808 | }; | ||
809 | |||
810 | static struct clk_init_data clk_vip_init = { | ||
811 | .name = "vip", | ||
812 | .ops = &ios_ops, | ||
813 | .parent_names = std_clk_io_parents, | ||
814 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
815 | }; | ||
816 | |||
817 | static struct clk_std clk_vip = { | ||
818 | .enable_bit = 42, | ||
819 | .hw = { | ||
820 | .init = &clk_vip_init, | ||
821 | }, | ||
822 | }; | ||
823 | |||
824 | static struct clk_init_data clk_spi0_init = { | ||
825 | .name = "spi0", | ||
826 | .ops = &ios_ops, | ||
827 | .parent_names = std_clk_io_parents, | ||
828 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
829 | }; | ||
830 | |||
831 | static struct clk_std clk_spi0 = { | ||
832 | .enable_bit = 43, | ||
833 | .hw = { | ||
834 | .init = &clk_spi0_init, | ||
835 | }, | ||
836 | }; | ||
837 | |||
838 | static struct clk_init_data clk_spi1_init = { | ||
839 | .name = "spi1", | ||
840 | .ops = &ios_ops, | ||
841 | .parent_names = std_clk_io_parents, | ||
842 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
843 | }; | ||
844 | |||
845 | static struct clk_std clk_spi1 = { | ||
846 | .enable_bit = 44, | ||
847 | .hw = { | ||
848 | .init = &clk_spi1_init, | ||
849 | }, | ||
850 | }; | ||
851 | |||
852 | static struct clk_init_data clk_tsc_init = { | ||
853 | .name = "tsc", | ||
854 | .ops = &ios_ops, | ||
855 | .parent_names = std_clk_io_parents, | ||
856 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
857 | }; | ||
858 | |||
859 | static struct clk_std clk_tsc = { | ||
860 | .enable_bit = 45, | ||
861 | .hw = { | ||
862 | .init = &clk_tsc_init, | ||
863 | }, | ||
864 | }; | ||
865 | |||
866 | static struct clk_init_data clk_i2c0_init = { | ||
867 | .name = "i2c0", | ||
868 | .ops = &ios_ops, | ||
869 | .parent_names = std_clk_io_parents, | ||
870 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
871 | }; | ||
872 | |||
873 | static struct clk_std clk_i2c0 = { | ||
874 | .enable_bit = 46, | ||
875 | .hw = { | ||
876 | .init = &clk_i2c0_init, | ||
877 | }, | ||
878 | }; | ||
879 | |||
880 | static struct clk_init_data clk_i2c1_init = { | ||
881 | .name = "i2c1", | ||
882 | .ops = &ios_ops, | ||
883 | .parent_names = std_clk_io_parents, | ||
884 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
885 | }; | ||
886 | |||
887 | static struct clk_std clk_i2c1 = { | ||
888 | .enable_bit = 47, | ||
889 | .hw = { | ||
890 | .init = &clk_i2c1_init, | ||
891 | }, | ||
892 | }; | ||
893 | |||
894 | static struct clk_init_data clk_pwmc_init = { | ||
895 | .name = "pwmc", | ||
896 | .ops = &ios_ops, | ||
897 | .parent_names = std_clk_io_parents, | ||
898 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
899 | }; | ||
900 | |||
901 | static struct clk_std clk_pwmc = { | ||
902 | .enable_bit = 48, | ||
903 | .hw = { | ||
904 | .init = &clk_pwmc_init, | ||
905 | }, | ||
906 | }; | ||
907 | |||
908 | static struct clk_init_data clk_efuse_init = { | ||
909 | .name = "efuse", | ||
910 | .ops = &ios_ops, | ||
911 | .parent_names = std_clk_io_parents, | ||
912 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
913 | }; | ||
914 | |||
915 | static struct clk_std clk_efuse = { | ||
916 | .enable_bit = 49, | ||
917 | .hw = { | ||
918 | .init = &clk_efuse_init, | ||
919 | }, | ||
920 | }; | ||
921 | |||
922 | static struct clk_init_data clk_pulse_init = { | ||
923 | .name = "pulse", | ||
924 | .ops = &ios_ops, | ||
925 | .parent_names = std_clk_io_parents, | ||
926 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
927 | }; | ||
928 | |||
929 | static struct clk_std clk_pulse = { | ||
930 | .enable_bit = 50, | ||
931 | .hw = { | ||
932 | .init = &clk_pulse_init, | ||
933 | }, | ||
934 | }; | ||
935 | |||
936 | static const char *std_clk_dsp_parents[] = { | ||
937 | "dsp", | ||
938 | }; | ||
939 | |||
940 | static struct clk_init_data clk_gps_init = { | ||
941 | .name = "gps", | ||
942 | .ops = &ios_ops, | ||
943 | .parent_names = std_clk_dsp_parents, | ||
944 | .num_parents = ARRAY_SIZE(std_clk_dsp_parents), | ||
945 | }; | ||
946 | |||
947 | static struct clk_std clk_gps = { | ||
948 | .enable_bit = 1, | ||
949 | .hw = { | ||
950 | .init = &clk_gps_init, | ||
951 | }, | ||
952 | }; | ||
953 | |||
954 | static struct clk_init_data clk_mf_init = { | ||
955 | .name = "mf", | ||
956 | .ops = &ios_ops, | ||
957 | .parent_names = std_clk_io_parents, | ||
958 | .num_parents = ARRAY_SIZE(std_clk_io_parents), | ||
959 | }; | ||
960 | |||
961 | static struct clk_std clk_mf = { | ||
962 | .enable_bit = 2, | ||
963 | .hw = { | ||
964 | .init = &clk_mf_init, | ||
965 | }, | ||
966 | }; | ||
967 | |||
968 | static const char *std_clk_sys_parents[] = { | ||
969 | "sys", | ||
970 | }; | ||
971 | |||
972 | static struct clk_init_data clk_security_init = { | ||
973 | .name = "mf", | ||
974 | .ops = &ios_ops, | ||
975 | .parent_names = std_clk_sys_parents, | ||
976 | .num_parents = ARRAY_SIZE(std_clk_sys_parents), | ||
977 | }; | ||
978 | |||
979 | static struct clk_std clk_security = { | ||
980 | .enable_bit = 19, | ||
981 | .hw = { | ||
982 | .init = &clk_security_init, | ||
983 | }, | ||
984 | }; | ||
985 | |||
986 | static const char *std_clk_usb_parents[] = { | ||
987 | "usb_pll", | ||
988 | }; | ||
989 | |||
990 | static struct clk_init_data clk_usb0_init = { | ||
991 | .name = "usb0", | ||
992 | .ops = &ios_ops, | ||
993 | .parent_names = std_clk_usb_parents, | ||
994 | .num_parents = ARRAY_SIZE(std_clk_usb_parents), | ||
995 | }; | ||
996 | |||
997 | static struct clk_std clk_usb0 = { | ||
998 | .enable_bit = 16, | ||
999 | .hw = { | ||
1000 | .init = &clk_usb0_init, | ||
1001 | }, | ||
1002 | }; | ||
1003 | |||
1004 | static struct clk_init_data clk_usb1_init = { | ||
1005 | .name = "usb1", | ||
1006 | .ops = &ios_ops, | ||
1007 | .parent_names = std_clk_usb_parents, | ||
1008 | .num_parents = ARRAY_SIZE(std_clk_usb_parents), | ||
1009 | }; | ||
1010 | |||
1011 | static struct clk_std clk_usb1 = { | ||
1012 | .enable_bit = 17, | ||
1013 | .hw = { | ||
1014 | .init = &clk_usb1_init, | ||
1015 | }, | ||
1016 | }; | ||
1017 | |||
1018 | static struct of_device_id clkc_ids[] = { | ||
1019 | { .compatible = "sirf,prima2-clkc" }, | ||
1020 | {}, | ||
1021 | }; | ||
1022 | |||
1023 | static struct of_device_id rsc_ids[] = { | ||
1024 | { .compatible = "sirf,prima2-rsc" }, | ||
1025 | {}, | ||
1026 | }; | ||
1027 | |||
1028 | void __init sirfsoc_of_clk_init(void) | ||
1029 | { | ||
1030 | struct clk *clk; | ||
1031 | struct device_node *np; | ||
1032 | |||
1033 | np = of_find_matching_node(NULL, clkc_ids); | ||
1034 | if (!np) | ||
1035 | panic("unable to find compatible clkc node in dtb\n"); | ||
1036 | |||
1037 | sirfsoc_clk_vbase = of_iomap(np, 0); | ||
1038 | if (!sirfsoc_clk_vbase) | ||
1039 | panic("unable to map clkc registers\n"); | ||
1040 | |||
1041 | of_node_put(np); | ||
1042 | |||
1043 | np = of_find_matching_node(NULL, rsc_ids); | ||
1044 | if (!np) | ||
1045 | panic("unable to find compatible rsc node in dtb\n"); | ||
1046 | |||
1047 | sirfsoc_rsc_vbase = of_iomap(np, 0); | ||
1048 | if (!sirfsoc_rsc_vbase) | ||
1049 | panic("unable to map rsc registers\n"); | ||
1050 | |||
1051 | of_node_put(np); | ||
1052 | |||
1053 | |||
1054 | /* These are always available (RTC and 26MHz OSC)*/ | ||
1055 | clk = clk_register_fixed_rate(NULL, "rtc", NULL, | ||
1056 | CLK_IS_ROOT, 32768); | ||
1057 | BUG_ON(!clk); | ||
1058 | clk = clk_register_fixed_rate(NULL, "osc", NULL, | ||
1059 | CLK_IS_ROOT, 26000000); | ||
1060 | BUG_ON(!clk); | ||
1061 | |||
1062 | clk = clk_register(NULL, &clk_pll1.hw); | ||
1063 | BUG_ON(!clk); | ||
1064 | clk = clk_register(NULL, &clk_pll2.hw); | ||
1065 | BUG_ON(!clk); | ||
1066 | clk = clk_register(NULL, &clk_pll3.hw); | ||
1067 | BUG_ON(!clk); | ||
1068 | clk = clk_register(NULL, &clk_mem.hw); | ||
1069 | BUG_ON(!clk); | ||
1070 | clk = clk_register(NULL, &clk_sys.hw); | ||
1071 | BUG_ON(!clk); | ||
1072 | clk = clk_register(NULL, &clk_security.hw); | ||
1073 | BUG_ON(!clk); | ||
1074 | clk_register_clkdev(clk, NULL, "b8030000.security"); | ||
1075 | clk = clk_register(NULL, &clk_dsp.hw); | ||
1076 | BUG_ON(!clk); | ||
1077 | clk = clk_register(NULL, &clk_gps.hw); | ||
1078 | BUG_ON(!clk); | ||
1079 | clk_register_clkdev(clk, NULL, "a8010000.gps"); | ||
1080 | clk = clk_register(NULL, &clk_mf.hw); | ||
1081 | BUG_ON(!clk); | ||
1082 | clk = clk_register(NULL, &clk_io.hw); | ||
1083 | BUG_ON(!clk); | ||
1084 | clk_register_clkdev(clk, NULL, "io"); | ||
1085 | clk = clk_register(NULL, &clk_cpu.hw); | ||
1086 | BUG_ON(!clk); | ||
1087 | clk_register_clkdev(clk, NULL, "cpu"); | ||
1088 | clk = clk_register(NULL, &clk_uart0.hw); | ||
1089 | BUG_ON(!clk); | ||
1090 | clk_register_clkdev(clk, NULL, "b0050000.uart"); | ||
1091 | clk = clk_register(NULL, &clk_uart1.hw); | ||
1092 | BUG_ON(!clk); | ||
1093 | clk_register_clkdev(clk, NULL, "b0060000.uart"); | ||
1094 | clk = clk_register(NULL, &clk_uart2.hw); | ||
1095 | BUG_ON(!clk); | ||
1096 | clk_register_clkdev(clk, NULL, "b0070000.uart"); | ||
1097 | clk = clk_register(NULL, &clk_tsc.hw); | ||
1098 | BUG_ON(!clk); | ||
1099 | clk_register_clkdev(clk, NULL, "b0110000.tsc"); | ||
1100 | clk = clk_register(NULL, &clk_i2c0.hw); | ||
1101 | BUG_ON(!clk); | ||
1102 | clk_register_clkdev(clk, NULL, "b00e0000.i2c"); | ||
1103 | clk = clk_register(NULL, &clk_i2c1.hw); | ||
1104 | BUG_ON(!clk); | ||
1105 | clk_register_clkdev(clk, NULL, "b00f0000.i2c"); | ||
1106 | clk = clk_register(NULL, &clk_spi0.hw); | ||
1107 | BUG_ON(!clk); | ||
1108 | clk_register_clkdev(clk, NULL, "b00d0000.spi"); | ||
1109 | clk = clk_register(NULL, &clk_spi1.hw); | ||
1110 | BUG_ON(!clk); | ||
1111 | clk_register_clkdev(clk, NULL, "b0170000.spi"); | ||
1112 | clk = clk_register(NULL, &clk_pwmc.hw); | ||
1113 | BUG_ON(!clk); | ||
1114 | clk_register_clkdev(clk, NULL, "b0130000.pwm"); | ||
1115 | clk = clk_register(NULL, &clk_efuse.hw); | ||
1116 | BUG_ON(!clk); | ||
1117 | clk_register_clkdev(clk, NULL, "b0140000.efusesys"); | ||
1118 | clk = clk_register(NULL, &clk_pulse.hw); | ||
1119 | BUG_ON(!clk); | ||
1120 | clk_register_clkdev(clk, NULL, "b0150000.pulsec"); | ||
1121 | clk = clk_register(NULL, &clk_dmac0.hw); | ||
1122 | BUG_ON(!clk); | ||
1123 | clk_register_clkdev(clk, NULL, "b00b0000.dma-controller"); | ||
1124 | clk = clk_register(NULL, &clk_dmac1.hw); | ||
1125 | BUG_ON(!clk); | ||
1126 | clk_register_clkdev(clk, NULL, "b0160000.dma-controller"); | ||
1127 | clk = clk_register(NULL, &clk_nand.hw); | ||
1128 | BUG_ON(!clk); | ||
1129 | clk_register_clkdev(clk, NULL, "b0030000.nand"); | ||
1130 | clk = clk_register(NULL, &clk_audio.hw); | ||
1131 | BUG_ON(!clk); | ||
1132 | clk_register_clkdev(clk, NULL, "b0040000.audio"); | ||
1133 | clk = clk_register(NULL, &clk_usp0.hw); | ||
1134 | BUG_ON(!clk); | ||
1135 | clk_register_clkdev(clk, NULL, "b0080000.usp"); | ||
1136 | clk = clk_register(NULL, &clk_usp1.hw); | ||
1137 | BUG_ON(!clk); | ||
1138 | clk_register_clkdev(clk, NULL, "b0090000.usp"); | ||
1139 | clk = clk_register(NULL, &clk_usp2.hw); | ||
1140 | BUG_ON(!clk); | ||
1141 | clk_register_clkdev(clk, NULL, "b00a0000.usp"); | ||
1142 | clk = clk_register(NULL, &clk_vip.hw); | ||
1143 | BUG_ON(!clk); | ||
1144 | clk_register_clkdev(clk, NULL, "b00c0000.vip"); | ||
1145 | clk = clk_register(NULL, &clk_gfx.hw); | ||
1146 | BUG_ON(!clk); | ||
1147 | clk_register_clkdev(clk, NULL, "98000000.graphics"); | ||
1148 | clk = clk_register(NULL, &clk_mm.hw); | ||
1149 | BUG_ON(!clk); | ||
1150 | clk_register_clkdev(clk, NULL, "a0000000.multimedia"); | ||
1151 | clk = clk_register(NULL, &clk_lcd.hw); | ||
1152 | BUG_ON(!clk); | ||
1153 | clk_register_clkdev(clk, NULL, "90010000.display"); | ||
1154 | clk = clk_register(NULL, &clk_vpp.hw); | ||
1155 | BUG_ON(!clk); | ||
1156 | clk_register_clkdev(clk, NULL, "90020000.vpp"); | ||
1157 | clk = clk_register(NULL, &clk_mmc01.hw); | ||
1158 | BUG_ON(!clk); | ||
1159 | clk = clk_register(NULL, &clk_mmc23.hw); | ||
1160 | BUG_ON(!clk); | ||
1161 | clk = clk_register(NULL, &clk_mmc45.hw); | ||
1162 | BUG_ON(!clk); | ||
1163 | clk = clk_register(NULL, &usb_pll_clk_hw); | ||
1164 | BUG_ON(!clk); | ||
1165 | clk = clk_register(NULL, &clk_usb0.hw); | ||
1166 | BUG_ON(!clk); | ||
1167 | clk_register_clkdev(clk, NULL, "b00e0000.usb"); | ||
1168 | clk = clk_register(NULL, &clk_usb1.hw); | ||
1169 | BUG_ON(!clk); | ||
1170 | clk_register_clkdev(clk, NULL, "b00f0000.usb"); | ||
1171 | } | ||
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index efdfd009c270..56e4495ebeb1 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c | |||
@@ -558,25 +558,6 @@ int clk_enable(struct clk *clk) | |||
558 | EXPORT_SYMBOL_GPL(clk_enable); | 558 | EXPORT_SYMBOL_GPL(clk_enable); |
559 | 559 | ||
560 | /** | 560 | /** |
561 | * clk_get_rate - return the rate of clk | ||
562 | * @clk: the clk whose rate is being returned | ||
563 | * | ||
564 | * Simply returns the cached rate of the clk. Does not query the hardware. If | ||
565 | * clk is NULL then returns 0. | ||
566 | */ | ||
567 | unsigned long clk_get_rate(struct clk *clk) | ||
568 | { | ||
569 | unsigned long rate; | ||
570 | |||
571 | mutex_lock(&prepare_lock); | ||
572 | rate = __clk_get_rate(clk); | ||
573 | mutex_unlock(&prepare_lock); | ||
574 | |||
575 | return rate; | ||
576 | } | ||
577 | EXPORT_SYMBOL_GPL(clk_get_rate); | ||
578 | |||
579 | /** | ||
580 | * __clk_round_rate - round the given rate for a clk | 561 | * __clk_round_rate - round the given rate for a clk |
581 | * @clk: round the rate of this clock | 562 | * @clk: round the rate of this clock |
582 | * | 563 | * |
@@ -702,6 +683,30 @@ static void __clk_recalc_rates(struct clk *clk, unsigned long msg) | |||
702 | } | 683 | } |
703 | 684 | ||
704 | /** | 685 | /** |
686 | * clk_get_rate - return the rate of clk | ||
687 | * @clk: the clk whose rate is being returned | ||
688 | * | ||
689 | * Simply returns the cached rate of the clk, unless CLK_GET_RATE_NOCACHE flag | ||
690 | * is set, which means a recalc_rate will be issued. | ||
691 | * If clk is NULL then returns 0. | ||
692 | */ | ||
693 | unsigned long clk_get_rate(struct clk *clk) | ||
694 | { | ||
695 | unsigned long rate; | ||
696 | |||
697 | mutex_lock(&prepare_lock); | ||
698 | |||
699 | if (clk && (clk->flags & CLK_GET_RATE_NOCACHE)) | ||
700 | __clk_recalc_rates(clk, 0); | ||
701 | |||
702 | rate = __clk_get_rate(clk); | ||
703 | mutex_unlock(&prepare_lock); | ||
704 | |||
705 | return rate; | ||
706 | } | ||
707 | EXPORT_SYMBOL_GPL(clk_get_rate); | ||
708 | |||
709 | /** | ||
705 | * __clk_speculate_rates | 710 | * __clk_speculate_rates |
706 | * @clk: first clk in the subtree | 711 | * @clk: first clk in the subtree |
707 | * @parent_rate: the "future" rate of clk's parent | 712 | * @parent_rate: the "future" rate of clk's parent |
@@ -1582,6 +1587,20 @@ struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec, | |||
1582 | } | 1587 | } |
1583 | EXPORT_SYMBOL_GPL(of_clk_src_simple_get); | 1588 | EXPORT_SYMBOL_GPL(of_clk_src_simple_get); |
1584 | 1589 | ||
1590 | struct clk *of_clk_src_onecell_get(struct of_phandle_args *clkspec, void *data) | ||
1591 | { | ||
1592 | struct clk_onecell_data *clk_data = data; | ||
1593 | unsigned int idx = clkspec->args[0]; | ||
1594 | |||
1595 | if (idx >= clk_data->clk_num) { | ||
1596 | pr_err("%s: invalid clock index %d\n", __func__, idx); | ||
1597 | return ERR_PTR(-EINVAL); | ||
1598 | } | ||
1599 | |||
1600 | return clk_data->clks[idx]; | ||
1601 | } | ||
1602 | EXPORT_SYMBOL_GPL(of_clk_src_onecell_get); | ||
1603 | |||
1585 | /** | 1604 | /** |
1586 | * of_clk_add_provider() - Register a clock provider for a node | 1605 | * of_clk_add_provider() - Register a clock provider for a node |
1587 | * @np: Device node pointer associated with clock provider | 1606 | * @np: Device node pointer associated with clock provider |
diff --git a/drivers/clk/mmp/Makefile b/drivers/clk/mmp/Makefile new file mode 100644 index 000000000000..392d78044ce3 --- /dev/null +++ b/drivers/clk/mmp/Makefile | |||
@@ -0,0 +1,9 @@ | |||
1 | # | ||
2 | # Makefile for mmp specific clk | ||
3 | # | ||
4 | |||
5 | obj-y += clk-apbc.o clk-apmu.o clk-frac.o | ||
6 | |||
7 | obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o | ||
8 | obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o | ||
9 | obj-$(CONFIG_CPU_MMP2) += clk-mmp2.o | ||
diff --git a/drivers/clk/mmp/clk-apbc.c b/drivers/clk/mmp/clk-apbc.c new file mode 100644 index 000000000000..d14120eaa71f --- /dev/null +++ b/drivers/clk/mmp/clk-apbc.c | |||
@@ -0,0 +1,152 @@ | |||
1 | /* | ||
2 | * mmp APB clock operation source file | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * Chao Xie <xiechao.mail@gmail.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/slab.h> | ||
18 | |||
19 | #include "clk.h" | ||
20 | |||
21 | /* Common APB clock register bit definitions */ | ||
22 | #define APBC_APBCLK (1 << 0) /* APB Bus Clock Enable */ | ||
23 | #define APBC_FNCLK (1 << 1) /* Functional Clock Enable */ | ||
24 | #define APBC_RST (1 << 2) /* Reset Generation */ | ||
25 | #define APBC_POWER (1 << 7) /* Reset Generation */ | ||
26 | |||
27 | #define to_clk_apbc(hw) container_of(hw, struct clk_apbc, hw) | ||
28 | struct clk_apbc { | ||
29 | struct clk_hw hw; | ||
30 | void __iomem *base; | ||
31 | unsigned int delay; | ||
32 | unsigned int flags; | ||
33 | spinlock_t *lock; | ||
34 | }; | ||
35 | |||
36 | static int clk_apbc_prepare(struct clk_hw *hw) | ||
37 | { | ||
38 | struct clk_apbc *apbc = to_clk_apbc(hw); | ||
39 | unsigned int data; | ||
40 | unsigned long flags = 0; | ||
41 | |||
42 | /* | ||
43 | * It may share same register as MUX clock, | ||
44 | * and it will impact FNCLK enable. Spinlock is needed | ||
45 | */ | ||
46 | if (apbc->lock) | ||
47 | spin_lock_irqsave(apbc->lock, flags); | ||
48 | |||
49 | data = readl_relaxed(apbc->base); | ||
50 | if (apbc->flags & APBC_POWER_CTRL) | ||
51 | data |= APBC_POWER; | ||
52 | data |= APBC_FNCLK; | ||
53 | writel_relaxed(data, apbc->base); | ||
54 | |||
55 | if (apbc->lock) | ||
56 | spin_unlock_irqrestore(apbc->lock, flags); | ||
57 | |||
58 | udelay(apbc->delay); | ||
59 | |||
60 | if (apbc->lock) | ||
61 | spin_lock_irqsave(apbc->lock, flags); | ||
62 | |||
63 | data = readl_relaxed(apbc->base); | ||
64 | data |= APBC_APBCLK; | ||
65 | writel_relaxed(data, apbc->base); | ||
66 | |||
67 | if (apbc->lock) | ||
68 | spin_unlock_irqrestore(apbc->lock, flags); | ||
69 | |||
70 | udelay(apbc->delay); | ||
71 | |||
72 | if (!(apbc->flags & APBC_NO_BUS_CTRL)) { | ||
73 | if (apbc->lock) | ||
74 | spin_lock_irqsave(apbc->lock, flags); | ||
75 | |||
76 | data = readl_relaxed(apbc->base); | ||
77 | data &= ~APBC_RST; | ||
78 | writel_relaxed(data, apbc->base); | ||
79 | |||
80 | if (apbc->lock) | ||
81 | spin_unlock_irqrestore(apbc->lock, flags); | ||
82 | } | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static void clk_apbc_unprepare(struct clk_hw *hw) | ||
88 | { | ||
89 | struct clk_apbc *apbc = to_clk_apbc(hw); | ||
90 | unsigned long data; | ||
91 | unsigned long flags = 0; | ||
92 | |||
93 | if (apbc->lock) | ||
94 | spin_lock_irqsave(apbc->lock, flags); | ||
95 | |||
96 | data = readl_relaxed(apbc->base); | ||
97 | if (apbc->flags & APBC_POWER_CTRL) | ||
98 | data &= ~APBC_POWER; | ||
99 | data &= ~APBC_FNCLK; | ||
100 | writel_relaxed(data, apbc->base); | ||
101 | |||
102 | if (apbc->lock) | ||
103 | spin_unlock_irqrestore(apbc->lock, flags); | ||
104 | |||
105 | udelay(10); | ||
106 | |||
107 | if (apbc->lock) | ||
108 | spin_lock_irqsave(apbc->lock, flags); | ||
109 | |||
110 | data = readl_relaxed(apbc->base); | ||
111 | data &= ~APBC_APBCLK; | ||
112 | writel_relaxed(data, apbc->base); | ||
113 | |||
114 | if (apbc->lock) | ||
115 | spin_unlock_irqrestore(apbc->lock, flags); | ||
116 | } | ||
117 | |||
118 | struct clk_ops clk_apbc_ops = { | ||
119 | .prepare = clk_apbc_prepare, | ||
120 | .unprepare = clk_apbc_unprepare, | ||
121 | }; | ||
122 | |||
123 | struct clk *mmp_clk_register_apbc(const char *name, const char *parent_name, | ||
124 | void __iomem *base, unsigned int delay, | ||
125 | unsigned int apbc_flags, spinlock_t *lock) | ||
126 | { | ||
127 | struct clk_apbc *apbc; | ||
128 | struct clk *clk; | ||
129 | struct clk_init_data init; | ||
130 | |||
131 | apbc = kzalloc(sizeof(*apbc), GFP_KERNEL); | ||
132 | if (!apbc) | ||
133 | return NULL; | ||
134 | |||
135 | init.name = name; | ||
136 | init.ops = &clk_apbc_ops; | ||
137 | init.flags = CLK_SET_RATE_PARENT; | ||
138 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
139 | init.num_parents = (parent_name ? 1 : 0); | ||
140 | |||
141 | apbc->base = base; | ||
142 | apbc->delay = delay; | ||
143 | apbc->flags = apbc_flags; | ||
144 | apbc->lock = lock; | ||
145 | apbc->hw.init = &init; | ||
146 | |||
147 | clk = clk_register(NULL, &apbc->hw); | ||
148 | if (IS_ERR(clk)) | ||
149 | kfree(apbc); | ||
150 | |||
151 | return clk; | ||
152 | } | ||
diff --git a/drivers/clk/mmp/clk-apmu.c b/drivers/clk/mmp/clk-apmu.c new file mode 100644 index 000000000000..abe182b2377f --- /dev/null +++ b/drivers/clk/mmp/clk-apmu.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * mmp AXI peripharal clock operation source file | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * Chao Xie <xiechao.mail@gmail.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/slab.h> | ||
18 | |||
19 | #include "clk.h" | ||
20 | |||
21 | #define to_clk_apmu(clk) (container_of(clk, struct clk_apmu, clk)) | ||
22 | struct clk_apmu { | ||
23 | struct clk_hw hw; | ||
24 | void __iomem *base; | ||
25 | u32 rst_mask; | ||
26 | u32 enable_mask; | ||
27 | spinlock_t *lock; | ||
28 | }; | ||
29 | |||
30 | static int clk_apmu_enable(struct clk_hw *hw) | ||
31 | { | ||
32 | struct clk_apmu *apmu = to_clk_apmu(hw); | ||
33 | unsigned long data; | ||
34 | unsigned long flags = 0; | ||
35 | |||
36 | if (apmu->lock) | ||
37 | spin_lock_irqsave(apmu->lock, flags); | ||
38 | |||
39 | data = readl_relaxed(apmu->base) | apmu->enable_mask; | ||
40 | writel_relaxed(data, apmu->base); | ||
41 | |||
42 | if (apmu->lock) | ||
43 | spin_unlock_irqrestore(apmu->lock, flags); | ||
44 | |||
45 | return 0; | ||
46 | } | ||
47 | |||
48 | static void clk_apmu_disable(struct clk_hw *hw) | ||
49 | { | ||
50 | struct clk_apmu *apmu = to_clk_apmu(hw); | ||
51 | unsigned long data; | ||
52 | unsigned long flags = 0; | ||
53 | |||
54 | if (apmu->lock) | ||
55 | spin_lock_irqsave(apmu->lock, flags); | ||
56 | |||
57 | data = readl_relaxed(apmu->base) & ~apmu->enable_mask; | ||
58 | writel_relaxed(data, apmu->base); | ||
59 | |||
60 | if (apmu->lock) | ||
61 | spin_unlock_irqrestore(apmu->lock, flags); | ||
62 | } | ||
63 | |||
64 | struct clk_ops clk_apmu_ops = { | ||
65 | .enable = clk_apmu_enable, | ||
66 | .disable = clk_apmu_disable, | ||
67 | }; | ||
68 | |||
69 | struct clk *mmp_clk_register_apmu(const char *name, const char *parent_name, | ||
70 | void __iomem *base, u32 enable_mask, spinlock_t *lock) | ||
71 | { | ||
72 | struct clk_apmu *apmu; | ||
73 | struct clk *clk; | ||
74 | struct clk_init_data init; | ||
75 | |||
76 | apmu = kzalloc(sizeof(*apmu), GFP_KERNEL); | ||
77 | if (!apmu) | ||
78 | return NULL; | ||
79 | |||
80 | init.name = name; | ||
81 | init.ops = &clk_apmu_ops; | ||
82 | init.flags = CLK_SET_RATE_PARENT; | ||
83 | init.parent_names = (parent_name ? &parent_name : NULL); | ||
84 | init.num_parents = (parent_name ? 1 : 0); | ||
85 | |||
86 | apmu->base = base; | ||
87 | apmu->enable_mask = enable_mask; | ||
88 | apmu->lock = lock; | ||
89 | apmu->hw.init = &init; | ||
90 | |||
91 | clk = clk_register(NULL, &apmu->hw); | ||
92 | |||
93 | if (IS_ERR(clk)) | ||
94 | kfree(apmu); | ||
95 | |||
96 | return clk; | ||
97 | } | ||
diff --git a/drivers/clk/mmp/clk-frac.c b/drivers/clk/mmp/clk-frac.c new file mode 100644 index 000000000000..80c1dd15d15c --- /dev/null +++ b/drivers/clk/mmp/clk-frac.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * mmp factor clock operation source file | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * Chao Xie <xiechao.mail@gmail.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/err.h> | ||
16 | |||
17 | #include "clk.h" | ||
18 | /* | ||
19 | * It is M/N clock | ||
20 | * | ||
21 | * Fout from synthesizer can be given from two equations: | ||
22 | * numerator/denominator = Fin / (Fout * factor) | ||
23 | */ | ||
24 | |||
25 | #define to_clk_factor(hw) container_of(hw, struct clk_factor, hw) | ||
26 | struct clk_factor { | ||
27 | struct clk_hw hw; | ||
28 | void __iomem *base; | ||
29 | struct clk_factor_masks *masks; | ||
30 | struct clk_factor_tbl *ftbl; | ||
31 | unsigned int ftbl_cnt; | ||
32 | }; | ||
33 | |||
34 | static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate, | ||
35 | unsigned long *prate) | ||
36 | { | ||
37 | struct clk_factor *factor = to_clk_factor(hw); | ||
38 | unsigned long rate = 0, prev_rate; | ||
39 | int i; | ||
40 | |||
41 | for (i = 0; i < factor->ftbl_cnt; i++) { | ||
42 | prev_rate = rate; | ||
43 | rate = (((*prate / 10000) * factor->ftbl[i].num) / | ||
44 | (factor->ftbl[i].den * factor->masks->factor)) * 10000; | ||
45 | if (rate > drate) | ||
46 | break; | ||
47 | } | ||
48 | if (i == 0) | ||
49 | return rate; | ||
50 | else | ||
51 | return prev_rate; | ||
52 | } | ||
53 | |||
54 | static unsigned long clk_factor_recalc_rate(struct clk_hw *hw, | ||
55 | unsigned long parent_rate) | ||
56 | { | ||
57 | struct clk_factor *factor = to_clk_factor(hw); | ||
58 | struct clk_factor_masks *masks = factor->masks; | ||
59 | unsigned int val, num, den; | ||
60 | |||
61 | val = readl_relaxed(factor->base); | ||
62 | |||
63 | /* calculate numerator */ | ||
64 | num = (val >> masks->num_shift) & masks->num_mask; | ||
65 | |||
66 | /* calculate denominator */ | ||
67 | den = (val >> masks->den_shift) & masks->num_mask; | ||
68 | |||
69 | if (!den) | ||
70 | return 0; | ||
71 | |||
72 | return (((parent_rate / 10000) * den) / | ||
73 | (num * factor->masks->factor)) * 10000; | ||
74 | } | ||
75 | |||
76 | /* Configures new clock rate*/ | ||
77 | static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate, | ||
78 | unsigned long prate) | ||
79 | { | ||
80 | struct clk_factor *factor = to_clk_factor(hw); | ||
81 | struct clk_factor_masks *masks = factor->masks; | ||
82 | int i; | ||
83 | unsigned long val; | ||
84 | unsigned long prev_rate, rate = 0; | ||
85 | |||
86 | for (i = 0; i < factor->ftbl_cnt; i++) { | ||
87 | prev_rate = rate; | ||
88 | rate = (((prate / 10000) * factor->ftbl[i].num) / | ||
89 | (factor->ftbl[i].den * factor->masks->factor)) * 10000; | ||
90 | if (rate > drate) | ||
91 | break; | ||
92 | } | ||
93 | if (i > 0) | ||
94 | i--; | ||
95 | |||
96 | val = readl_relaxed(factor->base); | ||
97 | |||
98 | val &= ~(masks->num_mask << masks->num_shift); | ||
99 | val |= (factor->ftbl[i].num & masks->num_mask) << masks->num_shift; | ||
100 | |||
101 | val &= ~(masks->den_mask << masks->den_shift); | ||
102 | val |= (factor->ftbl[i].den & masks->den_mask) << masks->den_shift; | ||
103 | |||
104 | writel_relaxed(val, factor->base); | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static struct clk_ops clk_factor_ops = { | ||
110 | .recalc_rate = clk_factor_recalc_rate, | ||
111 | .round_rate = clk_factor_round_rate, | ||
112 | .set_rate = clk_factor_set_rate, | ||
113 | }; | ||
114 | |||
115 | struct clk *mmp_clk_register_factor(const char *name, const char *parent_name, | ||
116 | unsigned long flags, void __iomem *base, | ||
117 | struct clk_factor_masks *masks, struct clk_factor_tbl *ftbl, | ||
118 | unsigned int ftbl_cnt) | ||
119 | { | ||
120 | struct clk_factor *factor; | ||
121 | struct clk_init_data init; | ||
122 | struct clk *clk; | ||
123 | |||
124 | if (!masks) { | ||
125 | pr_err("%s: must pass a clk_factor_mask\n", __func__); | ||
126 | return ERR_PTR(-EINVAL); | ||
127 | } | ||
128 | |||
129 | factor = kzalloc(sizeof(*factor), GFP_KERNEL); | ||
130 | if (!factor) { | ||
131 | pr_err("%s: could not allocate factor clk\n", __func__); | ||
132 | return ERR_PTR(-ENOMEM); | ||
133 | } | ||
134 | |||
135 | /* struct clk_aux assignments */ | ||
136 | factor->base = base; | ||
137 | factor->masks = masks; | ||
138 | factor->ftbl = ftbl; | ||
139 | factor->ftbl_cnt = ftbl_cnt; | ||
140 | factor->hw.init = &init; | ||
141 | |||
142 | init.name = name; | ||
143 | init.ops = &clk_factor_ops; | ||
144 | init.flags = flags; | ||
145 | init.parent_names = &parent_name; | ||
146 | init.num_parents = 1; | ||
147 | |||
148 | clk = clk_register(NULL, &factor->hw); | ||
149 | if (IS_ERR_OR_NULL(clk)) | ||
150 | kfree(factor); | ||
151 | |||
152 | return clk; | ||
153 | } | ||
diff --git a/drivers/clk/mmp/clk-mmp2.c b/drivers/clk/mmp/clk-mmp2.c new file mode 100644 index 000000000000..ade435820c7e --- /dev/null +++ b/drivers/clk/mmp/clk-mmp2.c | |||
@@ -0,0 +1,449 @@ | |||
1 | /* | ||
2 | * mmp2 clock framework source file | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * Chao Xie <xiechao.mail@gmail.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/err.h> | ||
18 | |||
19 | #include <mach/addr-map.h> | ||
20 | |||
21 | #include "clk.h" | ||
22 | |||
23 | #define APBC_RTC 0x0 | ||
24 | #define APBC_TWSI0 0x4 | ||
25 | #define APBC_TWSI1 0x8 | ||
26 | #define APBC_TWSI2 0xc | ||
27 | #define APBC_TWSI3 0x10 | ||
28 | #define APBC_TWSI4 0x7c | ||
29 | #define APBC_TWSI5 0x80 | ||
30 | #define APBC_KPC 0x18 | ||
31 | #define APBC_UART0 0x2c | ||
32 | #define APBC_UART1 0x30 | ||
33 | #define APBC_UART2 0x34 | ||
34 | #define APBC_UART3 0x88 | ||
35 | #define APBC_GPIO 0x38 | ||
36 | #define APBC_PWM0 0x3c | ||
37 | #define APBC_PWM1 0x40 | ||
38 | #define APBC_PWM2 0x44 | ||
39 | #define APBC_PWM3 0x48 | ||
40 | #define APBC_SSP0 0x50 | ||
41 | #define APBC_SSP1 0x54 | ||
42 | #define APBC_SSP2 0x58 | ||
43 | #define APBC_SSP3 0x5c | ||
44 | #define APMU_SDH0 0x54 | ||
45 | #define APMU_SDH1 0x58 | ||
46 | #define APMU_SDH2 0xe8 | ||
47 | #define APMU_SDH3 0xec | ||
48 | #define APMU_USB 0x5c | ||
49 | #define APMU_DISP0 0x4c | ||
50 | #define APMU_DISP1 0x110 | ||
51 | #define APMU_CCIC0 0x50 | ||
52 | #define APMU_CCIC1 0xf4 | ||
53 | #define MPMU_UART_PLL 0x14 | ||
54 | |||
55 | static DEFINE_SPINLOCK(clk_lock); | ||
56 | |||
57 | static struct clk_factor_masks uart_factor_masks = { | ||
58 | .factor = 2, | ||
59 | .num_mask = 0x1fff, | ||
60 | .den_mask = 0x1fff, | ||
61 | .num_shift = 16, | ||
62 | .den_shift = 0, | ||
63 | }; | ||
64 | |||
65 | static struct clk_factor_tbl uart_factor_tbl[] = { | ||
66 | {.num = 14634, .den = 2165}, /*14.745MHZ */ | ||
67 | {.num = 3521, .den = 689}, /*19.23MHZ */ | ||
68 | {.num = 9679, .den = 5728}, /*58.9824MHZ */ | ||
69 | {.num = 15850, .den = 9451}, /*59.429MHZ */ | ||
70 | }; | ||
71 | |||
72 | static const char *uart_parent[] = {"uart_pll", "vctcxo"}; | ||
73 | static const char *ssp_parent[] = {"vctcxo_4", "vctcxo_2", "vctcxo", "pll1_16"}; | ||
74 | static const char *sdh_parent[] = {"pll1_4", "pll2", "usb_pll", "pll1"}; | ||
75 | static const char *disp_parent[] = {"pll1", "pll1_16", "pll2", "vctcxo"}; | ||
76 | static const char *ccic_parent[] = {"pll1_2", "pll1_16", "vctcxo"}; | ||
77 | |||
78 | void __init mmp2_clk_init(void) | ||
79 | { | ||
80 | struct clk *clk; | ||
81 | struct clk *vctcxo; | ||
82 | void __iomem *mpmu_base; | ||
83 | void __iomem *apmu_base; | ||
84 | void __iomem *apbc_base; | ||
85 | |||
86 | mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K); | ||
87 | if (mpmu_base == NULL) { | ||
88 | pr_err("error to ioremap MPMU base\n"); | ||
89 | return; | ||
90 | } | ||
91 | |||
92 | apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K); | ||
93 | if (apmu_base == NULL) { | ||
94 | pr_err("error to ioremap APMU base\n"); | ||
95 | return; | ||
96 | } | ||
97 | |||
98 | apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K); | ||
99 | if (apbc_base == NULL) { | ||
100 | pr_err("error to ioremap APBC base\n"); | ||
101 | return; | ||
102 | } | ||
103 | |||
104 | clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); | ||
105 | clk_register_clkdev(clk, "clk32", NULL); | ||
106 | |||
107 | vctcxo = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, | ||
108 | 26000000); | ||
109 | clk_register_clkdev(vctcxo, "vctcxo", NULL); | ||
110 | |||
111 | clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, | ||
112 | 800000000); | ||
113 | clk_register_clkdev(clk, "pll1", NULL); | ||
114 | |||
115 | clk = clk_register_fixed_rate(NULL, "usb_pll", NULL, CLK_IS_ROOT, | ||
116 | 480000000); | ||
117 | clk_register_clkdev(clk, "usb_pll", NULL); | ||
118 | |||
119 | clk = clk_register_fixed_rate(NULL, "pll2", NULL, CLK_IS_ROOT, | ||
120 | 960000000); | ||
121 | clk_register_clkdev(clk, "pll2", NULL); | ||
122 | |||
123 | clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1", | ||
124 | CLK_SET_RATE_PARENT, 1, 2); | ||
125 | clk_register_clkdev(clk, "pll1_2", NULL); | ||
126 | |||
127 | clk = clk_register_fixed_factor(NULL, "pll1_4", "pll1_2", | ||
128 | CLK_SET_RATE_PARENT, 1, 2); | ||
129 | clk_register_clkdev(clk, "pll1_4", NULL); | ||
130 | |||
131 | clk = clk_register_fixed_factor(NULL, "pll1_8", "pll1_4", | ||
132 | CLK_SET_RATE_PARENT, 1, 2); | ||
133 | clk_register_clkdev(clk, "pll1_8", NULL); | ||
134 | |||
135 | clk = clk_register_fixed_factor(NULL, "pll1_16", "pll1_8", | ||
136 | CLK_SET_RATE_PARENT, 1, 2); | ||
137 | clk_register_clkdev(clk, "pll1_16", NULL); | ||
138 | |||
139 | clk = clk_register_fixed_factor(NULL, "pll1_20", "pll1_4", | ||
140 | CLK_SET_RATE_PARENT, 1, 5); | ||
141 | clk_register_clkdev(clk, "pll1_20", NULL); | ||
142 | |||
143 | clk = clk_register_fixed_factor(NULL, "pll1_3", "pll1", | ||
144 | CLK_SET_RATE_PARENT, 1, 3); | ||
145 | clk_register_clkdev(clk, "pll1_3", NULL); | ||
146 | |||
147 | clk = clk_register_fixed_factor(NULL, "pll1_6", "pll1_3", | ||
148 | CLK_SET_RATE_PARENT, 1, 2); | ||
149 | clk_register_clkdev(clk, "pll1_6", NULL); | ||
150 | |||
151 | clk = clk_register_fixed_factor(NULL, "pll1_12", "pll1_6", | ||
152 | CLK_SET_RATE_PARENT, 1, 2); | ||
153 | clk_register_clkdev(clk, "pll1_12", NULL); | ||
154 | |||
155 | clk = clk_register_fixed_factor(NULL, "pll2_2", "pll2", | ||
156 | CLK_SET_RATE_PARENT, 1, 2); | ||
157 | clk_register_clkdev(clk, "pll2_2", NULL); | ||
158 | |||
159 | clk = clk_register_fixed_factor(NULL, "pll2_4", "pll2_2", | ||
160 | CLK_SET_RATE_PARENT, 1, 2); | ||
161 | clk_register_clkdev(clk, "pll2_4", NULL); | ||
162 | |||
163 | clk = clk_register_fixed_factor(NULL, "pll2_8", "pll2_4", | ||
164 | CLK_SET_RATE_PARENT, 1, 2); | ||
165 | clk_register_clkdev(clk, "pll2_8", NULL); | ||
166 | |||
167 | clk = clk_register_fixed_factor(NULL, "pll2_16", "pll2_8", | ||
168 | CLK_SET_RATE_PARENT, 1, 2); | ||
169 | clk_register_clkdev(clk, "pll2_16", NULL); | ||
170 | |||
171 | clk = clk_register_fixed_factor(NULL, "pll2_3", "pll2", | ||
172 | CLK_SET_RATE_PARENT, 1, 3); | ||
173 | clk_register_clkdev(clk, "pll2_3", NULL); | ||
174 | |||
175 | clk = clk_register_fixed_factor(NULL, "pll2_6", "pll2_3", | ||
176 | CLK_SET_RATE_PARENT, 1, 2); | ||
177 | clk_register_clkdev(clk, "pll2_6", NULL); | ||
178 | |||
179 | clk = clk_register_fixed_factor(NULL, "pll2_12", "pll2_6", | ||
180 | CLK_SET_RATE_PARENT, 1, 2); | ||
181 | clk_register_clkdev(clk, "pll2_12", NULL); | ||
182 | |||
183 | clk = clk_register_fixed_factor(NULL, "vctcxo_2", "vctcxo", | ||
184 | CLK_SET_RATE_PARENT, 1, 2); | ||
185 | clk_register_clkdev(clk, "vctcxo_2", NULL); | ||
186 | |||
187 | clk = clk_register_fixed_factor(NULL, "vctcxo_4", "vctcxo_2", | ||
188 | CLK_SET_RATE_PARENT, 1, 2); | ||
189 | clk_register_clkdev(clk, "vctcxo_4", NULL); | ||
190 | |||
191 | clk = mmp_clk_register_factor("uart_pll", "pll1_4", 0, | ||
192 | mpmu_base + MPMU_UART_PLL, | ||
193 | &uart_factor_masks, uart_factor_tbl, | ||
194 | ARRAY_SIZE(uart_factor_tbl)); | ||
195 | clk_set_rate(clk, 14745600); | ||
196 | clk_register_clkdev(clk, "uart_pll", NULL); | ||
197 | |||
198 | clk = mmp_clk_register_apbc("twsi0", "vctcxo", | ||
199 | apbc_base + APBC_TWSI0, 10, 0, &clk_lock); | ||
200 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.0"); | ||
201 | |||
202 | clk = mmp_clk_register_apbc("twsi1", "vctcxo", | ||
203 | apbc_base + APBC_TWSI1, 10, 0, &clk_lock); | ||
204 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.1"); | ||
205 | |||
206 | clk = mmp_clk_register_apbc("twsi2", "vctcxo", | ||
207 | apbc_base + APBC_TWSI2, 10, 0, &clk_lock); | ||
208 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.2"); | ||
209 | |||
210 | clk = mmp_clk_register_apbc("twsi3", "vctcxo", | ||
211 | apbc_base + APBC_TWSI3, 10, 0, &clk_lock); | ||
212 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.3"); | ||
213 | |||
214 | clk = mmp_clk_register_apbc("twsi4", "vctcxo", | ||
215 | apbc_base + APBC_TWSI4, 10, 0, &clk_lock); | ||
216 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.4"); | ||
217 | |||
218 | clk = mmp_clk_register_apbc("twsi5", "vctcxo", | ||
219 | apbc_base + APBC_TWSI5, 10, 0, &clk_lock); | ||
220 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.5"); | ||
221 | |||
222 | clk = mmp_clk_register_apbc("gpio", "vctcxo", | ||
223 | apbc_base + APBC_GPIO, 10, 0, &clk_lock); | ||
224 | clk_register_clkdev(clk, NULL, "pxa-gpio"); | ||
225 | |||
226 | clk = mmp_clk_register_apbc("kpc", "clk32", | ||
227 | apbc_base + APBC_KPC, 10, 0, &clk_lock); | ||
228 | clk_register_clkdev(clk, NULL, "pxa27x-keypad"); | ||
229 | |||
230 | clk = mmp_clk_register_apbc("rtc", "clk32", | ||
231 | apbc_base + APBC_RTC, 10, 0, &clk_lock); | ||
232 | clk_register_clkdev(clk, NULL, "mmp-rtc"); | ||
233 | |||
234 | clk = mmp_clk_register_apbc("pwm0", "vctcxo", | ||
235 | apbc_base + APBC_PWM0, 10, 0, &clk_lock); | ||
236 | clk_register_clkdev(clk, NULL, "mmp2-pwm.0"); | ||
237 | |||
238 | clk = mmp_clk_register_apbc("pwm1", "vctcxo", | ||
239 | apbc_base + APBC_PWM1, 10, 0, &clk_lock); | ||
240 | clk_register_clkdev(clk, NULL, "mmp2-pwm.1"); | ||
241 | |||
242 | clk = mmp_clk_register_apbc("pwm2", "vctcxo", | ||
243 | apbc_base + APBC_PWM2, 10, 0, &clk_lock); | ||
244 | clk_register_clkdev(clk, NULL, "mmp2-pwm.2"); | ||
245 | |||
246 | clk = mmp_clk_register_apbc("pwm3", "vctcxo", | ||
247 | apbc_base + APBC_PWM3, 10, 0, &clk_lock); | ||
248 | clk_register_clkdev(clk, NULL, "mmp2-pwm.3"); | ||
249 | |||
250 | clk = clk_register_mux(NULL, "uart0_mux", uart_parent, | ||
251 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
252 | apbc_base + APBC_UART0, 4, 3, 0, &clk_lock); | ||
253 | clk_set_parent(clk, vctcxo); | ||
254 | clk_register_clkdev(clk, "uart_mux.0", NULL); | ||
255 | |||
256 | clk = mmp_clk_register_apbc("uart0", "uart0_mux", | ||
257 | apbc_base + APBC_UART0, 10, 0, &clk_lock); | ||
258 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.0"); | ||
259 | |||
260 | clk = clk_register_mux(NULL, "uart1_mux", uart_parent, | ||
261 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
262 | apbc_base + APBC_UART1, 4, 3, 0, &clk_lock); | ||
263 | clk_set_parent(clk, vctcxo); | ||
264 | clk_register_clkdev(clk, "uart_mux.1", NULL); | ||
265 | |||
266 | clk = mmp_clk_register_apbc("uart1", "uart1_mux", | ||
267 | apbc_base + APBC_UART1, 10, 0, &clk_lock); | ||
268 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.1"); | ||
269 | |||
270 | clk = clk_register_mux(NULL, "uart2_mux", uart_parent, | ||
271 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
272 | apbc_base + APBC_UART2, 4, 3, 0, &clk_lock); | ||
273 | clk_set_parent(clk, vctcxo); | ||
274 | clk_register_clkdev(clk, "uart_mux.2", NULL); | ||
275 | |||
276 | clk = mmp_clk_register_apbc("uart2", "uart2_mux", | ||
277 | apbc_base + APBC_UART2, 10, 0, &clk_lock); | ||
278 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.2"); | ||
279 | |||
280 | clk = clk_register_mux(NULL, "uart3_mux", uart_parent, | ||
281 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
282 | apbc_base + APBC_UART3, 4, 3, 0, &clk_lock); | ||
283 | clk_set_parent(clk, vctcxo); | ||
284 | clk_register_clkdev(clk, "uart_mux.3", NULL); | ||
285 | |||
286 | clk = mmp_clk_register_apbc("uart3", "uart3_mux", | ||
287 | apbc_base + APBC_UART3, 10, 0, &clk_lock); | ||
288 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.3"); | ||
289 | |||
290 | clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent, | ||
291 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
292 | apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock); | ||
293 | clk_register_clkdev(clk, "uart_mux.0", NULL); | ||
294 | |||
295 | clk = mmp_clk_register_apbc("ssp0", "ssp0_mux", | ||
296 | apbc_base + APBC_SSP0, 10, 0, &clk_lock); | ||
297 | clk_register_clkdev(clk, NULL, "mmp-ssp.0"); | ||
298 | |||
299 | clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent, | ||
300 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
301 | apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock); | ||
302 | clk_register_clkdev(clk, "ssp_mux.1", NULL); | ||
303 | |||
304 | clk = mmp_clk_register_apbc("ssp1", "ssp1_mux", | ||
305 | apbc_base + APBC_SSP1, 10, 0, &clk_lock); | ||
306 | clk_register_clkdev(clk, NULL, "mmp-ssp.1"); | ||
307 | |||
308 | clk = clk_register_mux(NULL, "ssp2_mux", ssp_parent, | ||
309 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
310 | apbc_base + APBC_SSP2, 4, 3, 0, &clk_lock); | ||
311 | clk_register_clkdev(clk, "ssp_mux.2", NULL); | ||
312 | |||
313 | clk = mmp_clk_register_apbc("ssp2", "ssp2_mux", | ||
314 | apbc_base + APBC_SSP2, 10, 0, &clk_lock); | ||
315 | clk_register_clkdev(clk, NULL, "mmp-ssp.2"); | ||
316 | |||
317 | clk = clk_register_mux(NULL, "ssp3_mux", ssp_parent, | ||
318 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
319 | apbc_base + APBC_SSP3, 4, 3, 0, &clk_lock); | ||
320 | clk_register_clkdev(clk, "ssp_mux.3", NULL); | ||
321 | |||
322 | clk = mmp_clk_register_apbc("ssp3", "ssp3_mux", | ||
323 | apbc_base + APBC_SSP3, 10, 0, &clk_lock); | ||
324 | clk_register_clkdev(clk, NULL, "mmp-ssp.3"); | ||
325 | |||
326 | clk = clk_register_mux(NULL, "sdh_mux", sdh_parent, | ||
327 | ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT, | ||
328 | apmu_base + APMU_SDH0, 8, 2, 0, &clk_lock); | ||
329 | clk_register_clkdev(clk, "sdh_mux", NULL); | ||
330 | |||
331 | clk = clk_register_divider(NULL, "sdh_div", "sdh_mux", | ||
332 | CLK_SET_RATE_PARENT, apmu_base + APMU_SDH0, | ||
333 | 10, 4, CLK_DIVIDER_ONE_BASED, &clk_lock); | ||
334 | clk_register_clkdev(clk, "sdh_div", NULL); | ||
335 | |||
336 | clk = mmp_clk_register_apmu("sdh0", "sdh_div", apmu_base + APMU_SDH0, | ||
337 | 0x1b, &clk_lock); | ||
338 | clk_register_clkdev(clk, NULL, "sdhci-pxav3.0"); | ||
339 | |||
340 | clk = mmp_clk_register_apmu("sdh1", "sdh_div", apmu_base + APMU_SDH1, | ||
341 | 0x1b, &clk_lock); | ||
342 | clk_register_clkdev(clk, NULL, "sdhci-pxav3.1"); | ||
343 | |||
344 | clk = mmp_clk_register_apmu("sdh2", "sdh_div", apmu_base + APMU_SDH2, | ||
345 | 0x1b, &clk_lock); | ||
346 | clk_register_clkdev(clk, NULL, "sdhci-pxav3.2"); | ||
347 | |||
348 | clk = mmp_clk_register_apmu("sdh3", "sdh_div", apmu_base + APMU_SDH3, | ||
349 | 0x1b, &clk_lock); | ||
350 | clk_register_clkdev(clk, NULL, "sdhci-pxav3.3"); | ||
351 | |||
352 | clk = mmp_clk_register_apmu("usb", "usb_pll", apmu_base + APMU_USB, | ||
353 | 0x9, &clk_lock); | ||
354 | clk_register_clkdev(clk, "usb_clk", NULL); | ||
355 | |||
356 | clk = clk_register_mux(NULL, "disp0_mux", disp_parent, | ||
357 | ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT, | ||
358 | apmu_base + APMU_DISP0, 6, 2, 0, &clk_lock); | ||
359 | clk_register_clkdev(clk, "disp_mux.0", NULL); | ||
360 | |||
361 | clk = clk_register_divider(NULL, "disp0_div", "disp0_mux", | ||
362 | CLK_SET_RATE_PARENT, apmu_base + APMU_DISP0, | ||
363 | 8, 4, CLK_DIVIDER_ONE_BASED, &clk_lock); | ||
364 | clk_register_clkdev(clk, "disp_div.0", NULL); | ||
365 | |||
366 | clk = mmp_clk_register_apmu("disp0", "disp0_div", | ||
367 | apmu_base + APMU_DISP0, 0x1b, &clk_lock); | ||
368 | clk_register_clkdev(clk, NULL, "mmp-disp.0"); | ||
369 | |||
370 | clk = clk_register_divider(NULL, "disp0_sphy_div", "disp0_mux", 0, | ||
371 | apmu_base + APMU_DISP0, 15, 5, 0, &clk_lock); | ||
372 | clk_register_clkdev(clk, "disp_sphy_div.0", NULL); | ||
373 | |||
374 | clk = mmp_clk_register_apmu("disp0_sphy", "disp0_sphy_div", | ||
375 | apmu_base + APMU_DISP0, 0x1024, &clk_lock); | ||
376 | clk_register_clkdev(clk, "disp_sphy.0", NULL); | ||
377 | |||
378 | clk = clk_register_mux(NULL, "disp1_mux", disp_parent, | ||
379 | ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT, | ||
380 | apmu_base + APMU_DISP1, 6, 2, 0, &clk_lock); | ||
381 | clk_register_clkdev(clk, "disp_mux.1", NULL); | ||
382 | |||
383 | clk = clk_register_divider(NULL, "disp1_div", "disp1_mux", | ||
384 | CLK_SET_RATE_PARENT, apmu_base + APMU_DISP1, | ||
385 | 8, 4, CLK_DIVIDER_ONE_BASED, &clk_lock); | ||
386 | clk_register_clkdev(clk, "disp_div.1", NULL); | ||
387 | |||
388 | clk = mmp_clk_register_apmu("disp1", "disp1_div", | ||
389 | apmu_base + APMU_DISP1, 0x1b, &clk_lock); | ||
390 | clk_register_clkdev(clk, NULL, "mmp-disp.1"); | ||
391 | |||
392 | clk = mmp_clk_register_apmu("ccic_arbiter", "vctcxo", | ||
393 | apmu_base + APMU_CCIC0, 0x1800, &clk_lock); | ||
394 | clk_register_clkdev(clk, "ccic_arbiter", NULL); | ||
395 | |||
396 | clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent, | ||
397 | ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT, | ||
398 | apmu_base + APMU_CCIC0, 6, 2, 0, &clk_lock); | ||
399 | clk_register_clkdev(clk, "ccic_mux.0", NULL); | ||
400 | |||
401 | clk = clk_register_divider(NULL, "ccic0_div", "ccic0_mux", | ||
402 | CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0, | ||
403 | 17, 4, CLK_DIVIDER_ONE_BASED, &clk_lock); | ||
404 | clk_register_clkdev(clk, "ccic_div.0", NULL); | ||
405 | |||
406 | clk = mmp_clk_register_apmu("ccic0", "ccic0_div", | ||
407 | apmu_base + APMU_CCIC0, 0x1b, &clk_lock); | ||
408 | clk_register_clkdev(clk, "fnclk", "mmp-ccic.0"); | ||
409 | |||
410 | clk = mmp_clk_register_apmu("ccic0_phy", "ccic0_div", | ||
411 | apmu_base + APMU_CCIC0, 0x24, &clk_lock); | ||
412 | clk_register_clkdev(clk, "phyclk", "mmp-ccic.0"); | ||
413 | |||
414 | clk = clk_register_divider(NULL, "ccic0_sphy_div", "ccic0_div", | ||
415 | CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0, | ||
416 | 10, 5, 0, &clk_lock); | ||
417 | clk_register_clkdev(clk, "sphyclk_div", "mmp-ccic.0"); | ||
418 | |||
419 | clk = mmp_clk_register_apmu("ccic0_sphy", "ccic0_sphy_div", | ||
420 | apmu_base + APMU_CCIC0, 0x300, &clk_lock); | ||
421 | clk_register_clkdev(clk, "sphyclk", "mmp-ccic.0"); | ||
422 | |||
423 | clk = clk_register_mux(NULL, "ccic1_mux", ccic_parent, | ||
424 | ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT, | ||
425 | apmu_base + APMU_CCIC1, 6, 2, 0, &clk_lock); | ||
426 | clk_register_clkdev(clk, "ccic_mux.1", NULL); | ||
427 | |||
428 | clk = clk_register_divider(NULL, "ccic1_div", "ccic1_mux", | ||
429 | CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC1, | ||
430 | 16, 4, CLK_DIVIDER_ONE_BASED, &clk_lock); | ||
431 | clk_register_clkdev(clk, "ccic_div.1", NULL); | ||
432 | |||
433 | clk = mmp_clk_register_apmu("ccic1", "ccic1_div", | ||
434 | apmu_base + APMU_CCIC1, 0x1b, &clk_lock); | ||
435 | clk_register_clkdev(clk, "fnclk", "mmp-ccic.1"); | ||
436 | |||
437 | clk = mmp_clk_register_apmu("ccic1_phy", "ccic1_div", | ||
438 | apmu_base + APMU_CCIC1, 0x24, &clk_lock); | ||
439 | clk_register_clkdev(clk, "phyclk", "mmp-ccic.1"); | ||
440 | |||
441 | clk = clk_register_divider(NULL, "ccic1_sphy_div", "ccic1_div", | ||
442 | CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC1, | ||
443 | 10, 5, 0, &clk_lock); | ||
444 | clk_register_clkdev(clk, "sphyclk_div", "mmp-ccic.1"); | ||
445 | |||
446 | clk = mmp_clk_register_apmu("ccic1_sphy", "ccic1_sphy_div", | ||
447 | apmu_base + APMU_CCIC1, 0x300, &clk_lock); | ||
448 | clk_register_clkdev(clk, "sphyclk", "mmp-ccic.1"); | ||
449 | } | ||
diff --git a/drivers/clk/mmp/clk-pxa168.c b/drivers/clk/mmp/clk-pxa168.c new file mode 100644 index 000000000000..e8d036c12cbf --- /dev/null +++ b/drivers/clk/mmp/clk-pxa168.c | |||
@@ -0,0 +1,346 @@ | |||
1 | /* | ||
2 | * pxa168 clock framework source file | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * Chao Xie <xiechao.mail@gmail.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/err.h> | ||
18 | |||
19 | #include <mach/addr-map.h> | ||
20 | |||
21 | #include "clk.h" | ||
22 | |||
23 | #define APBC_RTC 0x28 | ||
24 | #define APBC_TWSI0 0x2c | ||
25 | #define APBC_KPC 0x30 | ||
26 | #define APBC_UART0 0x0 | ||
27 | #define APBC_UART1 0x4 | ||
28 | #define APBC_GPIO 0x8 | ||
29 | #define APBC_PWM0 0xc | ||
30 | #define APBC_PWM1 0x10 | ||
31 | #define APBC_PWM2 0x14 | ||
32 | #define APBC_PWM3 0x18 | ||
33 | #define APBC_SSP0 0x81c | ||
34 | #define APBC_SSP1 0x820 | ||
35 | #define APBC_SSP2 0x84c | ||
36 | #define APBC_SSP3 0x858 | ||
37 | #define APBC_SSP4 0x85c | ||
38 | #define APBC_TWSI1 0x6c | ||
39 | #define APBC_UART2 0x70 | ||
40 | #define APMU_SDH0 0x54 | ||
41 | #define APMU_SDH1 0x58 | ||
42 | #define APMU_USB 0x5c | ||
43 | #define APMU_DISP0 0x4c | ||
44 | #define APMU_CCIC0 0x50 | ||
45 | #define APMU_DFC 0x60 | ||
46 | #define MPMU_UART_PLL 0x14 | ||
47 | |||
48 | static DEFINE_SPINLOCK(clk_lock); | ||
49 | |||
50 | static struct clk_factor_masks uart_factor_masks = { | ||
51 | .factor = 2, | ||
52 | .num_mask = 0x1fff, | ||
53 | .den_mask = 0x1fff, | ||
54 | .num_shift = 16, | ||
55 | .den_shift = 0, | ||
56 | }; | ||
57 | |||
58 | static struct clk_factor_tbl uart_factor_tbl[] = { | ||
59 | {.num = 8125, .den = 1536}, /*14.745MHZ */ | ||
60 | }; | ||
61 | |||
62 | static const char *uart_parent[] = {"pll1_3_16", "uart_pll"}; | ||
63 | static const char *ssp_parent[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; | ||
64 | static const char *sdh_parent[] = {"pll1_12", "pll1_13"}; | ||
65 | static const char *disp_parent[] = {"pll1_2", "pll1_12"}; | ||
66 | static const char *ccic_parent[] = {"pll1_2", "pll1_12"}; | ||
67 | static const char *ccic_phy_parent[] = {"pll1_6", "pll1_12"}; | ||
68 | |||
69 | void __init pxa168_clk_init(void) | ||
70 | { | ||
71 | struct clk *clk; | ||
72 | struct clk *uart_pll; | ||
73 | void __iomem *mpmu_base; | ||
74 | void __iomem *apmu_base; | ||
75 | void __iomem *apbc_base; | ||
76 | |||
77 | mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K); | ||
78 | if (mpmu_base == NULL) { | ||
79 | pr_err("error to ioremap MPMU base\n"); | ||
80 | return; | ||
81 | } | ||
82 | |||
83 | apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K); | ||
84 | if (apmu_base == NULL) { | ||
85 | pr_err("error to ioremap APMU base\n"); | ||
86 | return; | ||
87 | } | ||
88 | |||
89 | apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K); | ||
90 | if (apbc_base == NULL) { | ||
91 | pr_err("error to ioremap APBC base\n"); | ||
92 | return; | ||
93 | } | ||
94 | |||
95 | clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); | ||
96 | clk_register_clkdev(clk, "clk32", NULL); | ||
97 | |||
98 | clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, | ||
99 | 26000000); | ||
100 | clk_register_clkdev(clk, "vctcxo", NULL); | ||
101 | |||
102 | clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, | ||
103 | 624000000); | ||
104 | clk_register_clkdev(clk, "pll1", NULL); | ||
105 | |||
106 | clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1", | ||
107 | CLK_SET_RATE_PARENT, 1, 2); | ||
108 | clk_register_clkdev(clk, "pll1_2", NULL); | ||
109 | |||
110 | clk = clk_register_fixed_factor(NULL, "pll1_4", "pll1_2", | ||
111 | CLK_SET_RATE_PARENT, 1, 2); | ||
112 | clk_register_clkdev(clk, "pll1_4", NULL); | ||
113 | |||
114 | clk = clk_register_fixed_factor(NULL, "pll1_8", "pll1_4", | ||
115 | CLK_SET_RATE_PARENT, 1, 2); | ||
116 | clk_register_clkdev(clk, "pll1_8", NULL); | ||
117 | |||
118 | clk = clk_register_fixed_factor(NULL, "pll1_16", "pll1_8", | ||
119 | CLK_SET_RATE_PARENT, 1, 2); | ||
120 | clk_register_clkdev(clk, "pll1_16", NULL); | ||
121 | |||
122 | clk = clk_register_fixed_factor(NULL, "pll1_6", "pll1_2", | ||
123 | CLK_SET_RATE_PARENT, 1, 3); | ||
124 | clk_register_clkdev(clk, "pll1_6", NULL); | ||
125 | |||
126 | clk = clk_register_fixed_factor(NULL, "pll1_12", "pll1_6", | ||
127 | CLK_SET_RATE_PARENT, 1, 2); | ||
128 | clk_register_clkdev(clk, "pll1_12", NULL); | ||
129 | |||
130 | clk = clk_register_fixed_factor(NULL, "pll1_24", "pll1_12", | ||
131 | CLK_SET_RATE_PARENT, 1, 2); | ||
132 | clk_register_clkdev(clk, "pll1_24", NULL); | ||
133 | |||
134 | clk = clk_register_fixed_factor(NULL, "pll1_48", "pll1_24", | ||
135 | CLK_SET_RATE_PARENT, 1, 2); | ||
136 | clk_register_clkdev(clk, "pll1_48", NULL); | ||
137 | |||
138 | clk = clk_register_fixed_factor(NULL, "pll1_96", "pll1_48", | ||
139 | CLK_SET_RATE_PARENT, 1, 2); | ||
140 | clk_register_clkdev(clk, "pll1_96", NULL); | ||
141 | |||
142 | clk = clk_register_fixed_factor(NULL, "pll1_13", "pll1", | ||
143 | CLK_SET_RATE_PARENT, 1, 13); | ||
144 | clk_register_clkdev(clk, "pll1_13", NULL); | ||
145 | |||
146 | clk = clk_register_fixed_factor(NULL, "pll1_13_1_5", "pll1", | ||
147 | CLK_SET_RATE_PARENT, 2, 3); | ||
148 | clk_register_clkdev(clk, "pll1_13_1_5", NULL); | ||
149 | |||
150 | clk = clk_register_fixed_factor(NULL, "pll1_2_1_5", "pll1", | ||
151 | CLK_SET_RATE_PARENT, 2, 3); | ||
152 | clk_register_clkdev(clk, "pll1_2_1_5", NULL); | ||
153 | |||
154 | clk = clk_register_fixed_factor(NULL, "pll1_3_16", "pll1", | ||
155 | CLK_SET_RATE_PARENT, 3, 16); | ||
156 | clk_register_clkdev(clk, "pll1_3_16", NULL); | ||
157 | |||
158 | uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, | ||
159 | mpmu_base + MPMU_UART_PLL, | ||
160 | &uart_factor_masks, uart_factor_tbl, | ||
161 | ARRAY_SIZE(uart_factor_tbl)); | ||
162 | clk_set_rate(uart_pll, 14745600); | ||
163 | clk_register_clkdev(uart_pll, "uart_pll", NULL); | ||
164 | |||
165 | clk = mmp_clk_register_apbc("twsi0", "pll1_13_1_5", | ||
166 | apbc_base + APBC_TWSI0, 10, 0, &clk_lock); | ||
167 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.0"); | ||
168 | |||
169 | clk = mmp_clk_register_apbc("twsi1", "pll1_13_1_5", | ||
170 | apbc_base + APBC_TWSI1, 10, 0, &clk_lock); | ||
171 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.1"); | ||
172 | |||
173 | clk = mmp_clk_register_apbc("gpio", "vctcxo", | ||
174 | apbc_base + APBC_GPIO, 10, 0, &clk_lock); | ||
175 | clk_register_clkdev(clk, NULL, "pxa-gpio"); | ||
176 | |||
177 | clk = mmp_clk_register_apbc("kpc", "clk32", | ||
178 | apbc_base + APBC_KPC, 10, 0, &clk_lock); | ||
179 | clk_register_clkdev(clk, NULL, "pxa27x-keypad"); | ||
180 | |||
181 | clk = mmp_clk_register_apbc("rtc", "clk32", | ||
182 | apbc_base + APBC_RTC, 10, 0, &clk_lock); | ||
183 | clk_register_clkdev(clk, NULL, "sa1100-rtc"); | ||
184 | |||
185 | clk = mmp_clk_register_apbc("pwm0", "pll1_48", | ||
186 | apbc_base + APBC_PWM0, 10, 0, &clk_lock); | ||
187 | clk_register_clkdev(clk, NULL, "pxa168-pwm.0"); | ||
188 | |||
189 | clk = mmp_clk_register_apbc("pwm1", "pll1_48", | ||
190 | apbc_base + APBC_PWM1, 10, 0, &clk_lock); | ||
191 | clk_register_clkdev(clk, NULL, "pxa168-pwm.1"); | ||
192 | |||
193 | clk = mmp_clk_register_apbc("pwm2", "pll1_48", | ||
194 | apbc_base + APBC_PWM2, 10, 0, &clk_lock); | ||
195 | clk_register_clkdev(clk, NULL, "pxa168-pwm.2"); | ||
196 | |||
197 | clk = mmp_clk_register_apbc("pwm3", "pll1_48", | ||
198 | apbc_base + APBC_PWM3, 10, 0, &clk_lock); | ||
199 | clk_register_clkdev(clk, NULL, "pxa168-pwm.3"); | ||
200 | |||
201 | clk = clk_register_mux(NULL, "uart0_mux", uart_parent, | ||
202 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
203 | apbc_base + APBC_UART0, 4, 3, 0, &clk_lock); | ||
204 | clk_set_parent(clk, uart_pll); | ||
205 | clk_register_clkdev(clk, "uart_mux.0", NULL); | ||
206 | |||
207 | clk = mmp_clk_register_apbc("uart0", "uart0_mux", | ||
208 | apbc_base + APBC_UART0, 10, 0, &clk_lock); | ||
209 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.0"); | ||
210 | |||
211 | clk = clk_register_mux(NULL, "uart1_mux", uart_parent, | ||
212 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
213 | apbc_base + APBC_UART1, 4, 3, 0, &clk_lock); | ||
214 | clk_set_parent(clk, uart_pll); | ||
215 | clk_register_clkdev(clk, "uart_mux.1", NULL); | ||
216 | |||
217 | clk = mmp_clk_register_apbc("uart1", "uart1_mux", | ||
218 | apbc_base + APBC_UART1, 10, 0, &clk_lock); | ||
219 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.1"); | ||
220 | |||
221 | clk = clk_register_mux(NULL, "uart2_mux", uart_parent, | ||
222 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
223 | apbc_base + APBC_UART2, 4, 3, 0, &clk_lock); | ||
224 | clk_set_parent(clk, uart_pll); | ||
225 | clk_register_clkdev(clk, "uart_mux.2", NULL); | ||
226 | |||
227 | clk = mmp_clk_register_apbc("uart2", "uart2_mux", | ||
228 | apbc_base + APBC_UART2, 10, 0, &clk_lock); | ||
229 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.2"); | ||
230 | |||
231 | clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent, | ||
232 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
233 | apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock); | ||
234 | clk_register_clkdev(clk, "uart_mux.0", NULL); | ||
235 | |||
236 | clk = mmp_clk_register_apbc("ssp0", "ssp0_mux", apbc_base + APBC_SSP0, | ||
237 | 10, 0, &clk_lock); | ||
238 | clk_register_clkdev(clk, NULL, "mmp-ssp.0"); | ||
239 | |||
240 | clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent, | ||
241 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
242 | apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock); | ||
243 | clk_register_clkdev(clk, "ssp_mux.1", NULL); | ||
244 | |||
245 | clk = mmp_clk_register_apbc("ssp1", "ssp1_mux", apbc_base + APBC_SSP1, | ||
246 | 10, 0, &clk_lock); | ||
247 | clk_register_clkdev(clk, NULL, "mmp-ssp.1"); | ||
248 | |||
249 | clk = clk_register_mux(NULL, "ssp2_mux", ssp_parent, | ||
250 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
251 | apbc_base + APBC_SSP2, 4, 3, 0, &clk_lock); | ||
252 | clk_register_clkdev(clk, "ssp_mux.2", NULL); | ||
253 | |||
254 | clk = mmp_clk_register_apbc("ssp2", "ssp1_mux", apbc_base + APBC_SSP2, | ||
255 | 10, 0, &clk_lock); | ||
256 | clk_register_clkdev(clk, NULL, "mmp-ssp.2"); | ||
257 | |||
258 | clk = clk_register_mux(NULL, "ssp3_mux", ssp_parent, | ||
259 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
260 | apbc_base + APBC_SSP3, 4, 3, 0, &clk_lock); | ||
261 | clk_register_clkdev(clk, "ssp_mux.3", NULL); | ||
262 | |||
263 | clk = mmp_clk_register_apbc("ssp3", "ssp1_mux", apbc_base + APBC_SSP3, | ||
264 | 10, 0, &clk_lock); | ||
265 | clk_register_clkdev(clk, NULL, "mmp-ssp.3"); | ||
266 | |||
267 | clk = clk_register_mux(NULL, "ssp4_mux", ssp_parent, | ||
268 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
269 | apbc_base + APBC_SSP4, 4, 3, 0, &clk_lock); | ||
270 | clk_register_clkdev(clk, "ssp_mux.4", NULL); | ||
271 | |||
272 | clk = mmp_clk_register_apbc("ssp4", "ssp1_mux", apbc_base + APBC_SSP4, | ||
273 | 10, 0, &clk_lock); | ||
274 | clk_register_clkdev(clk, NULL, "mmp-ssp.4"); | ||
275 | |||
276 | clk = mmp_clk_register_apmu("dfc", "pll1_4", apmu_base + APMU_DFC, | ||
277 | 0x19b, &clk_lock); | ||
278 | clk_register_clkdev(clk, NULL, "pxa3xx-nand.0"); | ||
279 | |||
280 | clk = clk_register_mux(NULL, "sdh0_mux", sdh_parent, | ||
281 | ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT, | ||
282 | apmu_base + APMU_SDH0, 6, 1, 0, &clk_lock); | ||
283 | clk_register_clkdev(clk, "sdh0_mux", NULL); | ||
284 | |||
285 | clk = mmp_clk_register_apmu("sdh0", "sdh_mux", apmu_base + APMU_SDH0, | ||
286 | 0x1b, &clk_lock); | ||
287 | clk_register_clkdev(clk, NULL, "sdhci-pxa.0"); | ||
288 | |||
289 | clk = clk_register_mux(NULL, "sdh1_mux", sdh_parent, | ||
290 | ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT, | ||
291 | apmu_base + APMU_SDH1, 6, 1, 0, &clk_lock); | ||
292 | clk_register_clkdev(clk, "sdh1_mux", NULL); | ||
293 | |||
294 | clk = mmp_clk_register_apmu("sdh1", "sdh1_mux", apmu_base + APMU_SDH1, | ||
295 | 0x1b, &clk_lock); | ||
296 | clk_register_clkdev(clk, NULL, "sdhci-pxa.1"); | ||
297 | |||
298 | clk = mmp_clk_register_apmu("usb", "usb_pll", apmu_base + APMU_USB, | ||
299 | 0x9, &clk_lock); | ||
300 | clk_register_clkdev(clk, "usb_clk", NULL); | ||
301 | |||
302 | clk = mmp_clk_register_apmu("sph", "usb_pll", apmu_base + APMU_USB, | ||
303 | 0x12, &clk_lock); | ||
304 | clk_register_clkdev(clk, "sph_clk", NULL); | ||
305 | |||
306 | clk = clk_register_mux(NULL, "disp0_mux", disp_parent, | ||
307 | ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT, | ||
308 | apmu_base + APMU_DISP0, 6, 1, 0, &clk_lock); | ||
309 | clk_register_clkdev(clk, "disp_mux.0", NULL); | ||
310 | |||
311 | clk = mmp_clk_register_apmu("disp0", "disp0_mux", | ||
312 | apmu_base + APMU_DISP0, 0x1b, &clk_lock); | ||
313 | clk_register_clkdev(clk, "fnclk", "mmp-disp.0"); | ||
314 | |||
315 | clk = mmp_clk_register_apmu("disp0_hclk", "disp0_mux", | ||
316 | apmu_base + APMU_DISP0, 0x24, &clk_lock); | ||
317 | clk_register_clkdev(clk, "hclk", "mmp-disp.0"); | ||
318 | |||
319 | clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent, | ||
320 | ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT, | ||
321 | apmu_base + APMU_CCIC0, 6, 1, 0, &clk_lock); | ||
322 | clk_register_clkdev(clk, "ccic_mux.0", NULL); | ||
323 | |||
324 | clk = mmp_clk_register_apmu("ccic0", "ccic0_mux", | ||
325 | apmu_base + APMU_CCIC0, 0x1b, &clk_lock); | ||
326 | clk_register_clkdev(clk, "fnclk", "mmp-ccic.0"); | ||
327 | |||
328 | clk = clk_register_mux(NULL, "ccic0_phy_mux", ccic_phy_parent, | ||
329 | ARRAY_SIZE(ccic_phy_parent), | ||
330 | CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0, | ||
331 | 7, 1, 0, &clk_lock); | ||
332 | clk_register_clkdev(clk, "ccic_phy_mux.0", NULL); | ||
333 | |||
334 | clk = mmp_clk_register_apmu("ccic0_phy", "ccic0_phy_mux", | ||
335 | apmu_base + APMU_CCIC0, 0x24, &clk_lock); | ||
336 | clk_register_clkdev(clk, "phyclk", "mmp-ccic.0"); | ||
337 | |||
338 | clk = clk_register_divider(NULL, "ccic0_sphy_div", "ccic0_mux", | ||
339 | CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0, | ||
340 | 10, 5, 0, &clk_lock); | ||
341 | clk_register_clkdev(clk, "sphyclk_div", NULL); | ||
342 | |||
343 | clk = mmp_clk_register_apmu("ccic0_sphy", "ccic0_sphy_div", | ||
344 | apmu_base + APMU_CCIC0, 0x300, &clk_lock); | ||
345 | clk_register_clkdev(clk, "sphyclk", "mmp-ccic.0"); | ||
346 | } | ||
diff --git a/drivers/clk/mmp/clk-pxa910.c b/drivers/clk/mmp/clk-pxa910.c new file mode 100644 index 000000000000..7048c31d6e7e --- /dev/null +++ b/drivers/clk/mmp/clk-pxa910.c | |||
@@ -0,0 +1,320 @@ | |||
1 | /* | ||
2 | * pxa910 clock framework source file | ||
3 | * | ||
4 | * Copyright (C) 2012 Marvell | ||
5 | * Chao Xie <xiechao.mail@gmail.com> | ||
6 | * | ||
7 | * This file is licensed under the terms of the GNU General Public | ||
8 | * License version 2. This program is licensed "as is" without any | ||
9 | * warranty of any kind, whether express or implied. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/spinlock.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/err.h> | ||
18 | |||
19 | #include <mach/addr-map.h> | ||
20 | |||
21 | #include "clk.h" | ||
22 | |||
23 | #define APBC_RTC 0x28 | ||
24 | #define APBC_TWSI0 0x2c | ||
25 | #define APBC_KPC 0x18 | ||
26 | #define APBC_UART0 0x0 | ||
27 | #define APBC_UART1 0x4 | ||
28 | #define APBC_GPIO 0x8 | ||
29 | #define APBC_PWM0 0xc | ||
30 | #define APBC_PWM1 0x10 | ||
31 | #define APBC_PWM2 0x14 | ||
32 | #define APBC_PWM3 0x18 | ||
33 | #define APBC_SSP0 0x1c | ||
34 | #define APBC_SSP1 0x20 | ||
35 | #define APBC_SSP2 0x4c | ||
36 | #define APBCP_TWSI1 0x28 | ||
37 | #define APBCP_UART2 0x1c | ||
38 | #define APMU_SDH0 0x54 | ||
39 | #define APMU_SDH1 0x58 | ||
40 | #define APMU_USB 0x5c | ||
41 | #define APMU_DISP0 0x4c | ||
42 | #define APMU_CCIC0 0x50 | ||
43 | #define APMU_DFC 0x60 | ||
44 | #define MPMU_UART_PLL 0x14 | ||
45 | |||
46 | static DEFINE_SPINLOCK(clk_lock); | ||
47 | |||
48 | static struct clk_factor_masks uart_factor_masks = { | ||
49 | .factor = 2, | ||
50 | .num_mask = 0x1fff, | ||
51 | .den_mask = 0x1fff, | ||
52 | .num_shift = 16, | ||
53 | .den_shift = 0, | ||
54 | }; | ||
55 | |||
56 | static struct clk_factor_tbl uart_factor_tbl[] = { | ||
57 | {.num = 8125, .den = 1536}, /*14.745MHZ */ | ||
58 | }; | ||
59 | |||
60 | static const char *uart_parent[] = {"pll1_3_16", "uart_pll"}; | ||
61 | static const char *ssp_parent[] = {"pll1_96", "pll1_48", "pll1_24", "pll1_12"}; | ||
62 | static const char *sdh_parent[] = {"pll1_12", "pll1_13"}; | ||
63 | static const char *disp_parent[] = {"pll1_2", "pll1_12"}; | ||
64 | static const char *ccic_parent[] = {"pll1_2", "pll1_12"}; | ||
65 | static const char *ccic_phy_parent[] = {"pll1_6", "pll1_12"}; | ||
66 | |||
67 | void __init pxa910_clk_init(void) | ||
68 | { | ||
69 | struct clk *clk; | ||
70 | struct clk *uart_pll; | ||
71 | void __iomem *mpmu_base; | ||
72 | void __iomem *apmu_base; | ||
73 | void __iomem *apbcp_base; | ||
74 | void __iomem *apbc_base; | ||
75 | |||
76 | mpmu_base = ioremap(APB_PHYS_BASE + 0x50000, SZ_4K); | ||
77 | if (mpmu_base == NULL) { | ||
78 | pr_err("error to ioremap MPMU base\n"); | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | apmu_base = ioremap(AXI_PHYS_BASE + 0x82800, SZ_4K); | ||
83 | if (apmu_base == NULL) { | ||
84 | pr_err("error to ioremap APMU base\n"); | ||
85 | return; | ||
86 | } | ||
87 | |||
88 | apbcp_base = ioremap(APB_PHYS_BASE + 0x3b000, SZ_4K); | ||
89 | if (apbcp_base == NULL) { | ||
90 | pr_err("error to ioremap APBC extension base\n"); | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | apbc_base = ioremap(APB_PHYS_BASE + 0x15000, SZ_4K); | ||
95 | if (apbc_base == NULL) { | ||
96 | pr_err("error to ioremap APBC base\n"); | ||
97 | return; | ||
98 | } | ||
99 | |||
100 | clk = clk_register_fixed_rate(NULL, "clk32", NULL, CLK_IS_ROOT, 3200); | ||
101 | clk_register_clkdev(clk, "clk32", NULL); | ||
102 | |||
103 | clk = clk_register_fixed_rate(NULL, "vctcxo", NULL, CLK_IS_ROOT, | ||
104 | 26000000); | ||
105 | clk_register_clkdev(clk, "vctcxo", NULL); | ||
106 | |||
107 | clk = clk_register_fixed_rate(NULL, "pll1", NULL, CLK_IS_ROOT, | ||
108 | 624000000); | ||
109 | clk_register_clkdev(clk, "pll1", NULL); | ||
110 | |||
111 | clk = clk_register_fixed_factor(NULL, "pll1_2", "pll1", | ||
112 | CLK_SET_RATE_PARENT, 1, 2); | ||
113 | clk_register_clkdev(clk, "pll1_2", NULL); | ||
114 | |||
115 | clk = clk_register_fixed_factor(NULL, "pll1_4", "pll1_2", | ||
116 | CLK_SET_RATE_PARENT, 1, 2); | ||
117 | clk_register_clkdev(clk, "pll1_4", NULL); | ||
118 | |||
119 | clk = clk_register_fixed_factor(NULL, "pll1_8", "pll1_4", | ||
120 | CLK_SET_RATE_PARENT, 1, 2); | ||
121 | clk_register_clkdev(clk, "pll1_8", NULL); | ||
122 | |||
123 | clk = clk_register_fixed_factor(NULL, "pll1_16", "pll1_8", | ||
124 | CLK_SET_RATE_PARENT, 1, 2); | ||
125 | clk_register_clkdev(clk, "pll1_16", NULL); | ||
126 | |||
127 | clk = clk_register_fixed_factor(NULL, "pll1_6", "pll1_2", | ||
128 | CLK_SET_RATE_PARENT, 1, 3); | ||
129 | clk_register_clkdev(clk, "pll1_6", NULL); | ||
130 | |||
131 | clk = clk_register_fixed_factor(NULL, "pll1_12", "pll1_6", | ||
132 | CLK_SET_RATE_PARENT, 1, 2); | ||
133 | clk_register_clkdev(clk, "pll1_12", NULL); | ||
134 | |||
135 | clk = clk_register_fixed_factor(NULL, "pll1_24", "pll1_12", | ||
136 | CLK_SET_RATE_PARENT, 1, 2); | ||
137 | clk_register_clkdev(clk, "pll1_24", NULL); | ||
138 | |||
139 | clk = clk_register_fixed_factor(NULL, "pll1_48", "pll1_24", | ||
140 | CLK_SET_RATE_PARENT, 1, 2); | ||
141 | clk_register_clkdev(clk, "pll1_48", NULL); | ||
142 | |||
143 | clk = clk_register_fixed_factor(NULL, "pll1_96", "pll1_48", | ||
144 | CLK_SET_RATE_PARENT, 1, 2); | ||
145 | clk_register_clkdev(clk, "pll1_96", NULL); | ||
146 | |||
147 | clk = clk_register_fixed_factor(NULL, "pll1_13", "pll1", | ||
148 | CLK_SET_RATE_PARENT, 1, 13); | ||
149 | clk_register_clkdev(clk, "pll1_13", NULL); | ||
150 | |||
151 | clk = clk_register_fixed_factor(NULL, "pll1_13_1_5", "pll1", | ||
152 | CLK_SET_RATE_PARENT, 2, 3); | ||
153 | clk_register_clkdev(clk, "pll1_13_1_5", NULL); | ||
154 | |||
155 | clk = clk_register_fixed_factor(NULL, "pll1_2_1_5", "pll1", | ||
156 | CLK_SET_RATE_PARENT, 2, 3); | ||
157 | clk_register_clkdev(clk, "pll1_2_1_5", NULL); | ||
158 | |||
159 | clk = clk_register_fixed_factor(NULL, "pll1_3_16", "pll1", | ||
160 | CLK_SET_RATE_PARENT, 3, 16); | ||
161 | clk_register_clkdev(clk, "pll1_3_16", NULL); | ||
162 | |||
163 | uart_pll = mmp_clk_register_factor("uart_pll", "pll1_4", 0, | ||
164 | mpmu_base + MPMU_UART_PLL, | ||
165 | &uart_factor_masks, uart_factor_tbl, | ||
166 | ARRAY_SIZE(uart_factor_tbl)); | ||
167 | clk_set_rate(uart_pll, 14745600); | ||
168 | clk_register_clkdev(uart_pll, "uart_pll", NULL); | ||
169 | |||
170 | clk = mmp_clk_register_apbc("twsi0", "pll1_13_1_5", | ||
171 | apbc_base + APBC_TWSI0, 10, 0, &clk_lock); | ||
172 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.0"); | ||
173 | |||
174 | clk = mmp_clk_register_apbc("twsi1", "pll1_13_1_5", | ||
175 | apbcp_base + APBCP_TWSI1, 10, 0, &clk_lock); | ||
176 | clk_register_clkdev(clk, NULL, "pxa2xx-i2c.1"); | ||
177 | |||
178 | clk = mmp_clk_register_apbc("gpio", "vctcxo", | ||
179 | apbc_base + APBC_GPIO, 10, 0, &clk_lock); | ||
180 | clk_register_clkdev(clk, NULL, "pxa-gpio"); | ||
181 | |||
182 | clk = mmp_clk_register_apbc("kpc", "clk32", | ||
183 | apbc_base + APBC_KPC, 10, 0, &clk_lock); | ||
184 | clk_register_clkdev(clk, NULL, "pxa27x-keypad"); | ||
185 | |||
186 | clk = mmp_clk_register_apbc("rtc", "clk32", | ||
187 | apbc_base + APBC_RTC, 10, 0, &clk_lock); | ||
188 | clk_register_clkdev(clk, NULL, "sa1100-rtc"); | ||
189 | |||
190 | clk = mmp_clk_register_apbc("pwm0", "pll1_48", | ||
191 | apbc_base + APBC_PWM0, 10, 0, &clk_lock); | ||
192 | clk_register_clkdev(clk, NULL, "pxa910-pwm.0"); | ||
193 | |||
194 | clk = mmp_clk_register_apbc("pwm1", "pll1_48", | ||
195 | apbc_base + APBC_PWM1, 10, 0, &clk_lock); | ||
196 | clk_register_clkdev(clk, NULL, "pxa910-pwm.1"); | ||
197 | |||
198 | clk = mmp_clk_register_apbc("pwm2", "pll1_48", | ||
199 | apbc_base + APBC_PWM2, 10, 0, &clk_lock); | ||
200 | clk_register_clkdev(clk, NULL, "pxa910-pwm.2"); | ||
201 | |||
202 | clk = mmp_clk_register_apbc("pwm3", "pll1_48", | ||
203 | apbc_base + APBC_PWM3, 10, 0, &clk_lock); | ||
204 | clk_register_clkdev(clk, NULL, "pxa910-pwm.3"); | ||
205 | |||
206 | clk = clk_register_mux(NULL, "uart0_mux", uart_parent, | ||
207 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
208 | apbc_base + APBC_UART0, 4, 3, 0, &clk_lock); | ||
209 | clk_set_parent(clk, uart_pll); | ||
210 | clk_register_clkdev(clk, "uart_mux.0", NULL); | ||
211 | |||
212 | clk = mmp_clk_register_apbc("uart0", "uart0_mux", | ||
213 | apbc_base + APBC_UART0, 10, 0, &clk_lock); | ||
214 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.0"); | ||
215 | |||
216 | clk = clk_register_mux(NULL, "uart1_mux", uart_parent, | ||
217 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
218 | apbc_base + APBC_UART1, 4, 3, 0, &clk_lock); | ||
219 | clk_set_parent(clk, uart_pll); | ||
220 | clk_register_clkdev(clk, "uart_mux.1", NULL); | ||
221 | |||
222 | clk = mmp_clk_register_apbc("uart1", "uart1_mux", | ||
223 | apbc_base + APBC_UART1, 10, 0, &clk_lock); | ||
224 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.1"); | ||
225 | |||
226 | clk = clk_register_mux(NULL, "uart2_mux", uart_parent, | ||
227 | ARRAY_SIZE(uart_parent), CLK_SET_RATE_PARENT, | ||
228 | apbcp_base + APBCP_UART2, 4, 3, 0, &clk_lock); | ||
229 | clk_set_parent(clk, uart_pll); | ||
230 | clk_register_clkdev(clk, "uart_mux.2", NULL); | ||
231 | |||
232 | clk = mmp_clk_register_apbc("uart2", "uart2_mux", | ||
233 | apbcp_base + APBCP_UART2, 10, 0, &clk_lock); | ||
234 | clk_register_clkdev(clk, NULL, "pxa2xx-uart.2"); | ||
235 | |||
236 | clk = clk_register_mux(NULL, "ssp0_mux", ssp_parent, | ||
237 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
238 | apbc_base + APBC_SSP0, 4, 3, 0, &clk_lock); | ||
239 | clk_register_clkdev(clk, "uart_mux.0", NULL); | ||
240 | |||
241 | clk = mmp_clk_register_apbc("ssp0", "ssp0_mux", | ||
242 | apbc_base + APBC_SSP0, 10, 0, &clk_lock); | ||
243 | clk_register_clkdev(clk, NULL, "mmp-ssp.0"); | ||
244 | |||
245 | clk = clk_register_mux(NULL, "ssp1_mux", ssp_parent, | ||
246 | ARRAY_SIZE(ssp_parent), CLK_SET_RATE_PARENT, | ||
247 | apbc_base + APBC_SSP1, 4, 3, 0, &clk_lock); | ||
248 | clk_register_clkdev(clk, "ssp_mux.1", NULL); | ||
249 | |||
250 | clk = mmp_clk_register_apbc("ssp1", "ssp1_mux", | ||
251 | apbc_base + APBC_SSP1, 10, 0, &clk_lock); | ||
252 | clk_register_clkdev(clk, NULL, "mmp-ssp.1"); | ||
253 | |||
254 | clk = mmp_clk_register_apmu("dfc", "pll1_4", | ||
255 | apmu_base + APMU_DFC, 0x19b, &clk_lock); | ||
256 | clk_register_clkdev(clk, NULL, "pxa3xx-nand.0"); | ||
257 | |||
258 | clk = clk_register_mux(NULL, "sdh0_mux", sdh_parent, | ||
259 | ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT, | ||
260 | apmu_base + APMU_SDH0, 6, 1, 0, &clk_lock); | ||
261 | clk_register_clkdev(clk, "sdh0_mux", NULL); | ||
262 | |||
263 | clk = mmp_clk_register_apmu("sdh0", "sdh_mux", | ||
264 | apmu_base + APMU_SDH0, 0x1b, &clk_lock); | ||
265 | clk_register_clkdev(clk, NULL, "sdhci-pxa.0"); | ||
266 | |||
267 | clk = clk_register_mux(NULL, "sdh1_mux", sdh_parent, | ||
268 | ARRAY_SIZE(sdh_parent), CLK_SET_RATE_PARENT, | ||
269 | apmu_base + APMU_SDH1, 6, 1, 0, &clk_lock); | ||
270 | clk_register_clkdev(clk, "sdh1_mux", NULL); | ||
271 | |||
272 | clk = mmp_clk_register_apmu("sdh1", "sdh1_mux", | ||
273 | apmu_base + APMU_SDH1, 0x1b, &clk_lock); | ||
274 | clk_register_clkdev(clk, NULL, "sdhci-pxa.1"); | ||
275 | |||
276 | clk = mmp_clk_register_apmu("usb", "usb_pll", | ||
277 | apmu_base + APMU_USB, 0x9, &clk_lock); | ||
278 | clk_register_clkdev(clk, "usb_clk", NULL); | ||
279 | |||
280 | clk = mmp_clk_register_apmu("sph", "usb_pll", | ||
281 | apmu_base + APMU_USB, 0x12, &clk_lock); | ||
282 | clk_register_clkdev(clk, "sph_clk", NULL); | ||
283 | |||
284 | clk = clk_register_mux(NULL, "disp0_mux", disp_parent, | ||
285 | ARRAY_SIZE(disp_parent), CLK_SET_RATE_PARENT, | ||
286 | apmu_base + APMU_DISP0, 6, 1, 0, &clk_lock); | ||
287 | clk_register_clkdev(clk, "disp_mux.0", NULL); | ||
288 | |||
289 | clk = mmp_clk_register_apmu("disp0", "disp0_mux", | ||
290 | apmu_base + APMU_DISP0, 0x1b, &clk_lock); | ||
291 | clk_register_clkdev(clk, NULL, "mmp-disp.0"); | ||
292 | |||
293 | clk = clk_register_mux(NULL, "ccic0_mux", ccic_parent, | ||
294 | ARRAY_SIZE(ccic_parent), CLK_SET_RATE_PARENT, | ||
295 | apmu_base + APMU_CCIC0, 6, 1, 0, &clk_lock); | ||
296 | clk_register_clkdev(clk, "ccic_mux.0", NULL); | ||
297 | |||
298 | clk = mmp_clk_register_apmu("ccic0", "ccic0_mux", | ||
299 | apmu_base + APMU_CCIC0, 0x1b, &clk_lock); | ||
300 | clk_register_clkdev(clk, "fnclk", "mmp-ccic.0"); | ||
301 | |||
302 | clk = clk_register_mux(NULL, "ccic0_phy_mux", ccic_phy_parent, | ||
303 | ARRAY_SIZE(ccic_phy_parent), | ||
304 | CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0, | ||
305 | 7, 1, 0, &clk_lock); | ||
306 | clk_register_clkdev(clk, "ccic_phy_mux.0", NULL); | ||
307 | |||
308 | clk = mmp_clk_register_apmu("ccic0_phy", "ccic0_phy_mux", | ||
309 | apmu_base + APMU_CCIC0, 0x24, &clk_lock); | ||
310 | clk_register_clkdev(clk, "phyclk", "mmp-ccic.0"); | ||
311 | |||
312 | clk = clk_register_divider(NULL, "ccic0_sphy_div", "ccic0_mux", | ||
313 | CLK_SET_RATE_PARENT, apmu_base + APMU_CCIC0, | ||
314 | 10, 5, 0, &clk_lock); | ||
315 | clk_register_clkdev(clk, "sphyclk_div", NULL); | ||
316 | |||
317 | clk = mmp_clk_register_apmu("ccic0_sphy", "ccic0_sphy_div", | ||
318 | apmu_base + APMU_CCIC0, 0x300, &clk_lock); | ||
319 | clk_register_clkdev(clk, "sphyclk", "mmp-ccic.0"); | ||
320 | } | ||
diff --git a/drivers/clk/mmp/clk.h b/drivers/clk/mmp/clk.h new file mode 100644 index 000000000000..ab86dd4a416a --- /dev/null +++ b/drivers/clk/mmp/clk.h | |||
@@ -0,0 +1,35 @@ | |||
1 | #ifndef __MACH_MMP_CLK_H | ||
2 | #define __MACH_MMP_CLK_H | ||
3 | |||
4 | #include <linux/clk-provider.h> | ||
5 | #include <linux/clkdev.h> | ||
6 | |||
7 | #define APBC_NO_BUS_CTRL BIT(0) | ||
8 | #define APBC_POWER_CTRL BIT(1) | ||
9 | |||
10 | struct clk_factor_masks { | ||
11 | unsigned int factor; | ||
12 | unsigned int num_mask; | ||
13 | unsigned int den_mask; | ||
14 | unsigned int num_shift; | ||
15 | unsigned int den_shift; | ||
16 | }; | ||
17 | |||
18 | struct clk_factor_tbl { | ||
19 | unsigned int num; | ||
20 | unsigned int den; | ||
21 | }; | ||
22 | |||
23 | extern struct clk *mmp_clk_register_pll2(const char *name, | ||
24 | const char *parent_name, unsigned long flags); | ||
25 | extern struct clk *mmp_clk_register_apbc(const char *name, | ||
26 | const char *parent_name, void __iomem *base, | ||
27 | unsigned int delay, unsigned int apbc_flags, spinlock_t *lock); | ||
28 | extern struct clk *mmp_clk_register_apmu(const char *name, | ||
29 | const char *parent_name, void __iomem *base, u32 enable_mask, | ||
30 | spinlock_t *lock); | ||
31 | extern struct clk *mmp_clk_register_factor(const char *name, | ||
32 | const char *parent_name, unsigned long flags, | ||
33 | void __iomem *base, struct clk_factor_masks *masks, | ||
34 | struct clk_factor_tbl *ftbl, unsigned int ftbl_cnt); | ||
35 | #endif | ||
diff --git a/drivers/clk/mxs/clk-imx23.c b/drivers/clk/mxs/clk-imx23.c index 844043ad0fe4..9f6d15546cbe 100644 --- a/drivers/clk/mxs/clk-imx23.c +++ b/drivers/clk/mxs/clk-imx23.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/of.h> | ||
17 | #include <mach/common.h> | 18 | #include <mach/common.h> |
18 | #include <mach/mx23.h> | 19 | #include <mach/mx23.h> |
19 | #include "clk.h" | 20 | #include "clk.h" |
@@ -71,44 +72,6 @@ static void __init clk_misc_init(void) | |||
71 | __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC); | 72 | __mxs_setl(30 << BP_FRAC_IOFRAC, FRAC); |
72 | } | 73 | } |
73 | 74 | ||
74 | static struct clk_lookup uart_lookups[] = { | ||
75 | { .dev_id = "duart", }, | ||
76 | { .dev_id = "mxs-auart.0", }, | ||
77 | { .dev_id = "mxs-auart.1", }, | ||
78 | { .dev_id = "8006c000.serial", }, | ||
79 | { .dev_id = "8006e000.serial", }, | ||
80 | { .dev_id = "80070000.serial", }, | ||
81 | }; | ||
82 | |||
83 | static struct clk_lookup hbus_lookups[] = { | ||
84 | { .dev_id = "imx23-dma-apbh", }, | ||
85 | { .dev_id = "80004000.dma-apbh", }, | ||
86 | }; | ||
87 | |||
88 | static struct clk_lookup xbus_lookups[] = { | ||
89 | { .dev_id = "duart", .con_id = "apb_pclk"}, | ||
90 | { .dev_id = "80070000.serial", .con_id = "apb_pclk"}, | ||
91 | { .dev_id = "imx23-dma-apbx", }, | ||
92 | { .dev_id = "80024000.dma-apbx", }, | ||
93 | }; | ||
94 | |||
95 | static struct clk_lookup ssp_lookups[] = { | ||
96 | { .dev_id = "imx23-mmc.0", }, | ||
97 | { .dev_id = "imx23-mmc.1", }, | ||
98 | { .dev_id = "80010000.ssp", }, | ||
99 | { .dev_id = "80034000.ssp", }, | ||
100 | }; | ||
101 | |||
102 | static struct clk_lookup lcdif_lookups[] = { | ||
103 | { .dev_id = "imx23-fb", }, | ||
104 | { .dev_id = "80030000.lcdif", }, | ||
105 | }; | ||
106 | |||
107 | static struct clk_lookup gpmi_lookups[] = { | ||
108 | { .dev_id = "imx23-gpmi-nand", }, | ||
109 | { .dev_id = "8000c000.gpmi-nand", }, | ||
110 | }; | ||
111 | |||
112 | static const char *sel_pll[] __initconst = { "pll", "ref_xtal", }; | 75 | static const char *sel_pll[] __initconst = { "pll", "ref_xtal", }; |
113 | static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", }; | 76 | static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", }; |
114 | static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", }; | 77 | static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", }; |
@@ -127,6 +90,7 @@ enum imx23_clk { | |||
127 | }; | 90 | }; |
128 | 91 | ||
129 | static struct clk *clks[clk_max]; | 92 | static struct clk *clks[clk_max]; |
93 | static struct clk_onecell_data clk_data; | ||
130 | 94 | ||
131 | static enum imx23_clk clks_init_on[] __initdata = { | 95 | static enum imx23_clk clks_init_on[] __initdata = { |
132 | cpu, hbus, xbus, emi, uart, | 96 | cpu, hbus, xbus, emi, uart, |
@@ -134,6 +98,7 @@ static enum imx23_clk clks_init_on[] __initdata = { | |||
134 | 98 | ||
135 | int __init mx23_clocks_init(void) | 99 | int __init mx23_clocks_init(void) |
136 | { | 100 | { |
101 | struct device_node *np; | ||
137 | int i; | 102 | int i; |
138 | 103 | ||
139 | clk_misc_init(); | 104 | clk_misc_init(); |
@@ -188,14 +153,14 @@ int __init mx23_clocks_init(void) | |||
188 | return PTR_ERR(clks[i]); | 153 | return PTR_ERR(clks[i]); |
189 | } | 154 | } |
190 | 155 | ||
156 | np = of_find_compatible_node(NULL, NULL, "fsl,imx23-clkctrl"); | ||
157 | if (np) { | ||
158 | clk_data.clks = clks; | ||
159 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
160 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
161 | } | ||
162 | |||
191 | clk_register_clkdev(clks[clk32k], NULL, "timrot"); | 163 | clk_register_clkdev(clks[clk32k], NULL, "timrot"); |
192 | clk_register_clkdev(clks[pwm], NULL, "80064000.pwm"); | ||
193 | clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups)); | ||
194 | clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups)); | ||
195 | clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups)); | ||
196 | clk_register_clkdevs(clks[ssp], ssp_lookups, ARRAY_SIZE(ssp_lookups)); | ||
197 | clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups)); | ||
198 | clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups)); | ||
199 | 164 | ||
200 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | 165 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) |
201 | clk_prepare_enable(clks[clks_init_on[i]]); | 166 | clk_prepare_enable(clks[clks_init_on[i]]); |
diff --git a/drivers/clk/mxs/clk-imx28.c b/drivers/clk/mxs/clk-imx28.c index e3aab67b3eb7..613e76f3758e 100644 --- a/drivers/clk/mxs/clk-imx28.c +++ b/drivers/clk/mxs/clk-imx28.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/err.h> | 14 | #include <linux/err.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/of.h> | ||
17 | #include <mach/common.h> | 18 | #include <mach/common.h> |
18 | #include <mach/mx28.h> | 19 | #include <mach/mx28.h> |
19 | #include "clk.h" | 20 | #include "clk.h" |
@@ -120,90 +121,6 @@ static void __init clk_misc_init(void) | |||
120 | writel_relaxed(val, FRAC0); | 121 | writel_relaxed(val, FRAC0); |
121 | } | 122 | } |
122 | 123 | ||
123 | static struct clk_lookup uart_lookups[] = { | ||
124 | { .dev_id = "duart", }, | ||
125 | { .dev_id = "mxs-auart.0", }, | ||
126 | { .dev_id = "mxs-auart.1", }, | ||
127 | { .dev_id = "mxs-auart.2", }, | ||
128 | { .dev_id = "mxs-auart.3", }, | ||
129 | { .dev_id = "mxs-auart.4", }, | ||
130 | { .dev_id = "8006a000.serial", }, | ||
131 | { .dev_id = "8006c000.serial", }, | ||
132 | { .dev_id = "8006e000.serial", }, | ||
133 | { .dev_id = "80070000.serial", }, | ||
134 | { .dev_id = "80072000.serial", }, | ||
135 | { .dev_id = "80074000.serial", }, | ||
136 | }; | ||
137 | |||
138 | static struct clk_lookup hbus_lookups[] = { | ||
139 | { .dev_id = "imx28-dma-apbh", }, | ||
140 | { .dev_id = "80004000.dma-apbh", }, | ||
141 | }; | ||
142 | |||
143 | static struct clk_lookup xbus_lookups[] = { | ||
144 | { .dev_id = "duart", .con_id = "apb_pclk"}, | ||
145 | { .dev_id = "80074000.serial", .con_id = "apb_pclk"}, | ||
146 | { .dev_id = "imx28-dma-apbx", }, | ||
147 | { .dev_id = "80024000.dma-apbx", }, | ||
148 | }; | ||
149 | |||
150 | static struct clk_lookup ssp0_lookups[] = { | ||
151 | { .dev_id = "imx28-mmc.0", }, | ||
152 | { .dev_id = "80010000.ssp", }, | ||
153 | }; | ||
154 | |||
155 | static struct clk_lookup ssp1_lookups[] = { | ||
156 | { .dev_id = "imx28-mmc.1", }, | ||
157 | { .dev_id = "80012000.ssp", }, | ||
158 | }; | ||
159 | |||
160 | static struct clk_lookup ssp2_lookups[] = { | ||
161 | { .dev_id = "imx28-mmc.2", }, | ||
162 | { .dev_id = "80014000.ssp", }, | ||
163 | }; | ||
164 | |||
165 | static struct clk_lookup ssp3_lookups[] = { | ||
166 | { .dev_id = "imx28-mmc.3", }, | ||
167 | { .dev_id = "80016000.ssp", }, | ||
168 | }; | ||
169 | |||
170 | static struct clk_lookup lcdif_lookups[] = { | ||
171 | { .dev_id = "imx28-fb", }, | ||
172 | { .dev_id = "80030000.lcdif", }, | ||
173 | }; | ||
174 | |||
175 | static struct clk_lookup gpmi_lookups[] = { | ||
176 | { .dev_id = "imx28-gpmi-nand", }, | ||
177 | { .dev_id = "8000c000.gpmi-nand", }, | ||
178 | }; | ||
179 | |||
180 | static struct clk_lookup fec_lookups[] = { | ||
181 | { .dev_id = "imx28-fec.0", }, | ||
182 | { .dev_id = "imx28-fec.1", }, | ||
183 | { .dev_id = "800f0000.ethernet", }, | ||
184 | { .dev_id = "800f4000.ethernet", }, | ||
185 | }; | ||
186 | |||
187 | static struct clk_lookup can0_lookups[] = { | ||
188 | { .dev_id = "flexcan.0", }, | ||
189 | { .dev_id = "80032000.can", }, | ||
190 | }; | ||
191 | |||
192 | static struct clk_lookup can1_lookups[] = { | ||
193 | { .dev_id = "flexcan.1", }, | ||
194 | { .dev_id = "80034000.can", }, | ||
195 | }; | ||
196 | |||
197 | static struct clk_lookup saif0_lookups[] = { | ||
198 | { .dev_id = "mxs-saif.0", }, | ||
199 | { .dev_id = "80042000.saif", }, | ||
200 | }; | ||
201 | |||
202 | static struct clk_lookup saif1_lookups[] = { | ||
203 | { .dev_id = "mxs-saif.1", }, | ||
204 | { .dev_id = "80046000.saif", }, | ||
205 | }; | ||
206 | |||
207 | static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", }; | 124 | static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", }; |
208 | static const char *sel_io0[] __initconst = { "ref_io0", "ref_xtal", }; | 125 | static const char *sel_io0[] __initconst = { "ref_io0", "ref_xtal", }; |
209 | static const char *sel_io1[] __initconst = { "ref_io1", "ref_xtal", }; | 126 | static const char *sel_io1[] __initconst = { "ref_io1", "ref_xtal", }; |
@@ -228,6 +145,7 @@ enum imx28_clk { | |||
228 | }; | 145 | }; |
229 | 146 | ||
230 | static struct clk *clks[clk_max]; | 147 | static struct clk *clks[clk_max]; |
148 | static struct clk_onecell_data clk_data; | ||
231 | 149 | ||
232 | static enum imx28_clk clks_init_on[] __initdata = { | 150 | static enum imx28_clk clks_init_on[] __initdata = { |
233 | cpu, hbus, xbus, emi, uart, | 151 | cpu, hbus, xbus, emi, uart, |
@@ -235,6 +153,7 @@ static enum imx28_clk clks_init_on[] __initdata = { | |||
235 | 153 | ||
236 | int __init mx28_clocks_init(void) | 154 | int __init mx28_clocks_init(void) |
237 | { | 155 | { |
156 | struct device_node *np; | ||
238 | int i; | 157 | int i; |
239 | 158 | ||
240 | clk_misc_init(); | 159 | clk_misc_init(); |
@@ -312,27 +231,15 @@ int __init mx28_clocks_init(void) | |||
312 | return PTR_ERR(clks[i]); | 231 | return PTR_ERR(clks[i]); |
313 | } | 232 | } |
314 | 233 | ||
234 | np = of_find_compatible_node(NULL, NULL, "fsl,imx28-clkctrl"); | ||
235 | if (np) { | ||
236 | clk_data.clks = clks; | ||
237 | clk_data.clk_num = ARRAY_SIZE(clks); | ||
238 | of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); | ||
239 | } | ||
240 | |||
315 | clk_register_clkdev(clks[clk32k], NULL, "timrot"); | 241 | clk_register_clkdev(clks[clk32k], NULL, "timrot"); |
316 | clk_register_clkdev(clks[enet_out], NULL, "enet_out"); | 242 | clk_register_clkdev(clks[enet_out], NULL, "enet_out"); |
317 | clk_register_clkdev(clks[pwm], NULL, "80064000.pwm"); | ||
318 | clk_register_clkdevs(clks[hbus], hbus_lookups, ARRAY_SIZE(hbus_lookups)); | ||
319 | clk_register_clkdevs(clks[xbus], xbus_lookups, ARRAY_SIZE(xbus_lookups)); | ||
320 | clk_register_clkdevs(clks[uart], uart_lookups, ARRAY_SIZE(uart_lookups)); | ||
321 | clk_register_clkdevs(clks[ssp0], ssp0_lookups, ARRAY_SIZE(ssp0_lookups)); | ||
322 | clk_register_clkdevs(clks[ssp1], ssp1_lookups, ARRAY_SIZE(ssp1_lookups)); | ||
323 | clk_register_clkdevs(clks[ssp2], ssp2_lookups, ARRAY_SIZE(ssp2_lookups)); | ||
324 | clk_register_clkdevs(clks[ssp3], ssp3_lookups, ARRAY_SIZE(ssp3_lookups)); | ||
325 | clk_register_clkdevs(clks[gpmi], gpmi_lookups, ARRAY_SIZE(gpmi_lookups)); | ||
326 | clk_register_clkdevs(clks[saif0], saif0_lookups, ARRAY_SIZE(saif0_lookups)); | ||
327 | clk_register_clkdevs(clks[saif1], saif1_lookups, ARRAY_SIZE(saif1_lookups)); | ||
328 | clk_register_clkdevs(clks[lcdif], lcdif_lookups, ARRAY_SIZE(lcdif_lookups)); | ||
329 | clk_register_clkdevs(clks[fec], fec_lookups, ARRAY_SIZE(fec_lookups)); | ||
330 | clk_register_clkdevs(clks[can0], can0_lookups, ARRAY_SIZE(can0_lookups)); | ||
331 | clk_register_clkdevs(clks[can1], can1_lookups, ARRAY_SIZE(can1_lookups)); | ||
332 | clk_register_clkdev(clks[usb0_pwr], NULL, "8007c000.usbphy"); | ||
333 | clk_register_clkdev(clks[usb1_pwr], NULL, "8007e000.usbphy"); | ||
334 | clk_register_clkdev(clks[usb0], NULL, "80080000.usb"); | ||
335 | clk_register_clkdev(clks[usb1], NULL, "80090000.usb"); | ||
336 | 243 | ||
337 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) | 244 | for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) |
338 | clk_prepare_enable(clks[clks_init_on[i]]); | 245 | clk_prepare_enable(clks[clks_init_on[i]]); |
diff --git a/drivers/clk/ux500/Makefile b/drivers/clk/ux500/Makefile new file mode 100644 index 000000000000..858fbfe66281 --- /dev/null +++ b/drivers/clk/ux500/Makefile | |||
@@ -0,0 +1,12 @@ | |||
1 | # | ||
2 | # Makefile for ux500 clocks | ||
3 | # | ||
4 | |||
5 | # Clock types | ||
6 | obj-y += clk-prcc.o | ||
7 | obj-y += clk-prcmu.o | ||
8 | |||
9 | # Clock definitions | ||
10 | obj-y += u8500_clk.o | ||
11 | obj-y += u9540_clk.o | ||
12 | obj-y += u8540_clk.o | ||
diff --git a/drivers/clk/ux500/clk-prcc.c b/drivers/clk/ux500/clk-prcc.c new file mode 100644 index 000000000000..7eee7f768355 --- /dev/null +++ b/drivers/clk/ux500/clk-prcc.c | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * PRCC clock implementation for ux500 platform. | ||
3 | * | ||
4 | * Copyright (C) 2012 ST-Ericsson SA | ||
5 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
6 | * | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk-provider.h> | ||
11 | #include <linux/clk-private.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <mach/hardware.h> | ||
17 | |||
18 | #include "clk.h" | ||
19 | |||
20 | #define PRCC_PCKEN 0x000 | ||
21 | #define PRCC_PCKDIS 0x004 | ||
22 | #define PRCC_KCKEN 0x008 | ||
23 | #define PRCC_KCKDIS 0x00C | ||
24 | #define PRCC_PCKSR 0x010 | ||
25 | #define PRCC_KCKSR 0x014 | ||
26 | |||
27 | #define to_clk_prcc(_hw) container_of(_hw, struct clk_prcc, hw) | ||
28 | |||
29 | struct clk_prcc { | ||
30 | struct clk_hw hw; | ||
31 | void __iomem *base; | ||
32 | u32 cg_sel; | ||
33 | int is_enabled; | ||
34 | }; | ||
35 | |||
36 | /* PRCC clock operations. */ | ||
37 | |||
38 | static int clk_prcc_pclk_enable(struct clk_hw *hw) | ||
39 | { | ||
40 | struct clk_prcc *clk = to_clk_prcc(hw); | ||
41 | |||
42 | writel(clk->cg_sel, (clk->base + PRCC_PCKEN)); | ||
43 | while (!(readl(clk->base + PRCC_PCKSR) & clk->cg_sel)) | ||
44 | cpu_relax(); | ||
45 | |||
46 | clk->is_enabled = 1; | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | static void clk_prcc_pclk_disable(struct clk_hw *hw) | ||
51 | { | ||
52 | struct clk_prcc *clk = to_clk_prcc(hw); | ||
53 | |||
54 | writel(clk->cg_sel, (clk->base + PRCC_PCKDIS)); | ||
55 | clk->is_enabled = 0; | ||
56 | } | ||
57 | |||
58 | static int clk_prcc_kclk_enable(struct clk_hw *hw) | ||
59 | { | ||
60 | struct clk_prcc *clk = to_clk_prcc(hw); | ||
61 | |||
62 | writel(clk->cg_sel, (clk->base + PRCC_KCKEN)); | ||
63 | while (!(readl(clk->base + PRCC_KCKSR) & clk->cg_sel)) | ||
64 | cpu_relax(); | ||
65 | |||
66 | clk->is_enabled = 1; | ||
67 | return 0; | ||
68 | } | ||
69 | |||
70 | static void clk_prcc_kclk_disable(struct clk_hw *hw) | ||
71 | { | ||
72 | struct clk_prcc *clk = to_clk_prcc(hw); | ||
73 | |||
74 | writel(clk->cg_sel, (clk->base + PRCC_KCKDIS)); | ||
75 | clk->is_enabled = 0; | ||
76 | } | ||
77 | |||
78 | static int clk_prcc_is_enabled(struct clk_hw *hw) | ||
79 | { | ||
80 | struct clk_prcc *clk = to_clk_prcc(hw); | ||
81 | return clk->is_enabled; | ||
82 | } | ||
83 | |||
84 | static struct clk_ops clk_prcc_pclk_ops = { | ||
85 | .enable = clk_prcc_pclk_enable, | ||
86 | .disable = clk_prcc_pclk_disable, | ||
87 | .is_enabled = clk_prcc_is_enabled, | ||
88 | }; | ||
89 | |||
90 | static struct clk_ops clk_prcc_kclk_ops = { | ||
91 | .enable = clk_prcc_kclk_enable, | ||
92 | .disable = clk_prcc_kclk_disable, | ||
93 | .is_enabled = clk_prcc_is_enabled, | ||
94 | }; | ||
95 | |||
96 | static struct clk *clk_reg_prcc(const char *name, | ||
97 | const char *parent_name, | ||
98 | resource_size_t phy_base, | ||
99 | u32 cg_sel, | ||
100 | unsigned long flags, | ||
101 | struct clk_ops *clk_prcc_ops) | ||
102 | { | ||
103 | struct clk_prcc *clk; | ||
104 | struct clk_init_data clk_prcc_init; | ||
105 | struct clk *clk_reg; | ||
106 | |||
107 | if (!name) { | ||
108 | pr_err("clk_prcc: %s invalid arguments passed\n", __func__); | ||
109 | return ERR_PTR(-EINVAL); | ||
110 | } | ||
111 | |||
112 | clk = kzalloc(sizeof(struct clk_prcc), GFP_KERNEL); | ||
113 | if (!clk) { | ||
114 | pr_err("clk_prcc: %s could not allocate clk\n", __func__); | ||
115 | return ERR_PTR(-ENOMEM); | ||
116 | } | ||
117 | |||
118 | clk->base = ioremap(phy_base, SZ_4K); | ||
119 | if (!clk->base) | ||
120 | goto free_clk; | ||
121 | |||
122 | clk->cg_sel = cg_sel; | ||
123 | clk->is_enabled = 1; | ||
124 | |||
125 | clk_prcc_init.name = name; | ||
126 | clk_prcc_init.ops = clk_prcc_ops; | ||
127 | clk_prcc_init.flags = flags; | ||
128 | clk_prcc_init.parent_names = (parent_name ? &parent_name : NULL); | ||
129 | clk_prcc_init.num_parents = (parent_name ? 1 : 0); | ||
130 | clk->hw.init = &clk_prcc_init; | ||
131 | |||
132 | clk_reg = clk_register(NULL, &clk->hw); | ||
133 | if (IS_ERR_OR_NULL(clk_reg)) | ||
134 | goto unmap_clk; | ||
135 | |||
136 | return clk_reg; | ||
137 | |||
138 | unmap_clk: | ||
139 | iounmap(clk->base); | ||
140 | free_clk: | ||
141 | kfree(clk); | ||
142 | pr_err("clk_prcc: %s failed to register clk\n", __func__); | ||
143 | return ERR_PTR(-ENOMEM); | ||
144 | } | ||
145 | |||
146 | struct clk *clk_reg_prcc_pclk(const char *name, | ||
147 | const char *parent_name, | ||
148 | resource_size_t phy_base, | ||
149 | u32 cg_sel, | ||
150 | unsigned long flags) | ||
151 | { | ||
152 | return clk_reg_prcc(name, parent_name, phy_base, cg_sel, flags, | ||
153 | &clk_prcc_pclk_ops); | ||
154 | } | ||
155 | |||
156 | struct clk *clk_reg_prcc_kclk(const char *name, | ||
157 | const char *parent_name, | ||
158 | resource_size_t phy_base, | ||
159 | u32 cg_sel, | ||
160 | unsigned long flags) | ||
161 | { | ||
162 | return clk_reg_prcc(name, parent_name, phy_base, cg_sel, flags, | ||
163 | &clk_prcc_kclk_ops); | ||
164 | } | ||
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c new file mode 100644 index 000000000000..930cdfeb47ab --- /dev/null +++ b/drivers/clk/ux500/clk-prcmu.c | |||
@@ -0,0 +1,252 @@ | |||
1 | /* | ||
2 | * PRCMU clock implementation for ux500 platform. | ||
3 | * | ||
4 | * Copyright (C) 2012 ST-Ericsson SA | ||
5 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
6 | * | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk-provider.h> | ||
11 | #include <linux/clk-private.h> | ||
12 | #include <linux/mfd/dbx500-prcmu.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/err.h> | ||
16 | #include "clk.h" | ||
17 | |||
18 | #define to_clk_prcmu(_hw) container_of(_hw, struct clk_prcmu, hw) | ||
19 | |||
20 | struct clk_prcmu { | ||
21 | struct clk_hw hw; | ||
22 | u8 cg_sel; | ||
23 | int is_enabled; | ||
24 | }; | ||
25 | |||
26 | /* PRCMU clock operations. */ | ||
27 | |||
28 | static int clk_prcmu_prepare(struct clk_hw *hw) | ||
29 | { | ||
30 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
31 | return prcmu_request_clock(clk->cg_sel, true); | ||
32 | } | ||
33 | |||
34 | static void clk_prcmu_unprepare(struct clk_hw *hw) | ||
35 | { | ||
36 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
37 | if (prcmu_request_clock(clk->cg_sel, false)) | ||
38 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, | ||
39 | hw->init->name); | ||
40 | } | ||
41 | |||
42 | static int clk_prcmu_enable(struct clk_hw *hw) | ||
43 | { | ||
44 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
45 | clk->is_enabled = 1; | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static void clk_prcmu_disable(struct clk_hw *hw) | ||
50 | { | ||
51 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
52 | clk->is_enabled = 0; | ||
53 | } | ||
54 | |||
55 | static int clk_prcmu_is_enabled(struct clk_hw *hw) | ||
56 | { | ||
57 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
58 | return clk->is_enabled; | ||
59 | } | ||
60 | |||
61 | static unsigned long clk_prcmu_recalc_rate(struct clk_hw *hw, | ||
62 | unsigned long parent_rate) | ||
63 | { | ||
64 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
65 | return prcmu_clock_rate(clk->cg_sel); | ||
66 | } | ||
67 | |||
68 | static long clk_prcmu_round_rate(struct clk_hw *hw, unsigned long rate, | ||
69 | unsigned long *parent_rate) | ||
70 | { | ||
71 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
72 | return prcmu_round_clock_rate(clk->cg_sel, rate); | ||
73 | } | ||
74 | |||
75 | static int clk_prcmu_set_rate(struct clk_hw *hw, unsigned long rate, | ||
76 | unsigned long parent_rate) | ||
77 | { | ||
78 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
79 | return prcmu_set_clock_rate(clk->cg_sel, rate); | ||
80 | } | ||
81 | |||
82 | static int request_ape_opp100(bool enable) | ||
83 | { | ||
84 | static int reqs; | ||
85 | int err = 0; | ||
86 | |||
87 | if (enable) { | ||
88 | if (!reqs) | ||
89 | err = prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, | ||
90 | "clock", 100); | ||
91 | if (!err) | ||
92 | reqs++; | ||
93 | } else { | ||
94 | reqs--; | ||
95 | if (!reqs) | ||
96 | prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, | ||
97 | "clock"); | ||
98 | } | ||
99 | return err; | ||
100 | } | ||
101 | |||
102 | static int clk_prcmu_opp_prepare(struct clk_hw *hw) | ||
103 | { | ||
104 | int err; | ||
105 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
106 | |||
107 | err = request_ape_opp100(true); | ||
108 | if (err) { | ||
109 | pr_err("clk_prcmu: %s failed to request APE OPP100 for %s.\n", | ||
110 | __func__, hw->init->name); | ||
111 | return err; | ||
112 | } | ||
113 | |||
114 | err = prcmu_request_clock(clk->cg_sel, true); | ||
115 | if (err) | ||
116 | request_ape_opp100(false); | ||
117 | |||
118 | return err; | ||
119 | } | ||
120 | |||
121 | static void clk_prcmu_opp_unprepare(struct clk_hw *hw) | ||
122 | { | ||
123 | struct clk_prcmu *clk = to_clk_prcmu(hw); | ||
124 | |||
125 | if (prcmu_request_clock(clk->cg_sel, false)) | ||
126 | goto out_error; | ||
127 | if (request_ape_opp100(false)) | ||
128 | goto out_error; | ||
129 | return; | ||
130 | |||
131 | out_error: | ||
132 | pr_err("clk_prcmu: %s failed to disable %s.\n", __func__, | ||
133 | hw->init->name); | ||
134 | } | ||
135 | |||
136 | static struct clk_ops clk_prcmu_scalable_ops = { | ||
137 | .prepare = clk_prcmu_prepare, | ||
138 | .unprepare = clk_prcmu_unprepare, | ||
139 | .enable = clk_prcmu_enable, | ||
140 | .disable = clk_prcmu_disable, | ||
141 | .is_enabled = clk_prcmu_is_enabled, | ||
142 | .recalc_rate = clk_prcmu_recalc_rate, | ||
143 | .round_rate = clk_prcmu_round_rate, | ||
144 | .set_rate = clk_prcmu_set_rate, | ||
145 | }; | ||
146 | |||
147 | static struct clk_ops clk_prcmu_gate_ops = { | ||
148 | .prepare = clk_prcmu_prepare, | ||
149 | .unprepare = clk_prcmu_unprepare, | ||
150 | .enable = clk_prcmu_enable, | ||
151 | .disable = clk_prcmu_disable, | ||
152 | .is_enabled = clk_prcmu_is_enabled, | ||
153 | .recalc_rate = clk_prcmu_recalc_rate, | ||
154 | }; | ||
155 | |||
156 | static struct clk_ops clk_prcmu_rate_ops = { | ||
157 | .is_enabled = clk_prcmu_is_enabled, | ||
158 | .recalc_rate = clk_prcmu_recalc_rate, | ||
159 | }; | ||
160 | |||
161 | static struct clk_ops clk_prcmu_opp_gate_ops = { | ||
162 | .prepare = clk_prcmu_opp_prepare, | ||
163 | .unprepare = clk_prcmu_opp_unprepare, | ||
164 | .enable = clk_prcmu_enable, | ||
165 | .disable = clk_prcmu_disable, | ||
166 | .is_enabled = clk_prcmu_is_enabled, | ||
167 | .recalc_rate = clk_prcmu_recalc_rate, | ||
168 | }; | ||
169 | |||
170 | static struct clk *clk_reg_prcmu(const char *name, | ||
171 | const char *parent_name, | ||
172 | u8 cg_sel, | ||
173 | unsigned long rate, | ||
174 | unsigned long flags, | ||
175 | struct clk_ops *clk_prcmu_ops) | ||
176 | { | ||
177 | struct clk_prcmu *clk; | ||
178 | struct clk_init_data clk_prcmu_init; | ||
179 | struct clk *clk_reg; | ||
180 | |||
181 | if (!name) { | ||
182 | pr_err("clk_prcmu: %s invalid arguments passed\n", __func__); | ||
183 | return ERR_PTR(-EINVAL); | ||
184 | } | ||
185 | |||
186 | clk = kzalloc(sizeof(struct clk_prcmu), GFP_KERNEL); | ||
187 | if (!clk) { | ||
188 | pr_err("clk_prcmu: %s could not allocate clk\n", __func__); | ||
189 | return ERR_PTR(-ENOMEM); | ||
190 | } | ||
191 | |||
192 | clk->cg_sel = cg_sel; | ||
193 | clk->is_enabled = 1; | ||
194 | /* "rate" can be used for changing the initial frequency */ | ||
195 | if (rate) | ||
196 | prcmu_set_clock_rate(cg_sel, rate); | ||
197 | |||
198 | clk_prcmu_init.name = name; | ||
199 | clk_prcmu_init.ops = clk_prcmu_ops; | ||
200 | clk_prcmu_init.flags = flags; | ||
201 | clk_prcmu_init.parent_names = (parent_name ? &parent_name : NULL); | ||
202 | clk_prcmu_init.num_parents = (parent_name ? 1 : 0); | ||
203 | clk->hw.init = &clk_prcmu_init; | ||
204 | |||
205 | clk_reg = clk_register(NULL, &clk->hw); | ||
206 | if (IS_ERR_OR_NULL(clk_reg)) | ||
207 | goto free_clk; | ||
208 | |||
209 | return clk_reg; | ||
210 | |||
211 | free_clk: | ||
212 | kfree(clk); | ||
213 | pr_err("clk_prcmu: %s failed to register clk\n", __func__); | ||
214 | return ERR_PTR(-ENOMEM); | ||
215 | } | ||
216 | |||
217 | struct clk *clk_reg_prcmu_scalable(const char *name, | ||
218 | const char *parent_name, | ||
219 | u8 cg_sel, | ||
220 | unsigned long rate, | ||
221 | unsigned long flags) | ||
222 | { | ||
223 | return clk_reg_prcmu(name, parent_name, cg_sel, rate, flags, | ||
224 | &clk_prcmu_scalable_ops); | ||
225 | } | ||
226 | |||
227 | struct clk *clk_reg_prcmu_gate(const char *name, | ||
228 | const char *parent_name, | ||
229 | u8 cg_sel, | ||
230 | unsigned long flags) | ||
231 | { | ||
232 | return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, | ||
233 | &clk_prcmu_gate_ops); | ||
234 | } | ||
235 | |||
236 | struct clk *clk_reg_prcmu_rate(const char *name, | ||
237 | const char *parent_name, | ||
238 | u8 cg_sel, | ||
239 | unsigned long flags) | ||
240 | { | ||
241 | return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, | ||
242 | &clk_prcmu_rate_ops); | ||
243 | } | ||
244 | |||
245 | struct clk *clk_reg_prcmu_opp_gate(const char *name, | ||
246 | const char *parent_name, | ||
247 | u8 cg_sel, | ||
248 | unsigned long flags) | ||
249 | { | ||
250 | return clk_reg_prcmu(name, parent_name, cg_sel, 0, flags, | ||
251 | &clk_prcmu_opp_gate_ops); | ||
252 | } | ||
diff --git a/drivers/clk/ux500/clk.h b/drivers/clk/ux500/clk.h new file mode 100644 index 000000000000..836d7d16751e --- /dev/null +++ b/drivers/clk/ux500/clk.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * Clocks for ux500 platforms | ||
3 | * | ||
4 | * Copyright (C) 2012 ST-Ericsson SA | ||
5 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
6 | * | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | */ | ||
9 | |||
10 | #ifndef __UX500_CLK_H | ||
11 | #define __UX500_CLK_H | ||
12 | |||
13 | #include <linux/clk.h> | ||
14 | |||
15 | struct clk *clk_reg_prcc_pclk(const char *name, | ||
16 | const char *parent_name, | ||
17 | unsigned int phy_base, | ||
18 | u32 cg_sel, | ||
19 | unsigned long flags); | ||
20 | |||
21 | struct clk *clk_reg_prcc_kclk(const char *name, | ||
22 | const char *parent_name, | ||
23 | unsigned int phy_base, | ||
24 | u32 cg_sel, | ||
25 | unsigned long flags); | ||
26 | |||
27 | struct clk *clk_reg_prcmu_scalable(const char *name, | ||
28 | const char *parent_name, | ||
29 | u8 cg_sel, | ||
30 | unsigned long rate, | ||
31 | unsigned long flags); | ||
32 | |||
33 | struct clk *clk_reg_prcmu_gate(const char *name, | ||
34 | const char *parent_name, | ||
35 | u8 cg_sel, | ||
36 | unsigned long flags); | ||
37 | |||
38 | struct clk *clk_reg_prcmu_rate(const char *name, | ||
39 | const char *parent_name, | ||
40 | u8 cg_sel, | ||
41 | unsigned long flags); | ||
42 | |||
43 | struct clk *clk_reg_prcmu_opp_gate(const char *name, | ||
44 | const char *parent_name, | ||
45 | u8 cg_sel, | ||
46 | unsigned long flags); | ||
47 | |||
48 | #endif /* __UX500_CLK_H */ | ||
diff --git a/drivers/clk/ux500/u8500_clk.c b/drivers/clk/ux500/u8500_clk.c new file mode 100644 index 000000000000..ca4a25ed844c --- /dev/null +++ b/drivers/clk/ux500/u8500_clk.c | |||
@@ -0,0 +1,477 @@ | |||
1 | /* | ||
2 | * Clock definitions for u8500 platform. | ||
3 | * | ||
4 | * Copyright (C) 2012 ST-Ericsson SA | ||
5 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
6 | * | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk.h> | ||
11 | #include <linux/clkdev.h> | ||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/mfd/dbx500-prcmu.h> | ||
14 | #include <linux/platform_data/clk-ux500.h> | ||
15 | |||
16 | #include "clk.h" | ||
17 | |||
18 | void u8500_clk_init(void) | ||
19 | { | ||
20 | struct prcmu_fw_version *fw_version; | ||
21 | const char *sgaclk_parent = NULL; | ||
22 | struct clk *clk; | ||
23 | |||
24 | /* Clock sources */ | ||
25 | clk = clk_reg_prcmu_gate("soc0_pll", NULL, PRCMU_PLLSOC0, | ||
26 | CLK_IS_ROOT|CLK_IGNORE_UNUSED); | ||
27 | clk_register_clkdev(clk, "soc0_pll", NULL); | ||
28 | |||
29 | clk = clk_reg_prcmu_gate("soc1_pll", NULL, PRCMU_PLLSOC1, | ||
30 | CLK_IS_ROOT|CLK_IGNORE_UNUSED); | ||
31 | clk_register_clkdev(clk, "soc1_pll", NULL); | ||
32 | |||
33 | clk = clk_reg_prcmu_gate("ddr_pll", NULL, PRCMU_PLLDDR, | ||
34 | CLK_IS_ROOT|CLK_IGNORE_UNUSED); | ||
35 | clk_register_clkdev(clk, "ddr_pll", NULL); | ||
36 | |||
37 | /* FIXME: Add sys, ulp and int clocks here. */ | ||
38 | |||
39 | clk = clk_register_fixed_rate(NULL, "rtc32k", "NULL", | ||
40 | CLK_IS_ROOT|CLK_IGNORE_UNUSED, | ||
41 | 32768); | ||
42 | clk_register_clkdev(clk, "clk32k", NULL); | ||
43 | clk_register_clkdev(clk, NULL, "rtc-pl031"); | ||
44 | |||
45 | /* PRCMU clocks */ | ||
46 | fw_version = prcmu_get_fw_version(); | ||
47 | if (fw_version != NULL) { | ||
48 | switch (fw_version->project) { | ||
49 | case PRCMU_FW_PROJECT_U8500_C2: | ||
50 | case PRCMU_FW_PROJECT_U8520: | ||
51 | case PRCMU_FW_PROJECT_U8420: | ||
52 | sgaclk_parent = "soc0_pll"; | ||
53 | break; | ||
54 | default: | ||
55 | break; | ||
56 | } | ||
57 | } | ||
58 | |||
59 | if (sgaclk_parent) | ||
60 | clk = clk_reg_prcmu_gate("sgclk", sgaclk_parent, | ||
61 | PRCMU_SGACLK, 0); | ||
62 | else | ||
63 | clk = clk_reg_prcmu_gate("sgclk", NULL, | ||
64 | PRCMU_SGACLK, CLK_IS_ROOT); | ||
65 | clk_register_clkdev(clk, NULL, "mali"); | ||
66 | |||
67 | clk = clk_reg_prcmu_gate("uartclk", NULL, PRCMU_UARTCLK, CLK_IS_ROOT); | ||
68 | clk_register_clkdev(clk, NULL, "UART"); | ||
69 | |||
70 | clk = clk_reg_prcmu_gate("msp02clk", NULL, PRCMU_MSP02CLK, CLK_IS_ROOT); | ||
71 | clk_register_clkdev(clk, NULL, "MSP02"); | ||
72 | |||
73 | clk = clk_reg_prcmu_gate("msp1clk", NULL, PRCMU_MSP1CLK, CLK_IS_ROOT); | ||
74 | clk_register_clkdev(clk, NULL, "MSP1"); | ||
75 | |||
76 | clk = clk_reg_prcmu_gate("i2cclk", NULL, PRCMU_I2CCLK, CLK_IS_ROOT); | ||
77 | clk_register_clkdev(clk, NULL, "I2C"); | ||
78 | |||
79 | clk = clk_reg_prcmu_gate("slimclk", NULL, PRCMU_SLIMCLK, CLK_IS_ROOT); | ||
80 | clk_register_clkdev(clk, NULL, "slim"); | ||
81 | |||
82 | clk = clk_reg_prcmu_gate("per1clk", NULL, PRCMU_PER1CLK, CLK_IS_ROOT); | ||
83 | clk_register_clkdev(clk, NULL, "PERIPH1"); | ||
84 | |||
85 | clk = clk_reg_prcmu_gate("per2clk", NULL, PRCMU_PER2CLK, CLK_IS_ROOT); | ||
86 | clk_register_clkdev(clk, NULL, "PERIPH2"); | ||
87 | |||
88 | clk = clk_reg_prcmu_gate("per3clk", NULL, PRCMU_PER3CLK, CLK_IS_ROOT); | ||
89 | clk_register_clkdev(clk, NULL, "PERIPH3"); | ||
90 | |||
91 | clk = clk_reg_prcmu_gate("per5clk", NULL, PRCMU_PER5CLK, CLK_IS_ROOT); | ||
92 | clk_register_clkdev(clk, NULL, "PERIPH5"); | ||
93 | |||
94 | clk = clk_reg_prcmu_gate("per6clk", NULL, PRCMU_PER6CLK, CLK_IS_ROOT); | ||
95 | clk_register_clkdev(clk, NULL, "PERIPH6"); | ||
96 | |||
97 | clk = clk_reg_prcmu_gate("per7clk", NULL, PRCMU_PER7CLK, CLK_IS_ROOT); | ||
98 | clk_register_clkdev(clk, NULL, "PERIPH7"); | ||
99 | |||
100 | clk = clk_reg_prcmu_scalable("lcdclk", NULL, PRCMU_LCDCLK, 0, | ||
101 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
102 | clk_register_clkdev(clk, NULL, "lcd"); | ||
103 | clk_register_clkdev(clk, "lcd", "mcde"); | ||
104 | |||
105 | clk = clk_reg_prcmu_opp_gate("bmlclk", NULL, PRCMU_BMLCLK, CLK_IS_ROOT); | ||
106 | clk_register_clkdev(clk, NULL, "bml"); | ||
107 | |||
108 | clk = clk_reg_prcmu_scalable("hsitxclk", NULL, PRCMU_HSITXCLK, 0, | ||
109 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
110 | |||
111 | clk = clk_reg_prcmu_scalable("hsirxclk", NULL, PRCMU_HSIRXCLK, 0, | ||
112 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
113 | |||
114 | clk = clk_reg_prcmu_scalable("hdmiclk", NULL, PRCMU_HDMICLK, 0, | ||
115 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
116 | clk_register_clkdev(clk, NULL, "hdmi"); | ||
117 | clk_register_clkdev(clk, "hdmi", "mcde"); | ||
118 | |||
119 | clk = clk_reg_prcmu_gate("apeatclk", NULL, PRCMU_APEATCLK, CLK_IS_ROOT); | ||
120 | clk_register_clkdev(clk, NULL, "apeat"); | ||
121 | |||
122 | clk = clk_reg_prcmu_gate("apetraceclk", NULL, PRCMU_APETRACECLK, | ||
123 | CLK_IS_ROOT); | ||
124 | clk_register_clkdev(clk, NULL, "apetrace"); | ||
125 | |||
126 | clk = clk_reg_prcmu_gate("mcdeclk", NULL, PRCMU_MCDECLK, CLK_IS_ROOT); | ||
127 | clk_register_clkdev(clk, NULL, "mcde"); | ||
128 | clk_register_clkdev(clk, "mcde", "mcde"); | ||
129 | clk_register_clkdev(clk, "dsisys", "dsilink.0"); | ||
130 | clk_register_clkdev(clk, "dsisys", "dsilink.1"); | ||
131 | clk_register_clkdev(clk, "dsisys", "dsilink.2"); | ||
132 | |||
133 | clk = clk_reg_prcmu_opp_gate("ipi2cclk", NULL, PRCMU_IPI2CCLK, | ||
134 | CLK_IS_ROOT); | ||
135 | clk_register_clkdev(clk, NULL, "ipi2"); | ||
136 | |||
137 | clk = clk_reg_prcmu_gate("dsialtclk", NULL, PRCMU_DSIALTCLK, | ||
138 | CLK_IS_ROOT); | ||
139 | clk_register_clkdev(clk, NULL, "dsialt"); | ||
140 | |||
141 | clk = clk_reg_prcmu_gate("dmaclk", NULL, PRCMU_DMACLK, CLK_IS_ROOT); | ||
142 | clk_register_clkdev(clk, NULL, "dma40.0"); | ||
143 | |||
144 | clk = clk_reg_prcmu_gate("b2r2clk", NULL, PRCMU_B2R2CLK, CLK_IS_ROOT); | ||
145 | clk_register_clkdev(clk, NULL, "b2r2"); | ||
146 | clk_register_clkdev(clk, NULL, "b2r2_core"); | ||
147 | clk_register_clkdev(clk, NULL, "U8500-B2R2.0"); | ||
148 | |||
149 | clk = clk_reg_prcmu_scalable("tvclk", NULL, PRCMU_TVCLK, 0, | ||
150 | CLK_IS_ROOT|CLK_SET_RATE_GATE); | ||
151 | clk_register_clkdev(clk, NULL, "tv"); | ||
152 | clk_register_clkdev(clk, "tv", "mcde"); | ||
153 | |||
154 | clk = clk_reg_prcmu_gate("sspclk", NULL, PRCMU_SSPCLK, CLK_IS_ROOT); | ||
155 | clk_register_clkdev(clk, NULL, "SSP"); | ||
156 | |||
157 | clk = clk_reg_prcmu_gate("rngclk", NULL, PRCMU_RNGCLK, CLK_IS_ROOT); | ||
158 | clk_register_clkdev(clk, NULL, "rngclk"); | ||
159 | |||
160 | clk = clk_reg_prcmu_gate("uiccclk", NULL, PRCMU_UICCCLK, CLK_IS_ROOT); | ||
161 | clk_register_clkdev(clk, NULL, "uicc"); | ||
162 | |||
163 | /* | ||
164 | * FIXME: The MTU clocks might need some kind of "parent muxed join" | ||
165 | * and these have no K-clocks. For now, we ignore the missing | ||
166 | * connection to the corresponding P-clocks, p6_mtu0_clk and | ||
167 | * p6_mtu1_clk. Instead timclk is used which is the valid parent. | ||
168 | */ | ||
169 | clk = clk_reg_prcmu_gate("timclk", NULL, PRCMU_TIMCLK, CLK_IS_ROOT); | ||
170 | clk_register_clkdev(clk, NULL, "mtu0"); | ||
171 | clk_register_clkdev(clk, NULL, "mtu1"); | ||
172 | |||
173 | clk = clk_reg_prcmu_gate("sdmmcclk", NULL, PRCMU_SDMMCCLK, CLK_IS_ROOT); | ||
174 | clk_register_clkdev(clk, NULL, "sdmmc"); | ||
175 | |||
176 | |||
177 | clk = clk_reg_prcmu_scalable("dsi_pll", "hdmiclk", | ||
178 | PRCMU_PLLDSI, 0, CLK_SET_RATE_GATE); | ||
179 | clk_register_clkdev(clk, "dsihs2", "mcde"); | ||
180 | clk_register_clkdev(clk, "dsihs2", "dsilink.2"); | ||
181 | |||
182 | |||
183 | clk = clk_reg_prcmu_scalable("dsi0clk", "dsi_pll", | ||
184 | PRCMU_DSI0CLK, 0, CLK_SET_RATE_GATE); | ||
185 | clk_register_clkdev(clk, "dsihs0", "mcde"); | ||
186 | clk_register_clkdev(clk, "dsihs0", "dsilink.0"); | ||
187 | |||
188 | clk = clk_reg_prcmu_scalable("dsi1clk", "dsi_pll", | ||
189 | PRCMU_DSI1CLK, 0, CLK_SET_RATE_GATE); | ||
190 | clk_register_clkdev(clk, "dsihs1", "mcde"); | ||
191 | clk_register_clkdev(clk, "dsihs1", "dsilink.1"); | ||
192 | |||
193 | clk = clk_reg_prcmu_scalable("dsi0escclk", "tvclk", | ||
194 | PRCMU_DSI0ESCCLK, 0, CLK_SET_RATE_GATE); | ||
195 | clk_register_clkdev(clk, "dsilp0", "dsilink.0"); | ||
196 | clk_register_clkdev(clk, "dsilp0", "mcde"); | ||
197 | |||
198 | clk = clk_reg_prcmu_scalable("dsi1escclk", "tvclk", | ||
199 | PRCMU_DSI1ESCCLK, 0, CLK_SET_RATE_GATE); | ||
200 | clk_register_clkdev(clk, "dsilp1", "dsilink.1"); | ||
201 | clk_register_clkdev(clk, "dsilp1", "mcde"); | ||
202 | |||
203 | clk = clk_reg_prcmu_scalable("dsi2escclk", "tvclk", | ||
204 | PRCMU_DSI2ESCCLK, 0, CLK_SET_RATE_GATE); | ||
205 | clk_register_clkdev(clk, "dsilp2", "dsilink.2"); | ||
206 | clk_register_clkdev(clk, "dsilp2", "mcde"); | ||
207 | |||
208 | clk = clk_reg_prcmu_rate("smp_twd", NULL, PRCMU_ARMSS, | ||
209 | CLK_IS_ROOT|CLK_GET_RATE_NOCACHE| | ||
210 | CLK_IGNORE_UNUSED); | ||
211 | clk_register_clkdev(clk, NULL, "smp_twd"); | ||
212 | |||
213 | /* | ||
214 | * FIXME: Add special handled PRCMU clocks here: | ||
215 | * 1. clk_arm, use PRCMU_ARMCLK. | ||
216 | * 2. clkout0yuv, use PRCMU as parent + need regulator + pinctrl. | ||
217 | * 3. ab9540_clkout1yuv, see clkout0yuv | ||
218 | */ | ||
219 | |||
220 | /* PRCC P-clocks */ | ||
221 | clk = clk_reg_prcc_pclk("p1_pclk0", "per1clk", U8500_CLKRST1_BASE, | ||
222 | BIT(0), 0); | ||
223 | clk_register_clkdev(clk, "apb_pclk", "uart0"); | ||
224 | |||
225 | clk = clk_reg_prcc_pclk("p1_pclk1", "per1clk", U8500_CLKRST1_BASE, | ||
226 | BIT(1), 0); | ||
227 | clk_register_clkdev(clk, "apb_pclk", "uart1"); | ||
228 | |||
229 | clk = clk_reg_prcc_pclk("p1_pclk2", "per1clk", U8500_CLKRST1_BASE, | ||
230 | BIT(2), 0); | ||
231 | clk = clk_reg_prcc_pclk("p1_pclk3", "per1clk", U8500_CLKRST1_BASE, | ||
232 | BIT(3), 0); | ||
233 | clk = clk_reg_prcc_pclk("p1_pclk4", "per1clk", U8500_CLKRST1_BASE, | ||
234 | BIT(4), 0); | ||
235 | |||
236 | clk = clk_reg_prcc_pclk("p1_pclk5", "per1clk", U8500_CLKRST1_BASE, | ||
237 | BIT(5), 0); | ||
238 | clk_register_clkdev(clk, "apb_pclk", "sdi0"); | ||
239 | |||
240 | clk = clk_reg_prcc_pclk("p1_pclk6", "per1clk", U8500_CLKRST1_BASE, | ||
241 | BIT(6), 0); | ||
242 | |||
243 | clk = clk_reg_prcc_pclk("p1_pclk7", "per1clk", U8500_CLKRST1_BASE, | ||
244 | BIT(7), 0); | ||
245 | clk_register_clkdev(clk, NULL, "spi3"); | ||
246 | |||
247 | clk = clk_reg_prcc_pclk("p1_pclk8", "per1clk", U8500_CLKRST1_BASE, | ||
248 | BIT(8), 0); | ||
249 | |||
250 | clk = clk_reg_prcc_pclk("p1_pclk9", "per1clk", U8500_CLKRST1_BASE, | ||
251 | BIT(9), 0); | ||
252 | clk_register_clkdev(clk, NULL, "gpio.0"); | ||
253 | clk_register_clkdev(clk, NULL, "gpio.1"); | ||
254 | clk_register_clkdev(clk, NULL, "gpioblock0"); | ||
255 | |||
256 | clk = clk_reg_prcc_pclk("p1_pclk10", "per1clk", U8500_CLKRST1_BASE, | ||
257 | BIT(10), 0); | ||
258 | clk = clk_reg_prcc_pclk("p1_pclk11", "per1clk", U8500_CLKRST1_BASE, | ||
259 | BIT(11), 0); | ||
260 | |||
261 | clk = clk_reg_prcc_pclk("p2_pclk0", "per2clk", U8500_CLKRST2_BASE, | ||
262 | BIT(0), 0); | ||
263 | |||
264 | clk = clk_reg_prcc_pclk("p2_pclk1", "per2clk", U8500_CLKRST2_BASE, | ||
265 | BIT(1), 0); | ||
266 | clk_register_clkdev(clk, NULL, "spi2"); | ||
267 | |||
268 | clk = clk_reg_prcc_pclk("p2_pclk2", "per2clk", U8500_CLKRST2_BASE, | ||
269 | BIT(2), 0); | ||
270 | clk_register_clkdev(clk, NULL, "spi1"); | ||
271 | |||
272 | clk = clk_reg_prcc_pclk("p2_pclk3", "per2clk", U8500_CLKRST2_BASE, | ||
273 | BIT(3), 0); | ||
274 | clk_register_clkdev(clk, NULL, "pwl"); | ||
275 | |||
276 | clk = clk_reg_prcc_pclk("p2_pclk4", "per2clk", U8500_CLKRST2_BASE, | ||
277 | BIT(4), 0); | ||
278 | clk_register_clkdev(clk, "apb_pclk", "sdi4"); | ||
279 | |||
280 | clk = clk_reg_prcc_pclk("p2_pclk5", "per2clk", U8500_CLKRST2_BASE, | ||
281 | BIT(5), 0); | ||
282 | |||
283 | clk = clk_reg_prcc_pclk("p2_pclk6", "per2clk", U8500_CLKRST2_BASE, | ||
284 | BIT(6), 0); | ||
285 | clk_register_clkdev(clk, "apb_pclk", "sdi1"); | ||
286 | |||
287 | |||
288 | clk = clk_reg_prcc_pclk("p2_pclk7", "per2clk", U8500_CLKRST2_BASE, | ||
289 | BIT(7), 0); | ||
290 | clk_register_clkdev(clk, "apb_pclk", "sdi3"); | ||
291 | |||
292 | clk = clk_reg_prcc_pclk("p2_pclk8", "per2clk", U8500_CLKRST2_BASE, | ||
293 | BIT(8), 0); | ||
294 | clk_register_clkdev(clk, NULL, "spi0"); | ||
295 | |||
296 | clk = clk_reg_prcc_pclk("p2_pclk9", "per2clk", U8500_CLKRST2_BASE, | ||
297 | BIT(9), 0); | ||
298 | clk_register_clkdev(clk, "hsir_hclk", "ste_hsi.0"); | ||
299 | |||
300 | clk = clk_reg_prcc_pclk("p2_pclk10", "per2clk", U8500_CLKRST2_BASE, | ||
301 | BIT(10), 0); | ||
302 | clk_register_clkdev(clk, "hsit_hclk", "ste_hsi.0"); | ||
303 | |||
304 | clk = clk_reg_prcc_pclk("p2_pclk11", "per2clk", U8500_CLKRST2_BASE, | ||
305 | BIT(11), 0); | ||
306 | clk_register_clkdev(clk, NULL, "gpio.6"); | ||
307 | clk_register_clkdev(clk, NULL, "gpio.7"); | ||
308 | clk_register_clkdev(clk, NULL, "gpioblock1"); | ||
309 | |||
310 | clk = clk_reg_prcc_pclk("p2_pclk12", "per2clk", U8500_CLKRST2_BASE, | ||
311 | BIT(11), 0); | ||
312 | |||
313 | clk = clk_reg_prcc_pclk("p3_pclk0", "per3clk", U8500_CLKRST3_BASE, | ||
314 | BIT(0), 0); | ||
315 | clk_register_clkdev(clk, NULL, "fsmc"); | ||
316 | |||
317 | clk = clk_reg_prcc_pclk("p3_pclk1", "per3clk", U8500_CLKRST3_BASE, | ||
318 | BIT(1), 0); | ||
319 | clk = clk_reg_prcc_pclk("p3_pclk2", "per3clk", U8500_CLKRST3_BASE, | ||
320 | BIT(2), 0); | ||
321 | clk = clk_reg_prcc_pclk("p3_pclk3", "per3clk", U8500_CLKRST3_BASE, | ||
322 | BIT(3), 0); | ||
323 | |||
324 | clk = clk_reg_prcc_pclk("p3_pclk4", "per3clk", U8500_CLKRST3_BASE, | ||
325 | BIT(4), 0); | ||
326 | clk_register_clkdev(clk, "apb_pclk", "sdi2"); | ||
327 | |||
328 | clk = clk_reg_prcc_pclk("p3_pclk5", "per3clk", U8500_CLKRST3_BASE, | ||
329 | BIT(5), 0); | ||
330 | |||
331 | clk = clk_reg_prcc_pclk("p3_pclk6", "per3clk", U8500_CLKRST3_BASE, | ||
332 | BIT(6), 0); | ||
333 | clk_register_clkdev(clk, "apb_pclk", "uart2"); | ||
334 | |||
335 | clk = clk_reg_prcc_pclk("p3_pclk7", "per3clk", U8500_CLKRST3_BASE, | ||
336 | BIT(7), 0); | ||
337 | clk_register_clkdev(clk, "apb_pclk", "sdi5"); | ||
338 | |||
339 | clk = clk_reg_prcc_pclk("p3_pclk8", "per3clk", U8500_CLKRST3_BASE, | ||
340 | BIT(8), 0); | ||
341 | clk_register_clkdev(clk, NULL, "gpio.2"); | ||
342 | clk_register_clkdev(clk, NULL, "gpio.3"); | ||
343 | clk_register_clkdev(clk, NULL, "gpio.4"); | ||
344 | clk_register_clkdev(clk, NULL, "gpio.5"); | ||
345 | clk_register_clkdev(clk, NULL, "gpioblock2"); | ||
346 | |||
347 | clk = clk_reg_prcc_pclk("p5_pclk0", "per5clk", U8500_CLKRST5_BASE, | ||
348 | BIT(0), 0); | ||
349 | clk_register_clkdev(clk, "usb", "musb-ux500.0"); | ||
350 | |||
351 | clk = clk_reg_prcc_pclk("p5_pclk1", "per5clk", U8500_CLKRST5_BASE, | ||
352 | BIT(1), 0); | ||
353 | clk_register_clkdev(clk, NULL, "gpio.8"); | ||
354 | clk_register_clkdev(clk, NULL, "gpioblock3"); | ||
355 | |||
356 | clk = clk_reg_prcc_pclk("p6_pclk0", "per6clk", U8500_CLKRST6_BASE, | ||
357 | BIT(0), 0); | ||
358 | |||
359 | clk = clk_reg_prcc_pclk("p6_pclk1", "per6clk", U8500_CLKRST6_BASE, | ||
360 | BIT(1), 0); | ||
361 | clk_register_clkdev(clk, NULL, "cryp0"); | ||
362 | clk_register_clkdev(clk, NULL, "cryp1"); | ||
363 | |||
364 | clk = clk_reg_prcc_pclk("p6_pclk2", "per6clk", U8500_CLKRST6_BASE, | ||
365 | BIT(2), 0); | ||
366 | clk_register_clkdev(clk, NULL, "hash0"); | ||
367 | |||
368 | clk = clk_reg_prcc_pclk("p6_pclk3", "per6clk", U8500_CLKRST6_BASE, | ||
369 | BIT(3), 0); | ||
370 | clk_register_clkdev(clk, NULL, "pka"); | ||
371 | |||
372 | clk = clk_reg_prcc_pclk("p6_pclk4", "per6clk", U8500_CLKRST6_BASE, | ||
373 | BIT(4), 0); | ||
374 | clk_register_clkdev(clk, NULL, "hash1"); | ||
375 | |||
376 | clk = clk_reg_prcc_pclk("p6_pclk5", "per6clk", U8500_CLKRST6_BASE, | ||
377 | BIT(5), 0); | ||
378 | clk_register_clkdev(clk, NULL, "cfgreg"); | ||
379 | |||
380 | clk = clk_reg_prcc_pclk("p6_pclk6", "per6clk", U8500_CLKRST6_BASE, | ||
381 | BIT(6), 0); | ||
382 | clk = clk_reg_prcc_pclk("p6_pclk7", "per6clk", U8500_CLKRST6_BASE, | ||
383 | BIT(7), 0); | ||
384 | |||
385 | /* PRCC K-clocks | ||
386 | * | ||
387 | * FIXME: Some drivers requires PERPIH[n| to be automatically enabled | ||
388 | * by enabling just the K-clock, even if it is not a valid parent to | ||
389 | * the K-clock. Until drivers get fixed we might need some kind of | ||
390 | * "parent muxed join". | ||
391 | */ | ||
392 | |||
393 | /* Periph1 */ | ||
394 | clk = clk_reg_prcc_kclk("p1_uart0_kclk", "uartclk", | ||
395 | U8500_CLKRST1_BASE, BIT(0), CLK_SET_RATE_GATE); | ||
396 | clk_register_clkdev(clk, NULL, "uart0"); | ||
397 | |||
398 | clk = clk_reg_prcc_kclk("p1_uart1_kclk", "uartclk", | ||
399 | U8500_CLKRST1_BASE, BIT(1), CLK_SET_RATE_GATE); | ||
400 | clk_register_clkdev(clk, NULL, "uart1"); | ||
401 | |||
402 | clk = clk_reg_prcc_kclk("p1_i2c1_kclk", "i2cclk", | ||
403 | U8500_CLKRST1_BASE, BIT(2), CLK_SET_RATE_GATE); | ||
404 | clk = clk_reg_prcc_kclk("p1_msp0_kclk", "msp02clk", | ||
405 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); | ||
406 | clk = clk_reg_prcc_kclk("p1_msp1_kclk", "msp1clk", | ||
407 | U8500_CLKRST1_BASE, BIT(4), CLK_SET_RATE_GATE); | ||
408 | |||
409 | clk = clk_reg_prcc_kclk("p1_sdi0_kclk", "sdmmcclk", | ||
410 | U8500_CLKRST1_BASE, BIT(5), CLK_SET_RATE_GATE); | ||
411 | clk_register_clkdev(clk, NULL, "sdi0"); | ||
412 | |||
413 | clk = clk_reg_prcc_kclk("p1_i2c2_kclk", "i2cclk", | ||
414 | U8500_CLKRST1_BASE, BIT(6), CLK_SET_RATE_GATE); | ||
415 | clk = clk_reg_prcc_kclk("p1_slimbus0_kclk", "slimclk", | ||
416 | U8500_CLKRST1_BASE, BIT(3), CLK_SET_RATE_GATE); | ||
417 | /* FIXME: Redefinition of BIT(3). */ | ||
418 | clk = clk_reg_prcc_kclk("p1_i2c4_kclk", "i2cclk", | ||
419 | U8500_CLKRST1_BASE, BIT(9), CLK_SET_RATE_GATE); | ||
420 | clk = clk_reg_prcc_kclk("p1_msp3_kclk", "msp1clk", | ||
421 | U8500_CLKRST1_BASE, BIT(10), CLK_SET_RATE_GATE); | ||
422 | |||
423 | /* Periph2 */ | ||
424 | clk = clk_reg_prcc_kclk("p2_i2c3_kclk", "i2cclk", | ||
425 | U8500_CLKRST2_BASE, BIT(0), CLK_SET_RATE_GATE); | ||
426 | |||
427 | clk = clk_reg_prcc_kclk("p2_sdi4_kclk", "sdmmcclk", | ||
428 | U8500_CLKRST2_BASE, BIT(2), CLK_SET_RATE_GATE); | ||
429 | clk_register_clkdev(clk, NULL, "sdi4"); | ||
430 | |||
431 | clk = clk_reg_prcc_kclk("p2_msp2_kclk", "msp02clk", | ||
432 | U8500_CLKRST2_BASE, BIT(3), CLK_SET_RATE_GATE); | ||
433 | |||
434 | clk = clk_reg_prcc_kclk("p2_sdi1_kclk", "sdmmcclk", | ||
435 | U8500_CLKRST2_BASE, BIT(4), CLK_SET_RATE_GATE); | ||
436 | clk_register_clkdev(clk, NULL, "sdi1"); | ||
437 | |||
438 | clk = clk_reg_prcc_kclk("p2_sdi3_kclk", "sdmmcclk", | ||
439 | U8500_CLKRST2_BASE, BIT(5), CLK_SET_RATE_GATE); | ||
440 | clk_register_clkdev(clk, NULL, "sdi3"); | ||
441 | |||
442 | /* Note that rate is received from parent. */ | ||
443 | clk = clk_reg_prcc_kclk("p2_ssirx_kclk", "hsirxclk", | ||
444 | U8500_CLKRST2_BASE, BIT(6), | ||
445 | CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT); | ||
446 | clk = clk_reg_prcc_kclk("p2_ssitx_kclk", "hsitxclk", | ||
447 | U8500_CLKRST2_BASE, BIT(7), | ||
448 | CLK_SET_RATE_GATE|CLK_SET_RATE_PARENT); | ||
449 | |||
450 | /* Periph3 */ | ||
451 | clk = clk_reg_prcc_kclk("p3_ssp0_kclk", "sspclk", | ||
452 | U8500_CLKRST3_BASE, BIT(1), CLK_SET_RATE_GATE); | ||
453 | clk = clk_reg_prcc_kclk("p3_ssp1_kclk", "sspclk", | ||
454 | U8500_CLKRST3_BASE, BIT(2), CLK_SET_RATE_GATE); | ||
455 | clk = clk_reg_prcc_kclk("p3_i2c0_kclk", "i2cclk", | ||
456 | U8500_CLKRST3_BASE, BIT(3), CLK_SET_RATE_GATE); | ||
457 | |||
458 | clk = clk_reg_prcc_kclk("p3_sdi2_kclk", "sdmmcclk", | ||
459 | U8500_CLKRST3_BASE, BIT(4), CLK_SET_RATE_GATE); | ||
460 | clk_register_clkdev(clk, NULL, "sdi2"); | ||
461 | |||
462 | clk = clk_reg_prcc_kclk("p3_ske_kclk", "rtc32k", | ||
463 | U8500_CLKRST3_BASE, BIT(5), CLK_SET_RATE_GATE); | ||
464 | |||
465 | clk = clk_reg_prcc_kclk("p3_uart2_kclk", "uartclk", | ||
466 | U8500_CLKRST3_BASE, BIT(6), CLK_SET_RATE_GATE); | ||
467 | clk_register_clkdev(clk, NULL, "uart2"); | ||
468 | |||
469 | clk = clk_reg_prcc_kclk("p3_sdi5_kclk", "sdmmcclk", | ||
470 | U8500_CLKRST3_BASE, BIT(7), CLK_SET_RATE_GATE); | ||
471 | clk_register_clkdev(clk, NULL, "sdi5"); | ||
472 | |||
473 | /* Periph6 */ | ||
474 | clk = clk_reg_prcc_kclk("p3_rng_kclk", "rngclk", | ||
475 | U8500_CLKRST6_BASE, BIT(0), CLK_SET_RATE_GATE); | ||
476 | |||
477 | } | ||
diff --git a/drivers/clk/ux500/u8540_clk.c b/drivers/clk/ux500/u8540_clk.c new file mode 100644 index 000000000000..10adfd2ead21 --- /dev/null +++ b/drivers/clk/ux500/u8540_clk.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Clock definitions for u8540 platform. | ||
3 | * | ||
4 | * Copyright (C) 2012 ST-Ericsson SA | ||
5 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
6 | * | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk.h> | ||
11 | #include <linux/clkdev.h> | ||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/mfd/dbx500-prcmu.h> | ||
14 | #include <linux/platform_data/clk-ux500.h> | ||
15 | |||
16 | #include "clk.h" | ||
17 | |||
18 | void u8540_clk_init(void) | ||
19 | { | ||
20 | /* register clocks here */ | ||
21 | } | ||
diff --git a/drivers/clk/ux500/u9540_clk.c b/drivers/clk/ux500/u9540_clk.c new file mode 100644 index 000000000000..dbc0191e16c8 --- /dev/null +++ b/drivers/clk/ux500/u9540_clk.c | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Clock definitions for u9540 platform. | ||
3 | * | ||
4 | * Copyright (C) 2012 ST-Ericsson SA | ||
5 | * Author: Ulf Hansson <ulf.hansson@linaro.org> | ||
6 | * | ||
7 | * License terms: GNU General Public License (GPL) version 2 | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk.h> | ||
11 | #include <linux/clkdev.h> | ||
12 | #include <linux/clk-provider.h> | ||
13 | #include <linux/mfd/dbx500-prcmu.h> | ||
14 | #include <linux/platform_data/clk-ux500.h> | ||
15 | |||
16 | #include "clk.h" | ||
17 | |||
18 | void u9540_clk_init(void) | ||
19 | { | ||
20 | /* register clocks here */ | ||
21 | } | ||
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index 50cf6a2ee693..c0a0f6478798 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | # Makefile for Versatile-specific clocks | 1 | # Makefile for Versatile-specific clocks |
2 | obj-$(CONFIG_ICST) += clk-icst.o | 2 | obj-$(CONFIG_ICST) += clk-icst.o |
3 | obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o | 3 | obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o |
4 | obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o | ||
diff --git a/drivers/clk/versatile/clk-realview.c b/drivers/clk/versatile/clk-realview.c new file mode 100644 index 000000000000..e21a99cef378 --- /dev/null +++ b/drivers/clk/versatile/clk-realview.c | |||
@@ -0,0 +1,114 @@ | |||
1 | #include <linux/clk.h> | ||
2 | #include <linux/clkdev.h> | ||
3 | #include <linux/err.h> | ||
4 | #include <linux/io.h> | ||
5 | #include <linux/clk-provider.h> | ||
6 | |||
7 | #include <mach/hardware.h> | ||
8 | #include <mach/platform.h> | ||
9 | |||
10 | #include "clk-icst.h" | ||
11 | |||
12 | /* | ||
13 | * Implementation of the ARM RealView clock trees. | ||
14 | */ | ||
15 | |||
16 | static void __iomem *sys_lock; | ||
17 | static void __iomem *sys_vcoreg; | ||
18 | |||
19 | /** | ||
20 | * realview_oscvco_get() - get ICST OSC settings for the RealView | ||
21 | */ | ||
22 | static struct icst_vco realview_oscvco_get(void) | ||
23 | { | ||
24 | u32 val; | ||
25 | struct icst_vco vco; | ||
26 | |||
27 | val = readl(sys_vcoreg); | ||
28 | vco.v = val & 0x1ff; | ||
29 | vco.r = (val >> 9) & 0x7f; | ||
30 | vco.s = (val >> 16) & 03; | ||
31 | return vco; | ||
32 | } | ||
33 | |||
34 | static void realview_oscvco_set(struct icst_vco vco) | ||
35 | { | ||
36 | u32 val; | ||
37 | |||
38 | val = readl(sys_vcoreg) & ~0x7ffff; | ||
39 | val |= vco.v | (vco.r << 9) | (vco.s << 16); | ||
40 | |||
41 | /* This magic unlocks the CM VCO so it can be controlled */ | ||
42 | writel(0xa05f, sys_lock); | ||
43 | writel(val, sys_vcoreg); | ||
44 | /* This locks the CM again */ | ||
45 | writel(0, sys_lock); | ||
46 | } | ||
47 | |||
48 | static const struct icst_params realview_oscvco_params = { | ||
49 | .ref = 24000000, | ||
50 | .vco_max = ICST307_VCO_MAX, | ||
51 | .vco_min = ICST307_VCO_MIN, | ||
52 | .vd_min = 4 + 8, | ||
53 | .vd_max = 511 + 8, | ||
54 | .rd_min = 1 + 2, | ||
55 | .rd_max = 127 + 2, | ||
56 | .s2div = icst307_s2div, | ||
57 | .idx2s = icst307_idx2s, | ||
58 | }; | ||
59 | |||
60 | static const struct clk_icst_desc __initdata realview_icst_desc = { | ||
61 | .params = &realview_oscvco_params, | ||
62 | .getvco = realview_oscvco_get, | ||
63 | .setvco = realview_oscvco_set, | ||
64 | }; | ||
65 | |||
66 | /* | ||
67 | * realview_clk_init() - set up the RealView clock tree | ||
68 | */ | ||
69 | void __init realview_clk_init(void __iomem *sysbase, bool is_pb1176) | ||
70 | { | ||
71 | struct clk *clk; | ||
72 | |||
73 | sys_lock = sysbase + REALVIEW_SYS_LOCK_OFFSET; | ||
74 | if (is_pb1176) | ||
75 | sys_vcoreg = sysbase + REALVIEW_SYS_OSC0_OFFSET; | ||
76 | else | ||
77 | sys_vcoreg = sysbase + REALVIEW_SYS_OSC4_OFFSET; | ||
78 | |||
79 | |||
80 | /* APB clock dummy */ | ||
81 | clk = clk_register_fixed_rate(NULL, "apb_pclk", NULL, CLK_IS_ROOT, 0); | ||
82 | clk_register_clkdev(clk, "apb_pclk", NULL); | ||
83 | |||
84 | /* 24 MHz clock */ | ||
85 | clk = clk_register_fixed_rate(NULL, "clk24mhz", NULL, CLK_IS_ROOT, | ||
86 | 24000000); | ||
87 | clk_register_clkdev(clk, NULL, "dev:uart0"); | ||
88 | clk_register_clkdev(clk, NULL, "dev:uart1"); | ||
89 | clk_register_clkdev(clk, NULL, "dev:uart2"); | ||
90 | clk_register_clkdev(clk, NULL, "fpga:kmi0"); | ||
91 | clk_register_clkdev(clk, NULL, "fpga:kmi1"); | ||
92 | clk_register_clkdev(clk, NULL, "fpga:mmc0"); | ||
93 | clk_register_clkdev(clk, NULL, "dev:ssp0"); | ||
94 | if (is_pb1176) { | ||
95 | /* | ||
96 | * UART3 is on the dev chip in PB1176 | ||
97 | * UART4 only exists in PB1176 | ||
98 | */ | ||
99 | clk_register_clkdev(clk, NULL, "dev:uart3"); | ||
100 | clk_register_clkdev(clk, NULL, "dev:uart4"); | ||
101 | } else | ||
102 | clk_register_clkdev(clk, NULL, "fpga:uart3"); | ||
103 | |||
104 | |||
105 | /* 1 MHz clock */ | ||
106 | clk = clk_register_fixed_rate(NULL, "clk1mhz", NULL, CLK_IS_ROOT, | ||
107 | 1000000); | ||
108 | clk_register_clkdev(clk, NULL, "sp804"); | ||
109 | |||
110 | /* ICST VCO clock */ | ||
111 | clk = icst_clk_register(NULL, &realview_icst_desc); | ||
112 | clk_register_clkdev(clk, NULL, "dev:clcd"); | ||
113 | clk_register_clkdev(clk, NULL, "issp:clcd"); | ||
114 | } | ||
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index b65d0c56ab35..d496a55f6bb0 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -13,3 +13,4 @@ obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o | |||
13 | obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o | 13 | obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o |
14 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o | 14 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o |
15 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o | 15 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o |
16 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o | ||
diff --git a/drivers/clocksource/bcm2835_timer.c b/drivers/clocksource/bcm2835_timer.c new file mode 100644 index 000000000000..bc19f12c20ce --- /dev/null +++ b/drivers/clocksource/bcm2835_timer.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Simon Arlott | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | |||
19 | #include <linux/bcm2835_timer.h> | ||
20 | #include <linux/bitops.h> | ||
21 | #include <linux/clockchips.h> | ||
22 | #include <linux/clocksource.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/irqreturn.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/of_address.h> | ||
28 | #include <linux/of_irq.h> | ||
29 | #include <linux/of_platform.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/string.h> | ||
32 | |||
33 | #include <asm/sched_clock.h> | ||
34 | #include <asm/irq.h> | ||
35 | |||
36 | #define REG_CONTROL 0x00 | ||
37 | #define REG_COUNTER_LO 0x04 | ||
38 | #define REG_COUNTER_HI 0x08 | ||
39 | #define REG_COMPARE(n) (0x0c + (n) * 4) | ||
40 | #define MAX_TIMER 3 | ||
41 | #define DEFAULT_TIMER 3 | ||
42 | |||
43 | struct bcm2835_timer { | ||
44 | void __iomem *control; | ||
45 | void __iomem *compare; | ||
46 | int match_mask; | ||
47 | struct clock_event_device evt; | ||
48 | struct irqaction act; | ||
49 | }; | ||
50 | |||
51 | static void __iomem *system_clock __read_mostly; | ||
52 | |||
53 | static u32 notrace bcm2835_sched_read(void) | ||
54 | { | ||
55 | return readl_relaxed(system_clock); | ||
56 | } | ||
57 | |||
58 | static void bcm2835_time_set_mode(enum clock_event_mode mode, | ||
59 | struct clock_event_device *evt_dev) | ||
60 | { | ||
61 | switch (mode) { | ||
62 | case CLOCK_EVT_MODE_ONESHOT: | ||
63 | case CLOCK_EVT_MODE_UNUSED: | ||
64 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
65 | case CLOCK_EVT_MODE_RESUME: | ||
66 | break; | ||
67 | default: | ||
68 | WARN(1, "%s: unhandled event mode %d\n", __func__, mode); | ||
69 | break; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | static int bcm2835_time_set_next_event(unsigned long event, | ||
74 | struct clock_event_device *evt_dev) | ||
75 | { | ||
76 | struct bcm2835_timer *timer = container_of(evt_dev, | ||
77 | struct bcm2835_timer, evt); | ||
78 | writel_relaxed(readl_relaxed(system_clock) + event, | ||
79 | timer->compare); | ||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static irqreturn_t bcm2835_time_interrupt(int irq, void *dev_id) | ||
84 | { | ||
85 | struct bcm2835_timer *timer = dev_id; | ||
86 | void (*event_handler)(struct clock_event_device *); | ||
87 | if (readl_relaxed(timer->control) & timer->match_mask) { | ||
88 | writel_relaxed(timer->match_mask, timer->control); | ||
89 | |||
90 | event_handler = ACCESS_ONCE(timer->evt.event_handler); | ||
91 | if (event_handler) | ||
92 | event_handler(&timer->evt); | ||
93 | return IRQ_HANDLED; | ||
94 | } else { | ||
95 | return IRQ_NONE; | ||
96 | } | ||
97 | } | ||
98 | |||
99 | static struct of_device_id bcm2835_time_match[] __initconst = { | ||
100 | { .compatible = "brcm,bcm2835-system-timer" }, | ||
101 | {} | ||
102 | }; | ||
103 | |||
104 | static void __init bcm2835_time_init(void) | ||
105 | { | ||
106 | struct device_node *node; | ||
107 | void __iomem *base; | ||
108 | u32 freq; | ||
109 | int irq; | ||
110 | struct bcm2835_timer *timer; | ||
111 | |||
112 | node = of_find_matching_node(NULL, bcm2835_time_match); | ||
113 | if (!node) | ||
114 | panic("No bcm2835 timer node"); | ||
115 | |||
116 | base = of_iomap(node, 0); | ||
117 | if (!base) | ||
118 | panic("Can't remap registers"); | ||
119 | |||
120 | if (of_property_read_u32(node, "clock-frequency", &freq)) | ||
121 | panic("Can't read clock-frequency"); | ||
122 | |||
123 | system_clock = base + REG_COUNTER_LO; | ||
124 | setup_sched_clock(bcm2835_sched_read, 32, freq); | ||
125 | |||
126 | clocksource_mmio_init(base + REG_COUNTER_LO, node->name, | ||
127 | freq, 300, 32, clocksource_mmio_readl_up); | ||
128 | |||
129 | irq = irq_of_parse_and_map(node, DEFAULT_TIMER); | ||
130 | if (irq <= 0) | ||
131 | panic("Can't parse IRQ"); | ||
132 | |||
133 | timer = kzalloc(sizeof(*timer), GFP_KERNEL); | ||
134 | if (!timer) | ||
135 | panic("Can't allocate timer struct\n"); | ||
136 | |||
137 | timer->control = base + REG_CONTROL; | ||
138 | timer->compare = base + REG_COMPARE(DEFAULT_TIMER); | ||
139 | timer->match_mask = BIT(DEFAULT_TIMER); | ||
140 | timer->evt.name = node->name; | ||
141 | timer->evt.rating = 300; | ||
142 | timer->evt.features = CLOCK_EVT_FEAT_ONESHOT; | ||
143 | timer->evt.set_mode = bcm2835_time_set_mode; | ||
144 | timer->evt.set_next_event = bcm2835_time_set_next_event; | ||
145 | timer->evt.cpumask = cpumask_of(0); | ||
146 | timer->act.name = node->name; | ||
147 | timer->act.flags = IRQF_TIMER | IRQF_SHARED; | ||
148 | timer->act.dev_id = timer; | ||
149 | timer->act.handler = bcm2835_time_interrupt; | ||
150 | |||
151 | if (setup_irq(irq, &timer->act)) | ||
152 | panic("Can't set up timer IRQ\n"); | ||
153 | |||
154 | clockevents_config_and_register(&timer->evt, freq, 0xf, 0xffffffff); | ||
155 | |||
156 | pr_info("bcm2835: system timer (irq = %d)\n", irq); | ||
157 | } | ||
158 | |||
159 | struct sys_timer bcm2835_timer = { | ||
160 | .init = bcm2835_time_init, | ||
161 | }; | ||
diff --git a/drivers/crypto/caam/key_gen.c b/drivers/crypto/caam/key_gen.c index 002888185f17..d216cd3cc569 100644 --- a/drivers/crypto/caam/key_gen.c +++ b/drivers/crypto/caam/key_gen.c | |||
@@ -120,3 +120,4 @@ u32 gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len, | |||
120 | 120 | ||
121 | return ret; | 121 | return ret; |
122 | } | 122 | } |
123 | EXPORT_SYMBOL(gen_split_key); | ||
diff --git a/drivers/crypto/ux500/cryp/cryp_core.c b/drivers/crypto/ux500/cryp/cryp_core.c index 1c307e1b840c..ef17e3871c71 100644 --- a/drivers/crypto/ux500/cryp/cryp_core.c +++ b/drivers/crypto/ux500/cryp/cryp_core.c | |||
@@ -32,7 +32,7 @@ | |||
32 | 32 | ||
33 | #include <plat/ste_dma40.h> | 33 | #include <plat/ste_dma40.h> |
34 | 34 | ||
35 | #include <mach/crypto-ux500.h> | 35 | #include <linux/platform_data/crypto-ux500.h> |
36 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
37 | 37 | ||
38 | #include "cryp_p.h" | 38 | #include "cryp_p.h" |
diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c index 08d5032cb564..08765072a2b3 100644 --- a/drivers/crypto/ux500/hash/hash_core.c +++ b/drivers/crypto/ux500/hash/hash_core.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <crypto/scatterwalk.h> | 31 | #include <crypto/scatterwalk.h> |
32 | #include <crypto/algapi.h> | 32 | #include <crypto/algapi.h> |
33 | 33 | ||
34 | #include <mach/crypto-ux500.h> | 34 | #include <linux/platform_data/crypto-ux500.h> |
35 | #include <mach/hardware.h> | 35 | #include <mach/hardware.h> |
36 | 36 | ||
37 | #include "hash_alg.h" | 37 | #include "hash_alg.h" |
diff --git a/drivers/dma/at_hdmac_regs.h b/drivers/dma/at_hdmac_regs.h index 8a6c8e8b2940..116e4adffb08 100644 --- a/drivers/dma/at_hdmac_regs.h +++ b/drivers/dma/at_hdmac_regs.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #ifndef AT_HDMAC_REGS_H | 11 | #ifndef AT_HDMAC_REGS_H |
12 | #define AT_HDMAC_REGS_H | 12 | #define AT_HDMAC_REGS_H |
13 | 13 | ||
14 | #include <mach/at_hdmac.h> | 14 | #include <linux/platform_data/dma-atmel.h> |
15 | 15 | ||
16 | #define AT_DMA_MAX_NR_CHANNELS 8 | 16 | #define AT_DMA_MAX_NR_CHANNELS 8 |
17 | 17 | ||
diff --git a/drivers/dma/ep93xx_dma.c b/drivers/dma/ep93xx_dma.c index c64917ec313d..4aeaea77f72e 100644 --- a/drivers/dma/ep93xx_dma.c +++ b/drivers/dma/ep93xx_dma.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | #include <mach/dma.h> | 29 | #include <linux/platform_data/dma-ep93xx.h> |
30 | 30 | ||
31 | #include "dmaengine.h" | 31 | #include "dmaengine.h" |
32 | 32 | ||
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index 5084975d793c..b90aaec4ccc4 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | 29 | ||
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | #include <mach/dma.h> | 31 | #include <linux/platform_data/dma-imx.h> |
32 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
33 | 33 | ||
34 | #include "dmaengine.h" | 34 | #include "dmaengine.h" |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 1dc2a4ad0026..1b781d6ac425 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -38,8 +38,8 @@ | |||
38 | #include <linux/of_device.h> | 38 | #include <linux/of_device.h> |
39 | 39 | ||
40 | #include <asm/irq.h> | 40 | #include <asm/irq.h> |
41 | #include <mach/sdma.h> | 41 | #include <linux/platform_data/dma-imx-sdma.h> |
42 | #include <mach/dma.h> | 42 | #include <linux/platform_data/dma-imx.h> |
43 | #include <mach/hardware.h> | 43 | #include <mach/hardware.h> |
44 | 44 | ||
45 | #include "dmaengine.h" | 45 | #include "dmaengine.h" |
diff --git a/drivers/dma/mmp_tdma.c b/drivers/dma/mmp_tdma.c index 8a15cf2163dc..07fa48688ba9 100644 --- a/drivers/dma/mmp_tdma.c +++ b/drivers/dma/mmp_tdma.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <mach/regs-icu.h> | 21 | #include <mach/regs-icu.h> |
22 | #include <mach/sram.h> | 22 | #include <linux/platform_data/dma-mmp_tdma.h> |
23 | 23 | ||
24 | #include "dmaengine.h" | 24 | #include "dmaengine.h" |
25 | 25 | ||
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 0b12e68bf79c..e362e2b80efb 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/memory.h> | 27 | #include <linux/memory.h> |
28 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
29 | #include <plat/mv_xor.h> | 29 | #include <linux/platform_data/dma-mv_xor.h> |
30 | 30 | ||
31 | #include "dmaengine.h" | 31 | #include "dmaengine.h" |
32 | #include "mv_xor.h" | 32 | #include "mv_xor.h" |
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c index ae0561826137..2e1662777661 100644 --- a/drivers/dma/omap-dma.c +++ b/drivers/dma/omap-dma.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
19 | 19 | ||
20 | #include "virt-dma.h" | 20 | #include "virt-dma.h" |
21 | |||
22 | #include <plat/cpu.h> | ||
21 | #include <plat/dma.h> | 23 | #include <plat/dma.h> |
22 | 24 | ||
23 | struct omap_dmadev { | 25 | struct omap_dmadev { |
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index 920a609b2c35..38f9e52f358b 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c | |||
@@ -669,13 +669,18 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev) | |||
669 | } | 669 | } |
670 | info->dev = &pdev->dev; | 670 | info->dev = &pdev->dev; |
671 | info->max77693 = max77693; | 671 | info->max77693 = max77693; |
672 | info->max77693->regmap_muic = regmap_init_i2c(info->max77693->muic, | 672 | if (info->max77693->regmap_muic) |
673 | &max77693_muic_regmap_config); | 673 | dev_dbg(&pdev->dev, "allocate register map\n"); |
674 | if (IS_ERR(info->max77693->regmap_muic)) { | 674 | else { |
675 | ret = PTR_ERR(info->max77693->regmap_muic); | 675 | info->max77693->regmap_muic = devm_regmap_init_i2c( |
676 | dev_err(max77693->dev, | 676 | info->max77693->muic, |
677 | "failed to allocate register map: %d\n", ret); | 677 | &max77693_muic_regmap_config); |
678 | goto err_regmap; | 678 | if (IS_ERR(info->max77693->regmap_muic)) { |
679 | ret = PTR_ERR(info->max77693->regmap_muic); | ||
680 | dev_err(max77693->dev, | ||
681 | "failed to allocate register map: %d\n", ret); | ||
682 | goto err_regmap; | ||
683 | } | ||
679 | } | 684 | } |
680 | platform_set_drvdata(pdev, info); | 685 | platform_set_drvdata(pdev, info); |
681 | mutex_init(&info->mutex); | 686 | mutex_init(&info->mutex); |
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index e6efd77668f0..64fbce30c502 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c | |||
@@ -25,11 +25,9 @@ | |||
25 | #include <linux/of.h> | 25 | #include <linux/of.h> |
26 | #include <linux/of_device.h> | 26 | #include <linux/of_device.h> |
27 | #include <linux/irqdomain.h> | 27 | #include <linux/irqdomain.h> |
28 | #include <linux/gpio.h> | ||
29 | #include <linux/platform_data/gpio-omap.h> | ||
28 | 30 | ||
29 | #include <mach/hardware.h> | ||
30 | #include <asm/irq.h> | ||
31 | #include <mach/irqs.h> | ||
32 | #include <asm/gpio.h> | ||
33 | #include <asm/mach/irq.h> | 31 | #include <asm/mach/irq.h> |
34 | 32 | ||
35 | #define OFF_MODE 1 | 33 | #define OFF_MODE 1 |
@@ -385,13 +383,16 @@ static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, | |||
385 | static int gpio_irq_type(struct irq_data *d, unsigned type) | 383 | static int gpio_irq_type(struct irq_data *d, unsigned type) |
386 | { | 384 | { |
387 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); | 385 | struct gpio_bank *bank = irq_data_get_irq_chip_data(d); |
388 | unsigned gpio; | 386 | unsigned gpio = 0; |
389 | int retval; | 387 | int retval; |
390 | unsigned long flags; | 388 | unsigned long flags; |
391 | 389 | ||
392 | if (!cpu_class_is_omap2() && d->irq > IH_MPUIO_BASE) | 390 | #ifdef CONFIG_ARCH_OMAP1 |
391 | if (d->irq > IH_MPUIO_BASE) | ||
393 | gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE); | 392 | gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE); |
394 | else | 393 | #endif |
394 | |||
395 | if (!gpio) | ||
395 | gpio = irq_to_gpio(bank, d->irq); | 396 | gpio = irq_to_gpio(bank, d->irq); |
396 | 397 | ||
397 | if (type & ~IRQ_TYPE_SENSE_MASK) | 398 | if (type & ~IRQ_TYPE_SENSE_MASK) |
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 9cac88a65f78..9528779ca463 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/syscore_ops.h> | 26 | #include <linux/syscore_ops.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | 28 | ||
29 | #include <asm/mach/irq.h> | ||
30 | |||
29 | #include <mach/irqs.h> | 31 | #include <mach/irqs.h> |
30 | 32 | ||
31 | /* | 33 | /* |
@@ -59,6 +61,7 @@ | |||
59 | #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) | 61 | #define BANK_OFF(n) (((n) < 3) ? (n) << 2 : 0x100 + (((n) - 3) << 2)) |
60 | 62 | ||
61 | int pxa_last_gpio; | 63 | int pxa_last_gpio; |
64 | static int irq_base; | ||
62 | 65 | ||
63 | #ifdef CONFIG_OF | 66 | #ifdef CONFIG_OF |
64 | static struct irq_domain *domain; | 67 | static struct irq_domain *domain; |
@@ -167,63 +170,14 @@ static inline int __gpio_is_occupied(unsigned gpio) | |||
167 | return ret; | 170 | return ret; |
168 | } | 171 | } |
169 | 172 | ||
170 | #ifdef CONFIG_ARCH_PXA | ||
171 | static inline int __pxa_gpio_to_irq(int gpio) | ||
172 | { | ||
173 | if (gpio_is_pxa_type(gpio_type)) | ||
174 | return PXA_GPIO_TO_IRQ(gpio); | ||
175 | return -1; | ||
176 | } | ||
177 | |||
178 | static inline int __pxa_irq_to_gpio(int irq) | ||
179 | { | ||
180 | if (gpio_is_pxa_type(gpio_type)) | ||
181 | return irq - PXA_GPIO_TO_IRQ(0); | ||
182 | return -1; | ||
183 | } | ||
184 | #else | ||
185 | static inline int __pxa_gpio_to_irq(int gpio) { return -1; } | ||
186 | static inline int __pxa_irq_to_gpio(int irq) { return -1; } | ||
187 | #endif | ||
188 | |||
189 | #ifdef CONFIG_ARCH_MMP | ||
190 | static inline int __mmp_gpio_to_irq(int gpio) | ||
191 | { | ||
192 | if (gpio_is_mmp_type(gpio_type)) | ||
193 | return MMP_GPIO_TO_IRQ(gpio); | ||
194 | return -1; | ||
195 | } | ||
196 | |||
197 | static inline int __mmp_irq_to_gpio(int irq) | ||
198 | { | ||
199 | if (gpio_is_mmp_type(gpio_type)) | ||
200 | return irq - MMP_GPIO_TO_IRQ(0); | ||
201 | return -1; | ||
202 | } | ||
203 | #else | ||
204 | static inline int __mmp_gpio_to_irq(int gpio) { return -1; } | ||
205 | static inline int __mmp_irq_to_gpio(int irq) { return -1; } | ||
206 | #endif | ||
207 | |||
208 | static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) | 173 | static int pxa_gpio_to_irq(struct gpio_chip *chip, unsigned offset) |
209 | { | 174 | { |
210 | int gpio, ret; | 175 | return chip->base + offset + irq_base; |
211 | |||
212 | gpio = chip->base + offset; | ||
213 | ret = __pxa_gpio_to_irq(gpio); | ||
214 | if (ret >= 0) | ||
215 | return ret; | ||
216 | return __mmp_gpio_to_irq(gpio); | ||
217 | } | 176 | } |
218 | 177 | ||
219 | int pxa_irq_to_gpio(int irq) | 178 | int pxa_irq_to_gpio(int irq) |
220 | { | 179 | { |
221 | int ret; | 180 | return irq - irq_base; |
222 | |||
223 | ret = __pxa_irq_to_gpio(irq); | ||
224 | if (ret >= 0) | ||
225 | return ret; | ||
226 | return __mmp_irq_to_gpio(irq); | ||
227 | } | 181 | } |
228 | 182 | ||
229 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 183 | static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
@@ -403,6 +357,9 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
403 | struct pxa_gpio_chip *c; | 357 | struct pxa_gpio_chip *c; |
404 | int loop, gpio, gpio_base, n; | 358 | int loop, gpio, gpio_base, n; |
405 | unsigned long gedr; | 359 | unsigned long gedr; |
360 | struct irq_chip *chip = irq_desc_get_chip(desc); | ||
361 | |||
362 | chained_irq_enter(chip, desc); | ||
406 | 363 | ||
407 | do { | 364 | do { |
408 | loop = 0; | 365 | loop = 0; |
@@ -422,6 +379,8 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
422 | } | 379 | } |
423 | } | 380 | } |
424 | } while (loop); | 381 | } while (loop); |
382 | |||
383 | chained_irq_exit(chip, desc); | ||
425 | } | 384 | } |
426 | 385 | ||
427 | static void pxa_ack_muxed_gpio(struct irq_data *d) | 386 | static void pxa_ack_muxed_gpio(struct irq_data *d) |
@@ -535,7 +494,7 @@ const struct irq_domain_ops pxa_irq_domain_ops = { | |||
535 | 494 | ||
536 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | 495 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) |
537 | { | 496 | { |
538 | int ret, nr_banks, nr_gpios, irq_base; | 497 | int ret, nr_banks, nr_gpios; |
539 | struct device_node *prev, *next, *np = pdev->dev.of_node; | 498 | struct device_node *prev, *next, *np = pdev->dev.of_node; |
540 | const struct of_device_id *of_id = | 499 | const struct of_device_id *of_id = |
541 | of_match_device(pxa_gpio_dt_ids, &pdev->dev); | 500 | of_match_device(pxa_gpio_dt_ids, &pdev->dev); |
@@ -590,10 +549,20 @@ static int __devinit pxa_gpio_probe(struct platform_device *pdev) | |||
590 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; | 549 | int irq0 = 0, irq1 = 0, irq_mux, gpio_offset = 0; |
591 | 550 | ||
592 | ret = pxa_gpio_probe_dt(pdev); | 551 | ret = pxa_gpio_probe_dt(pdev); |
593 | if (ret < 0) | 552 | if (ret < 0) { |
594 | pxa_last_gpio = pxa_gpio_nums(); | 553 | pxa_last_gpio = pxa_gpio_nums(); |
595 | else | 554 | #ifdef CONFIG_ARCH_PXA |
555 | if (gpio_is_pxa_type(gpio_type)) | ||
556 | irq_base = PXA_GPIO_TO_IRQ(0); | ||
557 | #endif | ||
558 | #ifdef CONFIG_ARCH_MMP | ||
559 | if (gpio_is_mmp_type(gpio_type)) | ||
560 | irq_base = MMP_GPIO_TO_IRQ(0); | ||
561 | #endif | ||
562 | } else { | ||
596 | use_of = 1; | 563 | use_of = 1; |
564 | } | ||
565 | |||
597 | if (!pxa_last_gpio) | 566 | if (!pxa_last_gpio) |
598 | return -EINVAL; | 567 | return -EINVAL; |
599 | 568 | ||
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index ba126cc04073..8af4b06e80f7 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -938,6 +938,67 @@ static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) | |||
938 | s3c_gpiolib_track(chip); | 938 | s3c_gpiolib_track(chip); |
939 | } | 939 | } |
940 | 940 | ||
941 | #if defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) | ||
942 | static int s3c24xx_gpio_xlate(struct gpio_chip *gc, | ||
943 | const struct of_phandle_args *gpiospec, u32 *flags) | ||
944 | { | ||
945 | unsigned int pin; | ||
946 | |||
947 | if (WARN_ON(gc->of_gpio_n_cells < 3)) | ||
948 | return -EINVAL; | ||
949 | |||
950 | if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) | ||
951 | return -EINVAL; | ||
952 | |||
953 | if (gpiospec->args[0] > gc->ngpio) | ||
954 | return -EINVAL; | ||
955 | |||
956 | pin = gc->base + gpiospec->args[0]; | ||
957 | |||
958 | if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(gpiospec->args[1]))) | ||
959 | pr_warn("gpio_xlate: failed to set pin function\n"); | ||
960 | if (s3c_gpio_setpull(pin, gpiospec->args[2] & 0xffff)) | ||
961 | pr_warn("gpio_xlate: failed to set pin pull up/down\n"); | ||
962 | |||
963 | if (flags) | ||
964 | *flags = gpiospec->args[2] >> 16; | ||
965 | |||
966 | return gpiospec->args[0]; | ||
967 | } | ||
968 | |||
969 | static const struct of_device_id s3c24xx_gpio_dt_match[] __initdata = { | ||
970 | { .compatible = "samsung,s3c24xx-gpio", }, | ||
971 | {} | ||
972 | }; | ||
973 | |||
974 | static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, | ||
975 | u64 base, u64 offset) | ||
976 | { | ||
977 | struct gpio_chip *gc = &chip->chip; | ||
978 | u64 address; | ||
979 | |||
980 | if (!of_have_populated_dt()) | ||
981 | return; | ||
982 | |||
983 | address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset; | ||
984 | gc->of_node = of_find_matching_node_by_address(NULL, | ||
985 | s3c24xx_gpio_dt_match, address); | ||
986 | if (!gc->of_node) { | ||
987 | pr_info("gpio: device tree node not found for gpio controller" | ||
988 | " with base address %08llx\n", address); | ||
989 | return; | ||
990 | } | ||
991 | gc->of_gpio_n_cells = 3; | ||
992 | gc->of_xlate = s3c24xx_gpio_xlate; | ||
993 | } | ||
994 | #else | ||
995 | static __init void s3c24xx_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip, | ||
996 | u64 base, u64 offset) | ||
997 | { | ||
998 | return; | ||
999 | } | ||
1000 | #endif /* defined(CONFIG_PLAT_S3C24XX) && defined(CONFIG_OF) */ | ||
1001 | |||
941 | static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, | 1002 | static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, |
942 | int nr_chips, void __iomem *base) | 1003 | int nr_chips, void __iomem *base) |
943 | { | 1004 | { |
@@ -962,6 +1023,8 @@ static void __init s3c24xx_gpiolib_add_chips(struct samsung_gpio_chip *chip, | |||
962 | gc->direction_output = samsung_gpiolib_2bit_output; | 1023 | gc->direction_output = samsung_gpiolib_2bit_output; |
963 | 1024 | ||
964 | samsung_gpiolib_add(chip); | 1025 | samsung_gpiolib_add(chip); |
1026 | |||
1027 | s3c24xx_gpiolib_attach_ofnode(chip, S3C24XX_PA_GPIO, i * 0x10); | ||
965 | } | 1028 | } |
966 | } | 1029 | } |
967 | 1030 | ||
@@ -3131,46 +3194,6 @@ samsung_gpio_pull_t s3c_gpio_getpull(unsigned int pin) | |||
3131 | } | 3194 | } |
3132 | EXPORT_SYMBOL(s3c_gpio_getpull); | 3195 | EXPORT_SYMBOL(s3c_gpio_getpull); |
3133 | 3196 | ||
3134 | /* gpiolib wrappers until these are totally eliminated */ | ||
3135 | |||
3136 | void s3c2410_gpio_pullup(unsigned int pin, unsigned int to) | ||
3137 | { | ||
3138 | int ret; | ||
3139 | |||
3140 | WARN_ON(to); /* should be none of these left */ | ||
3141 | |||
3142 | if (!to) { | ||
3143 | /* if pull is enabled, try first with up, and if that | ||
3144 | * fails, try using down */ | ||
3145 | |||
3146 | ret = s3c_gpio_setpull(pin, S3C_GPIO_PULL_UP); | ||
3147 | if (ret) | ||
3148 | s3c_gpio_setpull(pin, S3C_GPIO_PULL_DOWN); | ||
3149 | } else { | ||
3150 | s3c_gpio_setpull(pin, S3C_GPIO_PULL_NONE); | ||
3151 | } | ||
3152 | } | ||
3153 | EXPORT_SYMBOL(s3c2410_gpio_pullup); | ||
3154 | |||
3155 | void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) | ||
3156 | { | ||
3157 | /* do this via gpiolib until all users removed */ | ||
3158 | |||
3159 | gpio_request(pin, "temporary"); | ||
3160 | gpio_set_value(pin, to); | ||
3161 | gpio_free(pin); | ||
3162 | } | ||
3163 | EXPORT_SYMBOL(s3c2410_gpio_setpin); | ||
3164 | |||
3165 | unsigned int s3c2410_gpio_getpin(unsigned int pin) | ||
3166 | { | ||
3167 | struct samsung_gpio_chip *chip = samsung_gpiolib_getchip(pin); | ||
3168 | unsigned long offs = pin - chip->chip.base; | ||
3169 | |||
3170 | return __raw_readl(chip->base + 0x04) & (1 << offs); | ||
3171 | } | ||
3172 | EXPORT_SYMBOL(s3c2410_gpio_getpin); | ||
3173 | |||
3174 | #ifdef CONFIG_S5P_GPIO_DRVSTR | 3197 | #ifdef CONFIG_S5P_GPIO_DRVSTR |
3175 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) | 3198 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) |
3176 | { | 3199 | { |
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index dc5184d57892..d982593d7563 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c | |||
@@ -30,9 +30,6 @@ | |||
30 | 30 | ||
31 | #include <asm/mach/irq.h> | 31 | #include <asm/mach/irq.h> |
32 | 32 | ||
33 | #include <mach/iomap.h> | ||
34 | #include <mach/suspend.h> | ||
35 | |||
36 | #define GPIO_BANK(x) ((x) >> 5) | 33 | #define GPIO_BANK(x) ((x) >> 5) |
37 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) | 34 | #define GPIO_PORT(x) (((x) >> 3) & 0x3) |
38 | #define GPIO_BIT(x) ((x) & 0x7) | 35 | #define GPIO_BIT(x) ((x) & 0x7) |
diff --git a/drivers/gpio/gpio-twl4030.c b/drivers/gpio/gpio-twl4030.c index 94256fe7bf36..c5f8ca233e1f 100644 --- a/drivers/gpio/gpio-twl4030.c +++ b/drivers/gpio/gpio-twl4030.c | |||
@@ -51,6 +51,7 @@ | |||
51 | 51 | ||
52 | 52 | ||
53 | static struct gpio_chip twl_gpiochip; | 53 | static struct gpio_chip twl_gpiochip; |
54 | static int twl4030_gpio_base; | ||
54 | static int twl4030_gpio_irq_base; | 55 | static int twl4030_gpio_irq_base; |
55 | 56 | ||
56 | /* genirq interfaces are not available to modules */ | 57 | /* genirq interfaces are not available to modules */ |
@@ -395,6 +396,29 @@ static int __devinit gpio_twl4030_debounce(u32 debounce, u8 mmc_cd) | |||
395 | 396 | ||
396 | static int gpio_twl4030_remove(struct platform_device *pdev); | 397 | static int gpio_twl4030_remove(struct platform_device *pdev); |
397 | 398 | ||
399 | static struct twl4030_gpio_platform_data *of_gpio_twl4030(struct device *dev) | ||
400 | { | ||
401 | struct twl4030_gpio_platform_data *omap_twl_info; | ||
402 | |||
403 | omap_twl_info = devm_kzalloc(dev, sizeof(*omap_twl_info), GFP_KERNEL); | ||
404 | if (!omap_twl_info) | ||
405 | return NULL; | ||
406 | |||
407 | omap_twl_info->use_leds = of_property_read_bool(dev->of_node, | ||
408 | "ti,use-leds"); | ||
409 | |||
410 | of_property_read_u32(dev->of_node, "ti,debounce", | ||
411 | &omap_twl_info->debounce); | ||
412 | of_property_read_u32(dev->of_node, "ti,mmc-cd", | ||
413 | (u32 *)&omap_twl_info->mmc_cd); | ||
414 | of_property_read_u32(dev->of_node, "ti,pullups", | ||
415 | &omap_twl_info->pullups); | ||
416 | of_property_read_u32(dev->of_node, "ti,pulldowns", | ||
417 | &omap_twl_info->pulldowns); | ||
418 | |||
419 | return omap_twl_info; | ||
420 | } | ||
421 | |||
398 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) | 422 | static int __devinit gpio_twl4030_probe(struct platform_device *pdev) |
399 | { | 423 | { |
400 | struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; | 424 | struct twl4030_gpio_platform_data *pdata = pdev->dev.platform_data; |
@@ -427,49 +451,57 @@ no_irqs: | |||
427 | twl_gpiochip.ngpio = TWL4030_GPIO_MAX; | 451 | twl_gpiochip.ngpio = TWL4030_GPIO_MAX; |
428 | twl_gpiochip.dev = &pdev->dev; | 452 | twl_gpiochip.dev = &pdev->dev; |
429 | 453 | ||
430 | if (pdata) { | 454 | if (node) |
431 | twl_gpiochip.base = pdata->gpio_base; | 455 | pdata = of_gpio_twl4030(&pdev->dev); |
432 | 456 | ||
433 | /* | 457 | if (pdata == NULL) { |
434 | * NOTE: boards may waste power if they don't set pullups | 458 | dev_err(&pdev->dev, "Platform data is missing\n"); |
435 | * and pulldowns correctly ... default for non-ULPI pins is | 459 | return -ENXIO; |
436 | * pulldown, and some other pins may have external pullups | ||
437 | * or pulldowns. Careful! | ||
438 | */ | ||
439 | ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns); | ||
440 | if (ret) | ||
441 | dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n", | ||
442 | pdata->pullups, pdata->pulldowns, | ||
443 | ret); | ||
444 | |||
445 | ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd); | ||
446 | if (ret) | ||
447 | dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n", | ||
448 | pdata->debounce, pdata->mmc_cd, | ||
449 | ret); | ||
450 | |||
451 | /* | ||
452 | * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE, | ||
453 | * is (still) clear if use_leds is set. | ||
454 | */ | ||
455 | if (pdata->use_leds) | ||
456 | twl_gpiochip.ngpio += 2; | ||
457 | } | 460 | } |
458 | 461 | ||
462 | /* | ||
463 | * NOTE: boards may waste power if they don't set pullups | ||
464 | * and pulldowns correctly ... default for non-ULPI pins is | ||
465 | * pulldown, and some other pins may have external pullups | ||
466 | * or pulldowns. Careful! | ||
467 | */ | ||
468 | ret = gpio_twl4030_pulls(pdata->pullups, pdata->pulldowns); | ||
469 | if (ret) | ||
470 | dev_dbg(&pdev->dev, "pullups %.05x %.05x --> %d\n", | ||
471 | pdata->pullups, pdata->pulldowns, ret); | ||
472 | |||
473 | ret = gpio_twl4030_debounce(pdata->debounce, pdata->mmc_cd); | ||
474 | if (ret) | ||
475 | dev_dbg(&pdev->dev, "debounce %.03x %.01x --> %d\n", | ||
476 | pdata->debounce, pdata->mmc_cd, ret); | ||
477 | |||
478 | /* | ||
479 | * NOTE: we assume VIBRA_CTL.VIBRA_EN, in MODULE_AUDIO_VOICE, | ||
480 | * is (still) clear if use_leds is set. | ||
481 | */ | ||
482 | if (pdata->use_leds) | ||
483 | twl_gpiochip.ngpio += 2; | ||
484 | |||
459 | ret = gpiochip_add(&twl_gpiochip); | 485 | ret = gpiochip_add(&twl_gpiochip); |
460 | if (ret < 0) { | 486 | if (ret < 0) { |
461 | dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); | 487 | dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret); |
462 | twl_gpiochip.ngpio = 0; | 488 | twl_gpiochip.ngpio = 0; |
463 | gpio_twl4030_remove(pdev); | 489 | gpio_twl4030_remove(pdev); |
464 | } else if (pdata && pdata->setup) { | 490 | goto out; |
491 | } | ||
492 | |||
493 | twl4030_gpio_base = twl_gpiochip.base; | ||
494 | |||
495 | if (pdata && pdata->setup) { | ||
465 | int status; | 496 | int status; |
466 | 497 | ||
467 | status = pdata->setup(&pdev->dev, | 498 | status = pdata->setup(&pdev->dev, |
468 | pdata->gpio_base, TWL4030_GPIO_MAX); | 499 | twl4030_gpio_base, TWL4030_GPIO_MAX); |
469 | if (status) | 500 | if (status) |
470 | dev_dbg(&pdev->dev, "setup --> %d\n", status); | 501 | dev_dbg(&pdev->dev, "setup --> %d\n", status); |
471 | } | 502 | } |
472 | 503 | ||
504 | out: | ||
473 | return ret; | 505 | return ret; |
474 | } | 506 | } |
475 | 507 | ||
@@ -481,7 +513,7 @@ static int gpio_twl4030_remove(struct platform_device *pdev) | |||
481 | 513 | ||
482 | if (pdata && pdata->teardown) { | 514 | if (pdata && pdata->teardown) { |
483 | status = pdata->teardown(&pdev->dev, | 515 | status = pdata->teardown(&pdev->dev, |
484 | pdata->gpio_base, TWL4030_GPIO_MAX); | 516 | twl4030_gpio_base, TWL4030_GPIO_MAX); |
485 | if (status) { | 517 | if (status) { |
486 | dev_dbg(&pdev->dev, "teardown --> %d\n", status); | 518 | dev_dbg(&pdev->dev, "teardown --> %d\n", status); |
487 | return status; | 519 | return status; |
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c index d0c4574ef49c..36164806b9d4 100644 --- a/drivers/gpu/drm/ast/ast_drv.c +++ b/drivers/gpu/drm/ast/ast_drv.c | |||
@@ -193,6 +193,9 @@ static const struct file_operations ast_fops = { | |||
193 | .mmap = ast_mmap, | 193 | .mmap = ast_mmap, |
194 | .poll = drm_poll, | 194 | .poll = drm_poll, |
195 | .fasync = drm_fasync, | 195 | .fasync = drm_fasync, |
196 | #ifdef CONFIG_COMPAT | ||
197 | .compat_ioctl = drm_compat_ioctl, | ||
198 | #endif | ||
196 | .read = drm_read, | 199 | .read = drm_read, |
197 | }; | 200 | }; |
198 | 201 | ||
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 7282c081fb53..a712cafcfa1d 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c | |||
@@ -841,7 +841,7 @@ int ast_cursor_init(struct drm_device *dev) | |||
841 | 841 | ||
842 | ast->cursor_cache = obj; | 842 | ast->cursor_cache = obj; |
843 | ast->cursor_cache_gpu_addr = gpu_addr; | 843 | ast->cursor_cache_gpu_addr = gpu_addr; |
844 | DRM_ERROR("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); | 844 | DRM_DEBUG_KMS("pinned cursor cache at %llx\n", ast->cursor_cache_gpu_addr); |
845 | return 0; | 845 | return 0; |
846 | fail: | 846 | fail: |
847 | return ret; | 847 | return ret; |
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c index 7053140c6596..b83a2d7ddd1a 100644 --- a/drivers/gpu/drm/cirrus/cirrus_drv.c +++ b/drivers/gpu/drm/cirrus/cirrus_drv.c | |||
@@ -74,6 +74,9 @@ static const struct file_operations cirrus_driver_fops = { | |||
74 | .unlocked_ioctl = drm_ioctl, | 74 | .unlocked_ioctl = drm_ioctl, |
75 | .mmap = cirrus_mmap, | 75 | .mmap = cirrus_mmap, |
76 | .poll = drm_poll, | 76 | .poll = drm_poll, |
77 | #ifdef CONFIG_COMPAT | ||
78 | .compat_ioctl = drm_compat_ioctl, | ||
79 | #endif | ||
77 | .fasync = drm_fasync, | 80 | .fasync = drm_fasync, |
78 | }; | 81 | }; |
79 | static struct drm_driver driver = { | 82 | static struct drm_driver driver = { |
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig index 7f5096763b7d..59a26e577b57 100644 --- a/drivers/gpu/drm/exynos/Kconfig +++ b/drivers/gpu/drm/exynos/Kconfig | |||
@@ -36,6 +36,6 @@ config DRM_EXYNOS_VIDI | |||
36 | 36 | ||
37 | config DRM_EXYNOS_G2D | 37 | config DRM_EXYNOS_G2D |
38 | bool "Exynos DRM G2D" | 38 | bool "Exynos DRM G2D" |
39 | depends on DRM_EXYNOS | 39 | depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_G2D |
40 | help | 40 | help |
41 | Choose this option if you want to use Exynos G2D for DRM. | 41 | Choose this option if you want to use Exynos G2D for DRM. |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index 613bf8a5d9b2..ae13febe0eaa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | |||
@@ -163,6 +163,12 @@ static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf, | |||
163 | /* TODO */ | 163 | /* TODO */ |
164 | } | 164 | } |
165 | 165 | ||
166 | static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf, | ||
167 | struct vm_area_struct *vma) | ||
168 | { | ||
169 | return -ENOTTY; | ||
170 | } | ||
171 | |||
166 | static struct dma_buf_ops exynos_dmabuf_ops = { | 172 | static struct dma_buf_ops exynos_dmabuf_ops = { |
167 | .map_dma_buf = exynos_gem_map_dma_buf, | 173 | .map_dma_buf = exynos_gem_map_dma_buf, |
168 | .unmap_dma_buf = exynos_gem_unmap_dma_buf, | 174 | .unmap_dma_buf = exynos_gem_unmap_dma_buf, |
@@ -170,6 +176,7 @@ static struct dma_buf_ops exynos_dmabuf_ops = { | |||
170 | .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, | 176 | .kmap_atomic = exynos_gem_dmabuf_kmap_atomic, |
171 | .kunmap = exynos_gem_dmabuf_kunmap, | 177 | .kunmap = exynos_gem_dmabuf_kunmap, |
172 | .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, | 178 | .kunmap_atomic = exynos_gem_dmabuf_kunmap_atomic, |
179 | .mmap = exynos_gem_dmabuf_mmap, | ||
173 | .release = exynos_dmabuf_release, | 180 | .release = exynos_dmabuf_release, |
174 | }; | 181 | }; |
175 | 182 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index ebacec6f1e48..d07071937453 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -160,7 +160,6 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) | |||
160 | if (!file_priv) | 160 | if (!file_priv) |
161 | return -ENOMEM; | 161 | return -ENOMEM; |
162 | 162 | ||
163 | drm_prime_init_file_private(&file->prime); | ||
164 | file->driver_priv = file_priv; | 163 | file->driver_priv = file_priv; |
165 | 164 | ||
166 | return exynos_drm_subdrv_open(dev, file); | 165 | return exynos_drm_subdrv_open(dev, file); |
@@ -184,7 +183,6 @@ static void exynos_drm_preclose(struct drm_device *dev, | |||
184 | e->base.destroy(&e->base); | 183 | e->base.destroy(&e->base); |
185 | } | 184 | } |
186 | } | 185 | } |
187 | drm_prime_destroy_file_private(&file->prime); | ||
188 | spin_unlock_irqrestore(&dev->event_lock, flags); | 186 | spin_unlock_irqrestore(&dev->event_lock, flags); |
189 | 187 | ||
190 | exynos_drm_subdrv_close(dev, file); | 188 | exynos_drm_subdrv_close(dev, file); |
@@ -241,6 +239,9 @@ static const struct file_operations exynos_drm_driver_fops = { | |||
241 | .poll = drm_poll, | 239 | .poll = drm_poll, |
242 | .read = drm_read, | 240 | .read = drm_read, |
243 | .unlocked_ioctl = drm_ioctl, | 241 | .unlocked_ioctl = drm_ioctl, |
242 | #ifdef CONFIG_COMPAT | ||
243 | .compat_ioctl = drm_compat_ioctl, | ||
244 | #endif | ||
244 | .release = drm_release, | 245 | .release = drm_release, |
245 | }; | 246 | }; |
246 | 247 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index a68d2b313f03..b19cd93e7047 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -831,11 +831,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
831 | } | 831 | } |
832 | 832 | ||
833 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 833 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
834 | if (!res) { | ||
835 | dev_err(dev, "failed to find registers\n"); | ||
836 | ret = -ENOENT; | ||
837 | goto err_clk; | ||
838 | } | ||
839 | 834 | ||
840 | ctx->regs = devm_request_and_ioremap(&pdev->dev, res); | 835 | ctx->regs = devm_request_and_ioremap(&pdev->dev, res); |
841 | if (!ctx->regs) { | 836 | if (!ctx->regs) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index d2d88f22a037..1065e90d0919 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c | |||
@@ -129,7 +129,6 @@ struct g2d_runqueue_node { | |||
129 | struct g2d_data { | 129 | struct g2d_data { |
130 | struct device *dev; | 130 | struct device *dev; |
131 | struct clk *gate_clk; | 131 | struct clk *gate_clk; |
132 | struct resource *regs_res; | ||
133 | void __iomem *regs; | 132 | void __iomem *regs; |
134 | int irq; | 133 | int irq; |
135 | struct workqueue_struct *g2d_workq; | 134 | struct workqueue_struct *g2d_workq; |
@@ -751,7 +750,7 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
751 | struct exynos_drm_subdrv *subdrv; | 750 | struct exynos_drm_subdrv *subdrv; |
752 | int ret; | 751 | int ret; |
753 | 752 | ||
754 | g2d = kzalloc(sizeof(*g2d), GFP_KERNEL); | 753 | g2d = devm_kzalloc(&pdev->dev, sizeof(*g2d), GFP_KERNEL); |
755 | if (!g2d) { | 754 | if (!g2d) { |
756 | dev_err(dev, "failed to allocate driver data\n"); | 755 | dev_err(dev, "failed to allocate driver data\n"); |
757 | return -ENOMEM; | 756 | return -ENOMEM; |
@@ -759,10 +758,8 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
759 | 758 | ||
760 | g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", | 759 | g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab", |
761 | sizeof(struct g2d_runqueue_node), 0, 0, NULL); | 760 | sizeof(struct g2d_runqueue_node), 0, 0, NULL); |
762 | if (!g2d->runqueue_slab) { | 761 | if (!g2d->runqueue_slab) |
763 | ret = -ENOMEM; | 762 | return -ENOMEM; |
764 | goto err_free_mem; | ||
765 | } | ||
766 | 763 | ||
767 | g2d->dev = dev; | 764 | g2d->dev = dev; |
768 | 765 | ||
@@ -794,38 +791,26 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
794 | pm_runtime_enable(dev); | 791 | pm_runtime_enable(dev); |
795 | 792 | ||
796 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 793 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
797 | if (!res) { | ||
798 | dev_err(dev, "failed to get I/O memory\n"); | ||
799 | ret = -ENOENT; | ||
800 | goto err_put_clk; | ||
801 | } | ||
802 | 794 | ||
803 | g2d->regs_res = request_mem_region(res->start, resource_size(res), | 795 | g2d->regs = devm_request_and_ioremap(&pdev->dev, res); |
804 | dev_name(dev)); | ||
805 | if (!g2d->regs_res) { | ||
806 | dev_err(dev, "failed to request I/O memory\n"); | ||
807 | ret = -ENOENT; | ||
808 | goto err_put_clk; | ||
809 | } | ||
810 | |||
811 | g2d->regs = ioremap(res->start, resource_size(res)); | ||
812 | if (!g2d->regs) { | 796 | if (!g2d->regs) { |
813 | dev_err(dev, "failed to remap I/O memory\n"); | 797 | dev_err(dev, "failed to remap I/O memory\n"); |
814 | ret = -ENXIO; | 798 | ret = -ENXIO; |
815 | goto err_release_res; | 799 | goto err_put_clk; |
816 | } | 800 | } |
817 | 801 | ||
818 | g2d->irq = platform_get_irq(pdev, 0); | 802 | g2d->irq = platform_get_irq(pdev, 0); |
819 | if (g2d->irq < 0) { | 803 | if (g2d->irq < 0) { |
820 | dev_err(dev, "failed to get irq\n"); | 804 | dev_err(dev, "failed to get irq\n"); |
821 | ret = g2d->irq; | 805 | ret = g2d->irq; |
822 | goto err_unmap_base; | 806 | goto err_put_clk; |
823 | } | 807 | } |
824 | 808 | ||
825 | ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d); | 809 | ret = devm_request_irq(&pdev->dev, g2d->irq, g2d_irq_handler, 0, |
810 | "drm_g2d", g2d); | ||
826 | if (ret < 0) { | 811 | if (ret < 0) { |
827 | dev_err(dev, "irq request failed\n"); | 812 | dev_err(dev, "irq request failed\n"); |
828 | goto err_unmap_base; | 813 | goto err_put_clk; |
829 | } | 814 | } |
830 | 815 | ||
831 | platform_set_drvdata(pdev, g2d); | 816 | platform_set_drvdata(pdev, g2d); |
@@ -838,7 +823,7 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
838 | ret = exynos_drm_subdrv_register(subdrv); | 823 | ret = exynos_drm_subdrv_register(subdrv); |
839 | if (ret < 0) { | 824 | if (ret < 0) { |
840 | dev_err(dev, "failed to register drm g2d device\n"); | 825 | dev_err(dev, "failed to register drm g2d device\n"); |
841 | goto err_free_irq; | 826 | goto err_put_clk; |
842 | } | 827 | } |
843 | 828 | ||
844 | dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", | 829 | dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n", |
@@ -846,13 +831,6 @@ static int __devinit g2d_probe(struct platform_device *pdev) | |||
846 | 831 | ||
847 | return 0; | 832 | return 0; |
848 | 833 | ||
849 | err_free_irq: | ||
850 | free_irq(g2d->irq, g2d); | ||
851 | err_unmap_base: | ||
852 | iounmap(g2d->regs); | ||
853 | err_release_res: | ||
854 | release_resource(g2d->regs_res); | ||
855 | kfree(g2d->regs_res); | ||
856 | err_put_clk: | 834 | err_put_clk: |
857 | pm_runtime_disable(dev); | 835 | pm_runtime_disable(dev); |
858 | clk_put(g2d->gate_clk); | 836 | clk_put(g2d->gate_clk); |
@@ -862,8 +840,6 @@ err_destroy_workqueue: | |||
862 | destroy_workqueue(g2d->g2d_workq); | 840 | destroy_workqueue(g2d->g2d_workq); |
863 | err_destroy_slab: | 841 | err_destroy_slab: |
864 | kmem_cache_destroy(g2d->runqueue_slab); | 842 | kmem_cache_destroy(g2d->runqueue_slab); |
865 | err_free_mem: | ||
866 | kfree(g2d); | ||
867 | return ret; | 843 | return ret; |
868 | } | 844 | } |
869 | 845 | ||
@@ -873,24 +849,18 @@ static int __devexit g2d_remove(struct platform_device *pdev) | |||
873 | 849 | ||
874 | cancel_work_sync(&g2d->runqueue_work); | 850 | cancel_work_sync(&g2d->runqueue_work); |
875 | exynos_drm_subdrv_unregister(&g2d->subdrv); | 851 | exynos_drm_subdrv_unregister(&g2d->subdrv); |
876 | free_irq(g2d->irq, g2d); | ||
877 | 852 | ||
878 | while (g2d->runqueue_node) { | 853 | while (g2d->runqueue_node) { |
879 | g2d_free_runqueue_node(g2d, g2d->runqueue_node); | 854 | g2d_free_runqueue_node(g2d, g2d->runqueue_node); |
880 | g2d->runqueue_node = g2d_get_runqueue_node(g2d); | 855 | g2d->runqueue_node = g2d_get_runqueue_node(g2d); |
881 | } | 856 | } |
882 | 857 | ||
883 | iounmap(g2d->regs); | ||
884 | release_resource(g2d->regs_res); | ||
885 | kfree(g2d->regs_res); | ||
886 | |||
887 | pm_runtime_disable(&pdev->dev); | 858 | pm_runtime_disable(&pdev->dev); |
888 | clk_put(g2d->gate_clk); | 859 | clk_put(g2d->gate_clk); |
889 | 860 | ||
890 | g2d_fini_cmdlist(g2d); | 861 | g2d_fini_cmdlist(g2d); |
891 | destroy_workqueue(g2d->g2d_workq); | 862 | destroy_workqueue(g2d->g2d_workq); |
892 | kmem_cache_destroy(g2d->runqueue_slab); | 863 | kmem_cache_destroy(g2d->runqueue_slab); |
893 | kfree(g2d); | ||
894 | 864 | ||
895 | return 0; | 865 | return 0; |
896 | } | 866 | } |
@@ -924,7 +894,7 @@ static int g2d_resume(struct device *dev) | |||
924 | } | 894 | } |
925 | #endif | 895 | #endif |
926 | 896 | ||
927 | SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); | 897 | static SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume); |
928 | 898 | ||
929 | struct platform_driver g2d_driver = { | 899 | struct platform_driver g2d_driver = { |
930 | .probe = g2d_probe, | 900 | .probe = g2d_probe, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index f9efde40c097..a38051c95ec4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -122,7 +122,7 @@ fail: | |||
122 | __free_page(pages[i]); | 122 | __free_page(pages[i]); |
123 | 123 | ||
124 | drm_free_large(pages); | 124 | drm_free_large(pages); |
125 | return ERR_PTR(PTR_ERR(p)); | 125 | return ERR_CAST(p); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void exynos_gem_put_pages(struct drm_gem_object *obj, | 128 | static void exynos_gem_put_pages(struct drm_gem_object *obj, |
@@ -662,7 +662,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv, | |||
662 | */ | 662 | */ |
663 | 663 | ||
664 | args->pitch = args->width * ((args->bpp + 7) / 8); | 664 | args->pitch = args->width * ((args->bpp + 7) / 8); |
665 | args->size = PAGE_ALIGN(args->pitch * args->height); | 665 | args->size = args->pitch * args->height; |
666 | 666 | ||
667 | exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); | 667 | exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size); |
668 | if (IS_ERR(exynos_gem_obj)) | 668 | if (IS_ERR(exynos_gem_obj)) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 8ffcdf8b9e22..3fdf0b65f47e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
@@ -345,7 +345,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) | |||
345 | 345 | ||
346 | DRM_DEBUG_KMS("%s\n", __FILE__); | 346 | DRM_DEBUG_KMS("%s\n", __FILE__); |
347 | 347 | ||
348 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 348 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
349 | if (!ctx) { | 349 | if (!ctx) { |
350 | DRM_LOG_KMS("failed to alloc common hdmi context.\n"); | 350 | DRM_LOG_KMS("failed to alloc common hdmi context.\n"); |
351 | return -ENOMEM; | 351 | return -ENOMEM; |
@@ -371,7 +371,6 @@ static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev) | |||
371 | DRM_DEBUG_KMS("%s\n", __FILE__); | 371 | DRM_DEBUG_KMS("%s\n", __FILE__); |
372 | 372 | ||
373 | exynos_drm_subdrv_unregister(&ctx->subdrv); | 373 | exynos_drm_subdrv_unregister(&ctx->subdrv); |
374 | kfree(ctx); | ||
375 | 374 | ||
376 | return 0; | 375 | return 0; |
377 | } | 376 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index b89829e5043a..e1f94b746bd7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c | |||
@@ -29,7 +29,6 @@ static const uint32_t formats[] = { | |||
29 | DRM_FORMAT_XRGB8888, | 29 | DRM_FORMAT_XRGB8888, |
30 | DRM_FORMAT_ARGB8888, | 30 | DRM_FORMAT_ARGB8888, |
31 | DRM_FORMAT_NV12, | 31 | DRM_FORMAT_NV12, |
32 | DRM_FORMAT_NV12M, | ||
33 | DRM_FORMAT_NV12MT, | 32 | DRM_FORMAT_NV12MT, |
34 | }; | 33 | }; |
35 | 34 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index bb1550c4dd57..537027a74fd5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -633,7 +633,7 @@ static int __devinit vidi_probe(struct platform_device *pdev) | |||
633 | 633 | ||
634 | DRM_DEBUG_KMS("%s\n", __FILE__); | 634 | DRM_DEBUG_KMS("%s\n", __FILE__); |
635 | 635 | ||
636 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 636 | ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL); |
637 | if (!ctx) | 637 | if (!ctx) |
638 | return -ENOMEM; | 638 | return -ENOMEM; |
639 | 639 | ||
@@ -673,8 +673,6 @@ static int __devexit vidi_remove(struct platform_device *pdev) | |||
673 | ctx->raw_edid = NULL; | 673 | ctx->raw_edid = NULL; |
674 | } | 674 | } |
675 | 675 | ||
676 | kfree(ctx); | ||
677 | |||
678 | return 0; | 676 | return 0; |
679 | } | 677 | } |
680 | 678 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 409e2ec1207c..a6aea6f3ea1a 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -2172,7 +2172,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata) | |||
2172 | 2172 | ||
2173 | DRM_DEBUG_KMS("HDMI resource init\n"); | 2173 | DRM_DEBUG_KMS("HDMI resource init\n"); |
2174 | 2174 | ||
2175 | memset(res, 0, sizeof *res); | 2175 | memset(res, 0, sizeof(*res)); |
2176 | 2176 | ||
2177 | /* get clocks, power */ | 2177 | /* get clocks, power */ |
2178 | res->hdmi = clk_get(dev, "hdmi"); | 2178 | res->hdmi = clk_get(dev, "hdmi"); |
@@ -2204,7 +2204,7 @@ static int __devinit hdmi_resources_init(struct hdmi_context *hdata) | |||
2204 | clk_set_parent(res->sclk_hdmi, res->sclk_pixel); | 2204 | clk_set_parent(res->sclk_hdmi, res->sclk_pixel); |
2205 | 2205 | ||
2206 | res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * | 2206 | res->regul_bulk = kzalloc(ARRAY_SIZE(supply) * |
2207 | sizeof res->regul_bulk[0], GFP_KERNEL); | 2207 | sizeof(res->regul_bulk[0]), GFP_KERNEL); |
2208 | if (!res->regul_bulk) { | 2208 | if (!res->regul_bulk) { |
2209 | DRM_ERROR("failed to get memory for regulators\n"); | 2209 | DRM_ERROR("failed to get memory for regulators\n"); |
2210 | goto fail; | 2210 | goto fail; |
@@ -2243,7 +2243,7 @@ static int hdmi_resources_cleanup(struct hdmi_context *hdata) | |||
2243 | clk_put(res->sclk_hdmi); | 2243 | clk_put(res->sclk_hdmi); |
2244 | if (!IS_ERR_OR_NULL(res->hdmi)) | 2244 | if (!IS_ERR_OR_NULL(res->hdmi)) |
2245 | clk_put(res->hdmi); | 2245 | clk_put(res->hdmi); |
2246 | memset(res, 0, sizeof *res); | 2246 | memset(res, 0, sizeof(*res)); |
2247 | 2247 | ||
2248 | return 0; | 2248 | return 0; |
2249 | } | 2249 | } |
@@ -2312,11 +2312,6 @@ static int __devinit hdmi_probe(struct platform_device *pdev) | |||
2312 | } | 2312 | } |
2313 | 2313 | ||
2314 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2314 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2315 | if (!res) { | ||
2316 | DRM_ERROR("failed to find registers\n"); | ||
2317 | ret = -ENOENT; | ||
2318 | goto err_resource; | ||
2319 | } | ||
2320 | 2315 | ||
2321 | hdata->regs = devm_request_and_ioremap(&pdev->dev, res); | 2316 | hdata->regs = devm_request_and_ioremap(&pdev->dev, res); |
2322 | if (!hdata->regs) { | 2317 | if (!hdata->regs) { |
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index 30fcc12f81dd..25b97d5e5fcb 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c | |||
@@ -236,11 +236,11 @@ static inline void vp_filter_set(struct mixer_resources *res, | |||
236 | static void vp_default_filter(struct mixer_resources *res) | 236 | static void vp_default_filter(struct mixer_resources *res) |
237 | { | 237 | { |
238 | vp_filter_set(res, VP_POLY8_Y0_LL, | 238 | vp_filter_set(res, VP_POLY8_Y0_LL, |
239 | filter_y_horiz_tap8, sizeof filter_y_horiz_tap8); | 239 | filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8)); |
240 | vp_filter_set(res, VP_POLY4_Y0_LL, | 240 | vp_filter_set(res, VP_POLY4_Y0_LL, |
241 | filter_y_vert_tap4, sizeof filter_y_vert_tap4); | 241 | filter_y_vert_tap4, sizeof(filter_y_vert_tap4)); |
242 | vp_filter_set(res, VP_POLY4_C0_LL, | 242 | vp_filter_set(res, VP_POLY4_C0_LL, |
243 | filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4); | 243 | filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4)); |
244 | } | 244 | } |
245 | 245 | ||
246 | static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) | 246 | static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable) |
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 0f9b7db80f6b..cf49ba5a54bf 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c | |||
@@ -476,6 +476,7 @@ static const struct psb_offset oaktrail_regmap[2] = { | |||
476 | .pos = DSPAPOS, | 476 | .pos = DSPAPOS, |
477 | .surf = DSPASURF, | 477 | .surf = DSPASURF, |
478 | .addr = MRST_DSPABASE, | 478 | .addr = MRST_DSPABASE, |
479 | .base = MRST_DSPABASE, | ||
479 | .status = PIPEASTAT, | 480 | .status = PIPEASTAT, |
480 | .linoff = DSPALINOFF, | 481 | .linoff = DSPALINOFF, |
481 | .tileoff = DSPATILEOFF, | 482 | .tileoff = DSPATILEOFF, |
@@ -499,6 +500,7 @@ static const struct psb_offset oaktrail_regmap[2] = { | |||
499 | .pos = DSPBPOS, | 500 | .pos = DSPBPOS, |
500 | .surf = DSPBSURF, | 501 | .surf = DSPBSURF, |
501 | .addr = DSPBBASE, | 502 | .addr = DSPBBASE, |
503 | .base = DSPBBASE, | ||
502 | .status = PIPEBSTAT, | 504 | .status = PIPEBSTAT, |
503 | .linoff = DSPBLINOFF, | 505 | .linoff = DSPBLINOFF, |
504 | .tileoff = DSPBTILEOFF, | 506 | .tileoff = DSPBTILEOFF, |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 57d892eaaa6e..463ec6871fe9 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -115,6 +115,9 @@ static const struct file_operations i810_buffer_fops = { | |||
115 | .unlocked_ioctl = drm_ioctl, | 115 | .unlocked_ioctl = drm_ioctl, |
116 | .mmap = i810_mmap_buffers, | 116 | .mmap = i810_mmap_buffers, |
117 | .fasync = drm_fasync, | 117 | .fasync = drm_fasync, |
118 | #ifdef CONFIG_COMPAT | ||
119 | .compat_ioctl = drm_compat_ioctl, | ||
120 | #endif | ||
118 | .llseek = noop_llseek, | 121 | .llseek = noop_llseek, |
119 | }; | 122 | }; |
120 | 123 | ||
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index f9924ad04d09..48cfcca2b350 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c | |||
@@ -51,6 +51,9 @@ static const struct file_operations i810_driver_fops = { | |||
51 | .mmap = drm_mmap, | 51 | .mmap = drm_mmap, |
52 | .poll = drm_poll, | 52 | .poll = drm_poll, |
53 | .fasync = drm_fasync, | 53 | .fasync = drm_fasync, |
54 | #ifdef CONFIG_COMPAT | ||
55 | .compat_ioctl = drm_compat_ioctl, | ||
56 | #endif | ||
54 | .llseek = noop_llseek, | 57 | .llseek = noop_llseek, |
55 | }; | 58 | }; |
56 | 59 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9cf7dfe022b9..914c0dfabe60 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1587,6 +1587,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1587 | spin_lock_init(&dev_priv->irq_lock); | 1587 | spin_lock_init(&dev_priv->irq_lock); |
1588 | spin_lock_init(&dev_priv->error_lock); | 1588 | spin_lock_init(&dev_priv->error_lock); |
1589 | spin_lock_init(&dev_priv->rps_lock); | 1589 | spin_lock_init(&dev_priv->rps_lock); |
1590 | spin_lock_init(&dev_priv->dpio_lock); | ||
1590 | 1591 | ||
1591 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) | 1592 | if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) |
1592 | dev_priv->num_pipe = 3; | 1593 | dev_priv->num_pipe = 3; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8a3828528b9d..5249640cce13 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -2700,9 +2700,6 @@ void intel_irq_init(struct drm_device *dev) | |||
2700 | dev->driver->irq_handler = i8xx_irq_handler; | 2700 | dev->driver->irq_handler = i8xx_irq_handler; |
2701 | dev->driver->irq_uninstall = i8xx_irq_uninstall; | 2701 | dev->driver->irq_uninstall = i8xx_irq_uninstall; |
2702 | } else if (INTEL_INFO(dev)->gen == 3) { | 2702 | } else if (INTEL_INFO(dev)->gen == 3) { |
2703 | /* IIR "flip pending" means done if this bit is set */ | ||
2704 | I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); | ||
2705 | |||
2706 | dev->driver->irq_preinstall = i915_irq_preinstall; | 2703 | dev->driver->irq_preinstall = i915_irq_preinstall; |
2707 | dev->driver->irq_postinstall = i915_irq_postinstall; | 2704 | dev->driver->irq_postinstall = i915_irq_postinstall; |
2708 | dev->driver->irq_uninstall = i915_irq_uninstall; | 2705 | dev->driver->irq_uninstall = i915_irq_uninstall; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 2dfa6cf4886b..bc2ad348e5d8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1376,7 +1376,8 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, | |||
1376 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", | 1376 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1377 | reg, pipe_name(pipe)); | 1377 | reg, pipe_name(pipe)); |
1378 | 1378 | ||
1379 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), | 1379 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 |
1380 | && (val & DP_PIPEB_SELECT), | ||
1380 | "IBX PCH dp port still using transcoder B\n"); | 1381 | "IBX PCH dp port still using transcoder B\n"); |
1381 | } | 1382 | } |
1382 | 1383 | ||
@@ -1388,7 +1389,8 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | |||
1388 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", | 1389 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
1389 | reg, pipe_name(pipe)); | 1390 | reg, pipe_name(pipe)); |
1390 | 1391 | ||
1391 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & SDVO_PIPE_B_SELECT), | 1392 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 |
1393 | && (val & SDVO_PIPE_B_SELECT), | ||
1392 | "IBX PCH hdmi port still using transcoder B\n"); | 1394 | "IBX PCH hdmi port still using transcoder B\n"); |
1393 | } | 1395 | } |
1394 | 1396 | ||
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index a6c426afaa7a..ace757af9133 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -2533,14 +2533,10 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2533 | break; | 2533 | break; |
2534 | } | 2534 | } |
2535 | 2535 | ||
2536 | intel_dp_i2c_init(intel_dp, intel_connector, name); | ||
2537 | |||
2538 | /* Cache some DPCD data in the eDP case */ | 2536 | /* Cache some DPCD data in the eDP case */ |
2539 | if (is_edp(intel_dp)) { | 2537 | if (is_edp(intel_dp)) { |
2540 | bool ret; | ||
2541 | struct edp_power_seq cur, vbt; | 2538 | struct edp_power_seq cur, vbt; |
2542 | u32 pp_on, pp_off, pp_div; | 2539 | u32 pp_on, pp_off, pp_div; |
2543 | struct edid *edid; | ||
2544 | 2540 | ||
2545 | pp_on = I915_READ(PCH_PP_ON_DELAYS); | 2541 | pp_on = I915_READ(PCH_PP_ON_DELAYS); |
2546 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); | 2542 | pp_off = I915_READ(PCH_PP_OFF_DELAYS); |
@@ -2591,6 +2587,13 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
2591 | 2587 | ||
2592 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", | 2588 | DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", |
2593 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); | 2589 | intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); |
2590 | } | ||
2591 | |||
2592 | intel_dp_i2c_init(intel_dp, intel_connector, name); | ||
2593 | |||
2594 | if (is_edp(intel_dp)) { | ||
2595 | bool ret; | ||
2596 | struct edid *edid; | ||
2594 | 2597 | ||
2595 | ironlake_edp_panel_vdd_on(intel_dp); | 2598 | ironlake_edp_panel_vdd_on(intel_dp); |
2596 | ret = intel_dp_get_dpcd(intel_dp); | 2599 | ret = intel_dp_get_dpcd(intel_dp); |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 3df4f5fa892a..e019b2369861 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -162,19 +162,12 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) | |||
162 | return val; | 162 | return val; |
163 | } | 163 | } |
164 | 164 | ||
165 | u32 intel_panel_get_max_backlight(struct drm_device *dev) | 165 | static u32 _intel_panel_get_max_backlight(struct drm_device *dev) |
166 | { | 166 | { |
167 | struct drm_i915_private *dev_priv = dev->dev_private; | 167 | struct drm_i915_private *dev_priv = dev->dev_private; |
168 | u32 max; | 168 | u32 max; |
169 | 169 | ||
170 | max = i915_read_blc_pwm_ctl(dev_priv); | 170 | max = i915_read_blc_pwm_ctl(dev_priv); |
171 | if (max == 0) { | ||
172 | /* XXX add code here to query mode clock or hardware clock | ||
173 | * and program max PWM appropriately. | ||
174 | */ | ||
175 | pr_warn_once("fixme: max PWM is zero\n"); | ||
176 | return 1; | ||
177 | } | ||
178 | 171 | ||
179 | if (HAS_PCH_SPLIT(dev)) { | 172 | if (HAS_PCH_SPLIT(dev)) { |
180 | max >>= 16; | 173 | max >>= 16; |
@@ -188,6 +181,22 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) | |||
188 | max *= 0xff; | 181 | max *= 0xff; |
189 | } | 182 | } |
190 | 183 | ||
184 | return max; | ||
185 | } | ||
186 | |||
187 | u32 intel_panel_get_max_backlight(struct drm_device *dev) | ||
188 | { | ||
189 | u32 max; | ||
190 | |||
191 | max = _intel_panel_get_max_backlight(dev); | ||
192 | if (max == 0) { | ||
193 | /* XXX add code here to query mode clock or hardware clock | ||
194 | * and program max PWM appropriately. | ||
195 | */ | ||
196 | pr_warn_once("fixme: max PWM is zero\n"); | ||
197 | return 1; | ||
198 | } | ||
199 | |||
191 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); | 200 | DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); |
192 | return max; | 201 | return max; |
193 | } | 202 | } |
@@ -424,7 +433,11 @@ int intel_panel_setup_backlight(struct drm_device *dev) | |||
424 | 433 | ||
425 | memset(&props, 0, sizeof(props)); | 434 | memset(&props, 0, sizeof(props)); |
426 | props.type = BACKLIGHT_RAW; | 435 | props.type = BACKLIGHT_RAW; |
427 | props.max_brightness = intel_panel_get_max_backlight(dev); | 436 | props.max_brightness = _intel_panel_get_max_backlight(dev); |
437 | if (props.max_brightness == 0) { | ||
438 | DRM_ERROR("Failed to get maximum backlight value\n"); | ||
439 | return -ENODEV; | ||
440 | } | ||
428 | dev_priv->backlight = | 441 | dev_priv->backlight = |
429 | backlight_device_register("intel_backlight", | 442 | backlight_device_register("intel_backlight", |
430 | &connector->kdev, dev, | 443 | &connector->kdev, dev, |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 1881c8c83f0e..ba8a27b1757a 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3672,6 +3672,9 @@ static void gen3_init_clock_gating(struct drm_device *dev) | |||
3672 | 3672 | ||
3673 | if (IS_PINEVIEW(dev)) | 3673 | if (IS_PINEVIEW(dev)) |
3674 | I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); | 3674 | I915_WRITE(ECOSKPD, _MASKED_BIT_ENABLE(ECO_GATING_CX_ONLY)); |
3675 | |||
3676 | /* IIR "flip pending" means done if this bit is set */ | ||
3677 | I915_WRITE(ECOSKPD, _MASKED_BIT_DISABLE(ECO_FLIP_DONE)); | ||
3675 | } | 3678 | } |
3676 | 3679 | ||
3677 | static void i85x_init_clock_gating(struct drm_device *dev) | 3680 | static void i85x_init_clock_gating(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d81bb0bf2885..123afd357611 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -2573,7 +2573,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2573 | hotplug_mask = intel_sdvo->is_sdvob ? | 2573 | hotplug_mask = intel_sdvo->is_sdvob ? |
2574 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; | 2574 | SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915; |
2575 | } | 2575 | } |
2576 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2577 | 2576 | ||
2578 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); | 2577 | drm_encoder_helper_add(&intel_encoder->base, &intel_sdvo_helper_funcs); |
2579 | 2578 | ||
@@ -2581,14 +2580,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2581 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) | 2580 | if (!intel_sdvo_get_capabilities(intel_sdvo, &intel_sdvo->caps)) |
2582 | goto err; | 2581 | goto err; |
2583 | 2582 | ||
2584 | /* Set up hotplug command - note paranoia about contents of reply. | ||
2585 | * We assume that the hardware is in a sane state, and only touch | ||
2586 | * the bits we think we understand. | ||
2587 | */ | ||
2588 | intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, | ||
2589 | &intel_sdvo->hotplug_active, 2); | ||
2590 | intel_sdvo->hotplug_active[0] &= ~0x3; | ||
2591 | |||
2592 | if (intel_sdvo_output_setup(intel_sdvo, | 2583 | if (intel_sdvo_output_setup(intel_sdvo, |
2593 | intel_sdvo->caps.output_flags) != true) { | 2584 | intel_sdvo->caps.output_flags) != true) { |
2594 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", | 2585 | DRM_DEBUG_KMS("SDVO output failed to setup on %s\n", |
@@ -2596,6 +2587,12 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob) | |||
2596 | goto err; | 2587 | goto err; |
2597 | } | 2588 | } |
2598 | 2589 | ||
2590 | /* Only enable the hotplug irq if we need it, to work around noisy | ||
2591 | * hotplug lines. | ||
2592 | */ | ||
2593 | if (intel_sdvo->hotplug_active[0]) | ||
2594 | dev_priv->hotplug_supported_mask |= hotplug_mask; | ||
2595 | |||
2599 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); | 2596 | intel_sdvo_select_ddc_bus(dev_priv, intel_sdvo, sdvo_reg); |
2600 | 2597 | ||
2601 | /* Set the input timing to the screen. Assume always input 0. */ | 2598 | /* Set the input timing to the screen. Assume always input 0. */ |
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c index ea1024d79974..e5f145d2cb3b 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.c +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c | |||
@@ -84,6 +84,9 @@ static const struct file_operations mgag200_driver_fops = { | |||
84 | .mmap = mgag200_mmap, | 84 | .mmap = mgag200_mmap, |
85 | .poll = drm_poll, | 85 | .poll = drm_poll, |
86 | .fasync = drm_fasync, | 86 | .fasync = drm_fasync, |
87 | #ifdef CONFIG_COMPAT | ||
88 | .compat_ioctl = drm_compat_ioctl, | ||
89 | #endif | ||
87 | .read = drm_read, | 90 | .read = drm_read, |
88 | }; | 91 | }; |
89 | 92 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 69688ef5cf46..7e16dc5e6467 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -598,7 +598,7 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, | |||
598 | args->size = args->pitch * args->height; | 598 | args->size = args->pitch * args->height; |
599 | args->size = roundup(args->size, PAGE_SIZE); | 599 | args->size = roundup(args->size, PAGE_SIZE); |
600 | 600 | ||
601 | ret = nouveau_gem_new(dev, args->size, 0, TTM_PL_FLAG_VRAM, 0, 0, &bo); | 601 | ret = nouveau_gem_new(dev, args->size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0, &bo); |
602 | if (ret) | 602 | if (ret) |
603 | return ret; | 603 | return ret; |
604 | 604 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index f429e6a8ca7a..f03490534893 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c | |||
@@ -115,6 +115,9 @@ nv50_gpio_init(struct drm_device *dev) | |||
115 | { | 115 | { |
116 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 116 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
117 | 117 | ||
118 | /* initialise gpios and routing to vbios defaults */ | ||
119 | nouveau_gpio_reset(dev); | ||
120 | |||
118 | /* disable, and ack any pending gpio interrupts */ | 121 | /* disable, and ack any pending gpio interrupts */ |
119 | nv_wr32(dev, 0xe050, 0x00000000); | 122 | nv_wr32(dev, 0xe050, 0x00000000); |
120 | nv_wr32(dev, 0xe054, 0xffffffff); | 123 | nv_wr32(dev, 0xe054, 0xffffffff); |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index dac525b2994e..8a2fc89b7763 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -1510,10 +1510,10 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, | |||
1510 | case OUTPUT_DP: | 1510 | case OUTPUT_DP: |
1511 | if (nv_connector->base.display_info.bpc == 6) { | 1511 | if (nv_connector->base.display_info.bpc == 6) { |
1512 | nv_encoder->dp.datarate = mode->clock * 18 / 8; | 1512 | nv_encoder->dp.datarate = mode->clock * 18 / 8; |
1513 | syncs |= 0x00000140; | 1513 | syncs |= 0x00000002 << 6; |
1514 | } else { | 1514 | } else { |
1515 | nv_encoder->dp.datarate = mode->clock * 24 / 8; | 1515 | nv_encoder->dp.datarate = mode->clock * 24 / 8; |
1516 | syncs |= 0x00000180; | 1516 | syncs |= 0x00000005 << 6; |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | if (nv_encoder->dcb->sorconf.link & 1) | 1519 | if (nv_encoder->dcb->sorconf.link & 1) |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 2817101fb167..e721e3087b99 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1479,14 +1479,98 @@ static void radeon_legacy_atom_fixup(struct drm_crtc *crtc) | |||
1479 | } | 1479 | } |
1480 | } | 1480 | } |
1481 | 1481 | ||
1482 | /** | ||
1483 | * radeon_get_pll_use_mask - look up a mask of which pplls are in use | ||
1484 | * | ||
1485 | * @crtc: drm crtc | ||
1486 | * | ||
1487 | * Returns the mask of which PPLLs (Pixel PLLs) are in use. | ||
1488 | */ | ||
1489 | static u32 radeon_get_pll_use_mask(struct drm_crtc *crtc) | ||
1490 | { | ||
1491 | struct drm_device *dev = crtc->dev; | ||
1492 | struct drm_crtc *test_crtc; | ||
1493 | struct radeon_crtc *radeon_test_crtc; | ||
1494 | u32 pll_in_use = 0; | ||
1495 | |||
1496 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | ||
1497 | if (crtc == test_crtc) | ||
1498 | continue; | ||
1499 | |||
1500 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1501 | if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) | ||
1502 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1503 | } | ||
1504 | return pll_in_use; | ||
1505 | } | ||
1506 | |||
1507 | /** | ||
1508 | * radeon_get_shared_dp_ppll - return the PPLL used by another crtc for DP | ||
1509 | * | ||
1510 | * @crtc: drm crtc | ||
1511 | * | ||
1512 | * Returns the PPLL (Pixel PLL) used by another crtc/encoder which is | ||
1513 | * also in DP mode. For DP, a single PPLL can be used for all DP | ||
1514 | * crtcs/encoders. | ||
1515 | */ | ||
1516 | static int radeon_get_shared_dp_ppll(struct drm_crtc *crtc) | ||
1517 | { | ||
1518 | struct drm_device *dev = crtc->dev; | ||
1519 | struct drm_encoder *test_encoder; | ||
1520 | struct radeon_crtc *radeon_test_crtc; | ||
1521 | |||
1522 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | ||
1523 | if (test_encoder->crtc && (test_encoder->crtc != crtc)) { | ||
1524 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | ||
1525 | /* for DP use the same PLL for all */ | ||
1526 | radeon_test_crtc = to_radeon_crtc(test_encoder->crtc); | ||
1527 | if (radeon_test_crtc->pll_id != ATOM_PPLL_INVALID) | ||
1528 | return radeon_test_crtc->pll_id; | ||
1529 | } | ||
1530 | } | ||
1531 | } | ||
1532 | return ATOM_PPLL_INVALID; | ||
1533 | } | ||
1534 | |||
1535 | /** | ||
1536 | * radeon_atom_pick_pll - Allocate a PPLL for use by the crtc. | ||
1537 | * | ||
1538 | * @crtc: drm crtc | ||
1539 | * | ||
1540 | * Returns the PPLL (Pixel PLL) to be used by the crtc. For DP monitors | ||
1541 | * a single PPLL can be used for all DP crtcs/encoders. For non-DP | ||
1542 | * monitors a dedicated PPLL must be used. If a particular board has | ||
1543 | * an external DP PLL, return ATOM_PPLL_INVALID to skip PLL programming | ||
1544 | * as there is no need to program the PLL itself. If we are not able to | ||
1545 | * allocate a PLL, return ATOM_PPLL_INVALID to skip PLL programming to | ||
1546 | * avoid messing up an existing monitor. | ||
1547 | * | ||
1548 | * Asic specific PLL information | ||
1549 | * | ||
1550 | * DCE 6.1 | ||
1551 | * - PPLL2 is only available to UNIPHYA (both DP and non-DP) | ||
1552 | * - PPLL0, PPLL1 are available for UNIPHYB/C/D/E/F (both DP and non-DP) | ||
1553 | * | ||
1554 | * DCE 6.0 | ||
1555 | * - PPLL0 is available to all UNIPHY (DP only) | ||
1556 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1557 | * | ||
1558 | * DCE 5.0 | ||
1559 | * - DCPLL is available to all UNIPHY (DP only) | ||
1560 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1561 | * | ||
1562 | * DCE 3.0/4.0/4.1 | ||
1563 | * - PPLL1, PPLL2 are available for all UNIPHY (both DP and non-DP) and DAC | ||
1564 | * | ||
1565 | */ | ||
1482 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) | 1566 | static int radeon_atom_pick_pll(struct drm_crtc *crtc) |
1483 | { | 1567 | { |
1484 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1568 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1485 | struct drm_device *dev = crtc->dev; | 1569 | struct drm_device *dev = crtc->dev; |
1486 | struct radeon_device *rdev = dev->dev_private; | 1570 | struct radeon_device *rdev = dev->dev_private; |
1487 | struct drm_encoder *test_encoder; | 1571 | struct drm_encoder *test_encoder; |
1488 | struct drm_crtc *test_crtc; | 1572 | u32 pll_in_use; |
1489 | uint32_t pll_in_use = 0; | 1573 | int pll; |
1490 | 1574 | ||
1491 | if (ASIC_IS_DCE61(rdev)) { | 1575 | if (ASIC_IS_DCE61(rdev)) { |
1492 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | 1576 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { |
@@ -1498,32 +1582,40 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1498 | 1582 | ||
1499 | if ((test_radeon_encoder->encoder_id == | 1583 | if ((test_radeon_encoder->encoder_id == |
1500 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && | 1584 | ENCODER_OBJECT_ID_INTERNAL_UNIPHY) && |
1501 | (dig->linkb == false)) /* UNIPHY A uses PPLL2 */ | 1585 | (dig->linkb == false)) |
1586 | /* UNIPHY A uses PPLL2 */ | ||
1502 | return ATOM_PPLL2; | 1587 | return ATOM_PPLL2; |
1588 | else if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | ||
1589 | /* UNIPHY B/C/D/E/F */ | ||
1590 | if (rdev->clock.dp_extclk) | ||
1591 | /* skip PPLL programming if using ext clock */ | ||
1592 | return ATOM_PPLL_INVALID; | ||
1593 | else { | ||
1594 | /* use the same PPLL for all DP monitors */ | ||
1595 | pll = radeon_get_shared_dp_ppll(crtc); | ||
1596 | if (pll != ATOM_PPLL_INVALID) | ||
1597 | return pll; | ||
1598 | } | ||
1599 | } | ||
1600 | break; | ||
1503 | } | 1601 | } |
1504 | } | 1602 | } |
1505 | /* UNIPHY B/C/D/E/F */ | 1603 | /* UNIPHY B/C/D/E/F */ |
1506 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | 1604 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1507 | struct radeon_crtc *radeon_test_crtc; | 1605 | if (!(pll_in_use & (1 << ATOM_PPLL0))) |
1508 | |||
1509 | if (crtc == test_crtc) | ||
1510 | continue; | ||
1511 | |||
1512 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1513 | if ((radeon_test_crtc->pll_id == ATOM_PPLL0) || | ||
1514 | (radeon_test_crtc->pll_id == ATOM_PPLL1)) | ||
1515 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1516 | } | ||
1517 | if (!(pll_in_use & 4)) | ||
1518 | return ATOM_PPLL0; | 1606 | return ATOM_PPLL0; |
1519 | return ATOM_PPLL1; | 1607 | if (!(pll_in_use & (1 << ATOM_PPLL1))) |
1608 | return ATOM_PPLL1; | ||
1609 | DRM_ERROR("unable to allocate a PPLL\n"); | ||
1610 | return ATOM_PPLL_INVALID; | ||
1520 | } else if (ASIC_IS_DCE4(rdev)) { | 1611 | } else if (ASIC_IS_DCE4(rdev)) { |
1521 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { | 1612 | list_for_each_entry(test_encoder, &dev->mode_config.encoder_list, head) { |
1522 | if (test_encoder->crtc && (test_encoder->crtc == crtc)) { | 1613 | if (test_encoder->crtc && (test_encoder->crtc == crtc)) { |
1523 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, | 1614 | /* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock, |
1524 | * depending on the asic: | 1615 | * depending on the asic: |
1525 | * DCE4: PPLL or ext clock | 1616 | * DCE4: PPLL or ext clock |
1526 | * DCE5: DCPLL or ext clock | 1617 | * DCE5: PPLL, DCPLL, or ext clock |
1618 | * DCE6: PPLL, PPLL0, or ext clock | ||
1527 | * | 1619 | * |
1528 | * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip | 1620 | * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip |
1529 | * PPLL/DCPLL programming and only program the DP DTO for the | 1621 | * PPLL/DCPLL programming and only program the DP DTO for the |
@@ -1531,31 +1623,34 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1531 | */ | 1623 | */ |
1532 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1624 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
1533 | if (rdev->clock.dp_extclk) | 1625 | if (rdev->clock.dp_extclk) |
1626 | /* skip PPLL programming if using ext clock */ | ||
1534 | return ATOM_PPLL_INVALID; | 1627 | return ATOM_PPLL_INVALID; |
1535 | else if (ASIC_IS_DCE6(rdev)) | 1628 | else if (ASIC_IS_DCE6(rdev)) |
1629 | /* use PPLL0 for all DP */ | ||
1536 | return ATOM_PPLL0; | 1630 | return ATOM_PPLL0; |
1537 | else if (ASIC_IS_DCE5(rdev)) | 1631 | else if (ASIC_IS_DCE5(rdev)) |
1632 | /* use DCPLL for all DP */ | ||
1538 | return ATOM_DCPLL; | 1633 | return ATOM_DCPLL; |
1634 | else { | ||
1635 | /* use the same PPLL for all DP monitors */ | ||
1636 | pll = radeon_get_shared_dp_ppll(crtc); | ||
1637 | if (pll != ATOM_PPLL_INVALID) | ||
1638 | return pll; | ||
1639 | } | ||
1539 | } | 1640 | } |
1641 | break; | ||
1540 | } | 1642 | } |
1541 | } | 1643 | } |
1542 | 1644 | /* all other cases */ | |
1543 | /* otherwise, pick one of the plls */ | 1645 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1544 | list_for_each_entry(test_crtc, &dev->mode_config.crtc_list, head) { | 1646 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
1545 | struct radeon_crtc *radeon_test_crtc; | 1647 | return ATOM_PPLL2; |
1546 | 1648 | if (!(pll_in_use & (1 << ATOM_PPLL1))) | |
1547 | if (crtc == test_crtc) | ||
1548 | continue; | ||
1549 | |||
1550 | radeon_test_crtc = to_radeon_crtc(test_crtc); | ||
1551 | if ((radeon_test_crtc->pll_id >= ATOM_PPLL1) && | ||
1552 | (radeon_test_crtc->pll_id <= ATOM_PPLL2)) | ||
1553 | pll_in_use |= (1 << radeon_test_crtc->pll_id); | ||
1554 | } | ||
1555 | if (!(pll_in_use & 1)) | ||
1556 | return ATOM_PPLL1; | 1649 | return ATOM_PPLL1; |
1557 | return ATOM_PPLL2; | 1650 | DRM_ERROR("unable to allocate a PPLL\n"); |
1651 | return ATOM_PPLL_INVALID; | ||
1558 | } else | 1652 | } else |
1653 | /* use PPLL1 or PPLL2 */ | ||
1559 | return radeon_crtc->crtc_id; | 1654 | return radeon_crtc->crtc_id; |
1560 | 1655 | ||
1561 | } | 1656 | } |
@@ -1697,7 +1792,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
1697 | break; | 1792 | break; |
1698 | } | 1793 | } |
1699 | done: | 1794 | done: |
1700 | radeon_crtc->pll_id = -1; | 1795 | radeon_crtc->pll_id = ATOM_PPLL_INVALID; |
1701 | } | 1796 | } |
1702 | 1797 | ||
1703 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | 1798 | static const struct drm_crtc_helper_funcs atombios_helper_funcs = { |
@@ -1746,6 +1841,6 @@ void radeon_atombios_init_crtc(struct drm_device *dev, | |||
1746 | else | 1841 | else |
1747 | radeon_crtc->crtc_offset = 0; | 1842 | radeon_crtc->crtc_offset = 0; |
1748 | } | 1843 | } |
1749 | radeon_crtc->pll_id = -1; | 1844 | radeon_crtc->pll_id = ATOM_PPLL_INVALID; |
1750 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); | 1845 | drm_crtc_helper_add(&radeon_crtc->base, &atombios_helper_funcs); |
1751 | } | 1846 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 7b737b9339ad..2a59375dbe52 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -131,7 +131,7 @@ int radeon_fence_emit(struct radeon_device *rdev, | |||
131 | */ | 131 | */ |
132 | void radeon_fence_process(struct radeon_device *rdev, int ring) | 132 | void radeon_fence_process(struct radeon_device *rdev, int ring) |
133 | { | 133 | { |
134 | uint64_t seq, last_seq; | 134 | uint64_t seq, last_seq, last_emitted; |
135 | unsigned count_loop = 0; | 135 | unsigned count_loop = 0; |
136 | bool wake = false; | 136 | bool wake = false; |
137 | 137 | ||
@@ -158,13 +158,15 @@ void radeon_fence_process(struct radeon_device *rdev, int ring) | |||
158 | */ | 158 | */ |
159 | last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq); | 159 | last_seq = atomic64_read(&rdev->fence_drv[ring].last_seq); |
160 | do { | 160 | do { |
161 | last_emitted = rdev->fence_drv[ring].sync_seq[ring]; | ||
161 | seq = radeon_fence_read(rdev, ring); | 162 | seq = radeon_fence_read(rdev, ring); |
162 | seq |= last_seq & 0xffffffff00000000LL; | 163 | seq |= last_seq & 0xffffffff00000000LL; |
163 | if (seq < last_seq) { | 164 | if (seq < last_seq) { |
164 | seq += 0x100000000LL; | 165 | seq &= 0xffffffff; |
166 | seq |= last_emitted & 0xffffffff00000000LL; | ||
165 | } | 167 | } |
166 | 168 | ||
167 | if (seq == last_seq) { | 169 | if (seq <= last_seq || seq > last_emitted) { |
168 | break; | 170 | break; |
169 | } | 171 | } |
170 | /* If we loop over we don't want to return without | 172 | /* If we loop over we don't want to return without |
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index d31d4cca9a4c..c5a164337bd5 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c | |||
@@ -43,6 +43,9 @@ static const struct file_operations savage_driver_fops = { | |||
43 | .mmap = drm_mmap, | 43 | .mmap = drm_mmap, |
44 | .poll = drm_poll, | 44 | .poll = drm_poll, |
45 | .fasync = drm_fasync, | 45 | .fasync = drm_fasync, |
46 | #ifdef CONFIG_COMPAT | ||
47 | .compat_ioctl = drm_compat_ioctl, | ||
48 | #endif | ||
46 | .llseek = noop_llseek, | 49 | .llseek = noop_llseek, |
47 | }; | 50 | }; |
48 | 51 | ||
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 7f119870147c..867dc03000e6 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -74,6 +74,9 @@ static const struct file_operations sis_driver_fops = { | |||
74 | .mmap = drm_mmap, | 74 | .mmap = drm_mmap, |
75 | .poll = drm_poll, | 75 | .poll = drm_poll, |
76 | .fasync = drm_fasync, | 76 | .fasync = drm_fasync, |
77 | #ifdef CONFIG_COMPAT | ||
78 | .compat_ioctl = drm_compat_ioctl, | ||
79 | #endif | ||
77 | .llseek = noop_llseek, | 80 | .llseek = noop_llseek, |
78 | }; | 81 | }; |
79 | 82 | ||
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 90f6b13acfac..a7f4d6bd1330 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c | |||
@@ -49,6 +49,9 @@ static const struct file_operations tdfx_driver_fops = { | |||
49 | .mmap = drm_mmap, | 49 | .mmap = drm_mmap, |
50 | .poll = drm_poll, | 50 | .poll = drm_poll, |
51 | .fasync = drm_fasync, | 51 | .fasync = drm_fasync, |
52 | #ifdef CONFIG_COMPAT | ||
53 | .compat_ioctl = drm_compat_ioctl, | ||
54 | #endif | ||
52 | .llseek = noop_llseek, | 55 | .llseek = noop_llseek, |
53 | }; | 56 | }; |
54 | 57 | ||
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c index 6e52069894b3..9f84128505bb 100644 --- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c | |||
@@ -66,6 +66,9 @@ static const struct file_operations udl_driver_fops = { | |||
66 | .unlocked_ioctl = drm_ioctl, | 66 | .unlocked_ioctl = drm_ioctl, |
67 | .release = drm_release, | 67 | .release = drm_release, |
68 | .fasync = drm_fasync, | 68 | .fasync = drm_fasync, |
69 | #ifdef CONFIG_COMPAT | ||
70 | .compat_ioctl = drm_compat_ioctl, | ||
71 | #endif | ||
69 | .llseek = noop_llseek, | 72 | .llseek = noop_llseek, |
70 | }; | 73 | }; |
71 | 74 | ||
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c index e927b4c052f5..af1b914b17e3 100644 --- a/drivers/gpu/drm/via/via_drv.c +++ b/drivers/gpu/drm/via/via_drv.c | |||
@@ -65,6 +65,9 @@ static const struct file_operations via_driver_fops = { | |||
65 | .mmap = drm_mmap, | 65 | .mmap = drm_mmap, |
66 | .poll = drm_poll, | 66 | .poll = drm_poll, |
67 | .fasync = drm_fasync, | 67 | .fasync = drm_fasync, |
68 | #ifdef CONFIG_COMPAT | ||
69 | .compat_ioctl = drm_compat_ioctl, | ||
70 | #endif | ||
68 | .llseek = noop_llseek, | 71 | .llseek = noop_llseek, |
69 | }; | 72 | }; |
70 | 73 | ||
diff --git a/drivers/gpu/drm/vmwgfx/Kconfig b/drivers/gpu/drm/vmwgfx/Kconfig index 794ff67c5701..b71bcd0bfbbf 100644 --- a/drivers/gpu/drm/vmwgfx/Kconfig +++ b/drivers/gpu/drm/vmwgfx/Kconfig | |||
@@ -12,3 +12,11 @@ config DRM_VMWGFX | |||
12 | This is a KMS enabled DRM driver for the VMware SVGA2 | 12 | This is a KMS enabled DRM driver for the VMware SVGA2 |
13 | virtual hardware. | 13 | virtual hardware. |
14 | The compiled module will be called "vmwgfx.ko". | 14 | The compiled module will be called "vmwgfx.ko". |
15 | |||
16 | config DRM_VMWGFX_FBCON | ||
17 | depends on DRM_VMWGFX | ||
18 | bool "Enable framebuffer console under vmwgfx by default" | ||
19 | help | ||
20 | Choose this option if you are shipping a new vmwgfx | ||
21 | userspace driver that supports using the kernel driver. | ||
22 | |||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 4d9edead01ac..ba2c35dbf10e 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -182,8 +182,9 @@ static struct pci_device_id vmw_pci_id_list[] = { | |||
182 | {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, | 182 | {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, |
183 | {0, 0, 0} | 183 | {0, 0, 0} |
184 | }; | 184 | }; |
185 | MODULE_DEVICE_TABLE(pci, vmw_pci_id_list); | ||
185 | 186 | ||
186 | static int enable_fbdev; | 187 | static int enable_fbdev = IS_ENABLED(CONFIG_DRM_VMWGFX_FBCON); |
187 | 188 | ||
188 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); | 189 | static int vmw_probe(struct pci_dev *, const struct pci_device_id *); |
189 | static void vmw_master_init(struct vmw_master *); | 190 | static void vmw_master_init(struct vmw_master *); |
@@ -1154,6 +1155,11 @@ static struct drm_driver driver = { | |||
1154 | .open = vmw_driver_open, | 1155 | .open = vmw_driver_open, |
1155 | .preclose = vmw_preclose, | 1156 | .preclose = vmw_preclose, |
1156 | .postclose = vmw_postclose, | 1157 | .postclose = vmw_postclose, |
1158 | |||
1159 | .dumb_create = vmw_dumb_create, | ||
1160 | .dumb_map_offset = vmw_dumb_map_offset, | ||
1161 | .dumb_destroy = vmw_dumb_destroy, | ||
1162 | |||
1157 | .fops = &vmwgfx_driver_fops, | 1163 | .fops = &vmwgfx_driver_fops, |
1158 | .name = VMWGFX_DRIVER_NAME, | 1164 | .name = VMWGFX_DRIVER_NAME, |
1159 | .desc = VMWGFX_DRIVER_DESC, | 1165 | .desc = VMWGFX_DRIVER_DESC, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index d0f2c079ee27..29c984ff7f23 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -645,6 +645,16 @@ int vmw_kms_readback(struct vmw_private *dev_priv, | |||
645 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, | 645 | int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, |
646 | struct drm_file *file_priv); | 646 | struct drm_file *file_priv); |
647 | 647 | ||
648 | int vmw_dumb_create(struct drm_file *file_priv, | ||
649 | struct drm_device *dev, | ||
650 | struct drm_mode_create_dumb *args); | ||
651 | |||
652 | int vmw_dumb_map_offset(struct drm_file *file_priv, | ||
653 | struct drm_device *dev, uint32_t handle, | ||
654 | uint64_t *offset); | ||
655 | int vmw_dumb_destroy(struct drm_file *file_priv, | ||
656 | struct drm_device *dev, | ||
657 | uint32_t handle); | ||
648 | /** | 658 | /** |
649 | * Overlay control - vmwgfx_overlay.c | 659 | * Overlay control - vmwgfx_overlay.c |
650 | */ | 660 | */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c index 22bf9a21ec71..2c6ffe0e2c07 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_resource.c | |||
@@ -1917,3 +1917,76 @@ err_ref: | |||
1917 | vmw_resource_unreference(&res); | 1917 | vmw_resource_unreference(&res); |
1918 | return ret; | 1918 | return ret; |
1919 | } | 1919 | } |
1920 | |||
1921 | |||
1922 | int vmw_dumb_create(struct drm_file *file_priv, | ||
1923 | struct drm_device *dev, | ||
1924 | struct drm_mode_create_dumb *args) | ||
1925 | { | ||
1926 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
1927 | struct vmw_master *vmaster = vmw_master(file_priv->master); | ||
1928 | struct vmw_user_dma_buffer *vmw_user_bo; | ||
1929 | struct ttm_buffer_object *tmp; | ||
1930 | int ret; | ||
1931 | |||
1932 | args->pitch = args->width * ((args->bpp + 7) / 8); | ||
1933 | args->size = args->pitch * args->height; | ||
1934 | |||
1935 | vmw_user_bo = kzalloc(sizeof(*vmw_user_bo), GFP_KERNEL); | ||
1936 | if (vmw_user_bo == NULL) | ||
1937 | return -ENOMEM; | ||
1938 | |||
1939 | ret = ttm_read_lock(&vmaster->lock, true); | ||
1940 | if (ret != 0) { | ||
1941 | kfree(vmw_user_bo); | ||
1942 | return ret; | ||
1943 | } | ||
1944 | |||
1945 | ret = vmw_dmabuf_init(dev_priv, &vmw_user_bo->dma, args->size, | ||
1946 | &vmw_vram_sys_placement, true, | ||
1947 | &vmw_user_dmabuf_destroy); | ||
1948 | if (ret != 0) | ||
1949 | goto out_no_dmabuf; | ||
1950 | |||
1951 | tmp = ttm_bo_reference(&vmw_user_bo->dma.base); | ||
1952 | ret = ttm_base_object_init(vmw_fpriv(file_priv)->tfile, | ||
1953 | &vmw_user_bo->base, | ||
1954 | false, | ||
1955 | ttm_buffer_type, | ||
1956 | &vmw_user_dmabuf_release, NULL); | ||
1957 | if (unlikely(ret != 0)) | ||
1958 | goto out_no_base_object; | ||
1959 | |||
1960 | args->handle = vmw_user_bo->base.hash.key; | ||
1961 | |||
1962 | out_no_base_object: | ||
1963 | ttm_bo_unref(&tmp); | ||
1964 | out_no_dmabuf: | ||
1965 | ttm_read_unlock(&vmaster->lock); | ||
1966 | return ret; | ||
1967 | } | ||
1968 | |||
1969 | int vmw_dumb_map_offset(struct drm_file *file_priv, | ||
1970 | struct drm_device *dev, uint32_t handle, | ||
1971 | uint64_t *offset) | ||
1972 | { | ||
1973 | struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile; | ||
1974 | struct vmw_dma_buffer *out_buf; | ||
1975 | int ret; | ||
1976 | |||
1977 | ret = vmw_user_dmabuf_lookup(tfile, handle, &out_buf); | ||
1978 | if (ret != 0) | ||
1979 | return -EINVAL; | ||
1980 | |||
1981 | *offset = out_buf->base.addr_space_offset; | ||
1982 | vmw_dmabuf_unreference(&out_buf); | ||
1983 | return 0; | ||
1984 | } | ||
1985 | |||
1986 | int vmw_dumb_destroy(struct drm_file *file_priv, | ||
1987 | struct drm_device *dev, | ||
1988 | uint32_t handle) | ||
1989 | { | ||
1990 | return ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, | ||
1991 | handle, TTM_REF_USAGE); | ||
1992 | } | ||
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c index 7f3f4a385729..602148299f68 100644 --- a/drivers/hwmon/ina2xx.c +++ b/drivers/hwmon/ina2xx.c | |||
@@ -69,22 +69,6 @@ struct ina2xx_data { | |||
69 | u16 regs[INA2XX_MAX_REGISTERS]; | 69 | u16 regs[INA2XX_MAX_REGISTERS]; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | int ina2xx_read_word(struct i2c_client *client, int reg) | ||
73 | { | ||
74 | int val = i2c_smbus_read_word_data(client, reg); | ||
75 | if (unlikely(val < 0)) { | ||
76 | dev_dbg(&client->dev, | ||
77 | "Failed to read register: %d\n", reg); | ||
78 | return val; | ||
79 | } | ||
80 | return be16_to_cpu(val); | ||
81 | } | ||
82 | |||
83 | void ina2xx_write_word(struct i2c_client *client, int reg, int data) | ||
84 | { | ||
85 | i2c_smbus_write_word_data(client, reg, cpu_to_be16(data)); | ||
86 | } | ||
87 | |||
88 | static struct ina2xx_data *ina2xx_update_device(struct device *dev) | 72 | static struct ina2xx_data *ina2xx_update_device(struct device *dev) |
89 | { | 73 | { |
90 | struct i2c_client *client = to_i2c_client(dev); | 74 | struct i2c_client *client = to_i2c_client(dev); |
@@ -102,7 +86,7 @@ static struct ina2xx_data *ina2xx_update_device(struct device *dev) | |||
102 | 86 | ||
103 | /* Read all registers */ | 87 | /* Read all registers */ |
104 | for (i = 0; i < data->registers; i++) { | 88 | for (i = 0; i < data->registers; i++) { |
105 | int rv = ina2xx_read_word(client, i); | 89 | int rv = i2c_smbus_read_word_swapped(client, i); |
106 | if (rv < 0) { | 90 | if (rv < 0) { |
107 | ret = ERR_PTR(rv); | 91 | ret = ERR_PTR(rv); |
108 | goto abort; | 92 | goto abort; |
@@ -279,22 +263,26 @@ static int ina2xx_probe(struct i2c_client *client, | |||
279 | switch (data->kind) { | 263 | switch (data->kind) { |
280 | case ina219: | 264 | case ina219: |
281 | /* device configuration */ | 265 | /* device configuration */ |
282 | ina2xx_write_word(client, INA2XX_CONFIG, INA219_CONFIG_DEFAULT); | 266 | i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, |
267 | INA219_CONFIG_DEFAULT); | ||
283 | 268 | ||
284 | /* set current LSB to 1mA, shunt is in uOhms */ | 269 | /* set current LSB to 1mA, shunt is in uOhms */ |
285 | /* (equation 13 in datasheet) */ | 270 | /* (equation 13 in datasheet) */ |
286 | ina2xx_write_word(client, INA2XX_CALIBRATION, 40960000 / shunt); | 271 | i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, |
272 | 40960000 / shunt); | ||
287 | dev_info(&client->dev, | 273 | dev_info(&client->dev, |
288 | "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); | 274 | "power monitor INA219 (Rshunt = %li uOhm)\n", shunt); |
289 | data->registers = INA219_REGISTERS; | 275 | data->registers = INA219_REGISTERS; |
290 | break; | 276 | break; |
291 | case ina226: | 277 | case ina226: |
292 | /* device configuration */ | 278 | /* device configuration */ |
293 | ina2xx_write_word(client, INA2XX_CONFIG, INA226_CONFIG_DEFAULT); | 279 | i2c_smbus_write_word_swapped(client, INA2XX_CONFIG, |
280 | INA226_CONFIG_DEFAULT); | ||
294 | 281 | ||
295 | /* set current LSB to 1mA, shunt is in uOhms */ | 282 | /* set current LSB to 1mA, shunt is in uOhms */ |
296 | /* (equation 1 in datasheet)*/ | 283 | /* (equation 1 in datasheet)*/ |
297 | ina2xx_write_word(client, INA2XX_CALIBRATION, 5120000 / shunt); | 284 | i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION, |
285 | 5120000 / shunt); | ||
298 | dev_info(&client->dev, | 286 | dev_info(&client->dev, |
299 | "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); | 287 | "power monitor INA226 (Rshunt = %li uOhm)\n", shunt); |
300 | data->registers = INA226_REGISTERS; | 288 | data->registers = INA226_REGISTERS; |
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index b7975f858cff..fe11b95670bd 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/hwmon-sysfs.h> | 34 | #include <linux/hwmon-sysfs.h> |
35 | 35 | ||
36 | #include <plat/adc.h> | 36 | #include <plat/adc.h> |
37 | #include <plat/hwmon.h> | 37 | #include <linux/platform_data/hwmon-s3c.h> |
38 | 38 | ||
39 | struct s3c_hwmon_attr { | 39 | struct s3c_hwmon_attr { |
40 | struct sensor_device_attribute in; | 40 | struct sensor_device_attribute in; |
diff --git a/drivers/hwmon/twl4030-madc-hwmon.c b/drivers/hwmon/twl4030-madc-hwmon.c index 0018c7dd0097..1a174f0a3cde 100644 --- a/drivers/hwmon/twl4030-madc-hwmon.c +++ b/drivers/hwmon/twl4030-madc-hwmon.c | |||
@@ -44,12 +44,13 @@ static ssize_t madc_read(struct device *dev, | |||
44 | struct device_attribute *devattr, char *buf) | 44 | struct device_attribute *devattr, char *buf) |
45 | { | 45 | { |
46 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 46 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
47 | struct twl4030_madc_request req; | 47 | struct twl4030_madc_request req = { |
48 | .channels = 1 << attr->index, | ||
49 | .method = TWL4030_MADC_SW2, | ||
50 | .type = TWL4030_MADC_WAIT, | ||
51 | }; | ||
48 | long val; | 52 | long val; |
49 | 53 | ||
50 | req.channels = (1 << attr->index); | ||
51 | req.method = TWL4030_MADC_SW2; | ||
52 | req.func_cb = NULL; | ||
53 | val = twl4030_madc_conversion(&req); | 54 | val = twl4030_madc_conversion(&req); |
54 | if (val < 0) | 55 | if (val < 0) |
55 | return val; | 56 | return val; |
diff --git a/drivers/i2c/algos/i2c-algo-pca.c b/drivers/i2c/algos/i2c-algo-pca.c index 73133b1063f0..6f5f98d69af7 100644 --- a/drivers/i2c/algos/i2c-algo-pca.c +++ b/drivers/i2c/algos/i2c-algo-pca.c | |||
@@ -476,17 +476,17 @@ static int pca_init(struct i2c_adapter *adap) | |||
476 | /* To avoid integer overflow, use clock/100 for calculations */ | 476 | /* To avoid integer overflow, use clock/100 for calculations */ |
477 | clock = pca_clock(pca_data) / 100; | 477 | clock = pca_clock(pca_data) / 100; |
478 | 478 | ||
479 | if (pca_data->i2c_clock > 10000) { | 479 | if (pca_data->i2c_clock > 1000000) { |
480 | mode = I2C_PCA_MODE_TURBO; | 480 | mode = I2C_PCA_MODE_TURBO; |
481 | min_tlow = 14; | 481 | min_tlow = 14; |
482 | min_thi = 5; | 482 | min_thi = 5; |
483 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | 483 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ |
484 | } else if (pca_data->i2c_clock > 4000) { | 484 | } else if (pca_data->i2c_clock > 400000) { |
485 | mode = I2C_PCA_MODE_FASTP; | 485 | mode = I2C_PCA_MODE_FASTP; |
486 | min_tlow = 17; | 486 | min_tlow = 17; |
487 | min_thi = 9; | 487 | min_thi = 9; |
488 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ | 488 | raise_fall_time = 22; /* Raise 11e-8s, Fall 11e-8s */ |
489 | } else if (pca_data->i2c_clock > 1000) { | 489 | } else if (pca_data->i2c_clock > 100000) { |
490 | mode = I2C_PCA_MODE_FAST; | 490 | mode = I2C_PCA_MODE_FAST; |
491 | min_tlow = 44; | 491 | min_tlow = 44; |
492 | min_thi = 20; | 492 | min_thi = 20; |
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index b4aaa1bd6728..42d9fdd63de0 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig | |||
@@ -104,6 +104,7 @@ config I2C_I801 | |||
104 | DH89xxCC (PCH) | 104 | DH89xxCC (PCH) |
105 | Panther Point (PCH) | 105 | Panther Point (PCH) |
106 | Lynx Point (PCH) | 106 | Lynx Point (PCH) |
107 | Lynx Point-LP (PCH) | ||
107 | 108 | ||
108 | This driver can also be built as a module. If so, the module | 109 | This driver can also be built as a module. If so, the module |
109 | will be called i2c-i801. | 110 | will be called i2c-i801. |
@@ -354,9 +355,13 @@ config I2C_DAVINCI | |||
354 | devices such as DaVinci NIC. | 355 | devices such as DaVinci NIC. |
355 | For details please see http://www.ti.com/davinci | 356 | For details please see http://www.ti.com/davinci |
356 | 357 | ||
358 | config I2C_DESIGNWARE_CORE | ||
359 | tristate | ||
360 | |||
357 | config I2C_DESIGNWARE_PLATFORM | 361 | config I2C_DESIGNWARE_PLATFORM |
358 | tristate "Synopsys DesignWare Platform" | 362 | tristate "Synopsys DesignWare Platform" |
359 | depends on HAVE_CLK | 363 | depends on HAVE_CLK |
364 | select I2C_DESIGNWARE_CORE | ||
360 | help | 365 | help |
361 | If you say yes to this option, support will be included for the | 366 | If you say yes to this option, support will be included for the |
362 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 367 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
@@ -367,6 +372,7 @@ config I2C_DESIGNWARE_PLATFORM | |||
367 | config I2C_DESIGNWARE_PCI | 372 | config I2C_DESIGNWARE_PCI |
368 | tristate "Synopsys DesignWare PCI" | 373 | tristate "Synopsys DesignWare PCI" |
369 | depends on PCI | 374 | depends on PCI |
375 | select I2C_DESIGNWARE_CORE | ||
370 | help | 376 | help |
371 | If you say yes to this option, support will be included for the | 377 | If you say yes to this option, support will be included for the |
372 | Synopsys DesignWare I2C adapter. Only master mode is supported. | 378 | Synopsys DesignWare I2C adapter. Only master mode is supported. |
@@ -545,7 +551,7 @@ config I2C_PMCMSP | |||
545 | 551 | ||
546 | config I2C_PNX | 552 | config I2C_PNX |
547 | tristate "I2C bus support for Philips PNX and NXP LPC targets" | 553 | tristate "I2C bus support for Philips PNX and NXP LPC targets" |
548 | depends on ARCH_PNX4008 || ARCH_LPC32XX | 554 | depends on ARCH_LPC32XX |
549 | help | 555 | help |
550 | This driver supports the Philips IP3204 I2C IP block master and/or | 556 | This driver supports the Philips IP3204 I2C IP block master and/or |
551 | slave controller | 557 | slave controller |
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index ce3c2be7fb40..37c4182cc98b 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile | |||
@@ -33,10 +33,11 @@ obj-$(CONFIG_I2C_AU1550) += i2c-au1550.o | |||
33 | obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o | 33 | obj-$(CONFIG_I2C_BLACKFIN_TWI) += i2c-bfin-twi.o |
34 | obj-$(CONFIG_I2C_CPM) += i2c-cpm.o | 34 | obj-$(CONFIG_I2C_CPM) += i2c-cpm.o |
35 | obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o | 35 | obj-$(CONFIG_I2C_DAVINCI) += i2c-davinci.o |
36 | obj-$(CONFIG_I2C_DESIGNWARE_CORE) += i2c-designware-core.o | ||
36 | obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o | 37 | obj-$(CONFIG_I2C_DESIGNWARE_PLATFORM) += i2c-designware-platform.o |
37 | i2c-designware-platform-objs := i2c-designware-platdrv.o i2c-designware-core.o | 38 | i2c-designware-platform-objs := i2c-designware-platdrv.o |
38 | obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o | 39 | obj-$(CONFIG_I2C_DESIGNWARE_PCI) += i2c-designware-pci.o |
39 | i2c-designware-pci-objs := i2c-designware-pcidrv.o i2c-designware-core.o | 40 | i2c-designware-pci-objs := i2c-designware-pcidrv.o |
40 | obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o | 41 | obj-$(CONFIG_I2C_EG20T) += i2c-eg20t.o |
41 | obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o | 42 | obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o |
42 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o | 43 | obj-$(CONFIG_I2C_HIGHLANDER) += i2c-highlander.o |
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c index 79b4bcb3b85c..79a2542d8c41 100644 --- a/drivers/i2c/busses/i2c-davinci.c +++ b/drivers/i2c/busses/i2c-davinci.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <linux/gpio.h> | 40 | #include <linux/gpio.h> |
41 | 41 | ||
42 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
43 | #include <mach/i2c.h> | 43 | #include <linux/platform_data/i2c-davinci.h> |
44 | 44 | ||
45 | /* ----- global defines ----------------------------------------------- */ | 45 | /* ----- global defines ----------------------------------------------- */ |
46 | 46 | ||
diff --git a/drivers/i2c/busses/i2c-designware-core.c b/drivers/i2c/busses/i2c-designware-core.c index 1e48bec80edf..7b8ebbefb581 100644 --- a/drivers/i2c/busses/i2c-designware-core.c +++ b/drivers/i2c/busses/i2c-designware-core.c | |||
@@ -25,6 +25,7 @@ | |||
25 | * ---------------------------------------------------------------------------- | 25 | * ---------------------------------------------------------------------------- |
26 | * | 26 | * |
27 | */ | 27 | */ |
28 | #include <linux/export.h> | ||
28 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
29 | #include <linux/errno.h> | 30 | #include <linux/errno.h> |
30 | #include <linux/err.h> | 31 | #include <linux/err.h> |
@@ -316,6 +317,7 @@ int i2c_dw_init(struct dw_i2c_dev *dev) | |||
316 | dw_writel(dev, dev->master_cfg , DW_IC_CON); | 317 | dw_writel(dev, dev->master_cfg , DW_IC_CON); |
317 | return 0; | 318 | return 0; |
318 | } | 319 | } |
320 | EXPORT_SYMBOL_GPL(i2c_dw_init); | ||
319 | 321 | ||
320 | /* | 322 | /* |
321 | * Waiting for bus not busy | 323 | * Waiting for bus not busy |
@@ -568,12 +570,14 @@ done: | |||
568 | 570 | ||
569 | return ret; | 571 | return ret; |
570 | } | 572 | } |
573 | EXPORT_SYMBOL_GPL(i2c_dw_xfer); | ||
571 | 574 | ||
572 | u32 i2c_dw_func(struct i2c_adapter *adap) | 575 | u32 i2c_dw_func(struct i2c_adapter *adap) |
573 | { | 576 | { |
574 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); | 577 | struct dw_i2c_dev *dev = i2c_get_adapdata(adap); |
575 | return dev->functionality; | 578 | return dev->functionality; |
576 | } | 579 | } |
580 | EXPORT_SYMBOL_GPL(i2c_dw_func); | ||
577 | 581 | ||
578 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) | 582 | static u32 i2c_dw_read_clear_intrbits(struct dw_i2c_dev *dev) |
579 | { | 583 | { |
@@ -678,17 +682,20 @@ tx_aborted: | |||
678 | 682 | ||
679 | return IRQ_HANDLED; | 683 | return IRQ_HANDLED; |
680 | } | 684 | } |
685 | EXPORT_SYMBOL_GPL(i2c_dw_isr); | ||
681 | 686 | ||
682 | void i2c_dw_enable(struct dw_i2c_dev *dev) | 687 | void i2c_dw_enable(struct dw_i2c_dev *dev) |
683 | { | 688 | { |
684 | /* Enable the adapter */ | 689 | /* Enable the adapter */ |
685 | dw_writel(dev, 1, DW_IC_ENABLE); | 690 | dw_writel(dev, 1, DW_IC_ENABLE); |
686 | } | 691 | } |
692 | EXPORT_SYMBOL_GPL(i2c_dw_enable); | ||
687 | 693 | ||
688 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) | 694 | u32 i2c_dw_is_enabled(struct dw_i2c_dev *dev) |
689 | { | 695 | { |
690 | return dw_readl(dev, DW_IC_ENABLE); | 696 | return dw_readl(dev, DW_IC_ENABLE); |
691 | } | 697 | } |
698 | EXPORT_SYMBOL_GPL(i2c_dw_is_enabled); | ||
692 | 699 | ||
693 | void i2c_dw_disable(struct dw_i2c_dev *dev) | 700 | void i2c_dw_disable(struct dw_i2c_dev *dev) |
694 | { | 701 | { |
@@ -699,18 +706,22 @@ void i2c_dw_disable(struct dw_i2c_dev *dev) | |||
699 | dw_writel(dev, 0, DW_IC_INTR_MASK); | 706 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
700 | dw_readl(dev, DW_IC_CLR_INTR); | 707 | dw_readl(dev, DW_IC_CLR_INTR); |
701 | } | 708 | } |
709 | EXPORT_SYMBOL_GPL(i2c_dw_disable); | ||
702 | 710 | ||
703 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) | 711 | void i2c_dw_clear_int(struct dw_i2c_dev *dev) |
704 | { | 712 | { |
705 | dw_readl(dev, DW_IC_CLR_INTR); | 713 | dw_readl(dev, DW_IC_CLR_INTR); |
706 | } | 714 | } |
715 | EXPORT_SYMBOL_GPL(i2c_dw_clear_int); | ||
707 | 716 | ||
708 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) | 717 | void i2c_dw_disable_int(struct dw_i2c_dev *dev) |
709 | { | 718 | { |
710 | dw_writel(dev, 0, DW_IC_INTR_MASK); | 719 | dw_writel(dev, 0, DW_IC_INTR_MASK); |
711 | } | 720 | } |
721 | EXPORT_SYMBOL_GPL(i2c_dw_disable_int); | ||
712 | 722 | ||
713 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) | 723 | u32 i2c_dw_read_comp_param(struct dw_i2c_dev *dev) |
714 | { | 724 | { |
715 | return dw_readl(dev, DW_IC_COMP_PARAM_1); | 725 | return dw_readl(dev, DW_IC_COMP_PARAM_1); |
716 | } | 726 | } |
727 | EXPORT_SYMBOL_GPL(i2c_dw_read_comp_param); | ||
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 898dcf9c7ade..33e9b0c09af2 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -52,6 +52,7 @@ | |||
52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes | 52 | DH89xxCC (PCH) 0x2330 32 hard yes yes yes |
53 | Panther Point (PCH) 0x1e22 32 hard yes yes yes | 53 | Panther Point (PCH) 0x1e22 32 hard yes yes yes |
54 | Lynx Point (PCH) 0x8c22 32 hard yes yes yes | 54 | Lynx Point (PCH) 0x8c22 32 hard yes yes yes |
55 | Lynx Point-LP (PCH) 0x9c22 32 hard yes yes yes | ||
55 | 56 | ||
56 | Features supported by this driver: | 57 | Features supported by this driver: |
57 | Software PEC no | 58 | Software PEC no |
@@ -155,6 +156,7 @@ | |||
155 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 | 156 | #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS 0x2330 |
156 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 | 157 | #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS 0x3b30 |
157 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 | 158 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS 0x8c22 |
159 | #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS 0x9c22 | ||
158 | 160 | ||
159 | struct i801_priv { | 161 | struct i801_priv { |
160 | struct i2c_adapter adapter; | 162 | struct i2c_adapter adapter; |
@@ -771,6 +773,7 @@ static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { | |||
771 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, | 773 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) }, |
772 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, | 774 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) }, |
773 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, | 775 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_SMBUS) }, |
776 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_SMBUS) }, | ||
774 | { 0, } | 777 | { 0, } |
775 | }; | 778 | }; |
776 | 779 | ||
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 0722f869465c..b7907ba7448a 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #include <linux/pinctrl/consumer.h> | 54 | #include <linux/pinctrl/consumer.h> |
55 | 55 | ||
56 | #include <mach/hardware.h> | 56 | #include <mach/hardware.h> |
57 | #include <mach/i2c.h> | 57 | #include <linux/platform_data/i2c-imx.h> |
58 | 58 | ||
59 | /** Defines ******************************************************************** | 59 | /** Defines ******************************************************************** |
60 | *******************************************************************************/ | 60 | *******************************************************************************/ |
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index 93f147a96b62..2f99613fd677 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c | |||
@@ -4,13 +4,13 @@ | |||
4 | /* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd | 4 | /* Copyright (C) 2003 Peter Milne, D-TACQ Solutions Ltd |
5 | * <Peter dot Milne at D hyphen TACQ dot com> | 5 | * <Peter dot Milne at D hyphen TACQ dot com> |
6 | * | 6 | * |
7 | * With acknowledgements to i2c-algo-ibm_ocp.c by | 7 | * With acknowledgements to i2c-algo-ibm_ocp.c by |
8 | * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com | 8 | * Ian DaSilva, MontaVista Software, Inc. idasilva@mvista.com |
9 | * | 9 | * |
10 | * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund: | 10 | * And i2c-algo-pcf.c, which was created by Simon G. Vogl and Hans Berglund: |
11 | * | 11 | * |
12 | * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund | 12 | * Copyright (C) 1995-1997 Simon G. Vogl, 1998-2000 Hans Berglund |
13 | * | 13 | * |
14 | * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>, | 14 | * And which acknowledged Kyösti Mälkki <kmalkki@cc.hut.fi>, |
15 | * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com> | 15 | * Frodo Looijaard <frodol@dds.nl>, Martin Bailey<mbailey@littlefeet-inc.com> |
16 | * | 16 | * |
@@ -39,14 +39,15 @@ | |||
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
41 | #include <linux/io.h> | 41 | #include <linux/io.h> |
42 | #include <linux/gpio.h> | ||
42 | 43 | ||
43 | #include "i2c-iop3xx.h" | 44 | #include "i2c-iop3xx.h" |
44 | 45 | ||
45 | /* global unit counter */ | 46 | /* global unit counter */ |
46 | static int i2c_id; | 47 | static int i2c_id; |
47 | 48 | ||
48 | static inline unsigned char | 49 | static inline unsigned char |
49 | iic_cook_addr(struct i2c_msg *msg) | 50 | iic_cook_addr(struct i2c_msg *msg) |
50 | { | 51 | { |
51 | unsigned char addr; | 52 | unsigned char addr; |
52 | 53 | ||
@@ -55,38 +56,38 @@ iic_cook_addr(struct i2c_msg *msg) | |||
55 | if (msg->flags & I2C_M_RD) | 56 | if (msg->flags & I2C_M_RD) |
56 | addr |= 1; | 57 | addr |= 1; |
57 | 58 | ||
58 | return addr; | 59 | return addr; |
59 | } | 60 | } |
60 | 61 | ||
61 | static void | 62 | static void |
62 | iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) | 63 | iop3xx_i2c_reset(struct i2c_algo_iop3xx_data *iop3xx_adap) |
63 | { | 64 | { |
64 | /* Follows devman 9.3 */ | 65 | /* Follows devman 9.3 */ |
65 | __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET); | 66 | __raw_writel(IOP3XX_ICR_UNIT_RESET, iop3xx_adap->ioaddr + CR_OFFSET); |
66 | __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET); | 67 | __raw_writel(IOP3XX_ISR_CLEARBITS, iop3xx_adap->ioaddr + SR_OFFSET); |
67 | __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); | 68 | __raw_writel(0, iop3xx_adap->ioaddr + CR_OFFSET); |
68 | } | 69 | } |
69 | 70 | ||
70 | static void | 71 | static void |
71 | iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) | 72 | iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) |
72 | { | 73 | { |
73 | u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE; | 74 | u32 cr = IOP3XX_ICR_GCD | IOP3XX_ICR_SCLEN | IOP3XX_ICR_UE; |
74 | 75 | ||
75 | /* | 76 | /* |
76 | * Every time unit enable is asserted, GPOD needs to be cleared | 77 | * Every time unit enable is asserted, GPOD needs to be cleared |
77 | * on IOP3XX to avoid data corruption on the bus. | 78 | * on IOP3XX to avoid data corruption on the bus. |
78 | */ | 79 | */ |
79 | #if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X) | 80 | #if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X) |
80 | if (iop3xx_adap->id == 0) { | 81 | if (iop3xx_adap->id == 0) { |
81 | gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW); | 82 | gpio_set_value(7, 0); |
82 | gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW); | 83 | gpio_set_value(6, 0); |
83 | } else { | 84 | } else { |
84 | gpio_line_set(IOP3XX_GPIO_LINE(5), GPIO_LOW); | 85 | gpio_set_value(5, 0); |
85 | gpio_line_set(IOP3XX_GPIO_LINE(4), GPIO_LOW); | 86 | gpio_set_value(4, 0); |
86 | } | 87 | } |
87 | #endif | 88 | #endif |
88 | /* NB SR bits not same position as CR IE bits :-( */ | 89 | /* NB SR bits not same position as CR IE bits :-( */ |
89 | iop3xx_adap->SR_enabled = | 90 | iop3xx_adap->SR_enabled = |
90 | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD | | 91 | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD | |
91 | IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY; | 92 | IOP3XX_ISR_RXFULL | IOP3XX_ISR_TXEMPTY; |
92 | 93 | ||
@@ -96,23 +97,23 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap) | |||
96 | __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); | 97 | __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); |
97 | } | 98 | } |
98 | 99 | ||
99 | static void | 100 | static void |
100 | iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap) | 101 | iop3xx_i2c_transaction_cleanup(struct i2c_algo_iop3xx_data *iop3xx_adap) |
101 | { | 102 | { |
102 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); | 103 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); |
103 | 104 | ||
104 | cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE | | 105 | cr &= ~(IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE | |
105 | IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN); | 106 | IOP3XX_ICR_MSTOP | IOP3XX_ICR_SCLEN); |
106 | 107 | ||
107 | __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); | 108 | __raw_writel(cr, iop3xx_adap->ioaddr + CR_OFFSET); |
108 | } | 109 | } |
109 | 110 | ||
110 | /* | 111 | /* |
111 | * NB: the handler has to clear the source of the interrupt! | 112 | * NB: the handler has to clear the source of the interrupt! |
112 | * Then it passes the SR flags of interest to BH via adap data | 113 | * Then it passes the SR flags of interest to BH via adap data |
113 | */ | 114 | */ |
114 | static irqreturn_t | 115 | static irqreturn_t |
115 | iop3xx_i2c_irq_handler(int this_irq, void *dev_id) | 116 | iop3xx_i2c_irq_handler(int this_irq, void *dev_id) |
116 | { | 117 | { |
117 | struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id; | 118 | struct i2c_algo_iop3xx_data *iop3xx_adap = dev_id; |
118 | u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET); | 119 | u32 sr = __raw_readl(iop3xx_adap->ioaddr + SR_OFFSET); |
@@ -126,7 +127,7 @@ iop3xx_i2c_irq_handler(int this_irq, void *dev_id) | |||
126 | } | 127 | } |
127 | 128 | ||
128 | /* check all error conditions, clear them , report most important */ | 129 | /* check all error conditions, clear them , report most important */ |
129 | static int | 130 | static int |
130 | iop3xx_i2c_error(u32 sr) | 131 | iop3xx_i2c_error(u32 sr) |
131 | { | 132 | { |
132 | int rc = 0; | 133 | int rc = 0; |
@@ -135,12 +136,12 @@ iop3xx_i2c_error(u32 sr) | |||
135 | if ( !rc ) rc = -I2C_ERR_BERR; | 136 | if ( !rc ) rc = -I2C_ERR_BERR; |
136 | } | 137 | } |
137 | if ((sr & IOP3XX_ISR_ALD)) { | 138 | if ((sr & IOP3XX_ISR_ALD)) { |
138 | if ( !rc ) rc = -I2C_ERR_ALD; | 139 | if ( !rc ) rc = -I2C_ERR_ALD; |
139 | } | 140 | } |
140 | return rc; | 141 | return rc; |
141 | } | 142 | } |
142 | 143 | ||
143 | static inline u32 | 144 | static inline u32 |
144 | iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) | 145 | iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) |
145 | { | 146 | { |
146 | unsigned long flags; | 147 | unsigned long flags; |
@@ -161,8 +162,8 @@ iop3xx_i2c_get_srstat(struct i2c_algo_iop3xx_data *iop3xx_adap) | |||
161 | typedef int (* compare_func)(unsigned test, unsigned mask); | 162 | typedef int (* compare_func)(unsigned test, unsigned mask); |
162 | /* returns 1 on correct comparison */ | 163 | /* returns 1 on correct comparison */ |
163 | 164 | ||
164 | static int | 165 | static int |
165 | iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, | 166 | iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, |
166 | unsigned flags, unsigned* status, | 167 | unsigned flags, unsigned* status, |
167 | compare_func compare) | 168 | compare_func compare) |
168 | { | 169 | { |
@@ -192,47 +193,47 @@ iop3xx_i2c_wait_event(struct i2c_algo_iop3xx_data *iop3xx_adap, | |||
192 | } | 193 | } |
193 | 194 | ||
194 | /* | 195 | /* |
195 | * Concrete compare_funcs | 196 | * Concrete compare_funcs |
196 | */ | 197 | */ |
197 | static int | 198 | static int |
198 | all_bits_clear(unsigned test, unsigned mask) | 199 | all_bits_clear(unsigned test, unsigned mask) |
199 | { | 200 | { |
200 | return (test & mask) == 0; | 201 | return (test & mask) == 0; |
201 | } | 202 | } |
202 | 203 | ||
203 | static int | 204 | static int |
204 | any_bits_set(unsigned test, unsigned mask) | 205 | any_bits_set(unsigned test, unsigned mask) |
205 | { | 206 | { |
206 | return (test & mask) != 0; | 207 | return (test & mask) != 0; |
207 | } | 208 | } |
208 | 209 | ||
209 | static int | 210 | static int |
210 | iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) | 211 | iop3xx_i2c_wait_tx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) |
211 | { | 212 | { |
212 | return iop3xx_i2c_wait_event( | 213 | return iop3xx_i2c_wait_event( |
213 | iop3xx_adap, | 214 | iop3xx_adap, |
214 | IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, | 215 | IOP3XX_ISR_TXEMPTY | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, |
215 | status, any_bits_set); | 216 | status, any_bits_set); |
216 | } | 217 | } |
217 | 218 | ||
218 | static int | 219 | static int |
219 | iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) | 220 | iop3xx_i2c_wait_rx_done(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) |
220 | { | 221 | { |
221 | return iop3xx_i2c_wait_event( | 222 | return iop3xx_i2c_wait_event( |
222 | iop3xx_adap, | 223 | iop3xx_adap, |
223 | IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, | 224 | IOP3XX_ISR_RXFULL | IOP3XX_ISR_ALD | IOP3XX_ISR_BERRD, |
224 | status, any_bits_set); | 225 | status, any_bits_set); |
225 | } | 226 | } |
226 | 227 | ||
227 | static int | 228 | static int |
228 | iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) | 229 | iop3xx_i2c_wait_idle(struct i2c_algo_iop3xx_data *iop3xx_adap, int *status) |
229 | { | 230 | { |
230 | return iop3xx_i2c_wait_event( | 231 | return iop3xx_i2c_wait_event( |
231 | iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear); | 232 | iop3xx_adap, IOP3XX_ISR_UNITBUSY, status, all_bits_clear); |
232 | } | 233 | } |
233 | 234 | ||
234 | static int | 235 | static int |
235 | iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, | 236 | iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, |
236 | struct i2c_msg* msg) | 237 | struct i2c_msg* msg) |
237 | { | 238 | { |
238 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); | 239 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); |
@@ -247,7 +248,7 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, | |||
247 | } | 248 | } |
248 | 249 | ||
249 | __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); | 250 | __raw_writel(iic_cook_addr(msg), iop3xx_adap->ioaddr + DBR_OFFSET); |
250 | 251 | ||
251 | cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); | 252 | cr &= ~(IOP3XX_ICR_MSTOP | IOP3XX_ICR_NACK); |
252 | cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE; | 253 | cr |= IOP3XX_ICR_MSTART | IOP3XX_ICR_TBYTE; |
253 | 254 | ||
@@ -257,8 +258,8 @@ iop3xx_i2c_send_target_addr(struct i2c_algo_iop3xx_data *iop3xx_adap, | |||
257 | return rc; | 258 | return rc; |
258 | } | 259 | } |
259 | 260 | ||
260 | static int | 261 | static int |
261 | iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, | 262 | iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, |
262 | int stop) | 263 | int stop) |
263 | { | 264 | { |
264 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); | 265 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); |
@@ -277,10 +278,10 @@ iop3xx_i2c_write_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char byte, | |||
277 | rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); | 278 | rc = iop3xx_i2c_wait_tx_done(iop3xx_adap, &status); |
278 | 279 | ||
279 | return rc; | 280 | return rc; |
280 | } | 281 | } |
281 | 282 | ||
282 | static int | 283 | static int |
283 | iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, | 284 | iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, |
284 | int stop) | 285 | int stop) |
285 | { | 286 | { |
286 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); | 287 | unsigned long cr = __raw_readl(iop3xx_adap->ioaddr + CR_OFFSET); |
@@ -304,19 +305,19 @@ iop3xx_i2c_read_byte(struct i2c_algo_iop3xx_data *iop3xx_adap, char* byte, | |||
304 | return rc; | 305 | return rc; |
305 | } | 306 | } |
306 | 307 | ||
307 | static int | 308 | static int |
308 | iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count) | 309 | iop3xx_i2c_writebytes(struct i2c_adapter *i2c_adap, const char *buf, int count) |
309 | { | 310 | { |
310 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; | 311 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; |
311 | int ii; | 312 | int ii; |
312 | int rc = 0; | 313 | int rc = 0; |
313 | 314 | ||
314 | for (ii = 0; rc == 0 && ii != count; ++ii) | 315 | for (ii = 0; rc == 0 && ii != count; ++ii) |
315 | rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1); | 316 | rc = iop3xx_i2c_write_byte(iop3xx_adap, buf[ii], ii==count-1); |
316 | return rc; | 317 | return rc; |
317 | } | 318 | } |
318 | 319 | ||
319 | static int | 320 | static int |
320 | iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) | 321 | iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) |
321 | { | 322 | { |
322 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; | 323 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; |
@@ -325,7 +326,7 @@ iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) | |||
325 | 326 | ||
326 | for (ii = 0; rc == 0 && ii != count; ++ii) | 327 | for (ii = 0; rc == 0 && ii != count; ++ii) |
327 | rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1); | 328 | rc = iop3xx_i2c_read_byte(iop3xx_adap, &buf[ii], ii==count-1); |
328 | 329 | ||
329 | return rc; | 330 | return rc; |
330 | } | 331 | } |
331 | 332 | ||
@@ -336,8 +337,8 @@ iop3xx_i2c_readbytes(struct i2c_adapter *i2c_adap, char *buf, int count) | |||
336 | * Each transfer (i.e. a read or a write) is separated by a repeated start | 337 | * Each transfer (i.e. a read or a write) is separated by a repeated start |
337 | * condition. | 338 | * condition. |
338 | */ | 339 | */ |
339 | static int | 340 | static int |
340 | iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) | 341 | iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) |
341 | { | 342 | { |
342 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; | 343 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; |
343 | int rc; | 344 | int rc; |
@@ -357,8 +358,8 @@ iop3xx_i2c_handle_msg(struct i2c_adapter *i2c_adap, struct i2c_msg* pmsg) | |||
357 | /* | 358 | /* |
358 | * master_xfer() - main read/write entry | 359 | * master_xfer() - main read/write entry |
359 | */ | 360 | */ |
360 | static int | 361 | static int |
361 | iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, | 362 | iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, |
362 | int num) | 363 | int num) |
363 | { | 364 | { |
364 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; | 365 | struct i2c_algo_iop3xx_data *iop3xx_adap = i2c_adap->algo_data; |
@@ -375,14 +376,14 @@ iop3xx_i2c_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, | |||
375 | } | 376 | } |
376 | 377 | ||
377 | iop3xx_i2c_transaction_cleanup(iop3xx_adap); | 378 | iop3xx_i2c_transaction_cleanup(iop3xx_adap); |
378 | 379 | ||
379 | if(ret) | 380 | if(ret) |
380 | return ret; | 381 | return ret; |
381 | 382 | ||
382 | return im; | 383 | return im; |
383 | } | 384 | } |
384 | 385 | ||
385 | static u32 | 386 | static u32 |
386 | iop3xx_i2c_func(struct i2c_adapter *adap) | 387 | iop3xx_i2c_func(struct i2c_adapter *adap) |
387 | { | 388 | { |
388 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | 389 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
@@ -393,11 +394,11 @@ static const struct i2c_algorithm iop3xx_i2c_algo = { | |||
393 | .functionality = iop3xx_i2c_func, | 394 | .functionality = iop3xx_i2c_func, |
394 | }; | 395 | }; |
395 | 396 | ||
396 | static int | 397 | static int |
397 | iop3xx_i2c_remove(struct platform_device *pdev) | 398 | iop3xx_i2c_remove(struct platform_device *pdev) |
398 | { | 399 | { |
399 | struct i2c_adapter *padapter = platform_get_drvdata(pdev); | 400 | struct i2c_adapter *padapter = platform_get_drvdata(pdev); |
400 | struct i2c_algo_iop3xx_data *adapter_data = | 401 | struct i2c_algo_iop3xx_data *adapter_data = |
401 | (struct i2c_algo_iop3xx_data *)padapter->algo_data; | 402 | (struct i2c_algo_iop3xx_data *)padapter->algo_data; |
402 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 403 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
403 | unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET); | 404 | unsigned long cr = __raw_readl(adapter_data->ioaddr + CR_OFFSET); |
@@ -419,7 +420,7 @@ iop3xx_i2c_remove(struct platform_device *pdev) | |||
419 | return 0; | 420 | return 0; |
420 | } | 421 | } |
421 | 422 | ||
422 | static int | 423 | static int |
423 | iop3xx_i2c_probe(struct platform_device *pdev) | 424 | iop3xx_i2c_probe(struct platform_device *pdev) |
424 | { | 425 | { |
425 | struct resource *res; | 426 | struct resource *res; |
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 088c5c1ed17d..51f05b8520ed 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
@@ -365,10 +365,6 @@ static int mxs_i2c_get_ofdata(struct mxs_i2c_dev *i2c) | |||
365 | struct device_node *node = dev->of_node; | 365 | struct device_node *node = dev->of_node; |
366 | int ret; | 366 | int ret; |
367 | 367 | ||
368 | if (!node) | ||
369 | return -EINVAL; | ||
370 | |||
371 | i2c->speed = &mxs_i2c_95kHz_config; | ||
372 | ret = of_property_read_u32(node, "clock-frequency", &speed); | 368 | ret = of_property_read_u32(node, "clock-frequency", &speed); |
373 | if (ret) | 369 | if (ret) |
374 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); | 370 | dev_warn(dev, "No I2C speed selected, using 100kHz\n"); |
@@ -419,10 +415,13 @@ static int __devinit mxs_i2c_probe(struct platform_device *pdev) | |||
419 | return err; | 415 | return err; |
420 | 416 | ||
421 | i2c->dev = dev; | 417 | i2c->dev = dev; |
418 | i2c->speed = &mxs_i2c_95kHz_config; | ||
422 | 419 | ||
423 | err = mxs_i2c_get_ofdata(i2c); | 420 | if (dev->of_node) { |
424 | if (err) | 421 | err = mxs_i2c_get_ofdata(i2c); |
425 | return err; | 422 | if (err) |
423 | return err; | ||
424 | } | ||
426 | 425 | ||
427 | platform_set_drvdata(pdev, i2c); | 426 | platform_set_drvdata(pdev, i2c); |
428 | 427 | ||
diff --git a/drivers/i2c/busses/i2c-nuc900.c b/drivers/i2c/busses/i2c-nuc900.c index a26dfb8cd586..f41502ef3f55 100644 --- a/drivers/i2c/busses/i2c-nuc900.c +++ b/drivers/i2c/busses/i2c-nuc900.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/io.h> | 29 | #include <linux/io.h> |
30 | 30 | ||
31 | #include <mach/mfp.h> | 31 | #include <mach/mfp.h> |
32 | #include <mach/i2c.h> | 32 | #include <linux/platform_data/i2c-nuc900.h> |
33 | 33 | ||
34 | /* nuc900 i2c registers offset */ | 34 | /* nuc900 i2c registers offset */ |
35 | 35 | ||
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 5d54416770b0..8488bddfe465 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
@@ -48,8 +48,9 @@ enum { | |||
48 | mcntrl_afie = 0x00000002, | 48 | mcntrl_afie = 0x00000002, |
49 | mcntrl_naie = 0x00000004, | 49 | mcntrl_naie = 0x00000004, |
50 | mcntrl_drmie = 0x00000008, | 50 | mcntrl_drmie = 0x00000008, |
51 | mcntrl_daie = 0x00000020, | 51 | mcntrl_drsie = 0x00000010, |
52 | mcntrl_rffie = 0x00000040, | 52 | mcntrl_rffie = 0x00000020, |
53 | mcntrl_daie = 0x00000040, | ||
53 | mcntrl_tffie = 0x00000080, | 54 | mcntrl_tffie = 0x00000080, |
54 | mcntrl_reset = 0x00000100, | 55 | mcntrl_reset = 0x00000100, |
55 | mcntrl_cdbmode = 0x00000400, | 56 | mcntrl_cdbmode = 0x00000400, |
@@ -290,31 +291,37 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) | |||
290 | * or we didn't 'ask' for it yet. | 291 | * or we didn't 'ask' for it yet. |
291 | */ | 292 | */ |
292 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { | 293 | if (ioread32(I2C_REG_STS(alg_data)) & mstatus_rfe) { |
293 | dev_dbg(&alg_data->adapter.dev, | 294 | /* 'Asking' is done asynchronously, e.g. dummy TX of several |
294 | "%s(): Write dummy data to fill Rx-fifo...\n", | 295 | * bytes is done before the first actual RX arrives in FIFO. |
295 | __func__); | 296 | * Therefore, ordered bytes (via TX) are counted separately. |
297 | */ | ||
298 | if (alg_data->mif.order) { | ||
299 | dev_dbg(&alg_data->adapter.dev, | ||
300 | "%s(): Write dummy data to fill Rx-fifo...\n", | ||
301 | __func__); | ||
296 | 302 | ||
297 | if (alg_data->mif.len == 1) { | 303 | if (alg_data->mif.order == 1) { |
298 | /* Last byte, do not acknowledge next rcv. */ | 304 | /* Last byte, do not acknowledge next rcv. */ |
299 | val |= stop_bit; | 305 | val |= stop_bit; |
306 | |||
307 | /* | ||
308 | * Enable interrupt RFDAIE (data in Rx fifo), | ||
309 | * and disable DRMIE (need data for Tx) | ||
310 | */ | ||
311 | ctl = ioread32(I2C_REG_CTL(alg_data)); | ||
312 | ctl |= mcntrl_rffie | mcntrl_daie; | ||
313 | ctl &= ~mcntrl_drmie; | ||
314 | iowrite32(ctl, I2C_REG_CTL(alg_data)); | ||
315 | } | ||
300 | 316 | ||
301 | /* | 317 | /* |
302 | * Enable interrupt RFDAIE (data in Rx fifo), | 318 | * Now we'll 'ask' for data: |
303 | * and disable DRMIE (need data for Tx) | 319 | * For each byte we want to receive, we must |
320 | * write a (dummy) byte to the Tx-FIFO. | ||
304 | */ | 321 | */ |
305 | ctl = ioread32(I2C_REG_CTL(alg_data)); | 322 | iowrite32(val, I2C_REG_TX(alg_data)); |
306 | ctl |= mcntrl_rffie | mcntrl_daie; | 323 | alg_data->mif.order--; |
307 | ctl &= ~mcntrl_drmie; | ||
308 | iowrite32(ctl, I2C_REG_CTL(alg_data)); | ||
309 | } | 324 | } |
310 | |||
311 | /* | ||
312 | * Now we'll 'ask' for data: | ||
313 | * For each byte we want to receive, we must | ||
314 | * write a (dummy) byte to the Tx-FIFO. | ||
315 | */ | ||
316 | iowrite32(val, I2C_REG_TX(alg_data)); | ||
317 | |||
318 | return 0; | 325 | return 0; |
319 | } | 326 | } |
320 | 327 | ||
@@ -514,6 +521,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
514 | 521 | ||
515 | alg_data->mif.buf = pmsg->buf; | 522 | alg_data->mif.buf = pmsg->buf; |
516 | alg_data->mif.len = pmsg->len; | 523 | alg_data->mif.len = pmsg->len; |
524 | alg_data->mif.order = pmsg->len; | ||
517 | alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? | 525 | alg_data->mif.mode = (pmsg->flags & I2C_M_RD) ? |
518 | I2C_SMBUS_READ : I2C_SMBUS_WRITE; | 526 | I2C_SMBUS_READ : I2C_SMBUS_WRITE; |
519 | alg_data->mif.ret = 0; | 527 | alg_data->mif.ret = 0; |
@@ -566,6 +574,7 @@ i2c_pnx_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num) | |||
566 | /* Cleanup to be sure... */ | 574 | /* Cleanup to be sure... */ |
567 | alg_data->mif.buf = NULL; | 575 | alg_data->mif.buf = NULL; |
568 | alg_data->mif.len = 0; | 576 | alg_data->mif.len = 0; |
577 | alg_data->mif.order = 0; | ||
569 | 578 | ||
570 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", | 579 | dev_dbg(&alg_data->adapter.dev, "%s(): exiting, stat = %x\n", |
571 | __func__, ioread32(I2C_REG_STS(alg_data))); | 580 | __func__, ioread32(I2C_REG_STS(alg_data))); |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 5ae3b0236bd3..4d07dea9bca9 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <asm/irq.h> | 42 | #include <asm/irq.h> |
43 | 43 | ||
44 | #include <plat/regs-iic.h> | 44 | #include <plat/regs-iic.h> |
45 | #include <plat/iic.h> | 45 | #include <linux/platform_data/i2c-s3c2410.h> |
46 | 46 | ||
47 | /* Treat S3C2410 as baseline hardware, anything else is supported via quirks */ | 47 | /* Treat S3C2410 as baseline hardware, anything else is supported via quirks */ |
48 | #define QUIRK_S3C2440 (1 << 0) | 48 | #define QUIRK_S3C2440 (1 << 0) |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 2efa56c5ff2c..2091ae8f539a 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -637,6 +637,22 @@ static void i2c_adapter_dev_release(struct device *dev) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | /* | 639 | /* |
640 | * This function is only needed for mutex_lock_nested, so it is never | ||
641 | * called unless locking correctness checking is enabled. Thus we | ||
642 | * make it inline to avoid a compiler warning. That's what gcc ends up | ||
643 | * doing anyway. | ||
644 | */ | ||
645 | static inline unsigned int i2c_adapter_depth(struct i2c_adapter *adapter) | ||
646 | { | ||
647 | unsigned int depth = 0; | ||
648 | |||
649 | while ((adapter = i2c_parent_is_i2c_adapter(adapter))) | ||
650 | depth++; | ||
651 | |||
652 | return depth; | ||
653 | } | ||
654 | |||
655 | /* | ||
640 | * Let users instantiate I2C devices through sysfs. This can be used when | 656 | * Let users instantiate I2C devices through sysfs. This can be used when |
641 | * platform initialization code doesn't contain the proper data for | 657 | * platform initialization code doesn't contain the proper data for |
642 | * whatever reason. Also useful for drivers that do device detection and | 658 | * whatever reason. Also useful for drivers that do device detection and |
@@ -726,7 +742,8 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr, | |||
726 | 742 | ||
727 | /* Make sure the device was added through sysfs */ | 743 | /* Make sure the device was added through sysfs */ |
728 | res = -ENOENT; | 744 | res = -ENOENT; |
729 | mutex_lock(&adap->userspace_clients_lock); | 745 | mutex_lock_nested(&adap->userspace_clients_lock, |
746 | i2c_adapter_depth(adap)); | ||
730 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 747 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
731 | detected) { | 748 | detected) { |
732 | if (client->addr == addr) { | 749 | if (client->addr == addr) { |
@@ -1073,7 +1090,8 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
1073 | return res; | 1090 | return res; |
1074 | 1091 | ||
1075 | /* Remove devices instantiated from sysfs */ | 1092 | /* Remove devices instantiated from sysfs */ |
1076 | mutex_lock(&adap->userspace_clients_lock); | 1093 | mutex_lock_nested(&adap->userspace_clients_lock, |
1094 | i2c_adapter_depth(adap)); | ||
1077 | list_for_each_entry_safe(client, next, &adap->userspace_clients, | 1095 | list_for_each_entry_safe(client, next, &adap->userspace_clients, |
1078 | detected) { | 1096 | detected) { |
1079 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, | 1097 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name, |
diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index f61780a02374..3bd5540238a7 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c | |||
@@ -617,7 +617,7 @@ static int __devinit at91_adc_probe(struct platform_device *pdev) | |||
617 | st->adc_clk = clk_get(&pdev->dev, "adc_op_clk"); | 617 | st->adc_clk = clk_get(&pdev->dev, "adc_op_clk"); |
618 | if (IS_ERR(st->adc_clk)) { | 618 | if (IS_ERR(st->adc_clk)) { |
619 | dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); | 619 | dev_err(&pdev->dev, "Failed to get the ADC clock.\n"); |
620 | ret = PTR_ERR(st->clk); | 620 | ret = PTR_ERR(st->adc_clk); |
621 | goto error_disable_clk; | 621 | goto error_disable_clk; |
622 | } | 622 | } |
623 | 623 | ||
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index c50fa75416f8..b4b65af8612a 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -533,7 +533,7 @@ config KEYBOARD_DAVINCI | |||
533 | 533 | ||
534 | config KEYBOARD_OMAP | 534 | config KEYBOARD_OMAP |
535 | tristate "TI OMAP keypad support" | 535 | tristate "TI OMAP keypad support" |
536 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 536 | depends on ARCH_OMAP1 |
537 | select INPUT_MATRIXKMAP | 537 | select INPUT_MATRIXKMAP |
538 | help | 538 | help |
539 | Say Y here if you want to use the OMAP keypad. | 539 | Say Y here if you want to use the OMAP keypad. |
diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index 9d82b3aeff5e..d5bacbb479b0 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c | |||
@@ -36,7 +36,7 @@ | |||
36 | 36 | ||
37 | #include <mach/hardware.h> | 37 | #include <mach/hardware.h> |
38 | #include <mach/irqs.h> | 38 | #include <mach/irqs.h> |
39 | #include <mach/keyscan.h> | 39 | #include <linux/platform_data/keyscan-davinci.h> |
40 | 40 | ||
41 | /* Key scan registers */ | 41 | /* Key scan registers */ |
42 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 | 42 | #define DAVINCI_KEYSCAN_KEYCTRL 0x0000 |
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c index c46fc8185469..7363402de8d4 100644 --- a/drivers/input/keyboard/ep93xx_keypad.c +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | 30 | ||
31 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
32 | #include <mach/ep93xx_keypad.h> | 32 | #include <linux/platform_data/keypad-ep93xx.h> |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Keypad Interface Register offsets | 35 | * Keypad Interface Register offsets |
diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index a880e7414202..49f5fa64e0b1 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | 22 | ||
23 | #include <plat/ske.h> | 23 | #include <linux/platform_data/keypad-nomadik-ske.h> |
24 | 24 | ||
25 | /* SKE_CR bits */ | 25 | /* SKE_CR bits */ |
26 | #define SKE_KPMLT (0x1 << 6) | 26 | #define SKE_KPMLT (0x1 << 6) |
diff --git a/drivers/input/keyboard/omap-keypad.c b/drivers/input/keyboard/omap-keypad.c index a0222db4dc86..6d6b1427ae12 100644 --- a/drivers/input/keyboard/omap-keypad.c +++ b/drivers/input/keyboard/omap-keypad.c | |||
@@ -35,13 +35,9 @@ | |||
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <asm/gpio.h> | 38 | #include <linux/gpio.h> |
39 | #include <plat/keypad.h> | 39 | #include <linux/platform_data/gpio-omap.h> |
40 | #include <plat/menelaus.h> | 40 | #include <linux/platform_data/keypad-omap.h> |
41 | #include <asm/irq.h> | ||
42 | #include <mach/hardware.h> | ||
43 | #include <asm/io.h> | ||
44 | #include <plat/mux.h> | ||
45 | 41 | ||
46 | #undef NEW_BOARD_LEARNING_MODE | 42 | #undef NEW_BOARD_LEARNING_MODE |
47 | 43 | ||
@@ -96,28 +92,8 @@ static u8 get_row_gpio_val(struct omap_kp *omap_kp) | |||
96 | 92 | ||
97 | static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) | 93 | static irqreturn_t omap_kp_interrupt(int irq, void *dev_id) |
98 | { | 94 | { |
99 | struct omap_kp *omap_kp = dev_id; | ||
100 | |||
101 | /* disable keyboard interrupt and schedule for handling */ | 95 | /* disable keyboard interrupt and schedule for handling */ |
102 | if (cpu_is_omap24xx()) { | 96 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
103 | int i; | ||
104 | |||
105 | for (i = 0; i < omap_kp->rows; i++) { | ||
106 | int gpio_irq = gpio_to_irq(row_gpios[i]); | ||
107 | /* | ||
108 | * The interrupt which we're currently handling should | ||
109 | * be disabled _nosync() to avoid deadlocks waiting | ||
110 | * for this handler to complete. All others should | ||
111 | * be disabled the regular way for SMP safety. | ||
112 | */ | ||
113 | if (gpio_irq == irq) | ||
114 | disable_irq_nosync(gpio_irq); | ||
115 | else | ||
116 | disable_irq(gpio_irq); | ||
117 | } | ||
118 | } else | ||
119 | /* disable keyboard interrupt and schedule for handling */ | ||
120 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
121 | 97 | ||
122 | tasklet_schedule(&kp_tasklet); | 98 | tasklet_schedule(&kp_tasklet); |
123 | 99 | ||
@@ -133,33 +109,22 @@ static void omap_kp_scan_keypad(struct omap_kp *omap_kp, unsigned char *state) | |||
133 | { | 109 | { |
134 | int col = 0; | 110 | int col = 0; |
135 | 111 | ||
136 | /* read the keypad status */ | 112 | /* disable keyboard interrupt and schedule for handling */ |
137 | if (cpu_is_omap24xx()) { | 113 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
138 | /* read the keypad status */ | ||
139 | for (col = 0; col < omap_kp->cols; col++) { | ||
140 | set_col_gpio_val(omap_kp, ~(1 << col)); | ||
141 | state[col] = ~(get_row_gpio_val(omap_kp)) & 0xff; | ||
142 | } | ||
143 | set_col_gpio_val(omap_kp, 0); | ||
144 | |||
145 | } else { | ||
146 | /* disable keyboard interrupt and schedule for handling */ | ||
147 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
148 | 114 | ||
149 | /* read the keypad status */ | 115 | /* read the keypad status */ |
150 | omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | 116 | omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); |
151 | for (col = 0; col < omap_kp->cols; col++) { | 117 | for (col = 0; col < omap_kp->cols; col++) { |
152 | omap_writew(~(1 << col) & 0xff, | 118 | omap_writew(~(1 << col) & 0xff, |
153 | OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | 119 | OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); |
154 | 120 | ||
155 | udelay(omap_kp->delay); | 121 | udelay(omap_kp->delay); |
156 | 122 | ||
157 | state[col] = ~omap_readw(OMAP1_MPUIO_BASE + | 123 | state[col] = ~omap_readw(OMAP1_MPUIO_BASE + |
158 | OMAP_MPUIO_KBR_LATCH) & 0xff; | 124 | OMAP_MPUIO_KBR_LATCH) & 0xff; |
159 | } | ||
160 | omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
161 | udelay(2); | ||
162 | } | 125 | } |
126 | omap_writew(0x00, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBC); | ||
127 | udelay(2); | ||
163 | } | 128 | } |
164 | 129 | ||
165 | static void omap_kp_tasklet(unsigned long data) | 130 | static void omap_kp_tasklet(unsigned long data) |
@@ -222,14 +187,8 @@ static void omap_kp_tasklet(unsigned long data) | |||
222 | mod_timer(&omap_kp_data->timer, jiffies + delay); | 187 | mod_timer(&omap_kp_data->timer, jiffies + delay); |
223 | } else { | 188 | } else { |
224 | /* enable interrupts */ | 189 | /* enable interrupts */ |
225 | if (cpu_is_omap24xx()) { | 190 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
226 | int i; | 191 | kp_cur_group = -1; |
227 | for (i = 0; i < omap_kp_data->rows; i++) | ||
228 | enable_irq(gpio_to_irq(row_gpios[i])); | ||
229 | } else { | ||
230 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
231 | kp_cur_group = -1; | ||
232 | } | ||
233 | } | 192 | } |
234 | } | 193 | } |
235 | 194 | ||
@@ -242,6 +201,7 @@ static ssize_t omap_kp_enable_show(struct device *dev, | |||
242 | static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr, | 201 | static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute *attr, |
243 | const char *buf, size_t count) | 202 | const char *buf, size_t count) |
244 | { | 203 | { |
204 | struct omap_kp *omap_kp = dev_get_drvdata(dev); | ||
245 | int state; | 205 | int state; |
246 | 206 | ||
247 | if (sscanf(buf, "%u", &state) != 1) | 207 | if (sscanf(buf, "%u", &state) != 1) |
@@ -253,9 +213,9 @@ static ssize_t omap_kp_enable_store(struct device *dev, struct device_attribute | |||
253 | mutex_lock(&kp_enable_mutex); | 213 | mutex_lock(&kp_enable_mutex); |
254 | if (state != kp_enable) { | 214 | if (state != kp_enable) { |
255 | if (state) | 215 | if (state) |
256 | enable_irq(INT_KEYBOARD); | 216 | enable_irq(omap_kp->irq); |
257 | else | 217 | else |
258 | disable_irq(INT_KEYBOARD); | 218 | disable_irq(omap_kp->irq); |
259 | kp_enable = state; | 219 | kp_enable = state; |
260 | } | 220 | } |
261 | mutex_unlock(&kp_enable_mutex); | 221 | mutex_unlock(&kp_enable_mutex); |
@@ -289,7 +249,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
289 | struct omap_kp *omap_kp; | 249 | struct omap_kp *omap_kp; |
290 | struct input_dev *input_dev; | 250 | struct input_dev *input_dev; |
291 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; | 251 | struct omap_kp_platform_data *pdata = pdev->dev.platform_data; |
292 | int i, col_idx, row_idx, irq_idx, ret; | 252 | int i, col_idx, row_idx, ret; |
293 | unsigned int row_shift, keycodemax; | 253 | unsigned int row_shift, keycodemax; |
294 | 254 | ||
295 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { | 255 | if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { |
@@ -314,8 +274,7 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
314 | omap_kp->input = input_dev; | 274 | omap_kp->input = input_dev; |
315 | 275 | ||
316 | /* Disable the interrupt for the MPUIO keyboard */ | 276 | /* Disable the interrupt for the MPUIO keyboard */ |
317 | if (!cpu_is_omap24xx()) | 277 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
318 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
319 | 278 | ||
320 | if (pdata->delay) | 279 | if (pdata->delay) |
321 | omap_kp->delay = pdata->delay; | 280 | omap_kp->delay = pdata->delay; |
@@ -328,31 +287,8 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
328 | omap_kp->rows = pdata->rows; | 287 | omap_kp->rows = pdata->rows; |
329 | omap_kp->cols = pdata->cols; | 288 | omap_kp->cols = pdata->cols; |
330 | 289 | ||
331 | if (cpu_is_omap24xx()) { | 290 | col_idx = 0; |
332 | /* Cols: outputs */ | 291 | row_idx = 0; |
333 | for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) { | ||
334 | if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) { | ||
335 | printk(KERN_ERR "Failed to request" | ||
336 | "GPIO%d for keypad\n", | ||
337 | col_gpios[col_idx]); | ||
338 | goto err1; | ||
339 | } | ||
340 | gpio_direction_output(col_gpios[col_idx], 0); | ||
341 | } | ||
342 | /* Rows: inputs */ | ||
343 | for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) { | ||
344 | if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) { | ||
345 | printk(KERN_ERR "Failed to request" | ||
346 | "GPIO%d for keypad\n", | ||
347 | row_gpios[row_idx]); | ||
348 | goto err2; | ||
349 | } | ||
350 | gpio_direction_input(row_gpios[row_idx]); | ||
351 | } | ||
352 | } else { | ||
353 | col_idx = 0; | ||
354 | row_idx = 0; | ||
355 | } | ||
356 | 292 | ||
357 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); | 293 | setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); |
358 | 294 | ||
@@ -394,27 +330,16 @@ static int __devinit omap_kp_probe(struct platform_device *pdev) | |||
394 | 330 | ||
395 | /* scan current status and enable interrupt */ | 331 | /* scan current status and enable interrupt */ |
396 | omap_kp_scan_keypad(omap_kp, keypad_state); | 332 | omap_kp_scan_keypad(omap_kp, keypad_state); |
397 | if (!cpu_is_omap24xx()) { | 333 | omap_kp->irq = platform_get_irq(pdev, 0); |
398 | omap_kp->irq = platform_get_irq(pdev, 0); | 334 | if (omap_kp->irq >= 0) { |
399 | if (omap_kp->irq >= 0) { | 335 | if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, |
400 | if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, | 336 | "omap-keypad", omap_kp) < 0) |
401 | "omap-keypad", omap_kp) < 0) | 337 | goto err4; |
402 | goto err4; | ||
403 | } | ||
404 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
405 | } else { | ||
406 | for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) { | ||
407 | if (request_irq(gpio_to_irq(row_gpios[irq_idx]), | ||
408 | omap_kp_interrupt, | ||
409 | IRQF_TRIGGER_FALLING, | ||
410 | "omap-keypad", omap_kp) < 0) | ||
411 | goto err5; | ||
412 | } | ||
413 | } | 338 | } |
339 | omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
340 | |||
414 | return 0; | 341 | return 0; |
415 | err5: | 342 | |
416 | for (i = irq_idx - 1; i >=0; i--) | ||
417 | free_irq(row_gpios[i], omap_kp); | ||
418 | err4: | 343 | err4: |
419 | input_unregister_device(omap_kp->input); | 344 | input_unregister_device(omap_kp->input); |
420 | input_dev = NULL; | 345 | input_dev = NULL; |
@@ -423,7 +348,6 @@ err3: | |||
423 | err2: | 348 | err2: |
424 | for (i = row_idx - 1; i >=0; i--) | 349 | for (i = row_idx - 1; i >=0; i--) |
425 | gpio_free(row_gpios[i]); | 350 | gpio_free(row_gpios[i]); |
426 | err1: | ||
427 | for (i = col_idx - 1; i >=0; i--) | 351 | for (i = col_idx - 1; i >=0; i--) |
428 | gpio_free(col_gpios[i]); | 352 | gpio_free(col_gpios[i]); |
429 | 353 | ||
@@ -439,18 +363,8 @@ static int __devexit omap_kp_remove(struct platform_device *pdev) | |||
439 | 363 | ||
440 | /* disable keypad interrupt handling */ | 364 | /* disable keypad interrupt handling */ |
441 | tasklet_disable(&kp_tasklet); | 365 | tasklet_disable(&kp_tasklet); |
442 | if (cpu_is_omap24xx()) { | 366 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); |
443 | int i; | 367 | free_irq(omap_kp->irq, omap_kp); |
444 | for (i = 0; i < omap_kp->cols; i++) | ||
445 | gpio_free(col_gpios[i]); | ||
446 | for (i = 0; i < omap_kp->rows; i++) { | ||
447 | gpio_free(row_gpios[i]); | ||
448 | free_irq(gpio_to_irq(row_gpios[i]), omap_kp); | ||
449 | } | ||
450 | } else { | ||
451 | omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); | ||
452 | free_irq(omap_kp->irq, omap_kp); | ||
453 | } | ||
454 | 368 | ||
455 | del_timer_sync(&omap_kp->timer); | 369 | del_timer_sync(&omap_kp->timer); |
456 | tasklet_kill(&kp_tasklet); | 370 | tasklet_kill(&kp_tasklet); |
diff --git a/drivers/input/keyboard/pxa27x_keypad.c b/drivers/input/keyboard/pxa27x_keypad.c index 7f7b72464a37..803ff6fe021e 100644 --- a/drivers/input/keyboard/pxa27x_keypad.c +++ b/drivers/input/keyboard/pxa27x_keypad.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <asm/mach/map.h> | 32 | #include <asm/mach/map.h> |
33 | 33 | ||
34 | #include <mach/hardware.h> | 34 | #include <mach/hardware.h> |
35 | #include <plat/pxa27x_keypad.h> | 35 | #include <linux/platform_data/keypad-pxa27x.h> |
36 | /* | 36 | /* |
37 | * Keypad Controller registers | 37 | * Keypad Controller registers |
38 | */ | 38 | */ |
diff --git a/drivers/input/keyboard/pxa930_rotary.c b/drivers/input/keyboard/pxa930_rotary.c index d7f1134b789e..41488f9add20 100644 --- a/drivers/input/keyboard/pxa930_rotary.c +++ b/drivers/input/keyboard/pxa930_rotary.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | 17 | ||
18 | #include <mach/pxa930_rotary.h> | 18 | #include <linux/platform_data/keyboard-pxa930_rotary.h> |
19 | 19 | ||
20 | #define SBCR (0x04) | 20 | #define SBCR (0x04) |
21 | #define ERCR (0x0c) | 21 | #define ERCR (0x0c) |
diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 72ef01be3360..c7ca97f44bfb 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/pm_wakeup.h> | 24 | #include <linux/pm_wakeup.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <plat/keyboard.h> | 27 | #include <linux/platform_data/keyboard-spear.h> |
28 | 28 | ||
29 | /* Keyboard Registers */ | 29 | /* Keyboard Registers */ |
30 | #define MODE_CTL_REG 0x00 | 30 | #define MODE_CTL_REG 0x00 |
diff --git a/drivers/input/keyboard/w90p910_keypad.c b/drivers/input/keyboard/w90p910_keypad.c index 085ede4d972d..e0f6cd1ad0fd 100644 --- a/drivers/input/keyboard/w90p910_keypad.c +++ b/drivers/input/keyboard/w90p910_keypad.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | 23 | ||
24 | #include <mach/w90p910_keypad.h> | 24 | #include <linux/platform_data/keypad-w90p910.h> |
25 | 25 | ||
26 | /* Keypad Interface Control Registers */ | 26 | /* Keypad Interface Control Registers */ |
27 | #define KPI_CONF 0x00 | 27 | #define KPI_CONF 0x00 |
diff --git a/drivers/input/mouse/pxa930_trkball.c b/drivers/input/mouse/pxa930_trkball.c index a9e4bfdf31f4..4fe055f2c536 100644 --- a/drivers/input/mouse/pxa930_trkball.c +++ b/drivers/input/mouse/pxa930_trkball.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
21 | 21 | ||
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <mach/pxa930_trkball.h> | 23 | #include <linux/platform_data/mouse-pxa930_trkball.h> |
24 | 24 | ||
25 | /* Trackball Controller Register Definitions */ | 25 | /* Trackball Controller Register Definitions */ |
26 | #define TBCR (0x000C) | 26 | #define TBCR (0x000C) |
diff --git a/drivers/input/mouse/rpcmouse.c b/drivers/input/mouse/rpcmouse.c index 272deddc8db6..21c60fea5d31 100644 --- a/drivers/input/mouse/rpcmouse.c +++ b/drivers/input/mouse/rpcmouse.c | |||
@@ -42,7 +42,7 @@ static irqreturn_t rpcmouse_irq(int irq, void *dev_id) | |||
42 | 42 | ||
43 | x = (short) iomd_readl(IOMD_MOUSEX); | 43 | x = (short) iomd_readl(IOMD_MOUSEX); |
44 | y = (short) iomd_readl(IOMD_MOUSEY); | 44 | y = (short) iomd_readl(IOMD_MOUSEY); |
45 | b = (short) (__raw_readl(0xe0310000) ^ 0x70); | 45 | b = (short) (__raw_readl(IOMEM(0xe0310000)) ^ 0x70); |
46 | 46 | ||
47 | dx = x - rpcmouse_lastx; | 47 | dx = x - rpcmouse_lastx; |
48 | dy = y - rpcmouse_lasty; | 48 | dy = y - rpcmouse_lasty; |
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index f5fbdf94de3b..45887e31242a 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | 28 | ||
29 | #include <asm/mach-types.h> | 29 | #include <asm/mach-types.h> |
30 | #include <plat/board-ams-delta.h> | 30 | #include <mach/board-ams-delta.h> |
31 | 31 | ||
32 | #include <mach/ams-delta-fiq.h> | 32 | #include <mach/ams-delta-fiq.h> |
33 | 33 | ||
diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index bf1a06400067..df9e816d55e4 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | #include <plat/adc.h> | 38 | #include <plat/adc.h> |
39 | #include <plat/regs-adc.h> | 39 | #include <plat/regs-adc.h> |
40 | #include <plat/ts.h> | 40 | #include <linux/platform_data/touchscreen-s3c2410.h> |
41 | 41 | ||
42 | #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) | 42 | #define TSC_SLEEP (S3C2410_ADCTSC_PULL_UP_DISABLE | S3C2410_ADCTSC_XY_PST(0)) |
43 | 43 | ||
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/drivers/irqchip/Kconfig | |||
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile new file mode 100644 index 000000000000..054321db4350 --- /dev/null +++ b/drivers/irqchip/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-$(CONFIG_ARCH_BCM2835) += irq-bcm2835.o | |||
diff --git a/drivers/irqchip/irq-bcm2835.c b/drivers/irqchip/irq-bcm2835.c new file mode 100644 index 000000000000..dc670ccc6978 --- /dev/null +++ b/drivers/irqchip/irq-bcm2835.c | |||
@@ -0,0 +1,223 @@ | |||
1 | /* | ||
2 | * Copyright 2010 Broadcom | ||
3 | * Copyright 2012 Simon Arlott, Chris Boot, Stephen Warren | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | * GNU General Public License for more details. | ||
14 | * | ||
15 | * Quirk 1: Shortcut interrupts don't set the bank 1/2 register pending bits | ||
16 | * | ||
17 | * If an interrupt fires on bank 1 that isn't in the shortcuts list, bit 8 | ||
18 | * on bank 0 is set to signify that an interrupt in bank 1 has fired, and | ||
19 | * to look in the bank 1 status register for more information. | ||
20 | * | ||
21 | * If an interrupt fires on bank 1 that _is_ in the shortcuts list, its | ||
22 | * shortcut bit in bank 0 is set as well as its interrupt bit in the bank 1 | ||
23 | * status register, but bank 0 bit 8 is _not_ set. | ||
24 | * | ||
25 | * Quirk 2: You can't mask the register 1/2 pending interrupts | ||
26 | * | ||
27 | * In a proper cascaded interrupt controller, the interrupt lines with | ||
28 | * cascaded interrupt controllers on them are just normal interrupt lines. | ||
29 | * You can mask the interrupts and get on with things. With this controller | ||
30 | * you can't do that. | ||
31 | * | ||
32 | * Quirk 3: The shortcut interrupts can't be (un)masked in bank 0 | ||
33 | * | ||
34 | * Those interrupts that have shortcuts can only be masked/unmasked in | ||
35 | * their respective banks' enable/disable registers. Doing so in the bank 0 | ||
36 | * enable/disable registers has no effect. | ||
37 | * | ||
38 | * The FIQ control register: | ||
39 | * Bits 0-6: IRQ (index in order of interrupts from banks 1, 2, then 0) | ||
40 | * Bit 7: Enable FIQ generation | ||
41 | * Bits 8+: Unused | ||
42 | * | ||
43 | * An interrupt must be disabled before configuring it for FIQ generation | ||
44 | * otherwise both handlers will fire at the same time! | ||
45 | */ | ||
46 | |||
47 | #include <linux/io.h> | ||
48 | #include <linux/slab.h> | ||
49 | #include <linux/of_address.h> | ||
50 | #include <linux/of_irq.h> | ||
51 | #include <linux/irqdomain.h> | ||
52 | #include <linux/irqchip/bcm2835.h> | ||
53 | |||
54 | #include <asm/exception.h> | ||
55 | |||
56 | /* Put the bank and irq (32 bits) into the hwirq */ | ||
57 | #define MAKE_HWIRQ(b, n) ((b << 5) | (n)) | ||
58 | #define HWIRQ_BANK(i) (i >> 5) | ||
59 | #define HWIRQ_BIT(i) BIT(i & 0x1f) | ||
60 | |||
61 | #define NR_IRQS_BANK0 8 | ||
62 | #define BANK0_HWIRQ_MASK 0xff | ||
63 | /* Shortcuts can't be disabled so any unknown new ones need to be masked */ | ||
64 | #define SHORTCUT1_MASK 0x00007c00 | ||
65 | #define SHORTCUT2_MASK 0x001f8000 | ||
66 | #define SHORTCUT_SHIFT 10 | ||
67 | #define BANK1_HWIRQ BIT(8) | ||
68 | #define BANK2_HWIRQ BIT(9) | ||
69 | #define BANK0_VALID_MASK (BANK0_HWIRQ_MASK | BANK1_HWIRQ | BANK2_HWIRQ \ | ||
70 | | SHORTCUT1_MASK | SHORTCUT2_MASK) | ||
71 | |||
72 | #define REG_FIQ_CONTROL 0x0c | ||
73 | |||
74 | #define NR_BANKS 3 | ||
75 | #define IRQS_PER_BANK 32 | ||
76 | |||
77 | static int reg_pending[] __initconst = { 0x00, 0x04, 0x08 }; | ||
78 | static int reg_enable[] __initconst = { 0x18, 0x10, 0x14 }; | ||
79 | static int reg_disable[] __initconst = { 0x24, 0x1c, 0x20 }; | ||
80 | static int bank_irqs[] __initconst = { 8, 32, 32 }; | ||
81 | |||
82 | static const int shortcuts[] = { | ||
83 | 7, 9, 10, 18, 19, /* Bank 1 */ | ||
84 | 21, 22, 23, 24, 25, 30 /* Bank 2 */ | ||
85 | }; | ||
86 | |||
87 | struct armctrl_ic { | ||
88 | void __iomem *base; | ||
89 | void __iomem *pending[NR_BANKS]; | ||
90 | void __iomem *enable[NR_BANKS]; | ||
91 | void __iomem *disable[NR_BANKS]; | ||
92 | struct irq_domain *domain; | ||
93 | }; | ||
94 | |||
95 | static struct armctrl_ic intc __read_mostly; | ||
96 | |||
97 | static void armctrl_mask_irq(struct irq_data *d) | ||
98 | { | ||
99 | writel_relaxed(HWIRQ_BIT(d->hwirq), intc.disable[HWIRQ_BANK(d->hwirq)]); | ||
100 | } | ||
101 | |||
102 | static void armctrl_unmask_irq(struct irq_data *d) | ||
103 | { | ||
104 | writel_relaxed(HWIRQ_BIT(d->hwirq), intc.enable[HWIRQ_BANK(d->hwirq)]); | ||
105 | } | ||
106 | |||
107 | static struct irq_chip armctrl_chip = { | ||
108 | .name = "ARMCTRL-level", | ||
109 | .irq_mask = armctrl_mask_irq, | ||
110 | .irq_unmask = armctrl_unmask_irq | ||
111 | }; | ||
112 | |||
113 | static int armctrl_xlate(struct irq_domain *d, struct device_node *ctrlr, | ||
114 | const u32 *intspec, unsigned int intsize, | ||
115 | unsigned long *out_hwirq, unsigned int *out_type) | ||
116 | { | ||
117 | if (WARN_ON(intsize != 2)) | ||
118 | return -EINVAL; | ||
119 | |||
120 | if (WARN_ON(intspec[0] >= NR_BANKS)) | ||
121 | return -EINVAL; | ||
122 | |||
123 | if (WARN_ON(intspec[1] >= IRQS_PER_BANK)) | ||
124 | return -EINVAL; | ||
125 | |||
126 | if (WARN_ON(intspec[0] == 0 && intspec[1] >= NR_IRQS_BANK0)) | ||
127 | return -EINVAL; | ||
128 | |||
129 | *out_hwirq = MAKE_HWIRQ(intspec[0], intspec[1]); | ||
130 | *out_type = IRQ_TYPE_NONE; | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static struct irq_domain_ops armctrl_ops = { | ||
135 | .xlate = armctrl_xlate | ||
136 | }; | ||
137 | |||
138 | static int __init armctrl_of_init(struct device_node *node, | ||
139 | struct device_node *parent) | ||
140 | { | ||
141 | void __iomem *base; | ||
142 | int irq, b, i; | ||
143 | |||
144 | base = of_iomap(node, 0); | ||
145 | if (!base) | ||
146 | panic("%s: unable to map IC registers\n", | ||
147 | node->full_name); | ||
148 | |||
149 | intc.domain = irq_domain_add_linear(node, MAKE_HWIRQ(NR_BANKS, 0), | ||
150 | &armctrl_ops, NULL); | ||
151 | if (!intc.domain) | ||
152 | panic("%s: unable to create IRQ domain\n", node->full_name); | ||
153 | |||
154 | for (b = 0; b < NR_BANKS; b++) { | ||
155 | intc.pending[b] = base + reg_pending[b]; | ||
156 | intc.enable[b] = base + reg_enable[b]; | ||
157 | intc.disable[b] = base + reg_disable[b]; | ||
158 | |||
159 | for (i = 0; i < bank_irqs[b]; i++) { | ||
160 | irq = irq_create_mapping(intc.domain, MAKE_HWIRQ(b, i)); | ||
161 | BUG_ON(irq <= 0); | ||
162 | irq_set_chip_and_handler(irq, &armctrl_chip, | ||
163 | handle_level_irq); | ||
164 | set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); | ||
165 | } | ||
166 | } | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static struct of_device_id irq_of_match[] __initconst = { | ||
171 | { .compatible = "brcm,bcm2835-armctrl-ic", .data = armctrl_of_init } | ||
172 | }; | ||
173 | |||
174 | void __init bcm2835_init_irq(void) | ||
175 | { | ||
176 | of_irq_init(irq_of_match); | ||
177 | } | ||
178 | |||
179 | /* | ||
180 | * Handle each interrupt across the entire interrupt controller. This reads the | ||
181 | * status register before handling each interrupt, which is necessary given that | ||
182 | * handle_IRQ may briefly re-enable interrupts for soft IRQ handling. | ||
183 | */ | ||
184 | |||
185 | static void armctrl_handle_bank(int bank, struct pt_regs *regs) | ||
186 | { | ||
187 | u32 stat, irq; | ||
188 | |||
189 | while ((stat = readl_relaxed(intc.pending[bank]))) { | ||
190 | irq = MAKE_HWIRQ(bank, ffs(stat) - 1); | ||
191 | handle_IRQ(irq_linear_revmap(intc.domain, irq), regs); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static void armctrl_handle_shortcut(int bank, struct pt_regs *regs, | ||
196 | u32 stat) | ||
197 | { | ||
198 | u32 irq = MAKE_HWIRQ(bank, shortcuts[ffs(stat >> SHORTCUT_SHIFT) - 1]); | ||
199 | handle_IRQ(irq_linear_revmap(intc.domain, irq), regs); | ||
200 | } | ||
201 | |||
202 | asmlinkage void __exception_irq_entry bcm2835_handle_irq( | ||
203 | struct pt_regs *regs) | ||
204 | { | ||
205 | u32 stat, irq; | ||
206 | |||
207 | while ((stat = readl_relaxed(intc.pending[0]) & BANK0_VALID_MASK)) { | ||
208 | if (stat & BANK0_HWIRQ_MASK) { | ||
209 | irq = MAKE_HWIRQ(0, ffs(stat & BANK0_HWIRQ_MASK) - 1); | ||
210 | handle_IRQ(irq_linear_revmap(intc.domain, irq), regs); | ||
211 | } else if (stat & SHORTCUT1_MASK) { | ||
212 | armctrl_handle_shortcut(1, regs, stat & SHORTCUT1_MASK); | ||
213 | } else if (stat & SHORTCUT2_MASK) { | ||
214 | armctrl_handle_shortcut(2, regs, stat & SHORTCUT2_MASK); | ||
215 | } else if (stat & BANK1_HWIRQ) { | ||
216 | armctrl_handle_bank(1, regs); | ||
217 | } else if (stat & BANK2_HWIRQ) { | ||
218 | armctrl_handle_bank(2, regs); | ||
219 | } else { | ||
220 | BUG(); | ||
221 | } | ||
222 | } | ||
223 | } | ||
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index 38c4bd87b2c9..c679867c2ccd 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c | |||
@@ -234,7 +234,8 @@ static struct capiminor *capiminor_alloc(struct capi20_appl *ap, u32 ncci) | |||
234 | 234 | ||
235 | mp->minor = minor; | 235 | mp->minor = minor; |
236 | 236 | ||
237 | dev = tty_register_device(capinc_tty_driver, minor, NULL); | 237 | dev = tty_port_register_device(&mp->port, capinc_tty_driver, minor, |
238 | NULL); | ||
238 | if (IS_ERR(dev)) | 239 | if (IS_ERR(dev)) |
239 | goto err_out2; | 240 | goto err_out2; |
240 | 241 | ||
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index a6d9fd2858f7..67abf3ff45e8 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -446,8 +446,8 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
446 | goto out; | 446 | goto out; |
447 | } | 447 | } |
448 | 448 | ||
449 | iflag = tty->termios->c_iflag; | 449 | iflag = tty->termios.c_iflag; |
450 | cflag = tty->termios->c_cflag; | 450 | cflag = tty->termios.c_cflag; |
451 | old_cflag = old ? old->c_cflag : cflag; | 451 | old_cflag = old ? old->c_cflag : cflag; |
452 | gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", | 452 | gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x", |
453 | cs->minor_index, iflag, cflag, old_cflag); | 453 | cs->minor_index, iflag, cflag, old_cflag); |
@@ -524,7 +524,8 @@ void gigaset_if_init(struct cardstate *cs) | |||
524 | tasklet_init(&cs->if_wake_tasklet, if_wake, (unsigned long) cs); | 524 | tasklet_init(&cs->if_wake_tasklet, if_wake, (unsigned long) cs); |
525 | 525 | ||
526 | mutex_lock(&cs->mutex); | 526 | mutex_lock(&cs->mutex); |
527 | cs->tty_dev = tty_register_device(drv->tty, cs->minor_index, NULL); | 527 | cs->tty_dev = tty_port_register_device(&cs->port, drv->tty, |
528 | cs->minor_index, NULL); | ||
528 | 529 | ||
529 | if (!IS_ERR(cs->tty_dev)) | 530 | if (!IS_ERR(cs->tty_dev)) |
530 | dev_set_drvdata(cs->tty_dev, cs); | 531 | dev_set_drvdata(cs->tty_dev, cs); |
diff --git a/drivers/isdn/hardware/mISDN/avmfritz.c b/drivers/isdn/hardware/mISDN/avmfritz.c index fa6ca4733725..dceaec821b0e 100644 --- a/drivers/isdn/hardware/mISDN/avmfritz.c +++ b/drivers/isdn/hardware/mISDN/avmfritz.c | |||
@@ -857,8 +857,9 @@ avm_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
857 | switch (cmd) { | 857 | switch (cmd) { |
858 | case CLOSE_CHANNEL: | 858 | case CLOSE_CHANNEL: |
859 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 859 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
860 | cancel_work_sync(&bch->workq); | ||
860 | spin_lock_irqsave(&fc->lock, flags); | 861 | spin_lock_irqsave(&fc->lock, flags); |
861 | mISDN_freebchannel(bch); | 862 | mISDN_clear_bchannel(bch); |
862 | modehdlc(bch, ISDN_P_NONE); | 863 | modehdlc(bch, ISDN_P_NONE); |
863 | spin_unlock_irqrestore(&fc->lock, flags); | 864 | spin_unlock_irqrestore(&fc->lock, flags); |
864 | ch->protocol = ISDN_P_NONE; | 865 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c index 5e402cf2e795..f02794203bb1 100644 --- a/drivers/isdn/hardware/mISDN/hfcmulti.c +++ b/drivers/isdn/hardware/mISDN/hfcmulti.c | |||
@@ -5059,6 +5059,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, | |||
5059 | printk(KERN_INFO | 5059 | printk(KERN_INFO |
5060 | "HFC-E1 #%d has overlapping B-channels on fragment #%d\n", | 5060 | "HFC-E1 #%d has overlapping B-channels on fragment #%d\n", |
5061 | E1_cnt + 1, pt); | 5061 | E1_cnt + 1, pt); |
5062 | kfree(hc); | ||
5062 | return -EINVAL; | 5063 | return -EINVAL; |
5063 | } | 5064 | } |
5064 | maskcheck |= hc->bmask[pt]; | 5065 | maskcheck |= hc->bmask[pt]; |
@@ -5086,6 +5087,7 @@ hfcmulti_init(struct hm_map *m, struct pci_dev *pdev, | |||
5086 | if ((poll >> 1) > sizeof(hc->silence_data)) { | 5087 | if ((poll >> 1) > sizeof(hc->silence_data)) { |
5087 | printk(KERN_ERR "HFCMULTI error: silence_data too small, " | 5088 | printk(KERN_ERR "HFCMULTI error: silence_data too small, " |
5088 | "please fix\n"); | 5089 | "please fix\n"); |
5090 | kfree(hc); | ||
5089 | return -EINVAL; | 5091 | return -EINVAL; |
5090 | } | 5092 | } |
5091 | for (i = 0; i < (poll >> 1); i++) | 5093 | for (i = 0; i < (poll >> 1); i++) |
diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 752e0825591f..ccd7d851be26 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c | |||
@@ -1406,8 +1406,9 @@ hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1406 | switch (cmd) { | 1406 | switch (cmd) { |
1407 | case CLOSE_CHANNEL: | 1407 | case CLOSE_CHANNEL: |
1408 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1408 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1409 | cancel_work_sync(&bch->workq); | ||
1409 | spin_lock_irqsave(hx->ip->hwlock, flags); | 1410 | spin_lock_irqsave(hx->ip->hwlock, flags); |
1410 | mISDN_freebchannel(bch); | 1411 | mISDN_clear_bchannel(bch); |
1411 | hscx_mode(hx, ISDN_P_NONE); | 1412 | hscx_mode(hx, ISDN_P_NONE); |
1412 | spin_unlock_irqrestore(hx->ip->hwlock, flags); | 1413 | spin_unlock_irqrestore(hx->ip->hwlock, flags); |
1413 | ch->protocol = ISDN_P_NONE; | 1414 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/mISDNisar.c b/drivers/isdn/hardware/mISDN/mISDNisar.c index be5973ded6d6..182ecf0626c2 100644 --- a/drivers/isdn/hardware/mISDN/mISDNisar.c +++ b/drivers/isdn/hardware/mISDN/mISDNisar.c | |||
@@ -1588,8 +1588,9 @@ isar_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1588 | switch (cmd) { | 1588 | switch (cmd) { |
1589 | case CLOSE_CHANNEL: | 1589 | case CLOSE_CHANNEL: |
1590 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1590 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1591 | cancel_work_sync(&bch->workq); | ||
1591 | spin_lock_irqsave(ich->is->hwlock, flags); | 1592 | spin_lock_irqsave(ich->is->hwlock, flags); |
1592 | mISDN_freebchannel(bch); | 1593 | mISDN_clear_bchannel(bch); |
1593 | modeisar(ich, ISDN_P_NONE); | 1594 | modeisar(ich, ISDN_P_NONE); |
1594 | spin_unlock_irqrestore(ich->is->hwlock, flags); | 1595 | spin_unlock_irqrestore(ich->is->hwlock, flags); |
1595 | ch->protocol = ISDN_P_NONE; | 1596 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/netjet.c b/drivers/isdn/hardware/mISDN/netjet.c index c3e3e7686273..9bcade59eb73 100644 --- a/drivers/isdn/hardware/mISDN/netjet.c +++ b/drivers/isdn/hardware/mISDN/netjet.c | |||
@@ -812,8 +812,9 @@ nj_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
812 | switch (cmd) { | 812 | switch (cmd) { |
813 | case CLOSE_CHANNEL: | 813 | case CLOSE_CHANNEL: |
814 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 814 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
815 | cancel_work_sync(&bch->workq); | ||
815 | spin_lock_irqsave(&card->lock, flags); | 816 | spin_lock_irqsave(&card->lock, flags); |
816 | mISDN_freebchannel(bch); | 817 | mISDN_clear_bchannel(bch); |
817 | mode_tiger(bc, ISDN_P_NONE); | 818 | mode_tiger(bc, ISDN_P_NONE); |
818 | spin_unlock_irqrestore(&card->lock, flags); | 819 | spin_unlock_irqrestore(&card->lock, flags); |
819 | ch->protocol = ISDN_P_NONE; | 820 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/hardware/mISDN/w6692.c b/drivers/isdn/hardware/mISDN/w6692.c index 26a86b846099..335fe6455002 100644 --- a/drivers/isdn/hardware/mISDN/w6692.c +++ b/drivers/isdn/hardware/mISDN/w6692.c | |||
@@ -1054,8 +1054,9 @@ w6692_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg) | |||
1054 | switch (cmd) { | 1054 | switch (cmd) { |
1055 | case CLOSE_CHANNEL: | 1055 | case CLOSE_CHANNEL: |
1056 | test_and_clear_bit(FLG_OPEN, &bch->Flags); | 1056 | test_and_clear_bit(FLG_OPEN, &bch->Flags); |
1057 | cancel_work_sync(&bch->workq); | ||
1057 | spin_lock_irqsave(&card->lock, flags); | 1058 | spin_lock_irqsave(&card->lock, flags); |
1058 | mISDN_freebchannel(bch); | 1059 | mISDN_clear_bchannel(bch); |
1059 | w6692_mode(bc, ISDN_P_NONE); | 1060 | w6692_mode(bc, ISDN_P_NONE); |
1060 | spin_unlock_irqrestore(&card->lock, flags); | 1061 | spin_unlock_irqrestore(&card->lock, flags); |
1061 | ch->protocol = ISDN_P_NONE; | 1062 | ch->protocol = ISDN_P_NONE; |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 7bc50670d7d9..b817809f763c 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1009,15 +1009,15 @@ isdn_tty_change_speed(modem_info *info) | |||
1009 | quot; | 1009 | quot; |
1010 | int i; | 1010 | int i; |
1011 | 1011 | ||
1012 | if (!port->tty || !port->tty->termios) | 1012 | if (!port->tty) |
1013 | return; | 1013 | return; |
1014 | cflag = port->tty->termios->c_cflag; | 1014 | cflag = port->tty->termios.c_cflag; |
1015 | 1015 | ||
1016 | quot = i = cflag & CBAUD; | 1016 | quot = i = cflag & CBAUD; |
1017 | if (i & CBAUDEX) { | 1017 | if (i & CBAUDEX) { |
1018 | i &= ~CBAUDEX; | 1018 | i &= ~CBAUDEX; |
1019 | if (i < 1 || i > 2) | 1019 | if (i < 1 || i > 2) |
1020 | port->tty->termios->c_cflag &= ~CBAUDEX; | 1020 | port->tty->termios.c_cflag &= ~CBAUDEX; |
1021 | else | 1021 | else |
1022 | i += 15; | 1022 | i += 15; |
1023 | } | 1023 | } |
@@ -1097,7 +1097,7 @@ isdn_tty_shutdown(modem_info *info) | |||
1097 | #endif | 1097 | #endif |
1098 | isdn_unlock_drivers(); | 1098 | isdn_unlock_drivers(); |
1099 | info->msr &= ~UART_MSR_RI; | 1099 | info->msr &= ~UART_MSR_RI; |
1100 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) { | 1100 | if (!info->port.tty || (info->port.tty->termios.c_cflag & HUPCL)) { |
1101 | info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); | 1101 | info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS); |
1102 | if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) { | 1102 | if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) { |
1103 | isdn_tty_modem_reset_regs(info, 0); | 1103 | isdn_tty_modem_reset_regs(info, 0); |
@@ -1469,13 +1469,13 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1469 | if (!old_termios) | 1469 | if (!old_termios) |
1470 | isdn_tty_change_speed(info); | 1470 | isdn_tty_change_speed(info); |
1471 | else { | 1471 | else { |
1472 | if (tty->termios->c_cflag == old_termios->c_cflag && | 1472 | if (tty->termios.c_cflag == old_termios->c_cflag && |
1473 | tty->termios->c_ispeed == old_termios->c_ispeed && | 1473 | tty->termios.c_ispeed == old_termios->c_ispeed && |
1474 | tty->termios->c_ospeed == old_termios->c_ospeed) | 1474 | tty->termios.c_ospeed == old_termios->c_ospeed) |
1475 | return; | 1475 | return; |
1476 | isdn_tty_change_speed(info); | 1476 | isdn_tty_change_speed(info); |
1477 | if ((old_termios->c_cflag & CRTSCTS) && | 1477 | if ((old_termios->c_cflag & CRTSCTS) && |
1478 | !(tty->termios->c_cflag & CRTSCTS)) | 1478 | !(tty->termios.c_cflag & CRTSCTS)) |
1479 | tty->hw_stopped = 0; | 1479 | tty->hw_stopped = 0; |
1480 | } | 1480 | } |
1481 | } | 1481 | } |
@@ -1486,6 +1486,18 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1486 | * ------------------------------------------------------------ | 1486 | * ------------------------------------------------------------ |
1487 | */ | 1487 | */ |
1488 | 1488 | ||
1489 | static int isdn_tty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
1490 | { | ||
1491 | modem_info *info = &dev->mdm.info[tty->index]; | ||
1492 | |||
1493 | if (isdn_tty_paranoia_check(info, tty->name, __func__)) | ||
1494 | return -ENODEV; | ||
1495 | |||
1496 | tty->driver_data = info; | ||
1497 | |||
1498 | return tty_port_install(&info->port, driver, tty); | ||
1499 | } | ||
1500 | |||
1489 | /* | 1501 | /* |
1490 | * This routine is called whenever a serial port is opened. It | 1502 | * This routine is called whenever a serial port is opened. It |
1491 | * enables interrupts for a serial port, linking in its async structure into | 1503 | * enables interrupts for a serial port, linking in its async structure into |
@@ -1495,22 +1507,16 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1495 | static int | 1507 | static int |
1496 | isdn_tty_open(struct tty_struct *tty, struct file *filp) | 1508 | isdn_tty_open(struct tty_struct *tty, struct file *filp) |
1497 | { | 1509 | { |
1498 | struct tty_port *port; | 1510 | modem_info *info = tty->driver_data; |
1499 | modem_info *info; | 1511 | struct tty_port *port = &info->port; |
1500 | int retval; | 1512 | int retval; |
1501 | 1513 | ||
1502 | info = &dev->mdm.info[tty->index]; | ||
1503 | if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open")) | ||
1504 | return -ENODEV; | ||
1505 | port = &info->port; | ||
1506 | #ifdef ISDN_DEBUG_MODEM_OPEN | 1514 | #ifdef ISDN_DEBUG_MODEM_OPEN |
1507 | printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name, | 1515 | printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name, |
1508 | port->count); | 1516 | port->count); |
1509 | #endif | 1517 | #endif |
1510 | port->count++; | 1518 | port->count++; |
1511 | tty->driver_data = info; | ||
1512 | port->tty = tty; | 1519 | port->tty = tty; |
1513 | tty->port = port; | ||
1514 | /* | 1520 | /* |
1515 | * Start up serial port | 1521 | * Start up serial port |
1516 | */ | 1522 | */ |
@@ -1738,6 +1744,7 @@ modem_write_profile(atemu *m) | |||
1738 | } | 1744 | } |
1739 | 1745 | ||
1740 | static const struct tty_operations modem_ops = { | 1746 | static const struct tty_operations modem_ops = { |
1747 | .install = isdn_tty_install, | ||
1741 | .open = isdn_tty_open, | 1748 | .open = isdn_tty_open, |
1742 | .close = isdn_tty_close, | 1749 | .close = isdn_tty_close, |
1743 | .write = isdn_tty_write, | 1750 | .write = isdn_tty_write, |
@@ -1782,7 +1789,7 @@ isdn_tty_modem_init(void) | |||
1782 | m->tty_modem->subtype = SERIAL_TYPE_NORMAL; | 1789 | m->tty_modem->subtype = SERIAL_TYPE_NORMAL; |
1783 | m->tty_modem->init_termios = tty_std_termios; | 1790 | m->tty_modem->init_termios = tty_std_termios; |
1784 | m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; | 1791 | m->tty_modem->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL; |
1785 | m->tty_modem->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 1792 | m->tty_modem->flags = TTY_DRIVER_REAL_RAW; |
1786 | m->tty_modem->driver_name = "isdn_tty"; | 1793 | m->tty_modem->driver_name = "isdn_tty"; |
1787 | tty_set_operations(m->tty_modem, &modem_ops); | 1794 | tty_set_operations(m->tty_modem, &modem_ops); |
1788 | retval = tty_register_driver(m->tty_modem); | 1795 | retval = tty_register_driver(m->tty_modem); |
diff --git a/drivers/isdn/mISDN/hwchannel.c b/drivers/isdn/mISDN/hwchannel.c index ef34fd40867c..2602be23f341 100644 --- a/drivers/isdn/mISDN/hwchannel.c +++ b/drivers/isdn/mISDN/hwchannel.c | |||
@@ -148,17 +148,16 @@ mISDN_clear_bchannel(struct bchannel *ch) | |||
148 | ch->next_minlen = ch->init_minlen; | 148 | ch->next_minlen = ch->init_minlen; |
149 | ch->maxlen = ch->init_maxlen; | 149 | ch->maxlen = ch->init_maxlen; |
150 | ch->next_maxlen = ch->init_maxlen; | 150 | ch->next_maxlen = ch->init_maxlen; |
151 | skb_queue_purge(&ch->rqueue); | ||
152 | ch->rcount = 0; | ||
151 | } | 153 | } |
152 | EXPORT_SYMBOL(mISDN_clear_bchannel); | 154 | EXPORT_SYMBOL(mISDN_clear_bchannel); |
153 | 155 | ||
154 | int | 156 | void |
155 | mISDN_freebchannel(struct bchannel *ch) | 157 | mISDN_freebchannel(struct bchannel *ch) |
156 | { | 158 | { |
159 | cancel_work_sync(&ch->workq); | ||
157 | mISDN_clear_bchannel(ch); | 160 | mISDN_clear_bchannel(ch); |
158 | skb_queue_purge(&ch->rqueue); | ||
159 | ch->rcount = 0; | ||
160 | flush_work_sync(&ch->workq); | ||
161 | return 0; | ||
162 | } | 161 | } |
163 | EXPORT_SYMBOL(mISDN_freebchannel); | 162 | EXPORT_SYMBOL(mISDN_freebchannel); |
164 | 163 | ||
diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c index e37618e363cf..461bbf9b33fa 100644 --- a/drivers/leds/leds-netxbig.c +++ b/drivers/leds/leds-netxbig.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
30 | #include <linux/leds.h> | 30 | #include <linux/leds.h> |
31 | #include <mach/leds-netxbig.h> | 31 | #include <linux/platform_data/leds-kirkwood-netxbig.h> |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * GPIO extension bus. | 34 | * GPIO extension bus. |
diff --git a/drivers/leds/leds-ns2.c b/drivers/leds/leds-ns2.c index 10528dafb043..d176ec83f5d9 100644 --- a/drivers/leds/leds-ns2.c +++ b/drivers/leds/leds-ns2.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
30 | #include <linux/leds.h> | 30 | #include <linux/leds.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <mach/leds-ns2.h> | 32 | #include <linux/platform_data/leds-kirkwood-ns2.h> |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * The Network Space v2 dual-GPIO LED is wired to a CPLD and can blink in | 35 | * The Network Space v2 dual-GPIO LED is wired to a CPLD and can blink in |
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c index 942f0ea18178..e1a0df63a37f 100644 --- a/drivers/leds/leds-s3c24xx.c +++ b/drivers/leds/leds-s3c24xx.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #include <mach/hardware.h> | 22 | #include <mach/hardware.h> |
23 | #include <mach/regs-gpio.h> | 23 | #include <mach/regs-gpio.h> |
24 | #include <mach/leds-gpio.h> | 24 | #include <linux/platform_data/leds-s3c24xx.h> |
25 | 25 | ||
26 | /* our context */ | 26 | /* our context */ |
27 | 27 | ||
diff --git a/drivers/media/video/davinci/vpbe_venc.c b/drivers/media/video/davinci/vpbe_venc.c index b21ecc8d134d..0302669622d6 100644 --- a/drivers/media/video/davinci/vpbe_venc.c +++ b/drivers/media/video/davinci/vpbe_venc.c | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
29 | #include <mach/mux.h> | 29 | #include <mach/mux.h> |
30 | #include <mach/i2c.h> | 30 | #include <linux/platform_data/i2c-davinci.h> |
31 | 31 | ||
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | 33 | ||
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 560a65aa7038..bbe70991d30b 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -44,7 +44,7 @@ | |||
44 | #include <mach/dma-mx1-mx2.h> | 44 | #include <mach/dma-mx1-mx2.h> |
45 | #include <mach/hardware.h> | 45 | #include <mach/hardware.h> |
46 | #include <mach/irqs.h> | 46 | #include <mach/irqs.h> |
47 | #include <mach/mx1_camera.h> | 47 | #include <linux/platform_data/camera-mx1.h> |
48 | 48 | ||
49 | /* | 49 | /* |
50 | * CSI registers | 50 | * CSI registers |
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index ac175406e582..965427f279a5 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
@@ -40,7 +40,7 @@ | |||
40 | 40 | ||
41 | #include <linux/videodev2.h> | 41 | #include <linux/videodev2.h> |
42 | 42 | ||
43 | #include <mach/mx2_cam.h> | 43 | #include <linux/platform_data/camera-mx2.h> |
44 | #include <mach/hardware.h> | 44 | #include <mach/hardware.h> |
45 | 45 | ||
46 | #include <asm/dma.h> | 46 | #include <asm/dma.h> |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index af2297dd49c8..1481b0d419da 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -25,8 +25,8 @@ | |||
25 | #include <media/soc_mediabus.h> | 25 | #include <media/soc_mediabus.h> |
26 | 26 | ||
27 | #include <mach/ipu.h> | 27 | #include <mach/ipu.h> |
28 | #include <mach/mx3_camera.h> | 28 | #include <linux/platform_data/camera-mx3.h> |
29 | #include <mach/dma.h> | 29 | #include <linux/platform_data/dma-imx.h> |
30 | 30 | ||
31 | #define MX3_CAM_DRV_NAME "mx3-camera" | 31 | #define MX3_CAM_DRV_NAME "mx3-camera" |
32 | 32 | ||
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 88cf9d952631..409da0f8e5cf 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <media/v4l2-device.h> | 44 | #include <media/v4l2-device.h> |
45 | #include <media/v4l2-ioctl.h> | 45 | #include <media/v4l2-ioctl.h> |
46 | 46 | ||
47 | #include <plat/cpu.h> | ||
47 | #include <plat/dma.h> | 48 | #include <plat/dma.h> |
48 | #include <plat/vrfb.h> | 49 | #include <plat/vrfb.h> |
49 | #include <video/omapdss.h> | 50 | #include <video/omapdss.h> |
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index 1c347633e663..43e61fe5df50 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c | |||
@@ -70,6 +70,8 @@ | |||
70 | #include <media/v4l2-common.h> | 70 | #include <media/v4l2-common.h> |
71 | #include <media/v4l2-device.h> | 71 | #include <media/v4l2-device.h> |
72 | 72 | ||
73 | #include <plat/cpu.h> | ||
74 | |||
73 | #include "isp.h" | 75 | #include "isp.h" |
74 | #include "ispreg.h" | 76 | #include "ispreg.h" |
75 | #include "ispccdc.h" | 77 | #include "ispccdc.h" |
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c index 9c21e01f2c24..1e3776d08dac 100644 --- a/drivers/media/video/pxa_camera.c +++ b/drivers/media/video/pxa_camera.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/videodev2.h> | 37 | #include <linux/videodev2.h> |
38 | 38 | ||
39 | #include <mach/dma.h> | 39 | #include <mach/dma.h> |
40 | #include <mach/camera.h> | 40 | #include <linux/platform_data/camera-pxa.h> |
41 | 41 | ||
42 | #define PXA_CAM_VERSION "0.0.6" | 42 | #define PXA_CAM_VERSION "0.0.6" |
43 | #define PXA_CAM_DRV_NAME "pxa27x-camera" | 43 | #define PXA_CAM_DRV_NAME "pxa27x-camera" |
diff --git a/drivers/media/video/s5p-fimc/mipi-csis.c b/drivers/media/video/s5p-fimc/mipi-csis.c index 2f73d9e3d0b7..5e898432883a 100644 --- a/drivers/media/video/s5p-fimc/mipi-csis.c +++ b/drivers/media/video/s5p-fimc/mipi-csis.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
28 | #include <media/v4l2-subdev.h> | 28 | #include <media/v4l2-subdev.h> |
29 | #include <plat/mipi_csis.h> | 29 | #include <linux/platform_data/mipi-csis.h> |
30 | #include "mipi-csis.h" | 30 | #include "mipi-csis.h" |
31 | 31 | ||
32 | static int debug; | 32 | static int debug; |
diff --git a/drivers/mfd/88pm800.c b/drivers/mfd/88pm800.c index b67a3018b136..ce229ea933d1 100644 --- a/drivers/mfd/88pm800.c +++ b/drivers/mfd/88pm800.c | |||
@@ -470,7 +470,8 @@ static int __devinit device_800_init(struct pm80x_chip *chip, | |||
470 | 470 | ||
471 | ret = | 471 | ret = |
472 | mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 472 | mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
473 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0); | 473 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], 0, |
474 | NULL); | ||
474 | if (ret < 0) { | 475 | if (ret < 0) { |
475 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 476 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
476 | goto out_dev; | 477 | goto out_dev; |
@@ -481,7 +482,7 @@ static int __devinit device_800_init(struct pm80x_chip *chip, | |||
481 | rtc_devs[0].platform_data = pdata->rtc; | 482 | rtc_devs[0].platform_data = pdata->rtc; |
482 | rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata); | 483 | rtc_devs[0].pdata_size = sizeof(struct pm80x_rtc_pdata); |
483 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 484 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
484 | ARRAY_SIZE(rtc_devs), NULL, 0); | 485 | ARRAY_SIZE(rtc_devs), NULL, 0, NULL); |
485 | if (ret < 0) { | 486 | if (ret < 0) { |
486 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 487 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
487 | goto out_dev; | 488 | goto out_dev; |
diff --git a/drivers/mfd/88pm805.c b/drivers/mfd/88pm805.c index 6146583589f6..c20a31136f04 100644 --- a/drivers/mfd/88pm805.c +++ b/drivers/mfd/88pm805.c | |||
@@ -216,7 +216,8 @@ static int __devinit device_805_init(struct pm80x_chip *chip) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], | 218 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], |
219 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0); | 219 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0, |
220 | NULL); | ||
220 | if (ret < 0) { | 221 | if (ret < 0) { |
221 | dev_err(chip->dev, "Failed to add codec subdev\n"); | 222 | dev_err(chip->dev, "Failed to add codec subdev\n"); |
222 | goto out_codec; | 223 | goto out_codec; |
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c index d09918cf1b15..b73f033b2c60 100644 --- a/drivers/mfd/88pm860x-core.c +++ b/drivers/mfd/88pm860x-core.c | |||
@@ -637,7 +637,7 @@ static void __devinit device_bk_init(struct pm860x_chip *chip, | |||
637 | bk_devs[i].resources = &bk_resources[j]; | 637 | bk_devs[i].resources = &bk_resources[j]; |
638 | ret = mfd_add_devices(chip->dev, 0, | 638 | ret = mfd_add_devices(chip->dev, 0, |
639 | &bk_devs[i], 1, | 639 | &bk_devs[i], 1, |
640 | &bk_resources[j], 0); | 640 | &bk_resources[j], 0, NULL); |
641 | if (ret < 0) { | 641 | if (ret < 0) { |
642 | dev_err(chip->dev, "Failed to add " | 642 | dev_err(chip->dev, "Failed to add " |
643 | "backlight subdev\n"); | 643 | "backlight subdev\n"); |
@@ -672,7 +672,7 @@ static void __devinit device_led_init(struct pm860x_chip *chip, | |||
672 | led_devs[i].resources = &led_resources[j], | 672 | led_devs[i].resources = &led_resources[j], |
673 | ret = mfd_add_devices(chip->dev, 0, | 673 | ret = mfd_add_devices(chip->dev, 0, |
674 | &led_devs[i], 1, | 674 | &led_devs[i], 1, |
675 | &led_resources[j], 0); | 675 | &led_resources[j], 0, NULL); |
676 | if (ret < 0) { | 676 | if (ret < 0) { |
677 | dev_err(chip->dev, "Failed to add " | 677 | dev_err(chip->dev, "Failed to add " |
678 | "led subdev\n"); | 678 | "led subdev\n"); |
@@ -709,7 +709,7 @@ static void __devinit device_regulator_init(struct pm860x_chip *chip, | |||
709 | regulator_devs[i].resources = ®ulator_resources[seq]; | 709 | regulator_devs[i].resources = ®ulator_resources[seq]; |
710 | 710 | ||
711 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, | 711 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[i], 1, |
712 | ®ulator_resources[seq], 0); | 712 | ®ulator_resources[seq], 0, NULL); |
713 | if (ret < 0) { | 713 | if (ret < 0) { |
714 | dev_err(chip->dev, "Failed to add regulator subdev\n"); | 714 | dev_err(chip->dev, "Failed to add regulator subdev\n"); |
715 | goto out; | 715 | goto out; |
@@ -733,7 +733,7 @@ static void __devinit device_rtc_init(struct pm860x_chip *chip, | |||
733 | rtc_devs[0].resources = &rtc_resources[0]; | 733 | rtc_devs[0].resources = &rtc_resources[0]; |
734 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 734 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
735 | ARRAY_SIZE(rtc_devs), &rtc_resources[0], | 735 | ARRAY_SIZE(rtc_devs), &rtc_resources[0], |
736 | chip->irq_base); | 736 | chip->irq_base, NULL); |
737 | if (ret < 0) | 737 | if (ret < 0) |
738 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 738 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
739 | } | 739 | } |
@@ -752,7 +752,7 @@ static void __devinit device_touch_init(struct pm860x_chip *chip, | |||
752 | touch_devs[0].resources = &touch_resources[0]; | 752 | touch_devs[0].resources = &touch_resources[0]; |
753 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], | 753 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], |
754 | ARRAY_SIZE(touch_devs), &touch_resources[0], | 754 | ARRAY_SIZE(touch_devs), &touch_resources[0], |
755 | chip->irq_base); | 755 | chip->irq_base, NULL); |
756 | if (ret < 0) | 756 | if (ret < 0) |
757 | dev_err(chip->dev, "Failed to add touch subdev\n"); | 757 | dev_err(chip->dev, "Failed to add touch subdev\n"); |
758 | } | 758 | } |
@@ -770,7 +770,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
770 | power_devs[0].num_resources = ARRAY_SIZE(battery_resources); | 770 | power_devs[0].num_resources = ARRAY_SIZE(battery_resources); |
771 | power_devs[0].resources = &battery_resources[0], | 771 | power_devs[0].resources = &battery_resources[0], |
772 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, | 772 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1, |
773 | &battery_resources[0], chip->irq_base); | 773 | &battery_resources[0], chip->irq_base, NULL); |
774 | if (ret < 0) | 774 | if (ret < 0) |
775 | dev_err(chip->dev, "Failed to add battery subdev\n"); | 775 | dev_err(chip->dev, "Failed to add battery subdev\n"); |
776 | 776 | ||
@@ -779,7 +779,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
779 | power_devs[1].num_resources = ARRAY_SIZE(charger_resources); | 779 | power_devs[1].num_resources = ARRAY_SIZE(charger_resources); |
780 | power_devs[1].resources = &charger_resources[0], | 780 | power_devs[1].resources = &charger_resources[0], |
781 | ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, | 781 | ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1, |
782 | &charger_resources[0], chip->irq_base); | 782 | &charger_resources[0], chip->irq_base, NULL); |
783 | if (ret < 0) | 783 | if (ret < 0) |
784 | dev_err(chip->dev, "Failed to add charger subdev\n"); | 784 | dev_err(chip->dev, "Failed to add charger subdev\n"); |
785 | 785 | ||
@@ -788,7 +788,7 @@ static void __devinit device_power_init(struct pm860x_chip *chip, | |||
788 | power_devs[2].num_resources = ARRAY_SIZE(preg_resources); | 788 | power_devs[2].num_resources = ARRAY_SIZE(preg_resources); |
789 | power_devs[2].resources = &preg_resources[0], | 789 | power_devs[2].resources = &preg_resources[0], |
790 | ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, | 790 | ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1, |
791 | &preg_resources[0], chip->irq_base); | 791 | &preg_resources[0], chip->irq_base, NULL); |
792 | if (ret < 0) | 792 | if (ret < 0) |
793 | dev_err(chip->dev, "Failed to add preg subdev\n"); | 793 | dev_err(chip->dev, "Failed to add preg subdev\n"); |
794 | } | 794 | } |
@@ -802,7 +802,7 @@ static void __devinit device_onkey_init(struct pm860x_chip *chip, | |||
802 | onkey_devs[0].resources = &onkey_resources[0], | 802 | onkey_devs[0].resources = &onkey_resources[0], |
803 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 803 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
804 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], | 804 | ARRAY_SIZE(onkey_devs), &onkey_resources[0], |
805 | chip->irq_base); | 805 | chip->irq_base, NULL); |
806 | if (ret < 0) | 806 | if (ret < 0) |
807 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 807 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
808 | } | 808 | } |
@@ -815,7 +815,8 @@ static void __devinit device_codec_init(struct pm860x_chip *chip, | |||
815 | codec_devs[0].num_resources = ARRAY_SIZE(codec_resources); | 815 | codec_devs[0].num_resources = ARRAY_SIZE(codec_resources); |
816 | codec_devs[0].resources = &codec_resources[0], | 816 | codec_devs[0].resources = &codec_resources[0], |
817 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], | 817 | ret = mfd_add_devices(chip->dev, 0, &codec_devs[0], |
818 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0); | 818 | ARRAY_SIZE(codec_devs), &codec_resources[0], 0, |
819 | NULL); | ||
819 | if (ret < 0) | 820 | if (ret < 0) |
820 | dev_err(chip->dev, "Failed to add codec subdev\n"); | 821 | dev_err(chip->dev, "Failed to add codec subdev\n"); |
821 | } | 822 | } |
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 44a3fdbadef4..f1beb4971f87 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c | |||
@@ -424,7 +424,7 @@ static int aat2870_i2c_probe(struct i2c_client *client, | |||
424 | } | 424 | } |
425 | 425 | ||
426 | ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, | 426 | ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, |
427 | ARRAY_SIZE(aat2870_devs), NULL, 0); | 427 | ARRAY_SIZE(aat2870_devs), NULL, 0, NULL); |
428 | if (ret != 0) { | 428 | if (ret != 0) { |
429 | dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); | 429 | dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); |
430 | goto out_disable; | 430 | goto out_disable; |
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c index 78fca2902c8d..01781ae5d0d7 100644 --- a/drivers/mfd/ab3100-core.c +++ b/drivers/mfd/ab3100-core.c | |||
@@ -946,7 +946,7 @@ static int __devinit ab3100_probe(struct i2c_client *client, | |||
946 | } | 946 | } |
947 | 947 | ||
948 | err = mfd_add_devices(&client->dev, 0, ab3100_devs, | 948 | err = mfd_add_devices(&client->dev, 0, ab3100_devs, |
949 | ARRAY_SIZE(ab3100_devs), NULL, 0); | 949 | ARRAY_SIZE(ab3100_devs), NULL, 0, NULL); |
950 | 950 | ||
951 | ab3100_setup_debugfs(ab3100); | 951 | ab3100_setup_debugfs(ab3100); |
952 | 952 | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 626b4ecaf647..47adf800024e 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -1418,25 +1418,25 @@ static int __devinit ab8500_probe(struct platform_device *pdev) | |||
1418 | 1418 | ||
1419 | ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, | 1419 | ret = mfd_add_devices(ab8500->dev, 0, abx500_common_devs, |
1420 | ARRAY_SIZE(abx500_common_devs), NULL, | 1420 | ARRAY_SIZE(abx500_common_devs), NULL, |
1421 | ab8500->irq_base); | 1421 | ab8500->irq_base, ab8500->domain); |
1422 | if (ret) | 1422 | if (ret) |
1423 | goto out_freeirq; | 1423 | goto out_freeirq; |
1424 | 1424 | ||
1425 | if (is_ab9540(ab8500)) | 1425 | if (is_ab9540(ab8500)) |
1426 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, | 1426 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs, |
1427 | ARRAY_SIZE(ab9540_devs), NULL, | 1427 | ARRAY_SIZE(ab9540_devs), NULL, |
1428 | ab8500->irq_base); | 1428 | ab8500->irq_base, ab8500->domain); |
1429 | else | 1429 | else |
1430 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, | 1430 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, |
1431 | ARRAY_SIZE(ab8500_devs), NULL, | 1431 | ARRAY_SIZE(ab8500_devs), NULL, |
1432 | ab8500->irq_base); | 1432 | ab8500->irq_base, ab8500->domain); |
1433 | if (ret) | 1433 | if (ret) |
1434 | goto out_freeirq; | 1434 | goto out_freeirq; |
1435 | 1435 | ||
1436 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) | 1436 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) |
1437 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, | 1437 | ret = mfd_add_devices(ab8500->dev, 0, ab9540_ab8505_devs, |
1438 | ARRAY_SIZE(ab9540_ab8505_devs), NULL, | 1438 | ARRAY_SIZE(ab9540_ab8505_devs), NULL, |
1439 | ab8500->irq_base); | 1439 | ab8500->irq_base, ab8500->domain); |
1440 | if (ret) | 1440 | if (ret) |
1441 | goto out_freeirq; | 1441 | goto out_freeirq; |
1442 | 1442 | ||
@@ -1444,7 +1444,7 @@ static int __devinit ab8500_probe(struct platform_device *pdev) | |||
1444 | /* Add battery management devices */ | 1444 | /* Add battery management devices */ |
1445 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, | 1445 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs, |
1446 | ARRAY_SIZE(ab8500_bm_devs), NULL, | 1446 | ARRAY_SIZE(ab8500_bm_devs), NULL, |
1447 | ab8500->irq_base); | 1447 | ab8500->irq_base, ab8500->domain); |
1448 | if (ret) | 1448 | if (ret) |
1449 | dev_err(ab8500->dev, "error adding bm devices\n"); | 1449 | dev_err(ab8500->dev, "error adding bm devices\n"); |
1450 | } | 1450 | } |
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c index c7983e862549..1b48f2094806 100644 --- a/drivers/mfd/arizona-core.c +++ b/drivers/mfd/arizona-core.c | |||
@@ -316,7 +316,7 @@ int __devinit arizona_dev_init(struct arizona *arizona) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | ret = mfd_add_devices(arizona->dev, -1, early_devs, | 318 | ret = mfd_add_devices(arizona->dev, -1, early_devs, |
319 | ARRAY_SIZE(early_devs), NULL, 0); | 319 | ARRAY_SIZE(early_devs), NULL, 0, NULL); |
320 | if (ret != 0) { | 320 | if (ret != 0) { |
321 | dev_err(dev, "Failed to add early children: %d\n", ret); | 321 | dev_err(dev, "Failed to add early children: %d\n", ret); |
322 | return ret; | 322 | return ret; |
@@ -516,11 +516,11 @@ int __devinit arizona_dev_init(struct arizona *arizona) | |||
516 | switch (arizona->type) { | 516 | switch (arizona->type) { |
517 | case WM5102: | 517 | case WM5102: |
518 | ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, | 518 | ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, |
519 | ARRAY_SIZE(wm5102_devs), NULL, 0); | 519 | ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); |
520 | break; | 520 | break; |
521 | case WM5110: | 521 | case WM5110: |
522 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, | 522 | ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, |
523 | ARRAY_SIZE(wm5102_devs), NULL, 0); | 523 | ARRAY_SIZE(wm5102_devs), NULL, 0, NULL); |
524 | break; | 524 | break; |
525 | } | 525 | } |
526 | 526 | ||
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 683e18a23329..62f0883a7630 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -913,14 +913,14 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
913 | if (pdata->clock_rate) { | 913 | if (pdata->clock_rate) { |
914 | ds1wm_pdata.clock_rate = pdata->clock_rate; | 914 | ds1wm_pdata.clock_rate = pdata->clock_rate; |
915 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 915 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
916 | &asic3_cell_ds1wm, 1, mem, asic->irq_base); | 916 | &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL); |
917 | if (ret < 0) | 917 | if (ret < 0) |
918 | goto out; | 918 | goto out; |
919 | } | 919 | } |
920 | 920 | ||
921 | if (mem_sdio && (irq >= 0)) { | 921 | if (mem_sdio && (irq >= 0)) { |
922 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 922 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
923 | &asic3_cell_mmc, 1, mem_sdio, irq); | 923 | &asic3_cell_mmc, 1, mem_sdio, irq, NULL); |
924 | if (ret < 0) | 924 | if (ret < 0) |
925 | goto out; | 925 | goto out; |
926 | } | 926 | } |
@@ -934,7 +934,7 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
934 | asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); | 934 | asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]); |
935 | } | 935 | } |
936 | ret = mfd_add_devices(&pdev->dev, 0, | 936 | ret = mfd_add_devices(&pdev->dev, 0, |
937 | asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0); | 937 | asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL); |
938 | } | 938 | } |
939 | 939 | ||
940 | out: | 940 | out: |
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 3419e726de47..2b282133c725 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c | |||
@@ -149,7 +149,7 @@ static int __devinit cs5535_mfd_probe(struct pci_dev *pdev, | |||
149 | } | 149 | } |
150 | 150 | ||
151 | err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, | 151 | err = mfd_add_devices(&pdev->dev, -1, cs5535_mfd_cells, |
152 | ARRAY_SIZE(cs5535_mfd_cells), NULL, 0); | 152 | ARRAY_SIZE(cs5535_mfd_cells), NULL, 0, NULL); |
153 | if (err) { | 153 | if (err) { |
154 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); | 154 | dev_err(&pdev->dev, "MFD add devices failed: %d\n", err); |
155 | goto err_disable; | 155 | goto err_disable; |
diff --git a/drivers/mfd/da9052-core.c b/drivers/mfd/da9052-core.c index 2544910e1fd6..a0a62b24621b 100644 --- a/drivers/mfd/da9052-core.c +++ b/drivers/mfd/da9052-core.c | |||
@@ -803,7 +803,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) | |||
803 | dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret); | 803 | dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret); |
804 | 804 | ||
805 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, | 805 | ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, |
806 | ARRAY_SIZE(da9052_subdev_info), NULL, 0); | 806 | ARRAY_SIZE(da9052_subdev_info), NULL, 0, NULL); |
807 | if (ret) | 807 | if (ret) |
808 | goto err; | 808 | goto err; |
809 | 809 | ||
diff --git a/drivers/mfd/davinci_voicecodec.c b/drivers/mfd/davinci_voicecodec.c index 4e2af2cb2d26..45e83a68641b 100644 --- a/drivers/mfd/davinci_voicecodec.c +++ b/drivers/mfd/davinci_voicecodec.c | |||
@@ -129,7 +129,7 @@ static int __init davinci_vc_probe(struct platform_device *pdev) | |||
129 | cell->pdata_size = sizeof(*davinci_vc); | 129 | cell->pdata_size = sizeof(*davinci_vc); |
130 | 130 | ||
131 | ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, | 131 | ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, |
132 | DAVINCI_VC_CELLS, NULL, 0); | 132 | DAVINCI_VC_CELLS, NULL, 0, NULL); |
133 | if (ret != 0) { | 133 | if (ret != 0) { |
134 | dev_err(&pdev->dev, "fail to register client devices\n"); | 134 | dev_err(&pdev->dev, "fail to register client devices\n"); |
135 | goto fail4; | 135 | goto fail4; |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 7040a0081130..6b67edbdbd01 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -418,6 +418,9 @@ static struct { | |||
418 | 418 | ||
419 | static atomic_t ac_wake_req_state = ATOMIC_INIT(0); | 419 | static atomic_t ac_wake_req_state = ATOMIC_INIT(0); |
420 | 420 | ||
421 | /* Functions definition */ | ||
422 | static void compute_armss_rate(void); | ||
423 | |||
421 | /* Spinlocks */ | 424 | /* Spinlocks */ |
422 | static DEFINE_SPINLOCK(prcmu_lock); | 425 | static DEFINE_SPINLOCK(prcmu_lock); |
423 | static DEFINE_SPINLOCK(clkout_lock); | 426 | static DEFINE_SPINLOCK(clkout_lock); |
@@ -517,6 +520,7 @@ static struct dsiescclk dsiescclk[3] = { | |||
517 | } | 520 | } |
518 | }; | 521 | }; |
519 | 522 | ||
523 | |||
520 | /* | 524 | /* |
521 | * Used by MCDE to setup all necessary PRCMU registers | 525 | * Used by MCDE to setup all necessary PRCMU registers |
522 | */ | 526 | */ |
@@ -1013,6 +1017,7 @@ int db8500_prcmu_set_arm_opp(u8 opp) | |||
1013 | (mb1_transfer.ack.arm_opp != opp)) | 1017 | (mb1_transfer.ack.arm_opp != opp)) |
1014 | r = -EIO; | 1018 | r = -EIO; |
1015 | 1019 | ||
1020 | compute_armss_rate(); | ||
1016 | mutex_unlock(&mb1_transfer.lock); | 1021 | mutex_unlock(&mb1_transfer.lock); |
1017 | 1022 | ||
1018 | return r; | 1023 | return r; |
@@ -1612,6 +1617,7 @@ static unsigned long pll_rate(void __iomem *reg, unsigned long src_rate, | |||
1612 | if ((branch == PLL_FIX) || ((branch == PLL_DIV) && | 1617 | if ((branch == PLL_FIX) || ((branch == PLL_DIV) && |
1613 | (val & PRCM_PLL_FREQ_DIV2EN) && | 1618 | (val & PRCM_PLL_FREQ_DIV2EN) && |
1614 | ((reg == PRCM_PLLSOC0_FREQ) || | 1619 | ((reg == PRCM_PLLSOC0_FREQ) || |
1620 | (reg == PRCM_PLLARM_FREQ) || | ||
1615 | (reg == PRCM_PLLDDR_FREQ)))) | 1621 | (reg == PRCM_PLLDDR_FREQ)))) |
1616 | div *= 2; | 1622 | div *= 2; |
1617 | 1623 | ||
@@ -1661,6 +1667,39 @@ static unsigned long clock_rate(u8 clock) | |||
1661 | else | 1667 | else |
1662 | return 0; | 1668 | return 0; |
1663 | } | 1669 | } |
1670 | static unsigned long latest_armss_rate; | ||
1671 | static unsigned long armss_rate(void) | ||
1672 | { | ||
1673 | return latest_armss_rate; | ||
1674 | } | ||
1675 | |||
1676 | static void compute_armss_rate(void) | ||
1677 | { | ||
1678 | u32 r; | ||
1679 | unsigned long rate; | ||
1680 | |||
1681 | r = readl(PRCM_ARM_CHGCLKREQ); | ||
1682 | |||
1683 | if (r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ) { | ||
1684 | /* External ARMCLKFIX clock */ | ||
1685 | |||
1686 | rate = pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_FIX); | ||
1687 | |||
1688 | /* Check PRCM_ARM_CHGCLKREQ divider */ | ||
1689 | if (!(r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL)) | ||
1690 | rate /= 2; | ||
1691 | |||
1692 | /* Check PRCM_ARMCLKFIX_MGT divider */ | ||
1693 | r = readl(PRCM_ARMCLKFIX_MGT); | ||
1694 | r &= PRCM_CLK_MGT_CLKPLLDIV_MASK; | ||
1695 | rate /= r; | ||
1696 | |||
1697 | } else {/* ARM PLL */ | ||
1698 | rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV); | ||
1699 | } | ||
1700 | |||
1701 | latest_armss_rate = rate; | ||
1702 | } | ||
1664 | 1703 | ||
1665 | static unsigned long dsiclk_rate(u8 n) | 1704 | static unsigned long dsiclk_rate(u8 n) |
1666 | { | 1705 | { |
@@ -1707,6 +1746,8 @@ unsigned long prcmu_clock_rate(u8 clock) | |||
1707 | return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW); | 1746 | return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW); |
1708 | else if (clock == PRCMU_PLLSOC1) | 1747 | else if (clock == PRCMU_PLLSOC1) |
1709 | return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW); | 1748 | return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW); |
1749 | else if (clock == PRCMU_ARMSS) | ||
1750 | return armss_rate(); | ||
1710 | else if (clock == PRCMU_PLLDDR) | 1751 | else if (clock == PRCMU_PLLDDR) |
1711 | return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW); | 1752 | return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW); |
1712 | else if (clock == PRCMU_PLLDSI) | 1753 | else if (clock == PRCMU_PLLDSI) |
@@ -2693,6 +2734,7 @@ void __init db8500_prcmu_early_init(void) | |||
2693 | handle_simple_irq); | 2734 | handle_simple_irq); |
2694 | set_irq_flags(irq, IRQF_VALID); | 2735 | set_irq_flags(irq, IRQF_VALID); |
2695 | } | 2736 | } |
2737 | compute_armss_rate(); | ||
2696 | } | 2738 | } |
2697 | 2739 | ||
2698 | static void __init init_prcm_registers(void) | 2740 | static void __init init_prcm_registers(void) |
@@ -3010,7 +3052,7 @@ static int __devinit db8500_prcmu_probe(struct platform_device *pdev) | |||
3010 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); | 3052 | prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); |
3011 | 3053 | ||
3012 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, | 3054 | err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, |
3013 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0); | 3055 | ARRAY_SIZE(db8500_prcmu_devs), NULL, 0, NULL); |
3014 | if (err) { | 3056 | if (err) { |
3015 | pr_err("prcmu: Failed to add subdevices\n"); | 3057 | pr_err("prcmu: Failed to add subdevices\n"); |
3016 | return err; | 3058 | return err; |
diff --git a/drivers/mfd/dbx500-prcmu-regs.h b/drivers/mfd/dbx500-prcmu-regs.h index 23108a6e3167..79c76ebdba52 100644 --- a/drivers/mfd/dbx500-prcmu-regs.h +++ b/drivers/mfd/dbx500-prcmu-regs.h | |||
@@ -61,7 +61,8 @@ | |||
61 | #define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 | 61 | #define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 0x2 |
62 | 62 | ||
63 | #define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) | 63 | #define PRCM_ARM_CHGCLKREQ (_PRCMU_BASE + 0x114) |
64 | #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ 0x1 | 64 | #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0) |
65 | #define PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL BIT(16) | ||
65 | 66 | ||
66 | #define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) | 67 | #define PRCM_PLLARM_ENABLE (_PRCMU_BASE + 0x98) |
67 | #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 | 68 | #define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE 0x1 |
@@ -140,6 +141,7 @@ | |||
140 | /* PRCMU clock/PLL/reset registers */ | 141 | /* PRCMU clock/PLL/reset registers */ |
141 | #define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080) | 142 | #define PRCM_PLLSOC0_FREQ (_PRCMU_BASE + 0x080) |
142 | #define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084) | 143 | #define PRCM_PLLSOC1_FREQ (_PRCMU_BASE + 0x084) |
144 | #define PRCM_PLLARM_FREQ (_PRCMU_BASE + 0x088) | ||
143 | #define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C) | 145 | #define PRCM_PLLDDR_FREQ (_PRCMU_BASE + 0x08C) |
144 | #define PRCM_PLL_FREQ_D_SHIFT 0 | 146 | #define PRCM_PLL_FREQ_D_SHIFT 0 |
145 | #define PRCM_PLL_FREQ_D_MASK BITS(0, 7) | 147 | #define PRCM_PLL_FREQ_D_MASK BITS(0, 7) |
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index 04c7093d6499..9e5453d21a68 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c | |||
@@ -168,7 +168,7 @@ static int __init pasic3_probe(struct platform_device *pdev) | |||
168 | /* the first 5 PASIC3 registers control the DS1WM */ | 168 | /* the first 5 PASIC3 registers control the DS1WM */ |
169 | ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; | 169 | ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; |
170 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 170 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
171 | &ds1wm_cell, 1, r, irq); | 171 | &ds1wm_cell, 1, r, irq, NULL); |
172 | if (ret < 0) | 172 | if (ret < 0) |
173 | dev_warn(dev, "failed to register DS1WM\n"); | 173 | dev_warn(dev, "failed to register DS1WM\n"); |
174 | } | 174 | } |
@@ -176,7 +176,8 @@ static int __init pasic3_probe(struct platform_device *pdev) | |||
176 | if (pdata && pdata->led_pdata) { | 176 | if (pdata && pdata->led_pdata) { |
177 | led_cell.platform_data = pdata->led_pdata; | 177 | led_cell.platform_data = pdata->led_pdata; |
178 | led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); | 178 | led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo); |
179 | ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); | 179 | ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, |
180 | 0, NULL); | ||
180 | if (ret < 0) | 181 | if (ret < 0) |
181 | dev_warn(dev, "failed to register LED device\n"); | 182 | dev_warn(dev, "failed to register LED device\n"); |
182 | } | 183 | } |
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index 59df5584cb58..266bdc5bd96d 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c | |||
@@ -344,13 +344,13 @@ static int __devinit intel_msic_init_devices(struct intel_msic *msic) | |||
344 | continue; | 344 | continue; |
345 | 345 | ||
346 | ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, | 346 | ret = mfd_add_devices(&pdev->dev, -1, &msic_devs[i], 1, NULL, |
347 | pdata->irq[i]); | 347 | pdata->irq[i], NULL); |
348 | if (ret) | 348 | if (ret) |
349 | goto fail; | 349 | goto fail; |
350 | } | 350 | } |
351 | 351 | ||
352 | ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, | 352 | ret = mfd_add_devices(&pdev->dev, 0, msic_other_devs, |
353 | ARRAY_SIZE(msic_other_devs), NULL, 0); | 353 | ARRAY_SIZE(msic_other_devs), NULL, 0, NULL); |
354 | if (ret) | 354 | if (ret) |
355 | goto fail; | 355 | goto fail; |
356 | 356 | ||
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c index 2ea99989551a..965c4801df8a 100644 --- a/drivers/mfd/janz-cmodio.c +++ b/drivers/mfd/janz-cmodio.c | |||
@@ -147,7 +147,7 @@ static int __devinit cmodio_probe_submodules(struct cmodio_device *priv) | |||
147 | } | 147 | } |
148 | 148 | ||
149 | return mfd_add_devices(&pdev->dev, 0, priv->cells, | 149 | return mfd_add_devices(&pdev->dev, 0, priv->cells, |
150 | num_probed, NULL, pdev->irq); | 150 | num_probed, NULL, pdev->irq, NULL); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* | 153 | /* |
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index 87662a17dec6..c6b6d7dda517 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
@@ -287,7 +287,8 @@ static int __devinit jz4740_adc_probe(struct platform_device *pdev) | |||
287 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); | 287 | writeb(0xff, adc->base + JZ_REG_ADC_CTRL); |
288 | 288 | ||
289 | ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, | 289 | ret = mfd_add_devices(&pdev->dev, 0, jz4740_adc_cells, |
290 | ARRAY_SIZE(jz4740_adc_cells), mem_base, irq_base); | 290 | ARRAY_SIZE(jz4740_adc_cells), mem_base, |
291 | irq_base, NULL); | ||
291 | if (ret < 0) | 292 | if (ret < 0) |
292 | goto err_clk_put; | 293 | goto err_clk_put; |
293 | 294 | ||
diff --git a/drivers/mfd/lm3533-core.c b/drivers/mfd/lm3533-core.c index 0b2879b87fd9..24212f45b201 100644 --- a/drivers/mfd/lm3533-core.c +++ b/drivers/mfd/lm3533-core.c | |||
@@ -393,7 +393,8 @@ static int __devinit lm3533_device_als_init(struct lm3533 *lm3533) | |||
393 | lm3533_als_devs[0].platform_data = pdata->als; | 393 | lm3533_als_devs[0].platform_data = pdata->als; |
394 | lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); | 394 | lm3533_als_devs[0].pdata_size = sizeof(*pdata->als); |
395 | 395 | ||
396 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, 0); | 396 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL, |
397 | 0, NULL); | ||
397 | if (ret) { | 398 | if (ret) { |
398 | dev_err(lm3533->dev, "failed to add ALS device\n"); | 399 | dev_err(lm3533->dev, "failed to add ALS device\n"); |
399 | return ret; | 400 | return ret; |
@@ -422,7 +423,7 @@ static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533) | |||
422 | } | 423 | } |
423 | 424 | ||
424 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, | 425 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs, |
425 | pdata->num_backlights, NULL, 0); | 426 | pdata->num_backlights, NULL, 0, NULL); |
426 | if (ret) { | 427 | if (ret) { |
427 | dev_err(lm3533->dev, "failed to add backlight devices\n"); | 428 | dev_err(lm3533->dev, "failed to add backlight devices\n"); |
428 | return ret; | 429 | return ret; |
@@ -451,7 +452,7 @@ static int __devinit lm3533_device_led_init(struct lm3533 *lm3533) | |||
451 | } | 452 | } |
452 | 453 | ||
453 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, | 454 | ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs, |
454 | pdata->num_leds, NULL, 0); | 455 | pdata->num_leds, NULL, 0, NULL); |
455 | if (ret) { | 456 | if (ret) { |
456 | dev_err(lm3533->dev, "failed to add LED devices\n"); | 457 | dev_err(lm3533->dev, "failed to add LED devices\n"); |
457 | return ret; | 458 | return ret; |
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c index 027cc8f86132..092ad4b44b6d 100644 --- a/drivers/mfd/lpc_ich.c +++ b/drivers/mfd/lpc_ich.c | |||
@@ -750,7 +750,7 @@ gpe0_done: | |||
750 | 750 | ||
751 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); | 751 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id); |
752 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], | 752 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_GPIO], |
753 | 1, NULL, 0); | 753 | 1, NULL, 0, NULL); |
754 | 754 | ||
755 | gpio_done: | 755 | gpio_done: |
756 | if (acpi_conflict) | 756 | if (acpi_conflict) |
@@ -765,7 +765,6 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
765 | u32 base_addr_cfg; | 765 | u32 base_addr_cfg; |
766 | u32 base_addr; | 766 | u32 base_addr; |
767 | int ret; | 767 | int ret; |
768 | bool acpi_conflict = false; | ||
769 | struct resource *res; | 768 | struct resource *res; |
770 | 769 | ||
771 | /* Setup power management base register */ | 770 | /* Setup power management base register */ |
@@ -780,20 +779,11 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
780 | res = wdt_io_res(ICH_RES_IO_TCO); | 779 | res = wdt_io_res(ICH_RES_IO_TCO); |
781 | res->start = base_addr + ACPIBASE_TCO_OFF; | 780 | res->start = base_addr + ACPIBASE_TCO_OFF; |
782 | res->end = base_addr + ACPIBASE_TCO_END; | 781 | res->end = base_addr + ACPIBASE_TCO_END; |
783 | ret = acpi_check_resource_conflict(res); | ||
784 | if (ret) { | ||
785 | acpi_conflict = true; | ||
786 | goto wdt_done; | ||
787 | } | ||
788 | 782 | ||
789 | res = wdt_io_res(ICH_RES_IO_SMI); | 783 | res = wdt_io_res(ICH_RES_IO_SMI); |
790 | res->start = base_addr + ACPIBASE_SMI_OFF; | 784 | res->start = base_addr + ACPIBASE_SMI_OFF; |
791 | res->end = base_addr + ACPIBASE_SMI_END; | 785 | res->end = base_addr + ACPIBASE_SMI_END; |
792 | ret = acpi_check_resource_conflict(res); | 786 | |
793 | if (ret) { | ||
794 | acpi_conflict = true; | ||
795 | goto wdt_done; | ||
796 | } | ||
797 | lpc_ich_enable_acpi_space(dev); | 787 | lpc_ich_enable_acpi_space(dev); |
798 | 788 | ||
799 | /* | 789 | /* |
@@ -813,21 +803,13 @@ static int __devinit lpc_ich_init_wdt(struct pci_dev *dev, | |||
813 | res = wdt_mem_res(ICH_RES_MEM_GCS); | 803 | res = wdt_mem_res(ICH_RES_MEM_GCS); |
814 | res->start = base_addr + ACPIBASE_GCS_OFF; | 804 | res->start = base_addr + ACPIBASE_GCS_OFF; |
815 | res->end = base_addr + ACPIBASE_GCS_END; | 805 | res->end = base_addr + ACPIBASE_GCS_END; |
816 | ret = acpi_check_resource_conflict(res); | ||
817 | if (ret) { | ||
818 | acpi_conflict = true; | ||
819 | goto wdt_done; | ||
820 | } | ||
821 | } | 806 | } |
822 | 807 | ||
823 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); | 808 | lpc_ich_finalize_cell(&lpc_ich_cells[LPC_WDT], id); |
824 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], | 809 | ret = mfd_add_devices(&dev->dev, -1, &lpc_ich_cells[LPC_WDT], |
825 | 1, NULL, 0); | 810 | 1, NULL, 0, NULL); |
826 | 811 | ||
827 | wdt_done: | 812 | wdt_done: |
828 | if (acpi_conflict) | ||
829 | pr_warn("Resource conflict(s) found affecting %s\n", | ||
830 | lpc_ich_cells[LPC_WDT].name); | ||
831 | return ret; | 813 | return ret; |
832 | } | 814 | } |
833 | 815 | ||
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index 9f20abc5e393..f6b9c5c96b24 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c | |||
@@ -127,7 +127,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, | |||
127 | lpc_sch_cells[i].id = id->device; | 127 | lpc_sch_cells[i].id = id->device; |
128 | 128 | ||
129 | ret = mfd_add_devices(&dev->dev, 0, | 129 | ret = mfd_add_devices(&dev->dev, 0, |
130 | lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); | 130 | lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, |
131 | 0, NULL); | ||
131 | if (ret) | 132 | if (ret) |
132 | goto out_dev; | 133 | goto out_dev; |
133 | 134 | ||
@@ -153,7 +154,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, | |||
153 | tunnelcreek_cells[i].id = id->device; | 154 | tunnelcreek_cells[i].id = id->device; |
154 | 155 | ||
155 | ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, | 156 | ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, |
156 | ARRAY_SIZE(tunnelcreek_cells), NULL, 0); | 157 | ARRAY_SIZE(tunnelcreek_cells), NULL, |
158 | 0, NULL); | ||
157 | } | 159 | } |
158 | 160 | ||
159 | return ret; | 161 | return ret; |
diff --git a/drivers/mfd/max77686.c b/drivers/mfd/max77686.c index c03e12b51924..d9e24c849a00 100644 --- a/drivers/mfd/max77686.c +++ b/drivers/mfd/max77686.c | |||
@@ -126,7 +126,7 @@ static int max77686_i2c_probe(struct i2c_client *i2c, | |||
126 | max77686_irq_init(max77686); | 126 | max77686_irq_init(max77686); |
127 | 127 | ||
128 | ret = mfd_add_devices(max77686->dev, -1, max77686_devs, | 128 | ret = mfd_add_devices(max77686->dev, -1, max77686_devs, |
129 | ARRAY_SIZE(max77686_devs), NULL, 0); | 129 | ARRAY_SIZE(max77686_devs), NULL, 0, NULL); |
130 | 130 | ||
131 | if (ret < 0) | 131 | if (ret < 0) |
132 | goto err_mfd; | 132 | goto err_mfd; |
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c index 2b403569e0a6..1029d018c739 100644 --- a/drivers/mfd/max77693-irq.c +++ b/drivers/mfd/max77693-irq.c | |||
@@ -137,6 +137,9 @@ static void max77693_irq_mask(struct irq_data *data) | |||
137 | const struct max77693_irq_data *irq_data = | 137 | const struct max77693_irq_data *irq_data = |
138 | irq_to_max77693_irq(max77693, data->irq); | 138 | irq_to_max77693_irq(max77693, data->irq); |
139 | 139 | ||
140 | if (irq_data->group >= MAX77693_IRQ_GROUP_NR) | ||
141 | return; | ||
142 | |||
140 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) | 143 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) |
141 | max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; | 144 | max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask; |
142 | else | 145 | else |
@@ -149,6 +152,9 @@ static void max77693_irq_unmask(struct irq_data *data) | |||
149 | const struct max77693_irq_data *irq_data = | 152 | const struct max77693_irq_data *irq_data = |
150 | irq_to_max77693_irq(max77693, data->irq); | 153 | irq_to_max77693_irq(max77693, data->irq); |
151 | 154 | ||
155 | if (irq_data->group >= MAX77693_IRQ_GROUP_NR) | ||
156 | return; | ||
157 | |||
152 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) | 158 | if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3) |
153 | max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; | 159 | max77693->irq_masks_cur[irq_data->group] |= irq_data->mask; |
154 | else | 160 | else |
@@ -200,7 +206,7 @@ static irqreturn_t max77693_irq_thread(int irq, void *data) | |||
200 | 206 | ||
201 | if (irq_src & MAX77693_IRQSRC_MUIC) | 207 | if (irq_src & MAX77693_IRQSRC_MUIC) |
202 | /* MUIC INT1 ~ INT3 */ | 208 | /* MUIC INT1 ~ INT3 */ |
203 | max77693_bulk_read(max77693->regmap, MAX77693_MUIC_REG_INT1, | 209 | max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1, |
204 | MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); | 210 | MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]); |
205 | 211 | ||
206 | /* Apply masking */ | 212 | /* Apply masking */ |
@@ -255,7 +261,8 @@ int max77693_irq_init(struct max77693_dev *max77693) | |||
255 | { | 261 | { |
256 | struct irq_domain *domain; | 262 | struct irq_domain *domain; |
257 | int i; | 263 | int i; |
258 | int ret; | 264 | int ret = 0; |
265 | u8 intsrc_mask; | ||
259 | 266 | ||
260 | mutex_init(&max77693->irqlock); | 267 | mutex_init(&max77693->irqlock); |
261 | 268 | ||
@@ -287,19 +294,38 @@ int max77693_irq_init(struct max77693_dev *max77693) | |||
287 | &max77693_irq_domain_ops, max77693); | 294 | &max77693_irq_domain_ops, max77693); |
288 | if (!domain) { | 295 | if (!domain) { |
289 | dev_err(max77693->dev, "could not create irq domain\n"); | 296 | dev_err(max77693->dev, "could not create irq domain\n"); |
290 | return -ENODEV; | 297 | ret = -ENODEV; |
298 | goto err_irq; | ||
291 | } | 299 | } |
292 | max77693->irq_domain = domain; | 300 | max77693->irq_domain = domain; |
293 | 301 | ||
302 | /* Unmask max77693 interrupt */ | ||
303 | ret = max77693_read_reg(max77693->regmap, | ||
304 | MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask); | ||
305 | if (ret < 0) { | ||
306 | dev_err(max77693->dev, "fail to read PMIC register\n"); | ||
307 | goto err_irq; | ||
308 | } | ||
309 | |||
310 | intsrc_mask &= ~(MAX77693_IRQSRC_CHG); | ||
311 | intsrc_mask &= ~(MAX77693_IRQSRC_FLASH); | ||
312 | intsrc_mask &= ~(MAX77693_IRQSRC_MUIC); | ||
313 | ret = max77693_write_reg(max77693->regmap, | ||
314 | MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask); | ||
315 | if (ret < 0) { | ||
316 | dev_err(max77693->dev, "fail to write PMIC register\n"); | ||
317 | goto err_irq; | ||
318 | } | ||
319 | |||
294 | ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, | 320 | ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread, |
295 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | 321 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
296 | "max77693-irq", max77693); | 322 | "max77693-irq", max77693); |
297 | |||
298 | if (ret) | 323 | if (ret) |
299 | dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", | 324 | dev_err(max77693->dev, "Failed to request IRQ %d: %d\n", |
300 | max77693->irq, ret); | 325 | max77693->irq, ret); |
301 | 326 | ||
302 | return 0; | 327 | err_irq: |
328 | return ret; | ||
303 | } | 329 | } |
304 | 330 | ||
305 | void max77693_irq_exit(struct max77693_dev *max77693) | 331 | void max77693_irq_exit(struct max77693_dev *max77693) |
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c index a1811cb50ec7..cc5155e20494 100644 --- a/drivers/mfd/max77693.c +++ b/drivers/mfd/max77693.c | |||
@@ -152,6 +152,20 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
152 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); | 152 | max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); |
153 | i2c_set_clientdata(max77693->haptic, max77693); | 153 | i2c_set_clientdata(max77693->haptic, max77693); |
154 | 154 | ||
155 | /* | ||
156 | * Initialize register map for MUIC device because use regmap-muic | ||
157 | * instance of MUIC device when irq of max77693 is initialized | ||
158 | * before call max77693-muic probe() function. | ||
159 | */ | ||
160 | max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic, | ||
161 | &max77693_regmap_config); | ||
162 | if (IS_ERR(max77693->regmap_muic)) { | ||
163 | ret = PTR_ERR(max77693->regmap_muic); | ||
164 | dev_err(max77693->dev, | ||
165 | "failed to allocate register map: %d\n", ret); | ||
166 | goto err_regmap; | ||
167 | } | ||
168 | |||
155 | ret = max77693_irq_init(max77693); | 169 | ret = max77693_irq_init(max77693); |
156 | if (ret < 0) | 170 | if (ret < 0) |
157 | goto err_irq; | 171 | goto err_irq; |
@@ -159,7 +173,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c, | |||
159 | pm_runtime_set_active(max77693->dev); | 173 | pm_runtime_set_active(max77693->dev); |
160 | 174 | ||
161 | ret = mfd_add_devices(max77693->dev, -1, max77693_devs, | 175 | ret = mfd_add_devices(max77693->dev, -1, max77693_devs, |
162 | ARRAY_SIZE(max77693_devs), NULL, 0); | 176 | ARRAY_SIZE(max77693_devs), NULL, 0, NULL); |
163 | if (ret < 0) | 177 | if (ret < 0) |
164 | goto err_mfd; | 178 | goto err_mfd; |
165 | 179 | ||
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index 825a7f06d9ba..ee53757beca7 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -598,7 +598,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
598 | 598 | ||
599 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], | 599 | ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0], |
600 | ARRAY_SIZE(rtc_devs), | 600 | ARRAY_SIZE(rtc_devs), |
601 | &rtc_resources[0], chip->irq_base); | 601 | &rtc_resources[0], chip->irq_base, NULL); |
602 | if (ret < 0) { | 602 | if (ret < 0) { |
603 | dev_err(chip->dev, "Failed to add rtc subdev\n"); | 603 | dev_err(chip->dev, "Failed to add rtc subdev\n"); |
604 | goto out; | 604 | goto out; |
@@ -606,7 +606,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
606 | 606 | ||
607 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], | 607 | ret = mfd_add_devices(chip->dev, 0, &onkey_devs[0], |
608 | ARRAY_SIZE(onkey_devs), | 608 | ARRAY_SIZE(onkey_devs), |
609 | &onkey_resources[0], 0); | 609 | &onkey_resources[0], 0, NULL); |
610 | if (ret < 0) { | 610 | if (ret < 0) { |
611 | dev_err(chip->dev, "Failed to add onkey subdev\n"); | 611 | dev_err(chip->dev, "Failed to add onkey subdev\n"); |
612 | goto out_dev; | 612 | goto out_dev; |
@@ -615,7 +615,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
615 | if (pdata) { | 615 | if (pdata) { |
616 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], | 616 | ret = mfd_add_devices(chip->dev, 0, ®ulator_devs[0], |
617 | ARRAY_SIZE(regulator_devs), | 617 | ARRAY_SIZE(regulator_devs), |
618 | ®ulator_resources[0], 0); | 618 | ®ulator_resources[0], 0, NULL); |
619 | if (ret < 0) { | 619 | if (ret < 0) { |
620 | dev_err(chip->dev, "Failed to add regulator subdev\n"); | 620 | dev_err(chip->dev, "Failed to add regulator subdev\n"); |
621 | goto out_dev; | 621 | goto out_dev; |
@@ -625,7 +625,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
625 | if (pdata && pdata->backlight) { | 625 | if (pdata && pdata->backlight) { |
626 | ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], | 626 | ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0], |
627 | ARRAY_SIZE(backlight_devs), | 627 | ARRAY_SIZE(backlight_devs), |
628 | &backlight_resources[0], 0); | 628 | &backlight_resources[0], 0, NULL); |
629 | if (ret < 0) { | 629 | if (ret < 0) { |
630 | dev_err(chip->dev, "Failed to add backlight subdev\n"); | 630 | dev_err(chip->dev, "Failed to add backlight subdev\n"); |
631 | goto out_dev; | 631 | goto out_dev; |
@@ -635,7 +635,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
635 | if (pdata && pdata->power) { | 635 | if (pdata && pdata->power) { |
636 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], | 636 | ret = mfd_add_devices(chip->dev, 0, &power_devs[0], |
637 | ARRAY_SIZE(power_devs), | 637 | ARRAY_SIZE(power_devs), |
638 | &power_supply_resources[0], 0); | 638 | &power_supply_resources[0], 0, NULL); |
639 | if (ret < 0) { | 639 | if (ret < 0) { |
640 | dev_err(chip->dev, "Failed to add power supply " | 640 | dev_err(chip->dev, "Failed to add power supply " |
641 | "subdev\n"); | 641 | "subdev\n"); |
@@ -646,7 +646,7 @@ int __devinit max8925_device_init(struct max8925_chip *chip, | |||
646 | if (pdata && pdata->touch) { | 646 | if (pdata && pdata->touch) { |
647 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], | 647 | ret = mfd_add_devices(chip->dev, 0, &touch_devs[0], |
648 | ARRAY_SIZE(touch_devs), | 648 | ARRAY_SIZE(touch_devs), |
649 | &touch_resources[0], 0); | 649 | &touch_resources[0], 0, NULL); |
650 | if (ret < 0) { | 650 | if (ret < 0) { |
651 | dev_err(chip->dev, "Failed to add touch subdev\n"); | 651 | dev_err(chip->dev, "Failed to add touch subdev\n"); |
652 | goto out_dev; | 652 | goto out_dev; |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 10b629c245b6..f123517065ec 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -160,7 +160,7 @@ static int max8997_i2c_probe(struct i2c_client *i2c, | |||
160 | 160 | ||
161 | mfd_add_devices(max8997->dev, -1, max8997_devs, | 161 | mfd_add_devices(max8997->dev, -1, max8997_devs, |
162 | ARRAY_SIZE(max8997_devs), | 162 | ARRAY_SIZE(max8997_devs), |
163 | NULL, 0); | 163 | NULL, 0, NULL); |
164 | 164 | ||
165 | /* | 165 | /* |
166 | * TODO: enable others (flash, muic, rtc, battery, ...) and | 166 | * TODO: enable others (flash, muic, rtc, battery, ...) and |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index 6ef56d28c056..d7218cc90945 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -161,13 +161,13 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
161 | switch (id->driver_data) { | 161 | switch (id->driver_data) { |
162 | case TYPE_LP3974: | 162 | case TYPE_LP3974: |
163 | ret = mfd_add_devices(max8998->dev, -1, | 163 | ret = mfd_add_devices(max8998->dev, -1, |
164 | lp3974_devs, ARRAY_SIZE(lp3974_devs), | 164 | lp3974_devs, ARRAY_SIZE(lp3974_devs), |
165 | NULL, 0); | 165 | NULL, 0, NULL); |
166 | break; | 166 | break; |
167 | case TYPE_MAX8998: | 167 | case TYPE_MAX8998: |
168 | ret = mfd_add_devices(max8998->dev, -1, | 168 | ret = mfd_add_devices(max8998->dev, -1, |
169 | max8998_devs, ARRAY_SIZE(max8998_devs), | 169 | max8998_devs, ARRAY_SIZE(max8998_devs), |
170 | NULL, 0); | 170 | NULL, 0, NULL); |
171 | break; | 171 | break; |
172 | default: | 172 | default: |
173 | ret = -EINVAL; | 173 | ret = -EINVAL; |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index b801dc72f041..1ec79b54bd2f 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -612,7 +612,7 @@ static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx, | |||
612 | if (!cell.name) | 612 | if (!cell.name) |
613 | return -ENOMEM; | 613 | return -ENOMEM; |
614 | 614 | ||
615 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0); | 615 | return mfd_add_devices(mc13xxx->dev, -1, &cell, 1, NULL, 0, NULL); |
616 | } | 616 | } |
617 | 617 | ||
618 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | 618 | static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) |
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index c54e244ca0cf..f99d6299ec24 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
26 | #include <asm/mach-types.h> | 26 | #include <asm/mach-types.h> |
27 | #include <mach/mcp.h> | 27 | #include <linux/platform_data/mfd-mcp-sa11x0.h> |
28 | 28 | ||
29 | #define DRIVER_NAME "sa11x0-mcp" | 29 | #define DRIVER_NAME "sa11x0-mcp" |
30 | 30 | ||
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 0c3a01cde2f7..f8b77711ad2d 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -74,12 +74,11 @@ static int mfd_platform_add_cell(struct platform_device *pdev, | |||
74 | static int mfd_add_device(struct device *parent, int id, | 74 | static int mfd_add_device(struct device *parent, int id, |
75 | const struct mfd_cell *cell, | 75 | const struct mfd_cell *cell, |
76 | struct resource *mem_base, | 76 | struct resource *mem_base, |
77 | int irq_base) | 77 | int irq_base, struct irq_domain *domain) |
78 | { | 78 | { |
79 | struct resource *res; | 79 | struct resource *res; |
80 | struct platform_device *pdev; | 80 | struct platform_device *pdev; |
81 | struct device_node *np = NULL; | 81 | struct device_node *np = NULL; |
82 | struct irq_domain *domain = NULL; | ||
83 | int ret = -ENOMEM; | 82 | int ret = -ENOMEM; |
84 | int r; | 83 | int r; |
85 | 84 | ||
@@ -97,7 +96,6 @@ static int mfd_add_device(struct device *parent, int id, | |||
97 | for_each_child_of_node(parent->of_node, np) { | 96 | for_each_child_of_node(parent->of_node, np) { |
98 | if (of_device_is_compatible(np, cell->of_compatible)) { | 97 | if (of_device_is_compatible(np, cell->of_compatible)) { |
99 | pdev->dev.of_node = np; | 98 | pdev->dev.of_node = np; |
100 | domain = irq_find_host(parent->of_node); | ||
101 | break; | 99 | break; |
102 | } | 100 | } |
103 | } | 101 | } |
@@ -177,7 +175,7 @@ fail_alloc: | |||
177 | int mfd_add_devices(struct device *parent, int id, | 175 | int mfd_add_devices(struct device *parent, int id, |
178 | struct mfd_cell *cells, int n_devs, | 176 | struct mfd_cell *cells, int n_devs, |
179 | struct resource *mem_base, | 177 | struct resource *mem_base, |
180 | int irq_base) | 178 | int irq_base, struct irq_domain *domain) |
181 | { | 179 | { |
182 | int i; | 180 | int i; |
183 | int ret = 0; | 181 | int ret = 0; |
@@ -191,7 +189,8 @@ int mfd_add_devices(struct device *parent, int id, | |||
191 | for (i = 0; i < n_devs; i++) { | 189 | for (i = 0; i < n_devs; i++) { |
192 | atomic_set(&cnts[i], 0); | 190 | atomic_set(&cnts[i], 0); |
193 | cells[i].usage_count = &cnts[i]; | 191 | cells[i].usage_count = &cnts[i]; |
194 | ret = mfd_add_device(parent, id, cells + i, mem_base, irq_base); | 192 | ret = mfd_add_device(parent, id, cells + i, mem_base, |
193 | irq_base, domain); | ||
195 | if (ret) | 194 | if (ret) |
196 | break; | 195 | break; |
197 | } | 196 | } |
@@ -247,7 +246,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones) | |||
247 | for (i = 0; i < n_clones; i++) { | 246 | for (i = 0; i < n_clones; i++) { |
248 | cell_entry.name = clones[i]; | 247 | cell_entry.name = clones[i]; |
249 | /* don't give up if a single call fails; just report error */ | 248 | /* don't give up if a single call fails; just report error */ |
250 | if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0)) | 249 | if (mfd_add_device(pdev->dev.parent, -1, &cell_entry, NULL, 0, |
250 | NULL)) | ||
251 | dev_err(dev, "failed to create platform device '%s'\n", | 251 | dev_err(dev, "failed to create platform device '%s'\n", |
252 | clones[i]); | 252 | clones[i]); |
253 | } | 253 | } |
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index c4a69f193a1d..a345f9bb7b47 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c | |||
@@ -453,7 +453,8 @@ static int __devinit palmas_i2c_probe(struct i2c_client *i2c, | |||
453 | 453 | ||
454 | ret = mfd_add_devices(palmas->dev, -1, | 454 | ret = mfd_add_devices(palmas->dev, -1, |
455 | children, ARRAY_SIZE(palmas_children), | 455 | children, ARRAY_SIZE(palmas_children), |
456 | NULL, regmap_irq_chip_get_base(palmas->irq_data)); | 456 | NULL, regmap_irq_chip_get_base(palmas->irq_data), |
457 | NULL); | ||
457 | kfree(children); | 458 | kfree(children); |
458 | 459 | ||
459 | if (ret < 0) | 460 | if (ret < 0) |
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index cdc1df7fa0e9..3a8fa88567b1 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c | |||
@@ -289,7 +289,7 @@ static int __devinit rc5t583_i2c_probe(struct i2c_client *i2c, | |||
289 | } | 289 | } |
290 | 290 | ||
291 | ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, | 291 | ret = mfd_add_devices(rc5t583->dev, -1, rc5t583_subdevs, |
292 | ARRAY_SIZE(rc5t583_subdevs), NULL, 0); | 292 | ARRAY_SIZE(rc5t583_subdevs), NULL, 0, NULL); |
293 | if (ret) { | 293 | if (ret) { |
294 | dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret); | 294 | dev_err(&i2c->dev, "add mfd devices failed: %d\n", ret); |
295 | goto err_add_devs; | 295 | goto err_add_devs; |
diff --git a/drivers/mfd/rdc321x-southbridge.c b/drivers/mfd/rdc321x-southbridge.c index 685d61e431ad..0f70dce61160 100644 --- a/drivers/mfd/rdc321x-southbridge.c +++ b/drivers/mfd/rdc321x-southbridge.c | |||
@@ -87,7 +87,8 @@ static int __devinit rdc321x_sb_probe(struct pci_dev *pdev, | |||
87 | rdc321x_wdt_pdata.sb_pdev = pdev; | 87 | rdc321x_wdt_pdata.sb_pdev = pdev; |
88 | 88 | ||
89 | return mfd_add_devices(&pdev->dev, -1, | 89 | return mfd_add_devices(&pdev->dev, -1, |
90 | rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), NULL, 0); | 90 | rdc321x_sb_cells, ARRAY_SIZE(rdc321x_sb_cells), |
91 | NULL, 0, NULL); | ||
91 | } | 92 | } |
92 | 93 | ||
93 | static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) | 94 | static void __devexit rdc321x_sb_remove(struct pci_dev *pdev) |
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index 2988efde11eb..49d361a618d0 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -141,19 +141,19 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
141 | switch (sec_pmic->device_type) { | 141 | switch (sec_pmic->device_type) { |
142 | case S5M8751X: | 142 | case S5M8751X: |
143 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, | 143 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8751_devs, |
144 | ARRAY_SIZE(s5m8751_devs), NULL, 0); | 144 | ARRAY_SIZE(s5m8751_devs), NULL, 0, NULL); |
145 | break; | 145 | break; |
146 | case S5M8763X: | 146 | case S5M8763X: |
147 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, | 147 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8763_devs, |
148 | ARRAY_SIZE(s5m8763_devs), NULL, 0); | 148 | ARRAY_SIZE(s5m8763_devs), NULL, 0, NULL); |
149 | break; | 149 | break; |
150 | case S5M8767X: | 150 | case S5M8767X: |
151 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, | 151 | ret = mfd_add_devices(sec_pmic->dev, -1, s5m8767_devs, |
152 | ARRAY_SIZE(s5m8767_devs), NULL, 0); | 152 | ARRAY_SIZE(s5m8767_devs), NULL, 0, NULL); |
153 | break; | 153 | break; |
154 | case S2MPS11X: | 154 | case S2MPS11X: |
155 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, | 155 | ret = mfd_add_devices(sec_pmic->dev, -1, s2mps11_devs, |
156 | ARRAY_SIZE(s2mps11_devs), NULL, 0); | 156 | ARRAY_SIZE(s2mps11_devs), NULL, 0, NULL); |
157 | break; | 157 | break; |
158 | default: | 158 | default: |
159 | /* If this happens the probe function is problem */ | 159 | /* If this happens the probe function is problem */ |
diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index d31fed07aefb..d35da6820bea 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c | |||
@@ -407,7 +407,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev, | |||
407 | sta2x11_mfd_bar0, | 407 | sta2x11_mfd_bar0, |
408 | ARRAY_SIZE(sta2x11_mfd_bar0), | 408 | ARRAY_SIZE(sta2x11_mfd_bar0), |
409 | &pdev->resource[0], | 409 | &pdev->resource[0], |
410 | 0); | 410 | 0, NULL); |
411 | if (err) { | 411 | if (err) { |
412 | dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err); | 412 | dev_err(&pdev->dev, "mfd_add_devices[0] failed: %d\n", err); |
413 | goto err_disable; | 413 | goto err_disable; |
@@ -417,7 +417,7 @@ static int __devinit sta2x11_mfd_probe(struct pci_dev *pdev, | |||
417 | sta2x11_mfd_bar1, | 417 | sta2x11_mfd_bar1, |
418 | ARRAY_SIZE(sta2x11_mfd_bar1), | 418 | ARRAY_SIZE(sta2x11_mfd_bar1), |
419 | &pdev->resource[1], | 419 | &pdev->resource[1], |
420 | 0); | 420 | 0, NULL); |
421 | if (err) { | 421 | if (err) { |
422 | dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err); | 422 | dev_err(&pdev->dev, "mfd_add_devices[1] failed: %d\n", err); |
423 | goto err_disable; | 423 | goto err_disable; |
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 2dd8d49cb30b..c94f521f392c 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -962,7 +962,7 @@ static int __devinit stmpe_add_device(struct stmpe *stmpe, | |||
962 | struct mfd_cell *cell, int irq) | 962 | struct mfd_cell *cell, int irq) |
963 | { | 963 | { |
964 | return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, | 964 | return mfd_add_devices(stmpe->dev, stmpe->pdata->id, cell, 1, |
965 | NULL, stmpe->irq_base + irq); | 965 | NULL, stmpe->irq_base + irq, NULL); |
966 | } | 966 | } |
967 | 967 | ||
968 | static int __devinit stmpe_devices_init(struct stmpe *stmpe) | 968 | static int __devinit stmpe_devices_init(struct stmpe *stmpe) |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 2d9e8799e733..b32940ec9034 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -388,7 +388,7 @@ static int t7l66xb_probe(struct platform_device *dev) | |||
388 | 388 | ||
389 | ret = mfd_add_devices(&dev->dev, dev->id, | 389 | ret = mfd_add_devices(&dev->dev, dev->id, |
390 | t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), | 390 | t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), |
391 | iomem, t7l66xb->irq_base); | 391 | iomem, t7l66xb->irq_base, NULL); |
392 | 392 | ||
393 | if (!ret) | 393 | if (!ret) |
394 | return 0; | 394 | return 0; |
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c index 048bf0532a09..b56ba6b43294 100644 --- a/drivers/mfd/tc3589x.c +++ b/drivers/mfd/tc3589x.c | |||
@@ -262,8 +262,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) | |||
262 | 262 | ||
263 | if (blocks & TC3589x_BLOCK_GPIO) { | 263 | if (blocks & TC3589x_BLOCK_GPIO) { |
264 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, | 264 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio, |
265 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, | 265 | ARRAY_SIZE(tc3589x_dev_gpio), NULL, |
266 | tc3589x->irq_base); | 266 | tc3589x->irq_base, NULL); |
267 | if (ret) { | 267 | if (ret) { |
268 | dev_err(tc3589x->dev, "failed to add gpio child\n"); | 268 | dev_err(tc3589x->dev, "failed to add gpio child\n"); |
269 | return ret; | 269 | return ret; |
@@ -273,8 +273,8 @@ static int __devinit tc3589x_device_init(struct tc3589x *tc3589x) | |||
273 | 273 | ||
274 | if (blocks & TC3589x_BLOCK_KEYPAD) { | 274 | if (blocks & TC3589x_BLOCK_KEYPAD) { |
275 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, | 275 | ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad, |
276 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, | 276 | ARRAY_SIZE(tc3589x_dev_keypad), NULL, |
277 | tc3589x->irq_base); | 277 | tc3589x->irq_base, NULL); |
278 | if (ret) { | 278 | if (ret) { |
279 | dev_err(tc3589x->dev, "failed to keypad child\n"); | 279 | dev_err(tc3589x->dev, "failed to keypad child\n"); |
280 | return ret; | 280 | return ret; |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index d20a284ad4ba..413c891102f8 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -192,7 +192,7 @@ static int __devinit tc6387xb_probe(struct platform_device *dev) | |||
192 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); | 192 | printk(KERN_INFO "Toshiba tc6387xb initialised\n"); |
193 | 193 | ||
194 | ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, | 194 | ret = mfd_add_devices(&dev->dev, dev->id, tc6387xb_cells, |
195 | ARRAY_SIZE(tc6387xb_cells), iomem, irq); | 195 | ARRAY_SIZE(tc6387xb_cells), iomem, irq, NULL); |
196 | 196 | ||
197 | if (!ret) | 197 | if (!ret) |
198 | return 0; | 198 | return 0; |
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c index 9612264f0e6d..dcab026fcbb2 100644 --- a/drivers/mfd/tc6393xb.c +++ b/drivers/mfd/tc6393xb.c | |||
@@ -700,8 +700,8 @@ static int __devinit tc6393xb_probe(struct platform_device *dev) | |||
700 | tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); | 700 | tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data); |
701 | 701 | ||
702 | ret = mfd_add_devices(&dev->dev, dev->id, | 702 | ret = mfd_add_devices(&dev->dev, dev->id, |
703 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), | 703 | tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells), |
704 | iomem, tcpd->irq_base); | 704 | iomem, tcpd->irq_base, NULL); |
705 | 705 | ||
706 | if (!ret) | 706 | if (!ret) |
707 | return 0; | 707 | return 0; |
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c index 4fb0e6c8e8fe..7c3675a74f93 100644 --- a/drivers/mfd/ti-ssp.c +++ b/drivers/mfd/ti-ssp.c | |||
@@ -412,7 +412,7 @@ static int __devinit ti_ssp_probe(struct platform_device *pdev) | |||
412 | cells[id].data_size = data->pdata_size; | 412 | cells[id].data_size = data->pdata_size; |
413 | } | 413 | } |
414 | 414 | ||
415 | error = mfd_add_devices(dev, 0, cells, 2, NULL, 0); | 415 | error = mfd_add_devices(dev, 0, cells, 2, NULL, 0, NULL); |
416 | if (error < 0) { | 416 | if (error < 0) { |
417 | dev_err(dev, "cannot add mfd cells\n"); | 417 | dev_err(dev, "cannot add mfd cells\n"); |
418 | goto error_enable; | 418 | goto error_enable; |
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index a447f4ec11fb..cccc626c83c8 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c | |||
@@ -757,25 +757,25 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
757 | err = mfd_add_devices(&dev->dev, -1, | 757 | err = mfd_add_devices(&dev->dev, -1, |
758 | timberdale_cells_bar0_cfg0, | 758 | timberdale_cells_bar0_cfg0, |
759 | ARRAY_SIZE(timberdale_cells_bar0_cfg0), | 759 | ARRAY_SIZE(timberdale_cells_bar0_cfg0), |
760 | &dev->resource[0], msix_entries[0].vector); | 760 | &dev->resource[0], msix_entries[0].vector, NULL); |
761 | break; | 761 | break; |
762 | case TIMB_HW_VER1: | 762 | case TIMB_HW_VER1: |
763 | err = mfd_add_devices(&dev->dev, -1, | 763 | err = mfd_add_devices(&dev->dev, -1, |
764 | timberdale_cells_bar0_cfg1, | 764 | timberdale_cells_bar0_cfg1, |
765 | ARRAY_SIZE(timberdale_cells_bar0_cfg1), | 765 | ARRAY_SIZE(timberdale_cells_bar0_cfg1), |
766 | &dev->resource[0], msix_entries[0].vector); | 766 | &dev->resource[0], msix_entries[0].vector, NULL); |
767 | break; | 767 | break; |
768 | case TIMB_HW_VER2: | 768 | case TIMB_HW_VER2: |
769 | err = mfd_add_devices(&dev->dev, -1, | 769 | err = mfd_add_devices(&dev->dev, -1, |
770 | timberdale_cells_bar0_cfg2, | 770 | timberdale_cells_bar0_cfg2, |
771 | ARRAY_SIZE(timberdale_cells_bar0_cfg2), | 771 | ARRAY_SIZE(timberdale_cells_bar0_cfg2), |
772 | &dev->resource[0], msix_entries[0].vector); | 772 | &dev->resource[0], msix_entries[0].vector, NULL); |
773 | break; | 773 | break; |
774 | case TIMB_HW_VER3: | 774 | case TIMB_HW_VER3: |
775 | err = mfd_add_devices(&dev->dev, -1, | 775 | err = mfd_add_devices(&dev->dev, -1, |
776 | timberdale_cells_bar0_cfg3, | 776 | timberdale_cells_bar0_cfg3, |
777 | ARRAY_SIZE(timberdale_cells_bar0_cfg3), | 777 | ARRAY_SIZE(timberdale_cells_bar0_cfg3), |
778 | &dev->resource[0], msix_entries[0].vector); | 778 | &dev->resource[0], msix_entries[0].vector, NULL); |
779 | break; | 779 | break; |
780 | default: | 780 | default: |
781 | dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", | 781 | dev_err(&dev->dev, "Uknown IP setup: %d.%d.%d\n", |
@@ -792,7 +792,7 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
792 | 792 | ||
793 | err = mfd_add_devices(&dev->dev, 0, | 793 | err = mfd_add_devices(&dev->dev, 0, |
794 | timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), | 794 | timberdale_cells_bar1, ARRAY_SIZE(timberdale_cells_bar1), |
795 | &dev->resource[1], msix_entries[0].vector); | 795 | &dev->resource[1], msix_entries[0].vector, NULL); |
796 | if (err) { | 796 | if (err) { |
797 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); | 797 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); |
798 | goto err_mfd2; | 798 | goto err_mfd2; |
@@ -803,7 +803,7 @@ static int __devinit timb_probe(struct pci_dev *dev, | |||
803 | ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) { | 803 | ((priv->fw.config & TIMB_HW_VER_MASK) == TIMB_HW_VER3)) { |
804 | err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2, | 804 | err = mfd_add_devices(&dev->dev, 1, timberdale_cells_bar2, |
805 | ARRAY_SIZE(timberdale_cells_bar2), | 805 | ARRAY_SIZE(timberdale_cells_bar2), |
806 | &dev->resource[2], msix_entries[0].vector); | 806 | &dev->resource[2], msix_entries[0].vector, NULL); |
807 | if (err) { | 807 | if (err) { |
808 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); | 808 | dev_err(&dev->dev, "mfd_add_devices failed: %d\n", err); |
809 | goto err_mfd2; | 809 | goto err_mfd2; |
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c index a293b978e27c..14051bdc714b 100644 --- a/drivers/mfd/tps6105x.c +++ b/drivers/mfd/tps6105x.c | |||
@@ -188,7 +188,7 @@ static int __devinit tps6105x_probe(struct i2c_client *client, | |||
188 | } | 188 | } |
189 | 189 | ||
190 | ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, | 190 | ret = mfd_add_devices(&client->dev, 0, tps6105x_cells, |
191 | ARRAY_SIZE(tps6105x_cells), NULL, 0); | 191 | ARRAY_SIZE(tps6105x_cells), NULL, 0, NULL); |
192 | if (ret) | 192 | if (ret) |
193 | goto fail; | 193 | goto fail; |
194 | 194 | ||
diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index 33ba7723c967..1b203499c744 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c | |||
@@ -100,7 +100,7 @@ static int tps6507x_i2c_probe(struct i2c_client *i2c, | |||
100 | 100 | ||
101 | ret = mfd_add_devices(tps6507x->dev, -1, | 101 | ret = mfd_add_devices(tps6507x->dev, -1, |
102 | tps6507x_devs, ARRAY_SIZE(tps6507x_devs), | 102 | tps6507x_devs, ARRAY_SIZE(tps6507x_devs), |
103 | NULL, 0); | 103 | NULL, 0, NULL); |
104 | 104 | ||
105 | if (ret < 0) | 105 | if (ret < 0) |
106 | goto err; | 106 | goto err; |
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index 80e24f4b47bf..50fd87c87a1c 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c | |||
@@ -292,7 +292,7 @@ static int __devinit tps65090_i2c_probe(struct i2c_client *client, | |||
292 | } | 292 | } |
293 | 293 | ||
294 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, | 294 | ret = mfd_add_devices(tps65090->dev, -1, tps65090s, |
295 | ARRAY_SIZE(tps65090s), NULL, 0); | 295 | ARRAY_SIZE(tps65090s), NULL, 0, NULL); |
296 | if (ret) { | 296 | if (ret) { |
297 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", | 297 | dev_err(&client->dev, "add mfd devices failed with err: %d\n", |
298 | ret); | 298 | ret); |
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c index 61c097a98f5d..a95e9421b735 100644 --- a/drivers/mfd/tps65217.c +++ b/drivers/mfd/tps65217.c | |||
@@ -24,11 +24,18 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/regmap.h> | 25 | #include <linux/regmap.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/regulator/of_regulator.h> | 27 | #include <linux/of.h> |
28 | #include <linux/of_device.h> | ||
28 | 29 | ||
29 | #include <linux/mfd/core.h> | 30 | #include <linux/mfd/core.h> |
30 | #include <linux/mfd/tps65217.h> | 31 | #include <linux/mfd/tps65217.h> |
31 | 32 | ||
33 | static struct mfd_cell tps65217s[] = { | ||
34 | { | ||
35 | .name = "tps65217-pmic", | ||
36 | }, | ||
37 | }; | ||
38 | |||
32 | /** | 39 | /** |
33 | * tps65217_reg_read: Read a single tps65217 register. | 40 | * tps65217_reg_read: Read a single tps65217 register. |
34 | * | 41 | * |
@@ -133,83 +140,48 @@ int tps65217_clear_bits(struct tps65217 *tps, unsigned int reg, | |||
133 | } | 140 | } |
134 | EXPORT_SYMBOL_GPL(tps65217_clear_bits); | 141 | EXPORT_SYMBOL_GPL(tps65217_clear_bits); |
135 | 142 | ||
136 | #ifdef CONFIG_OF | ||
137 | static struct of_regulator_match reg_matches[] = { | ||
138 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
139 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
140 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
141 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
142 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
143 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
144 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
145 | }; | ||
146 | |||
147 | static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) | ||
148 | { | ||
149 | struct device_node *node = client->dev.of_node; | ||
150 | struct tps65217_board *pdata; | ||
151 | struct device_node *regs; | ||
152 | int count = ARRAY_SIZE(reg_matches); | ||
153 | int ret, i; | ||
154 | |||
155 | regs = of_find_node_by_name(node, "regulators"); | ||
156 | if (!regs) | ||
157 | return NULL; | ||
158 | |||
159 | ret = of_regulator_match(&client->dev, regs, reg_matches, count); | ||
160 | of_node_put(regs); | ||
161 | if ((ret < 0) || (ret > count)) | ||
162 | return NULL; | ||
163 | |||
164 | count = ret; | ||
165 | pdata = devm_kzalloc(&client->dev, count * sizeof(*pdata), GFP_KERNEL); | ||
166 | if (!pdata) | ||
167 | return NULL; | ||
168 | |||
169 | for (i = 0; i < count; i++) { | ||
170 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | ||
171 | continue; | ||
172 | |||
173 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
174 | pdata->of_node[i] = reg_matches[i].of_node; | ||
175 | } | ||
176 | |||
177 | return pdata; | ||
178 | } | ||
179 | |||
180 | static struct of_device_id tps65217_of_match[] = { | ||
181 | { .compatible = "ti,tps65217", }, | ||
182 | { }, | ||
183 | }; | ||
184 | #else | ||
185 | static struct tps65217_board *tps65217_parse_dt(struct i2c_client *client) | ||
186 | { | ||
187 | return NULL; | ||
188 | } | ||
189 | #endif | ||
190 | |||
191 | static struct regmap_config tps65217_regmap_config = { | 143 | static struct regmap_config tps65217_regmap_config = { |
192 | .reg_bits = 8, | 144 | .reg_bits = 8, |
193 | .val_bits = 8, | 145 | .val_bits = 8, |
194 | }; | 146 | }; |
195 | 147 | ||
148 | static const struct of_device_id tps65217_of_match[] = { | ||
149 | { .compatible = "ti,tps65217", .data = (void *)TPS65217 }, | ||
150 | { /* sentinel */ }, | ||
151 | }; | ||
152 | |||
196 | static int __devinit tps65217_probe(struct i2c_client *client, | 153 | static int __devinit tps65217_probe(struct i2c_client *client, |
197 | const struct i2c_device_id *ids) | 154 | const struct i2c_device_id *ids) |
198 | { | 155 | { |
199 | struct tps65217 *tps; | 156 | struct tps65217 *tps; |
200 | struct regulator_init_data *reg_data; | ||
201 | struct tps65217_board *pdata = client->dev.platform_data; | ||
202 | int i, ret; | ||
203 | unsigned int version; | 157 | unsigned int version; |
158 | unsigned int chip_id = ids->driver_data; | ||
159 | const struct of_device_id *match; | ||
160 | int ret; | ||
204 | 161 | ||
205 | if (!pdata && client->dev.of_node) | 162 | if (client->dev.of_node) { |
206 | pdata = tps65217_parse_dt(client); | 163 | match = of_match_device(tps65217_of_match, &client->dev); |
164 | if (!match) { | ||
165 | dev_err(&client->dev, | ||
166 | "Failed to find matching dt id\n"); | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | chip_id = (unsigned int)match->data; | ||
170 | } | ||
171 | |||
172 | if (!chip_id) { | ||
173 | dev_err(&client->dev, "id is null.\n"); | ||
174 | return -ENODEV; | ||
175 | } | ||
207 | 176 | ||
208 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); | 177 | tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); |
209 | if (!tps) | 178 | if (!tps) |
210 | return -ENOMEM; | 179 | return -ENOMEM; |
211 | 180 | ||
212 | tps->pdata = pdata; | 181 | i2c_set_clientdata(client, tps); |
182 | tps->dev = &client->dev; | ||
183 | tps->id = chip_id; | ||
184 | |||
213 | tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config); | 185 | tps->regmap = devm_regmap_init_i2c(client, &tps65217_regmap_config); |
214 | if (IS_ERR(tps->regmap)) { | 186 | if (IS_ERR(tps->regmap)) { |
215 | ret = PTR_ERR(tps->regmap); | 187 | ret = PTR_ERR(tps->regmap); |
@@ -218,8 +190,12 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
218 | return ret; | 190 | return ret; |
219 | } | 191 | } |
220 | 192 | ||
221 | i2c_set_clientdata(client, tps); | 193 | ret = mfd_add_devices(tps->dev, -1, tps65217s, |
222 | tps->dev = &client->dev; | 194 | ARRAY_SIZE(tps65217s), NULL, 0, NULL); |
195 | if (ret < 0) { | ||
196 | dev_err(tps->dev, "mfd_add_devices failed: %d\n", ret); | ||
197 | return ret; | ||
198 | } | ||
223 | 199 | ||
224 | ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); | 200 | ret = tps65217_reg_read(tps, TPS65217_REG_CHIPID, &version); |
225 | if (ret < 0) { | 201 | if (ret < 0) { |
@@ -232,41 +208,21 @@ static int __devinit tps65217_probe(struct i2c_client *client, | |||
232 | (version & TPS65217_CHIPID_CHIP_MASK) >> 4, | 208 | (version & TPS65217_CHIPID_CHIP_MASK) >> 4, |
233 | version & TPS65217_CHIPID_REV_MASK); | 209 | version & TPS65217_CHIPID_REV_MASK); |
234 | 210 | ||
235 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | ||
236 | struct platform_device *pdev; | ||
237 | |||
238 | pdev = platform_device_alloc("tps65217-pmic", i); | ||
239 | if (!pdev) { | ||
240 | dev_err(tps->dev, "Cannot create regulator %d\n", i); | ||
241 | continue; | ||
242 | } | ||
243 | |||
244 | pdev->dev.parent = tps->dev; | ||
245 | pdev->dev.of_node = pdata->of_node[i]; | ||
246 | reg_data = pdata->tps65217_init_data[i]; | ||
247 | platform_device_add_data(pdev, reg_data, sizeof(*reg_data)); | ||
248 | tps->regulator_pdev[i] = pdev; | ||
249 | |||
250 | platform_device_add(pdev); | ||
251 | } | ||
252 | |||
253 | return 0; | 211 | return 0; |
254 | } | 212 | } |
255 | 213 | ||
256 | static int __devexit tps65217_remove(struct i2c_client *client) | 214 | static int __devexit tps65217_remove(struct i2c_client *client) |
257 | { | 215 | { |
258 | struct tps65217 *tps = i2c_get_clientdata(client); | 216 | struct tps65217 *tps = i2c_get_clientdata(client); |
259 | int i; | ||
260 | 217 | ||
261 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) | 218 | mfd_remove_devices(tps->dev); |
262 | platform_device_unregister(tps->regulator_pdev[i]); | ||
263 | 219 | ||
264 | return 0; | 220 | return 0; |
265 | } | 221 | } |
266 | 222 | ||
267 | static const struct i2c_device_id tps65217_id_table[] = { | 223 | static const struct i2c_device_id tps65217_id_table[] = { |
268 | {"tps65217", 0xF0}, | 224 | {"tps65217", TPS65217}, |
269 | {/* end of list */} | 225 | { /* sentinel */ } |
270 | }; | 226 | }; |
271 | MODULE_DEVICE_TABLE(i2c, tps65217_id_table); | 227 | MODULE_DEVICE_TABLE(i2c, tps65217_id_table); |
272 | 228 | ||
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c index 353c34812120..345960ca2fd8 100644 --- a/drivers/mfd/tps6586x.c +++ b/drivers/mfd/tps6586x.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
26 | #include <linux/regmap.h> | 26 | #include <linux/regmap.h> |
27 | #include <linux/regulator/of_regulator.h> | 27 | #include <linux/regulator/of_regulator.h> |
28 | #include <linux/regulator/machine.h> | ||
28 | 29 | ||
29 | #include <linux/mfd/core.h> | 30 | #include <linux/mfd/core.h> |
30 | #include <linux/mfd/tps6586x.h> | 31 | #include <linux/mfd/tps6586x.h> |
@@ -346,6 +347,7 @@ failed: | |||
346 | 347 | ||
347 | #ifdef CONFIG_OF | 348 | #ifdef CONFIG_OF |
348 | static struct of_regulator_match tps6586x_matches[] = { | 349 | static struct of_regulator_match tps6586x_matches[] = { |
350 | { .name = "sys", .driver_data = (void *)TPS6586X_ID_SYS }, | ||
349 | { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, | 351 | { .name = "sm0", .driver_data = (void *)TPS6586X_ID_SM_0 }, |
350 | { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, | 352 | { .name = "sm1", .driver_data = (void *)TPS6586X_ID_SM_1 }, |
351 | { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, | 353 | { .name = "sm2", .driver_data = (void *)TPS6586X_ID_SM_2 }, |
@@ -369,6 +371,7 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien | |||
369 | struct tps6586x_platform_data *pdata; | 371 | struct tps6586x_platform_data *pdata; |
370 | struct tps6586x_subdev_info *devs; | 372 | struct tps6586x_subdev_info *devs; |
371 | struct device_node *regs; | 373 | struct device_node *regs; |
374 | const char *sys_rail_name = NULL; | ||
372 | unsigned int count; | 375 | unsigned int count; |
373 | unsigned int i, j; | 376 | unsigned int i, j; |
374 | int err; | 377 | int err; |
@@ -391,12 +394,22 @@ static struct tps6586x_platform_data *tps6586x_parse_dt(struct i2c_client *clien | |||
391 | return NULL; | 394 | return NULL; |
392 | 395 | ||
393 | for (i = 0, j = 0; i < num && j < count; i++) { | 396 | for (i = 0, j = 0; i < num && j < count; i++) { |
397 | struct regulator_init_data *reg_idata; | ||
398 | |||
394 | if (!tps6586x_matches[i].init_data) | 399 | if (!tps6586x_matches[i].init_data) |
395 | continue; | 400 | continue; |
396 | 401 | ||
402 | reg_idata = tps6586x_matches[i].init_data; | ||
397 | devs[j].name = "tps6586x-regulator"; | 403 | devs[j].name = "tps6586x-regulator"; |
398 | devs[j].platform_data = tps6586x_matches[i].init_data; | 404 | devs[j].platform_data = tps6586x_matches[i].init_data; |
399 | devs[j].id = (int)tps6586x_matches[i].driver_data; | 405 | devs[j].id = (int)tps6586x_matches[i].driver_data; |
406 | if (devs[j].id == TPS6586X_ID_SYS) | ||
407 | sys_rail_name = reg_idata->constraints.name; | ||
408 | |||
409 | if ((devs[j].id == TPS6586X_ID_LDO_5) || | ||
410 | (devs[j].id == TPS6586X_ID_LDO_RTC)) | ||
411 | reg_idata->supply_regulator = sys_rail_name; | ||
412 | |||
400 | devs[j].of_node = tps6586x_matches[i].of_node; | 413 | devs[j].of_node = tps6586x_matches[i].of_node; |
401 | j++; | 414 | j++; |
402 | } | 415 | } |
@@ -493,7 +506,8 @@ static int __devinit tps6586x_i2c_probe(struct i2c_client *client, | |||
493 | } | 506 | } |
494 | 507 | ||
495 | ret = mfd_add_devices(tps6586x->dev, -1, | 508 | ret = mfd_add_devices(tps6586x->dev, -1, |
496 | tps6586x_cell, ARRAY_SIZE(tps6586x_cell), NULL, 0); | 509 | tps6586x_cell, ARRAY_SIZE(tps6586x_cell), |
510 | NULL, 0, NULL); | ||
497 | if (ret < 0) { | 511 | if (ret < 0) { |
498 | dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret); | 512 | dev_err(&client->dev, "mfd_add_devices failed: %d\n", ret); |
499 | goto err_mfd_add; | 513 | goto err_mfd_add; |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 1c563792c777..d3ce4d569deb 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -254,7 +254,7 @@ static __devinit int tps65910_i2c_probe(struct i2c_client *i2c, | |||
254 | 254 | ||
255 | ret = mfd_add_devices(tps65910->dev, -1, | 255 | ret = mfd_add_devices(tps65910->dev, -1, |
256 | tps65910s, ARRAY_SIZE(tps65910s), | 256 | tps65910s, ARRAY_SIZE(tps65910s), |
257 | NULL, 0); | 257 | NULL, 0, NULL); |
258 | if (ret < 0) { | 258 | if (ret < 0) { |
259 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); | 259 | dev_err(&i2c->dev, "mfd_add_devices failed: %d\n", ret); |
260 | return ret; | 260 | return ret; |
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 74fd8cb5f372..4658b5bdcd84 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c | |||
@@ -146,7 +146,7 @@ int tps65912_device_init(struct tps65912 *tps65912) | |||
146 | 146 | ||
147 | ret = mfd_add_devices(tps65912->dev, -1, | 147 | ret = mfd_add_devices(tps65912->dev, -1, |
148 | tps65912s, ARRAY_SIZE(tps65912s), | 148 | tps65912s, ARRAY_SIZE(tps65912s), |
149 | NULL, 0); | 149 | NULL, 0, NULL); |
150 | if (ret < 0) | 150 | if (ret < 0) |
151 | goto err; | 151 | goto err; |
152 | 152 | ||
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 1c32afed28aa..9d3a0bc1a65f 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -1132,12 +1132,7 @@ static void clocks_init(struct device *dev, | |||
1132 | u32 rate; | 1132 | u32 rate; |
1133 | u8 ctrl = HFCLK_FREQ_26_MHZ; | 1133 | u8 ctrl = HFCLK_FREQ_26_MHZ; |
1134 | 1134 | ||
1135 | #if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3) | 1135 | osc = clk_get(dev, "fck"); |
1136 | if (cpu_is_omap2430()) | ||
1137 | osc = clk_get(dev, "osc_ck"); | ||
1138 | else | ||
1139 | osc = clk_get(dev, "osc_sys_ck"); | ||
1140 | |||
1141 | if (IS_ERR(osc)) { | 1136 | if (IS_ERR(osc)) { |
1142 | printk(KERN_WARNING "Skipping twl internal clock init and " | 1137 | printk(KERN_WARNING "Skipping twl internal clock init and " |
1143 | "using bootloader value (unknown osc rate)\n"); | 1138 | "using bootloader value (unknown osc rate)\n"); |
@@ -1147,18 +1142,6 @@ static void clocks_init(struct device *dev, | |||
1147 | rate = clk_get_rate(osc); | 1142 | rate = clk_get_rate(osc); |
1148 | clk_put(osc); | 1143 | clk_put(osc); |
1149 | 1144 | ||
1150 | #else | ||
1151 | /* REVISIT for non-OMAP systems, pass the clock rate from | ||
1152 | * board init code, using platform_data. | ||
1153 | */ | ||
1154 | osc = ERR_PTR(-EIO); | ||
1155 | |||
1156 | printk(KERN_WARNING "Skipping twl internal clock init and " | ||
1157 | "using bootloader value (unknown osc rate)\n"); | ||
1158 | |||
1159 | return; | ||
1160 | #endif | ||
1161 | |||
1162 | switch (rate) { | 1145 | switch (rate) { |
1163 | case 19200000: | 1146 | case 19200000: |
1164 | ctrl = HFCLK_FREQ_19p2_MHZ; | 1147 | ctrl = HFCLK_FREQ_19p2_MHZ; |
@@ -1220,10 +1203,23 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1220 | { | 1203 | { |
1221 | struct twl4030_platform_data *pdata = client->dev.platform_data; | 1204 | struct twl4030_platform_data *pdata = client->dev.platform_data; |
1222 | struct device_node *node = client->dev.of_node; | 1205 | struct device_node *node = client->dev.of_node; |
1206 | struct platform_device *pdev; | ||
1223 | int irq_base = 0; | 1207 | int irq_base = 0; |
1224 | int status; | 1208 | int status; |
1225 | unsigned i, num_slaves; | 1209 | unsigned i, num_slaves; |
1226 | 1210 | ||
1211 | pdev = platform_device_alloc(DRIVER_NAME, -1); | ||
1212 | if (!pdev) { | ||
1213 | dev_err(&client->dev, "can't alloc pdev\n"); | ||
1214 | return -ENOMEM; | ||
1215 | } | ||
1216 | |||
1217 | status = platform_device_add(pdev); | ||
1218 | if (status) { | ||
1219 | platform_device_put(pdev); | ||
1220 | return status; | ||
1221 | } | ||
1222 | |||
1227 | if (node && !pdata) { | 1223 | if (node && !pdata) { |
1228 | /* | 1224 | /* |
1229 | * XXX: Temporary pdata until the information is correctly | 1225 | * XXX: Temporary pdata until the information is correctly |
@@ -1232,23 +1228,30 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1232 | pdata = devm_kzalloc(&client->dev, | 1228 | pdata = devm_kzalloc(&client->dev, |
1233 | sizeof(struct twl4030_platform_data), | 1229 | sizeof(struct twl4030_platform_data), |
1234 | GFP_KERNEL); | 1230 | GFP_KERNEL); |
1235 | if (!pdata) | 1231 | if (!pdata) { |
1236 | return -ENOMEM; | 1232 | status = -ENOMEM; |
1233 | goto free; | ||
1234 | } | ||
1237 | } | 1235 | } |
1238 | 1236 | ||
1239 | if (!pdata) { | 1237 | if (!pdata) { |
1240 | dev_dbg(&client->dev, "no platform data?\n"); | 1238 | dev_dbg(&client->dev, "no platform data?\n"); |
1241 | return -EINVAL; | 1239 | status = -EINVAL; |
1240 | goto free; | ||
1242 | } | 1241 | } |
1243 | 1242 | ||
1243 | platform_set_drvdata(pdev, pdata); | ||
1244 | |||
1244 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { | 1245 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { |
1245 | dev_dbg(&client->dev, "can't talk I2C?\n"); | 1246 | dev_dbg(&client->dev, "can't talk I2C?\n"); |
1246 | return -EIO; | 1247 | status = -EIO; |
1248 | goto free; | ||
1247 | } | 1249 | } |
1248 | 1250 | ||
1249 | if (inuse) { | 1251 | if (inuse) { |
1250 | dev_dbg(&client->dev, "driver is already in use\n"); | 1252 | dev_dbg(&client->dev, "driver is already in use\n"); |
1251 | return -EBUSY; | 1253 | status = -EBUSY; |
1254 | goto free; | ||
1252 | } | 1255 | } |
1253 | 1256 | ||
1254 | if ((id->driver_data) & TWL6030_CLASS) { | 1257 | if ((id->driver_data) & TWL6030_CLASS) { |
@@ -1283,7 +1286,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1283 | inuse = true; | 1286 | inuse = true; |
1284 | 1287 | ||
1285 | /* setup clock framework */ | 1288 | /* setup clock framework */ |
1286 | clocks_init(&client->dev, pdata->clock); | 1289 | clocks_init(&pdev->dev, pdata->clock); |
1287 | 1290 | ||
1288 | /* read TWL IDCODE Register */ | 1291 | /* read TWL IDCODE Register */ |
1289 | if (twl_id == TWL4030_CLASS_ID) { | 1292 | if (twl_id == TWL4030_CLASS_ID) { |
@@ -1333,6 +1336,9 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1333 | fail: | 1336 | fail: |
1334 | if (status < 0) | 1337 | if (status < 0) |
1335 | twl_remove(client); | 1338 | twl_remove(client); |
1339 | free: | ||
1340 | if (status < 0) | ||
1341 | platform_device_unregister(pdev); | ||
1336 | 1342 | ||
1337 | return status; | 1343 | return status; |
1338 | } | 1344 | } |
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index 838ce4eb444e..77c9acb14583 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c | |||
@@ -223,7 +223,7 @@ static int __devinit twl4030_audio_probe(struct platform_device *pdev) | |||
223 | 223 | ||
224 | if (childs) | 224 | if (childs) |
225 | ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, | 225 | ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells, |
226 | childs, NULL, 0); | 226 | childs, NULL, 0, NULL); |
227 | else { | 227 | else { |
228 | dev_err(&pdev->dev, "No platform data found for childs\n"); | 228 | dev_err(&pdev->dev, "No platform data found for childs\n"); |
229 | ret = -ENODEV; | 229 | ret = -ENODEV; |
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index b0fad0ffca56..3dca5c195a20 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c | |||
@@ -632,7 +632,7 @@ static int __devinit twl6040_probe(struct i2c_client *client, | |||
632 | } | 632 | } |
633 | 633 | ||
634 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, | 634 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, |
635 | NULL, 0); | 635 | NULL, 0, NULL); |
636 | if (ret) | 636 | if (ret) |
637 | goto mfd_err; | 637 | goto mfd_err; |
638 | 638 | ||
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index 872aff21e4be..b9a636d44c7f 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c | |||
@@ -102,7 +102,7 @@ static __devinit int vx855_probe(struct pci_dev *pdev, | |||
102 | vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3; | 102 | vx855_gpio_resources[1].end = vx855_gpio_resources[1].start + 3; |
103 | 103 | ||
104 | ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), | 104 | ret = mfd_add_devices(&pdev->dev, -1, vx855_cells, ARRAY_SIZE(vx855_cells), |
105 | NULL, 0); | 105 | NULL, 0, NULL); |
106 | 106 | ||
107 | /* we always return -ENODEV here in order to enable other | 107 | /* we always return -ENODEV here in order to enable other |
108 | * drivers like old, not-yet-platform_device ported i2c-viapro */ | 108 | * drivers like old, not-yet-platform_device ported i2c-viapro */ |
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c index f39b756df561..86e0e4309fc2 100644 --- a/drivers/mfd/wl1273-core.c +++ b/drivers/mfd/wl1273-core.c | |||
@@ -241,7 +241,7 @@ static int __devinit wl1273_core_probe(struct i2c_client *client, | |||
241 | __func__, children); | 241 | __func__, children); |
242 | 242 | ||
243 | r = mfd_add_devices(&client->dev, -1, core->cells, | 243 | r = mfd_add_devices(&client->dev, -1, core->cells, |
244 | children, NULL, 0); | 244 | children, NULL, 0, NULL); |
245 | if (r) | 245 | if (r) |
246 | goto err; | 246 | goto err; |
247 | 247 | ||
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 946698fd2dc6..301731035940 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
@@ -1813,27 +1813,27 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1813 | case WM8310: | 1813 | case WM8310: |
1814 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1814 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1815 | wm8310_devs, ARRAY_SIZE(wm8310_devs), | 1815 | wm8310_devs, ARRAY_SIZE(wm8310_devs), |
1816 | NULL, 0); | 1816 | NULL, 0, NULL); |
1817 | break; | 1817 | break; |
1818 | 1818 | ||
1819 | case WM8311: | 1819 | case WM8311: |
1820 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1820 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1821 | wm8311_devs, ARRAY_SIZE(wm8311_devs), | 1821 | wm8311_devs, ARRAY_SIZE(wm8311_devs), |
1822 | NULL, 0); | 1822 | NULL, 0, NULL); |
1823 | if (!pdata || !pdata->disable_touch) | 1823 | if (!pdata || !pdata->disable_touch) |
1824 | mfd_add_devices(wm831x->dev, wm831x_num, | 1824 | mfd_add_devices(wm831x->dev, wm831x_num, |
1825 | touch_devs, ARRAY_SIZE(touch_devs), | 1825 | touch_devs, ARRAY_SIZE(touch_devs), |
1826 | NULL, 0); | 1826 | NULL, 0, NULL); |
1827 | break; | 1827 | break; |
1828 | 1828 | ||
1829 | case WM8312: | 1829 | case WM8312: |
1830 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1830 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1831 | wm8312_devs, ARRAY_SIZE(wm8312_devs), | 1831 | wm8312_devs, ARRAY_SIZE(wm8312_devs), |
1832 | NULL, 0); | 1832 | NULL, 0, NULL); |
1833 | if (!pdata || !pdata->disable_touch) | 1833 | if (!pdata || !pdata->disable_touch) |
1834 | mfd_add_devices(wm831x->dev, wm831x_num, | 1834 | mfd_add_devices(wm831x->dev, wm831x_num, |
1835 | touch_devs, ARRAY_SIZE(touch_devs), | 1835 | touch_devs, ARRAY_SIZE(touch_devs), |
1836 | NULL, 0); | 1836 | NULL, 0, NULL); |
1837 | break; | 1837 | break; |
1838 | 1838 | ||
1839 | case WM8320: | 1839 | case WM8320: |
@@ -1842,7 +1842,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1842 | case WM8326: | 1842 | case WM8326: |
1843 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1843 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1844 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | 1844 | wm8320_devs, ARRAY_SIZE(wm8320_devs), |
1845 | NULL, 0); | 1845 | NULL, 0, NULL); |
1846 | break; | 1846 | break; |
1847 | 1847 | ||
1848 | default: | 1848 | default: |
@@ -1867,7 +1867,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1867 | if (ret & WM831X_XTAL_ENA) { | 1867 | if (ret & WM831X_XTAL_ENA) { |
1868 | ret = mfd_add_devices(wm831x->dev, wm831x_num, | 1868 | ret = mfd_add_devices(wm831x->dev, wm831x_num, |
1869 | rtc_devs, ARRAY_SIZE(rtc_devs), | 1869 | rtc_devs, ARRAY_SIZE(rtc_devs), |
1870 | NULL, 0); | 1870 | NULL, 0, NULL); |
1871 | if (ret != 0) { | 1871 | if (ret != 0) { |
1872 | dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); | 1872 | dev_err(wm831x->dev, "Failed to add RTC: %d\n", ret); |
1873 | goto err_irq; | 1873 | goto err_irq; |
@@ -1880,7 +1880,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1880 | /* Treat errors as non-critical */ | 1880 | /* Treat errors as non-critical */ |
1881 | ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, | 1881 | ret = mfd_add_devices(wm831x->dev, wm831x_num, backlight_devs, |
1882 | ARRAY_SIZE(backlight_devs), NULL, | 1882 | ARRAY_SIZE(backlight_devs), NULL, |
1883 | 0); | 1883 | 0, NULL); |
1884 | if (ret < 0) | 1884 | if (ret < 0) |
1885 | dev_err(wm831x->dev, "Failed to add backlight: %d\n", | 1885 | dev_err(wm831x->dev, "Failed to add backlight: %d\n", |
1886 | ret); | 1886 | ret); |
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 4b7d378551d5..639ca359242f 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c | |||
@@ -70,7 +70,7 @@ static int wm8400_register_codec(struct wm8400 *wm8400) | |||
70 | .pdata_size = sizeof(*wm8400), | 70 | .pdata_size = sizeof(*wm8400), |
71 | }; | 71 | }; |
72 | 72 | ||
73 | return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0); | 73 | return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0, NULL); |
74 | } | 74 | } |
75 | 75 | ||
76 | /* | 76 | /* |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index eec74aa55fdf..2febf88cfce8 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -414,7 +414,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
414 | ret = mfd_add_devices(wm8994->dev, -1, | 414 | ret = mfd_add_devices(wm8994->dev, -1, |
415 | wm8994_regulator_devs, | 415 | wm8994_regulator_devs, |
416 | ARRAY_SIZE(wm8994_regulator_devs), | 416 | ARRAY_SIZE(wm8994_regulator_devs), |
417 | NULL, 0); | 417 | NULL, 0, NULL); |
418 | if (ret != 0) { | 418 | if (ret != 0) { |
419 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); | 419 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); |
420 | goto err; | 420 | goto err; |
@@ -648,7 +648,7 @@ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
648 | 648 | ||
649 | ret = mfd_add_devices(wm8994->dev, -1, | 649 | ret = mfd_add_devices(wm8994->dev, -1, |
650 | wm8994_devs, ARRAY_SIZE(wm8994_devs), | 650 | wm8994_devs, ARRAY_SIZE(wm8994_devs), |
651 | NULL, 0); | 651 | NULL, 0, NULL); |
652 | if (ret != 0) { | 652 | if (ret != 0) { |
653 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); | 653 | dev_err(wm8994->dev, "Failed to add children: %d\n", ret); |
654 | goto err_irq; | 654 | goto err_irq; |
diff --git a/drivers/misc/ibmasm/uart.c b/drivers/misc/ibmasm/uart.c index 1dcb9ae1905a..01e2b0d7e590 100644 --- a/drivers/misc/ibmasm/uart.c +++ b/drivers/misc/ibmasm/uart.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | void ibmasm_register_uart(struct service_processor *sp) | 34 | void ibmasm_register_uart(struct service_processor *sp) |
35 | { | 35 | { |
36 | struct uart_port uport; | 36 | struct uart_8250_port uart; |
37 | void __iomem *iomem_base; | 37 | void __iomem *iomem_base; |
38 | 38 | ||
39 | iomem_base = sp->base_address + SCOUT_COM_B_BASE; | 39 | iomem_base = sp->base_address + SCOUT_COM_B_BASE; |
@@ -47,14 +47,14 @@ void ibmasm_register_uart(struct service_processor *sp) | |||
47 | return; | 47 | return; |
48 | } | 48 | } |
49 | 49 | ||
50 | memset(&uport, 0, sizeof(struct uart_port)); | 50 | memset(&uart, 0, sizeof(uart)); |
51 | uport.irq = sp->irq; | 51 | uart.port.irq = sp->irq; |
52 | uport.uartclk = 3686400; | 52 | uart.port.uartclk = 3686400; |
53 | uport.flags = UPF_SHARE_IRQ; | 53 | uart.port.flags = UPF_SHARE_IRQ; |
54 | uport.iotype = UPIO_MEM; | 54 | uart.port.iotype = UPIO_MEM; |
55 | uport.membase = iomem_base; | 55 | uart.port.membase = iomem_base; |
56 | 56 | ||
57 | sp->serial_line = serial8250_register_port(&uport); | 57 | sp->serial_line = serial8250_register_8250_port(&uart); |
58 | if (sp->serial_line < 0) { | 58 | if (sp->serial_line < 0) { |
59 | dev_err(sp->dev, "Failed to register serial port\n"); | 59 | dev_err(sp->dev, "Failed to register serial port\n"); |
60 | return; | 60 | return; |
diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index b7eb545394b1..4999b34b7a60 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c | |||
@@ -60,7 +60,7 @@ struct pti_tty { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | struct pti_dev { | 62 | struct pti_dev { |
63 | struct tty_port port; | 63 | struct tty_port port[PTITTY_MINOR_NUM]; |
64 | unsigned long pti_addr; | 64 | unsigned long pti_addr; |
65 | unsigned long aperture_base; | 65 | unsigned long aperture_base; |
66 | void __iomem *pti_ioaddr; | 66 | void __iomem *pti_ioaddr; |
@@ -76,7 +76,7 @@ struct pti_dev { | |||
76 | */ | 76 | */ |
77 | static DEFINE_MUTEX(alloclock); | 77 | static DEFINE_MUTEX(alloclock); |
78 | 78 | ||
79 | static struct pci_device_id pci_ids[] __devinitconst = { | 79 | static const struct pci_device_id pci_ids[] __devinitconst = { |
80 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)}, | 80 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)}, |
81 | {0} | 81 | {0} |
82 | }; | 82 | }; |
@@ -393,25 +393,6 @@ void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count) | |||
393 | } | 393 | } |
394 | EXPORT_SYMBOL_GPL(pti_writedata); | 394 | EXPORT_SYMBOL_GPL(pti_writedata); |
395 | 395 | ||
396 | /** | ||
397 | * pti_pci_remove()- Driver exit method to remove PTI from | ||
398 | * PCI bus. | ||
399 | * @pdev: variable containing pci info of PTI. | ||
400 | */ | ||
401 | static void __devexit pti_pci_remove(struct pci_dev *pdev) | ||
402 | { | ||
403 | struct pti_dev *drv_data; | ||
404 | |||
405 | drv_data = pci_get_drvdata(pdev); | ||
406 | if (drv_data != NULL) { | ||
407 | pci_iounmap(pdev, drv_data->pti_ioaddr); | ||
408 | pci_set_drvdata(pdev, NULL); | ||
409 | kfree(drv_data); | ||
410 | pci_release_region(pdev, 1); | ||
411 | pci_disable_device(pdev); | ||
412 | } | ||
413 | } | ||
414 | |||
415 | /* | 396 | /* |
416 | * for the tty_driver_*() basic function descriptions, see tty_driver.h. | 397 | * for the tty_driver_*() basic function descriptions, see tty_driver.h. |
417 | * Specific header comments made for PTI-related specifics. | 398 | * Specific header comments made for PTI-related specifics. |
@@ -446,7 +427,7 @@ static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp) | |||
446 | * also removes a locking requirement for the actual write | 427 | * also removes a locking requirement for the actual write |
447 | * procedure. | 428 | * procedure. |
448 | */ | 429 | */ |
449 | return tty_port_open(&drv_data->port, tty, filp); | 430 | return tty_port_open(tty->port, tty, filp); |
450 | } | 431 | } |
451 | 432 | ||
452 | /** | 433 | /** |
@@ -462,7 +443,7 @@ static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp) | |||
462 | */ | 443 | */ |
463 | static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp) | 444 | static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp) |
464 | { | 445 | { |
465 | tty_port_close(&drv_data->port, tty, filp); | 446 | tty_port_close(tty->port, tty, filp); |
466 | } | 447 | } |
467 | 448 | ||
468 | /** | 449 | /** |
@@ -818,6 +799,7 @@ static const struct tty_port_operations tty_port_ops = { | |||
818 | static int __devinit pti_pci_probe(struct pci_dev *pdev, | 799 | static int __devinit pti_pci_probe(struct pci_dev *pdev, |
819 | const struct pci_device_id *ent) | 800 | const struct pci_device_id *ent) |
820 | { | 801 | { |
802 | unsigned int a; | ||
821 | int retval = -EINVAL; | 803 | int retval = -EINVAL; |
822 | int pci_bar = 1; | 804 | int pci_bar = 1; |
823 | 805 | ||
@@ -830,7 +812,7 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev, | |||
830 | __func__, __LINE__); | 812 | __func__, __LINE__); |
831 | pr_err("%s(%d): Error value returned: %d\n", | 813 | pr_err("%s(%d): Error value returned: %d\n", |
832 | __func__, __LINE__, retval); | 814 | __func__, __LINE__, retval); |
833 | return retval; | 815 | goto err; |
834 | } | 816 | } |
835 | 817 | ||
836 | retval = pci_enable_device(pdev); | 818 | retval = pci_enable_device(pdev); |
@@ -838,17 +820,16 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev, | |||
838 | dev_err(&pdev->dev, | 820 | dev_err(&pdev->dev, |
839 | "%s: pci_enable_device() returned error %d\n", | 821 | "%s: pci_enable_device() returned error %d\n", |
840 | __func__, retval); | 822 | __func__, retval); |
841 | return retval; | 823 | goto err_unreg_misc; |
842 | } | 824 | } |
843 | 825 | ||
844 | drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); | 826 | drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); |
845 | |||
846 | if (drv_data == NULL) { | 827 | if (drv_data == NULL) { |
847 | retval = -ENOMEM; | 828 | retval = -ENOMEM; |
848 | dev_err(&pdev->dev, | 829 | dev_err(&pdev->dev, |
849 | "%s(%d): kmalloc() returned NULL memory.\n", | 830 | "%s(%d): kmalloc() returned NULL memory.\n", |
850 | __func__, __LINE__); | 831 | __func__, __LINE__); |
851 | return retval; | 832 | goto err_disable_pci; |
852 | } | 833 | } |
853 | drv_data->pti_addr = pci_resource_start(pdev, pci_bar); | 834 | drv_data->pti_addr = pci_resource_start(pdev, pci_bar); |
854 | 835 | ||
@@ -857,33 +838,65 @@ static int __devinit pti_pci_probe(struct pci_dev *pdev, | |||
857 | dev_err(&pdev->dev, | 838 | dev_err(&pdev->dev, |
858 | "%s(%d): pci_request_region() returned error %d\n", | 839 | "%s(%d): pci_request_region() returned error %d\n", |
859 | __func__, __LINE__, retval); | 840 | __func__, __LINE__, retval); |
860 | kfree(drv_data); | 841 | goto err_free_dd; |
861 | return retval; | ||
862 | } | 842 | } |
863 | drv_data->aperture_base = drv_data->pti_addr+APERTURE_14; | 843 | drv_data->aperture_base = drv_data->pti_addr+APERTURE_14; |
864 | drv_data->pti_ioaddr = | 844 | drv_data->pti_ioaddr = |
865 | ioremap_nocache((u32)drv_data->aperture_base, | 845 | ioremap_nocache((u32)drv_data->aperture_base, |
866 | APERTURE_LEN); | 846 | APERTURE_LEN); |
867 | if (!drv_data->pti_ioaddr) { | 847 | if (!drv_data->pti_ioaddr) { |
868 | pci_release_region(pdev, pci_bar); | ||
869 | retval = -ENOMEM; | 848 | retval = -ENOMEM; |
870 | kfree(drv_data); | 849 | goto err_rel_reg; |
871 | return retval; | ||
872 | } | 850 | } |
873 | 851 | ||
874 | pci_set_drvdata(pdev, drv_data); | 852 | pci_set_drvdata(pdev, drv_data); |
875 | 853 | ||
876 | tty_port_init(&drv_data->port); | 854 | for (a = 0; a < PTITTY_MINOR_NUM; a++) { |
877 | drv_data->port.ops = &tty_port_ops; | 855 | struct tty_port *port = &drv_data->port[a]; |
856 | tty_port_init(port); | ||
857 | port->ops = &tty_port_ops; | ||
878 | 858 | ||
879 | tty_register_device(pti_tty_driver, 0, &pdev->dev); | 859 | tty_port_register_device(port, pti_tty_driver, a, &pdev->dev); |
880 | tty_register_device(pti_tty_driver, 1, &pdev->dev); | 860 | } |
881 | 861 | ||
882 | register_console(&pti_console); | 862 | register_console(&pti_console); |
883 | 863 | ||
864 | return 0; | ||
865 | err_rel_reg: | ||
866 | pci_release_region(pdev, pci_bar); | ||
867 | err_free_dd: | ||
868 | kfree(drv_data); | ||
869 | err_disable_pci: | ||
870 | pci_disable_device(pdev); | ||
871 | err_unreg_misc: | ||
872 | misc_deregister(&pti_char_driver); | ||
873 | err: | ||
884 | return retval; | 874 | return retval; |
885 | } | 875 | } |
886 | 876 | ||
877 | /** | ||
878 | * pti_pci_remove()- Driver exit method to remove PTI from | ||
879 | * PCI bus. | ||
880 | * @pdev: variable containing pci info of PTI. | ||
881 | */ | ||
882 | static void __devexit pti_pci_remove(struct pci_dev *pdev) | ||
883 | { | ||
884 | struct pti_dev *drv_data = pci_get_drvdata(pdev); | ||
885 | |||
886 | unregister_console(&pti_console); | ||
887 | |||
888 | tty_unregister_device(pti_tty_driver, 0); | ||
889 | tty_unregister_device(pti_tty_driver, 1); | ||
890 | |||
891 | iounmap(drv_data->pti_ioaddr); | ||
892 | pci_set_drvdata(pdev, NULL); | ||
893 | kfree(drv_data); | ||
894 | pci_release_region(pdev, 1); | ||
895 | pci_disable_device(pdev); | ||
896 | |||
897 | misc_deregister(&pti_char_driver); | ||
898 | } | ||
899 | |||
887 | static struct pci_driver pti_pci_driver = { | 900 | static struct pci_driver pti_pci_driver = { |
888 | .name = PCINAME, | 901 | .name = PCINAME, |
889 | .id_table = pci_ids, | 902 | .id_table = pci_ids, |
@@ -933,25 +946,24 @@ static int __init pti_init(void) | |||
933 | pr_err("%s(%d): Error value returned: %d\n", | 946 | pr_err("%s(%d): Error value returned: %d\n", |
934 | __func__, __LINE__, retval); | 947 | __func__, __LINE__, retval); |
935 | 948 | ||
936 | pti_tty_driver = NULL; | 949 | goto put_tty; |
937 | return retval; | ||
938 | } | 950 | } |
939 | 951 | ||
940 | retval = pci_register_driver(&pti_pci_driver); | 952 | retval = pci_register_driver(&pti_pci_driver); |
941 | |||
942 | if (retval) { | 953 | if (retval) { |
943 | pr_err("%s(%d): PCI registration failed of pti driver\n", | 954 | pr_err("%s(%d): PCI registration failed of pti driver\n", |
944 | __func__, __LINE__); | 955 | __func__, __LINE__); |
945 | pr_err("%s(%d): Error value returned: %d\n", | 956 | pr_err("%s(%d): Error value returned: %d\n", |
946 | __func__, __LINE__, retval); | 957 | __func__, __LINE__, retval); |
947 | 958 | goto unreg_tty; | |
948 | tty_unregister_driver(pti_tty_driver); | ||
949 | pr_err("%s(%d): Unregistering TTY part of pti driver\n", | ||
950 | __func__, __LINE__); | ||
951 | pti_tty_driver = NULL; | ||
952 | return retval; | ||
953 | } | 959 | } |
954 | 960 | ||
961 | return 0; | ||
962 | unreg_tty: | ||
963 | tty_unregister_driver(pti_tty_driver); | ||
964 | put_tty: | ||
965 | put_tty_driver(pti_tty_driver); | ||
966 | pti_tty_driver = NULL; | ||
955 | return retval; | 967 | return retval; |
956 | } | 968 | } |
957 | 969 | ||
@@ -960,31 +972,9 @@ static int __init pti_init(void) | |||
960 | */ | 972 | */ |
961 | static void __exit pti_exit(void) | 973 | static void __exit pti_exit(void) |
962 | { | 974 | { |
963 | int retval; | 975 | tty_unregister_driver(pti_tty_driver); |
964 | |||
965 | tty_unregister_device(pti_tty_driver, 0); | ||
966 | tty_unregister_device(pti_tty_driver, 1); | ||
967 | |||
968 | retval = tty_unregister_driver(pti_tty_driver); | ||
969 | if (retval) { | ||
970 | pr_err("%s(%d): TTY unregistration failed of pti driver\n", | ||
971 | __func__, __LINE__); | ||
972 | pr_err("%s(%d): Error value returned: %d\n", | ||
973 | __func__, __LINE__, retval); | ||
974 | } | ||
975 | |||
976 | pci_unregister_driver(&pti_pci_driver); | 976 | pci_unregister_driver(&pti_pci_driver); |
977 | 977 | put_tty_driver(pti_tty_driver); | |
978 | retval = misc_deregister(&pti_char_driver); | ||
979 | if (retval) { | ||
980 | pr_err("%s(%d): CHAR unregistration failed of pti driver\n", | ||
981 | __func__, __LINE__); | ||
982 | pr_err("%s(%d): Error value returned: %d\n", | ||
983 | __func__, __LINE__, retval); | ||
984 | } | ||
985 | |||
986 | unregister_console(&pti_console); | ||
987 | return; | ||
988 | } | 978 | } |
989 | 979 | ||
990 | module_init(pti_init); | 980 | module_init(pti_init); |
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 5a2cbfac66d2..d2339ea37815 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c | |||
@@ -518,7 +518,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port) | |||
518 | if (status & UART_MSR_DCTS) { | 518 | if (status & UART_MSR_DCTS) { |
519 | port->icount.cts++; | 519 | port->icount.cts++; |
520 | tty = tty_port_tty_get(&port->port); | 520 | tty = tty_port_tty_get(&port->port); |
521 | if (tty && (tty->termios->c_cflag & CRTSCTS)) { | 521 | if (tty && (tty->termios.c_cflag & CRTSCTS)) { |
522 | int cts = (status & UART_MSR_CTS); | 522 | int cts = (status & UART_MSR_CTS); |
523 | if (tty->hw_stopped) { | 523 | if (tty->hw_stopped) { |
524 | if (cts) { | 524 | if (cts) { |
@@ -671,12 +671,12 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty) | |||
671 | port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE; | 671 | port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE; |
672 | port->mctrl = TIOCM_OUT2; | 672 | port->mctrl = TIOCM_OUT2; |
673 | 673 | ||
674 | sdio_uart_change_speed(port, tty->termios, NULL); | 674 | sdio_uart_change_speed(port, &tty->termios, NULL); |
675 | 675 | ||
676 | if (tty->termios->c_cflag & CBAUD) | 676 | if (tty->termios.c_cflag & CBAUD) |
677 | sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); | 677 | sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); |
678 | 678 | ||
679 | if (tty->termios->c_cflag & CRTSCTS) | 679 | if (tty->termios.c_cflag & CRTSCTS) |
680 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) | 680 | if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS)) |
681 | tty->hw_stopped = 1; | 681 | tty->hw_stopped = 1; |
682 | 682 | ||
@@ -850,7 +850,7 @@ static void sdio_uart_throttle(struct tty_struct *tty) | |||
850 | { | 850 | { |
851 | struct sdio_uart_port *port = tty->driver_data; | 851 | struct sdio_uart_port *port = tty->driver_data; |
852 | 852 | ||
853 | if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS)) | 853 | if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS)) |
854 | return; | 854 | return; |
855 | 855 | ||
856 | if (sdio_uart_claim_func(port) != 0) | 856 | if (sdio_uart_claim_func(port) != 0) |
@@ -861,7 +861,7 @@ static void sdio_uart_throttle(struct tty_struct *tty) | |||
861 | sdio_uart_start_tx(port); | 861 | sdio_uart_start_tx(port); |
862 | } | 862 | } |
863 | 863 | ||
864 | if (tty->termios->c_cflag & CRTSCTS) | 864 | if (tty->termios.c_cflag & CRTSCTS) |
865 | sdio_uart_clear_mctrl(port, TIOCM_RTS); | 865 | sdio_uart_clear_mctrl(port, TIOCM_RTS); |
866 | 866 | ||
867 | sdio_uart_irq(port->func); | 867 | sdio_uart_irq(port->func); |
@@ -872,7 +872,7 @@ static void sdio_uart_unthrottle(struct tty_struct *tty) | |||
872 | { | 872 | { |
873 | struct sdio_uart_port *port = tty->driver_data; | 873 | struct sdio_uart_port *port = tty->driver_data; |
874 | 874 | ||
875 | if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS)) | 875 | if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS)) |
876 | return; | 876 | return; |
877 | 877 | ||
878 | if (sdio_uart_claim_func(port) != 0) | 878 | if (sdio_uart_claim_func(port) != 0) |
@@ -887,7 +887,7 @@ static void sdio_uart_unthrottle(struct tty_struct *tty) | |||
887 | } | 887 | } |
888 | } | 888 | } |
889 | 889 | ||
890 | if (tty->termios->c_cflag & CRTSCTS) | 890 | if (tty->termios.c_cflag & CRTSCTS) |
891 | sdio_uart_set_mctrl(port, TIOCM_RTS); | 891 | sdio_uart_set_mctrl(port, TIOCM_RTS); |
892 | 892 | ||
893 | sdio_uart_irq(port->func); | 893 | sdio_uart_irq(port->func); |
@@ -898,12 +898,12 @@ static void sdio_uart_set_termios(struct tty_struct *tty, | |||
898 | struct ktermios *old_termios) | 898 | struct ktermios *old_termios) |
899 | { | 899 | { |
900 | struct sdio_uart_port *port = tty->driver_data; | 900 | struct sdio_uart_port *port = tty->driver_data; |
901 | unsigned int cflag = tty->termios->c_cflag; | 901 | unsigned int cflag = tty->termios.c_cflag; |
902 | 902 | ||
903 | if (sdio_uart_claim_func(port) != 0) | 903 | if (sdio_uart_claim_func(port) != 0) |
904 | return; | 904 | return; |
905 | 905 | ||
906 | sdio_uart_change_speed(port, tty->termios, old_termios); | 906 | sdio_uart_change_speed(port, &tty->termios, old_termios); |
907 | 907 | ||
908 | /* Handle transition to B0 status */ | 908 | /* Handle transition to B0 status */ |
909 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) | 909 | if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD)) |
@@ -1132,8 +1132,8 @@ static int sdio_uart_probe(struct sdio_func *func, | |||
1132 | kfree(port); | 1132 | kfree(port); |
1133 | } else { | 1133 | } else { |
1134 | struct device *dev; | 1134 | struct device *dev; |
1135 | dev = tty_register_device(sdio_uart_tty_driver, | 1135 | dev = tty_port_register_device(&port->port, |
1136 | port->index, &func->dev); | 1136 | sdio_uart_tty_driver, port->index, &func->dev); |
1137 | if (IS_ERR(dev)) { | 1137 | if (IS_ERR(dev)) { |
1138 | sdio_uart_port_remove(port); | 1138 | sdio_uart_port_remove(port); |
1139 | ret = PTR_ERR(dev); | 1139 | ret = PTR_ERR(dev); |
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index 7cf6c624bf73..3dfd3473269d 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <linux/dma-mapping.h> | 33 | #include <linux/dma-mapping.h> |
34 | #include <linux/mmc/mmc.h> | 34 | #include <linux/mmc/mmc.h> |
35 | 35 | ||
36 | #include <mach/mmc.h> | 36 | #include <linux/platform_data/mmc-davinci.h> |
37 | #include <mach/edma.h> | 37 | #include <mach/edma.h> |
38 | 38 | ||
39 | /* | 39 | /* |
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 1d14cda95e56..7c0af0e80047 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <asm/div64.h> | 42 | #include <asm/div64.h> |
43 | #include <asm/sizes.h> | 43 | #include <asm/sizes.h> |
44 | 44 | ||
45 | #include <mach/mmc.h> | 45 | #include <linux/platform_data/mmc-msm_sdcc.h> |
46 | #include <mach/msm_iomap.h> | 46 | #include <mach/msm_iomap.h> |
47 | #include <mach/dma.h> | 47 | #include <mach/dma.h> |
48 | #include <mach/clk.h> | 48 | #include <mach/clk.h> |
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index a61cb5fca22d..de4c20b3936c 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <asm/sizes.h> | 26 | #include <asm/sizes.h> |
27 | #include <asm/unaligned.h> | 27 | #include <asm/unaligned.h> |
28 | #include <plat/mvsdio.h> | 28 | #include <linux/platform_data/mmc-mvsdio.h> |
29 | 29 | ||
30 | #include "mvsdio.h" | 30 | #include "mvsdio.h" |
31 | 31 | ||
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 28ed52d58f7f..7b1161de01d6 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -38,9 +38,9 @@ | |||
38 | #include <asm/dma.h> | 38 | #include <asm/dma.h> |
39 | #include <asm/irq.h> | 39 | #include <asm/irq.h> |
40 | #include <asm/sizes.h> | 40 | #include <asm/sizes.h> |
41 | #include <mach/mmc.h> | 41 | #include <linux/platform_data/mmc-mxcmmc.h> |
42 | 42 | ||
43 | #include <mach/dma.h> | 43 | #include <linux/platform_data/dma-imx.h> |
44 | #include <mach/hardware.h> | 44 | #include <mach/hardware.h> |
45 | 45 | ||
46 | #define DRIVER_NAME "mxc-mmc" | 46 | #define DRIVER_NAME "mxc-mmc" |
diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c index a5999a74496a..c6259a829544 100644 --- a/drivers/mmc/host/omap.c +++ b/drivers/mmc/host/omap.c | |||
@@ -33,11 +33,9 @@ | |||
33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
34 | #include <asm/irq.h> | 34 | #include <asm/irq.h> |
35 | 35 | ||
36 | #include <plat/board.h> | ||
37 | #include <plat/mmc.h> | 36 | #include <plat/mmc.h> |
38 | #include <asm/gpio.h> | 37 | #include <asm/gpio.h> |
39 | #include <plat/dma.h> | 38 | #include <plat/dma.h> |
40 | #include <plat/mux.h> | ||
41 | #include <plat/fpga.h> | 39 | #include <plat/fpga.h> |
42 | 40 | ||
43 | #define OMAP_MMC_REG_CMD 0x00 | 41 | #define OMAP_MMC_REG_CMD 0x00 |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index 3a09f93cc3b6..f871b31ece5a 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <linux/regulator/consumer.h> | 40 | #include <linux/regulator/consumer.h> |
41 | #include <linux/pm_runtime.h> | 41 | #include <linux/pm_runtime.h> |
42 | #include <mach/hardware.h> | 42 | #include <mach/hardware.h> |
43 | #include <plat/board.h> | ||
44 | #include <plat/mmc.h> | 43 | #include <plat/mmc.h> |
45 | #include <plat/cpu.h> | 44 | #include <plat/cpu.h> |
46 | 45 | ||
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index cb2dc0e75ba7..ca3915dac03d 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
37 | #include <mach/dma.h> | 37 | #include <mach/dma.h> |
38 | #include <mach/mmc.h> | 38 | #include <linux/platform_data/mmc-pxamci.h> |
39 | 39 | ||
40 | #include "pxamci.h" | 40 | #include "pxamci.h" |
41 | 41 | ||
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index bd5a5cce122c..4638ddab97b8 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | #include <mach/regs-sdi.h> | 28 | #include <mach/regs-sdi.h> |
29 | 29 | ||
30 | #include <plat/mci.h> | 30 | #include <linux/platform_data/mmc-s3cmci.h> |
31 | 31 | ||
32 | #include "s3cmci.h" | 32 | #include "s3cmci.h" |
33 | 33 | ||
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index e23f8134591c..c4c504c4802b 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/of_device.h> | 25 | #include <linux/of_device.h> |
26 | #include <linux/of_gpio.h> | 26 | #include <linux/of_gpio.h> |
27 | #include <linux/pinctrl/consumer.h> | 27 | #include <linux/pinctrl/consumer.h> |
28 | #include <mach/esdhc.h> | 28 | #include <linux/platform_data/mmc-esdhc-imx.h> |
29 | #include "sdhci-pltfm.h" | 29 | #include "sdhci-pltfm.h" |
30 | #include "sdhci-esdhc.h" | 30 | #include "sdhci-esdhc.h" |
31 | 31 | ||
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index 0810ccc23d7e..d43e7462941f 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <asm/gpio.h> | 28 | #include <asm/gpio.h> |
29 | 29 | ||
30 | #include <mach/gpio-tegra.h> | 30 | #include <mach/gpio-tegra.h> |
31 | #include <mach/sdhci.h> | 31 | #include <linux/platform_data/mmc-sdhci-tegra.h> |
32 | 32 | ||
33 | #include "sdhci-pltfm.h" | 33 | #include "sdhci-pltfm.h" |
34 | 34 | ||
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 861ca8f7e47d..a7040af08536 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c | |||
@@ -23,11 +23,15 @@ | |||
23 | #include <linux/mtd/mtd.h> | 23 | #include <linux/mtd/mtd.h> |
24 | #include <linux/mtd/nand.h> | 24 | #include <linux/mtd/nand.h> |
25 | #include <linux/mtd/partitions.h> | 25 | #include <linux/mtd/partitions.h> |
26 | #include <linux/gpio.h> | ||
27 | #include <linux/platform_data/gpio-omap.h> | ||
28 | |||
26 | #include <asm/io.h> | 29 | #include <asm/io.h> |
27 | #include <mach/hardware.h> | ||
28 | #include <asm/sizes.h> | 30 | #include <asm/sizes.h> |
29 | #include <linux/gpio.h> | 31 | |
30 | #include <plat/board-ams-delta.h> | 32 | #include <mach/board-ams-delta.h> |
33 | |||
34 | #include <mach/hardware.h> | ||
31 | 35 | ||
32 | /* | 36 | /* |
33 | * MTD structure for E3 (Delta) | 37 | * MTD structure for E3 (Delta) |
diff --git a/drivers/mtd/nand/bcm_umi_nand.c b/drivers/mtd/nand/bcm_umi_nand.c index c855e7cd337b..d0d1bd4d0e7d 100644 --- a/drivers/mtd/nand/bcm_umi_nand.c +++ b/drivers/mtd/nand/bcm_umi_nand.c | |||
@@ -249,20 +249,20 @@ static int nand_dev_ready(struct mtd_info *mtd) | |||
249 | int bcm_umi_nand_inithw(void) | 249 | int bcm_umi_nand_inithw(void) |
250 | { | 250 | { |
251 | /* Configure nand timing parameters */ | 251 | /* Configure nand timing parameters */ |
252 | REG_UMI_NAND_TCR &= ~0x7ffff; | 252 | writel(readl(®_UMI_NAND_TCR) & ~0x7ffff, ®_UMI_NAND_TCR); |
253 | REG_UMI_NAND_TCR |= HW_CFG_NAND_TCR; | 253 | writel(readl(®_UMI_NAND_TCR) | HW_CFG_NAND_TCR, ®_UMI_NAND_TCR); |
254 | 254 | ||
255 | #if !defined(CONFIG_MTD_NAND_BCM_UMI_HWCS) | 255 | #if !defined(CONFIG_MTD_NAND_BCM_UMI_HWCS) |
256 | /* enable software control of CS */ | 256 | /* enable software control of CS */ |
257 | REG_UMI_NAND_TCR |= REG_UMI_NAND_TCR_CS_SWCTRL; | 257 | writel(readl(®_UMI_NAND_TCR) | REG_UMI_NAND_TCR_CS_SWCTRL, ®_UMI_NAND_TCR); |
258 | #endif | 258 | #endif |
259 | 259 | ||
260 | /* keep NAND chip select asserted */ | 260 | /* keep NAND chip select asserted */ |
261 | REG_UMI_NAND_RCSR |= REG_UMI_NAND_RCSR_CS_ASSERTED; | 261 | writel(readl(®_UMI_NAND_RCSR) | REG_UMI_NAND_RCSR_CS_ASSERTED, ®_UMI_NAND_RCSR); |
262 | 262 | ||
263 | REG_UMI_NAND_TCR &= ~REG_UMI_NAND_TCR_WORD16; | 263 | writel(readl(®_UMI_NAND_TCR) & ~REG_UMI_NAND_TCR_WORD16, ®_UMI_NAND_TCR); |
264 | /* enable writes to flash */ | 264 | /* enable writes to flash */ |
265 | REG_UMI_MMD_ICR |= REG_UMI_MMD_ICR_FLASH_WP; | 265 | writel(readl(®_UMI_MMD_ICR) | REG_UMI_MMD_ICR_FLASH_WP, ®_UMI_MMD_ICR); |
266 | 266 | ||
267 | writel(NAND_CMD_RESET, bcm_umi_io_base + REG_NAND_CMD_OFFSET); | 267 | writel(NAND_CMD_RESET, bcm_umi_io_base + REG_NAND_CMD_OFFSET); |
268 | nand_bcm_umi_wait_till_ready(); | 268 | nand_bcm_umi_wait_till_ready(); |
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index d94b03c207af..f1deb1ee2c95 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -34,8 +34,8 @@ | |||
34 | #include <linux/mtd/partitions.h> | 34 | #include <linux/mtd/partitions.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | 36 | ||
37 | #include <mach/nand.h> | 37 | #include <linux/platform_data/mtd-davinci.h> |
38 | #include <mach/aemif.h> | 38 | #include <linux/platform_data/mtd-davinci-aemif.h> |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * This is a device driver for the NAND flash controller found on the | 41 | * This is a device driver for the NAND flash controller found on the |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 6acc790c2fbb..5683604967d7 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/of_mtd.h> | 36 | #include <linux/of_mtd.h> |
37 | 37 | ||
38 | #include <asm/mach/flash.h> | 38 | #include <asm/mach/flash.h> |
39 | #include <mach/mxc_nand.h> | 39 | #include <linux/platform_data/mtd-mxc_nand.h> |
40 | #include <mach/hardware.h> | 40 | #include <mach/hardware.h> |
41 | 41 | ||
42 | #define DRIVER_NAME "mxc_nand" | 42 | #define DRIVER_NAME "mxc_nand" |
diff --git a/drivers/mtd/nand/nand_bcm_umi.h b/drivers/mtd/nand/nand_bcm_umi.h index 198b304d6f72..d90186684db8 100644 --- a/drivers/mtd/nand/nand_bcm_umi.h +++ b/drivers/mtd/nand/nand_bcm_umi.h | |||
@@ -17,7 +17,7 @@ | |||
17 | /* ---- Include Files ---------------------------------------------------- */ | 17 | /* ---- Include Files ---------------------------------------------------- */ |
18 | #include <mach/reg_umi.h> | 18 | #include <mach/reg_umi.h> |
19 | #include <mach/reg_nand.h> | 19 | #include <mach/reg_nand.h> |
20 | #include <cfg_global.h> | 20 | #include <mach/cfg_global.h> |
21 | 21 | ||
22 | /* ---- Constants and Types ---------------------------------------------- */ | 22 | /* ---- Constants and Types ---------------------------------------------- */ |
23 | #if (CFG_GLOBAL_CHIP_FAMILY == CFG_GLOBAL_CHIP_FAMILY_BCMRING) | 23 | #if (CFG_GLOBAL_CHIP_FAMILY == CFG_GLOBAL_CHIP_FAMILY_BCMRING) |
@@ -48,7 +48,7 @@ int nand_bcm_umi_bch_correct_page(uint8_t *datap, uint8_t *readEccData, | |||
48 | /* Check in device is ready */ | 48 | /* Check in device is ready */ |
49 | static inline int nand_bcm_umi_dev_ready(void) | 49 | static inline int nand_bcm_umi_dev_ready(void) |
50 | { | 50 | { |
51 | return REG_UMI_NAND_RCSR & REG_UMI_NAND_RCSR_RDY; | 51 | return readl(®_UMI_NAND_RCSR) & REG_UMI_NAND_RCSR_RDY; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* Wait until device is ready */ | 54 | /* Wait until device is ready */ |
@@ -62,10 +62,11 @@ static inline void nand_bcm_umi_wait_till_ready(void) | |||
62 | static inline void nand_bcm_umi_hamming_enable_hwecc(void) | 62 | static inline void nand_bcm_umi_hamming_enable_hwecc(void) |
63 | { | 63 | { |
64 | /* disable and reset ECC, 512 byte page */ | 64 | /* disable and reset ECC, 512 byte page */ |
65 | REG_UMI_NAND_ECC_CSR &= ~(REG_UMI_NAND_ECC_CSR_ECC_ENABLE | | 65 | writel(readl(®_UMI_NAND_ECC_CSR) & ~(REG_UMI_NAND_ECC_CSR_ECC_ENABLE | |
66 | REG_UMI_NAND_ECC_CSR_256BYTE); | 66 | REG_UMI_NAND_ECC_CSR_256BYTE), ®_UMI_NAND_ECC_CSR); |
67 | /* enable ECC */ | 67 | /* enable ECC */ |
68 | REG_UMI_NAND_ECC_CSR |= REG_UMI_NAND_ECC_CSR_ECC_ENABLE; | 68 | writel(readl(®_UMI_NAND_ECC_CSR) | REG_UMI_NAND_ECC_CSR_ECC_ENABLE, |
69 | ®_UMI_NAND_ECC_CSR); | ||
69 | } | 70 | } |
70 | 71 | ||
71 | #if NAND_ECC_BCH | 72 | #if NAND_ECC_BCH |
@@ -76,18 +77,18 @@ static inline void nand_bcm_umi_hamming_enable_hwecc(void) | |||
76 | static inline void nand_bcm_umi_bch_enable_read_hwecc(void) | 77 | static inline void nand_bcm_umi_bch_enable_read_hwecc(void) |
77 | { | 78 | { |
78 | /* disable and reset ECC */ | 79 | /* disable and reset ECC */ |
79 | REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID; | 80 | writel(REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID, ®_UMI_BCH_CTRL_STATUS); |
80 | /* Turn on ECC */ | 81 | /* Turn on ECC */ |
81 | REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN; | 82 | writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN, ®_UMI_BCH_CTRL_STATUS); |
82 | } | 83 | } |
83 | 84 | ||
84 | /* Enable BCH Write ECC */ | 85 | /* Enable BCH Write ECC */ |
85 | static inline void nand_bcm_umi_bch_enable_write_hwecc(void) | 86 | static inline void nand_bcm_umi_bch_enable_write_hwecc(void) |
86 | { | 87 | { |
87 | /* disable and reset ECC */ | 88 | /* disable and reset ECC */ |
88 | REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID; | 89 | writel(REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID, ®_UMI_BCH_CTRL_STATUS); |
89 | /* Turn on ECC */ | 90 | /* Turn on ECC */ |
90 | REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN; | 91 | writel(REG_UMI_BCH_CTRL_STATUS_ECC_WR_EN, ®_UMI_BCH_CTRL_STATUS); |
91 | } | 92 | } |
92 | 93 | ||
93 | /* Config number of BCH ECC bytes */ | 94 | /* Config number of BCH ECC bytes */ |
@@ -99,9 +100,9 @@ static inline void nand_bcm_umi_bch_config_ecc(uint8_t numEccBytes) | |||
99 | uint32_t numBits = numEccBytes * 8; | 100 | uint32_t numBits = numEccBytes * 8; |
100 | 101 | ||
101 | /* disable and reset ECC */ | 102 | /* disable and reset ECC */ |
102 | REG_UMI_BCH_CTRL_STATUS = | 103 | writel(REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID | |
103 | REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID | | 104 | REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID, |
104 | REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID; | 105 | ®_UMI_BCH_CTRL_STATUS); |
105 | 106 | ||
106 | /* Every correctible bit requires 13 ECC bits */ | 107 | /* Every correctible bit requires 13 ECC bits */ |
107 | tValue = (uint32_t) (numBits / ECC_BITS_PER_CORRECTABLE_BIT); | 108 | tValue = (uint32_t) (numBits / ECC_BITS_PER_CORRECTABLE_BIT); |
@@ -113,23 +114,21 @@ static inline void nand_bcm_umi_bch_config_ecc(uint8_t numEccBytes) | |||
113 | kValue = nValue - (tValue * ECC_BITS_PER_CORRECTABLE_BIT); | 114 | kValue = nValue - (tValue * ECC_BITS_PER_CORRECTABLE_BIT); |
114 | 115 | ||
115 | /* Write the settings */ | 116 | /* Write the settings */ |
116 | REG_UMI_BCH_N = nValue; | 117 | writel(nValue, ®_UMI_BCH_N); |
117 | REG_UMI_BCH_T = tValue; | 118 | writel(tValue, ®_UMI_BCH_T); |
118 | REG_UMI_BCH_K = kValue; | 119 | writel(kValue, ®_UMI_BCH_K); |
119 | } | 120 | } |
120 | 121 | ||
121 | /* Pause during ECC read calculation to skip bytes in OOB */ | 122 | /* Pause during ECC read calculation to skip bytes in OOB */ |
122 | static inline void nand_bcm_umi_bch_pause_read_ecc_calc(void) | 123 | static inline void nand_bcm_umi_bch_pause_read_ecc_calc(void) |
123 | { | 124 | { |
124 | REG_UMI_BCH_CTRL_STATUS = | 125 | writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN | REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC, ®_UMI_BCH_CTRL_STATUS); |
125 | REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN | | ||
126 | REG_UMI_BCH_CTRL_STATUS_PAUSE_ECC_DEC; | ||
127 | } | 126 | } |
128 | 127 | ||
129 | /* Resume during ECC read calculation after skipping bytes in OOB */ | 128 | /* Resume during ECC read calculation after skipping bytes in OOB */ |
130 | static inline void nand_bcm_umi_bch_resume_read_ecc_calc(void) | 129 | static inline void nand_bcm_umi_bch_resume_read_ecc_calc(void) |
131 | { | 130 | { |
132 | REG_UMI_BCH_CTRL_STATUS = REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN; | 131 | writel(REG_UMI_BCH_CTRL_STATUS_ECC_RD_EN, ®_UMI_BCH_CTRL_STATUS); |
133 | } | 132 | } |
134 | 133 | ||
135 | /* Poll read ECC calc to check when hardware completes */ | 134 | /* Poll read ECC calc to check when hardware completes */ |
@@ -139,7 +138,7 @@ static inline uint32_t nand_bcm_umi_bch_poll_read_ecc_calc(void) | |||
139 | 138 | ||
140 | do { | 139 | do { |
141 | /* wait for ECC to be valid */ | 140 | /* wait for ECC to be valid */ |
142 | regVal = REG_UMI_BCH_CTRL_STATUS; | 141 | regVal = readl(®_UMI_BCH_CTRL_STATUS); |
143 | } while ((regVal & REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID) == 0); | 142 | } while ((regVal & REG_UMI_BCH_CTRL_STATUS_RD_ECC_VALID) == 0); |
144 | 143 | ||
145 | return regVal; | 144 | return regVal; |
@@ -149,7 +148,7 @@ static inline uint32_t nand_bcm_umi_bch_poll_read_ecc_calc(void) | |||
149 | static inline void nand_bcm_umi_bch_poll_write_ecc_calc(void) | 148 | static inline void nand_bcm_umi_bch_poll_write_ecc_calc(void) |
150 | { | 149 | { |
151 | /* wait for ECC to be valid */ | 150 | /* wait for ECC to be valid */ |
152 | while ((REG_UMI_BCH_CTRL_STATUS & REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID) | 151 | while ((readl(®_UMI_BCH_CTRL_STATUS) & REG_UMI_BCH_CTRL_STATUS_WR_ECC_VALID) |
153 | == 0) | 152 | == 0) |
154 | ; | 153 | ; |
155 | } | 154 | } |
@@ -170,9 +169,9 @@ static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize, | |||
170 | if (pageSize != NAND_DATA_ACCESS_SIZE) { | 169 | if (pageSize != NAND_DATA_ACCESS_SIZE) { |
171 | /* skip BI */ | 170 | /* skip BI */ |
172 | #if defined(__KERNEL__) && !defined(STANDALONE) | 171 | #if defined(__KERNEL__) && !defined(STANDALONE) |
173 | *oobp++ = REG_NAND_DATA8; | 172 | *oobp++ = readb(®_NAND_DATA8); |
174 | #else | 173 | #else |
175 | REG_NAND_DATA8; | 174 | readb(®_NAND_DATA8); |
176 | #endif | 175 | #endif |
177 | numToRead--; | 176 | numToRead--; |
178 | } | 177 | } |
@@ -180,9 +179,9 @@ static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize, | |||
180 | while (numToRead > numEccBytes) { | 179 | while (numToRead > numEccBytes) { |
181 | /* skip free oob region */ | 180 | /* skip free oob region */ |
182 | #if defined(__KERNEL__) && !defined(STANDALONE) | 181 | #if defined(__KERNEL__) && !defined(STANDALONE) |
183 | *oobp++ = REG_NAND_DATA8; | 182 | *oobp++ = readb(®_NAND_DATA8); |
184 | #else | 183 | #else |
185 | REG_NAND_DATA8; | 184 | readb(®_NAND_DATA8); |
186 | #endif | 185 | #endif |
187 | numToRead--; | 186 | numToRead--; |
188 | } | 187 | } |
@@ -193,11 +192,11 @@ static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize, | |||
193 | 192 | ||
194 | while (numToRead > 11) { | 193 | while (numToRead > 11) { |
195 | #if defined(__KERNEL__) && !defined(STANDALONE) | 194 | #if defined(__KERNEL__) && !defined(STANDALONE) |
196 | *oobp = REG_NAND_DATA8; | 195 | *oobp = readb(®_NAND_DATA8); |
197 | eccCalc[eccPos++] = *oobp; | 196 | eccCalc[eccPos++] = *oobp; |
198 | oobp++; | 197 | oobp++; |
199 | #else | 198 | #else |
200 | eccCalc[eccPos++] = REG_NAND_DATA8; | 199 | eccCalc[eccPos++] = readb(®_NAND_DATA8); |
201 | #endif | 200 | #endif |
202 | numToRead--; | 201 | numToRead--; |
203 | } | 202 | } |
@@ -207,9 +206,9 @@ static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize, | |||
207 | if (numToRead == 11) { | 206 | if (numToRead == 11) { |
208 | /* read BI */ | 207 | /* read BI */ |
209 | #if defined(__KERNEL__) && !defined(STANDALONE) | 208 | #if defined(__KERNEL__) && !defined(STANDALONE) |
210 | *oobp++ = REG_NAND_DATA8; | 209 | *oobp++ = readb(®_NAND_DATA8); |
211 | #else | 210 | #else |
212 | REG_NAND_DATA8; | 211 | readb(®_NAND_DATA8); |
213 | #endif | 212 | #endif |
214 | numToRead--; | 213 | numToRead--; |
215 | } | 214 | } |
@@ -219,11 +218,11 @@ static inline void nand_bcm_umi_bch_read_oobEcc(uint32_t pageSize, | |||
219 | nand_bcm_umi_bch_resume_read_ecc_calc(); | 218 | nand_bcm_umi_bch_resume_read_ecc_calc(); |
220 | while (numToRead) { | 219 | while (numToRead) { |
221 | #if defined(__KERNEL__) && !defined(STANDALONE) | 220 | #if defined(__KERNEL__) && !defined(STANDALONE) |
222 | *oobp = REG_NAND_DATA8; | 221 | *oobp = readb(®_NAND_DATA8); |
223 | eccCalc[eccPos++] = *oobp; | 222 | eccCalc[eccPos++] = *oobp; |
224 | oobp++; | 223 | oobp++; |
225 | #else | 224 | #else |
226 | eccCalc[eccPos++] = REG_NAND_DATA8; | 225 | eccCalc[eccPos++] = readb(®_NAND_DATA8); |
227 | #endif | 226 | #endif |
228 | numToRead--; | 227 | numToRead--; |
229 | } | 228 | } |
@@ -255,7 +254,7 @@ static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize, | |||
255 | if (pageSize == NAND_DATA_ACCESS_SIZE) { | 254 | if (pageSize == NAND_DATA_ACCESS_SIZE) { |
256 | /* Now fill in the ECC bytes */ | 255 | /* Now fill in the ECC bytes */ |
257 | if (numEccBytes >= 13) | 256 | if (numEccBytes >= 13) |
258 | eccVal = REG_UMI_BCH_WR_ECC_3; | 257 | eccVal = readl(®_UMI_BCH_WR_ECC_3); |
259 | 258 | ||
260 | /* Usually we skip CM in oob[0,1] */ | 259 | /* Usually we skip CM in oob[0,1] */ |
261 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[0], | 260 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[0], |
@@ -268,7 +267,7 @@ static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize, | |||
268 | eccVal & 0xff); /* ECC 12 */ | 267 | eccVal & 0xff); /* ECC 12 */ |
269 | 268 | ||
270 | if (numEccBytes >= 9) | 269 | if (numEccBytes >= 9) |
271 | eccVal = REG_UMI_BCH_WR_ECC_2; | 270 | eccVal = readl(®_UMI_BCH_WR_ECC_2); |
272 | 271 | ||
273 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[3], | 272 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[3], |
274 | (eccVal >> 24) & 0xff); /* ECC11 */ | 273 | (eccVal >> 24) & 0xff); /* ECC11 */ |
@@ -281,7 +280,7 @@ static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize, | |||
281 | 280 | ||
282 | /* Now fill in the ECC bytes */ | 281 | /* Now fill in the ECC bytes */ |
283 | if (numEccBytes >= 13) | 282 | if (numEccBytes >= 13) |
284 | eccVal = REG_UMI_BCH_WR_ECC_3; | 283 | eccVal = readl(®_UMI_BCH_WR_ECC_3); |
285 | 284 | ||
286 | /* Usually skip CM in oob[1,2] */ | 285 | /* Usually skip CM in oob[1,2] */ |
287 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[1], | 286 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 15, &oobp[1], |
@@ -294,7 +293,7 @@ static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize, | |||
294 | eccVal & 0xff); /* ECC12 */ | 293 | eccVal & 0xff); /* ECC12 */ |
295 | 294 | ||
296 | if (numEccBytes >= 9) | 295 | if (numEccBytes >= 9) |
297 | eccVal = REG_UMI_BCH_WR_ECC_2; | 296 | eccVal = readl(®_UMI_BCH_WR_ECC_2); |
298 | 297 | ||
299 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[4], | 298 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 12, &oobp[4], |
300 | (eccVal >> 24) & 0xff); /* ECC11 */ | 299 | (eccVal >> 24) & 0xff); /* ECC11 */ |
@@ -309,7 +308,7 @@ static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize, | |||
309 | eccVal & 0xff); /* ECC8 */ | 308 | eccVal & 0xff); /* ECC8 */ |
310 | 309 | ||
311 | if (numEccBytes >= 5) | 310 | if (numEccBytes >= 5) |
312 | eccVal = REG_UMI_BCH_WR_ECC_1; | 311 | eccVal = readl(®_UMI_BCH_WR_ECC_1); |
313 | 312 | ||
314 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 8, &oobp[8], | 313 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 8, &oobp[8], |
315 | (eccVal >> 24) & 0xff); /* ECC7 */ | 314 | (eccVal >> 24) & 0xff); /* ECC7 */ |
@@ -321,7 +320,7 @@ static inline void nand_bcm_umi_bch_write_oobEcc(uint32_t pageSize, | |||
321 | eccVal & 0xff); /* ECC4 */ | 320 | eccVal & 0xff); /* ECC4 */ |
322 | 321 | ||
323 | if (numEccBytes >= 1) | 322 | if (numEccBytes >= 1) |
324 | eccVal = REG_UMI_BCH_WR_ECC_0; | 323 | eccVal = readl(®_UMI_BCH_WR_ECC_0); |
325 | 324 | ||
326 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 4, &oobp[12], | 325 | NAND_BCM_UMI_ECC_WRITE(numEccBytes, 4, &oobp[12], |
327 | (eccVal >> 24) & 0xff); /* ECC3 */ | 326 | (eccVal >> 24) & 0xff); /* ECC3 */ |
diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c index a86aa812ca13..9ee0c4edfacf 100644 --- a/drivers/mtd/nand/nomadik_nand.c +++ b/drivers/mtd/nand/nomadik_nand.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/mtd/partitions.h> | 31 | #include <linux/mtd/partitions.h> |
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <mach/nand.h> | 34 | #include <linux/platform_data/mtd-nomadik-nand.h> |
35 | #include <mach/fsmc.h> | 35 | #include <mach/fsmc.h> |
36 | 36 | ||
37 | #include <mtd/mtd-abi.h> | 37 | #include <mtd/mtd-abi.h> |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index ac4fd756eda3..fc8111278d12 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -29,7 +29,7 @@ | |||
29 | 29 | ||
30 | #include <plat/dma.h> | 30 | #include <plat/dma.h> |
31 | #include <plat/gpmc.h> | 31 | #include <plat/gpmc.h> |
32 | #include <plat/nand.h> | 32 | #include <linux/platform_data/mtd-nand-omap2.h> |
33 | 33 | ||
34 | #define DRIVER_NAME "omap2-nand" | 34 | #define DRIVER_NAME "omap2-nand" |
35 | #define OMAP_NAND_TIMEOUT_MS 5000 | 35 | #define OMAP_NAND_TIMEOUT_MS 5000 |
@@ -101,6 +101,16 @@ | |||
101 | #define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0) | 101 | #define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0) |
102 | #define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1) | 102 | #define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1) |
103 | 103 | ||
104 | #define PREFETCH_CONFIG1_CS_SHIFT 24 | ||
105 | #define ECC_CONFIG_CS_SHIFT 1 | ||
106 | #define CS_MASK 0x7 | ||
107 | #define ENABLE_PREFETCH (0x1 << 7) | ||
108 | #define DMA_MPU_MODE_SHIFT 2 | ||
109 | #define ECCSIZE1_SHIFT 22 | ||
110 | #define ECC1RESULTSIZE 0x1 | ||
111 | #define ECCCLEAR 0x100 | ||
112 | #define ECC1 0x1 | ||
113 | |||
104 | /* oob info generated runtime depending on ecc algorithm and layout selected */ | 114 | /* oob info generated runtime depending on ecc algorithm and layout selected */ |
105 | static struct nand_ecclayout omap_oobinfo; | 115 | static struct nand_ecclayout omap_oobinfo; |
106 | /* Define some generic bad / good block scan pattern which are used | 116 | /* Define some generic bad / good block scan pattern which are used |
@@ -124,15 +134,18 @@ struct omap_nand_info { | |||
124 | 134 | ||
125 | int gpmc_cs; | 135 | int gpmc_cs; |
126 | unsigned long phys_base; | 136 | unsigned long phys_base; |
137 | unsigned long mem_size; | ||
127 | struct completion comp; | 138 | struct completion comp; |
128 | struct dma_chan *dma; | 139 | struct dma_chan *dma; |
129 | int gpmc_irq; | 140 | int gpmc_irq_fifo; |
141 | int gpmc_irq_count; | ||
130 | enum { | 142 | enum { |
131 | OMAP_NAND_IO_READ = 0, /* read */ | 143 | OMAP_NAND_IO_READ = 0, /* read */ |
132 | OMAP_NAND_IO_WRITE, /* write */ | 144 | OMAP_NAND_IO_WRITE, /* write */ |
133 | } iomode; | 145 | } iomode; |
134 | u_char *buf; | 146 | u_char *buf; |
135 | int buf_len; | 147 | int buf_len; |
148 | struct gpmc_nand_regs reg; | ||
136 | 149 | ||
137 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | 150 | #ifdef CONFIG_MTD_NAND_OMAP_BCH |
138 | struct bch_control *bch; | 151 | struct bch_control *bch; |
@@ -141,6 +154,63 @@ struct omap_nand_info { | |||
141 | }; | 154 | }; |
142 | 155 | ||
143 | /** | 156 | /** |
157 | * omap_prefetch_enable - configures and starts prefetch transfer | ||
158 | * @cs: cs (chip select) number | ||
159 | * @fifo_th: fifo threshold to be used for read/ write | ||
160 | * @dma_mode: dma mode enable (1) or disable (0) | ||
161 | * @u32_count: number of bytes to be transferred | ||
162 | * @is_write: prefetch read(0) or write post(1) mode | ||
163 | */ | ||
164 | static int omap_prefetch_enable(int cs, int fifo_th, int dma_mode, | ||
165 | unsigned int u32_count, int is_write, struct omap_nand_info *info) | ||
166 | { | ||
167 | u32 val; | ||
168 | |||
169 | if (fifo_th > PREFETCH_FIFOTHRESHOLD_MAX) | ||
170 | return -1; | ||
171 | |||
172 | if (readl(info->reg.gpmc_prefetch_control)) | ||
173 | return -EBUSY; | ||
174 | |||
175 | /* Set the amount of bytes to be prefetched */ | ||
176 | writel(u32_count, info->reg.gpmc_prefetch_config2); | ||
177 | |||
178 | /* Set dma/mpu mode, the prefetch read / post write and | ||
179 | * enable the engine. Set which cs is has requested for. | ||
180 | */ | ||
181 | val = ((cs << PREFETCH_CONFIG1_CS_SHIFT) | | ||
182 | PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH | | ||
183 | (dma_mode << DMA_MPU_MODE_SHIFT) | (0x1 & is_write)); | ||
184 | writel(val, info->reg.gpmc_prefetch_config1); | ||
185 | |||
186 | /* Start the prefetch engine */ | ||
187 | writel(0x1, info->reg.gpmc_prefetch_control); | ||
188 | |||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * omap_prefetch_reset - disables and stops the prefetch engine | ||
194 | */ | ||
195 | static int omap_prefetch_reset(int cs, struct omap_nand_info *info) | ||
196 | { | ||
197 | u32 config1; | ||
198 | |||
199 | /* check if the same module/cs is trying to reset */ | ||
200 | config1 = readl(info->reg.gpmc_prefetch_config1); | ||
201 | if (((config1 >> PREFETCH_CONFIG1_CS_SHIFT) & CS_MASK) != cs) | ||
202 | return -EINVAL; | ||
203 | |||
204 | /* Stop the PFPW engine */ | ||
205 | writel(0x0, info->reg.gpmc_prefetch_control); | ||
206 | |||
207 | /* Reset/disable the PFPW engine */ | ||
208 | writel(0x0, info->reg.gpmc_prefetch_config1); | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /** | ||
144 | * omap_hwcontrol - hardware specific access to control-lines | 214 | * omap_hwcontrol - hardware specific access to control-lines |
145 | * @mtd: MTD device structure | 215 | * @mtd: MTD device structure |
146 | * @cmd: command to device | 216 | * @cmd: command to device |
@@ -158,13 +228,13 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
158 | 228 | ||
159 | if (cmd != NAND_CMD_NONE) { | 229 | if (cmd != NAND_CMD_NONE) { |
160 | if (ctrl & NAND_CLE) | 230 | if (ctrl & NAND_CLE) |
161 | gpmc_nand_write(info->gpmc_cs, GPMC_NAND_COMMAND, cmd); | 231 | writeb(cmd, info->reg.gpmc_nand_command); |
162 | 232 | ||
163 | else if (ctrl & NAND_ALE) | 233 | else if (ctrl & NAND_ALE) |
164 | gpmc_nand_write(info->gpmc_cs, GPMC_NAND_ADDRESS, cmd); | 234 | writeb(cmd, info->reg.gpmc_nand_address); |
165 | 235 | ||
166 | else /* NAND_NCE */ | 236 | else /* NAND_NCE */ |
167 | gpmc_nand_write(info->gpmc_cs, GPMC_NAND_DATA, cmd); | 237 | writeb(cmd, info->reg.gpmc_nand_data); |
168 | } | 238 | } |
169 | } | 239 | } |
170 | 240 | ||
@@ -198,7 +268,8 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len) | |||
198 | iowrite8(*p++, info->nand.IO_ADDR_W); | 268 | iowrite8(*p++, info->nand.IO_ADDR_W); |
199 | /* wait until buffer is available for write */ | 269 | /* wait until buffer is available for write */ |
200 | do { | 270 | do { |
201 | status = gpmc_read_status(GPMC_STATUS_BUFFER); | 271 | status = readl(info->reg.gpmc_status) & |
272 | GPMC_STATUS_BUFF_EMPTY; | ||
202 | } while (!status); | 273 | } while (!status); |
203 | } | 274 | } |
204 | } | 275 | } |
@@ -235,7 +306,8 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len) | |||
235 | iowrite16(*p++, info->nand.IO_ADDR_W); | 306 | iowrite16(*p++, info->nand.IO_ADDR_W); |
236 | /* wait until buffer is available for write */ | 307 | /* wait until buffer is available for write */ |
237 | do { | 308 | do { |
238 | status = gpmc_read_status(GPMC_STATUS_BUFFER); | 309 | status = readl(info->reg.gpmc_status) & |
310 | GPMC_STATUS_BUFF_EMPTY; | ||
239 | } while (!status); | 311 | } while (!status); |
240 | } | 312 | } |
241 | } | 313 | } |
@@ -265,8 +337,8 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) | |||
265 | } | 337 | } |
266 | 338 | ||
267 | /* configure and start prefetch transfer */ | 339 | /* configure and start prefetch transfer */ |
268 | ret = gpmc_prefetch_enable(info->gpmc_cs, | 340 | ret = omap_prefetch_enable(info->gpmc_cs, |
269 | PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0); | 341 | PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x0, info); |
270 | if (ret) { | 342 | if (ret) { |
271 | /* PFPW engine is busy, use cpu copy method */ | 343 | /* PFPW engine is busy, use cpu copy method */ |
272 | if (info->nand.options & NAND_BUSWIDTH_16) | 344 | if (info->nand.options & NAND_BUSWIDTH_16) |
@@ -275,14 +347,15 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) | |||
275 | omap_read_buf8(mtd, (u_char *)p, len); | 347 | omap_read_buf8(mtd, (u_char *)p, len); |
276 | } else { | 348 | } else { |
277 | do { | 349 | do { |
278 | r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); | 350 | r_count = readl(info->reg.gpmc_prefetch_status); |
351 | r_count = GPMC_PREFETCH_STATUS_FIFO_CNT(r_count); | ||
279 | r_count = r_count >> 2; | 352 | r_count = r_count >> 2; |
280 | ioread32_rep(info->nand.IO_ADDR_R, p, r_count); | 353 | ioread32_rep(info->nand.IO_ADDR_R, p, r_count); |
281 | p += r_count; | 354 | p += r_count; |
282 | len -= r_count << 2; | 355 | len -= r_count << 2; |
283 | } while (len); | 356 | } while (len); |
284 | /* disable and stop the PFPW engine */ | 357 | /* disable and stop the PFPW engine */ |
285 | gpmc_prefetch_reset(info->gpmc_cs); | 358 | omap_prefetch_reset(info->gpmc_cs, info); |
286 | } | 359 | } |
287 | } | 360 | } |
288 | 361 | ||
@@ -301,6 +374,7 @@ static void omap_write_buf_pref(struct mtd_info *mtd, | |||
301 | int i = 0, ret = 0; | 374 | int i = 0, ret = 0; |
302 | u16 *p = (u16 *)buf; | 375 | u16 *p = (u16 *)buf; |
303 | unsigned long tim, limit; | 376 | unsigned long tim, limit; |
377 | u32 val; | ||
304 | 378 | ||
305 | /* take care of subpage writes */ | 379 | /* take care of subpage writes */ |
306 | if (len % 2 != 0) { | 380 | if (len % 2 != 0) { |
@@ -310,8 +384,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, | |||
310 | } | 384 | } |
311 | 385 | ||
312 | /* configure and start prefetch transfer */ | 386 | /* configure and start prefetch transfer */ |
313 | ret = gpmc_prefetch_enable(info->gpmc_cs, | 387 | ret = omap_prefetch_enable(info->gpmc_cs, |
314 | PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1); | 388 | PREFETCH_FIFOTHRESHOLD_MAX, 0x0, len, 0x1, info); |
315 | if (ret) { | 389 | if (ret) { |
316 | /* PFPW engine is busy, use cpu copy method */ | 390 | /* PFPW engine is busy, use cpu copy method */ |
317 | if (info->nand.options & NAND_BUSWIDTH_16) | 391 | if (info->nand.options & NAND_BUSWIDTH_16) |
@@ -320,7 +394,8 @@ static void omap_write_buf_pref(struct mtd_info *mtd, | |||
320 | omap_write_buf8(mtd, (u_char *)p, len); | 394 | omap_write_buf8(mtd, (u_char *)p, len); |
321 | } else { | 395 | } else { |
322 | while (len) { | 396 | while (len) { |
323 | w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); | 397 | w_count = readl(info->reg.gpmc_prefetch_status); |
398 | w_count = GPMC_PREFETCH_STATUS_FIFO_CNT(w_count); | ||
324 | w_count = w_count >> 1; | 399 | w_count = w_count >> 1; |
325 | for (i = 0; (i < w_count) && len; i++, len -= 2) | 400 | for (i = 0; (i < w_count) && len; i++, len -= 2) |
326 | iowrite16(*p++, info->nand.IO_ADDR_W); | 401 | iowrite16(*p++, info->nand.IO_ADDR_W); |
@@ -329,11 +404,14 @@ static void omap_write_buf_pref(struct mtd_info *mtd, | |||
329 | tim = 0; | 404 | tim = 0; |
330 | limit = (loops_per_jiffy * | 405 | limit = (loops_per_jiffy * |
331 | msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); | 406 | msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); |
332 | while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) | 407 | do { |
333 | cpu_relax(); | 408 | cpu_relax(); |
409 | val = readl(info->reg.gpmc_prefetch_status); | ||
410 | val = GPMC_PREFETCH_STATUS_COUNT(val); | ||
411 | } while (val && (tim++ < limit)); | ||
334 | 412 | ||
335 | /* disable and stop the PFPW engine */ | 413 | /* disable and stop the PFPW engine */ |
336 | gpmc_prefetch_reset(info->gpmc_cs); | 414 | omap_prefetch_reset(info->gpmc_cs, info); |
337 | } | 415 | } |
338 | } | 416 | } |
339 | 417 | ||
@@ -365,6 +443,7 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | |||
365 | unsigned long tim, limit; | 443 | unsigned long tim, limit; |
366 | unsigned n; | 444 | unsigned n; |
367 | int ret; | 445 | int ret; |
446 | u32 val; | ||
368 | 447 | ||
369 | if (addr >= high_memory) { | 448 | if (addr >= high_memory) { |
370 | struct page *p1; | 449 | struct page *p1; |
@@ -396,9 +475,9 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | |||
396 | tx->callback_param = &info->comp; | 475 | tx->callback_param = &info->comp; |
397 | dmaengine_submit(tx); | 476 | dmaengine_submit(tx); |
398 | 477 | ||
399 | /* configure and start prefetch transfer */ | 478 | /* configure and start prefetch transfer */ |
400 | ret = gpmc_prefetch_enable(info->gpmc_cs, | 479 | ret = omap_prefetch_enable(info->gpmc_cs, |
401 | PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write); | 480 | PREFETCH_FIFOTHRESHOLD_MAX, 0x1, len, is_write, info); |
402 | if (ret) | 481 | if (ret) |
403 | /* PFPW engine is busy, use cpu copy method */ | 482 | /* PFPW engine is busy, use cpu copy method */ |
404 | goto out_copy_unmap; | 483 | goto out_copy_unmap; |
@@ -410,11 +489,15 @@ static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | |||
410 | wait_for_completion(&info->comp); | 489 | wait_for_completion(&info->comp); |
411 | tim = 0; | 490 | tim = 0; |
412 | limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); | 491 | limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); |
413 | while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) | 492 | |
493 | do { | ||
414 | cpu_relax(); | 494 | cpu_relax(); |
495 | val = readl(info->reg.gpmc_prefetch_status); | ||
496 | val = GPMC_PREFETCH_STATUS_COUNT(val); | ||
497 | } while (val && (tim++ < limit)); | ||
415 | 498 | ||
416 | /* disable and stop the PFPW engine */ | 499 | /* disable and stop the PFPW engine */ |
417 | gpmc_prefetch_reset(info->gpmc_cs); | 500 | omap_prefetch_reset(info->gpmc_cs, info); |
418 | 501 | ||
419 | dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); | 502 | dma_unmap_sg(info->dma->device->dev, &sg, 1, dir); |
420 | return 0; | 503 | return 0; |
@@ -471,13 +554,12 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev) | |||
471 | { | 554 | { |
472 | struct omap_nand_info *info = (struct omap_nand_info *) dev; | 555 | struct omap_nand_info *info = (struct omap_nand_info *) dev; |
473 | u32 bytes; | 556 | u32 bytes; |
474 | u32 irq_stat; | ||
475 | 557 | ||
476 | irq_stat = gpmc_read_status(GPMC_GET_IRQ_STATUS); | 558 | bytes = readl(info->reg.gpmc_prefetch_status); |
477 | bytes = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT); | 559 | bytes = GPMC_PREFETCH_STATUS_FIFO_CNT(bytes); |
478 | bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ | 560 | bytes = bytes & 0xFFFC; /* io in multiple of 4 bytes */ |
479 | if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ | 561 | if (info->iomode == OMAP_NAND_IO_WRITE) { /* checks for write io */ |
480 | if (irq_stat & 0x2) | 562 | if (this_irq == info->gpmc_irq_count) |
481 | goto done; | 563 | goto done; |
482 | 564 | ||
483 | if (info->buf_len && (info->buf_len < bytes)) | 565 | if (info->buf_len && (info->buf_len < bytes)) |
@@ -494,20 +576,17 @@ static irqreturn_t omap_nand_irq(int this_irq, void *dev) | |||
494 | (u32 *)info->buf, bytes >> 2); | 576 | (u32 *)info->buf, bytes >> 2); |
495 | info->buf = info->buf + bytes; | 577 | info->buf = info->buf + bytes; |
496 | 578 | ||
497 | if (irq_stat & 0x2) | 579 | if (this_irq == info->gpmc_irq_count) |
498 | goto done; | 580 | goto done; |
499 | } | 581 | } |
500 | gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); | ||
501 | 582 | ||
502 | return IRQ_HANDLED; | 583 | return IRQ_HANDLED; |
503 | 584 | ||
504 | done: | 585 | done: |
505 | complete(&info->comp); | 586 | complete(&info->comp); |
506 | /* disable irq */ | ||
507 | gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, 0); | ||
508 | 587 | ||
509 | /* clear status */ | 588 | disable_irq_nosync(info->gpmc_irq_fifo); |
510 | gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, irq_stat); | 589 | disable_irq_nosync(info->gpmc_irq_count); |
511 | 590 | ||
512 | return IRQ_HANDLED; | 591 | return IRQ_HANDLED; |
513 | } | 592 | } |
@@ -534,22 +613,22 @@ static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) | |||
534 | init_completion(&info->comp); | 613 | init_completion(&info->comp); |
535 | 614 | ||
536 | /* configure and start prefetch transfer */ | 615 | /* configure and start prefetch transfer */ |
537 | ret = gpmc_prefetch_enable(info->gpmc_cs, | 616 | ret = omap_prefetch_enable(info->gpmc_cs, |
538 | PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0); | 617 | PREFETCH_FIFOTHRESHOLD_MAX/2, 0x0, len, 0x0, info); |
539 | if (ret) | 618 | if (ret) |
540 | /* PFPW engine is busy, use cpu copy method */ | 619 | /* PFPW engine is busy, use cpu copy method */ |
541 | goto out_copy; | 620 | goto out_copy; |
542 | 621 | ||
543 | info->buf_len = len; | 622 | info->buf_len = len; |
544 | /* enable irq */ | 623 | |
545 | gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, | 624 | enable_irq(info->gpmc_irq_count); |
546 | (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT)); | 625 | enable_irq(info->gpmc_irq_fifo); |
547 | 626 | ||
548 | /* waiting for read to complete */ | 627 | /* waiting for read to complete */ |
549 | wait_for_completion(&info->comp); | 628 | wait_for_completion(&info->comp); |
550 | 629 | ||
551 | /* disable and stop the PFPW engine */ | 630 | /* disable and stop the PFPW engine */ |
552 | gpmc_prefetch_reset(info->gpmc_cs); | 631 | omap_prefetch_reset(info->gpmc_cs, info); |
553 | return; | 632 | return; |
554 | 633 | ||
555 | out_copy: | 634 | out_copy: |
@@ -572,6 +651,7 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, | |||
572 | struct omap_nand_info, mtd); | 651 | struct omap_nand_info, mtd); |
573 | int ret = 0; | 652 | int ret = 0; |
574 | unsigned long tim, limit; | 653 | unsigned long tim, limit; |
654 | u32 val; | ||
575 | 655 | ||
576 | if (len <= mtd->oobsize) { | 656 | if (len <= mtd->oobsize) { |
577 | omap_write_buf_pref(mtd, buf, len); | 657 | omap_write_buf_pref(mtd, buf, len); |
@@ -583,27 +663,31 @@ static void omap_write_buf_irq_pref(struct mtd_info *mtd, | |||
583 | init_completion(&info->comp); | 663 | init_completion(&info->comp); |
584 | 664 | ||
585 | /* configure and start prefetch transfer : size=24 */ | 665 | /* configure and start prefetch transfer : size=24 */ |
586 | ret = gpmc_prefetch_enable(info->gpmc_cs, | 666 | ret = omap_prefetch_enable(info->gpmc_cs, |
587 | (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1); | 667 | (PREFETCH_FIFOTHRESHOLD_MAX * 3) / 8, 0x0, len, 0x1, info); |
588 | if (ret) | 668 | if (ret) |
589 | /* PFPW engine is busy, use cpu copy method */ | 669 | /* PFPW engine is busy, use cpu copy method */ |
590 | goto out_copy; | 670 | goto out_copy; |
591 | 671 | ||
592 | info->buf_len = len; | 672 | info->buf_len = len; |
593 | /* enable irq */ | 673 | |
594 | gpmc_cs_configure(info->gpmc_cs, GPMC_ENABLE_IRQ, | 674 | enable_irq(info->gpmc_irq_count); |
595 | (GPMC_IRQ_FIFOEVENTENABLE | GPMC_IRQ_COUNT_EVENT)); | 675 | enable_irq(info->gpmc_irq_fifo); |
596 | 676 | ||
597 | /* waiting for write to complete */ | 677 | /* waiting for write to complete */ |
598 | wait_for_completion(&info->comp); | 678 | wait_for_completion(&info->comp); |
679 | |||
599 | /* wait for data to flushed-out before reset the prefetch */ | 680 | /* wait for data to flushed-out before reset the prefetch */ |
600 | tim = 0; | 681 | tim = 0; |
601 | limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); | 682 | limit = (loops_per_jiffy * msecs_to_jiffies(OMAP_NAND_TIMEOUT_MS)); |
602 | while (gpmc_read_status(GPMC_PREFETCH_COUNT) && (tim++ < limit)) | 683 | do { |
684 | val = readl(info->reg.gpmc_prefetch_status); | ||
685 | val = GPMC_PREFETCH_STATUS_COUNT(val); | ||
603 | cpu_relax(); | 686 | cpu_relax(); |
687 | } while (val && (tim++ < limit)); | ||
604 | 688 | ||
605 | /* disable and stop the PFPW engine */ | 689 | /* disable and stop the PFPW engine */ |
606 | gpmc_prefetch_reset(info->gpmc_cs); | 690 | omap_prefetch_reset(info->gpmc_cs, info); |
607 | return; | 691 | return; |
608 | 692 | ||
609 | out_copy: | 693 | out_copy: |
@@ -843,7 +927,20 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | |||
843 | { | 927 | { |
844 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 928 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, |
845 | mtd); | 929 | mtd); |
846 | return gpmc_calculate_ecc(info->gpmc_cs, dat, ecc_code); | 930 | u32 val; |
931 | |||
932 | val = readl(info->reg.gpmc_ecc_config); | ||
933 | if (((val >> ECC_CONFIG_CS_SHIFT) & ~CS_MASK) != info->gpmc_cs) | ||
934 | return -EINVAL; | ||
935 | |||
936 | /* read ecc result */ | ||
937 | val = readl(info->reg.gpmc_ecc1_result); | ||
938 | *ecc_code++ = val; /* P128e, ..., P1e */ | ||
939 | *ecc_code++ = val >> 16; /* P128o, ..., P1o */ | ||
940 | /* P2048o, P1024o, P512o, P256o, P2048e, P1024e, P512e, P256e */ | ||
941 | *ecc_code++ = ((val >> 8) & 0x0f) | ((val >> 20) & 0xf0); | ||
942 | |||
943 | return 0; | ||
847 | } | 944 | } |
848 | 945 | ||
849 | /** | 946 | /** |
@@ -857,8 +954,34 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) | |||
857 | mtd); | 954 | mtd); |
858 | struct nand_chip *chip = mtd->priv; | 955 | struct nand_chip *chip = mtd->priv; |
859 | unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; | 956 | unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; |
957 | u32 val; | ||
958 | |||
959 | /* clear ecc and enable bits */ | ||
960 | val = ECCCLEAR | ECC1; | ||
961 | writel(val, info->reg.gpmc_ecc_control); | ||
962 | |||
963 | /* program ecc and result sizes */ | ||
964 | val = ((((info->nand.ecc.size >> 1) - 1) << ECCSIZE1_SHIFT) | | ||
965 | ECC1RESULTSIZE); | ||
966 | writel(val, info->reg.gpmc_ecc_size_config); | ||
860 | 967 | ||
861 | gpmc_enable_hwecc(info->gpmc_cs, mode, dev_width, info->nand.ecc.size); | 968 | switch (mode) { |
969 | case NAND_ECC_READ: | ||
970 | case NAND_ECC_WRITE: | ||
971 | writel(ECCCLEAR | ECC1, info->reg.gpmc_ecc_control); | ||
972 | break; | ||
973 | case NAND_ECC_READSYN: | ||
974 | writel(ECCCLEAR, info->reg.gpmc_ecc_control); | ||
975 | break; | ||
976 | default: | ||
977 | dev_info(&info->pdev->dev, | ||
978 | "error: unrecognized Mode[%d]!\n", mode); | ||
979 | break; | ||
980 | } | ||
981 | |||
982 | /* (ECC 16 or 8 bit col) | ( CS ) | ECC Enable */ | ||
983 | val = (dev_width << 7) | (info->gpmc_cs << 1) | (0x1); | ||
984 | writel(val, info->reg.gpmc_ecc_config); | ||
862 | } | 985 | } |
863 | 986 | ||
864 | /** | 987 | /** |
@@ -886,10 +1009,9 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
886 | else | 1009 | else |
887 | timeo += (HZ * 20) / 1000; | 1010 | timeo += (HZ * 20) / 1000; |
888 | 1011 | ||
889 | gpmc_nand_write(info->gpmc_cs, | 1012 | writeb(NAND_CMD_STATUS & 0xFF, info->reg.gpmc_nand_command); |
890 | GPMC_NAND_COMMAND, (NAND_CMD_STATUS & 0xFF)); | ||
891 | while (time_before(jiffies, timeo)) { | 1013 | while (time_before(jiffies, timeo)) { |
892 | status = gpmc_nand_read(info->gpmc_cs, GPMC_NAND_DATA); | 1014 | status = readb(info->reg.gpmc_nand_data); |
893 | if (status & NAND_STATUS_READY) | 1015 | if (status & NAND_STATUS_READY) |
894 | break; | 1016 | break; |
895 | cond_resched(); | 1017 | cond_resched(); |
@@ -909,22 +1031,13 @@ static int omap_dev_ready(struct mtd_info *mtd) | |||
909 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 1031 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, |
910 | mtd); | 1032 | mtd); |
911 | 1033 | ||
912 | val = gpmc_read_status(GPMC_GET_IRQ_STATUS); | 1034 | val = readl(info->reg.gpmc_status); |
1035 | |||
913 | if ((val & 0x100) == 0x100) { | 1036 | if ((val & 0x100) == 0x100) { |
914 | /* Clear IRQ Interrupt */ | 1037 | return 1; |
915 | val |= 0x100; | ||
916 | val &= ~(0x0); | ||
917 | gpmc_cs_configure(info->gpmc_cs, GPMC_SET_IRQ_STATUS, val); | ||
918 | } else { | 1038 | } else { |
919 | unsigned int cnt = 0; | 1039 | return 0; |
920 | while (cnt++ < 0x1FF) { | ||
921 | if ((val & 0x100) == 0x100) | ||
922 | return 0; | ||
923 | val = gpmc_read_status(GPMC_GET_IRQ_STATUS); | ||
924 | } | ||
925 | } | 1040 | } |
926 | |||
927 | return 1; | ||
928 | } | 1041 | } |
929 | 1042 | ||
930 | #ifdef CONFIG_MTD_NAND_OMAP_BCH | 1043 | #ifdef CONFIG_MTD_NAND_OMAP_BCH |
@@ -1155,6 +1268,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1155 | int i, offset; | 1268 | int i, offset; |
1156 | dma_cap_mask_t mask; | 1269 | dma_cap_mask_t mask; |
1157 | unsigned sig; | 1270 | unsigned sig; |
1271 | struct resource *res; | ||
1158 | 1272 | ||
1159 | pdata = pdev->dev.platform_data; | 1273 | pdata = pdev->dev.platform_data; |
1160 | if (pdata == NULL) { | 1274 | if (pdata == NULL) { |
@@ -1174,7 +1288,7 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1174 | info->pdev = pdev; | 1288 | info->pdev = pdev; |
1175 | 1289 | ||
1176 | info->gpmc_cs = pdata->cs; | 1290 | info->gpmc_cs = pdata->cs; |
1177 | info->phys_base = pdata->phys_base; | 1291 | info->reg = pdata->reg; |
1178 | 1292 | ||
1179 | info->mtd.priv = &info->nand; | 1293 | info->mtd.priv = &info->nand; |
1180 | info->mtd.name = dev_name(&pdev->dev); | 1294 | info->mtd.name = dev_name(&pdev->dev); |
@@ -1183,16 +1297,23 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1183 | info->nand.options = pdata->devsize; | 1297 | info->nand.options = pdata->devsize; |
1184 | info->nand.options |= NAND_SKIP_BBTSCAN; | 1298 | info->nand.options |= NAND_SKIP_BBTSCAN; |
1185 | 1299 | ||
1186 | /* NAND write protect off */ | 1300 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1187 | gpmc_cs_configure(info->gpmc_cs, GPMC_CONFIG_WP, 0); | 1301 | if (res == NULL) { |
1302 | err = -EINVAL; | ||
1303 | dev_err(&pdev->dev, "error getting memory resource\n"); | ||
1304 | goto out_free_info; | ||
1305 | } | ||
1306 | |||
1307 | info->phys_base = res->start; | ||
1308 | info->mem_size = resource_size(res); | ||
1188 | 1309 | ||
1189 | if (!request_mem_region(info->phys_base, NAND_IO_SIZE, | 1310 | if (!request_mem_region(info->phys_base, info->mem_size, |
1190 | pdev->dev.driver->name)) { | 1311 | pdev->dev.driver->name)) { |
1191 | err = -EBUSY; | 1312 | err = -EBUSY; |
1192 | goto out_free_info; | 1313 | goto out_free_info; |
1193 | } | 1314 | } |
1194 | 1315 | ||
1195 | info->nand.IO_ADDR_R = ioremap(info->phys_base, NAND_IO_SIZE); | 1316 | info->nand.IO_ADDR_R = ioremap(info->phys_base, info->mem_size); |
1196 | if (!info->nand.IO_ADDR_R) { | 1317 | if (!info->nand.IO_ADDR_R) { |
1197 | err = -ENOMEM; | 1318 | err = -ENOMEM; |
1198 | goto out_release_mem_region; | 1319 | goto out_release_mem_region; |
@@ -1265,17 +1386,39 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1265 | break; | 1386 | break; |
1266 | 1387 | ||
1267 | case NAND_OMAP_PREFETCH_IRQ: | 1388 | case NAND_OMAP_PREFETCH_IRQ: |
1268 | err = request_irq(pdata->gpmc_irq, | 1389 | info->gpmc_irq_fifo = platform_get_irq(pdev, 0); |
1269 | omap_nand_irq, IRQF_SHARED, "gpmc-nand", info); | 1390 | if (info->gpmc_irq_fifo <= 0) { |
1391 | dev_err(&pdev->dev, "error getting fifo irq\n"); | ||
1392 | err = -ENODEV; | ||
1393 | goto out_release_mem_region; | ||
1394 | } | ||
1395 | err = request_irq(info->gpmc_irq_fifo, omap_nand_irq, | ||
1396 | IRQF_SHARED, "gpmc-nand-fifo", info); | ||
1270 | if (err) { | 1397 | if (err) { |
1271 | dev_err(&pdev->dev, "requesting irq(%d) error:%d", | 1398 | dev_err(&pdev->dev, "requesting irq(%d) error:%d", |
1272 | pdata->gpmc_irq, err); | 1399 | info->gpmc_irq_fifo, err); |
1400 | info->gpmc_irq_fifo = 0; | ||
1401 | goto out_release_mem_region; | ||
1402 | } | ||
1403 | |||
1404 | info->gpmc_irq_count = platform_get_irq(pdev, 1); | ||
1405 | if (info->gpmc_irq_count <= 0) { | ||
1406 | dev_err(&pdev->dev, "error getting count irq\n"); | ||
1407 | err = -ENODEV; | ||
1408 | goto out_release_mem_region; | ||
1409 | } | ||
1410 | err = request_irq(info->gpmc_irq_count, omap_nand_irq, | ||
1411 | IRQF_SHARED, "gpmc-nand-count", info); | ||
1412 | if (err) { | ||
1413 | dev_err(&pdev->dev, "requesting irq(%d) error:%d", | ||
1414 | info->gpmc_irq_count, err); | ||
1415 | info->gpmc_irq_count = 0; | ||
1273 | goto out_release_mem_region; | 1416 | goto out_release_mem_region; |
1274 | } else { | ||
1275 | info->gpmc_irq = pdata->gpmc_irq; | ||
1276 | info->nand.read_buf = omap_read_buf_irq_pref; | ||
1277 | info->nand.write_buf = omap_write_buf_irq_pref; | ||
1278 | } | 1417 | } |
1418 | |||
1419 | info->nand.read_buf = omap_read_buf_irq_pref; | ||
1420 | info->nand.write_buf = omap_write_buf_irq_pref; | ||
1421 | |||
1279 | break; | 1422 | break; |
1280 | 1423 | ||
1281 | default: | 1424 | default: |
@@ -1363,7 +1506,11 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1363 | out_release_mem_region: | 1506 | out_release_mem_region: |
1364 | if (info->dma) | 1507 | if (info->dma) |
1365 | dma_release_channel(info->dma); | 1508 | dma_release_channel(info->dma); |
1366 | release_mem_region(info->phys_base, NAND_IO_SIZE); | 1509 | if (info->gpmc_irq_count > 0) |
1510 | free_irq(info->gpmc_irq_count, info); | ||
1511 | if (info->gpmc_irq_fifo > 0) | ||
1512 | free_irq(info->gpmc_irq_fifo, info); | ||
1513 | release_mem_region(info->phys_base, info->mem_size); | ||
1367 | out_free_info: | 1514 | out_free_info: |
1368 | kfree(info); | 1515 | kfree(info); |
1369 | 1516 | ||
@@ -1381,8 +1528,10 @@ static int omap_nand_remove(struct platform_device *pdev) | |||
1381 | if (info->dma) | 1528 | if (info->dma) |
1382 | dma_release_channel(info->dma); | 1529 | dma_release_channel(info->dma); |
1383 | 1530 | ||
1384 | if (info->gpmc_irq) | 1531 | if (info->gpmc_irq_count > 0) |
1385 | free_irq(info->gpmc_irq, info); | 1532 | free_irq(info->gpmc_irq_count, info); |
1533 | if (info->gpmc_irq_fifo > 0) | ||
1534 | free_irq(info->gpmc_irq_fifo, info); | ||
1386 | 1535 | ||
1387 | /* Release NAND device, its internal structures and partitions */ | 1536 | /* Release NAND device, its internal structures and partitions */ |
1388 | nand_release(&info->mtd); | 1537 | nand_release(&info->mtd); |
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index fc5a868c436e..131b58a133f1 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <asm/io.h> | 22 | #include <asm/io.h> |
23 | #include <asm/sizes.h> | 23 | #include <asm/sizes.h> |
24 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
25 | #include <plat/orion_nand.h> | 25 | #include <linux/platform_data/mtd-orion_nand.h> |
26 | 26 | ||
27 | static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 27 | static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
28 | { | 28 | { |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 252aaefcacfa..c45227173efd 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -22,9 +22,11 @@ | |||
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | #include <linux/irq.h> | 23 | #include <linux/irq.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/of.h> | ||
26 | #include <linux/of_device.h> | ||
25 | 27 | ||
26 | #include <mach/dma.h> | 28 | #include <mach/dma.h> |
27 | #include <plat/pxa3xx_nand.h> | 29 | #include <linux/platform_data/mtd-nand-pxa3xx.h> |
28 | 30 | ||
29 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) | 31 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) |
30 | #define NAND_STOP_DELAY (2 * HZ/50) | 32 | #define NAND_STOP_DELAY (2 * HZ/50) |
@@ -1032,7 +1034,7 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
1032 | struct pxa3xx_nand_platform_data *pdata; | 1034 | struct pxa3xx_nand_platform_data *pdata; |
1033 | struct pxa3xx_nand_info *info; | 1035 | struct pxa3xx_nand_info *info; |
1034 | struct pxa3xx_nand_host *host; | 1036 | struct pxa3xx_nand_host *host; |
1035 | struct nand_chip *chip; | 1037 | struct nand_chip *chip = NULL; |
1036 | struct mtd_info *mtd; | 1038 | struct mtd_info *mtd; |
1037 | struct resource *r; | 1039 | struct resource *r; |
1038 | int ret, irq, cs; | 1040 | int ret, irq, cs; |
@@ -1081,21 +1083,31 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
1081 | } | 1083 | } |
1082 | clk_enable(info->clk); | 1084 | clk_enable(info->clk); |
1083 | 1085 | ||
1084 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | 1086 | /* |
1085 | if (r == NULL) { | 1087 | * This is a dirty hack to make this driver work from devicetree |
1086 | dev_err(&pdev->dev, "no resource defined for data DMA\n"); | 1088 | * bindings. It can be removed once we have a prober DMA controller |
1087 | ret = -ENXIO; | 1089 | * framework for DT. |
1088 | goto fail_put_clk; | 1090 | */ |
1089 | } | 1091 | if (pdev->dev.of_node && cpu_is_pxa3xx()) { |
1090 | info->drcmr_dat = r->start; | 1092 | info->drcmr_dat = 97; |
1093 | info->drcmr_cmd = 99; | ||
1094 | } else { | ||
1095 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
1096 | if (r == NULL) { | ||
1097 | dev_err(&pdev->dev, "no resource defined for data DMA\n"); | ||
1098 | ret = -ENXIO; | ||
1099 | goto fail_put_clk; | ||
1100 | } | ||
1101 | info->drcmr_dat = r->start; | ||
1091 | 1102 | ||
1092 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | 1103 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); |
1093 | if (r == NULL) { | 1104 | if (r == NULL) { |
1094 | dev_err(&pdev->dev, "no resource defined for command DMA\n"); | 1105 | dev_err(&pdev->dev, "no resource defined for command DMA\n"); |
1095 | ret = -ENXIO; | 1106 | ret = -ENXIO; |
1096 | goto fail_put_clk; | 1107 | goto fail_put_clk; |
1108 | } | ||
1109 | info->drcmr_cmd = r->start; | ||
1097 | } | 1110 | } |
1098 | info->drcmr_cmd = r->start; | ||
1099 | 1111 | ||
1100 | irq = platform_get_irq(pdev, 0); | 1112 | irq = platform_get_irq(pdev, 0); |
1101 | if (irq < 0) { | 1113 | if (irq < 0) { |
@@ -1200,12 +1212,55 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) | |||
1200 | return 0; | 1212 | return 0; |
1201 | } | 1213 | } |
1202 | 1214 | ||
1215 | #ifdef CONFIG_OF | ||
1216 | static struct of_device_id pxa3xx_nand_dt_ids[] = { | ||
1217 | { .compatible = "marvell,pxa3xx-nand" }, | ||
1218 | {} | ||
1219 | }; | ||
1220 | MODULE_DEVICE_TABLE(of, i2c_pxa_dt_ids); | ||
1221 | |||
1222 | static int pxa3xx_nand_probe_dt(struct platform_device *pdev) | ||
1223 | { | ||
1224 | struct pxa3xx_nand_platform_data *pdata; | ||
1225 | struct device_node *np = pdev->dev.of_node; | ||
1226 | const struct of_device_id *of_id = | ||
1227 | of_match_device(pxa3xx_nand_dt_ids, &pdev->dev); | ||
1228 | |||
1229 | if (!of_id) | ||
1230 | return 0; | ||
1231 | |||
1232 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1233 | if (!pdata) | ||
1234 | return -ENOMEM; | ||
1235 | |||
1236 | if (of_get_property(np, "marvell,nand-enable-arbiter", NULL)) | ||
1237 | pdata->enable_arbiter = 1; | ||
1238 | if (of_get_property(np, "marvell,nand-keep-config", NULL)) | ||
1239 | pdata->keep_config = 1; | ||
1240 | of_property_read_u32(np, "num-cs", &pdata->num_cs); | ||
1241 | |||
1242 | pdev->dev.platform_data = pdata; | ||
1243 | |||
1244 | return 0; | ||
1245 | } | ||
1246 | #else | ||
1247 | static inline int pxa3xx_nand_probe_dt(struct platform_device *pdev) | ||
1248 | { | ||
1249 | return 0; | ||
1250 | } | ||
1251 | #endif | ||
1252 | |||
1203 | static int pxa3xx_nand_probe(struct platform_device *pdev) | 1253 | static int pxa3xx_nand_probe(struct platform_device *pdev) |
1204 | { | 1254 | { |
1205 | struct pxa3xx_nand_platform_data *pdata; | 1255 | struct pxa3xx_nand_platform_data *pdata; |
1256 | struct mtd_part_parser_data ppdata = {}; | ||
1206 | struct pxa3xx_nand_info *info; | 1257 | struct pxa3xx_nand_info *info; |
1207 | int ret, cs, probe_success; | 1258 | int ret, cs, probe_success; |
1208 | 1259 | ||
1260 | ret = pxa3xx_nand_probe_dt(pdev); | ||
1261 | if (ret) | ||
1262 | return ret; | ||
1263 | |||
1209 | pdata = pdev->dev.platform_data; | 1264 | pdata = pdev->dev.platform_data; |
1210 | if (!pdata) { | 1265 | if (!pdata) { |
1211 | dev_err(&pdev->dev, "no platform data defined\n"); | 1266 | dev_err(&pdev->dev, "no platform data defined\n"); |
@@ -1229,8 +1284,9 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1229 | continue; | 1284 | continue; |
1230 | } | 1285 | } |
1231 | 1286 | ||
1287 | ppdata.of_node = pdev->dev.of_node; | ||
1232 | ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, | 1288 | ret = mtd_device_parse_register(info->host[cs]->mtd, NULL, |
1233 | NULL, pdata->parts[cs], | 1289 | &ppdata, pdata->parts[cs], |
1234 | pdata->nr_parts[cs]); | 1290 | pdata->nr_parts[cs]); |
1235 | if (!ret) | 1291 | if (!ret) |
1236 | probe_success = 1; | 1292 | probe_success = 1; |
@@ -1306,6 +1362,7 @@ static int pxa3xx_nand_resume(struct platform_device *pdev) | |||
1306 | static struct platform_driver pxa3xx_nand_driver = { | 1362 | static struct platform_driver pxa3xx_nand_driver = { |
1307 | .driver = { | 1363 | .driver = { |
1308 | .name = "pxa3xx-nand", | 1364 | .name = "pxa3xx-nand", |
1365 | .of_match_table = of_match_ptr(pxa3xx_nand_dt_ids), | ||
1309 | }, | 1366 | }, |
1310 | .probe = pxa3xx_nand_probe, | 1367 | .probe = pxa3xx_nand_probe, |
1311 | .remove = pxa3xx_nand_remove, | 1368 | .remove = pxa3xx_nand_remove, |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 91121f33f743..d8040619ad8d 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -46,7 +46,7 @@ | |||
46 | #include <asm/io.h> | 46 | #include <asm/io.h> |
47 | 47 | ||
48 | #include <plat/regs-nand.h> | 48 | #include <plat/regs-nand.h> |
49 | #include <plat/nand.h> | 49 | #include <linux/platform_data/mtd-nand-s3c2410.h> |
50 | 50 | ||
51 | #ifdef CONFIG_MTD_NAND_S3C2410_HWECC | 51 | #ifdef CONFIG_MTD_NAND_S3C2410_HWECC |
52 | static int hardware_ecc = 1; | 52 | static int hardware_ecc = 1; |
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 398a82783848..1961be985171 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c | |||
@@ -39,22 +39,21 @@ | |||
39 | 39 | ||
40 | #include <asm/mach/flash.h> | 40 | #include <asm/mach/flash.h> |
41 | #include <plat/gpmc.h> | 41 | #include <plat/gpmc.h> |
42 | #include <plat/onenand.h> | 42 | #include <linux/platform_data/mtd-onenand-omap2.h> |
43 | #include <asm/gpio.h> | 43 | #include <asm/gpio.h> |
44 | 44 | ||
45 | #include <plat/dma.h> | 45 | #include <plat/dma.h> |
46 | 46 | #include <plat/cpu.h> | |
47 | #include <plat/board.h> | ||
48 | 47 | ||
49 | #define DRIVER_NAME "omap2-onenand" | 48 | #define DRIVER_NAME "omap2-onenand" |
50 | 49 | ||
51 | #define ONENAND_IO_SIZE SZ_128K | ||
52 | #define ONENAND_BUFRAM_SIZE (1024 * 5) | 50 | #define ONENAND_BUFRAM_SIZE (1024 * 5) |
53 | 51 | ||
54 | struct omap2_onenand { | 52 | struct omap2_onenand { |
55 | struct platform_device *pdev; | 53 | struct platform_device *pdev; |
56 | int gpmc_cs; | 54 | int gpmc_cs; |
57 | unsigned long phys_base; | 55 | unsigned long phys_base; |
56 | unsigned int mem_size; | ||
58 | int gpio_irq; | 57 | int gpio_irq; |
59 | struct mtd_info mtd; | 58 | struct mtd_info mtd; |
60 | struct onenand_chip onenand; | 59 | struct onenand_chip onenand; |
@@ -626,6 +625,7 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) | |||
626 | struct omap2_onenand *c; | 625 | struct omap2_onenand *c; |
627 | struct onenand_chip *this; | 626 | struct onenand_chip *this; |
628 | int r; | 627 | int r; |
628 | struct resource *res; | ||
629 | 629 | ||
630 | pdata = pdev->dev.platform_data; | 630 | pdata = pdev->dev.platform_data; |
631 | if (pdata == NULL) { | 631 | if (pdata == NULL) { |
@@ -647,20 +647,24 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev) | |||
647 | c->gpio_irq = 0; | 647 | c->gpio_irq = 0; |
648 | } | 648 | } |
649 | 649 | ||
650 | r = gpmc_cs_request(c->gpmc_cs, ONENAND_IO_SIZE, &c->phys_base); | 650 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
651 | if (r < 0) { | 651 | if (res == NULL) { |
652 | dev_err(&pdev->dev, "Cannot request GPMC CS\n"); | 652 | r = -EINVAL; |
653 | dev_err(&pdev->dev, "error getting memory resource\n"); | ||
653 | goto err_kfree; | 654 | goto err_kfree; |
654 | } | 655 | } |
655 | 656 | ||
656 | if (request_mem_region(c->phys_base, ONENAND_IO_SIZE, | 657 | c->phys_base = res->start; |
658 | c->mem_size = resource_size(res); | ||
659 | |||
660 | if (request_mem_region(c->phys_base, c->mem_size, | ||
657 | pdev->dev.driver->name) == NULL) { | 661 | pdev->dev.driver->name) == NULL) { |
658 | dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, " | 662 | dev_err(&pdev->dev, "Cannot reserve memory region at 0x%08lx, size: 0x%x\n", |
659 | "size: 0x%x\n", c->phys_base, ONENAND_IO_SIZE); | 663 | c->phys_base, c->mem_size); |
660 | r = -EBUSY; | 664 | r = -EBUSY; |
661 | goto err_free_cs; | 665 | goto err_kfree; |
662 | } | 666 | } |
663 | c->onenand.base = ioremap(c->phys_base, ONENAND_IO_SIZE); | 667 | c->onenand.base = ioremap(c->phys_base, c->mem_size); |
664 | if (c->onenand.base == NULL) { | 668 | if (c->onenand.base == NULL) { |
665 | r = -ENOMEM; | 669 | r = -ENOMEM; |
666 | goto err_release_mem_region; | 670 | goto err_release_mem_region; |
@@ -776,9 +780,7 @@ err_release_gpio: | |||
776 | err_iounmap: | 780 | err_iounmap: |
777 | iounmap(c->onenand.base); | 781 | iounmap(c->onenand.base); |
778 | err_release_mem_region: | 782 | err_release_mem_region: |
779 | release_mem_region(c->phys_base, ONENAND_IO_SIZE); | 783 | release_mem_region(c->phys_base, c->mem_size); |
780 | err_free_cs: | ||
781 | gpmc_cs_free(c->gpmc_cs); | ||
782 | err_kfree: | 784 | err_kfree: |
783 | kfree(c); | 785 | kfree(c); |
784 | 786 | ||
@@ -800,7 +802,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev) | |||
800 | gpio_free(c->gpio_irq); | 802 | gpio_free(c->gpio_irq); |
801 | } | 803 | } |
802 | iounmap(c->onenand.base); | 804 | iounmap(c->onenand.base); |
803 | release_mem_region(c->phys_base, ONENAND_IO_SIZE); | 805 | release_mem_region(c->phys_base, c->mem_size); |
804 | gpmc_cs_free(c->gpmc_cs); | 806 | gpmc_cs_free(c->gpmc_cs); |
805 | kfree(c); | 807 | kfree(c); |
806 | 808 | ||
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index a580db29e503..26e7129332ab 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c | |||
@@ -83,6 +83,11 @@ | |||
83 | #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) | 83 | #define INSTRUCTION_LOAD_TXB(n) (0x40 + 2 * (n)) |
84 | #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) | 84 | #define INSTRUCTION_READ_RXB(n) (((n) == 0) ? 0x90 : 0x94) |
85 | #define INSTRUCTION_RESET 0xC0 | 85 | #define INSTRUCTION_RESET 0xC0 |
86 | #define RTS_TXB0 0x01 | ||
87 | #define RTS_TXB1 0x02 | ||
88 | #define RTS_TXB2 0x04 | ||
89 | #define INSTRUCTION_RTS(n) (0x80 | ((n) & 0x07)) | ||
90 | |||
86 | 91 | ||
87 | /* MPC251x registers */ | 92 | /* MPC251x registers */ |
88 | #define CANSTAT 0x0e | 93 | #define CANSTAT 0x0e |
@@ -397,6 +402,7 @@ static void mcp251x_hw_tx_frame(struct spi_device *spi, u8 *buf, | |||
397 | static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, | 402 | static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, |
398 | int tx_buf_idx) | 403 | int tx_buf_idx) |
399 | { | 404 | { |
405 | struct mcp251x_priv *priv = dev_get_drvdata(&spi->dev); | ||
400 | u32 sid, eid, exide, rtr; | 406 | u32 sid, eid, exide, rtr; |
401 | u8 buf[SPI_TRANSFER_BUF_LEN]; | 407 | u8 buf[SPI_TRANSFER_BUF_LEN]; |
402 | 408 | ||
@@ -418,7 +424,10 @@ static void mcp251x_hw_tx(struct spi_device *spi, struct can_frame *frame, | |||
418 | buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; | 424 | buf[TXBDLC_OFF] = (rtr << DLC_RTR_SHIFT) | frame->can_dlc; |
419 | memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); | 425 | memcpy(buf + TXBDAT_OFF, frame->data, frame->can_dlc); |
420 | mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); | 426 | mcp251x_hw_tx_frame(spi, buf, frame->can_dlc, tx_buf_idx); |
421 | mcp251x_write_reg(spi, TXBCTRL(tx_buf_idx), TXBCTRL_TXREQ); | 427 | |
428 | /* use INSTRUCTION_RTS, to avoid "repeated frame problem" */ | ||
429 | priv->spi_tx_buf[0] = INSTRUCTION_RTS(1 << tx_buf_idx); | ||
430 | mcp251x_spi_trans(priv->spi, 1); | ||
422 | } | 431 | } |
423 | 432 | ||
424 | static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, | 433 | static void mcp251x_hw_rx_frame(struct spi_device *spi, u8 *buf, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 21b553229ea4..dfd86a55f1dc 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -710,17 +710,15 @@ static inline u16 bnx2x_tx_avail(struct bnx2x *bp, | |||
710 | prod = txdata->tx_bd_prod; | 710 | prod = txdata->tx_bd_prod; |
711 | cons = txdata->tx_bd_cons; | 711 | cons = txdata->tx_bd_cons; |
712 | 712 | ||
713 | /* NUM_TX_RINGS = number of "next-page" entries | 713 | used = SUB_S16(prod, cons); |
714 | It will be used as a threshold */ | ||
715 | used = SUB_S16(prod, cons) + (s16)NUM_TX_RINGS; | ||
716 | 714 | ||
717 | #ifdef BNX2X_STOP_ON_ERROR | 715 | #ifdef BNX2X_STOP_ON_ERROR |
718 | WARN_ON(used < 0); | 716 | WARN_ON(used < 0); |
719 | WARN_ON(used > bp->tx_ring_size); | 717 | WARN_ON(used > txdata->tx_ring_size); |
720 | WARN_ON((bp->tx_ring_size - used) > MAX_TX_AVAIL); | 718 | WARN_ON((txdata->tx_ring_size - used) > MAX_TX_AVAIL); |
721 | #endif | 719 | #endif |
722 | 720 | ||
723 | return (s16)(bp->tx_ring_size) - used; | 721 | return (s16)(txdata->tx_ring_size) - used; |
724 | } | 722 | } |
725 | 723 | ||
726 | static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) | 724 | static inline int bnx2x_tx_queue_has_work(struct bnx2x_fp_txdata *txdata) |
@@ -1088,6 +1086,7 @@ static inline void bnx2x_init_txdata(struct bnx2x *bp, | |||
1088 | txdata->txq_index = txq_index; | 1086 | txdata->txq_index = txq_index; |
1089 | txdata->tx_cons_sb = tx_cons_sb; | 1087 | txdata->tx_cons_sb = tx_cons_sb; |
1090 | txdata->parent_fp = fp; | 1088 | txdata->parent_fp = fp; |
1089 | txdata->tx_ring_size = IS_FCOE_FP(fp) ? MAX_TX_AVAIL : bp->tx_ring_size; | ||
1091 | 1090 | ||
1092 | DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", | 1091 | DP(NETIF_MSG_IFUP, "created tx data cid %d, txq %d\n", |
1093 | txdata->cid, txdata->txq_index); | 1092 | txdata->cid, txdata->txq_index); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h index 3e4cff9b1ebe..b926f58e983b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h | |||
@@ -401,11 +401,11 @@ static const struct reg_addr reg_addrs[] = { | |||
401 | { 0x70000, 8, RI_ALL_ONLINE }, | 401 | { 0x70000, 8, RI_ALL_ONLINE }, |
402 | { 0x70020, 8184, RI_ALL_OFFLINE }, | 402 | { 0x70020, 8184, RI_ALL_OFFLINE }, |
403 | { 0x78000, 8192, RI_E3E3B0_OFFLINE }, | 403 | { 0x78000, 8192, RI_E3E3B0_OFFLINE }, |
404 | { 0x85000, 3, RI_ALL_ONLINE }, | 404 | { 0x85000, 3, RI_ALL_OFFLINE }, |
405 | { 0x8501c, 7, RI_ALL_ONLINE }, | 405 | { 0x8501c, 7, RI_ALL_OFFLINE }, |
406 | { 0x85048, 1, RI_ALL_ONLINE }, | 406 | { 0x85048, 1, RI_ALL_OFFLINE }, |
407 | { 0x85200, 32, RI_ALL_ONLINE }, | 407 | { 0x85200, 32, RI_ALL_OFFLINE }, |
408 | { 0xb0000, 16384, RI_E1H_ONLINE }, | 408 | { 0xb0000, 16384, RI_E1H_OFFLINE }, |
409 | { 0xc1000, 7, RI_ALL_ONLINE }, | 409 | { 0xc1000, 7, RI_ALL_ONLINE }, |
410 | { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, | 410 | { 0xc103c, 2, RI_E2E3E3B0_ONLINE }, |
411 | { 0xc1800, 2, RI_ALL_ONLINE }, | 411 | { 0xc1800, 2, RI_ALL_ONLINE }, |
@@ -581,17 +581,12 @@ static const struct reg_addr reg_addrs[] = { | |||
581 | { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, | 581 | { 0x140188, 3, RI_E1E1HE2E3_ONLINE }, |
582 | { 0x140194, 13, RI_ALL_ONLINE }, | 582 | { 0x140194, 13, RI_ALL_ONLINE }, |
583 | { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, | 583 | { 0x140200, 6, RI_E1E1HE2E3_ONLINE }, |
584 | { 0x140220, 4, RI_E2E3_ONLINE }, | ||
585 | { 0x140240, 4, RI_E2E3_ONLINE }, | ||
586 | { 0x140260, 4, RI_E2E3_ONLINE }, | 584 | { 0x140260, 4, RI_E2E3_ONLINE }, |
587 | { 0x140280, 4, RI_E2E3_ONLINE }, | 585 | { 0x140280, 4, RI_E2E3_ONLINE }, |
588 | { 0x1402a0, 4, RI_E2E3_ONLINE }, | ||
589 | { 0x1402c0, 4, RI_E2E3_ONLINE }, | ||
590 | { 0x1402e0, 2, RI_E2E3_ONLINE }, | 586 | { 0x1402e0, 2, RI_E2E3_ONLINE }, |
591 | { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, | 587 | { 0x1402e8, 2, RI_E2E3E3B0_ONLINE }, |
592 | { 0x1402f0, 9, RI_E2E3_ONLINE }, | 588 | { 0x1402f0, 9, RI_E2E3_ONLINE }, |
593 | { 0x140314, 44, RI_E3B0_ONLINE }, | 589 | { 0x140314, 44, RI_E3B0_ONLINE }, |
594 | { 0x1403d0, 70, RI_E3B0_ONLINE }, | ||
595 | { 0x144000, 4, RI_E1E1H_ONLINE }, | 590 | { 0x144000, 4, RI_E1E1H_ONLINE }, |
596 | { 0x148000, 4, RI_E1E1H_ONLINE }, | 591 | { 0x148000, 4, RI_E1E1H_ONLINE }, |
597 | { 0x14c000, 4, RI_E1E1H_ONLINE }, | 592 | { 0x14c000, 4, RI_E1E1H_ONLINE }, |
@@ -704,7 +699,6 @@ static const struct reg_addr reg_addrs[] = { | |||
704 | { 0x180398, 1, RI_E2E3E3B0_ONLINE }, | 699 | { 0x180398, 1, RI_E2E3E3B0_ONLINE }, |
705 | { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, | 700 | { 0x1803a0, 5, RI_E2E3E3B0_ONLINE }, |
706 | { 0x1803b4, 2, RI_E3E3B0_ONLINE }, | 701 | { 0x1803b4, 2, RI_E3E3B0_ONLINE }, |
707 | { 0x180400, 1, RI_ALL_ONLINE }, | ||
708 | { 0x180404, 255, RI_E1E1H_OFFLINE }, | 702 | { 0x180404, 255, RI_E1E1H_OFFLINE }, |
709 | { 0x181000, 4, RI_ALL_ONLINE }, | 703 | { 0x181000, 4, RI_ALL_ONLINE }, |
710 | { 0x181010, 1020, RI_ALL_OFFLINE }, | 704 | { 0x181010, 1020, RI_ALL_OFFLINE }, |
@@ -800,9 +794,9 @@ static const struct reg_addr reg_addrs[] = { | |||
800 | { 0x1b905c, 1, RI_E3E3B0_ONLINE }, | 794 | { 0x1b905c, 1, RI_E3E3B0_ONLINE }, |
801 | { 0x1b9064, 1, RI_E3B0_ONLINE }, | 795 | { 0x1b9064, 1, RI_E3B0_ONLINE }, |
802 | { 0x1b9080, 10, RI_E3B0_ONLINE }, | 796 | { 0x1b9080, 10, RI_E3B0_ONLINE }, |
803 | { 0x1b9400, 14, RI_E2E3E3B0_ONLINE }, | 797 | { 0x1b9400, 14, RI_E2E3E3B0_OFFLINE }, |
804 | { 0x1b943c, 19, RI_E2E3E3B0_ONLINE }, | 798 | { 0x1b943c, 19, RI_E2E3E3B0_OFFLINE }, |
805 | { 0x1b9490, 10, RI_E2E3E3B0_ONLINE }, | 799 | { 0x1b9490, 10, RI_E2E3E3B0_OFFLINE }, |
806 | { 0x1c0000, 2, RI_ALL_ONLINE }, | 800 | { 0x1c0000, 2, RI_ALL_ONLINE }, |
807 | { 0x200000, 65, RI_ALL_ONLINE }, | 801 | { 0x200000, 65, RI_ALL_ONLINE }, |
808 | { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, | 802 | { 0x20014c, 2, RI_E1HE2E3E3B0_ONLINE }, |
@@ -814,7 +808,6 @@ static const struct reg_addr reg_addrs[] = { | |||
814 | { 0x200398, 1, RI_E2E3E3B0_ONLINE }, | 808 | { 0x200398, 1, RI_E2E3E3B0_ONLINE }, |
815 | { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, | 809 | { 0x2003a0, 1, RI_E2E3E3B0_ONLINE }, |
816 | { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, | 810 | { 0x2003a8, 2, RI_E2E3E3B0_ONLINE }, |
817 | { 0x200400, 1, RI_ALL_ONLINE }, | ||
818 | { 0x200404, 255, RI_E1E1H_OFFLINE }, | 811 | { 0x200404, 255, RI_E1E1H_OFFLINE }, |
819 | { 0x202000, 4, RI_ALL_ONLINE }, | 812 | { 0x202000, 4, RI_ALL_ONLINE }, |
820 | { 0x202010, 2044, RI_ALL_OFFLINE }, | 813 | { 0x202010, 2044, RI_ALL_OFFLINE }, |
@@ -921,7 +914,6 @@ static const struct reg_addr reg_addrs[] = { | |||
921 | { 0x280398, 1, RI_E2E3E3B0_ONLINE }, | 914 | { 0x280398, 1, RI_E2E3E3B0_ONLINE }, |
922 | { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, | 915 | { 0x2803a0, 1, RI_E2E3E3B0_ONLINE }, |
923 | { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, | 916 | { 0x2803a8, 2, RI_E2E3E3B0_ONLINE }, |
924 | { 0x280400, 1, RI_ALL_ONLINE }, | ||
925 | { 0x280404, 255, RI_E1E1H_OFFLINE }, | 917 | { 0x280404, 255, RI_E1E1H_OFFLINE }, |
926 | { 0x282000, 4, RI_ALL_ONLINE }, | 918 | { 0x282000, 4, RI_ALL_ONLINE }, |
927 | { 0x282010, 2044, RI_ALL_OFFLINE }, | 919 | { 0x282010, 2044, RI_ALL_OFFLINE }, |
@@ -1031,7 +1023,6 @@ static const struct reg_addr reg_addrs[] = { | |||
1031 | { 0x300398, 1, RI_E2E3E3B0_ONLINE }, | 1023 | { 0x300398, 1, RI_E2E3E3B0_ONLINE }, |
1032 | { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, | 1024 | { 0x3003a0, 1, RI_E2E3E3B0_ONLINE }, |
1033 | { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, | 1025 | { 0x3003a8, 2, RI_E2E3E3B0_ONLINE }, |
1034 | { 0x300400, 1, RI_ALL_ONLINE }, | ||
1035 | { 0x300404, 255, RI_E1E1H_OFFLINE }, | 1026 | { 0x300404, 255, RI_E1E1H_OFFLINE }, |
1036 | { 0x302000, 4, RI_ALL_ONLINE }, | 1027 | { 0x302000, 4, RI_ALL_ONLINE }, |
1037 | { 0x302010, 2044, RI_ALL_OFFLINE }, | 1028 | { 0x302010, 2044, RI_ALL_OFFLINE }, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index c37a68d68090..ebf40cd7aa10 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | |||
@@ -775,7 +775,7 @@ static void bnx2x_get_regs(struct net_device *dev, | |||
775 | struct bnx2x *bp = netdev_priv(dev); | 775 | struct bnx2x *bp = netdev_priv(dev); |
776 | struct dump_hdr dump_hdr = {0}; | 776 | struct dump_hdr dump_hdr = {0}; |
777 | 777 | ||
778 | regs->version = 0; | 778 | regs->version = 1; |
779 | memset(p, 0, regs->len); | 779 | memset(p, 0, regs->len); |
780 | 780 | ||
781 | if (!netif_running(bp->dev)) | 781 | if (!netif_running(bp->dev)) |
@@ -1587,6 +1587,12 @@ static int bnx2x_set_pauseparam(struct net_device *dev, | |||
1587 | bp->link_params.req_flow_ctrl[cfg_idx] = | 1587 | bp->link_params.req_flow_ctrl[cfg_idx] = |
1588 | BNX2X_FLOW_CTRL_AUTO; | 1588 | BNX2X_FLOW_CTRL_AUTO; |
1589 | } | 1589 | } |
1590 | bp->link_params.req_fc_auto_adv = BNX2X_FLOW_CTRL_NONE; | ||
1591 | if (epause->rx_pause) | ||
1592 | bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_RX; | ||
1593 | |||
1594 | if (epause->tx_pause) | ||
1595 | bp->link_params.req_fc_auto_adv |= BNX2X_FLOW_CTRL_TX; | ||
1590 | } | 1596 | } |
1591 | 1597 | ||
1592 | DP(BNX2X_MSG_ETHTOOL, | 1598 | DP(BNX2X_MSG_ETHTOOL, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index f4beb46c4709..b046beb435b2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | |||
@@ -2667,9 +2667,11 @@ int bnx2x_update_pfc(struct link_params *params, | |||
2667 | return bnx2x_status; | 2667 | return bnx2x_status; |
2668 | 2668 | ||
2669 | DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); | 2669 | DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n"); |
2670 | if (CHIP_IS_E3(bp)) | 2670 | |
2671 | bnx2x_update_pfc_xmac(params, vars, 0); | 2671 | if (CHIP_IS_E3(bp)) { |
2672 | else { | 2672 | if (vars->mac_type == MAC_TYPE_XMAC) |
2673 | bnx2x_update_pfc_xmac(params, vars, 0); | ||
2674 | } else { | ||
2673 | val = REG_RD(bp, MISC_REG_RESET_REG_2); | 2675 | val = REG_RD(bp, MISC_REG_RESET_REG_2); |
2674 | if ((val & | 2676 | if ((val & |
2675 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) | 2677 | (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) |
@@ -5432,7 +5434,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5432 | switch (speed_mask) { | 5434 | switch (speed_mask) { |
5433 | case GP_STATUS_10M: | 5435 | case GP_STATUS_10M: |
5434 | vars->line_speed = SPEED_10; | 5436 | vars->line_speed = SPEED_10; |
5435 | if (vars->duplex == DUPLEX_FULL) | 5437 | if (is_duplex == DUPLEX_FULL) |
5436 | vars->link_status |= LINK_10TFD; | 5438 | vars->link_status |= LINK_10TFD; |
5437 | else | 5439 | else |
5438 | vars->link_status |= LINK_10THD; | 5440 | vars->link_status |= LINK_10THD; |
@@ -5440,7 +5442,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5440 | 5442 | ||
5441 | case GP_STATUS_100M: | 5443 | case GP_STATUS_100M: |
5442 | vars->line_speed = SPEED_100; | 5444 | vars->line_speed = SPEED_100; |
5443 | if (vars->duplex == DUPLEX_FULL) | 5445 | if (is_duplex == DUPLEX_FULL) |
5444 | vars->link_status |= LINK_100TXFD; | 5446 | vars->link_status |= LINK_100TXFD; |
5445 | else | 5447 | else |
5446 | vars->link_status |= LINK_100TXHD; | 5448 | vars->link_status |= LINK_100TXHD; |
@@ -5449,7 +5451,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5449 | case GP_STATUS_1G: | 5451 | case GP_STATUS_1G: |
5450 | case GP_STATUS_1G_KX: | 5452 | case GP_STATUS_1G_KX: |
5451 | vars->line_speed = SPEED_1000; | 5453 | vars->line_speed = SPEED_1000; |
5452 | if (vars->duplex == DUPLEX_FULL) | 5454 | if (is_duplex == DUPLEX_FULL) |
5453 | vars->link_status |= LINK_1000TFD; | 5455 | vars->link_status |= LINK_1000TFD; |
5454 | else | 5456 | else |
5455 | vars->link_status |= LINK_1000THD; | 5457 | vars->link_status |= LINK_1000THD; |
@@ -5457,7 +5459,7 @@ static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy, | |||
5457 | 5459 | ||
5458 | case GP_STATUS_2_5G: | 5460 | case GP_STATUS_2_5G: |
5459 | vars->line_speed = SPEED_2500; | 5461 | vars->line_speed = SPEED_2500; |
5460 | if (vars->duplex == DUPLEX_FULL) | 5462 | if (is_duplex == DUPLEX_FULL) |
5461 | vars->link_status |= LINK_2500TFD; | 5463 | vars->link_status |= LINK_2500TFD; |
5462 | else | 5464 | else |
5463 | vars->link_status |= LINK_2500THD; | 5465 | vars->link_status |= LINK_2500THD; |
@@ -5531,6 +5533,7 @@ static int bnx2x_link_settings_status(struct bnx2x_phy *phy, | |||
5531 | 5533 | ||
5532 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { | 5534 | if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { |
5533 | if (SINGLE_MEDIA_DIRECT(params)) { | 5535 | if (SINGLE_MEDIA_DIRECT(params)) { |
5536 | vars->duplex = duplex; | ||
5534 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); | 5537 | bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status); |
5535 | if (phy->req_line_speed == SPEED_AUTO_NEG) | 5538 | if (phy->req_line_speed == SPEED_AUTO_NEG) |
5536 | bnx2x_xgxs_an_resolve(phy, params, vars, | 5539 | bnx2x_xgxs_an_resolve(phy, params, vars, |
@@ -5625,6 +5628,7 @@ static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy, | |||
5625 | LINK_STATUS_PARALLEL_DETECTION_USED; | 5628 | LINK_STATUS_PARALLEL_DETECTION_USED; |
5626 | } | 5629 | } |
5627 | bnx2x_ext_phy_resolve_fc(phy, params, vars); | 5630 | bnx2x_ext_phy_resolve_fc(phy, params, vars); |
5631 | vars->duplex = duplex; | ||
5628 | } | 5632 | } |
5629 | } | 5633 | } |
5630 | 5634 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 21054987257a..211753e01f81 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -7561,8 +7561,14 @@ int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac, | |||
7561 | } | 7561 | } |
7562 | 7562 | ||
7563 | rc = bnx2x_config_vlan_mac(bp, &ramrod_param); | 7563 | rc = bnx2x_config_vlan_mac(bp, &ramrod_param); |
7564 | if (rc < 0) | 7564 | |
7565 | if (rc == -EEXIST) { | ||
7566 | DP(BNX2X_MSG_SP, "Failed to schedule ADD operations: %d\n", rc); | ||
7567 | /* do not treat adding same MAC as error */ | ||
7568 | rc = 0; | ||
7569 | } else if (rc < 0) | ||
7565 | BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); | 7570 | BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); |
7571 | |||
7566 | return rc; | 7572 | return rc; |
7567 | } | 7573 | } |
7568 | 7574 | ||
@@ -10294,13 +10300,11 @@ static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp) | |||
10294 | dev_info.port_hw_config[port]. | 10300 | dev_info.port_hw_config[port]. |
10295 | fcoe_wwn_node_name_lower); | 10301 | fcoe_wwn_node_name_lower); |
10296 | } else if (!IS_MF_SD(bp)) { | 10302 | } else if (!IS_MF_SD(bp)) { |
10297 | u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); | ||
10298 | |||
10299 | /* | 10303 | /* |
10300 | * Read the WWN info only if the FCoE feature is enabled for | 10304 | * Read the WWN info only if the FCoE feature is enabled for |
10301 | * this function. | 10305 | * this function. |
10302 | */ | 10306 | */ |
10303 | if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) | 10307 | if (BNX2X_MF_EXT_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp)) |
10304 | bnx2x_get_ext_wwn_info(bp, func); | 10308 | bnx2x_get_ext_wwn_info(bp, func); |
10305 | 10309 | ||
10306 | } else if (IS_MF_FCOE_SD(bp)) | 10310 | } else if (IS_MF_FCOE_SD(bp)) |
@@ -11073,7 +11077,14 @@ static int bnx2x_set_uc_list(struct bnx2x *bp) | |||
11073 | netdev_for_each_uc_addr(ha, dev) { | 11077 | netdev_for_each_uc_addr(ha, dev) { |
11074 | rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, | 11078 | rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true, |
11075 | BNX2X_UC_LIST_MAC, &ramrod_flags); | 11079 | BNX2X_UC_LIST_MAC, &ramrod_flags); |
11076 | if (rc < 0) { | 11080 | if (rc == -EEXIST) { |
11081 | DP(BNX2X_MSG_SP, | ||
11082 | "Failed to schedule ADD operations: %d\n", rc); | ||
11083 | /* do not treat adding same MAC as error */ | ||
11084 | rc = 0; | ||
11085 | |||
11086 | } else if (rc < 0) { | ||
11087 | |||
11077 | BNX2X_ERR("Failed to schedule ADD operations: %d\n", | 11088 | BNX2X_ERR("Failed to schedule ADD operations: %d\n", |
11078 | rc); | 11089 | rc); |
11079 | return rc; | 11090 | return rc; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 332db64dd5be..a1d0446b39b3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | |||
@@ -101,6 +101,11 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) | |||
101 | if (CHIP_REV_IS_SLOW(bp)) | 101 | if (CHIP_REV_IS_SLOW(bp)) |
102 | return; | 102 | return; |
103 | 103 | ||
104 | /* Update MCP's statistics if possible */ | ||
105 | if (bp->func_stx) | ||
106 | memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, | ||
107 | sizeof(bp->func_stats)); | ||
108 | |||
104 | /* loader */ | 109 | /* loader */ |
105 | if (bp->executer_idx) { | 110 | if (bp->executer_idx) { |
106 | int loader_idx = PMF_DMAE_C(bp); | 111 | int loader_idx = PMF_DMAE_C(bp); |
@@ -128,8 +133,6 @@ static void bnx2x_hw_stats_post(struct bnx2x *bp) | |||
128 | 133 | ||
129 | } else if (bp->func_stx) { | 134 | } else if (bp->func_stx) { |
130 | *stats_comp = 0; | 135 | *stats_comp = 0; |
131 | memcpy(bnx2x_sp(bp, func_stats), &bp->func_stats, | ||
132 | sizeof(bp->func_stats)); | ||
133 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); | 136 | bnx2x_post_dmae(bp, dmae, INIT_DMAE_C(bp)); |
134 | } | 137 | } |
135 | } | 138 | } |
@@ -1151,9 +1154,11 @@ static void bnx2x_stats_update(struct bnx2x *bp) | |||
1151 | if (bp->port.pmf) | 1154 | if (bp->port.pmf) |
1152 | bnx2x_hw_stats_update(bp); | 1155 | bnx2x_hw_stats_update(bp); |
1153 | 1156 | ||
1154 | if (bnx2x_storm_stats_update(bp) && (bp->stats_pending++ == 3)) { | 1157 | if (bnx2x_storm_stats_update(bp)) { |
1155 | BNX2X_ERR("storm stats were not updated for 3 times\n"); | 1158 | if (bp->stats_pending++ == 3) { |
1156 | bnx2x_panic(); | 1159 | BNX2X_ERR("storm stats were not updated for 3 times\n"); |
1160 | bnx2x_panic(); | ||
1161 | } | ||
1157 | return; | 1162 | return; |
1158 | } | 1163 | } |
1159 | 1164 | ||
diff --git a/drivers/net/ethernet/i825xx/znet.c b/drivers/net/ethernet/i825xx/znet.c index bd1f1ef91e19..ba4e0cea3506 100644 --- a/drivers/net/ethernet/i825xx/znet.c +++ b/drivers/net/ethernet/i825xx/znet.c | |||
@@ -139,8 +139,11 @@ struct znet_private { | |||
139 | /* Only one can be built-in;-> */ | 139 | /* Only one can be built-in;-> */ |
140 | static struct net_device *znet_dev; | 140 | static struct net_device *znet_dev; |
141 | 141 | ||
142 | #define NETIDBLK_MAGIC "NETIDBLK" | ||
143 | #define NETIDBLK_MAGIC_SIZE 8 | ||
144 | |||
142 | struct netidblk { | 145 | struct netidblk { |
143 | char magic[8]; /* The magic number (string) "NETIDBLK" */ | 146 | char magic[NETIDBLK_MAGIC_SIZE]; /* The magic number (string) "NETIDBLK" */ |
144 | unsigned char netid[8]; /* The physical station address */ | 147 | unsigned char netid[8]; /* The physical station address */ |
145 | char nettype, globalopt; | 148 | char nettype, globalopt; |
146 | char vendor[8]; /* The machine vendor and product name. */ | 149 | char vendor[8]; /* The machine vendor and product name. */ |
@@ -373,14 +376,16 @@ static int __init znet_probe (void) | |||
373 | struct znet_private *znet; | 376 | struct znet_private *znet; |
374 | struct net_device *dev; | 377 | struct net_device *dev; |
375 | char *p; | 378 | char *p; |
379 | char *plast = phys_to_virt(0x100000 - NETIDBLK_MAGIC_SIZE); | ||
376 | int err = -ENOMEM; | 380 | int err = -ENOMEM; |
377 | 381 | ||
378 | /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ | 382 | /* This code scans the region 0xf0000 to 0xfffff for a "NETIDBLK". */ |
379 | for(p = (char *)phys_to_virt(0xf0000); p < (char *)phys_to_virt(0x100000); p++) | 383 | for(p = (char *)phys_to_virt(0xf0000); p <= plast; p++) |
380 | if (*p == 'N' && strncmp(p, "NETIDBLK", 8) == 0) | 384 | if (*p == 'N' && |
385 | strncmp(p, NETIDBLK_MAGIC, NETIDBLK_MAGIC_SIZE) == 0) | ||
381 | break; | 386 | break; |
382 | 387 | ||
383 | if (p >= (char *)phys_to_virt(0x100000)) { | 388 | if (p > plast) { |
384 | if (znet_debug > 1) | 389 | if (znet_debug > 1) |
385 | printk(KERN_INFO "No Z-Note ethernet adaptor found.\n"); | 390 | printk(KERN_INFO "No Z-Note ethernet adaptor found.\n"); |
386 | return -ENODEV; | 391 | return -ENODEV; |
diff --git a/drivers/net/ethernet/ibm/ibmveth.c b/drivers/net/ethernet/ibm/ibmveth.c index 9010cea68bc3..b68d28a130e6 100644 --- a/drivers/net/ethernet/ibm/ibmveth.c +++ b/drivers/net/ethernet/ibm/ibmveth.c | |||
@@ -472,14 +472,9 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter) | |||
472 | } | 472 | } |
473 | 473 | ||
474 | if (adapter->rx_queue.queue_addr != NULL) { | 474 | if (adapter->rx_queue.queue_addr != NULL) { |
475 | if (!dma_mapping_error(dev, adapter->rx_queue.queue_dma)) { | 475 | dma_free_coherent(dev, adapter->rx_queue.queue_len, |
476 | dma_unmap_single(dev, | 476 | adapter->rx_queue.queue_addr, |
477 | adapter->rx_queue.queue_dma, | 477 | adapter->rx_queue.queue_dma); |
478 | adapter->rx_queue.queue_len, | ||
479 | DMA_BIDIRECTIONAL); | ||
480 | adapter->rx_queue.queue_dma = DMA_ERROR_CODE; | ||
481 | } | ||
482 | kfree(adapter->rx_queue.queue_addr); | ||
483 | adapter->rx_queue.queue_addr = NULL; | 478 | adapter->rx_queue.queue_addr = NULL; |
484 | } | 479 | } |
485 | 480 | ||
@@ -556,10 +551,13 @@ static int ibmveth_open(struct net_device *netdev) | |||
556 | goto err_out; | 551 | goto err_out; |
557 | } | 552 | } |
558 | 553 | ||
554 | dev = &adapter->vdev->dev; | ||
555 | |||
559 | adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * | 556 | adapter->rx_queue.queue_len = sizeof(struct ibmveth_rx_q_entry) * |
560 | rxq_entries; | 557 | rxq_entries; |
561 | adapter->rx_queue.queue_addr = kmalloc(adapter->rx_queue.queue_len, | 558 | adapter->rx_queue.queue_addr = |
562 | GFP_KERNEL); | 559 | dma_alloc_coherent(dev, adapter->rx_queue.queue_len, |
560 | &adapter->rx_queue.queue_dma, GFP_KERNEL); | ||
563 | 561 | ||
564 | if (!adapter->rx_queue.queue_addr) { | 562 | if (!adapter->rx_queue.queue_addr) { |
565 | netdev_err(netdev, "unable to allocate rx queue pages\n"); | 563 | netdev_err(netdev, "unable to allocate rx queue pages\n"); |
@@ -567,19 +565,13 @@ static int ibmveth_open(struct net_device *netdev) | |||
567 | goto err_out; | 565 | goto err_out; |
568 | } | 566 | } |
569 | 567 | ||
570 | dev = &adapter->vdev->dev; | ||
571 | |||
572 | adapter->buffer_list_dma = dma_map_single(dev, | 568 | adapter->buffer_list_dma = dma_map_single(dev, |
573 | adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); | 569 | adapter->buffer_list_addr, 4096, DMA_BIDIRECTIONAL); |
574 | adapter->filter_list_dma = dma_map_single(dev, | 570 | adapter->filter_list_dma = dma_map_single(dev, |
575 | adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); | 571 | adapter->filter_list_addr, 4096, DMA_BIDIRECTIONAL); |
576 | adapter->rx_queue.queue_dma = dma_map_single(dev, | ||
577 | adapter->rx_queue.queue_addr, | ||
578 | adapter->rx_queue.queue_len, DMA_BIDIRECTIONAL); | ||
579 | 572 | ||
580 | if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || | 573 | if ((dma_mapping_error(dev, adapter->buffer_list_dma)) || |
581 | (dma_mapping_error(dev, adapter->filter_list_dma)) || | 574 | (dma_mapping_error(dev, adapter->filter_list_dma))) { |
582 | (dma_mapping_error(dev, adapter->rx_queue.queue_dma))) { | ||
583 | netdev_err(netdev, "unable to map filter or buffer list " | 575 | netdev_err(netdev, "unable to map filter or buffer list " |
584 | "pages\n"); | 576 | "pages\n"); |
585 | rc = -ENOMEM; | 577 | rc = -ENOMEM; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 827b72dfce99..2f816c6aed72 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -1234,13 +1234,13 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1234 | mlx4_info(dev, "non-primary physical function, skipping.\n"); | 1234 | mlx4_info(dev, "non-primary physical function, skipping.\n"); |
1235 | else | 1235 | else |
1236 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); | 1236 | mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); |
1237 | goto unmap_bf; | 1237 | return err; |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | err = mlx4_load_fw(dev); | 1240 | err = mlx4_load_fw(dev); |
1241 | if (err) { | 1241 | if (err) { |
1242 | mlx4_err(dev, "Failed to start FW, aborting.\n"); | 1242 | mlx4_err(dev, "Failed to start FW, aborting.\n"); |
1243 | goto unmap_bf; | 1243 | return err; |
1244 | } | 1244 | } |
1245 | 1245 | ||
1246 | mlx4_cfg.log_pg_sz_m = 1; | 1246 | mlx4_cfg.log_pg_sz_m = 1; |
@@ -1304,7 +1304,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1304 | err = mlx4_init_slave(dev); | 1304 | err = mlx4_init_slave(dev); |
1305 | if (err) { | 1305 | if (err) { |
1306 | mlx4_err(dev, "Failed to initialize slave\n"); | 1306 | mlx4_err(dev, "Failed to initialize slave\n"); |
1307 | goto unmap_bf; | 1307 | return err; |
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | err = mlx4_slave_cap(dev); | 1310 | err = mlx4_slave_cap(dev); |
@@ -1324,7 +1324,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1324 | err = mlx4_QUERY_ADAPTER(dev, &adapter); | 1324 | err = mlx4_QUERY_ADAPTER(dev, &adapter); |
1325 | if (err) { | 1325 | if (err) { |
1326 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); | 1326 | mlx4_err(dev, "QUERY_ADAPTER command failed, aborting.\n"); |
1327 | goto err_close; | 1327 | goto unmap_bf; |
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | priv->eq_table.inta_pin = adapter.inta_pin; | 1330 | priv->eq_table.inta_pin = adapter.inta_pin; |
@@ -1332,6 +1332,9 @@ static int mlx4_init_hca(struct mlx4_dev *dev) | |||
1332 | 1332 | ||
1333 | return 0; | 1333 | return 0; |
1334 | 1334 | ||
1335 | unmap_bf: | ||
1336 | unmap_bf_area(dev); | ||
1337 | |||
1335 | err_close: | 1338 | err_close: |
1336 | mlx4_close_hca(dev); | 1339 | mlx4_close_hca(dev); |
1337 | 1340 | ||
@@ -1344,8 +1347,6 @@ err_stop_fw: | |||
1344 | mlx4_UNMAP_FA(dev); | 1347 | mlx4_UNMAP_FA(dev); |
1345 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); | 1348 | mlx4_free_icm(dev, priv->fw.fw_icm, 0); |
1346 | } | 1349 | } |
1347 | unmap_bf: | ||
1348 | unmap_bf_area(dev); | ||
1349 | return err; | 1350 | return err; |
1350 | } | 1351 | } |
1351 | 1352 | ||
@@ -1996,7 +1997,8 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1996 | } | 1997 | } |
1997 | 1998 | ||
1998 | slave_start: | 1999 | slave_start: |
1999 | if (mlx4_cmd_init(dev)) { | 2000 | err = mlx4_cmd_init(dev); |
2001 | if (err) { | ||
2000 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); | 2002 | mlx4_err(dev, "Failed to init command interface, aborting.\n"); |
2001 | goto err_sriov; | 2003 | goto err_sriov; |
2002 | } | 2004 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index a018ea2a43de..e151c21baf2b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -137,11 +137,11 @@ static int mlx4_GID_HASH(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox, | |||
137 | return err; | 137 | return err; |
138 | } | 138 | } |
139 | 139 | ||
140 | static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 pf_num, | 140 | static struct mlx4_promisc_qp *get_promisc_qp(struct mlx4_dev *dev, u8 port, |
141 | enum mlx4_steer_type steer, | 141 | enum mlx4_steer_type steer, |
142 | u32 qpn) | 142 | u32 qpn) |
143 | { | 143 | { |
144 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[pf_num]; | 144 | struct mlx4_steer *s_steer = &mlx4_priv(dev)->steer[port - 1]; |
145 | struct mlx4_promisc_qp *pqp; | 145 | struct mlx4_promisc_qp *pqp; |
146 | 146 | ||
147 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { | 147 | list_for_each_entry(pqp, &s_steer->promisc_qps[steer], list) { |
@@ -182,7 +182,7 @@ static int new_steering_entry(struct mlx4_dev *dev, u8 port, | |||
182 | /* If the given qpn is also a promisc qp, | 182 | /* If the given qpn is also a promisc qp, |
183 | * it should be inserted to duplicates list | 183 | * it should be inserted to duplicates list |
184 | */ | 184 | */ |
185 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 185 | pqp = get_promisc_qp(dev, port, steer, qpn); |
186 | if (pqp) { | 186 | if (pqp) { |
187 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); | 187 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); |
188 | if (!dqp) { | 188 | if (!dqp) { |
@@ -256,7 +256,7 @@ static int existing_steering_entry(struct mlx4_dev *dev, u8 port, | |||
256 | 256 | ||
257 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 257 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
258 | 258 | ||
259 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 259 | pqp = get_promisc_qp(dev, port, steer, qpn); |
260 | if (!pqp) | 260 | if (!pqp) |
261 | return 0; /* nothing to do */ | 261 | return 0; /* nothing to do */ |
262 | 262 | ||
@@ -302,7 +302,7 @@ static bool check_duplicate_entry(struct mlx4_dev *dev, u8 port, | |||
302 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 302 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
303 | 303 | ||
304 | /* if qp is not promisc, it cannot be duplicated */ | 304 | /* if qp is not promisc, it cannot be duplicated */ |
305 | if (!get_promisc_qp(dev, 0, steer, qpn)) | 305 | if (!get_promisc_qp(dev, port, steer, qpn)) |
306 | return false; | 306 | return false; |
307 | 307 | ||
308 | /* The qp is promisc qp so it is a duplicate on this index | 308 | /* The qp is promisc qp so it is a duplicate on this index |
@@ -352,7 +352,7 @@ static bool can_remove_steering_entry(struct mlx4_dev *dev, u8 port, | |||
352 | members_count = be32_to_cpu(mgm->members_count) & 0xffffff; | 352 | members_count = be32_to_cpu(mgm->members_count) & 0xffffff; |
353 | for (i = 0; i < members_count; i++) { | 353 | for (i = 0; i < members_count; i++) { |
354 | qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; | 354 | qpn = be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK; |
355 | if (!get_promisc_qp(dev, 0, steer, qpn) && qpn != tqpn) { | 355 | if (!get_promisc_qp(dev, port, steer, qpn) && qpn != tqpn) { |
356 | /* the qp is not promisc, the entry can't be removed */ | 356 | /* the qp is not promisc, the entry can't be removed */ |
357 | goto out; | 357 | goto out; |
358 | } | 358 | } |
@@ -398,7 +398,7 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
398 | 398 | ||
399 | mutex_lock(&priv->mcg_table.mutex); | 399 | mutex_lock(&priv->mcg_table.mutex); |
400 | 400 | ||
401 | if (get_promisc_qp(dev, 0, steer, qpn)) { | 401 | if (get_promisc_qp(dev, port, steer, qpn)) { |
402 | err = 0; /* Noting to do, already exists */ | 402 | err = 0; /* Noting to do, already exists */ |
403 | goto out_mutex; | 403 | goto out_mutex; |
404 | } | 404 | } |
@@ -503,7 +503,7 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
503 | s_steer = &mlx4_priv(dev)->steer[port - 1]; | 503 | s_steer = &mlx4_priv(dev)->steer[port - 1]; |
504 | mutex_lock(&priv->mcg_table.mutex); | 504 | mutex_lock(&priv->mcg_table.mutex); |
505 | 505 | ||
506 | pqp = get_promisc_qp(dev, 0, steer, qpn); | 506 | pqp = get_promisc_qp(dev, port, steer, qpn); |
507 | if (unlikely(!pqp)) { | 507 | if (unlikely(!pqp)) { |
508 | mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); | 508 | mlx4_warn(dev, "QP %x is not promiscuous QP\n", qpn); |
509 | /* nothing to do */ | 509 | /* nothing to do */ |
@@ -650,13 +650,6 @@ static int find_entry(struct mlx4_dev *dev, u8 port, | |||
650 | return err; | 650 | return err; |
651 | } | 651 | } |
652 | 652 | ||
653 | struct mlx4_net_trans_rule_hw_ctrl { | ||
654 | __be32 ctrl; | ||
655 | __be32 vf_vep_port; | ||
656 | __be32 qpn; | ||
657 | __be32 reserved; | ||
658 | }; | ||
659 | |||
660 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | 653 | static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, |
661 | struct mlx4_net_trans_rule_hw_ctrl *hw) | 654 | struct mlx4_net_trans_rule_hw_ctrl *hw) |
662 | { | 655 | { |
@@ -680,87 +673,18 @@ static void trans_rule_ctrl_to_hw(struct mlx4_net_trans_rule *ctrl, | |||
680 | hw->qpn = cpu_to_be32(ctrl->qpn); | 673 | hw->qpn = cpu_to_be32(ctrl->qpn); |
681 | } | 674 | } |
682 | 675 | ||
683 | struct mlx4_net_trans_rule_hw_ib { | 676 | const u16 __sw_id_hw[] = { |
684 | u8 size; | 677 | [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, |
685 | u8 rsvd1; | 678 | [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, |
686 | __be16 id; | 679 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, |
687 | u32 rsvd2; | 680 | [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, |
688 | __be32 qpn; | 681 | [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, |
689 | __be32 qpn_mask; | 682 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 |
690 | u8 dst_gid[16]; | ||
691 | u8 dst_gid_msk[16]; | ||
692 | } __packed; | ||
693 | |||
694 | struct mlx4_net_trans_rule_hw_eth { | ||
695 | u8 size; | ||
696 | u8 rsvd; | ||
697 | __be16 id; | ||
698 | u8 rsvd1[6]; | ||
699 | u8 dst_mac[6]; | ||
700 | u16 rsvd2; | ||
701 | u8 dst_mac_msk[6]; | ||
702 | u16 rsvd3; | ||
703 | u8 src_mac[6]; | ||
704 | u16 rsvd4; | ||
705 | u8 src_mac_msk[6]; | ||
706 | u8 rsvd5; | ||
707 | u8 ether_type_enable; | ||
708 | __be16 ether_type; | ||
709 | __be16 vlan_id_msk; | ||
710 | __be16 vlan_id; | ||
711 | } __packed; | ||
712 | |||
713 | struct mlx4_net_trans_rule_hw_tcp_udp { | ||
714 | u8 size; | ||
715 | u8 rsvd; | ||
716 | __be16 id; | ||
717 | __be16 rsvd1[3]; | ||
718 | __be16 dst_port; | ||
719 | __be16 rsvd2; | ||
720 | __be16 dst_port_msk; | ||
721 | __be16 rsvd3; | ||
722 | __be16 src_port; | ||
723 | __be16 rsvd4; | ||
724 | __be16 src_port_msk; | ||
725 | } __packed; | ||
726 | |||
727 | struct mlx4_net_trans_rule_hw_ipv4 { | ||
728 | u8 size; | ||
729 | u8 rsvd; | ||
730 | __be16 id; | ||
731 | __be32 rsvd1; | ||
732 | __be32 dst_ip; | ||
733 | __be32 dst_ip_msk; | ||
734 | __be32 src_ip; | ||
735 | __be32 src_ip_msk; | ||
736 | } __packed; | ||
737 | |||
738 | struct _rule_hw { | ||
739 | union { | ||
740 | struct { | ||
741 | u8 size; | ||
742 | u8 rsvd; | ||
743 | __be16 id; | ||
744 | }; | ||
745 | struct mlx4_net_trans_rule_hw_eth eth; | ||
746 | struct mlx4_net_trans_rule_hw_ib ib; | ||
747 | struct mlx4_net_trans_rule_hw_ipv4 ipv4; | ||
748 | struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; | ||
749 | }; | ||
750 | }; | 683 | }; |
751 | 684 | ||
752 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, | 685 | static int parse_trans_rule(struct mlx4_dev *dev, struct mlx4_spec_list *spec, |
753 | struct _rule_hw *rule_hw) | 686 | struct _rule_hw *rule_hw) |
754 | { | 687 | { |
755 | static const u16 __sw_id_hw[] = { | ||
756 | [MLX4_NET_TRANS_RULE_ID_ETH] = 0xE001, | ||
757 | [MLX4_NET_TRANS_RULE_ID_IB] = 0xE005, | ||
758 | [MLX4_NET_TRANS_RULE_ID_IPV6] = 0xE003, | ||
759 | [MLX4_NET_TRANS_RULE_ID_IPV4] = 0xE002, | ||
760 | [MLX4_NET_TRANS_RULE_ID_TCP] = 0xE004, | ||
761 | [MLX4_NET_TRANS_RULE_ID_UDP] = 0xE006 | ||
762 | }; | ||
763 | |||
764 | static const size_t __rule_hw_sz[] = { | 688 | static const size_t __rule_hw_sz[] = { |
765 | [MLX4_NET_TRANS_RULE_ID_ETH] = | 689 | [MLX4_NET_TRANS_RULE_ID_ETH] = |
766 | sizeof(struct mlx4_net_trans_rule_hw_eth), | 690 | sizeof(struct mlx4_net_trans_rule_hw_eth), |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 4d9df8f2a126..dba69d98734a 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -690,6 +690,82 @@ struct mlx4_steer { | |||
690 | struct list_head steer_entries[MLX4_NUM_STEERS]; | 690 | struct list_head steer_entries[MLX4_NUM_STEERS]; |
691 | }; | 691 | }; |
692 | 692 | ||
693 | struct mlx4_net_trans_rule_hw_ctrl { | ||
694 | __be32 ctrl; | ||
695 | __be32 vf_vep_port; | ||
696 | __be32 qpn; | ||
697 | __be32 reserved; | ||
698 | }; | ||
699 | |||
700 | struct mlx4_net_trans_rule_hw_ib { | ||
701 | u8 size; | ||
702 | u8 rsvd1; | ||
703 | __be16 id; | ||
704 | u32 rsvd2; | ||
705 | __be32 qpn; | ||
706 | __be32 qpn_mask; | ||
707 | u8 dst_gid[16]; | ||
708 | u8 dst_gid_msk[16]; | ||
709 | } __packed; | ||
710 | |||
711 | struct mlx4_net_trans_rule_hw_eth { | ||
712 | u8 size; | ||
713 | u8 rsvd; | ||
714 | __be16 id; | ||
715 | u8 rsvd1[6]; | ||
716 | u8 dst_mac[6]; | ||
717 | u16 rsvd2; | ||
718 | u8 dst_mac_msk[6]; | ||
719 | u16 rsvd3; | ||
720 | u8 src_mac[6]; | ||
721 | u16 rsvd4; | ||
722 | u8 src_mac_msk[6]; | ||
723 | u8 rsvd5; | ||
724 | u8 ether_type_enable; | ||
725 | __be16 ether_type; | ||
726 | __be16 vlan_id_msk; | ||
727 | __be16 vlan_id; | ||
728 | } __packed; | ||
729 | |||
730 | struct mlx4_net_trans_rule_hw_tcp_udp { | ||
731 | u8 size; | ||
732 | u8 rsvd; | ||
733 | __be16 id; | ||
734 | __be16 rsvd1[3]; | ||
735 | __be16 dst_port; | ||
736 | __be16 rsvd2; | ||
737 | __be16 dst_port_msk; | ||
738 | __be16 rsvd3; | ||
739 | __be16 src_port; | ||
740 | __be16 rsvd4; | ||
741 | __be16 src_port_msk; | ||
742 | } __packed; | ||
743 | |||
744 | struct mlx4_net_trans_rule_hw_ipv4 { | ||
745 | u8 size; | ||
746 | u8 rsvd; | ||
747 | __be16 id; | ||
748 | __be32 rsvd1; | ||
749 | __be32 dst_ip; | ||
750 | __be32 dst_ip_msk; | ||
751 | __be32 src_ip; | ||
752 | __be32 src_ip_msk; | ||
753 | } __packed; | ||
754 | |||
755 | struct _rule_hw { | ||
756 | union { | ||
757 | struct { | ||
758 | u8 size; | ||
759 | u8 rsvd; | ||
760 | __be16 id; | ||
761 | }; | ||
762 | struct mlx4_net_trans_rule_hw_eth eth; | ||
763 | struct mlx4_net_trans_rule_hw_ib ib; | ||
764 | struct mlx4_net_trans_rule_hw_ipv4 ipv4; | ||
765 | struct mlx4_net_trans_rule_hw_tcp_udp tcp_udp; | ||
766 | }; | ||
767 | }; | ||
768 | |||
693 | struct mlx4_priv { | 769 | struct mlx4_priv { |
694 | struct mlx4_dev dev; | 770 | struct mlx4_dev dev; |
695 | 771 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 94ceddd17ab2..293c9e820c49 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/mlx4/cmd.h> | 42 | #include <linux/mlx4/cmd.h> |
43 | #include <linux/mlx4/qp.h> | 43 | #include <linux/mlx4/qp.h> |
44 | #include <linux/if_ether.h> | 44 | #include <linux/if_ether.h> |
45 | #include <linux/etherdevice.h> | ||
45 | 46 | ||
46 | #include "mlx4.h" | 47 | #include "mlx4.h" |
47 | #include "fw.h" | 48 | #include "fw.h" |
@@ -2776,18 +2777,133 @@ ex_put: | |||
2776 | return err; | 2777 | return err; |
2777 | } | 2778 | } |
2778 | 2779 | ||
2780 | /* | ||
2781 | * MAC validation for Flow Steering rules. | ||
2782 | * VF can attach rules only with a mac address which is assigned to it. | ||
2783 | */ | ||
2784 | static int validate_eth_header_mac(int slave, struct _rule_hw *eth_header, | ||
2785 | struct list_head *rlist) | ||
2786 | { | ||
2787 | struct mac_res *res, *tmp; | ||
2788 | __be64 be_mac; | ||
2789 | |||
2790 | /* make sure it isn't multicast or broadcast mac*/ | ||
2791 | if (!is_multicast_ether_addr(eth_header->eth.dst_mac) && | ||
2792 | !is_broadcast_ether_addr(eth_header->eth.dst_mac)) { | ||
2793 | list_for_each_entry_safe(res, tmp, rlist, list) { | ||
2794 | be_mac = cpu_to_be64(res->mac << 16); | ||
2795 | if (!memcmp(&be_mac, eth_header->eth.dst_mac, ETH_ALEN)) | ||
2796 | return 0; | ||
2797 | } | ||
2798 | pr_err("MAC %pM doesn't belong to VF %d, Steering rule rejected\n", | ||
2799 | eth_header->eth.dst_mac, slave); | ||
2800 | return -EINVAL; | ||
2801 | } | ||
2802 | return 0; | ||
2803 | } | ||
2804 | |||
2805 | /* | ||
2806 | * In case of missing eth header, append eth header with a MAC address | ||
2807 | * assigned to the VF. | ||
2808 | */ | ||
2809 | static int add_eth_header(struct mlx4_dev *dev, int slave, | ||
2810 | struct mlx4_cmd_mailbox *inbox, | ||
2811 | struct list_head *rlist, int header_id) | ||
2812 | { | ||
2813 | struct mac_res *res, *tmp; | ||
2814 | u8 port; | ||
2815 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | ||
2816 | struct mlx4_net_trans_rule_hw_eth *eth_header; | ||
2817 | struct mlx4_net_trans_rule_hw_ipv4 *ip_header; | ||
2818 | struct mlx4_net_trans_rule_hw_tcp_udp *l4_header; | ||
2819 | __be64 be_mac = 0; | ||
2820 | __be64 mac_msk = cpu_to_be64(MLX4_MAC_MASK << 16); | ||
2821 | |||
2822 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | ||
2823 | port = be32_to_cpu(ctrl->vf_vep_port) & 0xff; | ||
2824 | eth_header = (struct mlx4_net_trans_rule_hw_eth *)(ctrl + 1); | ||
2825 | |||
2826 | /* Clear a space in the inbox for eth header */ | ||
2827 | switch (header_id) { | ||
2828 | case MLX4_NET_TRANS_RULE_ID_IPV4: | ||
2829 | ip_header = | ||
2830 | (struct mlx4_net_trans_rule_hw_ipv4 *)(eth_header + 1); | ||
2831 | memmove(ip_header, eth_header, | ||
2832 | sizeof(*ip_header) + sizeof(*l4_header)); | ||
2833 | break; | ||
2834 | case MLX4_NET_TRANS_RULE_ID_TCP: | ||
2835 | case MLX4_NET_TRANS_RULE_ID_UDP: | ||
2836 | l4_header = (struct mlx4_net_trans_rule_hw_tcp_udp *) | ||
2837 | (eth_header + 1); | ||
2838 | memmove(l4_header, eth_header, sizeof(*l4_header)); | ||
2839 | break; | ||
2840 | default: | ||
2841 | return -EINVAL; | ||
2842 | } | ||
2843 | list_for_each_entry_safe(res, tmp, rlist, list) { | ||
2844 | if (port == res->port) { | ||
2845 | be_mac = cpu_to_be64(res->mac << 16); | ||
2846 | break; | ||
2847 | } | ||
2848 | } | ||
2849 | if (!be_mac) { | ||
2850 | pr_err("Failed adding eth header to FS rule, Can't find matching MAC for port %d .\n", | ||
2851 | port); | ||
2852 | return -EINVAL; | ||
2853 | } | ||
2854 | |||
2855 | memset(eth_header, 0, sizeof(*eth_header)); | ||
2856 | eth_header->size = sizeof(*eth_header) >> 2; | ||
2857 | eth_header->id = cpu_to_be16(__sw_id_hw[MLX4_NET_TRANS_RULE_ID_ETH]); | ||
2858 | memcpy(eth_header->dst_mac, &be_mac, ETH_ALEN); | ||
2859 | memcpy(eth_header->dst_mac_msk, &mac_msk, ETH_ALEN); | ||
2860 | |||
2861 | return 0; | ||
2862 | |||
2863 | } | ||
2864 | |||
2779 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 2865 | int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave, |
2780 | struct mlx4_vhcr *vhcr, | 2866 | struct mlx4_vhcr *vhcr, |
2781 | struct mlx4_cmd_mailbox *inbox, | 2867 | struct mlx4_cmd_mailbox *inbox, |
2782 | struct mlx4_cmd_mailbox *outbox, | 2868 | struct mlx4_cmd_mailbox *outbox, |
2783 | struct mlx4_cmd_info *cmd) | 2869 | struct mlx4_cmd_info *cmd) |
2784 | { | 2870 | { |
2871 | |||
2872 | struct mlx4_priv *priv = mlx4_priv(dev); | ||
2873 | struct mlx4_resource_tracker *tracker = &priv->mfunc.master.res_tracker; | ||
2874 | struct list_head *rlist = &tracker->slave_list[slave].res_list[RES_MAC]; | ||
2785 | int err; | 2875 | int err; |
2876 | struct mlx4_net_trans_rule_hw_ctrl *ctrl; | ||
2877 | struct _rule_hw *rule_header; | ||
2878 | int header_id; | ||
2786 | 2879 | ||
2787 | if (dev->caps.steering_mode != | 2880 | if (dev->caps.steering_mode != |
2788 | MLX4_STEERING_MODE_DEVICE_MANAGED) | 2881 | MLX4_STEERING_MODE_DEVICE_MANAGED) |
2789 | return -EOPNOTSUPP; | 2882 | return -EOPNOTSUPP; |
2790 | 2883 | ||
2884 | ctrl = (struct mlx4_net_trans_rule_hw_ctrl *)inbox->buf; | ||
2885 | rule_header = (struct _rule_hw *)(ctrl + 1); | ||
2886 | header_id = map_hw_to_sw_id(be16_to_cpu(rule_header->id)); | ||
2887 | |||
2888 | switch (header_id) { | ||
2889 | case MLX4_NET_TRANS_RULE_ID_ETH: | ||
2890 | if (validate_eth_header_mac(slave, rule_header, rlist)) | ||
2891 | return -EINVAL; | ||
2892 | break; | ||
2893 | case MLX4_NET_TRANS_RULE_ID_IPV4: | ||
2894 | case MLX4_NET_TRANS_RULE_ID_TCP: | ||
2895 | case MLX4_NET_TRANS_RULE_ID_UDP: | ||
2896 | pr_warn("Can't attach FS rule without L2 headers, adding L2 header.\n"); | ||
2897 | if (add_eth_header(dev, slave, inbox, rlist, header_id)) | ||
2898 | return -EINVAL; | ||
2899 | vhcr->in_modifier += | ||
2900 | sizeof(struct mlx4_net_trans_rule_hw_eth) >> 2; | ||
2901 | break; | ||
2902 | default: | ||
2903 | pr_err("Corrupted mailbox.\n"); | ||
2904 | return -EINVAL; | ||
2905 | } | ||
2906 | |||
2791 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, | 2907 | err = mlx4_cmd_imm(dev, inbox->dma, &vhcr->out_param, |
2792 | vhcr->in_modifier, 0, | 2908 | vhcr->in_modifier, 0, |
2793 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, | 2909 | MLX4_QP_FLOW_STEERING_ATTACH, MLX4_CMD_TIME_CLASS_A, |
diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index 9d11ab7521bc..63e7af44366f 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <mach/netx-regs.h> | 34 | #include <mach/netx-regs.h> |
35 | #include <mach/pfifo.h> | 35 | #include <mach/pfifo.h> |
36 | #include <mach/xc.h> | 36 | #include <mach/xc.h> |
37 | #include <mach/eth.h> | 37 | #include <linux/platform_data/eth-netx.h> |
38 | 38 | ||
39 | /* XC Fifo Offsets */ | 39 | /* XC Fifo Offsets */ |
40 | #define EMPTY_PTR_FIFO(xcno) (0 + ((xcno) << 3)) /* Index of the empty pointer FIFO */ | 40 | #define EMPTY_PTR_FIFO(xcno) (0 + ((xcno) << 3)) /* Index of the empty pointer FIFO */ |
diff --git a/drivers/net/ethernet/seeq/ether3.c b/drivers/net/ethernet/seeq/ether3.c index df808ac8cb65..6a40dd03a32f 100644 --- a/drivers/net/ethernet/seeq/ether3.c +++ b/drivers/net/ethernet/seeq/ether3.c | |||
@@ -99,13 +99,13 @@ typedef enum { | |||
99 | * The SEEQ8005 doesn't like us writing to its registers | 99 | * The SEEQ8005 doesn't like us writing to its registers |
100 | * too quickly. | 100 | * too quickly. |
101 | */ | 101 | */ |
102 | static inline void ether3_outb(int v, const void __iomem *r) | 102 | static inline void ether3_outb(int v, void __iomem *r) |
103 | { | 103 | { |
104 | writeb(v, r); | 104 | writeb(v, r); |
105 | udelay(1); | 105 | udelay(1); |
106 | } | 106 | } |
107 | 107 | ||
108 | static inline void ether3_outw(int v, const void __iomem *r) | 108 | static inline void ether3_outw(int v, void __iomem *r) |
109 | { | 109 | { |
110 | writew(v, r); | 110 | writew(v, r); |
111 | udelay(1); | 111 | udelay(1); |
diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index bb8c8222122b..4d15bf413bdc 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c | |||
@@ -751,6 +751,7 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev) | |||
751 | sp->srings = sr; | 751 | sp->srings = sr; |
752 | sp->rx_desc = sp->srings->rxvector; | 752 | sp->rx_desc = sp->srings->rxvector; |
753 | sp->tx_desc = sp->srings->txvector; | 753 | sp->tx_desc = sp->srings->txvector; |
754 | spin_lock_init(&sp->tx_lock); | ||
754 | 755 | ||
755 | /* A couple calculations now, saves many cycles later. */ | 756 | /* A couple calculations now, saves many cycles later. */ |
756 | setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); | 757 | setup_rx_ring(dev, sp->rx_desc, SEEQ_RX_BUFFERS); |
diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c index b5ba3084c7fc..3e5519a0acc7 100644 --- a/drivers/net/ethernet/sgi/ioc3-eth.c +++ b/drivers/net/ethernet/sgi/ioc3-eth.c | |||
@@ -1147,15 +1147,17 @@ static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart) | |||
1147 | { | 1147 | { |
1148 | #define COSMISC_CONSTANT 6 | 1148 | #define COSMISC_CONSTANT 6 |
1149 | 1149 | ||
1150 | struct uart_port port = { | 1150 | struct uart_8250_port port = { |
1151 | .irq = 0, | 1151 | .port = { |
1152 | .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, | 1152 | .irq = 0, |
1153 | .iotype = UPIO_MEM, | 1153 | .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, |
1154 | .regshift = 0, | 1154 | .iotype = UPIO_MEM, |
1155 | .uartclk = (22000000 << 1) / COSMISC_CONSTANT, | 1155 | .regshift = 0, |
1156 | 1156 | .uartclk = (22000000 << 1) / COSMISC_CONSTANT, | |
1157 | .membase = (unsigned char __iomem *) uart, | 1157 | |
1158 | .mapbase = (unsigned long) uart, | 1158 | .membase = (unsigned char __iomem *) uart, |
1159 | .mapbase = (unsigned long) uart, | ||
1160 | } | ||
1159 | }; | 1161 | }; |
1160 | unsigned char lcr; | 1162 | unsigned char lcr; |
1161 | 1163 | ||
@@ -1164,7 +1166,7 @@ static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart) | |||
1164 | uart->iu_scr = COSMISC_CONSTANT, | 1166 | uart->iu_scr = COSMISC_CONSTANT, |
1165 | uart->iu_lcr = lcr; | 1167 | uart->iu_lcr = lcr; |
1166 | uart->iu_lcr; | 1168 | uart->iu_lcr; |
1167 | serial8250_register_port(&port); | 1169 | serial8250_register_8250_port(&port); |
1168 | } | 1170 | } |
1169 | 1171 | ||
1170 | static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) | 1172 | static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3) |
diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c index 3352b2443e58..30087ca23a0f 100644 --- a/drivers/net/irda/irtty-sir.c +++ b/drivers/net/irda/irtty-sir.c | |||
@@ -124,8 +124,8 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed) | |||
124 | tty = priv->tty; | 124 | tty = priv->tty; |
125 | 125 | ||
126 | mutex_lock(&tty->termios_mutex); | 126 | mutex_lock(&tty->termios_mutex); |
127 | old_termios = *(tty->termios); | 127 | old_termios = tty->termios; |
128 | cflag = tty->termios->c_cflag; | 128 | cflag = tty->termios.c_cflag; |
129 | tty_encode_baud_rate(tty, speed, speed); | 129 | tty_encode_baud_rate(tty, speed, speed); |
130 | if (tty->ops->set_termios) | 130 | if (tty->ops->set_termios) |
131 | tty->ops->set_termios(tty, &old_termios); | 131 | tty->ops->set_termios(tty, &old_termios); |
@@ -281,15 +281,15 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop) | |||
281 | int cflag; | 281 | int cflag; |
282 | 282 | ||
283 | mutex_lock(&tty->termios_mutex); | 283 | mutex_lock(&tty->termios_mutex); |
284 | old_termios = *(tty->termios); | 284 | old_termios = tty->termios; |
285 | cflag = tty->termios->c_cflag; | 285 | cflag = tty->termios.c_cflag; |
286 | 286 | ||
287 | if (stop) | 287 | if (stop) |
288 | cflag &= ~CREAD; | 288 | cflag &= ~CREAD; |
289 | else | 289 | else |
290 | cflag |= CREAD; | 290 | cflag |= CREAD; |
291 | 291 | ||
292 | tty->termios->c_cflag = cflag; | 292 | tty->termios.c_cflag = cflag; |
293 | if (tty->ops->set_termios) | 293 | if (tty->ops->set_termios) |
294 | tty->ops->set_termios(tty, &old_termios); | 294 | tty->ops->set_termios(tty, &old_termios); |
295 | mutex_unlock(&tty->termios_mutex); | 295 | mutex_unlock(&tty->termios_mutex); |
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index 8d5476707912..002a442bf73f 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c | |||
@@ -28,9 +28,9 @@ | |||
28 | #include <net/irda/irda_device.h> | 28 | #include <net/irda/irda_device.h> |
29 | 29 | ||
30 | #include <mach/dma.h> | 30 | #include <mach/dma.h> |
31 | #include <mach/irda.h> | 31 | #include <linux/platform_data/irda-pxaficp.h> |
32 | #include <mach/regs-uart.h> | ||
33 | #include <mach/regs-ost.h> | 32 | #include <mach/regs-ost.h> |
33 | #include <mach/regs-uart.h> | ||
34 | 34 | ||
35 | #define FICP __REG(0x40800000) /* Start of FICP area */ | 35 | #define FICP __REG(0x40800000) /* Start of FICP area */ |
36 | #define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ | 36 | #define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */ |
@@ -112,6 +112,9 @@ struct pxa_irda { | |||
112 | int txdma; | 112 | int txdma; |
113 | int rxdma; | 113 | int rxdma; |
114 | 114 | ||
115 | int uart_irq; | ||
116 | int icp_irq; | ||
117 | |||
115 | struct irlap_cb *irlap; | 118 | struct irlap_cb *irlap; |
116 | struct qos_info qos; | 119 | struct qos_info qos; |
117 | 120 | ||
@@ -672,19 +675,19 @@ static int pxa_irda_start(struct net_device *dev) | |||
672 | 675 | ||
673 | si->speed = 9600; | 676 | si->speed = 9600; |
674 | 677 | ||
675 | err = request_irq(IRQ_STUART, pxa_irda_sir_irq, 0, dev->name, dev); | 678 | err = request_irq(si->uart_irq, pxa_irda_sir_irq, 0, dev->name, dev); |
676 | if (err) | 679 | if (err) |
677 | goto err_irq1; | 680 | goto err_irq1; |
678 | 681 | ||
679 | err = request_irq(IRQ_ICP, pxa_irda_fir_irq, 0, dev->name, dev); | 682 | err = request_irq(si->icp_irq, pxa_irda_fir_irq, 0, dev->name, dev); |
680 | if (err) | 683 | if (err) |
681 | goto err_irq2; | 684 | goto err_irq2; |
682 | 685 | ||
683 | /* | 686 | /* |
684 | * The interrupt must remain disabled for now. | 687 | * The interrupt must remain disabled for now. |
685 | */ | 688 | */ |
686 | disable_irq(IRQ_STUART); | 689 | disable_irq(si->uart_irq); |
687 | disable_irq(IRQ_ICP); | 690 | disable_irq(si->icp_irq); |
688 | 691 | ||
689 | err = -EBUSY; | 692 | err = -EBUSY; |
690 | si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev); | 693 | si->rxdma = pxa_request_dma("FICP_RX",DMA_PRIO_LOW, pxa_irda_fir_dma_rx_irq, dev); |
@@ -720,8 +723,8 @@ static int pxa_irda_start(struct net_device *dev) | |||
720 | /* | 723 | /* |
721 | * Now enable the interrupt and start the queue | 724 | * Now enable the interrupt and start the queue |
722 | */ | 725 | */ |
723 | enable_irq(IRQ_STUART); | 726 | enable_irq(si->uart_irq); |
724 | enable_irq(IRQ_ICP); | 727 | enable_irq(si->icp_irq); |
725 | netif_start_queue(dev); | 728 | netif_start_queue(dev); |
726 | 729 | ||
727 | printk(KERN_DEBUG "pxa_ir: irda driver opened\n"); | 730 | printk(KERN_DEBUG "pxa_ir: irda driver opened\n"); |
@@ -738,9 +741,9 @@ err_dma_rx_buff: | |||
738 | err_tx_dma: | 741 | err_tx_dma: |
739 | pxa_free_dma(si->rxdma); | 742 | pxa_free_dma(si->rxdma); |
740 | err_rx_dma: | 743 | err_rx_dma: |
741 | free_irq(IRQ_ICP, dev); | 744 | free_irq(si->icp_irq, dev); |
742 | err_irq2: | 745 | err_irq2: |
743 | free_irq(IRQ_STUART, dev); | 746 | free_irq(si->uart_irq, dev); |
744 | err_irq1: | 747 | err_irq1: |
745 | 748 | ||
746 | return err; | 749 | return err; |
@@ -760,8 +763,8 @@ static int pxa_irda_stop(struct net_device *dev) | |||
760 | si->irlap = NULL; | 763 | si->irlap = NULL; |
761 | } | 764 | } |
762 | 765 | ||
763 | free_irq(IRQ_STUART, dev); | 766 | free_irq(si->uart_irq, dev); |
764 | free_irq(IRQ_ICP, dev); | 767 | free_irq(si->icp_irq, dev); |
765 | 768 | ||
766 | pxa_free_dma(si->rxdma); | 769 | pxa_free_dma(si->rxdma); |
767 | pxa_free_dma(si->txdma); | 770 | pxa_free_dma(si->txdma); |
@@ -851,6 +854,9 @@ static int pxa_irda_probe(struct platform_device *pdev) | |||
851 | si->dev = &pdev->dev; | 854 | si->dev = &pdev->dev; |
852 | si->pdata = pdev->dev.platform_data; | 855 | si->pdata = pdev->dev.platform_data; |
853 | 856 | ||
857 | si->uart_irq = platform_get_irq(pdev, 0); | ||
858 | si->icp_irq = platform_get_irq(pdev, 1); | ||
859 | |||
854 | si->sir_clk = clk_get(&pdev->dev, "UARTCLK"); | 860 | si->sir_clk = clk_get(&pdev->dev, "UARTCLK"); |
855 | si->fir_clk = clk_get(&pdev->dev, "FICPCLK"); | 861 | si->fir_clk = clk_get(&pdev->dev, "FICPCLK"); |
856 | if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) { | 862 | if (IS_ERR(si->sir_clk) || IS_ERR(si->fir_clk)) { |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 62f30b46fa42..605a4baa9b7b 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -1107,7 +1107,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty, | |||
1107 | struct ktermios *old) | 1107 | struct ktermios *old) |
1108 | { | 1108 | { |
1109 | struct hso_serial *serial = tty->driver_data; | 1109 | struct hso_serial *serial = tty->driver_data; |
1110 | struct ktermios *termios; | ||
1111 | 1110 | ||
1112 | if (!serial) { | 1111 | if (!serial) { |
1113 | printk(KERN_ERR "%s: no tty structures", __func__); | 1112 | printk(KERN_ERR "%s: no tty structures", __func__); |
@@ -1119,16 +1118,15 @@ static void _hso_serial_set_termios(struct tty_struct *tty, | |||
1119 | /* | 1118 | /* |
1120 | * Fix up unsupported bits | 1119 | * Fix up unsupported bits |
1121 | */ | 1120 | */ |
1122 | termios = tty->termios; | 1121 | tty->termios.c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */ |
1123 | termios->c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */ | ||
1124 | 1122 | ||
1125 | termios->c_cflag &= | 1123 | tty->termios.c_cflag &= |
1126 | ~(CSIZE /* no size */ | 1124 | ~(CSIZE /* no size */ |
1127 | | PARENB /* disable parity bit */ | 1125 | | PARENB /* disable parity bit */ |
1128 | | CBAUD /* clear current baud rate */ | 1126 | | CBAUD /* clear current baud rate */ |
1129 | | CBAUDEX); /* clear current buad rate */ | 1127 | | CBAUDEX); /* clear current buad rate */ |
1130 | 1128 | ||
1131 | termios->c_cflag |= CS8; /* character size 8 bits */ | 1129 | tty->termios.c_cflag |= CS8; /* character size 8 bits */ |
1132 | 1130 | ||
1133 | /* baud rate 115200 */ | 1131 | /* baud rate 115200 */ |
1134 | tty_encode_baud_rate(tty, 115200, 115200); | 1132 | tty_encode_baud_rate(tty, 115200, 115200); |
@@ -1425,14 +1423,14 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1425 | 1423 | ||
1426 | if (old) | 1424 | if (old) |
1427 | D5("Termios called with: cflags new[%d] - old[%d]", | 1425 | D5("Termios called with: cflags new[%d] - old[%d]", |
1428 | tty->termios->c_cflag, old->c_cflag); | 1426 | tty->termios.c_cflag, old->c_cflag); |
1429 | 1427 | ||
1430 | /* the actual setup */ | 1428 | /* the actual setup */ |
1431 | spin_lock_irqsave(&serial->serial_lock, flags); | 1429 | spin_lock_irqsave(&serial->serial_lock, flags); |
1432 | if (serial->port.count) | 1430 | if (serial->port.count) |
1433 | _hso_serial_set_termios(tty, old); | 1431 | _hso_serial_set_termios(tty, old); |
1434 | else | 1432 | else |
1435 | tty->termios = old; | 1433 | tty->termios = *old; |
1436 | spin_unlock_irqrestore(&serial->serial_lock, flags); | 1434 | spin_unlock_irqrestore(&serial->serial_lock, flags); |
1437 | 1435 | ||
1438 | /* done */ | 1436 | /* done */ |
@@ -2289,9 +2287,11 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
2289 | if (minor < 0) | 2287 | if (minor < 0) |
2290 | goto exit; | 2288 | goto exit; |
2291 | 2289 | ||
2290 | tty_port_init(&serial->port); | ||
2291 | |||
2292 | /* register our minor number */ | 2292 | /* register our minor number */ |
2293 | serial->parent->dev = tty_register_device(tty_drv, minor, | 2293 | serial->parent->dev = tty_port_register_device(&serial->port, tty_drv, |
2294 | &serial->parent->interface->dev); | 2294 | minor, &serial->parent->interface->dev); |
2295 | dev = serial->parent->dev; | 2295 | dev = serial->parent->dev; |
2296 | dev_set_drvdata(dev, serial->parent); | 2296 | dev_set_drvdata(dev, serial->parent); |
2297 | i = device_create_file(dev, &dev_attr_hsotype); | 2297 | i = device_create_file(dev, &dev_attr_hsotype); |
@@ -2300,7 +2300,6 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs, | |||
2300 | serial->minor = minor; | 2300 | serial->minor = minor; |
2301 | serial->magic = HSO_SERIAL_MAGIC; | 2301 | serial->magic = HSO_SERIAL_MAGIC; |
2302 | spin_lock_init(&serial->serial_lock); | 2302 | spin_lock_init(&serial->serial_lock); |
2303 | tty_port_init(&serial->port); | ||
2304 | serial->num_rx_urbs = num_urbs; | 2303 | serial->num_rx_urbs = num_urbs; |
2305 | 2304 | ||
2306 | /* RX, allocate urb and initialize */ | 2305 | /* RX, allocate urb and initialize */ |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index adfab3fc5478..b1ba68f1a049 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -297,7 +297,7 @@ static int qmi_wwan_suspend(struct usb_interface *intf, pm_message_t message) | |||
297 | if (ret < 0) | 297 | if (ret < 0) |
298 | goto err; | 298 | goto err; |
299 | 299 | ||
300 | if (info->subdriver && info->subdriver->suspend) | 300 | if (intf == info->control && info->subdriver && info->subdriver->suspend) |
301 | ret = info->subdriver->suspend(intf, message); | 301 | ret = info->subdriver->suspend(intf, message); |
302 | if (ret < 0) | 302 | if (ret < 0) |
303 | usbnet_resume(intf); | 303 | usbnet_resume(intf); |
@@ -310,13 +310,14 @@ static int qmi_wwan_resume(struct usb_interface *intf) | |||
310 | struct usbnet *dev = usb_get_intfdata(intf); | 310 | struct usbnet *dev = usb_get_intfdata(intf); |
311 | struct qmi_wwan_state *info = (void *)&dev->data; | 311 | struct qmi_wwan_state *info = (void *)&dev->data; |
312 | int ret = 0; | 312 | int ret = 0; |
313 | bool callsub = (intf == info->control && info->subdriver && info->subdriver->resume); | ||
313 | 314 | ||
314 | if (info->subdriver && info->subdriver->resume) | 315 | if (callsub) |
315 | ret = info->subdriver->resume(intf); | 316 | ret = info->subdriver->resume(intf); |
316 | if (ret < 0) | 317 | if (ret < 0) |
317 | goto err; | 318 | goto err; |
318 | ret = usbnet_resume(intf); | 319 | ret = usbnet_resume(intf); |
319 | if (ret < 0 && info->subdriver && info->subdriver->resume && info->subdriver->suspend) | 320 | if (ret < 0 && callsub && info->subdriver->suspend) |
320 | info->subdriver->suspend(intf, PMSG_SUSPEND); | 321 | info->subdriver->suspend(intf, PMSG_SUSPEND); |
321 | err: | 322 | err: |
322 | return ret; | 323 | return ret; |
@@ -398,7 +399,6 @@ static const struct usb_device_id products[] = { | |||
398 | /* 4. Gobi 1000 devices */ | 399 | /* 4. Gobi 1000 devices */ |
399 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 400 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
400 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 401 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
401 | {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | ||
402 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ | 402 | {QMI_GOBI1K_DEVICE(0x04da, 0x250d)}, /* Panasonic Gobi Modem device */ |
403 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ | 403 | {QMI_GOBI1K_DEVICE(0x413c, 0x8172)}, /* Dell Gobi Modem device */ |
404 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ | 404 | {QMI_GOBI1K_DEVICE(0x1410, 0xa001)}, /* Novatel Gobi Modem device */ |
@@ -440,6 +440,7 @@ static const struct usb_device_id products[] = { | |||
440 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ | 440 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ |
441 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ | 441 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ |
442 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ | 442 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ |
443 | {QMI_GOBI_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | ||
443 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ | 444 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ |
444 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ | 445 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ |
445 | {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ | 446 | {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ |
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index 7be49ea60b6d..8e22417fa6c1 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c | |||
@@ -656,7 +656,7 @@ static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) | |||
656 | return -EIO; | 656 | return -EIO; |
657 | } | 657 | } |
658 | 658 | ||
659 | *datap = *attrdata; | 659 | *datap = le16_to_cpu(*attrdata); |
660 | 660 | ||
661 | kfree(attrdata); | 661 | kfree(attrdata); |
662 | return result; | 662 | return result; |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index fd4b26d46fd5..fc9f578a1e25 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -1201,19 +1201,26 @@ deferred: | |||
1201 | } | 1201 | } |
1202 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); | 1202 | EXPORT_SYMBOL_GPL(usbnet_start_xmit); |
1203 | 1203 | ||
1204 | static void rx_alloc_submit(struct usbnet *dev, gfp_t flags) | 1204 | static int rx_alloc_submit(struct usbnet *dev, gfp_t flags) |
1205 | { | 1205 | { |
1206 | struct urb *urb; | 1206 | struct urb *urb; |
1207 | int i; | 1207 | int i; |
1208 | int ret = 0; | ||
1208 | 1209 | ||
1209 | /* don't refill the queue all at once */ | 1210 | /* don't refill the queue all at once */ |
1210 | for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { | 1211 | for (i = 0; i < 10 && dev->rxq.qlen < RX_QLEN(dev); i++) { |
1211 | urb = usb_alloc_urb(0, flags); | 1212 | urb = usb_alloc_urb(0, flags); |
1212 | if (urb != NULL) { | 1213 | if (urb != NULL) { |
1213 | if (rx_submit(dev, urb, flags) == -ENOLINK) | 1214 | ret = rx_submit(dev, urb, flags); |
1214 | return; | 1215 | if (ret) |
1216 | goto err; | ||
1217 | } else { | ||
1218 | ret = -ENOMEM; | ||
1219 | goto err; | ||
1215 | } | 1220 | } |
1216 | } | 1221 | } |
1222 | err: | ||
1223 | return ret; | ||
1217 | } | 1224 | } |
1218 | 1225 | ||
1219 | /*-------------------------------------------------------------------------*/ | 1226 | /*-------------------------------------------------------------------------*/ |
@@ -1257,7 +1264,8 @@ static void usbnet_bh (unsigned long param) | |||
1257 | int temp = dev->rxq.qlen; | 1264 | int temp = dev->rxq.qlen; |
1258 | 1265 | ||
1259 | if (temp < RX_QLEN(dev)) { | 1266 | if (temp < RX_QLEN(dev)) { |
1260 | rx_alloc_submit(dev, GFP_ATOMIC); | 1267 | if (rx_alloc_submit(dev, GFP_ATOMIC) == -ENOLINK) |
1268 | return; | ||
1261 | if (temp != dev->rxq.qlen) | 1269 | if (temp != dev->rxq.qlen) |
1262 | netif_dbg(dev, link, dev->net, | 1270 | netif_dbg(dev, link, dev->net, |
1263 | "rxqlen %d --> %d\n", | 1271 | "rxqlen %d --> %d\n", |
diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index aaaca9aa2293..3f575afd8cfc 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
12 | 12 | ||
13 | #include <linux/module.h> | ||
13 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
14 | #include <linux/cdev.h> | 15 | #include <linux/cdev.h> |
15 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2c9f7d7ed4cc..0ed3846f9cbb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
@@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
142 | }; | 142 | }; |
143 | int training_power; | 143 | int training_power; |
144 | int i, val; | 144 | int i, val; |
145 | u32 am2pm_mask = ah->paprd_ratemask; | ||
145 | 146 | ||
146 | if (IS_CHAN_2GHZ(ah->curchan)) | 147 | if (IS_CHAN_2GHZ(ah->curchan)) |
147 | training_power = ar9003_get_training_power_2g(ah); | 148 | training_power = ar9003_get_training_power_2g(ah); |
@@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
158 | } | 159 | } |
159 | ah->paprd_training_power = training_power; | 160 | ah->paprd_training_power = training_power; |
160 | 161 | ||
162 | if (AR_SREV_9330(ah)) | ||
163 | am2pm_mask = 0; | ||
164 | |||
161 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, | 165 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, |
162 | ah->paprd_ratemask); | 166 | ah->paprd_ratemask); |
163 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, | 167 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, |
164 | ah->paprd_ratemask); | 168 | am2pm_mask); |
165 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, | 169 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, |
166 | ah->paprd_ratemask_ht40); | 170 | ah->paprd_ratemask_ht40); |
167 | 171 | ||
@@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) | |||
782 | } | 786 | } |
783 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); | 787 | EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); |
784 | 788 | ||
789 | static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah, | ||
790 | struct ath9k_hw_cal_data *caldata, | ||
791 | int chain) | ||
792 | { | ||
793 | u32 *pa_in = caldata->pa_table[chain]; | ||
794 | int capdiv_offset, quick_drop_offset; | ||
795 | int capdiv2g, quick_drop; | ||
796 | int count = 0; | ||
797 | int i; | ||
798 | |||
799 | if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah)) | ||
800 | return false; | ||
801 | |||
802 | capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, | ||
803 | AR_PHY_65NM_CH0_TXRF3_CAPDIV2G); | ||
804 | |||
805 | quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | ||
806 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP); | ||
807 | |||
808 | if (quick_drop) | ||
809 | quick_drop -= 0x40; | ||
810 | |||
811 | for (i = 0; i < NUM_BIN + 1; i++) { | ||
812 | if (pa_in[i] == 1400) | ||
813 | count++; | ||
814 | } | ||
815 | |||
816 | if (AR_SREV_9485(ah)) { | ||
817 | if (pa_in[23] < 800) { | ||
818 | capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150); | ||
819 | capdiv2g += capdiv_offset; | ||
820 | if (capdiv2g > 7) { | ||
821 | capdiv2g = 7; | ||
822 | if (pa_in[23] < 600) { | ||
823 | quick_drop++; | ||
824 | if (quick_drop > 0) | ||
825 | quick_drop = 0; | ||
826 | } | ||
827 | } | ||
828 | } else if (pa_in[23] == 1400) { | ||
829 | quick_drop_offset = min_t(int, count / 3, 2); | ||
830 | quick_drop += quick_drop_offset; | ||
831 | capdiv2g += quick_drop_offset / 2; | ||
832 | |||
833 | if (capdiv2g > 7) | ||
834 | capdiv2g = 7; | ||
835 | |||
836 | if (quick_drop > 0) { | ||
837 | quick_drop = 0; | ||
838 | capdiv2g -= quick_drop_offset; | ||
839 | if (capdiv2g < 0) | ||
840 | capdiv2g = 0; | ||
841 | } | ||
842 | } else { | ||
843 | return false; | ||
844 | } | ||
845 | } else if (AR_SREV_9330(ah)) { | ||
846 | if (pa_in[23] < 1000) { | ||
847 | capdiv_offset = (1000 - pa_in[23]) / 100; | ||
848 | capdiv2g += capdiv_offset; | ||
849 | if (capdiv_offset > 3) { | ||
850 | capdiv_offset = 1; | ||
851 | quick_drop--; | ||
852 | } | ||
853 | |||
854 | capdiv2g += capdiv_offset; | ||
855 | if (capdiv2g > 6) | ||
856 | capdiv2g = 6; | ||
857 | if (quick_drop < -4) | ||
858 | quick_drop = -4; | ||
859 | } else if (pa_in[23] == 1400) { | ||
860 | if (count > 3) { | ||
861 | quick_drop++; | ||
862 | capdiv2g -= count / 4; | ||
863 | if (quick_drop > -2) | ||
864 | quick_drop = -2; | ||
865 | } else { | ||
866 | capdiv2g--; | ||
867 | } | ||
868 | |||
869 | if (capdiv2g < 0) | ||
870 | capdiv2g = 0; | ||
871 | } else { | ||
872 | return false; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, | ||
877 | AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g); | ||
878 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, | ||
879 | AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, | ||
880 | quick_drop); | ||
881 | |||
882 | return true; | ||
883 | } | ||
884 | |||
785 | int ar9003_paprd_create_curve(struct ath_hw *ah, | 885 | int ar9003_paprd_create_curve(struct ath_hw *ah, |
786 | struct ath9k_hw_cal_data *caldata, int chain) | 886 | struct ath9k_hw_cal_data *caldata, int chain) |
787 | { | 887 | { |
@@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah, | |||
817 | if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) | 917 | if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) |
818 | status = -2; | 918 | status = -2; |
819 | 919 | ||
920 | if (ar9003_paprd_retrain_pa_in(ah, caldata, chain)) | ||
921 | status = -EINPROGRESS; | ||
922 | |||
820 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, | 923 | REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, |
821 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); | 924 | AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); |
822 | 925 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7bfbaf065a43..84d3d4956861 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -625,6 +625,10 @@ | |||
625 | #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) | 625 | #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) |
626 | #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) | 626 | #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) |
627 | 627 | ||
628 | #define AR_PHY_65NM_CH0_TXRF3 0x16048 | ||
629 | #define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e | ||
630 | #define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1 | ||
631 | |||
628 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c | 632 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c |
629 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) | 633 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) |
630 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) | 634 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index bacdb8fb4ef4..9f83f71742a5 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -341,7 +341,8 @@ void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) | |||
341 | { | 341 | { |
342 | struct ath_btcoex *btcoex = &sc->btcoex; | 342 | struct ath_btcoex *btcoex = &sc->btcoex; |
343 | 343 | ||
344 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | 344 | if (btcoex->hw_timer_enabled) |
345 | ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); | ||
345 | } | 346 | } |
346 | 347 | ||
347 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) | 348 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 60b6a9daff7e..48af40151d23 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -463,9 +463,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
463 | ah->config.spurchans[i][1] = AR_NO_SPUR; | 463 | ah->config.spurchans[i][1] = AR_NO_SPUR; |
464 | } | 464 | } |
465 | 465 | ||
466 | /* PAPRD needs some more work to be enabled */ | ||
467 | ah->config.paprd_disable = 1; | ||
468 | |||
469 | ah->config.rx_intr_mitigation = true; | 466 | ah->config.rx_intr_mitigation = true; |
470 | ah->config.pcieSerDesWrite = true; | 467 | ah->config.pcieSerDesWrite = true; |
471 | 468 | ||
@@ -978,9 +975,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
978 | else | 975 | else |
979 | imr_reg |= AR_IMR_TXOK; | 976 | imr_reg |= AR_IMR_TXOK; |
980 | 977 | ||
981 | if (opmode == NL80211_IFTYPE_AP) | ||
982 | imr_reg |= AR_IMR_MIB; | ||
983 | |||
984 | ENABLE_REGWRITE_BUFFER(ah); | 978 | ENABLE_REGWRITE_BUFFER(ah); |
985 | 979 | ||
986 | REG_WRITE(ah, AR_IMR, imr_reg); | 980 | REG_WRITE(ah, AR_IMR, imr_reg); |
@@ -1778,6 +1772,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1778 | /* Operating channel changed, reset channel calibration data */ | 1772 | /* Operating channel changed, reset channel calibration data */ |
1779 | memset(caldata, 0, sizeof(*caldata)); | 1773 | memset(caldata, 0, sizeof(*caldata)); |
1780 | ath9k_init_nfcal_hist_buffer(ah, chan); | 1774 | ath9k_init_nfcal_hist_buffer(ah, chan); |
1775 | } else if (caldata) { | ||
1776 | caldata->paprd_packet_sent = false; | ||
1781 | } | 1777 | } |
1782 | ah->noise = ath9k_hw_getchan_noise(ah, chan); | 1778 | ah->noise = ath9k_hw_getchan_noise(ah, chan); |
1783 | 1779 | ||
@@ -2502,7 +2498,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2502 | pCap->tx_desc_len = sizeof(struct ar9003_txc); | 2498 | pCap->tx_desc_len = sizeof(struct ar9003_txc); |
2503 | pCap->txs_len = sizeof(struct ar9003_txs); | 2499 | pCap->txs_len = sizeof(struct ar9003_txs); |
2504 | if (!ah->config.paprd_disable && | 2500 | if (!ah->config.paprd_disable && |
2505 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) | 2501 | ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && |
2502 | !AR_SREV_9462(ah)) | ||
2506 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; | 2503 | pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; |
2507 | } else { | 2504 | } else { |
2508 | pCap->tx_desc_len = sizeof(struct ath_desc); | 2505 | pCap->tx_desc_len = sizeof(struct ath_desc); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ce7332c64efb..6599a75f01fe 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -405,6 +405,7 @@ struct ath9k_hw_cal_data { | |||
405 | int8_t iCoff; | 405 | int8_t iCoff; |
406 | int8_t qCoff; | 406 | int8_t qCoff; |
407 | bool rtt_done; | 407 | bool rtt_done; |
408 | bool paprd_packet_sent; | ||
408 | bool paprd_done; | 409 | bool paprd_done; |
409 | bool nfcal_pending; | 410 | bool nfcal_pending; |
410 | bool nfcal_interference; | 411 | bool nfcal_interference; |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index d4549e9aac5c..825a29cc9313 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
254 | int chain_ok = 0; | 254 | int chain_ok = 0; |
255 | int chain; | 255 | int chain; |
256 | int len = 1800; | 256 | int len = 1800; |
257 | int ret; | ||
257 | 258 | ||
258 | if (!caldata) | 259 | if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done) |
259 | return; | 260 | return; |
260 | 261 | ||
261 | ath9k_ps_wakeup(sc); | 262 | ath9k_ps_wakeup(sc); |
@@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
282 | continue; | 283 | continue; |
283 | 284 | ||
284 | chain_ok = 0; | 285 | chain_ok = 0; |
285 | |||
286 | ath_dbg(common, CALIBRATE, | ||
287 | "Sending PAPRD frame for thermal measurement on chain %d\n", | ||
288 | chain); | ||
289 | if (!ath_paprd_send_frame(sc, skb, chain)) | ||
290 | goto fail_paprd; | ||
291 | |||
292 | ar9003_paprd_setup_gain_table(ah, chain); | 286 | ar9003_paprd_setup_gain_table(ah, chain); |
293 | 287 | ||
294 | ath_dbg(common, CALIBRATE, | 288 | ath_dbg(common, CALIBRATE, |
@@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
302 | break; | 296 | break; |
303 | } | 297 | } |
304 | 298 | ||
305 | if (ar9003_paprd_create_curve(ah, caldata, chain)) { | 299 | ret = ar9003_paprd_create_curve(ah, caldata, chain); |
300 | if (ret == -EINPROGRESS) { | ||
301 | ath_dbg(common, CALIBRATE, | ||
302 | "PAPRD curve on chain %d needs to be re-trained\n", | ||
303 | chain); | ||
304 | break; | ||
305 | } else if (ret) { | ||
306 | ath_dbg(common, CALIBRATE, | 306 | ath_dbg(common, CALIBRATE, |
307 | "PAPRD create curve failed on chain %d\n", | 307 | "PAPRD create curve failed on chain %d\n", |
308 | chain); | 308 | chain); |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 2c9da6b2ecb1..0d4155aec48d 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2018,6 +2018,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2018 | 2018 | ||
2019 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); | 2019 | ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); |
2020 | 2020 | ||
2021 | if (sc->sc_ah->caldata) | ||
2022 | sc->sc_ah->caldata->paprd_packet_sent = true; | ||
2023 | |||
2021 | if (!(tx_flags & ATH_TX_ERROR)) | 2024 | if (!(tx_flags & ATH_TX_ERROR)) |
2022 | /* Frame was ACKed */ | 2025 | /* Frame was ACKed */ |
2023 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | 2026 | tx_info->flags |= IEEE80211_TX_STAT_ACK; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index a299d42da8e7..58f89fa9c9f8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -519,7 +519,7 @@ static void brcmf_usb_tx_complete(struct urb *urb) | |||
519 | else | 519 | else |
520 | devinfo->bus_pub.bus->dstats.tx_errors++; | 520 | devinfo->bus_pub.bus->dstats.tx_errors++; |
521 | 521 | ||
522 | dev_kfree_skb(req->skb); | 522 | brcmu_pkt_buf_free_skb(req->skb); |
523 | req->skb = NULL; | 523 | req->skb = NULL; |
524 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); | 524 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); |
525 | 525 | ||
@@ -540,7 +540,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
540 | devinfo->bus_pub.bus->dstats.rx_packets++; | 540 | devinfo->bus_pub.bus->dstats.rx_packets++; |
541 | } else { | 541 | } else { |
542 | devinfo->bus_pub.bus->dstats.rx_errors++; | 542 | devinfo->bus_pub.bus->dstats.rx_errors++; |
543 | dev_kfree_skb(skb); | 543 | brcmu_pkt_buf_free_skb(skb); |
544 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 544 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
545 | return; | 545 | return; |
546 | } | 546 | } |
@@ -550,13 +550,15 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
550 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { | 550 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { |
551 | brcmf_dbg(ERROR, "rx protocol error\n"); | 551 | brcmf_dbg(ERROR, "rx protocol error\n"); |
552 | brcmu_pkt_buf_free_skb(skb); | 552 | brcmu_pkt_buf_free_skb(skb); |
553 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | ||
553 | devinfo->bus_pub.bus->dstats.rx_errors++; | 554 | devinfo->bus_pub.bus->dstats.rx_errors++; |
554 | } else { | 555 | } else { |
555 | brcmf_rx_packet(devinfo->dev, ifidx, skb); | 556 | brcmf_rx_packet(devinfo->dev, ifidx, skb); |
556 | brcmf_usb_rx_refill(devinfo, req); | 557 | brcmf_usb_rx_refill(devinfo, req); |
557 | } | 558 | } |
558 | } else { | 559 | } else { |
559 | dev_kfree_skb(skb); | 560 | brcmu_pkt_buf_free_skb(skb); |
561 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | ||
560 | } | 562 | } |
561 | return; | 563 | return; |
562 | 564 | ||
@@ -581,14 +583,13 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, | |||
581 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, | 583 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->rx_pipe, |
582 | skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, | 584 | skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, |
583 | req); | 585 | req); |
584 | req->urb->transfer_flags |= URB_ZERO_PACKET; | ||
585 | req->devinfo = devinfo; | 586 | req->devinfo = devinfo; |
587 | brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); | ||
586 | 588 | ||
587 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); | 589 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); |
588 | if (ret == 0) { | 590 | if (ret) { |
589 | brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); | 591 | brcmf_usb_del_fromq(devinfo, req); |
590 | } else { | 592 | brcmu_pkt_buf_free_skb(req->skb); |
591 | dev_kfree_skb(req->skb); | ||
592 | req->skb = NULL; | 593 | req->skb = NULL; |
593 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); | 594 | brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); |
594 | } | 595 | } |
@@ -683,23 +684,22 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) | |||
683 | 684 | ||
684 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); | 685 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); |
685 | if (!req) { | 686 | if (!req) { |
687 | brcmu_pkt_buf_free_skb(skb); | ||
686 | brcmf_dbg(ERROR, "no req to send\n"); | 688 | brcmf_dbg(ERROR, "no req to send\n"); |
687 | return -ENOMEM; | 689 | return -ENOMEM; |
688 | } | 690 | } |
689 | if (!req->urb) { | ||
690 | brcmf_dbg(ERROR, "no urb for req %p\n", req); | ||
691 | return -ENOBUFS; | ||
692 | } | ||
693 | 691 | ||
694 | req->skb = skb; | 692 | req->skb = skb; |
695 | req->devinfo = devinfo; | 693 | req->devinfo = devinfo; |
696 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, | 694 | usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, |
697 | skb->data, skb->len, brcmf_usb_tx_complete, req); | 695 | skb->data, skb->len, brcmf_usb_tx_complete, req); |
698 | req->urb->transfer_flags |= URB_ZERO_PACKET; | 696 | req->urb->transfer_flags |= URB_ZERO_PACKET; |
697 | brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); | ||
699 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); | 698 | ret = usb_submit_urb(req->urb, GFP_ATOMIC); |
700 | if (!ret) { | 699 | if (ret) { |
701 | brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); | 700 | brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n"); |
702 | } else { | 701 | brcmf_usb_del_fromq(devinfo, req); |
702 | brcmu_pkt_buf_free_skb(req->skb); | ||
703 | req->skb = NULL; | 703 | req->skb = NULL; |
704 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); | 704 | brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); |
705 | } | 705 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 28c5fbb4af26..c36e92312443 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -1876,16 +1876,17 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, | |||
1876 | } | 1876 | } |
1877 | 1877 | ||
1878 | if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { | 1878 | if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { |
1879 | scb_val.val = cpu_to_le32(0); | 1879 | memset(&scb_val, 0, sizeof(scb_val)); |
1880 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, | 1880 | err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, |
1881 | sizeof(struct brcmf_scb_val_le)); | 1881 | sizeof(struct brcmf_scb_val_le)); |
1882 | if (err) | 1882 | if (err) { |
1883 | WL_ERR("Could not get rssi (%d)\n", err); | 1883 | WL_ERR("Could not get rssi (%d)\n", err); |
1884 | 1884 | } else { | |
1885 | rssi = le32_to_cpu(scb_val.val); | 1885 | rssi = le32_to_cpu(scb_val.val); |
1886 | sinfo->filled |= STATION_INFO_SIGNAL; | 1886 | sinfo->filled |= STATION_INFO_SIGNAL; |
1887 | sinfo->signal = rssi; | 1887 | sinfo->signal = rssi; |
1888 | WL_CONN("RSSI %d dBm\n", rssi); | 1888 | WL_CONN("RSSI %d dBm\n", rssi); |
1889 | } | ||
1889 | } | 1890 | } |
1890 | 1891 | ||
1891 | done: | 1892 | done: |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e970897f6ab5..4cb234349fbf 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -1326,6 +1326,11 @@ static int if_sdio_suspend(struct device *dev) | |||
1326 | 1326 | ||
1327 | mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); | 1327 | mmc_pm_flag_t flags = sdio_get_host_pm_caps(func); |
1328 | 1328 | ||
1329 | /* If we're powered off anyway, just let the mmc layer remove the | ||
1330 | * card. */ | ||
1331 | if (!lbs_iface_active(card->priv)) | ||
1332 | return -ENOSYS; | ||
1333 | |||
1329 | dev_info(dev, "%s: suspend: PM flags = 0x%x\n", | 1334 | dev_info(dev, "%s: suspend: PM flags = 0x%x\n", |
1330 | sdio_func_id(func), flags); | 1335 | sdio_func_id(func), flags); |
1331 | 1336 | ||
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index c68adec3cc8b..565527aee0ea 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -170,7 +170,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, | |||
170 | cmd_code = le16_to_cpu(host_cmd->command); | 170 | cmd_code = le16_to_cpu(host_cmd->command); |
171 | cmd_size = le16_to_cpu(host_cmd->size); | 171 | cmd_size = le16_to_cpu(host_cmd->size); |
172 | 172 | ||
173 | skb_trim(cmd_node->cmd_skb, cmd_size); | 173 | /* Adjust skb length */ |
174 | if (cmd_node->cmd_skb->len > cmd_size) | ||
175 | /* | ||
176 | * cmd_size is less than sizeof(struct host_cmd_ds_command). | ||
177 | * Trim off the unused portion. | ||
178 | */ | ||
179 | skb_trim(cmd_node->cmd_skb, cmd_size); | ||
180 | else if (cmd_node->cmd_skb->len < cmd_size) | ||
181 | /* | ||
182 | * cmd_size is larger than sizeof(struct host_cmd_ds_command) | ||
183 | * because we have appended custom IE TLV. Increase skb length | ||
184 | * accordingly. | ||
185 | */ | ||
186 | skb_put(cmd_node->cmd_skb, cmd_size - cmd_node->cmd_skb->len); | ||
174 | 187 | ||
175 | do_gettimeofday(&tstamp); | 188 | do_gettimeofday(&tstamp); |
176 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," | 189 | dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d," |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 8b9dbd76a252..64328af496f5 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1611,6 +1611,7 @@ static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1611 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 1611 | static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
1612 | { | 1612 | { |
1613 | int retval; | 1613 | int retval; |
1614 | u32 reg; | ||
1614 | 1615 | ||
1615 | /* | 1616 | /* |
1616 | * Allocate eeprom data. | 1617 | * Allocate eeprom data. |
@@ -1624,6 +1625,14 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1624 | return retval; | 1625 | return retval; |
1625 | 1626 | ||
1626 | /* | 1627 | /* |
1628 | * Enable rfkill polling by setting GPIO direction of the | ||
1629 | * rfkill switch GPIO pin correctly. | ||
1630 | */ | ||
1631 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
1632 | rt2x00_set_field32(®, GPIOCSR_BIT8, 1); | ||
1633 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | ||
1634 | |||
1635 | /* | ||
1627 | * Initialize hw specifications. | 1636 | * Initialize hw specifications. |
1628 | */ | 1637 | */ |
1629 | retval = rt2400pci_probe_hw_mode(rt2x00dev); | 1638 | retval = rt2400pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h index d3a4a68cc439..7564ae992b73 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.h +++ b/drivers/net/wireless/rt2x00/rt2400pci.h | |||
@@ -670,6 +670,7 @@ | |||
670 | #define GPIOCSR_BIT5 FIELD32(0x00000020) | 670 | #define GPIOCSR_BIT5 FIELD32(0x00000020) |
671 | #define GPIOCSR_BIT6 FIELD32(0x00000040) | 671 | #define GPIOCSR_BIT6 FIELD32(0x00000040) |
672 | #define GPIOCSR_BIT7 FIELD32(0x00000080) | 672 | #define GPIOCSR_BIT7 FIELD32(0x00000080) |
673 | #define GPIOCSR_BIT8 FIELD32(0x00000100) | ||
673 | 674 | ||
674 | /* | 675 | /* |
675 | * BBPPCSR: BBP Pin control register. | 676 | * BBPPCSR: BBP Pin control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index d2cf8a4bc8b5..3de0406735f6 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1929,6 +1929,7 @@ static int rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1929 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 1929 | static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
1930 | { | 1930 | { |
1931 | int retval; | 1931 | int retval; |
1932 | u32 reg; | ||
1932 | 1933 | ||
1933 | /* | 1934 | /* |
1934 | * Allocate eeprom data. | 1935 | * Allocate eeprom data. |
@@ -1942,6 +1943,14 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1942 | return retval; | 1943 | return retval; |
1943 | 1944 | ||
1944 | /* | 1945 | /* |
1946 | * Enable rfkill polling by setting GPIO direction of the | ||
1947 | * rfkill switch GPIO pin correctly. | ||
1948 | */ | ||
1949 | rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®); | ||
1950 | rt2x00_set_field32(®, GPIOCSR_DIR0, 1); | ||
1951 | rt2x00pci_register_write(rt2x00dev, GPIOCSR, reg); | ||
1952 | |||
1953 | /* | ||
1945 | * Initialize hw specifications. | 1954 | * Initialize hw specifications. |
1946 | */ | 1955 | */ |
1947 | retval = rt2500pci_probe_hw_mode(rt2x00dev); | 1956 | retval = rt2500pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 3aae36bb0a9e..89fee311d8fd 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -283,7 +283,7 @@ static int rt2500usb_rfkill_poll(struct rt2x00_dev *rt2x00dev) | |||
283 | u16 reg; | 283 | u16 reg; |
284 | 284 | ||
285 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | 285 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); |
286 | return rt2x00_get_field32(reg, MAC_CSR19_BIT7); | 286 | return rt2x00_get_field16(reg, MAC_CSR19_BIT7); |
287 | } | 287 | } |
288 | 288 | ||
289 | #ifdef CONFIG_RT2X00_LIB_LEDS | 289 | #ifdef CONFIG_RT2X00_LIB_LEDS |
@@ -1768,6 +1768,7 @@ static int rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1768 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 1768 | static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
1769 | { | 1769 | { |
1770 | int retval; | 1770 | int retval; |
1771 | u16 reg; | ||
1771 | 1772 | ||
1772 | /* | 1773 | /* |
1773 | * Allocate eeprom data. | 1774 | * Allocate eeprom data. |
@@ -1781,6 +1782,14 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1781 | return retval; | 1782 | return retval; |
1782 | 1783 | ||
1783 | /* | 1784 | /* |
1785 | * Enable rfkill polling by setting GPIO direction of the | ||
1786 | * rfkill switch GPIO pin correctly. | ||
1787 | */ | ||
1788 | rt2500usb_register_read(rt2x00dev, MAC_CSR19, ®); | ||
1789 | rt2x00_set_field16(®, MAC_CSR19_BIT8, 0); | ||
1790 | rt2500usb_register_write(rt2x00dev, MAC_CSR19, reg); | ||
1791 | |||
1792 | /* | ||
1784 | * Initialize hw specifications. | 1793 | * Initialize hw specifications. |
1785 | */ | 1794 | */ |
1786 | retval = rt2500usb_probe_hw_mode(rt2x00dev); | 1795 | retval = rt2500usb_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h index b493306a7eed..196bd5103e4f 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.h +++ b/drivers/net/wireless/rt2x00/rt2500usb.h | |||
@@ -189,14 +189,15 @@ | |||
189 | * MAC_CSR19: GPIO control register. | 189 | * MAC_CSR19: GPIO control register. |
190 | */ | 190 | */ |
191 | #define MAC_CSR19 0x0426 | 191 | #define MAC_CSR19 0x0426 |
192 | #define MAC_CSR19_BIT0 FIELD32(0x0001) | 192 | #define MAC_CSR19_BIT0 FIELD16(0x0001) |
193 | #define MAC_CSR19_BIT1 FIELD32(0x0002) | 193 | #define MAC_CSR19_BIT1 FIELD16(0x0002) |
194 | #define MAC_CSR19_BIT2 FIELD32(0x0004) | 194 | #define MAC_CSR19_BIT2 FIELD16(0x0004) |
195 | #define MAC_CSR19_BIT3 FIELD32(0x0008) | 195 | #define MAC_CSR19_BIT3 FIELD16(0x0008) |
196 | #define MAC_CSR19_BIT4 FIELD32(0x0010) | 196 | #define MAC_CSR19_BIT4 FIELD16(0x0010) |
197 | #define MAC_CSR19_BIT5 FIELD32(0x0020) | 197 | #define MAC_CSR19_BIT5 FIELD16(0x0020) |
198 | #define MAC_CSR19_BIT6 FIELD32(0x0040) | 198 | #define MAC_CSR19_BIT6 FIELD16(0x0040) |
199 | #define MAC_CSR19_BIT7 FIELD32(0x0080) | 199 | #define MAC_CSR19_BIT7 FIELD16(0x0080) |
200 | #define MAC_CSR19_BIT8 FIELD16(0x0100) | ||
200 | 201 | ||
201 | /* | 202 | /* |
202 | * MAC_CSR20: LED control register. | 203 | * MAC_CSR20: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index cb8c2aca54e4..b93516d832fb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -4089,6 +4089,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
4089 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 4089 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
4090 | msleep(1); | 4090 | msleep(1); |
4091 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | 4091 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); |
4092 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 0); | ||
4092 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | 4093 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); |
4093 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | 4094 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); |
4094 | } | 4095 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 98aa426a3564..4765bbd654cd 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -983,6 +983,7 @@ static int rt2800pci_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
984 | { | 984 | { |
985 | int retval; | 985 | int retval; |
986 | u32 reg; | ||
986 | 987 | ||
987 | /* | 988 | /* |
988 | * Allocate eeprom data. | 989 | * Allocate eeprom data. |
@@ -996,6 +997,14 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
996 | return retval; | 997 | return retval; |
997 | 998 | ||
998 | /* | 999 | /* |
1000 | * Enable rfkill polling by setting GPIO direction of the | ||
1001 | * rfkill switch GPIO pin correctly. | ||
1002 | */ | ||
1003 | rt2x00pci_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
1004 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); | ||
1005 | rt2x00pci_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
1006 | |||
1007 | /* | ||
999 | * Initialize hw specifications. | 1008 | * Initialize hw specifications. |
1000 | */ | 1009 | */ |
1001 | retval = rt2800_probe_hw_mode(rt2x00dev); | 1010 | retval = rt2800_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 6cf336595e25..6b4226b71618 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -667,8 +667,16 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry, | |||
667 | skb_pull(entry->skb, RXINFO_DESC_SIZE); | 667 | skb_pull(entry->skb, RXINFO_DESC_SIZE); |
668 | 668 | ||
669 | /* | 669 | /* |
670 | * FIXME: we need to check for rx_pkt_len validity | 670 | * Check for rx_pkt_len validity. Return if invalid, leaving |
671 | * rxdesc->size zeroed out by the upper level. | ||
671 | */ | 672 | */ |
673 | if (unlikely(rx_pkt_len == 0 || | ||
674 | rx_pkt_len > entry->queue->data_size)) { | ||
675 | ERROR(entry->queue->rt2x00dev, | ||
676 | "Bad frame size %d, forcing to 0\n", rx_pkt_len); | ||
677 | return; | ||
678 | } | ||
679 | |||
672 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); | 680 | rxd = (__le32 *)(entry->skb->data + rx_pkt_len); |
673 | 681 | ||
674 | /* | 682 | /* |
@@ -736,6 +744,7 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
736 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 744 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
737 | { | 745 | { |
738 | int retval; | 746 | int retval; |
747 | u32 reg; | ||
739 | 748 | ||
740 | /* | 749 | /* |
741 | * Allocate eeprom data. | 750 | * Allocate eeprom data. |
@@ -749,6 +758,14 @@ static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
749 | return retval; | 758 | return retval; |
750 | 759 | ||
751 | /* | 760 | /* |
761 | * Enable rfkill polling by setting GPIO direction of the | ||
762 | * rfkill switch GPIO pin correctly. | ||
763 | */ | ||
764 | rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
765 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT2, 1); | ||
766 | rt2x00usb_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
767 | |||
768 | /* | ||
752 | * Initialize hw specifications. | 769 | * Initialize hw specifications. |
753 | */ | 770 | */ |
754 | retval = rt2800_probe_hw_mode(rt2x00dev); | 771 | retval = rt2800_probe_hw_mode(rt2x00dev); |
@@ -1157,6 +1174,8 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1157 | { USB_DEVICE(0x1690, 0x0744) }, | 1174 | { USB_DEVICE(0x1690, 0x0744) }, |
1158 | { USB_DEVICE(0x1690, 0x0761) }, | 1175 | { USB_DEVICE(0x1690, 0x0761) }, |
1159 | { USB_DEVICE(0x1690, 0x0764) }, | 1176 | { USB_DEVICE(0x1690, 0x0764) }, |
1177 | /* ASUS */ | ||
1178 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
1160 | /* Cisco */ | 1179 | /* Cisco */ |
1161 | { USB_DEVICE(0x167b, 0x4001) }, | 1180 | { USB_DEVICE(0x167b, 0x4001) }, |
1162 | /* EnGenius */ | 1181 | /* EnGenius */ |
@@ -1222,7 +1241,6 @@ static struct usb_device_id rt2800usb_device_table[] = { | |||
1222 | { USB_DEVICE(0x0b05, 0x1760) }, | 1241 | { USB_DEVICE(0x0b05, 0x1760) }, |
1223 | { USB_DEVICE(0x0b05, 0x1761) }, | 1242 | { USB_DEVICE(0x0b05, 0x1761) }, |
1224 | { USB_DEVICE(0x0b05, 0x1790) }, | 1243 | { USB_DEVICE(0x0b05, 0x1790) }, |
1225 | { USB_DEVICE(0x0b05, 0x179d) }, | ||
1226 | /* AzureWave */ | 1244 | /* AzureWave */ |
1227 | { USB_DEVICE(0x13d3, 0x3262) }, | 1245 | { USB_DEVICE(0x13d3, 0x3262) }, |
1228 | { USB_DEVICE(0x13d3, 0x3284) }, | 1246 | { USB_DEVICE(0x13d3, 0x3284) }, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index a6b88bd4a1a5..3f07e36f462b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -629,7 +629,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp) | |||
629 | */ | 629 | */ |
630 | if (unlikely(rxdesc.size == 0 || | 630 | if (unlikely(rxdesc.size == 0 || |
631 | rxdesc.size > entry->queue->data_size)) { | 631 | rxdesc.size > entry->queue->data_size)) { |
632 | WARNING(rt2x00dev, "Wrong frame size %d max %d.\n", | 632 | ERROR(rt2x00dev, "Wrong frame size %d max %d.\n", |
633 | rxdesc.size, entry->queue->data_size); | 633 | rxdesc.size, entry->queue->data_size); |
634 | dev_kfree_skb(entry->skb); | 634 | dev_kfree_skb(entry->skb); |
635 | goto renew_skb; | 635 | goto renew_skb; |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 3f7bc5cadf9a..b8ec96163922 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2832,6 +2832,7 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2832 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 2832 | static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
2833 | { | 2833 | { |
2834 | int retval; | 2834 | int retval; |
2835 | u32 reg; | ||
2835 | 2836 | ||
2836 | /* | 2837 | /* |
2837 | * Disable power saving. | 2838 | * Disable power saving. |
@@ -2850,6 +2851,14 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2850 | return retval; | 2851 | return retval; |
2851 | 2852 | ||
2852 | /* | 2853 | /* |
2854 | * Enable rfkill polling by setting GPIO direction of the | ||
2855 | * rfkill switch GPIO pin correctly. | ||
2856 | */ | ||
2857 | rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®); | ||
2858 | rt2x00_set_field32(®, MAC_CSR13_BIT13, 1); | ||
2859 | rt2x00pci_register_write(rt2x00dev, MAC_CSR13, reg); | ||
2860 | |||
2861 | /* | ||
2853 | * Initialize hw specifications. | 2862 | * Initialize hw specifications. |
2854 | */ | 2863 | */ |
2855 | retval = rt61pci_probe_hw_mode(rt2x00dev); | 2864 | retval = rt61pci_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index e3cd6db76b0e..8f3da5a56766 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -372,6 +372,7 @@ struct hw_pairwise_ta_entry { | |||
372 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | 372 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) |
373 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | 373 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) |
374 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | 374 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) |
375 | #define MAC_CSR13_BIT13 FIELD32(0x00002000) | ||
375 | 376 | ||
376 | /* | 377 | /* |
377 | * MAC_CSR14: LED control register. | 378 | * MAC_CSR14: LED control register. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index ba6e434b859d..248436c13ce0 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2177,6 +2177,7 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2177 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 2177 | static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
2178 | { | 2178 | { |
2179 | int retval; | 2179 | int retval; |
2180 | u32 reg; | ||
2180 | 2181 | ||
2181 | /* | 2182 | /* |
2182 | * Allocate eeprom data. | 2183 | * Allocate eeprom data. |
@@ -2190,6 +2191,14 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2190 | return retval; | 2191 | return retval; |
2191 | 2192 | ||
2192 | /* | 2193 | /* |
2194 | * Enable rfkill polling by setting GPIO direction of the | ||
2195 | * rfkill switch GPIO pin correctly. | ||
2196 | */ | ||
2197 | rt2x00usb_register_read(rt2x00dev, MAC_CSR13, ®); | ||
2198 | rt2x00_set_field32(®, MAC_CSR13_BIT15, 0); | ||
2199 | rt2x00usb_register_write(rt2x00dev, MAC_CSR13, reg); | ||
2200 | |||
2201 | /* | ||
2193 | * Initialize hw specifications. | 2202 | * Initialize hw specifications. |
2194 | */ | 2203 | */ |
2195 | retval = rt73usb_probe_hw_mode(rt2x00dev); | 2204 | retval = rt73usb_probe_hw_mode(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 9f6b470414d3..df1cc116b83b 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -282,6 +282,9 @@ struct hw_pairwise_ta_entry { | |||
282 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) | 282 | #define MAC_CSR13_BIT10 FIELD32(0x00000400) |
283 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) | 283 | #define MAC_CSR13_BIT11 FIELD32(0x00000800) |
284 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) | 284 | #define MAC_CSR13_BIT12 FIELD32(0x00001000) |
285 | #define MAC_CSR13_BIT13 FIELD32(0x00002000) | ||
286 | #define MAC_CSR13_BIT14 FIELD32(0x00004000) | ||
287 | #define MAC_CSR13_BIT15 FIELD32(0x00008000) | ||
285 | 288 | ||
286 | /* | 289 | /* |
287 | * MAC_CSR14: LED control register. | 290 | * MAC_CSR14: LED control register. |
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c index 5d6de380e42b..352f96180bc7 100644 --- a/drivers/parport/parport_gsc.c +++ b/drivers/parport/parport_gsc.c | |||
@@ -271,6 +271,7 @@ struct parport *__devinit parport_gsc_probe_port (unsigned long base, | |||
271 | if (!parport_SPP_supported (p)) { | 271 | if (!parport_SPP_supported (p)) { |
272 | /* No port. */ | 272 | /* No port. */ |
273 | kfree (priv); | 273 | kfree (priv); |
274 | kfree(ops); | ||
274 | return NULL; | 275 | return NULL; |
275 | } | 276 | } |
276 | parport_PS2_supported (p); | 277 | parport_PS2_supported (p); |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index e9c32274df3f..1631eeaf440e 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -62,6 +62,7 @@ enum parport_pc_pci_cards { | |||
62 | timedia_9079a, | 62 | timedia_9079a, |
63 | timedia_9079b, | 63 | timedia_9079b, |
64 | timedia_9079c, | 64 | timedia_9079c, |
65 | wch_ch353_2s1p, | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* each element directly indexed from enum list, above */ | 68 | /* each element directly indexed from enum list, above */ |
@@ -145,6 +146,7 @@ static struct parport_pc_pci cards[] __devinitdata = { | |||
145 | /* timedia_9079a */ { 1, { { 2, 3 }, } }, | 146 | /* timedia_9079a */ { 1, { { 2, 3 }, } }, |
146 | /* timedia_9079b */ { 1, { { 2, 3 }, } }, | 147 | /* timedia_9079b */ { 1, { { 2, 3 }, } }, |
147 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, | 148 | /* timedia_9079c */ { 1, { { 2, 3 }, } }, |
149 | /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, | ||
148 | }; | 150 | }; |
149 | 151 | ||
150 | static struct pci_device_id parport_serial_pci_tbl[] = { | 152 | static struct pci_device_id parport_serial_pci_tbl[] = { |
@@ -243,7 +245,8 @@ static struct pci_device_id parport_serial_pci_tbl[] = { | |||
243 | { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, | 245 | { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, |
244 | { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, | 246 | { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, |
245 | { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, | 247 | { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, |
246 | 248 | /* WCH CARDS */ | |
249 | { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, | ||
247 | { 0, } /* terminate list */ | 250 | { 0, } /* terminate list */ |
248 | }; | 251 | }; |
249 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); | 252 | MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); |
@@ -460,6 +463,12 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { | |||
460 | .base_baud = 921600, | 463 | .base_baud = 921600, |
461 | .uart_offset = 8, | 464 | .uart_offset = 8, |
462 | }, | 465 | }, |
466 | [wch_ch353_2s1p] = { | ||
467 | .flags = FL_BASE0|FL_BASE_BARS, | ||
468 | .num_ports = 2, | ||
469 | .base_baud = 115200, | ||
470 | .uart_offset = 8, | ||
471 | }, | ||
463 | }; | 472 | }; |
464 | 473 | ||
465 | struct parport_serial_private { | 474 | struct parport_serial_private { |
diff --git a/drivers/pcmcia/omap_cf.c b/drivers/pcmcia/omap_cf.c index 0ad06a3bd562..fa74efe82206 100644 --- a/drivers/pcmcia/omap_cf.c +++ b/drivers/pcmcia/omap_cf.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/sizes.h> | 25 | #include <asm/sizes.h> |
26 | 26 | ||
27 | #include <plat/mux.h> | 27 | #include <mach/mux.h> |
28 | #include <plat/tc.h> | 28 | #include <plat/tc.h> |
29 | 29 | ||
30 | 30 | ||
diff --git a/drivers/pcmcia/pxa2xx_viper.c b/drivers/pcmcia/pxa2xx_viper.c index cb0c37ec7f24..a76f495953ab 100644 --- a/drivers/pcmcia/pxa2xx_viper.c +++ b/drivers/pcmcia/pxa2xx_viper.c | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | 27 | ||
28 | #include <mach/arcom-pcmcia.h> | 28 | #include <linux/platform_data/pcmcia-pxa2xx_viper.h> |
29 | 29 | ||
30 | #include "soc_common.h" | 30 | #include "soc_common.h" |
31 | #include "pxa2xx_base.h" | 31 | #include "pxa2xx_base.h" |
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index cc0f00d73d15..b446c9641212 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c | |||
@@ -1,11 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * U300 GPIO module. | 2 | * U300 GPIO module. |
3 | * | 3 | * |
4 | * Copyright (C) 2007-2011 ST-Ericsson AB | 4 | * Copyright (C) 2007-2012 ST-Ericsson AB |
5 | * License terms: GNU General Public License (GPL) version 2 | 5 | * License terms: GNU General Public License (GPL) version 2 |
6 | * This can driver either of the two basic GPIO cores | ||
7 | * available in the U300 platforms: | ||
8 | * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) | ||
9 | * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) | 6 | * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) |
10 | * Author: Linus Walleij <linus.walleij@linaro.org> | 7 | * Author: Linus Walleij <linus.walleij@linaro.org> |
11 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | 8 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> |
@@ -24,19 +21,22 @@ | |||
24 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
25 | #include <linux/pinctrl/consumer.h> | 22 | #include <linux/pinctrl/consumer.h> |
26 | #include <linux/pinctrl/pinconf-generic.h> | 23 | #include <linux/pinctrl/pinconf-generic.h> |
27 | #include <mach/gpio-u300.h> | 24 | #include <linux/platform_data/pinctrl-coh901.h> |
28 | #include "pinctrl-coh901.h" | 25 | #include "pinctrl-coh901.h" |
29 | 26 | ||
27 | #define U300_GPIO_PORT_STRIDE (0x30) | ||
30 | /* | 28 | /* |
31 | * Register definitions for COH 901 335 variant | 29 | * Control Register 32bit (R/W) |
30 | * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores | ||
31 | * gives the number of GPIO pins. | ||
32 | * bit 8-2 (mask 0x000001FC) contains the core version ID. | ||
32 | */ | 33 | */ |
33 | #define U300_335_PORT_STRIDE (0x1C) | 34 | #define U300_GPIO_CR (0x00) |
34 | /* Port X Pin Data Register 32bit, this is both input and output (R/W) */ | 35 | #define U300_GPIO_CR_SYNC_SEL_ENABLE (0x00000002UL) |
35 | #define U300_335_PXPDIR (0x00) | 36 | #define U300_GPIO_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL) |
36 | #define U300_335_PXPDOR (0x00) | 37 | #define U300_GPIO_PXPDIR (0x04) |
37 | /* Port X Pin Config Register 32bit (R/W) */ | 38 | #define U300_GPIO_PXPDOR (0x08) |
38 | #define U300_335_PXPCR (0x04) | 39 | #define U300_GPIO_PXPCR (0x0C) |
39 | /* This register layout is the same in both blocks */ | ||
40 | #define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) | 40 | #define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) |
41 | #define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) | 41 | #define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) |
42 | #define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) | 42 | #define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) |
@@ -44,53 +44,17 @@ | |||
44 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) | 44 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) |
45 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) | 45 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) |
46 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) | 46 | #define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) |
47 | /* Port X Interrupt Event Register 32bit (R/W) */ | 47 | #define U300_GPIO_PXPER (0x10) |
48 | #define U300_335_PXIEV (0x08) | 48 | #define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) |
49 | /* Port X Interrupt Enable Register 32bit (R/W) */ | 49 | #define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) |
50 | #define U300_335_PXIEN (0x0C) | 50 | #define U300_GPIO_PXIEV (0x14) |
51 | /* Port X Interrupt Force Register 32bit (R/W) */ | 51 | #define U300_GPIO_PXIEN (0x18) |
52 | #define U300_335_PXIFR (0x10) | 52 | #define U300_GPIO_PXIFR (0x1C) |
53 | /* Port X Interrupt Config Register 32bit (R/W) */ | 53 | #define U300_GPIO_PXICR (0x20) |
54 | #define U300_335_PXICR (0x14) | ||
55 | /* This register layout is the same in both blocks */ | ||
56 | #define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) | 54 | #define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) |
57 | #define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) | 55 | #define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) |
58 | #define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) | 56 | #define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) |
59 | #define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) | 57 | #define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) |
60 | /* Port X Pull-up Enable Register 32bit (R/W) */ | ||
61 | #define U300_335_PXPER (0x18) | ||
62 | /* This register layout is the same in both blocks */ | ||
63 | #define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) | ||
64 | #define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) | ||
65 | /* Control Register 32bit (R/W) */ | ||
66 | #define U300_335_CR (0x54) | ||
67 | #define U300_335_CR_BLOCK_CLOCK_ENABLE (0x00000001UL) | ||
68 | |||
69 | /* | ||
70 | * Register definitions for COH 901 571 / 3 variant | ||
71 | */ | ||
72 | #define U300_571_PORT_STRIDE (0x30) | ||
73 | /* | ||
74 | * Control Register 32bit (R/W) | ||
75 | * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores | ||
76 | * gives the number of GPIO pins. | ||
77 | * bit 8-2 (mask 0x000001FC) contains the core version ID. | ||
78 | */ | ||
79 | #define U300_571_CR (0x00) | ||
80 | #define U300_571_CR_SYNC_SEL_ENABLE (0x00000002UL) | ||
81 | #define U300_571_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL) | ||
82 | /* | ||
83 | * These registers have the same layout and function as the corresponding | ||
84 | * COH 901 335 registers, just at different offset. | ||
85 | */ | ||
86 | #define U300_571_PXPDIR (0x04) | ||
87 | #define U300_571_PXPDOR (0x08) | ||
88 | #define U300_571_PXPCR (0x0C) | ||
89 | #define U300_571_PXPER (0x10) | ||
90 | #define U300_571_PXIEV (0x14) | ||
91 | #define U300_571_PXIEN (0x18) | ||
92 | #define U300_571_PXIFR (0x1C) | ||
93 | #define U300_571_PXICR (0x20) | ||
94 | 58 | ||
95 | /* 8 bits per port, no version has more than 7 ports */ | 59 | /* 8 bits per port, no version has more than 7 ports */ |
96 | #define U300_GPIO_PINS_PER_PORT 8 | 60 | #define U300_GPIO_PINS_PER_PORT 8 |
@@ -149,8 +113,6 @@ struct u300_gpio_confdata { | |||
149 | 113 | ||
150 | /* BS335 has seven ports of 8 bits each = GPIO pins 0..55 */ | 114 | /* BS335 has seven ports of 8 bits each = GPIO pins 0..55 */ |
151 | #define BS335_GPIO_NUM_PORTS 7 | 115 | #define BS335_GPIO_NUM_PORTS 7 |
152 | /* BS365 has five ports of 8 bits each = GPIO pins 0..39 */ | ||
153 | #define BS365_GPIO_NUM_PORTS 5 | ||
154 | 116 | ||
155 | #define U300_FLOATING_INPUT { \ | 117 | #define U300_FLOATING_INPUT { \ |
156 | .bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \ | 118 | .bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \ |
@@ -172,7 +134,6 @@ struct u300_gpio_confdata { | |||
172 | .outval = 1, \ | 134 | .outval = 1, \ |
173 | } | 135 | } |
174 | 136 | ||
175 | |||
176 | /* Initial configuration */ | 137 | /* Initial configuration */ |
177 | static const struct __initconst u300_gpio_confdata | 138 | static const struct __initconst u300_gpio_confdata |
178 | bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { | 139 | bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { |
@@ -255,66 +216,6 @@ bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { | |||
255 | } | 216 | } |
256 | }; | 217 | }; |
257 | 218 | ||
258 | static const struct __initconst u300_gpio_confdata | ||
259 | bs365_gpio_config[BS365_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { | ||
260 | /* Port 0, pins 0-7 */ | ||
261 | { | ||
262 | U300_FLOATING_INPUT, | ||
263 | U300_OUTPUT_LOW, | ||
264 | U300_FLOATING_INPUT, | ||
265 | U300_OUTPUT_LOW, | ||
266 | U300_OUTPUT_LOW, | ||
267 | U300_OUTPUT_LOW, | ||
268 | U300_PULL_UP_INPUT, | ||
269 | U300_FLOATING_INPUT, | ||
270 | }, | ||
271 | /* Port 1, pins 0-7 */ | ||
272 | { | ||
273 | U300_OUTPUT_LOW, | ||
274 | U300_FLOATING_INPUT, | ||
275 | U300_OUTPUT_LOW, | ||
276 | U300_FLOATING_INPUT, | ||
277 | U300_FLOATING_INPUT, | ||
278 | U300_OUTPUT_HIGH, | ||
279 | U300_OUTPUT_LOW, | ||
280 | U300_OUTPUT_LOW, | ||
281 | }, | ||
282 | /* Port 2, pins 0-7 */ | ||
283 | { | ||
284 | U300_FLOATING_INPUT, | ||
285 | U300_PULL_UP_INPUT, | ||
286 | U300_OUTPUT_LOW, | ||
287 | U300_OUTPUT_LOW, | ||
288 | U300_PULL_UP_INPUT, | ||
289 | U300_PULL_UP_INPUT, | ||
290 | U300_PULL_UP_INPUT, | ||
291 | U300_PULL_UP_INPUT, | ||
292 | }, | ||
293 | /* Port 3, pins 0-7 */ | ||
294 | { | ||
295 | U300_PULL_UP_INPUT, | ||
296 | U300_PULL_UP_INPUT, | ||
297 | U300_PULL_UP_INPUT, | ||
298 | U300_PULL_UP_INPUT, | ||
299 | U300_PULL_UP_INPUT, | ||
300 | U300_PULL_UP_INPUT, | ||
301 | U300_PULL_UP_INPUT, | ||
302 | U300_PULL_UP_INPUT, | ||
303 | }, | ||
304 | /* Port 4, pins 0-7 */ | ||
305 | { | ||
306 | U300_PULL_UP_INPUT, | ||
307 | U300_PULL_UP_INPUT, | ||
308 | U300_PULL_UP_INPUT, | ||
309 | U300_PULL_UP_INPUT, | ||
310 | /* These 4 pins doesn't exist on DB3210 */ | ||
311 | U300_OUTPUT_LOW, | ||
312 | U300_OUTPUT_LOW, | ||
313 | U300_OUTPUT_LOW, | ||
314 | U300_OUTPUT_LOW, | ||
315 | } | ||
316 | }; | ||
317 | |||
318 | /** | 219 | /** |
319 | * to_u300_gpio() - get the pointer to u300_gpio | 220 | * to_u300_gpio() - get the pointer to u300_gpio |
320 | * @chip: the gpio chip member of the structure u300_gpio | 221 | * @chip: the gpio chip member of the structure u300_gpio |
@@ -716,13 +617,7 @@ static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio, | |||
716 | const struct u300_gpio_confdata *conf; | 617 | const struct u300_gpio_confdata *conf; |
717 | int offset = (i*8) + j; | 618 | int offset = (i*8) + j; |
718 | 619 | ||
719 | if (plat->variant == U300_GPIO_COH901571_3_BS335) | 620 | conf = &bs335_gpio_config[i][j]; |
720 | conf = &bs335_gpio_config[i][j]; | ||
721 | else if (plat->variant == U300_GPIO_COH901571_3_BS365) | ||
722 | conf = &bs365_gpio_config[i][j]; | ||
723 | else | ||
724 | break; | ||
725 | |||
726 | u300_gpio_init_pin(gpio, offset, conf); | 621 | u300_gpio_init_pin(gpio, offset, conf); |
727 | } | 622 | } |
728 | } | 623 | } |
@@ -796,50 +691,27 @@ static int __init u300_gpio_probe(struct platform_device *pdev) | |||
796 | goto err_no_ioremap; | 691 | goto err_no_ioremap; |
797 | } | 692 | } |
798 | 693 | ||
799 | if (plat->variant == U300_GPIO_COH901335) { | 694 | dev_info(gpio->dev, |
800 | dev_info(gpio->dev, | 695 | "initializing GPIO Controller COH 901 571/3\n"); |
801 | "initializing GPIO Controller COH 901 335\n"); | 696 | gpio->stride = U300_GPIO_PORT_STRIDE; |
802 | gpio->stride = U300_335_PORT_STRIDE; | 697 | gpio->pcr = U300_GPIO_PXPCR; |
803 | gpio->pcr = U300_335_PXPCR; | 698 | gpio->dor = U300_GPIO_PXPDOR; |
804 | gpio->dor = U300_335_PXPDOR; | 699 | gpio->dir = U300_GPIO_PXPDIR; |
805 | gpio->dir = U300_335_PXPDIR; | 700 | gpio->per = U300_GPIO_PXPER; |
806 | gpio->per = U300_335_PXPER; | 701 | gpio->icr = U300_GPIO_PXICR; |
807 | gpio->icr = U300_335_PXICR; | 702 | gpio->ien = U300_GPIO_PXIEN; |
808 | gpio->ien = U300_335_PXIEN; | 703 | gpio->iev = U300_GPIO_PXIEV; |
809 | gpio->iev = U300_335_PXIEV; | 704 | ifr = U300_GPIO_PXIFR; |
810 | ifr = U300_335_PXIFR; | 705 | |
811 | 706 | val = readl(gpio->base + U300_GPIO_CR); | |
812 | /* Turn on the GPIO block */ | 707 | dev_info(gpio->dev, "COH901571/3 block version: %d, " \ |
813 | writel(U300_335_CR_BLOCK_CLOCK_ENABLE, | 708 | "number of cores: %d totalling %d pins\n", |
814 | gpio->base + U300_335_CR); | 709 | ((val & 0x000001FC) >> 2), |
815 | } else if (plat->variant == U300_GPIO_COH901571_3_BS335 || | 710 | ((val & 0x0000FE00) >> 9), |
816 | plat->variant == U300_GPIO_COH901571_3_BS365) { | 711 | ((val & 0x0000FE00) >> 9) * 8); |
817 | dev_info(gpio->dev, | 712 | writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, |
818 | "initializing GPIO Controller COH 901 571/3\n"); | 713 | gpio->base + U300_GPIO_CR); |
819 | gpio->stride = U300_571_PORT_STRIDE; | 714 | u300_gpio_init_coh901571(gpio, plat); |
820 | gpio->pcr = U300_571_PXPCR; | ||
821 | gpio->dor = U300_571_PXPDOR; | ||
822 | gpio->dir = U300_571_PXPDIR; | ||
823 | gpio->per = U300_571_PXPER; | ||
824 | gpio->icr = U300_571_PXICR; | ||
825 | gpio->ien = U300_571_PXIEN; | ||
826 | gpio->iev = U300_571_PXIEV; | ||
827 | ifr = U300_571_PXIFR; | ||
828 | |||
829 | val = readl(gpio->base + U300_571_CR); | ||
830 | dev_info(gpio->dev, "COH901571/3 block version: %d, " \ | ||
831 | "number of cores: %d totalling %d pins\n", | ||
832 | ((val & 0x000001FC) >> 2), | ||
833 | ((val & 0x0000FE00) >> 9), | ||
834 | ((val & 0x0000FE00) >> 9) * 8); | ||
835 | writel(U300_571_CR_BLOCK_CLKRQ_ENABLE, | ||
836 | gpio->base + U300_571_CR); | ||
837 | u300_gpio_init_coh901571(gpio, plat); | ||
838 | } else { | ||
839 | dev_err(gpio->dev, "unknown block variant\n"); | ||
840 | err = -ENODEV; | ||
841 | goto err_unknown_variant; | ||
842 | } | ||
843 | 715 | ||
844 | /* Add each port with its IRQ separately */ | 716 | /* Add each port with its IRQ separately */ |
845 | INIT_LIST_HEAD(&gpio->port_list); | 717 | INIT_LIST_HEAD(&gpio->port_list); |
@@ -906,7 +778,6 @@ err_no_pinctrl: | |||
906 | err_no_chip: | 778 | err_no_chip: |
907 | err_no_port: | 779 | err_no_port: |
908 | u300_gpio_free_ports(gpio); | 780 | u300_gpio_free_ports(gpio); |
909 | err_unknown_variant: | ||
910 | iounmap(gpio->base); | 781 | iounmap(gpio->base); |
911 | err_no_ioremap: | 782 | err_no_ioremap: |
912 | release_mem_region(gpio->memres->start, resource_size(gpio->memres)); | 783 | release_mem_region(gpio->memres->start, resource_size(gpio->memres)); |
@@ -923,16 +794,11 @@ err_no_clk: | |||
923 | 794 | ||
924 | static int __exit u300_gpio_remove(struct platform_device *pdev) | 795 | static int __exit u300_gpio_remove(struct platform_device *pdev) |
925 | { | 796 | { |
926 | struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); | ||
927 | struct u300_gpio *gpio = platform_get_drvdata(pdev); | 797 | struct u300_gpio *gpio = platform_get_drvdata(pdev); |
928 | int err; | 798 | int err; |
929 | 799 | ||
930 | /* Turn off the GPIO block */ | 800 | /* Turn off the GPIO block */ |
931 | if (plat->variant == U300_GPIO_COH901335) | 801 | writel(0x00000000U, gpio->base + U300_GPIO_CR); |
932 | writel(0x00000000U, gpio->base + U300_335_CR); | ||
933 | if (plat->variant == U300_GPIO_COH901571_3_BS335 || | ||
934 | plat->variant == U300_GPIO_COH901571_3_BS365) | ||
935 | writel(0x00000000U, gpio->base + U300_571_CR); | ||
936 | 802 | ||
937 | err = gpiochip_remove(&gpio->chip); | 803 | err = gpiochip_remove(&gpio->chip); |
938 | if (err < 0) { | 804 | if (err < 0) { |
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 7fca6ce5952b..304360cd213e 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/pinctrl/pinctrl.h> | 17 | #include <linux/pinctrl/pinctrl.h> |
18 | #include <linux/pinctrl/pinmux.h> | 18 | #include <linux/pinctrl/pinmux.h> |
19 | #include <linux/pinctrl/consumer.h> | 19 | #include <linux/pinctrl/consumer.h> |
20 | #include <linux/pinctrl/machine.h> | ||
20 | #include <linux/of.h> | 21 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
22 | #include <linux/of_device.h> | 23 | #include <linux/of_device.h> |
@@ -916,11 +917,66 @@ static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s | |||
916 | seq_printf(s, " " DRIVER_NAME); | 917 | seq_printf(s, " " DRIVER_NAME); |
917 | } | 918 | } |
918 | 919 | ||
920 | static int sirfsoc_dt_node_to_map(struct pinctrl_dev *pctldev, | ||
921 | struct device_node *np_config, | ||
922 | struct pinctrl_map **map, unsigned *num_maps) | ||
923 | { | ||
924 | struct sirfsoc_pmx *spmx = pinctrl_dev_get_drvdata(pctldev); | ||
925 | struct device_node *np; | ||
926 | struct property *prop; | ||
927 | const char *function, *group; | ||
928 | int ret, index = 0, count = 0; | ||
929 | |||
930 | /* calculate number of maps required */ | ||
931 | for_each_child_of_node(np_config, np) { | ||
932 | ret = of_property_read_string(np, "sirf,function", &function); | ||
933 | if (ret < 0) | ||
934 | return ret; | ||
935 | |||
936 | ret = of_property_count_strings(np, "sirf,pins"); | ||
937 | if (ret < 0) | ||
938 | return ret; | ||
939 | |||
940 | count += ret; | ||
941 | } | ||
942 | |||
943 | if (!count) { | ||
944 | dev_err(spmx->dev, "No child nodes passed via DT\n"); | ||
945 | return -ENODEV; | ||
946 | } | ||
947 | |||
948 | *map = kzalloc(sizeof(**map) * count, GFP_KERNEL); | ||
949 | if (!*map) | ||
950 | return -ENOMEM; | ||
951 | |||
952 | for_each_child_of_node(np_config, np) { | ||
953 | of_property_read_string(np, "sirf,function", &function); | ||
954 | of_property_for_each_string(np, "sirf,pins", prop, group) { | ||
955 | (*map)[index].type = PIN_MAP_TYPE_MUX_GROUP; | ||
956 | (*map)[index].data.mux.group = group; | ||
957 | (*map)[index].data.mux.function = function; | ||
958 | index++; | ||
959 | } | ||
960 | } | ||
961 | |||
962 | *num_maps = count; | ||
963 | |||
964 | return 0; | ||
965 | } | ||
966 | |||
967 | static void sirfsoc_dt_free_map(struct pinctrl_dev *pctldev, | ||
968 | struct pinctrl_map *map, unsigned num_maps) | ||
969 | { | ||
970 | kfree(map); | ||
971 | } | ||
972 | |||
919 | static struct pinctrl_ops sirfsoc_pctrl_ops = { | 973 | static struct pinctrl_ops sirfsoc_pctrl_ops = { |
920 | .get_groups_count = sirfsoc_get_groups_count, | 974 | .get_groups_count = sirfsoc_get_groups_count, |
921 | .get_group_name = sirfsoc_get_group_name, | 975 | .get_group_name = sirfsoc_get_group_name, |
922 | .get_group_pins = sirfsoc_get_group_pins, | 976 | .get_group_pins = sirfsoc_get_group_pins, |
923 | .pin_dbg_show = sirfsoc_pin_dbg_show, | 977 | .pin_dbg_show = sirfsoc_pin_dbg_show, |
978 | .dt_node_to_map = sirfsoc_dt_node_to_map, | ||
979 | .dt_free_map = sirfsoc_dt_free_map, | ||
924 | }; | 980 | }; |
925 | 981 | ||
926 | struct sirfsoc_pmx_func { | 982 | struct sirfsoc_pmx_func { |
@@ -1221,7 +1277,7 @@ out_no_gpio_remap: | |||
1221 | } | 1277 | } |
1222 | 1278 | ||
1223 | static const struct of_device_id pinmux_ids[] __devinitconst = { | 1279 | static const struct of_device_id pinmux_ids[] __devinitconst = { |
1224 | { .compatible = "sirf,prima2-gpio-pinmux" }, | 1280 | { .compatible = "sirf,prima2-pinctrl" }, |
1225 | {} | 1281 | {} |
1226 | }; | 1282 | }; |
1227 | 1283 | ||
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 3782e1cd3697..934d861a3235 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -2196,10 +2196,8 @@ static int __init acer_wmi_init(void) | |||
2196 | interface->capability &= ~ACER_CAP_BRIGHTNESS; | 2196 | interface->capability &= ~ACER_CAP_BRIGHTNESS; |
2197 | pr_info("Brightness must be controlled by acpi video driver\n"); | 2197 | pr_info("Brightness must be controlled by acpi video driver\n"); |
2198 | } else { | 2198 | } else { |
2199 | #ifdef CONFIG_ACPI_VIDEO | ||
2200 | pr_info("Disabling ACPI video driver\n"); | 2199 | pr_info("Disabling ACPI video driver\n"); |
2201 | acpi_video_unregister(); | 2200 | acpi_video_unregister(); |
2202 | #endif | ||
2203 | } | 2201 | } |
2204 | 2202 | ||
2205 | if (wmi_has_guid(WMID_GUID3)) { | 2203 | if (wmi_has_guid(WMID_GUID3)) { |
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index dfb1a92ce949..db8f63841b42 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c | |||
@@ -101,7 +101,7 @@ static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port, | |||
101 | 101 | ||
102 | for (i = 0; i < 4; i++) { | 102 | for (i = 0; i < 4; i++) { |
103 | tmpval = (val >> (i * 8)) & 0xff; | 103 | tmpval = (val >> (i * 8)) & 0xff; |
104 | outb(tmpval, port + i); | 104 | outb(tmpval, gmux_data->iostart + port + i); |
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
@@ -142,8 +142,9 @@ static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port) | |||
142 | u8 val; | 142 | u8 val; |
143 | 143 | ||
144 | mutex_lock(&gmux_data->index_lock); | 144 | mutex_lock(&gmux_data->index_lock); |
145 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
146 | gmux_index_wait_ready(gmux_data); | 145 | gmux_index_wait_ready(gmux_data); |
146 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
147 | gmux_index_wait_complete(gmux_data); | ||
147 | val = inb(gmux_data->iostart + GMUX_PORT_VALUE); | 148 | val = inb(gmux_data->iostart + GMUX_PORT_VALUE); |
148 | mutex_unlock(&gmux_data->index_lock); | 149 | mutex_unlock(&gmux_data->index_lock); |
149 | 150 | ||
@@ -166,8 +167,9 @@ static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port) | |||
166 | u32 val; | 167 | u32 val; |
167 | 168 | ||
168 | mutex_lock(&gmux_data->index_lock); | 169 | mutex_lock(&gmux_data->index_lock); |
169 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
170 | gmux_index_wait_ready(gmux_data); | 170 | gmux_index_wait_ready(gmux_data); |
171 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
172 | gmux_index_wait_complete(gmux_data); | ||
171 | val = inl(gmux_data->iostart + GMUX_PORT_VALUE); | 173 | val = inl(gmux_data->iostart + GMUX_PORT_VALUE); |
172 | mutex_unlock(&gmux_data->index_lock); | 174 | mutex_unlock(&gmux_data->index_lock); |
173 | 175 | ||
@@ -461,18 +463,22 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
461 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); | 463 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); |
462 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { | 464 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { |
463 | if (gmux_is_indexed(gmux_data)) { | 465 | if (gmux_is_indexed(gmux_data)) { |
466 | u32 version; | ||
464 | mutex_init(&gmux_data->index_lock); | 467 | mutex_init(&gmux_data->index_lock); |
465 | gmux_data->indexed = true; | 468 | gmux_data->indexed = true; |
469 | version = gmux_read32(gmux_data, | ||
470 | GMUX_PORT_VERSION_MAJOR); | ||
471 | ver_major = (version >> 24) & 0xff; | ||
472 | ver_minor = (version >> 16) & 0xff; | ||
473 | ver_release = (version >> 8) & 0xff; | ||
466 | } else { | 474 | } else { |
467 | pr_info("gmux device not present\n"); | 475 | pr_info("gmux device not present\n"); |
468 | ret = -ENODEV; | 476 | ret = -ENODEV; |
469 | goto err_release; | 477 | goto err_release; |
470 | } | 478 | } |
471 | pr_info("Found indexed gmux\n"); | ||
472 | } else { | ||
473 | pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, | ||
474 | ver_release); | ||
475 | } | 479 | } |
480 | pr_info("Found gmux version %d.%d.%d [%s]\n", ver_major, ver_minor, | ||
481 | ver_release, (gmux_data->indexed ? "indexed" : "classic")); | ||
476 | 482 | ||
477 | memset(&props, 0, sizeof(props)); | 483 | memset(&props, 0, sizeof(props)); |
478 | props.type = BACKLIGHT_PLATFORM; | 484 | props.type = BACKLIGHT_PLATFORM; |
@@ -505,9 +511,7 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
505 | * Disable the other backlight choices. | 511 | * Disable the other backlight choices. |
506 | */ | 512 | */ |
507 | acpi_video_dmi_promote_vendor(); | 513 | acpi_video_dmi_promote_vendor(); |
508 | #if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE) | ||
509 | acpi_video_unregister(); | 514 | acpi_video_unregister(); |
510 | #endif | ||
511 | apple_bl_unregister(); | 515 | apple_bl_unregister(); |
512 | 516 | ||
513 | gmux_data->power_state = VGA_SWITCHEROO_ON; | 517 | gmux_data->power_state = VGA_SWITCHEROO_ON; |
@@ -593,9 +597,7 @@ static void __devexit gmux_remove(struct pnp_dev *pnp) | |||
593 | kfree(gmux_data); | 597 | kfree(gmux_data); |
594 | 598 | ||
595 | acpi_video_dmi_demote_vendor(); | 599 | acpi_video_dmi_demote_vendor(); |
596 | #if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE) | ||
597 | acpi_video_register(); | 600 | acpi_video_register(); |
598 | #endif | ||
599 | apple_bl_register(); | 601 | apple_bl_register(); |
600 | } | 602 | } |
601 | 603 | ||
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index e38f91be0b10..4b568df56643 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -85,7 +85,7 @@ static char *wled_type = "unknown"; | |||
85 | static char *bled_type = "unknown"; | 85 | static char *bled_type = "unknown"; |
86 | 86 | ||
87 | module_param(wled_type, charp, 0444); | 87 | module_param(wled_type, charp, 0444); |
88 | MODULE_PARM_DESC(wlan_status, "Set the wled type on boot " | 88 | MODULE_PARM_DESC(wled_type, "Set the wled type on boot " |
89 | "(unknown, led or rfkill). " | 89 | "(unknown, led or rfkill). " |
90 | "default is unknown"); | 90 | "default is unknown"); |
91 | 91 | ||
@@ -863,9 +863,9 @@ static ssize_t show_infos(struct device *dev, | |||
863 | * The significance of others is yet to be found. | 863 | * The significance of others is yet to be found. |
864 | * If we don't find the method, we assume the device are present. | 864 | * If we don't find the method, we assume the device are present. |
865 | */ | 865 | */ |
866 | rv = acpi_evaluate_integer(asus->handle, "HRWS", NULL, &temp); | 866 | rv = acpi_evaluate_integer(asus->handle, "HWRS", NULL, &temp); |
867 | if (!ACPI_FAILURE(rv)) | 867 | if (!ACPI_FAILURE(rv)) |
868 | len += sprintf(page + len, "HRWS value : %#x\n", | 868 | len += sprintf(page + len, "HWRS value : %#x\n", |
869 | (uint) temp); | 869 | (uint) temp); |
870 | /* | 870 | /* |
871 | * Another value for userspace: the ASYM method returns 0x02 for | 871 | * Another value for userspace: the ASYM method returns 0x02 for |
@@ -1751,9 +1751,9 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
1751 | * The significance of others is yet to be found. | 1751 | * The significance of others is yet to be found. |
1752 | */ | 1752 | */ |
1753 | status = | 1753 | status = |
1754 | acpi_evaluate_integer(asus->handle, "HRWS", NULL, &hwrs_result); | 1754 | acpi_evaluate_integer(asus->handle, "HWRS", NULL, &hwrs_result); |
1755 | if (!ACPI_FAILURE(status)) | 1755 | if (!ACPI_FAILURE(status)) |
1756 | pr_notice(" HRWS returned %x", (int)hwrs_result); | 1756 | pr_notice(" HWRS returned %x", (int)hwrs_result); |
1757 | 1757 | ||
1758 | if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) | 1758 | if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL)) |
1759 | asus->have_rsts = true; | 1759 | asus->have_rsts = true; |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 2eb9fe8e8efd..c0e9ff489b24 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -47,9 +47,7 @@ | |||
47 | #include <linux/thermal.h> | 47 | #include <linux/thermal.h> |
48 | #include <acpi/acpi_bus.h> | 48 | #include <acpi/acpi_bus.h> |
49 | #include <acpi/acpi_drivers.h> | 49 | #include <acpi/acpi_drivers.h> |
50 | #ifdef CONFIG_ACPI_VIDEO | ||
51 | #include <acpi/video.h> | 50 | #include <acpi/video.h> |
52 | #endif | ||
53 | 51 | ||
54 | #include "asus-wmi.h" | 52 | #include "asus-wmi.h" |
55 | 53 | ||
@@ -1704,10 +1702,8 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1704 | if (asus->driver->quirks->wmi_backlight_power) | 1702 | if (asus->driver->quirks->wmi_backlight_power) |
1705 | acpi_video_dmi_promote_vendor(); | 1703 | acpi_video_dmi_promote_vendor(); |
1706 | if (!acpi_video_backlight_support()) { | 1704 | if (!acpi_video_backlight_support()) { |
1707 | #ifdef CONFIG_ACPI_VIDEO | ||
1708 | pr_info("Disabling ACPI video driver\n"); | 1705 | pr_info("Disabling ACPI video driver\n"); |
1709 | acpi_video_unregister(); | 1706 | acpi_video_unregister(); |
1710 | #endif | ||
1711 | err = asus_wmi_backlight_init(asus); | 1707 | err = asus_wmi_backlight_init(asus); |
1712 | if (err && err != -ENODEV) | 1708 | if (err && err != -ENODEV) |
1713 | goto fail_backlight; | 1709 | goto fail_backlight; |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index dab91b48d22c..5ca264179f4e 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -610,12 +610,12 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
610 | 610 | ||
611 | if (!bus) { | 611 | if (!bus) { |
612 | pr_warn("Unable to find PCI bus 1?\n"); | 612 | pr_warn("Unable to find PCI bus 1?\n"); |
613 | goto out_unlock; | 613 | goto out_put_dev; |
614 | } | 614 | } |
615 | 615 | ||
616 | if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { | 616 | if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) { |
617 | pr_err("Unable to read PCI config space?\n"); | 617 | pr_err("Unable to read PCI config space?\n"); |
618 | goto out_unlock; | 618 | goto out_put_dev; |
619 | } | 619 | } |
620 | 620 | ||
621 | absent = (l == 0xffffffff); | 621 | absent = (l == 0xffffffff); |
@@ -627,7 +627,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
627 | absent ? "absent" : "present"); | 627 | absent ? "absent" : "present"); |
628 | pr_warn("skipped wireless hotplug as probably " | 628 | pr_warn("skipped wireless hotplug as probably " |
629 | "inappropriate for this model\n"); | 629 | "inappropriate for this model\n"); |
630 | goto out_unlock; | 630 | goto out_put_dev; |
631 | } | 631 | } |
632 | 632 | ||
633 | if (!blocked) { | 633 | if (!blocked) { |
@@ -635,7 +635,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
635 | if (dev) { | 635 | if (dev) { |
636 | /* Device already present */ | 636 | /* Device already present */ |
637 | pci_dev_put(dev); | 637 | pci_dev_put(dev); |
638 | goto out_unlock; | 638 | goto out_put_dev; |
639 | } | 639 | } |
640 | dev = pci_scan_single_device(bus, 0); | 640 | dev = pci_scan_single_device(bus, 0); |
641 | if (dev) { | 641 | if (dev) { |
@@ -650,6 +650,8 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
650 | pci_dev_put(dev); | 650 | pci_dev_put(dev); |
651 | } | 651 | } |
652 | } | 652 | } |
653 | out_put_dev: | ||
654 | pci_dev_put(port); | ||
653 | } | 655 | } |
654 | 656 | ||
655 | out_unlock: | 657 | out_unlock: |
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c index c1ca7bcebb66..dd90d15f5210 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c | |||
@@ -26,9 +26,7 @@ | |||
26 | #include <linux/seq_file.h> | 26 | #include <linux/seq_file.h> |
27 | #include <linux/debugfs.h> | 27 | #include <linux/debugfs.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #ifdef CONFIG_ACPI_VIDEO | ||
30 | #include <acpi/video.h> | 29 | #include <acpi/video.h> |
31 | #endif | ||
32 | 30 | ||
33 | /* | 31 | /* |
34 | * This driver is needed because a number of Samsung laptops do not hook | 32 | * This driver is needed because a number of Samsung laptops do not hook |
@@ -1558,9 +1556,7 @@ static int __init samsung_init(void) | |||
1558 | samsung->handle_backlight = false; | 1556 | samsung->handle_backlight = false; |
1559 | } else if (samsung->quirks->broken_acpi_video) { | 1557 | } else if (samsung->quirks->broken_acpi_video) { |
1560 | pr_info("Disabling ACPI video driver\n"); | 1558 | pr_info("Disabling ACPI video driver\n"); |
1561 | #ifdef CONFIG_ACPI_VIDEO | ||
1562 | acpi_video_unregister(); | 1559 | acpi_video_unregister(); |
1563 | #endif | ||
1564 | } | 1560 | } |
1565 | #endif | 1561 | #endif |
1566 | 1562 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 80e377949314..52daaa816e53 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -545,7 +545,7 @@ TPACPI_HANDLE(hkey, ec, "\\_SB.HKEY", /* 600e/x, 770e, 770x */ | |||
545 | */ | 545 | */ |
546 | 546 | ||
547 | static int acpi_evalf(acpi_handle handle, | 547 | static int acpi_evalf(acpi_handle handle, |
548 | void *res, char *method, char *fmt, ...) | 548 | int *res, char *method, char *fmt, ...) |
549 | { | 549 | { |
550 | char *fmt0 = fmt; | 550 | char *fmt0 = fmt; |
551 | struct acpi_object_list params; | 551 | struct acpi_object_list params; |
@@ -606,7 +606,7 @@ static int acpi_evalf(acpi_handle handle, | |||
606 | success = (status == AE_OK && | 606 | success = (status == AE_OK && |
607 | out_obj.type == ACPI_TYPE_INTEGER); | 607 | out_obj.type == ACPI_TYPE_INTEGER); |
608 | if (success && res) | 608 | if (success && res) |
609 | *(int *)res = out_obj.integer.value; | 609 | *res = out_obj.integer.value; |
610 | break; | 610 | break; |
611 | case 'v': /* void */ | 611 | case 'v': /* void */ |
612 | success = status == AE_OK; | 612 | success = status == AE_OK; |
@@ -7386,17 +7386,18 @@ static int fan_get_status(u8 *status) | |||
7386 | * Add TPACPI_FAN_RD_ACPI_FANS ? */ | 7386 | * Add TPACPI_FAN_RD_ACPI_FANS ? */ |
7387 | 7387 | ||
7388 | switch (fan_status_access_mode) { | 7388 | switch (fan_status_access_mode) { |
7389 | case TPACPI_FAN_RD_ACPI_GFAN: | 7389 | case TPACPI_FAN_RD_ACPI_GFAN: { |
7390 | /* 570, 600e/x, 770e, 770x */ | 7390 | /* 570, 600e/x, 770e, 770x */ |
7391 | int res; | ||
7391 | 7392 | ||
7392 | if (unlikely(!acpi_evalf(gfan_handle, &s, NULL, "d"))) | 7393 | if (unlikely(!acpi_evalf(gfan_handle, &res, NULL, "d"))) |
7393 | return -EIO; | 7394 | return -EIO; |
7394 | 7395 | ||
7395 | if (likely(status)) | 7396 | if (likely(status)) |
7396 | *status = s & 0x07; | 7397 | *status = res & 0x07; |
7397 | 7398 | ||
7398 | break; | 7399 | break; |
7399 | 7400 | } | |
7400 | case TPACPI_FAN_RD_TPEC: | 7401 | case TPACPI_FAN_RD_TPEC: |
7401 | /* all except 570, 600e/x, 770e, 770x */ | 7402 | /* all except 570, 600e/x, 770e, 770x */ |
7402 | if (unlikely(!acpi_ec_read(fan_status_offset, &s))) | 7403 | if (unlikely(!acpi_ec_read(fan_status_offset, &s))) |
diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c index 44efc6e202af..d4957b4edb62 100644 --- a/drivers/power/avs/smartreflex.c +++ b/drivers/power/avs/smartreflex.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
28 | #include <linux/power/smartreflex.h> | 28 | #include <linux/power/smartreflex.h> |
29 | 29 | ||
30 | #include <plat/cpu.h> | ||
31 | |||
30 | #define SMARTREFLEX_NAME_LEN 16 | 32 | #define SMARTREFLEX_NAME_LEN 16 |
31 | #define NVALUE_NAME_LEN 40 | 33 | #define NVALUE_NAME_LEN 40 |
32 | #define SR_DISABLE_TIMEOUT 200 | 34 | #define SR_DISABLE_TIMEOUT 200 |
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c index 0b66d0f25922..4b6688909fee 100644 --- a/drivers/pwm/pwm-tiecap.c +++ b/drivers/pwm/pwm-tiecap.c | |||
@@ -100,6 +100,13 @@ static int ecap_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
100 | writel(period_cycles, pc->mmio_base + CAP3); | 100 | writel(period_cycles, pc->mmio_base + CAP3); |
101 | } | 101 | } |
102 | 102 | ||
103 | if (!test_bit(PWMF_ENABLED, &pwm->flags)) { | ||
104 | reg_val = readw(pc->mmio_base + ECCTL2); | ||
105 | /* Disable APWM mode to put APWM output Low */ | ||
106 | reg_val &= ~ECCTL2_APWM_MODE; | ||
107 | writew(reg_val, pc->mmio_base + ECCTL2); | ||
108 | } | ||
109 | |||
103 | pm_runtime_put_sync(pc->chip.dev); | 110 | pm_runtime_put_sync(pc->chip.dev); |
104 | return 0; | 111 | return 0; |
105 | } | 112 | } |
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index c3756d1be194..b1996bcd5b78 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c | |||
@@ -104,6 +104,7 @@ struct ehrpwm_pwm_chip { | |||
104 | struct pwm_chip chip; | 104 | struct pwm_chip chip; |
105 | unsigned int clk_rate; | 105 | unsigned int clk_rate; |
106 | void __iomem *mmio_base; | 106 | void __iomem *mmio_base; |
107 | unsigned long period_cycles[NUM_PWM_CHANNEL]; | ||
107 | }; | 108 | }; |
108 | 109 | ||
109 | static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) | 110 | static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) |
@@ -210,6 +211,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
210 | unsigned long long c; | 211 | unsigned long long c; |
211 | unsigned long period_cycles, duty_cycles; | 212 | unsigned long period_cycles, duty_cycles; |
212 | unsigned short ps_divval, tb_divval; | 213 | unsigned short ps_divval, tb_divval; |
214 | int i; | ||
213 | 215 | ||
214 | if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) | 216 | if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) |
215 | return -ERANGE; | 217 | return -ERANGE; |
@@ -229,6 +231,28 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
229 | duty_cycles = (unsigned long)c; | 231 | duty_cycles = (unsigned long)c; |
230 | } | 232 | } |
231 | 233 | ||
234 | /* | ||
235 | * Period values should be same for multiple PWM channels as IP uses | ||
236 | * same period register for multiple channels. | ||
237 | */ | ||
238 | for (i = 0; i < NUM_PWM_CHANNEL; i++) { | ||
239 | if (pc->period_cycles[i] && | ||
240 | (pc->period_cycles[i] != period_cycles)) { | ||
241 | /* | ||
242 | * Allow channel to reconfigure period if no other | ||
243 | * channels being configured. | ||
244 | */ | ||
245 | if (i == pwm->hwpwm) | ||
246 | continue; | ||
247 | |||
248 | dev_err(chip->dev, "Period value conflicts with channel %d\n", | ||
249 | i); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | } | ||
253 | |||
254 | pc->period_cycles[pwm->hwpwm] = period_cycles; | ||
255 | |||
232 | /* Configure clock prescaler to support Low frequency PWM wave */ | 256 | /* Configure clock prescaler to support Low frequency PWM wave */ |
233 | if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, | 257 | if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, |
234 | &tb_divval)) { | 258 | &tb_divval)) { |
@@ -320,10 +344,15 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
320 | 344 | ||
321 | static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) | 345 | static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) |
322 | { | 346 | { |
347 | struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); | ||
348 | |||
323 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { | 349 | if (test_bit(PWMF_ENABLED, &pwm->flags)) { |
324 | dev_warn(chip->dev, "Removing PWM device without disabling\n"); | 350 | dev_warn(chip->dev, "Removing PWM device without disabling\n"); |
325 | pm_runtime_put_sync(chip->dev); | 351 | pm_runtime_put_sync(chip->dev); |
326 | } | 352 | } |
353 | |||
354 | /* set period value to zero on free */ | ||
355 | pc->period_cycles[pwm->hwpwm] = 0; | ||
327 | } | 356 | } |
328 | 357 | ||
329 | static const struct pwm_ops ehrpwm_pwm_ops = { | 358 | static const struct pwm_ops ehrpwm_pwm_ops = { |
diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 6caa222af77a..ab00cab905b7 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/err.h> | 22 | #include <linux/err.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | 24 | ||
25 | #include <linux/regulator/of_regulator.h> | ||
25 | #include <linux/regulator/driver.h> | 26 | #include <linux/regulator/driver.h> |
26 | #include <linux/regulator/machine.h> | 27 | #include <linux/regulator/machine.h> |
27 | #include <linux/mfd/tps65217.h> | 28 | #include <linux/mfd/tps65217.h> |
@@ -281,37 +282,130 @@ static const struct regulator_desc regulators[] = { | |||
281 | NULL), | 282 | NULL), |
282 | }; | 283 | }; |
283 | 284 | ||
285 | #ifdef CONFIG_OF | ||
286 | static struct of_regulator_match reg_matches[] = { | ||
287 | { .name = "dcdc1", .driver_data = (void *)TPS65217_DCDC_1 }, | ||
288 | { .name = "dcdc2", .driver_data = (void *)TPS65217_DCDC_2 }, | ||
289 | { .name = "dcdc3", .driver_data = (void *)TPS65217_DCDC_3 }, | ||
290 | { .name = "ldo1", .driver_data = (void *)TPS65217_LDO_1 }, | ||
291 | { .name = "ldo2", .driver_data = (void *)TPS65217_LDO_2 }, | ||
292 | { .name = "ldo3", .driver_data = (void *)TPS65217_LDO_3 }, | ||
293 | { .name = "ldo4", .driver_data = (void *)TPS65217_LDO_4 }, | ||
294 | }; | ||
295 | |||
296 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
297 | { | ||
298 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
299 | struct device_node *node = tps->dev->of_node; | ||
300 | struct tps65217_board *pdata; | ||
301 | struct device_node *regs; | ||
302 | int i, count; | ||
303 | |||
304 | regs = of_find_node_by_name(node, "regulators"); | ||
305 | if (!regs) | ||
306 | return NULL; | ||
307 | |||
308 | count = of_regulator_match(pdev->dev.parent, regs, | ||
309 | reg_matches, TPS65217_NUM_REGULATOR); | ||
310 | of_node_put(regs); | ||
311 | if ((count < 0) || (count > TPS65217_NUM_REGULATOR)) | ||
312 | return NULL; | ||
313 | |||
314 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
315 | if (!pdata) | ||
316 | return NULL; | ||
317 | |||
318 | for (i = 0; i < count; i++) { | ||
319 | if (!reg_matches[i].init_data || !reg_matches[i].of_node) | ||
320 | continue; | ||
321 | |||
322 | pdata->tps65217_init_data[i] = reg_matches[i].init_data; | ||
323 | pdata->of_node[i] = reg_matches[i].of_node; | ||
324 | } | ||
325 | |||
326 | return pdata; | ||
327 | } | ||
328 | #else | ||
329 | static struct tps65217_board *tps65217_parse_dt(struct platform_device *pdev) | ||
330 | { | ||
331 | return NULL; | ||
332 | } | ||
333 | #endif | ||
334 | |||
284 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) | 335 | static int __devinit tps65217_regulator_probe(struct platform_device *pdev) |
285 | { | 336 | { |
337 | struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); | ||
338 | struct tps65217_board *pdata = dev_get_platdata(tps->dev); | ||
339 | struct regulator_init_data *reg_data; | ||
286 | struct regulator_dev *rdev; | 340 | struct regulator_dev *rdev; |
287 | struct tps65217 *tps; | ||
288 | struct tps_info *info = &tps65217_pmic_regs[pdev->id]; | ||
289 | struct regulator_config config = { }; | 341 | struct regulator_config config = { }; |
342 | int i, ret; | ||
290 | 343 | ||
291 | /* Already set by core driver */ | 344 | if (tps->dev->of_node) |
292 | tps = dev_to_tps65217(pdev->dev.parent); | 345 | pdata = tps65217_parse_dt(pdev); |
293 | tps->info[pdev->id] = info; | ||
294 | 346 | ||
295 | config.dev = &pdev->dev; | 347 | if (!pdata) { |
296 | config.of_node = pdev->dev.of_node; | 348 | dev_err(&pdev->dev, "Platform data not found\n"); |
297 | config.init_data = pdev->dev.platform_data; | 349 | return -EINVAL; |
298 | config.driver_data = tps; | 350 | } |
299 | 351 | ||
300 | rdev = regulator_register(®ulators[pdev->id], &config); | 352 | if (tps65217_chip_id(tps) != TPS65217) { |
301 | if (IS_ERR(rdev)) | 353 | dev_err(&pdev->dev, "Invalid tps chip version\n"); |
302 | return PTR_ERR(rdev); | 354 | return -ENODEV; |
355 | } | ||
303 | 356 | ||
304 | platform_set_drvdata(pdev, rdev); | 357 | platform_set_drvdata(pdev, tps); |
305 | 358 | ||
359 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { | ||
360 | |||
361 | reg_data = pdata->tps65217_init_data[i]; | ||
362 | |||
363 | /* | ||
364 | * Regulator API handles empty constraints but not NULL | ||
365 | * constraints | ||
366 | */ | ||
367 | if (!reg_data) | ||
368 | continue; | ||
369 | |||
370 | /* Register the regulators */ | ||
371 | tps->info[i] = &tps65217_pmic_regs[i]; | ||
372 | |||
373 | config.dev = tps->dev; | ||
374 | config.init_data = reg_data; | ||
375 | config.driver_data = tps; | ||
376 | config.regmap = tps->regmap; | ||
377 | if (tps->dev->of_node) | ||
378 | config.of_node = pdata->of_node[i]; | ||
379 | |||
380 | rdev = regulator_register(®ulators[i], &config); | ||
381 | if (IS_ERR(rdev)) { | ||
382 | dev_err(tps->dev, "failed to register %s regulator\n", | ||
383 | pdev->name); | ||
384 | ret = PTR_ERR(rdev); | ||
385 | goto err_unregister_regulator; | ||
386 | } | ||
387 | |||
388 | /* Save regulator for cleanup */ | ||
389 | tps->rdev[i] = rdev; | ||
390 | } | ||
306 | return 0; | 391 | return 0; |
392 | |||
393 | err_unregister_regulator: | ||
394 | while (--i >= 0) | ||
395 | regulator_unregister(tps->rdev[i]); | ||
396 | |||
397 | return ret; | ||
307 | } | 398 | } |
308 | 399 | ||
309 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) | 400 | static int __devexit tps65217_regulator_remove(struct platform_device *pdev) |
310 | { | 401 | { |
311 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | 402 | struct tps65217 *tps = platform_get_drvdata(pdev); |
403 | unsigned int i; | ||
404 | |||
405 | for (i = 0; i < TPS65217_NUM_REGULATOR; i++) | ||
406 | regulator_unregister(tps->rdev[i]); | ||
312 | 407 | ||
313 | platform_set_drvdata(pdev, NULL); | 408 | platform_set_drvdata(pdev, NULL); |
314 | regulator_unregister(rdev); | ||
315 | 409 | ||
316 | return 0; | 410 | return 0; |
317 | } | 411 | } |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 19241fc30050..82125269b667 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -162,6 +162,9 @@ static struct regulator_ops tps6586x_regulator_ops = { | |||
162 | .disable = tps6586x_regulator_disable, | 162 | .disable = tps6586x_regulator_disable, |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static struct regulator_ops tps6586x_sys_regulator_ops = { | ||
166 | }; | ||
167 | |||
165 | static const unsigned int tps6586x_ldo0_voltages[] = { | 168 | static const unsigned int tps6586x_ldo0_voltages[] = { |
166 | 1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, | 169 | 1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, |
167 | }; | 170 | }; |
@@ -230,15 +233,28 @@ static const unsigned int tps6586x_dvm_voltages[] = { | |||
230 | TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ | 233 | TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ |
231 | } | 234 | } |
232 | 235 | ||
236 | #define TPS6586X_SYS_REGULATOR() \ | ||
237 | { \ | ||
238 | .desc = { \ | ||
239 | .supply_name = "sys", \ | ||
240 | .name = "REG-SYS", \ | ||
241 | .ops = &tps6586x_sys_regulator_ops, \ | ||
242 | .type = REGULATOR_VOLTAGE, \ | ||
243 | .id = TPS6586X_ID_SYS, \ | ||
244 | .owner = THIS_MODULE, \ | ||
245 | }, \ | ||
246 | } | ||
247 | |||
233 | static struct tps6586x_regulator tps6586x_regulator[] = { | 248 | static struct tps6586x_regulator tps6586x_regulator[] = { |
249 | TPS6586X_SYS_REGULATOR(), | ||
234 | TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0), | 250 | TPS6586X_LDO(LDO_0, "vinldo01", ldo0, SUPPLYV1, 5, 3, ENC, 0, END, 0), |
235 | TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), | 251 | TPS6586X_LDO(LDO_3, "vinldo23", ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), |
236 | TPS6586X_LDO(LDO_5, NULL, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), | 252 | TPS6586X_LDO(LDO_5, "REG-SYS", ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), |
237 | TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), | 253 | TPS6586X_LDO(LDO_6, "vinldo678", ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), |
238 | TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), | 254 | TPS6586X_LDO(LDO_7, "vinldo678", ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), |
239 | TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), | 255 | TPS6586X_LDO(LDO_8, "vinldo678", ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), |
240 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | 256 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), |
241 | TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), | 257 | TPS6586X_LDO(LDO_RTC, "REG-SYS", ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), |
242 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | 258 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), |
243 | TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), | 259 | TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), |
244 | 260 | ||
diff --git a/drivers/remoteproc/omap_remoteproc.c b/drivers/remoteproc/omap_remoteproc.c index a1f7ac1f8cf6..b54504ee61f1 100644 --- a/drivers/remoteproc/omap_remoteproc.c +++ b/drivers/remoteproc/omap_remoteproc.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/remoteproc.h> | 29 | #include <linux/remoteproc.h> |
30 | 30 | ||
31 | #include <plat/mailbox.h> | 31 | #include <plat/mailbox.h> |
32 | #include <plat/remoteproc.h> | 32 | #include <linux/platform_data/remoteproc-omap.h> |
33 | 33 | ||
34 | #include "omap_remoteproc.h" | 34 | #include "omap_remoteproc.h" |
35 | #include "remoteproc_internal.h" | 35 | #include "remoteproc_internal.h" |
diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c index 0075c8fd93d8..f771b2ee4b18 100644 --- a/drivers/rtc/rtc-pxa.c +++ b/drivers/rtc/rtc-pxa.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/of.h> | ||
31 | #include <linux/of_device.h> | ||
30 | 32 | ||
31 | #include <mach/hardware.h> | 33 | #include <mach/hardware.h> |
32 | 34 | ||
@@ -396,6 +398,14 @@ static int __exit pxa_rtc_remove(struct platform_device *pdev) | |||
396 | return 0; | 398 | return 0; |
397 | } | 399 | } |
398 | 400 | ||
401 | #ifdef CONFIG_OF | ||
402 | static struct of_device_id pxa_rtc_dt_ids[] = { | ||
403 | { .compatible = "marvell,pxa-rtc" }, | ||
404 | {} | ||
405 | }; | ||
406 | MODULE_DEVICE_TABLE(of, pxa_rtc_dt_ids); | ||
407 | #endif | ||
408 | |||
399 | #ifdef CONFIG_PM | 409 | #ifdef CONFIG_PM |
400 | static int pxa_rtc_suspend(struct device *dev) | 410 | static int pxa_rtc_suspend(struct device *dev) |
401 | { | 411 | { |
@@ -425,6 +435,7 @@ static struct platform_driver pxa_rtc_driver = { | |||
425 | .remove = __exit_p(pxa_rtc_remove), | 435 | .remove = __exit_p(pxa_rtc_remove), |
426 | .driver = { | 436 | .driver = { |
427 | .name = "pxa-rtc", | 437 | .name = "pxa-rtc", |
438 | .of_match_table = of_match_ptr(pxa_rtc_dt_ids), | ||
428 | #ifdef CONFIG_PM | 439 | #ifdef CONFIG_PM |
429 | .pm = &pxa_rtc_pm_ops, | 440 | .pm = &pxa_rtc_pm_ops, |
430 | #endif | 441 | #endif |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 6c0116d48c74..9ffb6d5f17aa 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -716,10 +716,17 @@ static int raw3215_probe (struct ccw_device *cdev) | |||
716 | static void raw3215_remove (struct ccw_device *cdev) | 716 | static void raw3215_remove (struct ccw_device *cdev) |
717 | { | 717 | { |
718 | struct raw3215_info *raw; | 718 | struct raw3215_info *raw; |
719 | unsigned int line; | ||
719 | 720 | ||
720 | ccw_device_set_offline(cdev); | 721 | ccw_device_set_offline(cdev); |
721 | raw = dev_get_drvdata(&cdev->dev); | 722 | raw = dev_get_drvdata(&cdev->dev); |
722 | if (raw) { | 723 | if (raw) { |
724 | spin_lock(&raw3215_device_lock); | ||
725 | for (line = 0; line < NR_3215; line++) | ||
726 | if (raw3215[line] == raw) | ||
727 | break; | ||
728 | raw3215[line] = NULL; | ||
729 | spin_unlock(&raw3215_device_lock); | ||
723 | dev_set_drvdata(&cdev->dev, NULL); | 730 | dev_set_drvdata(&cdev->dev, NULL); |
724 | raw3215_free_info(raw); | 731 | raw3215_free_info(raw); |
725 | } | 732 | } |
@@ -935,6 +942,19 @@ static int __init con3215_init(void) | |||
935 | console_initcall(con3215_init); | 942 | console_initcall(con3215_init); |
936 | #endif | 943 | #endif |
937 | 944 | ||
945 | static int tty3215_install(struct tty_driver *driver, struct tty_struct *tty) | ||
946 | { | ||
947 | struct raw3215_info *raw; | ||
948 | |||
949 | raw = raw3215[tty->index]; | ||
950 | if (raw == NULL) | ||
951 | return -ENODEV; | ||
952 | |||
953 | tty->driver_data = raw; | ||
954 | |||
955 | return tty_port_install(&raw->port, driver, tty); | ||
956 | } | ||
957 | |||
938 | /* | 958 | /* |
939 | * tty3215_open | 959 | * tty3215_open |
940 | * | 960 | * |
@@ -942,14 +962,9 @@ console_initcall(con3215_init); | |||
942 | */ | 962 | */ |
943 | static int tty3215_open(struct tty_struct *tty, struct file * filp) | 963 | static int tty3215_open(struct tty_struct *tty, struct file * filp) |
944 | { | 964 | { |
945 | struct raw3215_info *raw; | 965 | struct raw3215_info *raw = tty->driver_data; |
946 | int retval; | 966 | int retval; |
947 | 967 | ||
948 | raw = raw3215[tty->index]; | ||
949 | if (raw == NULL) | ||
950 | return -ENODEV; | ||
951 | |||
952 | tty->driver_data = raw; | ||
953 | tty_port_tty_set(&raw->port, tty); | 968 | tty_port_tty_set(&raw->port, tty); |
954 | 969 | ||
955 | tty->low_latency = 0; /* don't use bottom half for pushing chars */ | 970 | tty->low_latency = 0; /* don't use bottom half for pushing chars */ |
@@ -1110,6 +1125,7 @@ static void tty3215_start(struct tty_struct *tty) | |||
1110 | } | 1125 | } |
1111 | 1126 | ||
1112 | static const struct tty_operations tty3215_ops = { | 1127 | static const struct tty_operations tty3215_ops = { |
1128 | .install = tty3215_install, | ||
1113 | .open = tty3215_open, | 1129 | .open = tty3215_open, |
1114 | .close = tty3215_close, | 1130 | .close = tty3215_close, |
1115 | .write = tty3215_write, | 1131 | .write = tty3215_write, |
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 0792c85baafe..30ec09e3d037 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c | |||
@@ -567,6 +567,7 @@ sclp_tty_init(void) | |||
567 | driver->init_termios.c_lflag = ISIG | ECHO; | 567 | driver->init_termios.c_lflag = ISIG | ECHO; |
568 | driver->flags = TTY_DRIVER_REAL_RAW; | 568 | driver->flags = TTY_DRIVER_REAL_RAW; |
569 | tty_set_operations(driver, &sclp_ops); | 569 | tty_set_operations(driver, &sclp_ops); |
570 | tty_port_link_device(&sclp_port, driver, 0); | ||
570 | rc = tty_register_driver(driver); | 571 | rc = tty_register_driver(driver); |
571 | if (rc) { | 572 | if (rc) { |
572 | put_tty_driver(driver); | 573 | put_tty_driver(driver); |
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index edfc0fd73dc6..7e60f3d2f3f9 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c | |||
@@ -691,6 +691,7 @@ static int __init sclp_vt220_tty_init(void) | |||
691 | driver->init_termios = tty_std_termios; | 691 | driver->init_termios = tty_std_termios; |
692 | driver->flags = TTY_DRIVER_REAL_RAW; | 692 | driver->flags = TTY_DRIVER_REAL_RAW; |
693 | tty_set_operations(driver, &sclp_vt220_ops); | 693 | tty_set_operations(driver, &sclp_vt220_ops); |
694 | tty_port_link_device(&sclp_vt220_port, driver, 0); | ||
694 | 695 | ||
695 | rc = tty_register_driver(driver); | 696 | rc = tty_register_driver(driver); |
696 | if (rc) | 697 | if (rc) |
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 1928f3458d10..482ee028f842 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c | |||
@@ -842,17 +842,14 @@ static struct raw3270_fn tty3270_fn = { | |||
842 | }; | 842 | }; |
843 | 843 | ||
844 | /* | 844 | /* |
845 | * This routine is called whenever a 3270 tty is opened. | 845 | * This routine is called whenever a 3270 tty is opened first time. |
846 | */ | 846 | */ |
847 | static int | 847 | static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty) |
848 | tty3270_open(struct tty_struct *tty, struct file * filp) | ||
849 | { | 848 | { |
850 | struct raw3270_view *view; | 849 | struct raw3270_view *view; |
851 | struct tty3270 *tp; | 850 | struct tty3270 *tp; |
852 | int i, rc; | 851 | int i, rc; |
853 | 852 | ||
854 | if (tty->count > 1) | ||
855 | return 0; | ||
856 | /* Check if the tty3270 is already there. */ | 853 | /* Check if the tty3270 is already there. */ |
857 | view = raw3270_find_view(&tty3270_fn, | 854 | view = raw3270_find_view(&tty3270_fn, |
858 | tty->index + RAW3270_FIRSTMINOR); | 855 | tty->index + RAW3270_FIRSTMINOR); |
@@ -865,7 +862,7 @@ tty3270_open(struct tty_struct *tty, struct file * filp) | |||
865 | /* why to reassign? */ | 862 | /* why to reassign? */ |
866 | tty_port_tty_set(&tp->port, tty); | 863 | tty_port_tty_set(&tp->port, tty); |
867 | tp->inattr = TF_INPUT; | 864 | tp->inattr = TF_INPUT; |
868 | return 0; | 865 | return tty_port_install(&tp->port, driver, tty); |
869 | } | 866 | } |
870 | if (tty3270_max_index < tty->index + 1) | 867 | if (tty3270_max_index < tty->index + 1) |
871 | tty3270_max_index = tty->index + 1; | 868 | tty3270_max_index = tty->index + 1; |
@@ -895,7 +892,6 @@ tty3270_open(struct tty_struct *tty, struct file * filp) | |||
895 | 892 | ||
896 | tty_port_tty_set(&tp->port, tty); | 893 | tty_port_tty_set(&tp->port, tty); |
897 | tty->low_latency = 0; | 894 | tty->low_latency = 0; |
898 | tty->driver_data = tp; | ||
899 | tty->winsize.ws_row = tp->view.rows - 2; | 895 | tty->winsize.ws_row = tp->view.rows - 2; |
900 | tty->winsize.ws_col = tp->view.cols; | 896 | tty->winsize.ws_col = tp->view.cols; |
901 | 897 | ||
@@ -915,6 +911,15 @@ tty3270_open(struct tty_struct *tty, struct file * filp) | |||
915 | kbd_ascebc(tp->kbd, tp->view.ascebc); | 911 | kbd_ascebc(tp->kbd, tp->view.ascebc); |
916 | 912 | ||
917 | raw3270_activate_view(&tp->view); | 913 | raw3270_activate_view(&tp->view); |
914 | |||
915 | rc = tty_port_install(&tp->port, driver, tty); | ||
916 | if (rc) { | ||
917 | raw3270_put_view(&tp->view); | ||
918 | return rc; | ||
919 | } | ||
920 | |||
921 | tty->driver_data = tp; | ||
922 | |||
918 | return 0; | 923 | return 0; |
919 | } | 924 | } |
920 | 925 | ||
@@ -932,10 +937,17 @@ tty3270_close(struct tty_struct *tty, struct file * filp) | |||
932 | if (tp) { | 937 | if (tp) { |
933 | tty->driver_data = NULL; | 938 | tty->driver_data = NULL; |
934 | tty_port_tty_set(&tp->port, NULL); | 939 | tty_port_tty_set(&tp->port, NULL); |
935 | raw3270_put_view(&tp->view); | ||
936 | } | 940 | } |
937 | } | 941 | } |
938 | 942 | ||
943 | static void tty3270_cleanup(struct tty_struct *tty) | ||
944 | { | ||
945 | struct tty3270 *tp = tty->driver_data; | ||
946 | |||
947 | if (tp) | ||
948 | raw3270_put_view(&tp->view); | ||
949 | } | ||
950 | |||
939 | /* | 951 | /* |
940 | * We always have room. | 952 | * We always have room. |
941 | */ | 953 | */ |
@@ -1737,7 +1749,8 @@ static long tty3270_compat_ioctl(struct tty_struct *tty, | |||
1737 | #endif | 1749 | #endif |
1738 | 1750 | ||
1739 | static const struct tty_operations tty3270_ops = { | 1751 | static const struct tty_operations tty3270_ops = { |
1740 | .open = tty3270_open, | 1752 | .install = tty3270_install, |
1753 | .cleanup = tty3270_cleanup, | ||
1741 | .close = tty3270_close, | 1754 | .close = tty3270_close, |
1742 | .write = tty3270_write, | 1755 | .write = tty3270_write, |
1743 | .put_char = tty3270_put_char, | 1756 | .put_char = tty3270_put_char, |
@@ -1781,7 +1794,7 @@ static int __init tty3270_init(void) | |||
1781 | driver->type = TTY_DRIVER_TYPE_SYSTEM; | 1794 | driver->type = TTY_DRIVER_TYPE_SYSTEM; |
1782 | driver->subtype = SYSTEM_TYPE_TTY; | 1795 | driver->subtype = SYSTEM_TYPE_TTY; |
1783 | driver->init_termios = tty_std_termios; | 1796 | driver->init_termios = tty_std_termios; |
1784 | driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_DYNAMIC_DEV; | 1797 | driver->flags = TTY_DRIVER_RESET_TERMIOS; |
1785 | tty_set_operations(driver, &tty3270_ops); | 1798 | tty_set_operations(driver, &tty3270_ops); |
1786 | ret = tty_register_driver(driver); | 1799 | ret = tty_register_driver(driver); |
1787 | if (ret) { | 1800 | if (ret) { |
@@ -1800,6 +1813,7 @@ tty3270_exit(void) | |||
1800 | driver = tty3270_driver; | 1813 | driver = tty3270_driver; |
1801 | tty3270_driver = NULL; | 1814 | tty3270_driver = NULL; |
1802 | tty_unregister_driver(driver); | 1815 | tty_unregister_driver(driver); |
1816 | put_tty_driver(driver); | ||
1803 | tty3270_del_views(); | 1817 | tty3270_del_views(); |
1804 | } | 1818 | } |
1805 | 1819 | ||
diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index edfd12b48c28..968d08358d20 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c | |||
@@ -273,7 +273,7 @@ static void eesoxscsi_buffer_out(void *buf, int length, void __iomem *base) | |||
273 | { | 273 | { |
274 | const void __iomem *reg_fas = base + EESOX_FAS216_OFFSET; | 274 | const void __iomem *reg_fas = base + EESOX_FAS216_OFFSET; |
275 | const void __iomem *reg_dmastat = base + EESOX_DMASTAT; | 275 | const void __iomem *reg_dmastat = base + EESOX_DMASTAT; |
276 | const void __iomem *reg_dmadata = base + EESOX_DMADATA; | 276 | void __iomem *reg_dmadata = base + EESOX_DMADATA; |
277 | 277 | ||
278 | do { | 278 | do { |
279 | unsigned int status; | 279 | unsigned int status; |
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index dc27598785e5..ed38454228c6 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c | |||
@@ -4066,7 +4066,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
4066 | spin_lock_init(&instance->cmd_pool_lock); | 4066 | spin_lock_init(&instance->cmd_pool_lock); |
4067 | spin_lock_init(&instance->hba_lock); | 4067 | spin_lock_init(&instance->hba_lock); |
4068 | spin_lock_init(&instance->completion_lock); | 4068 | spin_lock_init(&instance->completion_lock); |
4069 | spin_lock_init(&poll_aen_lock); | ||
4070 | 4069 | ||
4071 | mutex_init(&instance->aen_mutex); | 4070 | mutex_init(&instance->aen_mutex); |
4072 | mutex_init(&instance->reset_mutex); | 4071 | mutex_init(&instance->reset_mutex); |
@@ -5392,6 +5391,8 @@ static int __init megasas_init(void) | |||
5392 | printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, | 5391 | printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION, |
5393 | MEGASAS_EXT_VERSION); | 5392 | MEGASAS_EXT_VERSION); |
5394 | 5393 | ||
5394 | spin_lock_init(&poll_aen_lock); | ||
5395 | |||
5395 | support_poll_for_event = 2; | 5396 | support_poll_for_event = 2; |
5396 | support_device_change = 1; | 5397 | support_device_change = 1; |
5397 | 5398 | ||
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 9d46fcbe7755..b25757d1e91b 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -2424,10 +2424,13 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2424 | } | 2424 | } |
2425 | 2425 | ||
2426 | /* command line tunables for max controller queue depth */ | 2426 | /* command line tunables for max controller queue depth */ |
2427 | if (max_queue_depth != -1) | 2427 | if (max_queue_depth != -1 && max_queue_depth != 0) { |
2428 | max_request_credit = (max_queue_depth < facts->RequestCredit) | 2428 | max_request_credit = min_t(u16, max_queue_depth + |
2429 | ? max_queue_depth : facts->RequestCredit; | 2429 | ioc->hi_priority_depth + ioc->internal_depth, |
2430 | else | 2430 | facts->RequestCredit); |
2431 | if (max_request_credit > MAX_HBA_QUEUE_DEPTH) | ||
2432 | max_request_credit = MAX_HBA_QUEUE_DEPTH; | ||
2433 | } else | ||
2431 | max_request_credit = min_t(u16, facts->RequestCredit, | 2434 | max_request_credit = min_t(u16, facts->RequestCredit, |
2432 | MAX_HBA_QUEUE_DEPTH); | 2435 | MAX_HBA_QUEUE_DEPTH); |
2433 | 2436 | ||
@@ -2502,7 +2505,7 @@ _base_allocate_memory_pools(struct MPT2SAS_ADAPTER *ioc, int sleep_flag) | |||
2502 | /* set the scsi host can_queue depth | 2505 | /* set the scsi host can_queue depth |
2503 | * with some internal commands that could be outstanding | 2506 | * with some internal commands that could be outstanding |
2504 | */ | 2507 | */ |
2505 | ioc->shost->can_queue = ioc->scsiio_depth - (2); | 2508 | ioc->shost->can_queue = ioc->scsiio_depth; |
2506 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " | 2509 | dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "scsi host: " |
2507 | "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); | 2510 | "can_queue depth (%d)\n", ioc->name, ioc->shost->can_queue)); |
2508 | 2511 | ||
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 4a6381c87253..de2337f255a7 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -42,6 +42,8 @@ | |||
42 | 42 | ||
43 | #include <trace/events/scsi.h> | 43 | #include <trace/events/scsi.h> |
44 | 44 | ||
45 | static void scsi_eh_done(struct scsi_cmnd *scmd); | ||
46 | |||
45 | #define SENSE_TIMEOUT (10*HZ) | 47 | #define SENSE_TIMEOUT (10*HZ) |
46 | 48 | ||
47 | /* | 49 | /* |
@@ -241,6 +243,14 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
241 | if (! scsi_command_normalize_sense(scmd, &sshdr)) | 243 | if (! scsi_command_normalize_sense(scmd, &sshdr)) |
242 | return FAILED; /* no valid sense data */ | 244 | return FAILED; /* no valid sense data */ |
243 | 245 | ||
246 | if (scmd->cmnd[0] == TEST_UNIT_READY && scmd->scsi_done != scsi_eh_done) | ||
247 | /* | ||
248 | * nasty: for mid-layer issued TURs, we need to return the | ||
249 | * actual sense data without any recovery attempt. For eh | ||
250 | * issued ones, we need to try to recover and interpret | ||
251 | */ | ||
252 | return SUCCESS; | ||
253 | |||
244 | if (scsi_sense_is_deferred(&sshdr)) | 254 | if (scsi_sense_is_deferred(&sshdr)) |
245 | return NEEDS_RETRY; | 255 | return NEEDS_RETRY; |
246 | 256 | ||
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ffd77739ae3e..faa790fba134 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -776,7 +776,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
776 | } | 776 | } |
777 | 777 | ||
778 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ | 778 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) { /* SG_IO ioctl from block level */ |
779 | req->errors = result; | ||
780 | if (result) { | 779 | if (result) { |
781 | if (sense_valid && req->sense) { | 780 | if (sense_valid && req->sense) { |
782 | /* | 781 | /* |
@@ -792,6 +791,10 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
792 | if (!sense_deferred) | 791 | if (!sense_deferred) |
793 | error = __scsi_error_from_host_byte(cmd, result); | 792 | error = __scsi_error_from_host_byte(cmd, result); |
794 | } | 793 | } |
794 | /* | ||
795 | * __scsi_error_from_host_byte may have reset the host_byte | ||
796 | */ | ||
797 | req->errors = cmd->result; | ||
795 | 798 | ||
796 | req->resid_len = scsi_get_resid(cmd); | 799 | req->resid_len = scsi_get_resid(cmd); |
797 | 800 | ||
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 56a93794c470..d947ffc20ceb 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -764,6 +764,16 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
764 | sdev->model = (char *) (sdev->inquiry + 16); | 764 | sdev->model = (char *) (sdev->inquiry + 16); |
765 | sdev->rev = (char *) (sdev->inquiry + 32); | 765 | sdev->rev = (char *) (sdev->inquiry + 32); |
766 | 766 | ||
767 | if (strncmp(sdev->vendor, "ATA ", 8) == 0) { | ||
768 | /* | ||
769 | * sata emulation layer device. This is a hack to work around | ||
770 | * the SATL power management specifications which state that | ||
771 | * when the SATL detects the device has gone into standby | ||
772 | * mode, it shall respond with NOT READY. | ||
773 | */ | ||
774 | sdev->allow_restart = 1; | ||
775 | } | ||
776 | |||
767 | if (*bflags & BLIST_ISROM) { | 777 | if (*bflags & BLIST_ISROM) { |
768 | sdev->type = TYPE_ROM; | 778 | sdev->type = TYPE_ROM; |
769 | sdev->removable = 1; | 779 | sdev->removable = 1; |
diff --git a/drivers/sh/pfc/gpio.c b/drivers/sh/pfc/gpio.c index 62bca98474a9..038fa071382a 100644 --- a/drivers/sh/pfc/gpio.c +++ b/drivers/sh/pfc/gpio.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/pinctrl/consumer.h> | 19 | #include <linux/pinctrl/consumer.h> |
20 | #include <linux/sh_pfc.h> | ||
20 | 21 | ||
21 | struct sh_pfc_chip { | 22 | struct sh_pfc_chip { |
22 | struct sh_pfc *pfc; | 23 | struct sh_pfc *pfc; |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 5f84b5563c2d..2d198a01a410 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -366,7 +366,7 @@ config SPI_STMP3XXX | |||
366 | 366 | ||
367 | config SPI_TEGRA | 367 | config SPI_TEGRA |
368 | tristate "Nvidia Tegra SPI controller" | 368 | tristate "Nvidia Tegra SPI controller" |
369 | depends on ARCH_TEGRA && (TEGRA_SYSTEM_DMA || TEGRA20_APB_DMA) | 369 | depends on ARCH_TEGRA && TEGRA20_APB_DMA |
370 | help | 370 | help |
371 | SPI driver for NVidia Tegra SoCs | 371 | SPI driver for NVidia Tegra SoCs |
372 | 372 | ||
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c index 9b2901feaf78..3afe2f4f5b8e 100644 --- a/drivers/spi/spi-davinci.c +++ b/drivers/spi/spi-davinci.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/spi/spi_bitbang.h> | 30 | #include <linux/spi/spi_bitbang.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | 32 | ||
33 | #include <mach/spi.h> | 33 | #include <linux/platform_data/spi-davinci.h> |
34 | #include <mach/edma.h> | 34 | #include <mach/edma.h> |
35 | 35 | ||
36 | #define SPI_NO_RESOURCE ((resource_size_t)-1) | 36 | #define SPI_NO_RESOURCE ((resource_size_t)-1) |
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index f97f1d248800..3a219599612a 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c | |||
@@ -31,8 +31,8 @@ | |||
31 | #include <linux/scatterlist.h> | 31 | #include <linux/scatterlist.h> |
32 | #include <linux/spi/spi.h> | 32 | #include <linux/spi/spi.h> |
33 | 33 | ||
34 | #include <mach/dma.h> | 34 | #include <linux/platform_data/dma-ep93xx.h> |
35 | #include <mach/ep93xx_spi.h> | 35 | #include <linux/platform_data/spi-ep93xx.h> |
36 | 36 | ||
37 | #define SSPCR0 0x0000 | 37 | #define SSPCR0 0x0000 |
38 | #define SSPCR0_MODE_SHIFT 6 | 38 | #define SSPCR0_MODE_SHIFT 6 |
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index e834ff8c0188..63e7fc9801cd 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <linux/of_gpio.h> | 39 | #include <linux/of_gpio.h> |
40 | #include <linux/pinctrl/consumer.h> | 40 | #include <linux/pinctrl/consumer.h> |
41 | 41 | ||
42 | #include <mach/spi.h> | 42 | #include <linux/platform_data/spi-imx.h> |
43 | 43 | ||
44 | #define DRIVER_NAME "spi_imx" | 44 | #define DRIVER_NAME "spi_imx" |
45 | 45 | ||
diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index dae8be229c5d..a6eca6ffdabe 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/spi/spi.h> | 26 | #include <linux/spi/spi.h> |
27 | #include <linux/spi/spi_bitbang.h> | 27 | #include <linux/spi/spi_bitbang.h> |
28 | 28 | ||
29 | #include <mach/nuc900_spi.h> | 29 | #include <linux/platform_data/spi-nuc900.h> |
30 | 30 | ||
31 | /* usi registers offset */ | 31 | /* usi registers offset */ |
32 | #define USI_CNT 0x00 | 32 | #define USI_CNT 0x00 |
diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c index 9b0d71696039..0a94d9dc9c31 100644 --- a/drivers/spi/spi-omap-uwire.c +++ b/drivers/spi/spi-omap-uwire.c | |||
@@ -52,8 +52,9 @@ | |||
52 | #include <asm/io.h> | 52 | #include <asm/io.h> |
53 | #include <asm/mach-types.h> | 53 | #include <asm/mach-types.h> |
54 | 54 | ||
55 | #include <plat/mux.h> | 55 | #include <mach/mux.h> |
56 | #include <plat/omap7xx.h> /* OMAP7XX_IO_CONF registers */ | 56 | |
57 | #include <mach/omap7xx.h> /* OMAP7XX_IO_CONF registers */ | ||
57 | 58 | ||
58 | 59 | ||
59 | /* FIXME address is now a platform device resource, | 60 | /* FIXME address is now a platform device resource, |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index b2fb141da375..b9b7ad02ef4c 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/spi/spi.h> | 42 | #include <linux/spi/spi.h> |
43 | 43 | ||
44 | #include <plat/clock.h> | 44 | #include <plat/clock.h> |
45 | #include <plat/mcspi.h> | 45 | #include <linux/platform_data/spi-omap2-mcspi.h> |
46 | 46 | ||
47 | #define OMAP2_MCSPI_MAX_FREQ 48000000 | 47 | #define OMAP2_MCSPI_MAX_FREQ 48000000 |
48 | #define SPI_AUTOSUSPEND_TIMEOUT 2000 | 48 | #define SPI_AUTOSUSPEND_TIMEOUT 2000 |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index d1c8441f638c..0e2a02228d5e 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/of_gpio.h> | 32 | #include <linux/of_gpio.h> |
33 | 33 | ||
34 | #include <mach/dma.h> | 34 | #include <mach/dma.h> |
35 | #include <plat/s3c64xx-spi.h> | 35 | #include <linux/platform_data/spi-s3c64xx.h> |
36 | 36 | ||
37 | #define MAX_SPI_PORTS 3 | 37 | #define MAX_SPI_PORTS 3 |
38 | 38 | ||
diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c index ef52c1c6f5c5..488d9b6e9cbe 100644 --- a/drivers/spi/spi-tegra.c +++ b/drivers/spi/spi-tegra.c | |||
@@ -164,23 +164,15 @@ struct spi_tegra_data { | |||
164 | * for the generic case. | 164 | * for the generic case. |
165 | */ | 165 | */ |
166 | int dma_req_len; | 166 | int dma_req_len; |
167 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
168 | struct tegra_dma_req rx_dma_req; | ||
169 | struct tegra_dma_channel *rx_dma; | ||
170 | #else | ||
171 | struct dma_chan *rx_dma; | 167 | struct dma_chan *rx_dma; |
172 | struct dma_slave_config sconfig; | 168 | struct dma_slave_config sconfig; |
173 | struct dma_async_tx_descriptor *rx_dma_desc; | 169 | struct dma_async_tx_descriptor *rx_dma_desc; |
174 | dma_cookie_t rx_cookie; | 170 | dma_cookie_t rx_cookie; |
175 | #endif | ||
176 | u32 *rx_bb; | 171 | u32 *rx_bb; |
177 | dma_addr_t rx_bb_phys; | 172 | dma_addr_t rx_bb_phys; |
178 | }; | 173 | }; |
179 | 174 | ||
180 | #if !defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
181 | static void tegra_spi_rx_dma_complete(void *args); | 175 | static void tegra_spi_rx_dma_complete(void *args); |
182 | #endif | ||
183 | |||
184 | static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, | 176 | static inline unsigned long spi_tegra_readl(struct spi_tegra_data *tspi, |
185 | unsigned long reg) | 177 | unsigned long reg) |
186 | { | 178 | { |
@@ -204,10 +196,6 @@ static void spi_tegra_go(struct spi_tegra_data *tspi) | |||
204 | val &= ~SLINK_DMA_BLOCK_SIZE(~0) & ~SLINK_DMA_EN; | 196 | val &= ~SLINK_DMA_BLOCK_SIZE(~0) & ~SLINK_DMA_EN; |
205 | val |= SLINK_DMA_BLOCK_SIZE(tspi->dma_req_len / 4 - 1); | 197 | val |= SLINK_DMA_BLOCK_SIZE(tspi->dma_req_len / 4 - 1); |
206 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); | 198 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); |
207 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
208 | tspi->rx_dma_req.size = tspi->dma_req_len; | ||
209 | tegra_dma_enqueue_req(tspi->rx_dma, &tspi->rx_dma_req); | ||
210 | #else | ||
211 | tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma, | 199 | tspi->rx_dma_desc = dmaengine_prep_slave_single(tspi->rx_dma, |
212 | tspi->rx_bb_phys, tspi->dma_req_len, | 200 | tspi->rx_bb_phys, tspi->dma_req_len, |
213 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); | 201 | DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT); |
@@ -219,7 +207,6 @@ static void spi_tegra_go(struct spi_tegra_data *tspi) | |||
219 | tspi->rx_dma_desc->callback_param = tspi; | 207 | tspi->rx_dma_desc->callback_param = tspi; |
220 | tspi->rx_cookie = dmaengine_submit(tspi->rx_dma_desc); | 208 | tspi->rx_cookie = dmaengine_submit(tspi->rx_dma_desc); |
221 | dma_async_issue_pending(tspi->rx_dma); | 209 | dma_async_issue_pending(tspi->rx_dma); |
222 | #endif | ||
223 | 210 | ||
224 | val |= SLINK_DMA_EN; | 211 | val |= SLINK_DMA_EN; |
225 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); | 212 | spi_tegra_writel(tspi, val, SLINK_DMA_CTL); |
@@ -405,19 +392,12 @@ static void handle_spi_rx_dma_complete(struct spi_tegra_data *tspi) | |||
405 | 392 | ||
406 | spin_unlock_irqrestore(&tspi->lock, flags); | 393 | spin_unlock_irqrestore(&tspi->lock, flags); |
407 | } | 394 | } |
408 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | 395 | |
409 | static void tegra_spi_rx_dma_complete(struct tegra_dma_req *req) | ||
410 | { | ||
411 | struct spi_tegra_data *tspi = req->dev; | ||
412 | handle_spi_rx_dma_complete(tspi); | ||
413 | } | ||
414 | #else | ||
415 | static void tegra_spi_rx_dma_complete(void *args) | 396 | static void tegra_spi_rx_dma_complete(void *args) |
416 | { | 397 | { |
417 | struct spi_tegra_data *tspi = args; | 398 | struct spi_tegra_data *tspi = args; |
418 | handle_spi_rx_dma_complete(tspi); | 399 | handle_spi_rx_dma_complete(tspi); |
419 | } | 400 | } |
420 | #endif | ||
421 | 401 | ||
422 | static int spi_tegra_setup(struct spi_device *spi) | 402 | static int spi_tegra_setup(struct spi_device *spi) |
423 | { | 403 | { |
@@ -509,9 +489,7 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
509 | struct spi_tegra_data *tspi; | 489 | struct spi_tegra_data *tspi; |
510 | struct resource *r; | 490 | struct resource *r; |
511 | int ret; | 491 | int ret; |
512 | #if !defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
513 | dma_cap_mask_t mask; | 492 | dma_cap_mask_t mask; |
514 | #endif | ||
515 | 493 | ||
516 | master = spi_alloc_master(&pdev->dev, sizeof *tspi); | 494 | master = spi_alloc_master(&pdev->dev, sizeof *tspi); |
517 | if (master == NULL) { | 495 | if (master == NULL) { |
@@ -563,14 +541,6 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
563 | 541 | ||
564 | INIT_LIST_HEAD(&tspi->queue); | 542 | INIT_LIST_HEAD(&tspi->queue); |
565 | 543 | ||
566 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
567 | tspi->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT); | ||
568 | if (!tspi->rx_dma) { | ||
569 | dev_err(&pdev->dev, "can not allocate rx dma channel\n"); | ||
570 | ret = -ENODEV; | ||
571 | goto err3; | ||
572 | } | ||
573 | #else | ||
574 | dma_cap_zero(mask); | 544 | dma_cap_zero(mask); |
575 | dma_cap_set(DMA_SLAVE, mask); | 545 | dma_cap_set(DMA_SLAVE, mask); |
576 | tspi->rx_dma = dma_request_channel(mask, NULL, NULL); | 546 | tspi->rx_dma = dma_request_channel(mask, NULL, NULL); |
@@ -580,8 +550,6 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
580 | goto err3; | 550 | goto err3; |
581 | } | 551 | } |
582 | 552 | ||
583 | #endif | ||
584 | |||
585 | tspi->rx_bb = dma_alloc_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | 553 | tspi->rx_bb = dma_alloc_coherent(&pdev->dev, sizeof(u32) * BB_LEN, |
586 | &tspi->rx_bb_phys, GFP_KERNEL); | 554 | &tspi->rx_bb_phys, GFP_KERNEL); |
587 | if (!tspi->rx_bb) { | 555 | if (!tspi->rx_bb) { |
@@ -590,17 +558,6 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
590 | goto err4; | 558 | goto err4; |
591 | } | 559 | } |
592 | 560 | ||
593 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
594 | tspi->rx_dma_req.complete = tegra_spi_rx_dma_complete; | ||
595 | tspi->rx_dma_req.to_memory = 1; | ||
596 | tspi->rx_dma_req.dest_addr = tspi->rx_bb_phys; | ||
597 | tspi->rx_dma_req.dest_bus_width = 32; | ||
598 | tspi->rx_dma_req.source_addr = tspi->phys + SLINK_RX_FIFO; | ||
599 | tspi->rx_dma_req.source_bus_width = 32; | ||
600 | tspi->rx_dma_req.source_wrap = 4; | ||
601 | tspi->rx_dma_req.req_sel = spi_tegra_req_sels[pdev->id]; | ||
602 | tspi->rx_dma_req.dev = tspi; | ||
603 | #else | ||
604 | /* Dmaengine Dma slave config */ | 561 | /* Dmaengine Dma slave config */ |
605 | tspi->sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; | 562 | tspi->sconfig.src_addr = tspi->phys + SLINK_RX_FIFO; |
606 | tspi->sconfig.dst_addr = tspi->phys + SLINK_RX_FIFO; | 563 | tspi->sconfig.dst_addr = tspi->phys + SLINK_RX_FIFO; |
@@ -616,7 +573,6 @@ static int __devinit spi_tegra_probe(struct platform_device *pdev) | |||
616 | ret); | 573 | ret); |
617 | goto err4; | 574 | goto err4; |
618 | } | 575 | } |
619 | #endif | ||
620 | 576 | ||
621 | master->dev.of_node = pdev->dev.of_node; | 577 | master->dev.of_node = pdev->dev.of_node; |
622 | ret = spi_register_master(master); | 578 | ret = spi_register_master(master); |
@@ -630,11 +586,7 @@ err5: | |||
630 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | 586 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, |
631 | tspi->rx_bb, tspi->rx_bb_phys); | 587 | tspi->rx_bb, tspi->rx_bb_phys); |
632 | err4: | 588 | err4: |
633 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
634 | tegra_dma_free_channel(tspi->rx_dma); | ||
635 | #else | ||
636 | dma_release_channel(tspi->rx_dma); | 589 | dma_release_channel(tspi->rx_dma); |
637 | #endif | ||
638 | err3: | 590 | err3: |
639 | clk_put(tspi->clk); | 591 | clk_put(tspi->clk); |
640 | err2: | 592 | err2: |
@@ -656,12 +608,7 @@ static int __devexit spi_tegra_remove(struct platform_device *pdev) | |||
656 | tspi = spi_master_get_devdata(master); | 608 | tspi = spi_master_get_devdata(master); |
657 | 609 | ||
658 | spi_unregister_master(master); | 610 | spi_unregister_master(master); |
659 | #if defined(CONFIG_TEGRA_SYSTEM_DMA) | ||
660 | tegra_dma_free_channel(tspi->rx_dma); | ||
661 | #else | ||
662 | dma_release_channel(tspi->rx_dma); | 611 | dma_release_channel(tspi->rx_dma); |
663 | #endif | ||
664 | |||
665 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, | 612 | dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN, |
666 | tspi->rx_bb, tspi->rx_bb_phys); | 613 | tspi->rx_bb, tspi->rx_bb_phys); |
667 | 614 | ||
diff --git a/drivers/staging/android/android_alarm.h b/drivers/staging/android/android_alarm.h index d0cafd637199..f2ffd963f1c3 100644 --- a/drivers/staging/android/android_alarm.h +++ b/drivers/staging/android/android_alarm.h | |||
@@ -51,10 +51,12 @@ enum android_alarm_return_flags { | |||
51 | #define ANDROID_ALARM_WAIT _IO('a', 1) | 51 | #define ANDROID_ALARM_WAIT _IO('a', 1) |
52 | 52 | ||
53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) | 53 | #define ALARM_IOW(c, type, size) _IOW('a', (c) | ((type) << 4), size) |
54 | #define ALARM_IOR(c, type, size) _IOR('a', (c) | ((type) << 4), size) | ||
55 | |||
54 | /* Set alarm */ | 56 | /* Set alarm */ |
55 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) | 57 | #define ANDROID_ALARM_SET(type) ALARM_IOW(2, type, struct timespec) |
56 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) | 58 | #define ANDROID_ALARM_SET_AND_WAIT(type) ALARM_IOW(3, type, struct timespec) |
57 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOW(4, type, struct timespec) | 59 | #define ANDROID_ALARM_GET_TIME(type) ALARM_IOR(4, type, struct timespec) |
58 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) | 60 | #define ANDROID_ALARM_SET_RTC _IOW('a', 5, struct timespec) |
59 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) | 61 | #define ANDROID_ALARM_BASE_CMD(cmd) (cmd & ~(_IOC(0, 0, 0xf0, 0))) |
60 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) | 62 | #define ANDROID_ALARM_IOCTL_TO_TYPE(cmd) (_IOC_NR(cmd) >> 4) |
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c index 6c81e377262c..cc8931fde839 100644 --- a/drivers/staging/comedi/drivers/amplc_dio200.c +++ b/drivers/staging/comedi/drivers/amplc_dio200.c | |||
@@ -1412,6 +1412,13 @@ static int __devinit dio200_attach_pci(struct comedi_device *dev, | |||
1412 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 1412 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
1413 | return -EINVAL; | 1413 | return -EINVAL; |
1414 | } | 1414 | } |
1415 | /* | ||
1416 | * Need to 'get' the PCI device to match the 'put' in dio200_detach(). | ||
1417 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
1418 | * support for manual attachment of PCI devices via dio200_attach() | ||
1419 | * has been removed. | ||
1420 | */ | ||
1421 | pci_dev_get(pci_dev); | ||
1415 | return dio200_pci_common_attach(dev, pci_dev); | 1422 | return dio200_pci_common_attach(dev, pci_dev); |
1416 | } | 1423 | } |
1417 | 1424 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c index aabba9886b7d..f50287903038 100644 --- a/drivers/staging/comedi/drivers/amplc_pc236.c +++ b/drivers/staging/comedi/drivers/amplc_pc236.c | |||
@@ -565,6 +565,13 @@ static int __devinit pc236_attach_pci(struct comedi_device *dev, | |||
565 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 565 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
566 | return -EINVAL; | 566 | return -EINVAL; |
567 | } | 567 | } |
568 | /* | ||
569 | * Need to 'get' the PCI device to match the 'put' in pc236_detach(). | ||
570 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
571 | * support for manual attachment of PCI devices via pc236_attach() | ||
572 | * has been removed. | ||
573 | */ | ||
574 | pci_dev_get(pci_dev); | ||
568 | return pc236_pci_common_attach(dev, pci_dev); | 575 | return pc236_pci_common_attach(dev, pci_dev); |
569 | } | 576 | } |
570 | 577 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c index 40ec1ffebba6..8191c4e28e0a 100644 --- a/drivers/staging/comedi/drivers/amplc_pc263.c +++ b/drivers/staging/comedi/drivers/amplc_pc263.c | |||
@@ -298,6 +298,13 @@ static int __devinit pc263_attach_pci(struct comedi_device *dev, | |||
298 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 298 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
299 | return -EINVAL; | 299 | return -EINVAL; |
300 | } | 300 | } |
301 | /* | ||
302 | * Need to 'get' the PCI device to match the 'put' in pc263_detach(). | ||
303 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
304 | * support for manual attachment of PCI devices via pc263_attach() | ||
305 | * has been removed. | ||
306 | */ | ||
307 | pci_dev_get(pci_dev); | ||
301 | return pc263_pci_common_attach(dev, pci_dev); | 308 | return pc263_pci_common_attach(dev, pci_dev); |
302 | } | 309 | } |
303 | 310 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c index 4e17f13e57f6..8bf109e7bb05 100644 --- a/drivers/staging/comedi/drivers/amplc_pci224.c +++ b/drivers/staging/comedi/drivers/amplc_pci224.c | |||
@@ -1503,6 +1503,13 @@ pci224_attach_pci(struct comedi_device *dev, struct pci_dev *pci_dev) | |||
1503 | DRIVER_NAME ": BUG! cannot determine board type!\n"); | 1503 | DRIVER_NAME ": BUG! cannot determine board type!\n"); |
1504 | return -EINVAL; | 1504 | return -EINVAL; |
1505 | } | 1505 | } |
1506 | /* | ||
1507 | * Need to 'get' the PCI device to match the 'put' in pci224_detach(). | ||
1508 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
1509 | * support for manual attachment of PCI devices via pci224_attach() | ||
1510 | * has been removed. | ||
1511 | */ | ||
1512 | pci_dev_get(pci_dev); | ||
1506 | return pci224_attach_common(dev, pci_dev, NULL); | 1513 | return pci224_attach_common(dev, pci_dev, NULL); |
1507 | } | 1514 | } |
1508 | 1515 | ||
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 1b67d0c61fa7..66e74bd12267 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c | |||
@@ -2925,6 +2925,13 @@ static int __devinit pci230_attach_pci(struct comedi_device *dev, | |||
2925 | "amplc_pci230: BUG! cannot determine board type!\n"); | 2925 | "amplc_pci230: BUG! cannot determine board type!\n"); |
2926 | return -EINVAL; | 2926 | return -EINVAL; |
2927 | } | 2927 | } |
2928 | /* | ||
2929 | * Need to 'get' the PCI device to match the 'put' in pci230_detach(). | ||
2930 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
2931 | * support for manual attachment of PCI devices via pci230_attach() | ||
2932 | * has been removed. | ||
2933 | */ | ||
2934 | pci_dev_get(pci_dev); | ||
2928 | return pci230_attach_common(dev, pci_dev); | 2935 | return pci230_attach_common(dev, pci_dev); |
2929 | } | 2936 | } |
2930 | 2937 | ||
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c index 874e02e47668..67a914a10b55 100644 --- a/drivers/staging/comedi/drivers/das08.c +++ b/drivers/staging/comedi/drivers/das08.c | |||
@@ -378,7 +378,7 @@ das08jr_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, | |||
378 | int chan; | 378 | int chan; |
379 | 379 | ||
380 | lsb = data[0] & 0xff; | 380 | lsb = data[0] & 0xff; |
381 | msb = (data[0] >> 8) & 0xf; | 381 | msb = (data[0] >> 8) & 0xff; |
382 | 382 | ||
383 | chan = CR_CHAN(insn->chanspec); | 383 | chan = CR_CHAN(insn->chanspec); |
384 | 384 | ||
@@ -623,7 +623,7 @@ static const struct das08_board_struct das08_boards[] = { | |||
623 | .ai = das08_ai_rinsn, | 623 | .ai = das08_ai_rinsn, |
624 | .ai_nbits = 16, | 624 | .ai_nbits = 16, |
625 | .ai_pg = das08_pg_none, | 625 | .ai_pg = das08_pg_none, |
626 | .ai_encoding = das08_encode12, | 626 | .ai_encoding = das08_encode16, |
627 | .ao = das08jr_ao_winsn, | 627 | .ao = das08jr_ao_winsn, |
628 | .ao_nbits = 16, | 628 | .ao_nbits = 16, |
629 | .di = das08jr_di_rbits, | 629 | .di = das08jr_di_rbits, |
@@ -922,6 +922,13 @@ das08_attach_pci(struct comedi_device *dev, struct pci_dev *pdev) | |||
922 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); | 922 | dev_err(dev->class_dev, "BUG! cannot determine board type!\n"); |
923 | return -EINVAL; | 923 | return -EINVAL; |
924 | } | 924 | } |
925 | /* | ||
926 | * Need to 'get' the PCI device to match the 'put' in das08_detach(). | ||
927 | * TODO: Remove the pci_dev_get() and matching pci_dev_put() once | ||
928 | * support for manual attachment of PCI devices via das08_attach() | ||
929 | * has been removed. | ||
930 | */ | ||
931 | pci_dev_get(pdev); | ||
925 | return das08_pci_attach_common(dev, pdev); | 932 | return das08_pci_attach_common(dev, pdev); |
926 | } | 933 | } |
927 | 934 | ||
diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 18d108fd967a..f3da59063ed2 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c | |||
@@ -121,8 +121,10 @@ static int lis3l02dq_get_buffer_element(struct iio_dev *indio_dev, | |||
121 | if (rx_array == NULL) | 121 | if (rx_array == NULL) |
122 | return -ENOMEM; | 122 | return -ENOMEM; |
123 | ret = lis3l02dq_read_all(indio_dev, rx_array); | 123 | ret = lis3l02dq_read_all(indio_dev, rx_array); |
124 | if (ret < 0) | 124 | if (ret < 0) { |
125 | kfree(rx_array); | ||
125 | return ret; | 126 | return ret; |
127 | } | ||
126 | for (i = 0; i < scan_count; i++) | 128 | for (i = 0; i < scan_count; i++) |
127 | data[i] = combine_8_to_16(rx_array[i*4+1], | 129 | data[i] = combine_8_to_16(rx_array[i*4+1], |
128 | rx_array[i*4+3]); | 130 | rx_array[i*4+3]); |
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 095837285f4f..19a064d649e3 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c | |||
@@ -647,6 +647,8 @@ static ssize_t ad7192_write_frequency(struct device *dev, | |||
647 | ret = strict_strtoul(buf, 10, &lval); | 647 | ret = strict_strtoul(buf, 10, &lval); |
648 | if (ret) | 648 | if (ret) |
649 | return ret; | 649 | return ret; |
650 | if (lval == 0) | ||
651 | return -EINVAL; | ||
650 | 652 | ||
651 | mutex_lock(&indio_dev->mlock); | 653 | mutex_lock(&indio_dev->mlock); |
652 | if (iio_buffer_enabled(indio_dev)) { | 654 | if (iio_buffer_enabled(indio_dev)) { |
diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 93aa431287ac..eb8e9d69efd3 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c | |||
@@ -195,6 +195,8 @@ static ssize_t adis16260_write_frequency(struct device *dev, | |||
195 | ret = strict_strtol(buf, 10, &val); | 195 | ret = strict_strtol(buf, 10, &val); |
196 | if (ret) | 196 | if (ret) |
197 | return ret; | 197 | return ret; |
198 | if (val == 0) | ||
199 | return -EINVAL; | ||
198 | 200 | ||
199 | mutex_lock(&indio_dev->mlock); | 201 | mutex_lock(&indio_dev->mlock); |
200 | if (spi_get_device_id(st->us)) { | 202 | if (spi_get_device_id(st->us)) { |
diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index 1f4c17779b5a..a618327e06ed 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c | |||
@@ -234,6 +234,8 @@ static ssize_t adis16400_write_frequency(struct device *dev, | |||
234 | ret = strict_strtol(buf, 10, &val); | 234 | ret = strict_strtol(buf, 10, &val); |
235 | if (ret) | 235 | if (ret) |
236 | return ret; | 236 | return ret; |
237 | if (val == 0) | ||
238 | return -EINVAL; | ||
237 | 239 | ||
238 | mutex_lock(&indio_dev->mlock); | 240 | mutex_lock(&indio_dev->mlock); |
239 | 241 | ||
diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index f04ece7fbc2f..3ccff189f258 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c | |||
@@ -425,6 +425,8 @@ static ssize_t ade7753_write_frequency(struct device *dev, | |||
425 | ret = strict_strtol(buf, 10, &val); | 425 | ret = strict_strtol(buf, 10, &val); |
426 | if (ret) | 426 | if (ret) |
427 | return ret; | 427 | return ret; |
428 | if (val == 0) | ||
429 | return -EINVAL; | ||
428 | 430 | ||
429 | mutex_lock(&indio_dev->mlock); | 431 | mutex_lock(&indio_dev->mlock); |
430 | 432 | ||
diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index 6cee28a5e877..abb1e9c8d094 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c | |||
@@ -445,6 +445,8 @@ static ssize_t ade7754_write_frequency(struct device *dev, | |||
445 | ret = strict_strtol(buf, 10, &val); | 445 | ret = strict_strtol(buf, 10, &val); |
446 | if (ret) | 446 | if (ret) |
447 | return ret; | 447 | return ret; |
448 | if (val == 0) | ||
449 | return -EINVAL; | ||
448 | 450 | ||
449 | mutex_lock(&indio_dev->mlock); | 451 | mutex_lock(&indio_dev->mlock); |
450 | 452 | ||
diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index b3f7e0fa9612..eb0a2a98f388 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c | |||
@@ -385,6 +385,8 @@ static ssize_t ade7759_write_frequency(struct device *dev, | |||
385 | ret = strict_strtol(buf, 10, &val); | 385 | ret = strict_strtol(buf, 10, &val); |
386 | if (ret) | 386 | if (ret) |
387 | return ret; | 387 | return ret; |
388 | if (val == 0) | ||
389 | return -EINVAL; | ||
388 | 390 | ||
389 | mutex_lock(&indio_dev->mlock); | 391 | mutex_lock(&indio_dev->mlock); |
390 | 392 | ||
diff --git a/drivers/staging/ipack/devices/ipoctal.c b/drivers/staging/ipack/devices/ipoctal.c index fd0e30132ca2..a68d981c259f 100644 --- a/drivers/staging/ipack/devices/ipoctal.c +++ b/drivers/staging/ipack/devices/ipoctal.c | |||
@@ -502,7 +502,7 @@ static int ipoctal_inst_slot(struct ipoctal *ipoctal, unsigned int bus_nr, | |||
502 | ipoctal->pointer_read[i] = 0; | 502 | ipoctal->pointer_read[i] = 0; |
503 | ipoctal->pointer_write[i] = 0; | 503 | ipoctal->pointer_write[i] = 0; |
504 | ipoctal->nb_bytes[i] = 0; | 504 | ipoctal->nb_bytes[i] = 0; |
505 | tty_register_device(tty, i, NULL); | 505 | tty_port_register_device(&ipoctal->tty_port[i], tty, i, NULL); |
506 | 506 | ||
507 | /* | 507 | /* |
508 | * Enable again the RX. TX will be enabled when | 508 | * Enable again the RX. TX will be enabled when |
@@ -617,7 +617,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
617 | struct ipoctal *ipoctal = tty->driver_data; | 617 | struct ipoctal *ipoctal = tty->driver_data; |
618 | speed_t baud; | 618 | speed_t baud; |
619 | 619 | ||
620 | cflag = tty->termios->c_cflag; | 620 | cflag = tty->termios.c_cflag; |
621 | 621 | ||
622 | /* Disable and reset everything before change the setup */ | 622 | /* Disable and reset everything before change the setup */ |
623 | ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, | 623 | ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, |
@@ -643,7 +643,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
643 | default: | 643 | default: |
644 | mr1 |= MR1_CHRL_8_BITS; | 644 | mr1 |= MR1_CHRL_8_BITS; |
645 | /* By default, select CS8 */ | 645 | /* By default, select CS8 */ |
646 | tty->termios->c_cflag = (cflag & ~CSIZE) | CS8; | 646 | tty->termios.c_cflag = (cflag & ~CSIZE) | CS8; |
647 | break; | 647 | break; |
648 | } | 648 | } |
649 | 649 | ||
@@ -657,7 +657,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
657 | mr1 |= MR1_PARITY_OFF; | 657 | mr1 |= MR1_PARITY_OFF; |
658 | 658 | ||
659 | /* Mark or space parity is not supported */ | 659 | /* Mark or space parity is not supported */ |
660 | tty->termios->c_cflag &= ~CMSPAR; | 660 | tty->termios.c_cflag &= ~CMSPAR; |
661 | 661 | ||
662 | /* Set stop bits */ | 662 | /* Set stop bits */ |
663 | if (cflag & CSTOPB) | 663 | if (cflag & CSTOPB) |
@@ -690,10 +690,10 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
690 | } | 690 | } |
691 | 691 | ||
692 | baud = tty_get_baud_rate(tty); | 692 | baud = tty_get_baud_rate(tty); |
693 | tty_termios_encode_baud_rate(tty->termios, baud, baud); | 693 | tty_termios_encode_baud_rate(&tty->termios, baud, baud); |
694 | 694 | ||
695 | /* Set baud rate */ | 695 | /* Set baud rate */ |
696 | switch (tty->termios->c_ospeed) { | 696 | switch (baud) { |
697 | case 75: | 697 | case 75: |
698 | csr |= TX_CLK_75 | RX_CLK_75; | 698 | csr |= TX_CLK_75 | RX_CLK_75; |
699 | break; | 699 | break; |
@@ -734,7 +734,7 @@ static void ipoctal_set_termios(struct tty_struct *tty, | |||
734 | default: | 734 | default: |
735 | csr |= TX_CLK_38400 | RX_CLK_38400; | 735 | csr |= TX_CLK_38400 | RX_CLK_38400; |
736 | /* In case of default, we establish 38400 bps */ | 736 | /* In case of default, we establish 38400 bps */ |
737 | tty_termios_encode_baud_rate(tty->termios, 38400, 38400); | 737 | tty_termios_encode_baud_rate(&tty->termios, 38400, 38400); |
738 | break; | 738 | break; |
739 | } | 739 | } |
740 | 740 | ||
diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 695ea35f75b0..d0a7e408efe9 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c | |||
@@ -837,7 +837,7 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) | |||
837 | } | 837 | } |
838 | 838 | ||
839 | ret = mfd_add_devices(nvec->dev, -1, nvec_devices, | 839 | ret = mfd_add_devices(nvec->dev, -1, nvec_devices, |
840 | ARRAY_SIZE(nvec_devices), base, 0); | 840 | ARRAY_SIZE(nvec_devices), base, 0, NULL); |
841 | if (ret) | 841 | if (ret) |
842 | dev_err(nvec->dev, "error adding subdevices\n"); | 842 | dev_err(nvec->dev, "error adding subdevices\n"); |
843 | 843 | ||
diff --git a/drivers/staging/omapdrm/omap_connector.c b/drivers/staging/omapdrm/omap_connector.c index 5e2856c0e0bb..55e9c8655850 100644 --- a/drivers/staging/omapdrm/omap_connector.c +++ b/drivers/staging/omapdrm/omap_connector.c | |||
@@ -48,13 +48,20 @@ static inline void copy_timings_omap_to_drm(struct drm_display_mode *mode, | |||
48 | mode->vsync_end = mode->vsync_start + timings->vsw; | 48 | mode->vsync_end = mode->vsync_start + timings->vsw; |
49 | mode->vtotal = mode->vsync_end + timings->vbp; | 49 | mode->vtotal = mode->vsync_end + timings->vbp; |
50 | 50 | ||
51 | /* note: whether or not it is interlaced, +/- h/vsync, etc, | 51 | mode->flags = 0; |
52 | * which should be set in the mode flags, is not exposed in | 52 | |
53 | * the omap_video_timings struct.. but hdmi driver tracks | 53 | if (timings->interlace) |
54 | * those separately so all we have to have to set the mode | 54 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
55 | * is the way to recover these timings values, and the | 55 | |
56 | * omap_dss_driver would do the rest. | 56 | if (timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH) |
57 | */ | 57 | mode->flags |= DRM_MODE_FLAG_PHSYNC; |
58 | else | ||
59 | mode->flags |= DRM_MODE_FLAG_NHSYNC; | ||
60 | |||
61 | if (timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH) | ||
62 | mode->flags |= DRM_MODE_FLAG_PVSYNC; | ||
63 | else | ||
64 | mode->flags |= DRM_MODE_FLAG_NVSYNC; | ||
58 | } | 65 | } |
59 | 66 | ||
60 | static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, | 67 | static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, |
@@ -71,6 +78,22 @@ static inline void copy_timings_drm_to_omap(struct omap_video_timings *timings, | |||
71 | timings->vfp = mode->vsync_start - mode->vdisplay; | 78 | timings->vfp = mode->vsync_start - mode->vdisplay; |
72 | timings->vsw = mode->vsync_end - mode->vsync_start; | 79 | timings->vsw = mode->vsync_end - mode->vsync_start; |
73 | timings->vbp = mode->vtotal - mode->vsync_end; | 80 | timings->vbp = mode->vtotal - mode->vsync_end; |
81 | |||
82 | timings->interlace = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); | ||
83 | |||
84 | if (mode->flags & DRM_MODE_FLAG_PHSYNC) | ||
85 | timings->hsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
86 | else | ||
87 | timings->hsync_level = OMAPDSS_SIG_ACTIVE_LOW; | ||
88 | |||
89 | if (mode->flags & DRM_MODE_FLAG_PVSYNC) | ||
90 | timings->vsync_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
91 | else | ||
92 | timings->vsync_level = OMAPDSS_SIG_ACTIVE_LOW; | ||
93 | |||
94 | timings->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; | ||
95 | timings->de_level = OMAPDSS_SIG_ACTIVE_HIGH; | ||
96 | timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; | ||
74 | } | 97 | } |
75 | 98 | ||
76 | static void omap_connector_dpms(struct drm_connector *connector, int mode) | 99 | static void omap_connector_dpms(struct drm_connector *connector, int mode) |
@@ -187,7 +210,7 @@ static int omap_connector_get_modes(struct drm_connector *connector) | |||
187 | } | 210 | } |
188 | } else { | 211 | } else { |
189 | struct drm_display_mode *mode = drm_mode_create(dev); | 212 | struct drm_display_mode *mode = drm_mode_create(dev); |
190 | struct omap_video_timings timings; | 213 | struct omap_video_timings timings = {0}; |
191 | 214 | ||
192 | dssdrv->get_timings(dssdev, &timings); | 215 | dssdrv->get_timings(dssdev, &timings); |
193 | 216 | ||
@@ -291,7 +314,7 @@ void omap_connector_mode_set(struct drm_connector *connector, | |||
291 | struct omap_connector *omap_connector = to_omap_connector(connector); | 314 | struct omap_connector *omap_connector = to_omap_connector(connector); |
292 | struct omap_dss_device *dssdev = omap_connector->dssdev; | 315 | struct omap_dss_device *dssdev = omap_connector->dssdev; |
293 | struct omap_dss_driver *dssdrv = dssdev->driver; | 316 | struct omap_dss_driver *dssdrv = dssdev->driver; |
294 | struct omap_video_timings timings; | 317 | struct omap_video_timings timings = {0}; |
295 | 318 | ||
296 | copy_timings_drm_to_omap(&timings, mode); | 319 | copy_timings_drm_to_omap(&timings, mode); |
297 | 320 | ||
diff --git a/drivers/staging/ozwpan/ozcdev.c b/drivers/staging/ozwpan/ozcdev.c index d98321945802..758ce0a8d82e 100644 --- a/drivers/staging/ozwpan/ozcdev.c +++ b/drivers/staging/ozwpan/ozcdev.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/cdev.h> | 8 | #include <linux/cdev.h> |
9 | #include <linux/uaccess.h> | 9 | #include <linux/uaccess.h> |
10 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
11 | #include <linux/etherdevice.h> | ||
11 | #include <linux/poll.h> | 12 | #include <linux/poll.h> |
12 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
13 | #include "ozconfig.h" | 14 | #include "ozconfig.h" |
@@ -213,7 +214,7 @@ static int oz_set_active_pd(u8 *addr) | |||
213 | if (old_pd) | 214 | if (old_pd) |
214 | oz_pd_put(old_pd); | 215 | oz_pd_put(old_pd); |
215 | } else { | 216 | } else { |
216 | if (!memcmp(addr, "\0\0\0\0\0\0", sizeof(addr))) { | 217 | if (is_zero_ether_addr(addr)) { |
217 | spin_lock_bh(&g_cdev.lock); | 218 | spin_lock_bh(&g_cdev.lock); |
218 | pd = g_cdev.active_pd; | 219 | pd = g_cdev.active_pd; |
219 | g_cdev.active_pd = 0; | 220 | g_cdev.active_pd = 0; |
diff --git a/drivers/staging/rtl8712/recv_linux.c b/drivers/staging/rtl8712/recv_linux.c index 0e26d5f6cf2d..495ee1205e02 100644 --- a/drivers/staging/rtl8712/recv_linux.c +++ b/drivers/staging/rtl8712/recv_linux.c | |||
@@ -117,13 +117,8 @@ void r8712_recv_indicatepkt(struct _adapter *padapter, | |||
117 | if (skb == NULL) | 117 | if (skb == NULL) |
118 | goto _recv_indicatepkt_drop; | 118 | goto _recv_indicatepkt_drop; |
119 | skb->data = precv_frame->u.hdr.rx_data; | 119 | skb->data = precv_frame->u.hdr.rx_data; |
120 | #ifdef NET_SKBUFF_DATA_USES_OFFSET | ||
121 | skb->tail = (sk_buff_data_t)(precv_frame->u.hdr.rx_tail - | ||
122 | precv_frame->u.hdr.rx_head); | ||
123 | #else | ||
124 | skb->tail = (sk_buff_data_t)precv_frame->u.hdr.rx_tail; | ||
125 | #endif | ||
126 | skb->len = precv_frame->u.hdr.len; | 120 | skb->len = precv_frame->u.hdr.len; |
121 | skb_set_tail_pointer(skb, skb->len); | ||
127 | if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1)) | 122 | if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1)) |
128 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 123 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
129 | else | 124 | else |
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 8a362f7af379..c90de969be8f 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c | |||
@@ -315,10 +315,8 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
315 | } | 315 | } |
316 | 316 | ||
317 | tty = tty_port_tty_get(&port->port); | 317 | tty = tty_port_tty_get(&port->port); |
318 | if (!tty) { | 318 | if (!tty) |
319 | dbg("%s - bad tty pointer - exiting", __func__); | ||
320 | return; | 319 | return; |
321 | } | ||
322 | 320 | ||
323 | data = urb->transfer_buffer; | 321 | data = urb->transfer_buffer; |
324 | 322 | ||
@@ -364,7 +362,7 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
364 | goto exit; | 362 | goto exit; |
365 | } | 363 | } |
366 | 364 | ||
367 | if (tty && RxCount) { | 365 | if (RxCount) { |
368 | flag_data = 0; | 366 | flag_data = 0; |
369 | for (i = 0; i < RxCount; ++i) { | 367 | for (i = 0; i < RxCount; ++i) { |
370 | /* Look ahead code here */ | 368 | /* Look ahead code here */ |
@@ -428,7 +426,7 @@ static void qt_read_bulk_callback(struct urb *urb) | |||
428 | dbg("%s - failed resubmitting read urb, error %d", | 426 | dbg("%s - failed resubmitting read urb, error %d", |
429 | __func__, result); | 427 | __func__, result); |
430 | else { | 428 | else { |
431 | if (tty && RxCount) { | 429 | if (RxCount) { |
432 | tty_flip_buffer_push(tty); | 430 | tty_flip_buffer_push(tty); |
433 | tty_schedule_flip(tty); | 431 | tty_schedule_flip(tty); |
434 | } | 432 | } |
@@ -897,8 +895,6 @@ static int qt_open(struct tty_struct *tty, | |||
897 | * Put this here to make it responsive to stty and defaults set by | 895 | * Put this here to make it responsive to stty and defaults set by |
898 | * the tty layer | 896 | * the tty layer |
899 | */ | 897 | */ |
900 | /* FIXME: is this needed? */ | ||
901 | /* qt_set_termios(tty, port, NULL); */ | ||
902 | 898 | ||
903 | /* Check to see if we've set up our endpoint info yet */ | 899 | /* Check to see if we've set up our endpoint info yet */ |
904 | if (port0->open_ports == 1) { | 900 | if (port0->open_ports == 1) { |
@@ -1195,7 +1191,7 @@ static void qt_set_termios(struct tty_struct *tty, | |||
1195 | struct usb_serial_port *port, | 1191 | struct usb_serial_port *port, |
1196 | struct ktermios *old_termios) | 1192 | struct ktermios *old_termios) |
1197 | { | 1193 | { |
1198 | struct ktermios *termios = tty->termios; | 1194 | struct ktermios *termios = &tty->termios; |
1199 | unsigned char new_LCR = 0; | 1195 | unsigned char new_LCR = 0; |
1200 | unsigned int cflag = termios->c_cflag; | 1196 | unsigned int cflag = termios->c_cflag; |
1201 | unsigned int index; | 1197 | unsigned int index; |
@@ -1204,7 +1200,7 @@ static void qt_set_termios(struct tty_struct *tty, | |||
1204 | 1200 | ||
1205 | index = tty->index - port->serial->minor; | 1201 | index = tty->index - port->serial->minor; |
1206 | 1202 | ||
1207 | switch (cflag) { | 1203 | switch (cflag & CSIZE) { |
1208 | case CS5: | 1204 | case CS5: |
1209 | new_LCR |= SERIAL_5_DATA; | 1205 | new_LCR |= SERIAL_5_DATA; |
1210 | break; | 1206 | break; |
@@ -1215,6 +1211,8 @@ static void qt_set_termios(struct tty_struct *tty, | |||
1215 | new_LCR |= SERIAL_7_DATA; | 1211 | new_LCR |= SERIAL_7_DATA; |
1216 | break; | 1212 | break; |
1217 | default: | 1213 | default: |
1214 | termios->c_cflag &= ~CSIZE; | ||
1215 | termios->c_cflag |= CS8; | ||
1218 | case CS8: | 1216 | case CS8: |
1219 | new_LCR |= SERIAL_8_DATA; | 1217 | new_LCR |= SERIAL_8_DATA; |
1220 | break; | 1218 | break; |
@@ -1301,7 +1299,7 @@ static void qt_set_termios(struct tty_struct *tty, | |||
1301 | dbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n"); | 1299 | dbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n"); |
1302 | 1300 | ||
1303 | } | 1301 | } |
1304 | tty->termios->c_cflag &= ~CMSPAR; | 1302 | termios->c_cflag &= ~CMSPAR; |
1305 | /* FIXME: Error cases should be returning the actual bits changed only */ | 1303 | /* FIXME: Error cases should be returning the actual bits changed only */ |
1306 | } | 1304 | } |
1307 | 1305 | ||
diff --git a/drivers/staging/speakup/serialio.h b/drivers/staging/speakup/serialio.h index 614271f9b99f..55d68b5ad165 100644 --- a/drivers/staging/speakup/serialio.h +++ b/drivers/staging/speakup/serialio.h | |||
@@ -1,8 +1,7 @@ | |||
1 | #ifndef _SPEAKUP_SERIAL_H | 1 | #ifndef _SPEAKUP_SERIAL_H |
2 | #define _SPEAKUP_SERIAL_H | 2 | #define _SPEAKUP_SERIAL_H |
3 | 3 | ||
4 | #include <linux/serial.h> /* for rs_table, serial constants & | 4 | #include <linux/serial.h> /* for rs_table, serial constants */ |
5 | serial_uart_config */ | ||
6 | #include <linux/serial_reg.h> /* for more serial constants */ | 5 | #include <linux/serial_reg.h> /* for more serial constants */ |
7 | #ifndef __sparc__ | 6 | #ifndef __sparc__ |
8 | #include <asm/serial.h> | 7 | #include <asm/serial.h> |
diff --git a/drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c b/drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c index a272e488e5b9..47439c3f7258 100644 --- a/drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c +++ b/drivers/staging/ste_rmi4/board-mop500-u8500uib-rmi4.c | |||
@@ -5,7 +5,6 @@ | |||
5 | #include <linux/i2c.h> | 5 | #include <linux/i2c.h> |
6 | #include <linux/gpio.h> | 6 | #include <linux/gpio.h> |
7 | #include <linux/interrupt.h> | 7 | #include <linux/interrupt.h> |
8 | #include <mach/gpio.h> | ||
9 | #include <mach/irqs.h> | 8 | #include <mach/irqs.h> |
10 | #include "synaptics_i2c_rmi4.h" | 9 | #include "synaptics_i2c_rmi4.h" |
11 | 10 | ||
diff --git a/drivers/staging/tidspbridge/core/dsp-clock.c b/drivers/staging/tidspbridge/core/dsp-clock.c index c7df34e6b60b..7d056bd1eaad 100644 --- a/drivers/staging/tidspbridge/core/dsp-clock.c +++ b/drivers/staging/tidspbridge/core/dsp-clock.c | |||
@@ -21,7 +21,7 @@ | |||
21 | /* ----------------------------------- Host OS */ | 21 | /* ----------------------------------- Host OS */ |
22 | #include <dspbridge/host_os.h> | 22 | #include <dspbridge/host_os.h> |
23 | #include <plat/dmtimer.h> | 23 | #include <plat/dmtimer.h> |
24 | #include <plat/mcbsp.h> | 24 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
25 | 25 | ||
26 | /* ----------------------------------- DSP/BIOS Bridge */ | 26 | /* ----------------------------------- DSP/BIOS Bridge */ |
27 | #include <dspbridge/dbdefs.h> | 27 | #include <dspbridge/dbdefs.h> |
diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index f9609ce2c163..7bf55c40944e 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <plat/dsp.h> | 19 | #include <linux/platform_data/dsp-omap.h> |
20 | 20 | ||
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | /* ----------------------------------- Host OS */ | 22 | /* ----------------------------------- Host OS */ |
diff --git a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c index 16a4aafa86ae..55675b7b9b66 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430_pwr.c +++ b/drivers/staging/tidspbridge/core/tiomap3430_pwr.c | |||
@@ -19,7 +19,7 @@ | |||
19 | /* ----------------------------------- Host OS */ | 19 | /* ----------------------------------- Host OS */ |
20 | #include <dspbridge/host_os.h> | 20 | #include <dspbridge/host_os.h> |
21 | 21 | ||
22 | #include <plat/dsp.h> | 22 | #include <linux/platform_data/dsp-omap.h> |
23 | 23 | ||
24 | /* ----------------------------------- DSP/BIOS Bridge */ | 24 | /* ----------------------------------- DSP/BIOS Bridge */ |
25 | #include <dspbridge/dbdefs.h> | 25 | #include <dspbridge/dbdefs.h> |
diff --git a/drivers/staging/tidspbridge/core/tiomap_io.c b/drivers/staging/tidspbridge/core/tiomap_io.c index 7fda10c36862..f53ed98d18c1 100644 --- a/drivers/staging/tidspbridge/core/tiomap_io.c +++ b/drivers/staging/tidspbridge/core/tiomap_io.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <plat/dsp.h> | 19 | #include <linux/platform_data/dsp-omap.h> |
20 | 20 | ||
21 | /* ----------------------------------- DSP/BIOS Bridge */ | 21 | /* ----------------------------------- DSP/BIOS Bridge */ |
22 | #include <dspbridge/dbdefs.h> | 22 | #include <dspbridge/dbdefs.h> |
diff --git a/drivers/staging/tidspbridge/core/wdt.c b/drivers/staging/tidspbridge/core/wdt.c index 870f934f4f3b..453ef748bf45 100644 --- a/drivers/staging/tidspbridge/core/wdt.c +++ b/drivers/staging/tidspbridge/core/wdt.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <dspbridge/host_os.h> | 25 | #include <dspbridge/host_os.h> |
26 | 26 | ||
27 | 27 | ||
28 | #define OMAP34XX_WDT3_BASE (L4_PER_34XX_BASE + 0x30000) | 28 | #define INT_34XX_WDT3_IRQ (36 + NR_IRQS) |
29 | 29 | ||
30 | static struct dsp_wdt_setting dsp_wdt; | 30 | static struct dsp_wdt_setting dsp_wdt; |
31 | 31 | ||
diff --git a/drivers/staging/tidspbridge/rmgr/drv_interface.c b/drivers/staging/tidspbridge/rmgr/drv_interface.c index 3cac01492063..49c9b662392f 100644 --- a/drivers/staging/tidspbridge/rmgr/drv_interface.c +++ b/drivers/staging/tidspbridge/rmgr/drv_interface.c | |||
@@ -16,7 +16,7 @@ | |||
16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | 16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <plat/dsp.h> | 19 | #include <linux/platform_data/dsp-omap.h> |
20 | 20 | ||
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index e4bdf2a2b582..3aa895ec6507 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c | |||
@@ -200,7 +200,7 @@ s_vProcessRxMACHeader ( | |||
200 | } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { | 200 | } else if (!compare_ether_addr(pbyRxBuffer, &pDevice->abySNAP_RFC1042[0])) { |
201 | cbHeaderSize += 6; | 201 | cbHeaderSize += 6; |
202 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); | 202 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); |
203 | if ((*pwType == cpu_to_le16(ETH_P_IPX)) || | 203 | if ((*pwType == cpu_to_be16(ETH_P_IPX)) || |
204 | (*pwType == cpu_to_le16(0xF380))) { | 204 | (*pwType == cpu_to_le16(0xF380))) { |
205 | cbHeaderSize -= 8; | 205 | cbHeaderSize -= 8; |
206 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); | 206 | pwType = (PWORD) (pbyRxBufferAddr + cbHeaderSize); |
diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index bb464527fc1b..b6e04e7b629b 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c | |||
@@ -1699,7 +1699,7 @@ s_bPacketToWirelessUsb( | |||
1699 | // 802.1H | 1699 | // 802.1H |
1700 | if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { | 1700 | if (ntohs(psEthHeader->wType) > ETH_DATA_LEN) { |
1701 | if (pDevice->dwDiagRefCount == 0) { | 1701 | if (pDevice->dwDiagRefCount == 0) { |
1702 | if ((psEthHeader->wType == cpu_to_le16(ETH_P_IPX)) || | 1702 | if ((psEthHeader->wType == cpu_to_be16(ETH_P_IPX)) || |
1703 | (psEthHeader->wType == cpu_to_le16(0xF380))) { | 1703 | (psEthHeader->wType == cpu_to_le16(0xF380))) { |
1704 | memcpy((PBYTE) (pbyPayloadHead), | 1704 | memcpy((PBYTE) (pbyPayloadHead), |
1705 | abySNAP_Bridgetunnel, 6); | 1705 | abySNAP_Bridgetunnel, 6); |
@@ -2838,10 +2838,10 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
2838 | Packet_Type = skb->data[ETH_HLEN+1]; | 2838 | Packet_Type = skb->data[ETH_HLEN+1]; |
2839 | Descriptor_type = skb->data[ETH_HLEN+1+1+2]; | 2839 | Descriptor_type = skb->data[ETH_HLEN+1+1+2]; |
2840 | Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); | 2840 | Key_info = (skb->data[ETH_HLEN+1+1+2+1] << 8)|(skb->data[ETH_HLEN+1+1+2+2]); |
2841 | if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { | 2841 | if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { |
2842 | /* 802.1x OR eapol-key challenge frame transfer */ | 2842 | /* 802.1x OR eapol-key challenge frame transfer */ |
2843 | if (((Protocol_Version == 1) || (Protocol_Version == 2)) && | 2843 | if (((Protocol_Version == 1) || (Protocol_Version == 2)) && |
2844 | (Packet_Type == 3)) { | 2844 | (Packet_Type == 3)) { |
2845 | bTxeapol_key = TRUE; | 2845 | bTxeapol_key = TRUE; |
2846 | if(!(Key_info & BIT3) && //WPA or RSN group-key challenge | 2846 | if(!(Key_info & BIT3) && //WPA or RSN group-key challenge |
2847 | (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key | 2847 | (Key_info & BIT8) && (Key_info & BIT9)) { //send 2/2 key |
@@ -2987,19 +2987,19 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
2987 | } | 2987 | } |
2988 | } | 2988 | } |
2989 | 2989 | ||
2990 | if (pDevice->sTxEthHeader.wType == cpu_to_le16(ETH_P_PAE)) { | 2990 | if (pDevice->sTxEthHeader.wType == cpu_to_be16(ETH_P_PAE)) { |
2991 | if (pDevice->byBBType != BB_TYPE_11A) { | 2991 | if (pDevice->byBBType != BB_TYPE_11A) { |
2992 | pDevice->wCurrentRate = RATE_1M; | 2992 | pDevice->wCurrentRate = RATE_1M; |
2993 | pDevice->byACKRate = RATE_1M; | 2993 | pDevice->byACKRate = RATE_1M; |
2994 | pDevice->byTopCCKBasicRate = RATE_1M; | 2994 | pDevice->byTopCCKBasicRate = RATE_1M; |
2995 | pDevice->byTopOFDMBasicRate = RATE_6M; | 2995 | pDevice->byTopOFDMBasicRate = RATE_6M; |
2996 | } else { | 2996 | } else { |
2997 | pDevice->wCurrentRate = RATE_6M; | 2997 | pDevice->wCurrentRate = RATE_6M; |
2998 | pDevice->byACKRate = RATE_6M; | 2998 | pDevice->byACKRate = RATE_6M; |
2999 | pDevice->byTopCCKBasicRate = RATE_1M; | 2999 | pDevice->byTopCCKBasicRate = RATE_1M; |
3000 | pDevice->byTopOFDMBasicRate = RATE_6M; | 3000 | pDevice->byTopOFDMBasicRate = RATE_6M; |
3001 | } | 3001 | } |
3002 | } | 3002 | } |
3003 | 3003 | ||
3004 | DBG_PRT(MSG_LEVEL_DEBUG, | 3004 | DBG_PRT(MSG_LEVEL_DEBUG, |
3005 | KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", | 3005 | KERN_INFO "dma_tx: pDevice->wCurrentRate = %d\n", |
@@ -3015,7 +3015,7 @@ int nsDMA_tx_packet(PSDevice pDevice, unsigned int uDMAIdx, struct sk_buff *skb) | |||
3015 | 3015 | ||
3016 | if (bNeedEncryption == TRUE) { | 3016 | if (bNeedEncryption == TRUE) { |
3017 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); | 3017 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"ntohs Pkt Type=%04x\n", ntohs(pDevice->sTxEthHeader.wType)); |
3018 | if ((pDevice->sTxEthHeader.wType) == cpu_to_le16(ETH_P_PAE)) { | 3018 | if ((pDevice->sTxEthHeader.wType) == cpu_to_be16(ETH_P_PAE)) { |
3019 | bNeedEncryption = FALSE; | 3019 | bNeedEncryption = FALSE; |
3020 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); | 3020 | DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Pkt Type=%04x\n", (pDevice->sTxEthHeader.wType)); |
3021 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { | 3021 | if ((pMgmt->eCurrMode == WMAC_MODE_ESS_STA) && (pMgmt->eCurrState == WMAC_STATE_ASSOC)) { |
diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c index fabff4d650ef..0970127344e6 100644 --- a/drivers/staging/wlan-ng/cfg80211.c +++ b/drivers/staging/wlan-ng/cfg80211.c | |||
@@ -327,9 +327,9 @@ int prism2_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
327 | return result; | 327 | return result; |
328 | } | 328 | } |
329 | 329 | ||
330 | int prism2_scan(struct wiphy *wiphy, struct net_device *dev, | 330 | int prism2_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) |
331 | struct cfg80211_scan_request *request) | ||
332 | { | 331 | { |
332 | struct net_device *dev = request->wdev->netdev; | ||
333 | struct prism2_wiphy_private *priv = wiphy_priv(wiphy); | 333 | struct prism2_wiphy_private *priv = wiphy_priv(wiphy); |
334 | wlandevice_t *wlandev = dev->ml_priv; | 334 | wlandevice_t *wlandev = dev->ml_priv; |
335 | struct p80211msg_dot11req_scan msg1; | 335 | struct p80211msg_dot11req_scan msg1; |
diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index c214977b4ab4..52b43b7b83d7 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c | |||
@@ -1251,13 +1251,12 @@ static int zcache_pampd_get_data_and_free(char *data, size_t *bufsize, bool raw, | |||
1251 | void *pampd, struct tmem_pool *pool, | 1251 | void *pampd, struct tmem_pool *pool, |
1252 | struct tmem_oid *oid, uint32_t index) | 1252 | struct tmem_oid *oid, uint32_t index) |
1253 | { | 1253 | { |
1254 | int ret = 0; | ||
1255 | |||
1256 | BUG_ON(!is_ephemeral(pool)); | 1254 | BUG_ON(!is_ephemeral(pool)); |
1257 | zbud_decompress((struct page *)(data), pampd); | 1255 | if (zbud_decompress((struct page *)(data), pampd) < 0) |
1256 | return -EINVAL; | ||
1258 | zbud_free_and_delist((struct zbud_hdr *)pampd); | 1257 | zbud_free_and_delist((struct zbud_hdr *)pampd); |
1259 | atomic_dec(&zcache_curr_eph_pampd_count); | 1258 | atomic_dec(&zcache_curr_eph_pampd_count); |
1260 | return ret; | 1259 | return 0; |
1261 | } | 1260 | } |
1262 | 1261 | ||
1263 | /* | 1262 | /* |
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 0694d9b1bce6..6aba4395e8d8 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c | |||
@@ -221,6 +221,7 @@ static int iscsi_login_zero_tsih_s1( | |||
221 | { | 221 | { |
222 | struct iscsi_session *sess = NULL; | 222 | struct iscsi_session *sess = NULL; |
223 | struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; | 223 | struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; |
224 | int ret; | ||
224 | 225 | ||
225 | sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); | 226 | sess = kzalloc(sizeof(struct iscsi_session), GFP_KERNEL); |
226 | if (!sess) { | 227 | if (!sess) { |
@@ -257,9 +258,17 @@ static int iscsi_login_zero_tsih_s1( | |||
257 | return -ENOMEM; | 258 | return -ENOMEM; |
258 | } | 259 | } |
259 | spin_lock(&sess_idr_lock); | 260 | spin_lock(&sess_idr_lock); |
260 | idr_get_new(&sess_idr, NULL, &sess->session_index); | 261 | ret = idr_get_new(&sess_idr, NULL, &sess->session_index); |
261 | spin_unlock(&sess_idr_lock); | 262 | spin_unlock(&sess_idr_lock); |
262 | 263 | ||
264 | if (ret < 0) { | ||
265 | pr_err("idr_get_new() for sess_idr failed\n"); | ||
266 | iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, | ||
267 | ISCSI_LOGIN_STATUS_NO_RESOURCES); | ||
268 | kfree(sess); | ||
269 | return -ENOMEM; | ||
270 | } | ||
271 | |||
263 | sess->creation_time = get_jiffies_64(); | 272 | sess->creation_time = get_jiffies_64(); |
264 | spin_lock_init(&sess->session_stats_lock); | 273 | spin_lock_init(&sess->session_stats_lock); |
265 | /* | 274 | /* |
diff --git a/drivers/target/target_core_alua.c b/drivers/target/target_core_alua.c index 91799973081a..41641ba54828 100644 --- a/drivers/target/target_core_alua.c +++ b/drivers/target/target_core_alua.c | |||
@@ -218,6 +218,13 @@ int target_emulate_set_target_port_groups(struct se_cmd *cmd) | |||
218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | 218 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; |
219 | return -EINVAL; | 219 | return -EINVAL; |
220 | } | 220 | } |
221 | if (cmd->data_length < 4) { | ||
222 | pr_warn("SET TARGET PORT GROUPS parameter list length %u too" | ||
223 | " small\n", cmd->data_length); | ||
224 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
225 | return -EINVAL; | ||
226 | } | ||
227 | |||
221 | buf = transport_kmap_data_sg(cmd); | 228 | buf = transport_kmap_data_sg(cmd); |
222 | 229 | ||
223 | /* | 230 | /* |
diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c index cf2c66f3c116..9fc9a6006ca0 100644 --- a/drivers/target/target_core_device.c +++ b/drivers/target/target_core_device.c | |||
@@ -669,6 +669,13 @@ int target_report_luns(struct se_cmd *se_cmd) | |||
669 | unsigned char *buf; | 669 | unsigned char *buf; |
670 | u32 lun_count = 0, offset = 8, i; | 670 | u32 lun_count = 0, offset = 8, i; |
671 | 671 | ||
672 | if (se_cmd->data_length < 16) { | ||
673 | pr_warn("REPORT LUNS allocation length %u too small\n", | ||
674 | se_cmd->data_length); | ||
675 | se_cmd->scsi_sense_reason = TCM_INVALID_CDB_FIELD; | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | |||
672 | buf = transport_kmap_data_sg(se_cmd); | 679 | buf = transport_kmap_data_sg(se_cmd); |
673 | if (!buf) | 680 | if (!buf) |
674 | return -ENOMEM; | 681 | return -ENOMEM; |
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c index 76db75e836ed..9ba495477fd2 100644 --- a/drivers/target/target_core_iblock.c +++ b/drivers/target/target_core_iblock.c | |||
@@ -325,17 +325,30 @@ static int iblock_execute_unmap(struct se_cmd *cmd) | |||
325 | struct iblock_dev *ibd = dev->dev_ptr; | 325 | struct iblock_dev *ibd = dev->dev_ptr; |
326 | unsigned char *buf, *ptr = NULL; | 326 | unsigned char *buf, *ptr = NULL; |
327 | sector_t lba; | 327 | sector_t lba; |
328 | int size = cmd->data_length; | 328 | int size; |
329 | u32 range; | 329 | u32 range; |
330 | int ret = 0; | 330 | int ret = 0; |
331 | int dl, bd_dl; | 331 | int dl, bd_dl; |
332 | 332 | ||
333 | if (cmd->data_length < 8) { | ||
334 | pr_warn("UNMAP parameter list length %u too small\n", | ||
335 | cmd->data_length); | ||
336 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
337 | return -EINVAL; | ||
338 | } | ||
339 | |||
333 | buf = transport_kmap_data_sg(cmd); | 340 | buf = transport_kmap_data_sg(cmd); |
334 | 341 | ||
335 | dl = get_unaligned_be16(&buf[0]); | 342 | dl = get_unaligned_be16(&buf[0]); |
336 | bd_dl = get_unaligned_be16(&buf[2]); | 343 | bd_dl = get_unaligned_be16(&buf[2]); |
337 | 344 | ||
338 | size = min(size - 8, bd_dl); | 345 | size = cmd->data_length - 8; |
346 | if (bd_dl > size) | ||
347 | pr_warn("UNMAP parameter list length %u too small, ignoring bd_dl %u\n", | ||
348 | cmd->data_length, bd_dl); | ||
349 | else | ||
350 | size = bd_dl; | ||
351 | |||
339 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { | 352 | if (size / 16 > dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count) { |
340 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | 353 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; |
341 | ret = -EINVAL; | 354 | ret = -EINVAL; |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index 1e946502c378..956c84c6b666 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -1540,6 +1540,14 @@ static int core_scsi3_decode_spec_i_port( | |||
1540 | tidh_new->dest_local_nexus = 1; | 1540 | tidh_new->dest_local_nexus = 1; |
1541 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); | 1541 | list_add_tail(&tidh_new->dest_list, &tid_dest_list); |
1542 | 1542 | ||
1543 | if (cmd->data_length < 28) { | ||
1544 | pr_warn("SPC-PR: Received PR OUT parameter list" | ||
1545 | " length too small: %u\n", cmd->data_length); | ||
1546 | cmd->scsi_sense_reason = TCM_INVALID_PARAMETER_LIST; | ||
1547 | ret = -EINVAL; | ||
1548 | goto out; | ||
1549 | } | ||
1550 | |||
1543 | buf = transport_kmap_data_sg(cmd); | 1551 | buf = transport_kmap_data_sg(cmd); |
1544 | /* | 1552 | /* |
1545 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, | 1553 | * For a PERSISTENT RESERVE OUT specify initiator ports payload, |
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 5552fa7426bc..9d7ce3daa262 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c | |||
@@ -667,7 +667,8 @@ static void pscsi_free_device(void *p) | |||
667 | kfree(pdv); | 667 | kfree(pdv); |
668 | } | 668 | } |
669 | 669 | ||
670 | static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | 670 | static void pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg, |
671 | unsigned char *sense_buffer) | ||
671 | { | 672 | { |
672 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; | 673 | struct pscsi_dev_virt *pdv = cmd->se_dev->dev_ptr; |
673 | struct scsi_device *sd = pdv->pdv_sd; | 674 | struct scsi_device *sd = pdv->pdv_sd; |
@@ -679,7 +680,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | |||
679 | * not been allocated because TCM is handling the emulation directly. | 680 | * not been allocated because TCM is handling the emulation directly. |
680 | */ | 681 | */ |
681 | if (!pt) | 682 | if (!pt) |
682 | return 0; | 683 | return; |
683 | 684 | ||
684 | cdb = &pt->pscsi_cdb[0]; | 685 | cdb = &pt->pscsi_cdb[0]; |
685 | result = pt->pscsi_result; | 686 | result = pt->pscsi_result; |
@@ -687,11 +688,11 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | |||
687 | * Hack to make sure that Write-Protect modepage is set if R/O mode is | 688 | * Hack to make sure that Write-Protect modepage is set if R/O mode is |
688 | * forced. | 689 | * forced. |
689 | */ | 690 | */ |
691 | if (!cmd->se_deve || !cmd->data_length) | ||
692 | goto after_mode_sense; | ||
693 | |||
690 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && | 694 | if (((cdb[0] == MODE_SENSE) || (cdb[0] == MODE_SENSE_10)) && |
691 | (status_byte(result) << 1) == SAM_STAT_GOOD) { | 695 | (status_byte(result) << 1) == SAM_STAT_GOOD) { |
692 | if (!cmd->se_deve) | ||
693 | goto after_mode_sense; | ||
694 | |||
695 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { | 696 | if (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY) { |
696 | unsigned char *buf = transport_kmap_data_sg(cmd); | 697 | unsigned char *buf = transport_kmap_data_sg(cmd); |
697 | 698 | ||
@@ -708,7 +709,7 @@ static int pscsi_transport_complete(struct se_cmd *cmd, struct scatterlist *sg) | |||
708 | } | 709 | } |
709 | after_mode_sense: | 710 | after_mode_sense: |
710 | 711 | ||
711 | if (sd->type != TYPE_TAPE) | 712 | if (sd->type != TYPE_TAPE || !cmd->data_length) |
712 | goto after_mode_select; | 713 | goto after_mode_select; |
713 | 714 | ||
714 | /* | 715 | /* |
@@ -750,10 +751,10 @@ after_mode_sense: | |||
750 | } | 751 | } |
751 | after_mode_select: | 752 | after_mode_select: |
752 | 753 | ||
753 | if (status_byte(result) & CHECK_CONDITION) | 754 | if (sense_buffer && (status_byte(result) & CHECK_CONDITION)) { |
754 | return 1; | 755 | memcpy(sense_buffer, pt->pscsi_sense, TRANSPORT_SENSE_BUFFER); |
755 | 756 | cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; | |
756 | return 0; | 757 | } |
757 | } | 758 | } |
758 | 759 | ||
759 | enum { | 760 | enum { |
@@ -1184,13 +1185,6 @@ fail: | |||
1184 | return -ENOMEM; | 1185 | return -ENOMEM; |
1185 | } | 1186 | } |
1186 | 1187 | ||
1187 | static unsigned char *pscsi_get_sense_buffer(struct se_cmd *cmd) | ||
1188 | { | ||
1189 | struct pscsi_plugin_task *pt = cmd->priv; | ||
1190 | |||
1191 | return pt->pscsi_sense; | ||
1192 | } | ||
1193 | |||
1194 | /* pscsi_get_device_rev(): | 1188 | /* pscsi_get_device_rev(): |
1195 | * | 1189 | * |
1196 | * | 1190 | * |
@@ -1273,7 +1267,6 @@ static struct se_subsystem_api pscsi_template = { | |||
1273 | .check_configfs_dev_params = pscsi_check_configfs_dev_params, | 1267 | .check_configfs_dev_params = pscsi_check_configfs_dev_params, |
1274 | .set_configfs_dev_params = pscsi_set_configfs_dev_params, | 1268 | .set_configfs_dev_params = pscsi_set_configfs_dev_params, |
1275 | .show_configfs_dev_params = pscsi_show_configfs_dev_params, | 1269 | .show_configfs_dev_params = pscsi_show_configfs_dev_params, |
1276 | .get_sense_buffer = pscsi_get_sense_buffer, | ||
1277 | .get_device_rev = pscsi_get_device_rev, | 1270 | .get_device_rev = pscsi_get_device_rev, |
1278 | .get_device_type = pscsi_get_device_type, | 1271 | .get_device_type = pscsi_get_device_type, |
1279 | .get_blocks = pscsi_get_blocks, | 1272 | .get_blocks = pscsi_get_blocks, |
diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index 4c861de538c9..388a922c8f6d 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c | |||
@@ -877,9 +877,11 @@ static int spc_emulate_modesense(struct se_cmd *cmd) | |||
877 | static int spc_emulate_request_sense(struct se_cmd *cmd) | 877 | static int spc_emulate_request_sense(struct se_cmd *cmd) |
878 | { | 878 | { |
879 | unsigned char *cdb = cmd->t_task_cdb; | 879 | unsigned char *cdb = cmd->t_task_cdb; |
880 | unsigned char *buf; | 880 | unsigned char *rbuf; |
881 | u8 ua_asc = 0, ua_ascq = 0; | 881 | u8 ua_asc = 0, ua_ascq = 0; |
882 | int err = 0; | 882 | unsigned char buf[SE_SENSE_BUF]; |
883 | |||
884 | memset(buf, 0, SE_SENSE_BUF); | ||
883 | 885 | ||
884 | if (cdb[1] & 0x01) { | 886 | if (cdb[1] & 0x01) { |
885 | pr_err("REQUEST_SENSE description emulation not" | 887 | pr_err("REQUEST_SENSE description emulation not" |
@@ -888,20 +890,21 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
888 | return -ENOSYS; | 890 | return -ENOSYS; |
889 | } | 891 | } |
890 | 892 | ||
891 | buf = transport_kmap_data_sg(cmd); | 893 | rbuf = transport_kmap_data_sg(cmd); |
892 | 894 | if (cmd->scsi_sense_reason != 0) { | |
893 | if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | 895 | /* |
896 | * Out of memory. We will fail with CHECK CONDITION, so | ||
897 | * we must not clear the unit attention condition. | ||
898 | */ | ||
899 | target_complete_cmd(cmd, CHECK_CONDITION); | ||
900 | return 0; | ||
901 | } else if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) { | ||
894 | /* | 902 | /* |
895 | * CURRENT ERROR, UNIT ATTENTION | 903 | * CURRENT ERROR, UNIT ATTENTION |
896 | */ | 904 | */ |
897 | buf[0] = 0x70; | 905 | buf[0] = 0x70; |
898 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; | 906 | buf[SPC_SENSE_KEY_OFFSET] = UNIT_ATTENTION; |
899 | 907 | ||
900 | if (cmd->data_length < 18) { | ||
901 | buf[7] = 0x00; | ||
902 | err = -EINVAL; | ||
903 | goto end; | ||
904 | } | ||
905 | /* | 908 | /* |
906 | * The Additional Sense Code (ASC) from the UNIT ATTENTION | 909 | * The Additional Sense Code (ASC) from the UNIT ATTENTION |
907 | */ | 910 | */ |
@@ -915,11 +918,6 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
915 | buf[0] = 0x70; | 918 | buf[0] = 0x70; |
916 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; | 919 | buf[SPC_SENSE_KEY_OFFSET] = NO_SENSE; |
917 | 920 | ||
918 | if (cmd->data_length < 18) { | ||
919 | buf[7] = 0x00; | ||
920 | err = -EINVAL; | ||
921 | goto end; | ||
922 | } | ||
923 | /* | 921 | /* |
924 | * NO ADDITIONAL SENSE INFORMATION | 922 | * NO ADDITIONAL SENSE INFORMATION |
925 | */ | 923 | */ |
@@ -927,8 +925,11 @@ static int spc_emulate_request_sense(struct se_cmd *cmd) | |||
927 | buf[7] = 0x0A; | 925 | buf[7] = 0x0A; |
928 | } | 926 | } |
929 | 927 | ||
930 | end: | 928 | if (rbuf) { |
931 | transport_kunmap_data_sg(cmd); | 929 | memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); |
930 | transport_kunmap_data_sg(cmd); | ||
931 | } | ||
932 | |||
932 | target_complete_cmd(cmd, GOOD); | 933 | target_complete_cmd(cmd, GOOD); |
933 | return 0; | 934 | return 0; |
934 | } | 935 | } |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 4de3186dc44e..269f54488397 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -567,6 +567,34 @@ static void target_complete_failure_work(struct work_struct *work) | |||
567 | transport_generic_request_failure(cmd); | 567 | transport_generic_request_failure(cmd); |
568 | } | 568 | } |
569 | 569 | ||
570 | /* | ||
571 | * Used when asking transport to copy Sense Data from the underlying | ||
572 | * Linux/SCSI struct scsi_cmnd | ||
573 | */ | ||
574 | static unsigned char *transport_get_sense_buffer(struct se_cmd *cmd) | ||
575 | { | ||
576 | unsigned char *buffer = cmd->sense_buffer; | ||
577 | struct se_device *dev = cmd->se_dev; | ||
578 | u32 offset = 0; | ||
579 | |||
580 | WARN_ON(!cmd->se_lun); | ||
581 | |||
582 | if (!dev) | ||
583 | return NULL; | ||
584 | |||
585 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) | ||
586 | return NULL; | ||
587 | |||
588 | offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); | ||
589 | |||
590 | /* Automatically padded */ | ||
591 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; | ||
592 | |||
593 | pr_debug("HBA_[%u]_PLUG[%s]: Requesting sense for SAM STATUS: 0x%02x\n", | ||
594 | dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); | ||
595 | return &buffer[offset]; | ||
596 | } | ||
597 | |||
570 | void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | 598 | void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) |
571 | { | 599 | { |
572 | struct se_device *dev = cmd->se_dev; | 600 | struct se_device *dev = cmd->se_dev; |
@@ -580,11 +608,11 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status) | |||
580 | cmd->transport_state &= ~CMD_T_BUSY; | 608 | cmd->transport_state &= ~CMD_T_BUSY; |
581 | 609 | ||
582 | if (dev && dev->transport->transport_complete) { | 610 | if (dev && dev->transport->transport_complete) { |
583 | if (dev->transport->transport_complete(cmd, | 611 | dev->transport->transport_complete(cmd, |
584 | cmd->t_data_sg) != 0) { | 612 | cmd->t_data_sg, |
585 | cmd->se_cmd_flags |= SCF_TRANSPORT_TASK_SENSE; | 613 | transport_get_sense_buffer(cmd)); |
614 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) | ||
586 | success = 1; | 615 | success = 1; |
587 | } | ||
588 | } | 616 | } |
589 | 617 | ||
590 | /* | 618 | /* |
@@ -1181,15 +1209,20 @@ int target_cmd_size_check(struct se_cmd *cmd, unsigned int size) | |||
1181 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ | 1209 | /* Returns CHECK_CONDITION + INVALID_CDB_FIELD */ |
1182 | goto out_invalid_cdb_field; | 1210 | goto out_invalid_cdb_field; |
1183 | } | 1211 | } |
1184 | 1212 | /* | |
1213 | * For the overflow case keep the existing fabric provided | ||
1214 | * ->data_length. Otherwise for the underflow case, reset | ||
1215 | * ->data_length to the smaller SCSI expected data transfer | ||
1216 | * length. | ||
1217 | */ | ||
1185 | if (size > cmd->data_length) { | 1218 | if (size > cmd->data_length) { |
1186 | cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; | 1219 | cmd->se_cmd_flags |= SCF_OVERFLOW_BIT; |
1187 | cmd->residual_count = (size - cmd->data_length); | 1220 | cmd->residual_count = (size - cmd->data_length); |
1188 | } else { | 1221 | } else { |
1189 | cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; | 1222 | cmd->se_cmd_flags |= SCF_UNDERFLOW_BIT; |
1190 | cmd->residual_count = (cmd->data_length - size); | 1223 | cmd->residual_count = (cmd->data_length - size); |
1224 | cmd->data_length = size; | ||
1191 | } | 1225 | } |
1192 | cmd->data_length = size; | ||
1193 | } | 1226 | } |
1194 | 1227 | ||
1195 | return 0; | 1228 | return 0; |
@@ -1816,61 +1849,6 @@ execute: | |||
1816 | EXPORT_SYMBOL(target_execute_cmd); | 1849 | EXPORT_SYMBOL(target_execute_cmd); |
1817 | 1850 | ||
1818 | /* | 1851 | /* |
1819 | * Used to obtain Sense Data from underlying Linux/SCSI struct scsi_cmnd | ||
1820 | */ | ||
1821 | static int transport_get_sense_data(struct se_cmd *cmd) | ||
1822 | { | ||
1823 | unsigned char *buffer = cmd->sense_buffer, *sense_buffer = NULL; | ||
1824 | struct se_device *dev = cmd->se_dev; | ||
1825 | unsigned long flags; | ||
1826 | u32 offset = 0; | ||
1827 | |||
1828 | WARN_ON(!cmd->se_lun); | ||
1829 | |||
1830 | if (!dev) | ||
1831 | return 0; | ||
1832 | |||
1833 | spin_lock_irqsave(&cmd->t_state_lock, flags); | ||
1834 | if (cmd->se_cmd_flags & SCF_SENT_CHECK_CONDITION) { | ||
1835 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1836 | return 0; | ||
1837 | } | ||
1838 | |||
1839 | if (!(cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE)) | ||
1840 | goto out; | ||
1841 | |||
1842 | if (!dev->transport->get_sense_buffer) { | ||
1843 | pr_err("dev->transport->get_sense_buffer is NULL\n"); | ||
1844 | goto out; | ||
1845 | } | ||
1846 | |||
1847 | sense_buffer = dev->transport->get_sense_buffer(cmd); | ||
1848 | if (!sense_buffer) { | ||
1849 | pr_err("ITT 0x%08x cmd %p: Unable to locate" | ||
1850 | " sense buffer for task with sense\n", | ||
1851 | cmd->se_tfo->get_task_tag(cmd), cmd); | ||
1852 | goto out; | ||
1853 | } | ||
1854 | |||
1855 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1856 | |||
1857 | offset = cmd->se_tfo->set_fabric_sense_len(cmd, TRANSPORT_SENSE_BUFFER); | ||
1858 | |||
1859 | memcpy(&buffer[offset], sense_buffer, TRANSPORT_SENSE_BUFFER); | ||
1860 | |||
1861 | /* Automatically padded */ | ||
1862 | cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER + offset; | ||
1863 | |||
1864 | pr_debug("HBA_[%u]_PLUG[%s]: Set SAM STATUS: 0x%02x and sense\n", | ||
1865 | dev->se_hba->hba_id, dev->transport->name, cmd->scsi_status); | ||
1866 | return 0; | ||
1867 | |||
1868 | out: | ||
1869 | spin_unlock_irqrestore(&cmd->t_state_lock, flags); | ||
1870 | return -1; | ||
1871 | } | ||
1872 | |||
1873 | /* | ||
1874 | * Process all commands up to the last received ORDERED task attribute which | 1852 | * Process all commands up to the last received ORDERED task attribute which |
1875 | * requires another blocking boundary | 1853 | * requires another blocking boundary |
1876 | */ | 1854 | */ |
@@ -1985,7 +1963,7 @@ static void transport_handle_queue_full( | |||
1985 | static void target_complete_ok_work(struct work_struct *work) | 1963 | static void target_complete_ok_work(struct work_struct *work) |
1986 | { | 1964 | { |
1987 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); | 1965 | struct se_cmd *cmd = container_of(work, struct se_cmd, work); |
1988 | int reason = 0, ret; | 1966 | int ret; |
1989 | 1967 | ||
1990 | /* | 1968 | /* |
1991 | * Check if we need to move delayed/dormant tasks from cmds on the | 1969 | * Check if we need to move delayed/dormant tasks from cmds on the |
@@ -2002,23 +1980,19 @@ static void target_complete_ok_work(struct work_struct *work) | |||
2002 | schedule_work(&cmd->se_dev->qf_work_queue); | 1980 | schedule_work(&cmd->se_dev->qf_work_queue); |
2003 | 1981 | ||
2004 | /* | 1982 | /* |
2005 | * Check if we need to retrieve a sense buffer from | 1983 | * Check if we need to send a sense buffer from |
2006 | * the struct se_cmd in question. | 1984 | * the struct se_cmd in question. |
2007 | */ | 1985 | */ |
2008 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { | 1986 | if (cmd->se_cmd_flags & SCF_TRANSPORT_TASK_SENSE) { |
2009 | if (transport_get_sense_data(cmd) < 0) | 1987 | WARN_ON(!cmd->scsi_status); |
2010 | reason = TCM_NON_EXISTENT_LUN; | 1988 | ret = transport_send_check_condition_and_sense( |
2011 | 1989 | cmd, 0, 1); | |
2012 | if (cmd->scsi_status) { | 1990 | if (ret == -EAGAIN || ret == -ENOMEM) |
2013 | ret = transport_send_check_condition_and_sense( | 1991 | goto queue_full; |
2014 | cmd, reason, 1); | ||
2015 | if (ret == -EAGAIN || ret == -ENOMEM) | ||
2016 | goto queue_full; | ||
2017 | 1992 | ||
2018 | transport_lun_remove_cmd(cmd); | 1993 | transport_lun_remove_cmd(cmd); |
2019 | transport_cmd_check_stop_to_fabric(cmd); | 1994 | transport_cmd_check_stop_to_fabric(cmd); |
2020 | return; | 1995 | return; |
2021 | } | ||
2022 | } | 1996 | } |
2023 | /* | 1997 | /* |
2024 | * Check for a callback, used by amongst other things | 1998 | * Check for a callback, used by amongst other things |
@@ -2216,7 +2190,6 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2216 | struct page **pages; | 2190 | struct page **pages; |
2217 | int i; | 2191 | int i; |
2218 | 2192 | ||
2219 | BUG_ON(!sg); | ||
2220 | /* | 2193 | /* |
2221 | * We need to take into account a possible offset here for fabrics like | 2194 | * We need to take into account a possible offset here for fabrics like |
2222 | * tcm_loop who may be using a contig buffer from the SCSI midlayer for | 2195 | * tcm_loop who may be using a contig buffer from the SCSI midlayer for |
@@ -2224,13 +2197,17 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2224 | */ | 2197 | */ |
2225 | if (!cmd->t_data_nents) | 2198 | if (!cmd->t_data_nents) |
2226 | return NULL; | 2199 | return NULL; |
2227 | else if (cmd->t_data_nents == 1) | 2200 | |
2201 | BUG_ON(!sg); | ||
2202 | if (cmd->t_data_nents == 1) | ||
2228 | return kmap(sg_page(sg)) + sg->offset; | 2203 | return kmap(sg_page(sg)) + sg->offset; |
2229 | 2204 | ||
2230 | /* >1 page. use vmap */ | 2205 | /* >1 page. use vmap */ |
2231 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); | 2206 | pages = kmalloc(sizeof(*pages) * cmd->t_data_nents, GFP_KERNEL); |
2232 | if (!pages) | 2207 | if (!pages) { |
2208 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2233 | return NULL; | 2209 | return NULL; |
2210 | } | ||
2234 | 2211 | ||
2235 | /* convert sg[] to pages[] */ | 2212 | /* convert sg[] to pages[] */ |
2236 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { | 2213 | for_each_sg(cmd->t_data_sg, sg, cmd->t_data_nents, i) { |
@@ -2239,8 +2216,10 @@ void *transport_kmap_data_sg(struct se_cmd *cmd) | |||
2239 | 2216 | ||
2240 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); | 2217 | cmd->t_data_vmap = vmap(pages, cmd->t_data_nents, VM_MAP, PAGE_KERNEL); |
2241 | kfree(pages); | 2218 | kfree(pages); |
2242 | if (!cmd->t_data_vmap) | 2219 | if (!cmd->t_data_vmap) { |
2220 | cmd->scsi_sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; | ||
2243 | return NULL; | 2221 | return NULL; |
2222 | } | ||
2244 | 2223 | ||
2245 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; | 2224 | return cmd->t_data_vmap + cmd->t_data_sg[0].offset; |
2246 | } | 2225 | } |
@@ -2326,19 +2305,14 @@ int transport_generic_new_cmd(struct se_cmd *cmd) | |||
2326 | * into the fabric for data transfers, go ahead and complete it right | 2305 | * into the fabric for data transfers, go ahead and complete it right |
2327 | * away. | 2306 | * away. |
2328 | */ | 2307 | */ |
2329 | if (!cmd->data_length) { | 2308 | if (!cmd->data_length && |
2309 | cmd->t_task_cdb[0] != REQUEST_SENSE && | ||
2310 | cmd->se_dev->transport->transport_type != TRANSPORT_PLUGIN_PHBA_PDEV) { | ||
2330 | spin_lock_irq(&cmd->t_state_lock); | 2311 | spin_lock_irq(&cmd->t_state_lock); |
2331 | cmd->t_state = TRANSPORT_COMPLETE; | 2312 | cmd->t_state = TRANSPORT_COMPLETE; |
2332 | cmd->transport_state |= CMD_T_ACTIVE; | 2313 | cmd->transport_state |= CMD_T_ACTIVE; |
2333 | spin_unlock_irq(&cmd->t_state_lock); | 2314 | spin_unlock_irq(&cmd->t_state_lock); |
2334 | 2315 | ||
2335 | if (cmd->t_task_cdb[0] == REQUEST_SENSE) { | ||
2336 | u8 ua_asc = 0, ua_ascq = 0; | ||
2337 | |||
2338 | core_scsi3_ua_clear_for_request_sense(cmd, | ||
2339 | &ua_asc, &ua_ascq); | ||
2340 | } | ||
2341 | |||
2342 | INIT_WORK(&cmd->work, target_complete_ok_work); | 2316 | INIT_WORK(&cmd->work, target_complete_ok_work); |
2343 | queue_work(target_completion_wq, &cmd->work); | 2317 | queue_work(target_completion_wq, &cmd->work); |
2344 | return 0; | 2318 | return 0; |
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c index 6cc4358f68c1..42d0a2581a87 100644 --- a/drivers/tty/amiserial.c +++ b/drivers/tty/amiserial.c | |||
@@ -420,7 +420,7 @@ static void check_modem_status(struct serial_state *info) | |||
420 | tty_hangup(port->tty); | 420 | tty_hangup(port->tty); |
421 | } | 421 | } |
422 | } | 422 | } |
423 | if (port->flags & ASYNC_CTS_FLOW) { | 423 | if (tty_port_cts_enabled(port)) { |
424 | if (port->tty->hw_stopped) { | 424 | if (port->tty->hw_stopped) { |
425 | if (!(status & SER_CTS)) { | 425 | if (!(status & SER_CTS)) { |
426 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) | 426 | #if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW)) |
@@ -646,7 +646,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info) | |||
646 | custom.adkcon = AC_UARTBRK; | 646 | custom.adkcon = AC_UARTBRK; |
647 | mb(); | 647 | mb(); |
648 | 648 | ||
649 | if (tty->termios->c_cflag & HUPCL) | 649 | if (tty->termios.c_cflag & HUPCL) |
650 | info->MCR &= ~(SER_DTR|SER_RTS); | 650 | info->MCR &= ~(SER_DTR|SER_RTS); |
651 | rtsdtr_ctrl(info->MCR); | 651 | rtsdtr_ctrl(info->MCR); |
652 | 652 | ||
@@ -670,7 +670,7 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, | |||
670 | int bits; | 670 | int bits; |
671 | unsigned long flags; | 671 | unsigned long flags; |
672 | 672 | ||
673 | cflag = tty->termios->c_cflag; | 673 | cflag = tty->termios.c_cflag; |
674 | 674 | ||
675 | /* Byte size is always 8 bits plus parity bit if requested */ | 675 | /* Byte size is always 8 bits plus parity bit if requested */ |
676 | 676 | ||
@@ -707,8 +707,8 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info, | |||
707 | /* If the quotient is zero refuse the change */ | 707 | /* If the quotient is zero refuse the change */ |
708 | if (!quot && old_termios) { | 708 | if (!quot && old_termios) { |
709 | /* FIXME: Will need updating for new tty in the end */ | 709 | /* FIXME: Will need updating for new tty in the end */ |
710 | tty->termios->c_cflag &= ~CBAUD; | 710 | tty->termios.c_cflag &= ~CBAUD; |
711 | tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD); | 711 | tty->termios.c_cflag |= (old_termios->c_cflag & CBAUD); |
712 | baud = tty_get_baud_rate(tty); | 712 | baud = tty_get_baud_rate(tty); |
713 | if (!baud) | 713 | if (!baud) |
714 | baud = 9600; | 714 | baud = 9600; |
@@ -984,7 +984,7 @@ static void rs_throttle(struct tty_struct * tty) | |||
984 | if (I_IXOFF(tty)) | 984 | if (I_IXOFF(tty)) |
985 | rs_send_xchar(tty, STOP_CHAR(tty)); | 985 | rs_send_xchar(tty, STOP_CHAR(tty)); |
986 | 986 | ||
987 | if (tty->termios->c_cflag & CRTSCTS) | 987 | if (tty->termios.c_cflag & CRTSCTS) |
988 | info->MCR &= ~SER_RTS; | 988 | info->MCR &= ~SER_RTS; |
989 | 989 | ||
990 | local_irq_save(flags); | 990 | local_irq_save(flags); |
@@ -1012,7 +1012,7 @@ static void rs_unthrottle(struct tty_struct * tty) | |||
1012 | else | 1012 | else |
1013 | rs_send_xchar(tty, START_CHAR(tty)); | 1013 | rs_send_xchar(tty, START_CHAR(tty)); |
1014 | } | 1014 | } |
1015 | if (tty->termios->c_cflag & CRTSCTS) | 1015 | if (tty->termios.c_cflag & CRTSCTS) |
1016 | info->MCR |= SER_RTS; | 1016 | info->MCR |= SER_RTS; |
1017 | local_irq_save(flags); | 1017 | local_irq_save(flags); |
1018 | rtsdtr_ctrl(info->MCR); | 1018 | rtsdtr_ctrl(info->MCR); |
@@ -1033,7 +1033,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
1033 | if (!retinfo) | 1033 | if (!retinfo) |
1034 | return -EFAULT; | 1034 | return -EFAULT; |
1035 | memset(&tmp, 0, sizeof(tmp)); | 1035 | memset(&tmp, 0, sizeof(tmp)); |
1036 | tty_lock(); | 1036 | tty_lock(tty); |
1037 | tmp.line = tty->index; | 1037 | tmp.line = tty->index; |
1038 | tmp.port = state->port; | 1038 | tmp.port = state->port; |
1039 | tmp.flags = state->tport.flags; | 1039 | tmp.flags = state->tport.flags; |
@@ -1042,7 +1042,7 @@ static int get_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
1042 | tmp.close_delay = state->tport.close_delay; | 1042 | tmp.close_delay = state->tport.close_delay; |
1043 | tmp.closing_wait = state->tport.closing_wait; | 1043 | tmp.closing_wait = state->tport.closing_wait; |
1044 | tmp.custom_divisor = state->custom_divisor; | 1044 | tmp.custom_divisor = state->custom_divisor; |
1045 | tty_unlock(); | 1045 | tty_unlock(tty); |
1046 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) | 1046 | if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) |
1047 | return -EFAULT; | 1047 | return -EFAULT; |
1048 | return 0; | 1048 | return 0; |
@@ -1059,12 +1059,12 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
1059 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) | 1059 | if (copy_from_user(&new_serial,new_info,sizeof(new_serial))) |
1060 | return -EFAULT; | 1060 | return -EFAULT; |
1061 | 1061 | ||
1062 | tty_lock(); | 1062 | tty_lock(tty); |
1063 | change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || | 1063 | change_spd = ((new_serial.flags ^ port->flags) & ASYNC_SPD_MASK) || |
1064 | new_serial.custom_divisor != state->custom_divisor; | 1064 | new_serial.custom_divisor != state->custom_divisor; |
1065 | if (new_serial.irq || new_serial.port != state->port || | 1065 | if (new_serial.irq || new_serial.port != state->port || |
1066 | new_serial.xmit_fifo_size != state->xmit_fifo_size) { | 1066 | new_serial.xmit_fifo_size != state->xmit_fifo_size) { |
1067 | tty_unlock(); | 1067 | tty_unlock(tty); |
1068 | return -EINVAL; | 1068 | return -EINVAL; |
1069 | } | 1069 | } |
1070 | 1070 | ||
@@ -1074,7 +1074,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
1074 | (new_serial.xmit_fifo_size != state->xmit_fifo_size) || | 1074 | (new_serial.xmit_fifo_size != state->xmit_fifo_size) || |
1075 | ((new_serial.flags & ~ASYNC_USR_MASK) != | 1075 | ((new_serial.flags & ~ASYNC_USR_MASK) != |
1076 | (port->flags & ~ASYNC_USR_MASK))) { | 1076 | (port->flags & ~ASYNC_USR_MASK))) { |
1077 | tty_unlock(); | 1077 | tty_unlock(tty); |
1078 | return -EPERM; | 1078 | return -EPERM; |
1079 | } | 1079 | } |
1080 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | | 1080 | port->flags = ((port->flags & ~ASYNC_USR_MASK) | |
@@ -1084,7 +1084,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_state *state, | |||
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | if (new_serial.baud_base < 9600) { | 1086 | if (new_serial.baud_base < 9600) { |
1087 | tty_unlock(); | 1087 | tty_unlock(tty); |
1088 | return -EINVAL; | 1088 | return -EINVAL; |
1089 | } | 1089 | } |
1090 | 1090 | ||
@@ -1116,7 +1116,7 @@ check_and_exit: | |||
1116 | } | 1116 | } |
1117 | } else | 1117 | } else |
1118 | retval = startup(tty, state); | 1118 | retval = startup(tty, state); |
1119 | tty_unlock(); | 1119 | tty_unlock(tty); |
1120 | return retval; | 1120 | return retval; |
1121 | } | 1121 | } |
1122 | 1122 | ||
@@ -1330,7 +1330,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1330 | { | 1330 | { |
1331 | struct serial_state *info = tty->driver_data; | 1331 | struct serial_state *info = tty->driver_data; |
1332 | unsigned long flags; | 1332 | unsigned long flags; |
1333 | unsigned int cflag = tty->termios->c_cflag; | 1333 | unsigned int cflag = tty->termios.c_cflag; |
1334 | 1334 | ||
1335 | change_speed(tty, info, old_termios); | 1335 | change_speed(tty, info, old_termios); |
1336 | 1336 | ||
@@ -1347,7 +1347,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1347 | if (!(old_termios->c_cflag & CBAUD) && | 1347 | if (!(old_termios->c_cflag & CBAUD) && |
1348 | (cflag & CBAUD)) { | 1348 | (cflag & CBAUD)) { |
1349 | info->MCR |= SER_DTR; | 1349 | info->MCR |= SER_DTR; |
1350 | if (!(tty->termios->c_cflag & CRTSCTS) || | 1350 | if (!(tty->termios.c_cflag & CRTSCTS) || |
1351 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 1351 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
1352 | info->MCR |= SER_RTS; | 1352 | info->MCR |= SER_RTS; |
1353 | } | 1353 | } |
@@ -1358,7 +1358,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1358 | 1358 | ||
1359 | /* Handle turning off CRTSCTS */ | 1359 | /* Handle turning off CRTSCTS */ |
1360 | if ((old_termios->c_cflag & CRTSCTS) && | 1360 | if ((old_termios->c_cflag & CRTSCTS) && |
1361 | !(tty->termios->c_cflag & CRTSCTS)) { | 1361 | !(tty->termios.c_cflag & CRTSCTS)) { |
1362 | tty->hw_stopped = 0; | 1362 | tty->hw_stopped = 0; |
1363 | rs_start(tty); | 1363 | rs_start(tty); |
1364 | } | 1364 | } |
@@ -1371,7 +1371,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
1371 | * or not. Hence, this may change..... | 1371 | * or not. Hence, this may change..... |
1372 | */ | 1372 | */ |
1373 | if (!(old_termios->c_cflag & CLOCAL) && | 1373 | if (!(old_termios->c_cflag & CLOCAL) && |
1374 | (tty->termios->c_cflag & CLOCAL)) | 1374 | (tty->termios.c_cflag & CLOCAL)) |
1375 | wake_up_interruptible(&info->open_wait); | 1375 | wake_up_interruptible(&info->open_wait); |
1376 | #endif | 1376 | #endif |
1377 | } | 1377 | } |
@@ -1710,10 +1710,6 @@ static int __init amiga_serial_probe(struct platform_device *pdev) | |||
1710 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 1710 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
1711 | tty_set_operations(serial_driver, &serial_ops); | 1711 | tty_set_operations(serial_driver, &serial_ops); |
1712 | 1712 | ||
1713 | error = tty_register_driver(serial_driver); | ||
1714 | if (error) | ||
1715 | goto fail_put_tty_driver; | ||
1716 | |||
1717 | state = rs_table; | 1713 | state = rs_table; |
1718 | state->port = (int)&custom.serdatr; /* Just to give it a value */ | 1714 | state->port = (int)&custom.serdatr; /* Just to give it a value */ |
1719 | state->custom_divisor = 0; | 1715 | state->custom_divisor = 0; |
@@ -1724,6 +1720,11 @@ static int __init amiga_serial_probe(struct platform_device *pdev) | |||
1724 | state->icount.overrun = state->icount.brk = 0; | 1720 | state->icount.overrun = state->icount.brk = 0; |
1725 | tty_port_init(&state->tport); | 1721 | tty_port_init(&state->tport); |
1726 | state->tport.ops = &amiga_port_ops; | 1722 | state->tport.ops = &amiga_port_ops; |
1723 | tty_port_link_device(&state->tport, serial_driver, 0); | ||
1724 | |||
1725 | error = tty_register_driver(serial_driver); | ||
1726 | if (error) | ||
1727 | goto fail_put_tty_driver; | ||
1727 | 1728 | ||
1728 | printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n"); | 1729 | printk(KERN_INFO "ttyS0 is the amiga builtin serial port\n"); |
1729 | 1730 | ||
diff --git a/drivers/tty/bfin_jtag_comm.c b/drivers/tty/bfin_jtag_comm.c index 61fc74fe1747..02b7d3a09696 100644 --- a/drivers/tty/bfin_jtag_comm.c +++ b/drivers/tty/bfin_jtag_comm.c | |||
@@ -263,6 +263,7 @@ static int __init bfin_jc_init(void) | |||
263 | bfin_jc_driver->subtype = SERIAL_TYPE_NORMAL; | 263 | bfin_jc_driver->subtype = SERIAL_TYPE_NORMAL; |
264 | bfin_jc_driver->init_termios = tty_std_termios; | 264 | bfin_jc_driver->init_termios = tty_std_termios; |
265 | tty_set_operations(bfin_jc_driver, &bfin_jc_ops); | 265 | tty_set_operations(bfin_jc_driver, &bfin_jc_ops); |
266 | tty_port_link_device(&port, bfin_jc_driver, 0); | ||
266 | 267 | ||
267 | ret = tty_register_driver(bfin_jc_driver); | 268 | ret = tty_register_driver(bfin_jc_driver); |
268 | if (ret) | 269 | if (ret) |
diff --git a/drivers/tty/cyclades.c b/drivers/tty/cyclades.c index e61cabdd69df..0a6a0bc1b598 100644 --- a/drivers/tty/cyclades.c +++ b/drivers/tty/cyclades.c | |||
@@ -727,7 +727,7 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip, | |||
727 | else | 727 | else |
728 | tty_hangup(tty); | 728 | tty_hangup(tty); |
729 | } | 729 | } |
730 | if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) { | 730 | if ((mdm_change & CyCTS) && tty_port_cts_enabled(&info->port)) { |
731 | if (tty->hw_stopped) { | 731 | if (tty->hw_stopped) { |
732 | if (mdm_status & CyCTS) { | 732 | if (mdm_status & CyCTS) { |
733 | /* cy_start isn't used | 733 | /* cy_start isn't used |
@@ -1459,7 +1459,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1459 | info->port.xmit_buf = NULL; | 1459 | info->port.xmit_buf = NULL; |
1460 | free_page((unsigned long)temp); | 1460 | free_page((unsigned long)temp); |
1461 | } | 1461 | } |
1462 | if (tty->termios->c_cflag & HUPCL) | 1462 | if (tty->termios.c_cflag & HUPCL) |
1463 | cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); | 1463 | cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR); |
1464 | 1464 | ||
1465 | cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); | 1465 | cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR); |
@@ -1488,7 +1488,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty) | |||
1488 | free_page((unsigned long)temp); | 1488 | free_page((unsigned long)temp); |
1489 | } | 1489 | } |
1490 | 1490 | ||
1491 | if (tty->termios->c_cflag & HUPCL) | 1491 | if (tty->termios.c_cflag & HUPCL) |
1492 | tty_port_lower_dtr_rts(&info->port); | 1492 | tty_port_lower_dtr_rts(&info->port); |
1493 | 1493 | ||
1494 | set_bit(TTY_IO_ERROR, &tty->flags); | 1494 | set_bit(TTY_IO_ERROR, &tty->flags); |
@@ -1599,7 +1599,7 @@ static int cy_open(struct tty_struct *tty, struct file *filp) | |||
1599 | * If the port is the middle of closing, bail out now | 1599 | * If the port is the middle of closing, bail out now |
1600 | */ | 1600 | */ |
1601 | if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { | 1601 | if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) { |
1602 | wait_event_interruptible_tty(info->port.close_wait, | 1602 | wait_event_interruptible_tty(tty, info->port.close_wait, |
1603 | !(info->port.flags & ASYNC_CLOSING)); | 1603 | !(info->port.flags & ASYNC_CLOSING)); |
1604 | return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; | 1604 | return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; |
1605 | } | 1605 | } |
@@ -1999,14 +1999,11 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty) | |||
1999 | int baud, baud_rate = 0; | 1999 | int baud, baud_rate = 0; |
2000 | int i; | 2000 | int i; |
2001 | 2001 | ||
2002 | if (!tty->termios) /* XXX can this happen at all? */ | ||
2003 | return; | ||
2004 | |||
2005 | if (info->line == -1) | 2002 | if (info->line == -1) |
2006 | return; | 2003 | return; |
2007 | 2004 | ||
2008 | cflag = tty->termios->c_cflag; | 2005 | cflag = tty->termios.c_cflag; |
2009 | iflag = tty->termios->c_iflag; | 2006 | iflag = tty->termios.c_iflag; |
2010 | 2007 | ||
2011 | /* | 2008 | /* |
2012 | * Set up the tty->alt_speed kludge | 2009 | * Set up the tty->alt_speed kludge |
@@ -2825,7 +2822,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
2825 | cy_set_line_char(info, tty); | 2822 | cy_set_line_char(info, tty); |
2826 | 2823 | ||
2827 | if ((old_termios->c_cflag & CRTSCTS) && | 2824 | if ((old_termios->c_cflag & CRTSCTS) && |
2828 | !(tty->termios->c_cflag & CRTSCTS)) { | 2825 | !(tty->termios.c_cflag & CRTSCTS)) { |
2829 | tty->hw_stopped = 0; | 2826 | tty->hw_stopped = 0; |
2830 | cy_start(tty); | 2827 | cy_start(tty); |
2831 | } | 2828 | } |
@@ -2837,7 +2834,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
2837 | * or not. Hence, this may change..... | 2834 | * or not. Hence, this may change..... |
2838 | */ | 2835 | */ |
2839 | if (!(old_termios->c_cflag & CLOCAL) && | 2836 | if (!(old_termios->c_cflag & CLOCAL) && |
2840 | (tty->termios->c_cflag & CLOCAL)) | 2837 | (tty->termios.c_cflag & CLOCAL)) |
2841 | wake_up_interruptible(&info->port.open_wait); | 2838 | wake_up_interruptible(&info->port.open_wait); |
2842 | #endif | 2839 | #endif |
2843 | } /* cy_set_termios */ | 2840 | } /* cy_set_termios */ |
@@ -2899,7 +2896,7 @@ static void cy_throttle(struct tty_struct *tty) | |||
2899 | info->throttle = 1; | 2896 | info->throttle = 1; |
2900 | } | 2897 | } |
2901 | 2898 | ||
2902 | if (tty->termios->c_cflag & CRTSCTS) { | 2899 | if (tty->termios.c_cflag & CRTSCTS) { |
2903 | if (!cy_is_Z(card)) { | 2900 | if (!cy_is_Z(card)) { |
2904 | spin_lock_irqsave(&card->card_lock, flags); | 2901 | spin_lock_irqsave(&card->card_lock, flags); |
2905 | cyy_change_rts_dtr(info, 0, TIOCM_RTS); | 2902 | cyy_change_rts_dtr(info, 0, TIOCM_RTS); |
@@ -2938,7 +2935,7 @@ static void cy_unthrottle(struct tty_struct *tty) | |||
2938 | cy_send_xchar(tty, START_CHAR(tty)); | 2935 | cy_send_xchar(tty, START_CHAR(tty)); |
2939 | } | 2936 | } |
2940 | 2937 | ||
2941 | if (tty->termios->c_cflag & CRTSCTS) { | 2938 | if (tty->termios.c_cflag & CRTSCTS) { |
2942 | card = info->card; | 2939 | card = info->card; |
2943 | if (!cy_is_Z(card)) { | 2940 | if (!cy_is_Z(card)) { |
2944 | spin_lock_irqsave(&card->card_lock, flags); | 2941 | spin_lock_irqsave(&card->card_lock, flags); |
@@ -3289,9 +3286,10 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr, | |||
3289 | static int __init cy_detect_isa(void) | 3286 | static int __init cy_detect_isa(void) |
3290 | { | 3287 | { |
3291 | #ifdef CONFIG_ISA | 3288 | #ifdef CONFIG_ISA |
3289 | struct cyclades_card *card; | ||
3292 | unsigned short cy_isa_irq, nboard; | 3290 | unsigned short cy_isa_irq, nboard; |
3293 | void __iomem *cy_isa_address; | 3291 | void __iomem *cy_isa_address; |
3294 | unsigned short i, j, cy_isa_nchan; | 3292 | unsigned short i, j, k, cy_isa_nchan; |
3295 | int isparam = 0; | 3293 | int isparam = 0; |
3296 | 3294 | ||
3297 | nboard = 0; | 3295 | nboard = 0; |
@@ -3349,7 +3347,8 @@ static int __init cy_detect_isa(void) | |||
3349 | } | 3347 | } |
3350 | /* fill the next cy_card structure available */ | 3348 | /* fill the next cy_card structure available */ |
3351 | for (j = 0; j < NR_CARDS; j++) { | 3349 | for (j = 0; j < NR_CARDS; j++) { |
3352 | if (cy_card[j].base_addr == NULL) | 3350 | card = &cy_card[j]; |
3351 | if (card->base_addr == NULL) | ||
3353 | break; | 3352 | break; |
3354 | } | 3353 | } |
3355 | if (j == NR_CARDS) { /* no more cy_cards available */ | 3354 | if (j == NR_CARDS) { /* no more cy_cards available */ |
@@ -3363,7 +3362,7 @@ static int __init cy_detect_isa(void) | |||
3363 | 3362 | ||
3364 | /* allocate IRQ */ | 3363 | /* allocate IRQ */ |
3365 | if (request_irq(cy_isa_irq, cyy_interrupt, | 3364 | if (request_irq(cy_isa_irq, cyy_interrupt, |
3366 | 0, "Cyclom-Y", &cy_card[j])) { | 3365 | 0, "Cyclom-Y", card)) { |
3367 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " | 3366 | printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but " |
3368 | "could not allocate IRQ#%d.\n", | 3367 | "could not allocate IRQ#%d.\n", |
3369 | (unsigned long)cy_isa_address, cy_isa_irq); | 3368 | (unsigned long)cy_isa_address, cy_isa_irq); |
@@ -3372,16 +3371,16 @@ static int __init cy_detect_isa(void) | |||
3372 | } | 3371 | } |
3373 | 3372 | ||
3374 | /* set cy_card */ | 3373 | /* set cy_card */ |
3375 | cy_card[j].base_addr = cy_isa_address; | 3374 | card->base_addr = cy_isa_address; |
3376 | cy_card[j].ctl_addr.p9050 = NULL; | 3375 | card->ctl_addr.p9050 = NULL; |
3377 | cy_card[j].irq = (int)cy_isa_irq; | 3376 | card->irq = (int)cy_isa_irq; |
3378 | cy_card[j].bus_index = 0; | 3377 | card->bus_index = 0; |
3379 | cy_card[j].first_line = cy_next_channel; | 3378 | card->first_line = cy_next_channel; |
3380 | cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP; | 3379 | card->num_chips = cy_isa_nchan / CyPORTS_PER_CHIP; |
3381 | cy_card[j].nports = cy_isa_nchan; | 3380 | card->nports = cy_isa_nchan; |
3382 | if (cy_init_card(&cy_card[j])) { | 3381 | if (cy_init_card(card)) { |
3383 | cy_card[j].base_addr = NULL; | 3382 | card->base_addr = NULL; |
3384 | free_irq(cy_isa_irq, &cy_card[j]); | 3383 | free_irq(cy_isa_irq, card); |
3385 | iounmap(cy_isa_address); | 3384 | iounmap(cy_isa_address); |
3386 | continue; | 3385 | continue; |
3387 | } | 3386 | } |
@@ -3393,9 +3392,10 @@ static int __init cy_detect_isa(void) | |||
3393 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), | 3392 | (unsigned long)(cy_isa_address + (CyISA_Ywin - 1)), |
3394 | cy_isa_irq, cy_isa_nchan, cy_next_channel); | 3393 | cy_isa_irq, cy_isa_nchan, cy_next_channel); |
3395 | 3394 | ||
3396 | for (j = cy_next_channel; | 3395 | for (k = 0, j = cy_next_channel; |
3397 | j < cy_next_channel + cy_isa_nchan; j++) | 3396 | j < cy_next_channel + cy_isa_nchan; j++, k++) |
3398 | tty_register_device(cy_serial_driver, j, NULL); | 3397 | tty_port_register_device(&card->ports[k].port, |
3398 | cy_serial_driver, j, NULL); | ||
3399 | cy_next_channel += cy_isa_nchan; | 3399 | cy_next_channel += cy_isa_nchan; |
3400 | } | 3400 | } |
3401 | return nboard; | 3401 | return nboard; |
@@ -3695,10 +3695,11 @@ err: | |||
3695 | static int __devinit cy_pci_probe(struct pci_dev *pdev, | 3695 | static int __devinit cy_pci_probe(struct pci_dev *pdev, |
3696 | const struct pci_device_id *ent) | 3696 | const struct pci_device_id *ent) |
3697 | { | 3697 | { |
3698 | struct cyclades_card *card; | ||
3698 | void __iomem *addr0 = NULL, *addr2 = NULL; | 3699 | void __iomem *addr0 = NULL, *addr2 = NULL; |
3699 | char *card_name = NULL; | 3700 | char *card_name = NULL; |
3700 | u32 uninitialized_var(mailbox); | 3701 | u32 uninitialized_var(mailbox); |
3701 | unsigned int device_id, nchan = 0, card_no, i; | 3702 | unsigned int device_id, nchan = 0, card_no, i, j; |
3702 | unsigned char plx_ver; | 3703 | unsigned char plx_ver; |
3703 | int retval, irq; | 3704 | int retval, irq; |
3704 | 3705 | ||
@@ -3829,7 +3830,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
3829 | } | 3830 | } |
3830 | /* fill the next cy_card structure available */ | 3831 | /* fill the next cy_card structure available */ |
3831 | for (card_no = 0; card_no < NR_CARDS; card_no++) { | 3832 | for (card_no = 0; card_no < NR_CARDS; card_no++) { |
3832 | if (cy_card[card_no].base_addr == NULL) | 3833 | card = &cy_card[card_no]; |
3834 | if (card->base_addr == NULL) | ||
3833 | break; | 3835 | break; |
3834 | } | 3836 | } |
3835 | if (card_no == NR_CARDS) { /* no more cy_cards available */ | 3837 | if (card_no == NR_CARDS) { /* no more cy_cards available */ |
@@ -3843,27 +3845,26 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
3843 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 3845 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
3844 | /* allocate IRQ */ | 3846 | /* allocate IRQ */ |
3845 | retval = request_irq(irq, cyy_interrupt, | 3847 | retval = request_irq(irq, cyy_interrupt, |
3846 | IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]); | 3848 | IRQF_SHARED, "Cyclom-Y", card); |
3847 | if (retval) { | 3849 | if (retval) { |
3848 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | 3850 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
3849 | goto err_unmap; | 3851 | goto err_unmap; |
3850 | } | 3852 | } |
3851 | cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP; | 3853 | card->num_chips = nchan / CyPORTS_PER_CHIP; |
3852 | } else { | 3854 | } else { |
3853 | struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS; | 3855 | struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS; |
3854 | struct ZFW_CTRL __iomem *zfw_ctrl; | 3856 | struct ZFW_CTRL __iomem *zfw_ctrl; |
3855 | 3857 | ||
3856 | zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff); | 3858 | zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff); |
3857 | 3859 | ||
3858 | cy_card[card_no].hw_ver = mailbox; | 3860 | card->hw_ver = mailbox; |
3859 | cy_card[card_no].num_chips = (unsigned int)-1; | 3861 | card->num_chips = (unsigned int)-1; |
3860 | cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl; | 3862 | card->board_ctrl = &zfw_ctrl->board_ctrl; |
3861 | #ifdef CONFIG_CYZ_INTR | 3863 | #ifdef CONFIG_CYZ_INTR |
3862 | /* allocate IRQ only if board has an IRQ */ | 3864 | /* allocate IRQ only if board has an IRQ */ |
3863 | if (irq != 0 && irq != 255) { | 3865 | if (irq != 0 && irq != 255) { |
3864 | retval = request_irq(irq, cyz_interrupt, | 3866 | retval = request_irq(irq, cyz_interrupt, |
3865 | IRQF_SHARED, "Cyclades-Z", | 3867 | IRQF_SHARED, "Cyclades-Z", card); |
3866 | &cy_card[card_no]); | ||
3867 | if (retval) { | 3868 | if (retval) { |
3868 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | 3869 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
3869 | goto err_unmap; | 3870 | goto err_unmap; |
@@ -3873,17 +3874,17 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
3873 | } | 3874 | } |
3874 | 3875 | ||
3875 | /* set cy_card */ | 3876 | /* set cy_card */ |
3876 | cy_card[card_no].base_addr = addr2; | 3877 | card->base_addr = addr2; |
3877 | cy_card[card_no].ctl_addr.p9050 = addr0; | 3878 | card->ctl_addr.p9050 = addr0; |
3878 | cy_card[card_no].irq = irq; | 3879 | card->irq = irq; |
3879 | cy_card[card_no].bus_index = 1; | 3880 | card->bus_index = 1; |
3880 | cy_card[card_no].first_line = cy_next_channel; | 3881 | card->first_line = cy_next_channel; |
3881 | cy_card[card_no].nports = nchan; | 3882 | card->nports = nchan; |
3882 | retval = cy_init_card(&cy_card[card_no]); | 3883 | retval = cy_init_card(card); |
3883 | if (retval) | 3884 | if (retval) |
3884 | goto err_null; | 3885 | goto err_null; |
3885 | 3886 | ||
3886 | pci_set_drvdata(pdev, &cy_card[card_no]); | 3887 | pci_set_drvdata(pdev, card); |
3887 | 3888 | ||
3888 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || | 3889 | if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo || |
3889 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { | 3890 | device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) { |
@@ -3909,14 +3910,15 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev, | |||
3909 | 3910 | ||
3910 | dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " | 3911 | dev_info(&pdev->dev, "%s/PCI #%d found: %d channels starting from " |
3911 | "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); | 3912 | "port %d.\n", card_name, card_no + 1, nchan, cy_next_channel); |
3912 | for (i = cy_next_channel; i < cy_next_channel + nchan; i++) | 3913 | for (j = 0, i = cy_next_channel; i < cy_next_channel + nchan; i++, j++) |
3913 | tty_register_device(cy_serial_driver, i, &pdev->dev); | 3914 | tty_port_register_device(&card->ports[j].port, |
3915 | cy_serial_driver, i, &pdev->dev); | ||
3914 | cy_next_channel += nchan; | 3916 | cy_next_channel += nchan; |
3915 | 3917 | ||
3916 | return 0; | 3918 | return 0; |
3917 | err_null: | 3919 | err_null: |
3918 | cy_card[card_no].base_addr = NULL; | 3920 | card->base_addr = NULL; |
3919 | free_irq(irq, &cy_card[card_no]); | 3921 | free_irq(irq, card); |
3920 | err_unmap: | 3922 | err_unmap: |
3921 | iounmap(addr0); | 3923 | iounmap(addr0); |
3922 | if (addr2) | 3924 | if (addr2) |
diff --git a/drivers/tty/ehv_bytechan.c b/drivers/tty/ehv_bytechan.c index 4813684cb634..4ab936b7aac6 100644 --- a/drivers/tty/ehv_bytechan.c +++ b/drivers/tty/ehv_bytechan.c | |||
@@ -738,16 +738,17 @@ static int __devinit ehv_bc_tty_probe(struct platform_device *pdev) | |||
738 | goto error; | 738 | goto error; |
739 | } | 739 | } |
740 | 740 | ||
741 | bc->dev = tty_register_device(ehv_bc_driver, i, &pdev->dev); | 741 | tty_port_init(&bc->port); |
742 | bc->port.ops = &ehv_bc_tty_port_ops; | ||
743 | |||
744 | bc->dev = tty_port_register_device(&bc->port, ehv_bc_driver, i, | ||
745 | &pdev->dev); | ||
742 | if (IS_ERR(bc->dev)) { | 746 | if (IS_ERR(bc->dev)) { |
743 | ret = PTR_ERR(bc->dev); | 747 | ret = PTR_ERR(bc->dev); |
744 | dev_err(&pdev->dev, "could not register tty (ret=%i)\n", ret); | 748 | dev_err(&pdev->dev, "could not register tty (ret=%i)\n", ret); |
745 | goto error; | 749 | goto error; |
746 | } | 750 | } |
747 | 751 | ||
748 | tty_port_init(&bc->port); | ||
749 | bc->port.ops = &ehv_bc_tty_port_ops; | ||
750 | |||
751 | dev_set_drvdata(&pdev->dev, bc); | 752 | dev_set_drvdata(&pdev->dev, bc); |
752 | 753 | ||
753 | dev_info(&pdev->dev, "registered /dev/%s%u for byte channel %u\n", | 754 | dev_info(&pdev->dev, "registered /dev/%s%u for byte channel %u\n", |
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 2d691eb7c40a..7f80f15681cd 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
@@ -299,20 +299,33 @@ static void hvc_unthrottle(struct tty_struct *tty) | |||
299 | hvc_kick(); | 299 | hvc_kick(); |
300 | } | 300 | } |
301 | 301 | ||
302 | static int hvc_install(struct tty_driver *driver, struct tty_struct *tty) | ||
303 | { | ||
304 | struct hvc_struct *hp; | ||
305 | int rc; | ||
306 | |||
307 | /* Auto increments kref reference if found. */ | ||
308 | if (!(hp = hvc_get_by_index(tty->index))) | ||
309 | return -ENODEV; | ||
310 | |||
311 | tty->driver_data = hp; | ||
312 | |||
313 | rc = tty_port_install(&hp->port, driver, tty); | ||
314 | if (rc) | ||
315 | tty_port_put(&hp->port); | ||
316 | return rc; | ||
317 | } | ||
318 | |||
302 | /* | 319 | /* |
303 | * The TTY interface won't be used until after the vio layer has exposed the vty | 320 | * The TTY interface won't be used until after the vio layer has exposed the vty |
304 | * adapter to the kernel. | 321 | * adapter to the kernel. |
305 | */ | 322 | */ |
306 | static int hvc_open(struct tty_struct *tty, struct file * filp) | 323 | static int hvc_open(struct tty_struct *tty, struct file * filp) |
307 | { | 324 | { |
308 | struct hvc_struct *hp; | 325 | struct hvc_struct *hp = tty->driver_data; |
309 | unsigned long flags; | 326 | unsigned long flags; |
310 | int rc = 0; | 327 | int rc = 0; |
311 | 328 | ||
312 | /* Auto increments kref reference if found. */ | ||
313 | if (!(hp = hvc_get_by_index(tty->index))) | ||
314 | return -ENODEV; | ||
315 | |||
316 | spin_lock_irqsave(&hp->port.lock, flags); | 329 | spin_lock_irqsave(&hp->port.lock, flags); |
317 | /* Check and then increment for fast path open. */ | 330 | /* Check and then increment for fast path open. */ |
318 | if (hp->port.count++ > 0) { | 331 | if (hp->port.count++ > 0) { |
@@ -322,7 +335,6 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) | |||
322 | } /* else count == 0 */ | 335 | } /* else count == 0 */ |
323 | spin_unlock_irqrestore(&hp->port.lock, flags); | 336 | spin_unlock_irqrestore(&hp->port.lock, flags); |
324 | 337 | ||
325 | tty->driver_data = hp; | ||
326 | tty_port_tty_set(&hp->port, tty); | 338 | tty_port_tty_set(&hp->port, tty); |
327 | 339 | ||
328 | if (hp->ops->notifier_add) | 340 | if (hp->ops->notifier_add) |
@@ -389,6 +401,11 @@ static void hvc_close(struct tty_struct *tty, struct file * filp) | |||
389 | hp->vtermno, hp->port.count); | 401 | hp->vtermno, hp->port.count); |
390 | spin_unlock_irqrestore(&hp->port.lock, flags); | 402 | spin_unlock_irqrestore(&hp->port.lock, flags); |
391 | } | 403 | } |
404 | } | ||
405 | |||
406 | static void hvc_cleanup(struct tty_struct *tty) | ||
407 | { | ||
408 | struct hvc_struct *hp = tty->driver_data; | ||
392 | 409 | ||
393 | tty_port_put(&hp->port); | 410 | tty_port_put(&hp->port); |
394 | } | 411 | } |
@@ -792,8 +809,10 @@ static void hvc_poll_put_char(struct tty_driver *driver, int line, char ch) | |||
792 | #endif | 809 | #endif |
793 | 810 | ||
794 | static const struct tty_operations hvc_ops = { | 811 | static const struct tty_operations hvc_ops = { |
812 | .install = hvc_install, | ||
795 | .open = hvc_open, | 813 | .open = hvc_open, |
796 | .close = hvc_close, | 814 | .close = hvc_close, |
815 | .cleanup = hvc_cleanup, | ||
797 | .write = hvc_write, | 816 | .write = hvc_write, |
798 | .hangup = hvc_hangup, | 817 | .hangup = hvc_hangup, |
799 | .unthrottle = hvc_unthrottle, | 818 | .unthrottle = hvc_unthrottle, |
diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index d56788c83974..cab5c7adf8e8 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c | |||
@@ -1102,27 +1102,20 @@ static struct hvcs_struct *hvcs_get_by_index(int index) | |||
1102 | return NULL; | 1102 | return NULL; |
1103 | } | 1103 | } |
1104 | 1104 | ||
1105 | /* | 1105 | static int hvcs_install(struct tty_driver *driver, struct tty_struct *tty) |
1106 | * This is invoked via the tty_open interface when a user app connects to the | ||
1107 | * /dev node. | ||
1108 | */ | ||
1109 | static int hvcs_open(struct tty_struct *tty, struct file *filp) | ||
1110 | { | 1106 | { |
1111 | struct hvcs_struct *hvcsd; | 1107 | struct hvcs_struct *hvcsd; |
1112 | int rc, retval = 0; | ||
1113 | unsigned long flags; | ||
1114 | unsigned int irq; | ||
1115 | struct vio_dev *vdev; | 1108 | struct vio_dev *vdev; |
1116 | unsigned long unit_address; | 1109 | unsigned long unit_address, flags; |
1117 | 1110 | unsigned int irq; | |
1118 | if (tty->driver_data) | 1111 | int retval; |
1119 | goto fast_open; | ||
1120 | 1112 | ||
1121 | /* | 1113 | /* |
1122 | * Is there a vty-server that shares the same index? | 1114 | * Is there a vty-server that shares the same index? |
1123 | * This function increments the kref index. | 1115 | * This function increments the kref index. |
1124 | */ | 1116 | */ |
1125 | if (!(hvcsd = hvcs_get_by_index(tty->index))) { | 1117 | hvcsd = hvcs_get_by_index(tty->index); |
1118 | if (!hvcsd) { | ||
1126 | printk(KERN_WARNING "HVCS: open failed, no device associated" | 1119 | printk(KERN_WARNING "HVCS: open failed, no device associated" |
1127 | " with tty->index %d.\n", tty->index); | 1120 | " with tty->index %d.\n", tty->index); |
1128 | return -ENODEV; | 1121 | return -ENODEV; |
@@ -1130,11 +1123,16 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) | |||
1130 | 1123 | ||
1131 | spin_lock_irqsave(&hvcsd->lock, flags); | 1124 | spin_lock_irqsave(&hvcsd->lock, flags); |
1132 | 1125 | ||
1133 | if (hvcsd->connected == 0) | 1126 | if (hvcsd->connected == 0) { |
1134 | if ((retval = hvcs_partner_connect(hvcsd))) | 1127 | retval = hvcs_partner_connect(hvcsd); |
1135 | goto error_release; | 1128 | if (retval) { |
1129 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1130 | printk(KERN_WARNING "HVCS: partner connect failed.\n"); | ||
1131 | goto err_put; | ||
1132 | } | ||
1133 | } | ||
1136 | 1134 | ||
1137 | hvcsd->port.count = 1; | 1135 | hvcsd->port.count = 0; |
1138 | hvcsd->port.tty = tty; | 1136 | hvcsd->port.tty = tty; |
1139 | tty->driver_data = hvcsd; | 1137 | tty->driver_data = hvcsd; |
1140 | 1138 | ||
@@ -1155,37 +1153,48 @@ static int hvcs_open(struct tty_struct *tty, struct file *filp) | |||
1155 | * This must be done outside of the spinlock because it requests irqs | 1153 | * This must be done outside of the spinlock because it requests irqs |
1156 | * and will grab the spinlock and free the connection if it fails. | 1154 | * and will grab the spinlock and free the connection if it fails. |
1157 | */ | 1155 | */ |
1158 | if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) { | 1156 | retval = hvcs_enable_device(hvcsd, unit_address, irq, vdev); |
1159 | tty_port_put(&hvcsd->port); | 1157 | if (retval) { |
1160 | printk(KERN_WARNING "HVCS: enable device failed.\n"); | 1158 | printk(KERN_WARNING "HVCS: enable device failed.\n"); |
1161 | return rc; | 1159 | goto err_put; |
1162 | } | 1160 | } |
1163 | 1161 | ||
1164 | goto open_success; | 1162 | retval = tty_port_install(&hvcsd->port, driver, tty); |
1163 | if (retval) | ||
1164 | goto err_irq; | ||
1165 | 1165 | ||
1166 | fast_open: | 1166 | return 0; |
1167 | hvcsd = tty->driver_data; | 1167 | err_irq: |
1168 | spin_lock_irqsave(&hvcsd->lock, flags); | ||
1169 | vio_disable_interrupts(hvcsd->vdev); | ||
1170 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1171 | free_irq(irq, hvcsd); | ||
1172 | err_put: | ||
1173 | tty_port_put(&hvcsd->port); | ||
1174 | |||
1175 | return retval; | ||
1176 | } | ||
1177 | |||
1178 | /* | ||
1179 | * This is invoked via the tty_open interface when a user app connects to the | ||
1180 | * /dev node. | ||
1181 | */ | ||
1182 | static int hvcs_open(struct tty_struct *tty, struct file *filp) | ||
1183 | { | ||
1184 | struct hvcs_struct *hvcsd = tty->driver_data; | ||
1185 | unsigned long flags; | ||
1168 | 1186 | ||
1169 | spin_lock_irqsave(&hvcsd->lock, flags); | 1187 | spin_lock_irqsave(&hvcsd->lock, flags); |
1170 | tty_port_get(&hvcsd->port); | ||
1171 | hvcsd->port.count++; | 1188 | hvcsd->port.count++; |
1172 | hvcsd->todo_mask |= HVCS_SCHED_READ; | 1189 | hvcsd->todo_mask |= HVCS_SCHED_READ; |
1173 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1190 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
1174 | 1191 | ||
1175 | open_success: | ||
1176 | hvcs_kick(); | 1192 | hvcs_kick(); |
1177 | 1193 | ||
1178 | printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n", | 1194 | printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n", |
1179 | hvcsd->vdev->unit_address ); | 1195 | hvcsd->vdev->unit_address ); |
1180 | 1196 | ||
1181 | return 0; | 1197 | return 0; |
1182 | |||
1183 | error_release: | ||
1184 | spin_unlock_irqrestore(&hvcsd->lock, flags); | ||
1185 | tty_port_put(&hvcsd->port); | ||
1186 | |||
1187 | printk(KERN_WARNING "HVCS: partner connect failed.\n"); | ||
1188 | return retval; | ||
1189 | } | 1198 | } |
1190 | 1199 | ||
1191 | static void hvcs_close(struct tty_struct *tty, struct file *filp) | 1200 | static void hvcs_close(struct tty_struct *tty, struct file *filp) |
@@ -1236,7 +1245,6 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
1236 | tty->driver_data = NULL; | 1245 | tty->driver_data = NULL; |
1237 | 1246 | ||
1238 | free_irq(irq, hvcsd); | 1247 | free_irq(irq, hvcsd); |
1239 | tty_port_put(&hvcsd->port); | ||
1240 | return; | 1248 | return; |
1241 | } else if (hvcsd->port.count < 0) { | 1249 | } else if (hvcsd->port.count < 0) { |
1242 | printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" | 1250 | printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" |
@@ -1245,6 +1253,12 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) | |||
1245 | } | 1253 | } |
1246 | 1254 | ||
1247 | spin_unlock_irqrestore(&hvcsd->lock, flags); | 1255 | spin_unlock_irqrestore(&hvcsd->lock, flags); |
1256 | } | ||
1257 | |||
1258 | static void hvcs_cleanup(struct tty_struct * tty) | ||
1259 | { | ||
1260 | struct hvcs_struct *hvcsd = tty->driver_data; | ||
1261 | |||
1248 | tty_port_put(&hvcsd->port); | 1262 | tty_port_put(&hvcsd->port); |
1249 | } | 1263 | } |
1250 | 1264 | ||
@@ -1431,8 +1445,10 @@ static int hvcs_chars_in_buffer(struct tty_struct *tty) | |||
1431 | } | 1445 | } |
1432 | 1446 | ||
1433 | static const struct tty_operations hvcs_ops = { | 1447 | static const struct tty_operations hvcs_ops = { |
1448 | .install = hvcs_install, | ||
1434 | .open = hvcs_open, | 1449 | .open = hvcs_open, |
1435 | .close = hvcs_close, | 1450 | .close = hvcs_close, |
1451 | .cleanup = hvcs_cleanup, | ||
1436 | .hangup = hvcs_hangup, | 1452 | .hangup = hvcs_hangup, |
1437 | .write = hvcs_write, | 1453 | .write = hvcs_write, |
1438 | .write_room = hvcs_write_room, | 1454 | .write_room = hvcs_write_room, |
diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index 6f5bc49c441f..0083bc1f63f4 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c | |||
@@ -1080,6 +1080,8 @@ static int __init hvsi_init(void) | |||
1080 | struct hvsi_struct *hp = &hvsi_ports[i]; | 1080 | struct hvsi_struct *hp = &hvsi_ports[i]; |
1081 | int ret = 1; | 1081 | int ret = 1; |
1082 | 1082 | ||
1083 | tty_port_link_device(&hp->port, hvsi_driver, i); | ||
1084 | |||
1083 | ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); | 1085 | ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); |
1084 | if (ret) | 1086 | if (ret) |
1085 | printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", | 1087 | printk(KERN_ERR "HVSI: couldn't reserve irq 0x%x (error %i)\n", |
diff --git a/drivers/tty/hvc/hvsi_lib.c b/drivers/tty/hvc/hvsi_lib.c index 59c135dd5d20..3396eb9d57a3 100644 --- a/drivers/tty/hvc/hvsi_lib.c +++ b/drivers/tty/hvc/hvsi_lib.c | |||
@@ -400,7 +400,7 @@ void hvsilib_close(struct hvsi_priv *pv, struct hvc_struct *hp) | |||
400 | spin_unlock_irqrestore(&hp->lock, flags); | 400 | spin_unlock_irqrestore(&hp->lock, flags); |
401 | 401 | ||
402 | /* Clear our own DTR */ | 402 | /* Clear our own DTR */ |
403 | if (!pv->tty || (pv->tty->termios->c_cflag & HUPCL)) | 403 | if (!pv->tty || (pv->tty->termios.c_cflag & HUPCL)) |
404 | hvsilib_write_mctrl(pv, 0); | 404 | hvsilib_write_mctrl(pv, 0); |
405 | 405 | ||
406 | /* Tear down the connection */ | 406 | /* Tear down the connection */ |
diff --git a/drivers/tty/ipwireless/tty.c b/drivers/tty/ipwireless/tty.c index f8b5fa0093a3..160f0ad9589d 100644 --- a/drivers/tty/ipwireless/tty.c +++ b/drivers/tty/ipwireless/tty.c | |||
@@ -476,7 +476,7 @@ static int add_tty(int j, | |||
476 | mutex_init(&ttys[j]->ipw_tty_mutex); | 476 | mutex_init(&ttys[j]->ipw_tty_mutex); |
477 | tty_port_init(&ttys[j]->port); | 477 | tty_port_init(&ttys[j]->port); |
478 | 478 | ||
479 | tty_register_device(ipw_tty_driver, j, NULL); | 479 | tty_port_register_device(&ttys[j]->port, ipw_tty_driver, j, NULL); |
480 | ipwireless_associate_network_tty(network, channel_idx, ttys[j]); | 480 | ipwireless_associate_network_tty(network, channel_idx, ttys[j]); |
481 | 481 | ||
482 | if (secondary_channel_idx != -1) | 482 | if (secondary_channel_idx != -1) |
diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index e1235accab74..d7492e183607 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c | |||
@@ -600,7 +600,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id) | |||
600 | port->status &= ~ISI_DCD; | 600 | port->status &= ~ISI_DCD; |
601 | } | 601 | } |
602 | 602 | ||
603 | if (port->port.flags & ASYNC_CTS_FLOW) { | 603 | if (tty_port_cts_enabled(&port->port)) { |
604 | if (tty->hw_stopped) { | 604 | if (tty->hw_stopped) { |
605 | if (header & ISI_CTS) { | 605 | if (header & ISI_CTS) { |
606 | port->port.tty->hw_stopped = 0; | 606 | port->port.tty->hw_stopped = 0; |
@@ -702,7 +702,7 @@ static void isicom_config_port(struct tty_struct *tty) | |||
702 | 702 | ||
703 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ | 703 | /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ |
704 | if (baud < 1 || baud > 4) | 704 | if (baud < 1 || baud > 4) |
705 | tty->termios->c_cflag &= ~CBAUDEX; | 705 | tty->termios.c_cflag &= ~CBAUDEX; |
706 | else | 706 | else |
707 | baud += 15; | 707 | baud += 15; |
708 | } | 708 | } |
@@ -1196,8 +1196,8 @@ static void isicom_set_termios(struct tty_struct *tty, | |||
1196 | if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) | 1196 | if (isicom_paranoia_check(port, tty->name, "isicom_set_termios")) |
1197 | return; | 1197 | return; |
1198 | 1198 | ||
1199 | if (tty->termios->c_cflag == old_termios->c_cflag && | 1199 | if (tty->termios.c_cflag == old_termios->c_cflag && |
1200 | tty->termios->c_iflag == old_termios->c_iflag) | 1200 | tty->termios.c_iflag == old_termios->c_iflag) |
1201 | return; | 1201 | return; |
1202 | 1202 | ||
1203 | spin_lock_irqsave(&port->card->card_lock, flags); | 1203 | spin_lock_irqsave(&port->card->card_lock, flags); |
@@ -1205,7 +1205,7 @@ static void isicom_set_termios(struct tty_struct *tty, | |||
1205 | spin_unlock_irqrestore(&port->card->card_lock, flags); | 1205 | spin_unlock_irqrestore(&port->card->card_lock, flags); |
1206 | 1206 | ||
1207 | if ((old_termios->c_cflag & CRTSCTS) && | 1207 | if ((old_termios->c_cflag & CRTSCTS) && |
1208 | !(tty->termios->c_cflag & CRTSCTS)) { | 1208 | !(tty->termios.c_cflag & CRTSCTS)) { |
1209 | tty->hw_stopped = 0; | 1209 | tty->hw_stopped = 0; |
1210 | isicom_start(tty); | 1210 | isicom_start(tty); |
1211 | } | 1211 | } |
@@ -1611,7 +1611,8 @@ static int __devinit isicom_probe(struct pci_dev *pdev, | |||
1611 | goto errunri; | 1611 | goto errunri; |
1612 | 1612 | ||
1613 | for (index = 0; index < board->port_count; index++) | 1613 | for (index = 0; index < board->port_count; index++) |
1614 | tty_register_device(isicom_normal, board->index * 16 + index, | 1614 | tty_port_register_device(&board->ports[index].port, |
1615 | isicom_normal, board->index * 16 + index, | ||
1615 | &pdev->dev); | 1616 | &pdev->dev); |
1616 | 1617 | ||
1617 | return 0; | 1618 | return 0; |
diff --git a/drivers/tty/moxa.c b/drivers/tty/moxa.c index 324467d28a54..56e616b9109a 100644 --- a/drivers/tty/moxa.c +++ b/drivers/tty/moxa.c | |||
@@ -169,6 +169,7 @@ static DEFINE_SPINLOCK(moxa_lock); | |||
169 | static unsigned long baseaddr[MAX_BOARDS]; | 169 | static unsigned long baseaddr[MAX_BOARDS]; |
170 | static unsigned int type[MAX_BOARDS]; | 170 | static unsigned int type[MAX_BOARDS]; |
171 | static unsigned int numports[MAX_BOARDS]; | 171 | static unsigned int numports[MAX_BOARDS]; |
172 | static struct tty_port moxa_service_port; | ||
172 | 173 | ||
173 | MODULE_AUTHOR("William Chen"); | 174 | MODULE_AUTHOR("William Chen"); |
174 | MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); | 175 | MODULE_DESCRIPTION("MOXA Intellio Family Multiport Board Device Driver"); |
@@ -367,10 +368,10 @@ static int moxa_ioctl(struct tty_struct *tty, | |||
367 | tmp.dcd = 1; | 368 | tmp.dcd = 1; |
368 | 369 | ||
369 | ttyp = tty_port_tty_get(&p->port); | 370 | ttyp = tty_port_tty_get(&p->port); |
370 | if (!ttyp || !ttyp->termios) | 371 | if (!ttyp) |
371 | tmp.cflag = p->cflag; | 372 | tmp.cflag = p->cflag; |
372 | else | 373 | else |
373 | tmp.cflag = ttyp->termios->c_cflag; | 374 | tmp.cflag = ttyp->termios.c_cflag; |
374 | tty_kref_put(ttyp); | 375 | tty_kref_put(ttyp); |
375 | copy: | 376 | copy: |
376 | if (copy_to_user(argm, &tmp, sizeof(tmp))) | 377 | if (copy_to_user(argm, &tmp, sizeof(tmp))) |
@@ -834,7 +835,7 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) | |||
834 | const struct firmware *fw; | 835 | const struct firmware *fw; |
835 | const char *file; | 836 | const char *file; |
836 | struct moxa_port *p; | 837 | struct moxa_port *p; |
837 | unsigned int i; | 838 | unsigned int i, first_idx; |
838 | int ret; | 839 | int ret; |
839 | 840 | ||
840 | brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports), | 841 | brd->ports = kcalloc(MAX_PORTS_PER_BOARD, sizeof(*brd->ports), |
@@ -887,6 +888,11 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev) | |||
887 | mod_timer(&moxaTimer, jiffies + HZ / 50); | 888 | mod_timer(&moxaTimer, jiffies + HZ / 50); |
888 | spin_unlock_bh(&moxa_lock); | 889 | spin_unlock_bh(&moxa_lock); |
889 | 890 | ||
891 | first_idx = (brd - moxa_boards) * MAX_PORTS_PER_BOARD; | ||
892 | for (i = 0; i < brd->numPorts; i++) | ||
893 | tty_port_register_device(&brd->ports[i].port, moxaDriver, | ||
894 | first_idx + i, dev); | ||
895 | |||
890 | return 0; | 896 | return 0; |
891 | err_free: | 897 | err_free: |
892 | kfree(brd->ports); | 898 | kfree(brd->ports); |
@@ -896,7 +902,7 @@ err: | |||
896 | 902 | ||
897 | static void moxa_board_deinit(struct moxa_board_conf *brd) | 903 | static void moxa_board_deinit(struct moxa_board_conf *brd) |
898 | { | 904 | { |
899 | unsigned int a, opened; | 905 | unsigned int a, opened, first_idx; |
900 | 906 | ||
901 | mutex_lock(&moxa_openlock); | 907 | mutex_lock(&moxa_openlock); |
902 | spin_lock_bh(&moxa_lock); | 908 | spin_lock_bh(&moxa_lock); |
@@ -925,6 +931,10 @@ static void moxa_board_deinit(struct moxa_board_conf *brd) | |||
925 | mutex_lock(&moxa_openlock); | 931 | mutex_lock(&moxa_openlock); |
926 | } | 932 | } |
927 | 933 | ||
934 | first_idx = (brd - moxa_boards) * MAX_PORTS_PER_BOARD; | ||
935 | for (a = 0; a < brd->numPorts; a++) | ||
936 | tty_unregister_device(moxaDriver, first_idx + a); | ||
937 | |||
928 | iounmap(brd->basemem); | 938 | iounmap(brd->basemem); |
929 | brd->basemem = NULL; | 939 | brd->basemem = NULL; |
930 | kfree(brd->ports); | 940 | kfree(brd->ports); |
@@ -967,6 +977,7 @@ static int __devinit moxa_pci_probe(struct pci_dev *pdev, | |||
967 | board->basemem = ioremap_nocache(pci_resource_start(pdev, 2), 0x4000); | 977 | board->basemem = ioremap_nocache(pci_resource_start(pdev, 2), 0x4000); |
968 | if (board->basemem == NULL) { | 978 | if (board->basemem == NULL) { |
969 | dev_err(&pdev->dev, "can't remap io space 2\n"); | 979 | dev_err(&pdev->dev, "can't remap io space 2\n"); |
980 | retval = -ENOMEM; | ||
970 | goto err_reg; | 981 | goto err_reg; |
971 | } | 982 | } |
972 | 983 | ||
@@ -1031,9 +1042,14 @@ static int __init moxa_init(void) | |||
1031 | 1042 | ||
1032 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", | 1043 | printk(KERN_INFO "MOXA Intellio family driver version %s\n", |
1033 | MOXA_VERSION); | 1044 | MOXA_VERSION); |
1034 | moxaDriver = alloc_tty_driver(MAX_PORTS + 1); | 1045 | |
1035 | if (!moxaDriver) | 1046 | tty_port_init(&moxa_service_port); |
1036 | return -ENOMEM; | 1047 | |
1048 | moxaDriver = tty_alloc_driver(MAX_PORTS + 1, | ||
1049 | TTY_DRIVER_REAL_RAW | | ||
1050 | TTY_DRIVER_DYNAMIC_DEV); | ||
1051 | if (IS_ERR(moxaDriver)) | ||
1052 | return PTR_ERR(moxaDriver); | ||
1037 | 1053 | ||
1038 | moxaDriver->name = "ttyMX"; | 1054 | moxaDriver->name = "ttyMX"; |
1039 | moxaDriver->major = ttymajor; | 1055 | moxaDriver->major = ttymajor; |
@@ -1044,8 +1060,9 @@ static int __init moxa_init(void) | |||
1044 | moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; | 1060 | moxaDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; |
1045 | moxaDriver->init_termios.c_ispeed = 9600; | 1061 | moxaDriver->init_termios.c_ispeed = 9600; |
1046 | moxaDriver->init_termios.c_ospeed = 9600; | 1062 | moxaDriver->init_termios.c_ospeed = 9600; |
1047 | moxaDriver->flags = TTY_DRIVER_REAL_RAW; | ||
1048 | tty_set_operations(moxaDriver, &moxa_ops); | 1063 | tty_set_operations(moxaDriver, &moxa_ops); |
1064 | /* Having one more port only for ioctls is ugly */ | ||
1065 | tty_port_link_device(&moxa_service_port, moxaDriver, MAX_PORTS); | ||
1049 | 1066 | ||
1050 | if (tty_register_driver(moxaDriver)) { | 1067 | if (tty_register_driver(moxaDriver)) { |
1051 | printk(KERN_ERR "can't register MOXA Smartio tty driver!\n"); | 1068 | printk(KERN_ERR "can't register MOXA Smartio tty driver!\n"); |
@@ -1178,7 +1195,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1178 | mutex_lock(&ch->port.mutex); | 1195 | mutex_lock(&ch->port.mutex); |
1179 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { | 1196 | if (!(ch->port.flags & ASYNC_INITIALIZED)) { |
1180 | ch->statusflags = 0; | 1197 | ch->statusflags = 0; |
1181 | moxa_set_tty_param(tty, tty->termios); | 1198 | moxa_set_tty_param(tty, &tty->termios); |
1182 | MoxaPortLineCtrl(ch, 1, 1); | 1199 | MoxaPortLineCtrl(ch, 1, 1); |
1183 | MoxaPortEnable(ch); | 1200 | MoxaPortEnable(ch); |
1184 | MoxaSetFifo(ch, ch->type == PORT_16550A); | 1201 | MoxaSetFifo(ch, ch->type == PORT_16550A); |
@@ -1193,7 +1210,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp) | |||
1193 | static void moxa_close(struct tty_struct *tty, struct file *filp) | 1210 | static void moxa_close(struct tty_struct *tty, struct file *filp) |
1194 | { | 1211 | { |
1195 | struct moxa_port *ch = tty->driver_data; | 1212 | struct moxa_port *ch = tty->driver_data; |
1196 | ch->cflag = tty->termios->c_cflag; | 1213 | ch->cflag = tty->termios.c_cflag; |
1197 | tty_port_close(&ch->port, tty, filp); | 1214 | tty_port_close(&ch->port, tty, filp); |
1198 | } | 1215 | } |
1199 | 1216 | ||
@@ -1464,7 +1481,7 @@ static void moxa_poll(unsigned long ignored) | |||
1464 | 1481 | ||
1465 | static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios) | 1482 | static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios) |
1466 | { | 1483 | { |
1467 | register struct ktermios *ts = tty->termios; | 1484 | register struct ktermios *ts = &tty->termios; |
1468 | struct moxa_port *ch = tty->driver_data; | 1485 | struct moxa_port *ch = tty->driver_data; |
1469 | int rts, cts, txflow, rxflow, xany, baud; | 1486 | int rts, cts, txflow, rxflow, xany, baud; |
1470 | 1487 | ||
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c index 90cc680c4f0e..cfda47dabd28 100644 --- a/drivers/tty/mxser.c +++ b/drivers/tty/mxser.c | |||
@@ -643,7 +643,7 @@ static int mxser_change_speed(struct tty_struct *tty, | |||
643 | int ret = 0; | 643 | int ret = 0; |
644 | unsigned char status; | 644 | unsigned char status; |
645 | 645 | ||
646 | cflag = tty->termios->c_cflag; | 646 | cflag = tty->termios.c_cflag; |
647 | if (!info->ioaddr) | 647 | if (!info->ioaddr) |
648 | return ret; | 648 | return ret; |
649 | 649 | ||
@@ -830,7 +830,7 @@ static void mxser_check_modem_status(struct tty_struct *tty, | |||
830 | wake_up_interruptible(&port->port.open_wait); | 830 | wake_up_interruptible(&port->port.open_wait); |
831 | } | 831 | } |
832 | 832 | ||
833 | if (port->port.flags & ASYNC_CTS_FLOW) { | 833 | if (tty_port_cts_enabled(&port->port)) { |
834 | if (tty->hw_stopped) { | 834 | if (tty->hw_stopped) { |
835 | if (status & UART_MSR_CTS) { | 835 | if (status & UART_MSR_CTS) { |
836 | tty->hw_stopped = 0; | 836 | tty->hw_stopped = 0; |
@@ -1520,10 +1520,10 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1520 | 1520 | ||
1521 | tty = tty_port_tty_get(port); | 1521 | tty = tty_port_tty_get(port); |
1522 | 1522 | ||
1523 | if (!tty || !tty->termios) | 1523 | if (!tty) |
1524 | ms.cflag = ip->normal_termios.c_cflag; | 1524 | ms.cflag = ip->normal_termios.c_cflag; |
1525 | else | 1525 | else |
1526 | ms.cflag = tty->termios->c_cflag; | 1526 | ms.cflag = tty->termios.c_cflag; |
1527 | tty_kref_put(tty); | 1527 | tty_kref_put(tty); |
1528 | spin_lock_irq(&ip->slock); | 1528 | spin_lock_irq(&ip->slock); |
1529 | status = inb(ip->ioaddr + UART_MSR); | 1529 | status = inb(ip->ioaddr + UART_MSR); |
@@ -1589,13 +1589,13 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp) | |||
1589 | 1589 | ||
1590 | tty = tty_port_tty_get(&ip->port); | 1590 | tty = tty_port_tty_get(&ip->port); |
1591 | 1591 | ||
1592 | if (!tty || !tty->termios) { | 1592 | if (!tty) { |
1593 | cflag = ip->normal_termios.c_cflag; | 1593 | cflag = ip->normal_termios.c_cflag; |
1594 | iflag = ip->normal_termios.c_iflag; | 1594 | iflag = ip->normal_termios.c_iflag; |
1595 | me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios); | 1595 | me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios); |
1596 | } else { | 1596 | } else { |
1597 | cflag = tty->termios->c_cflag; | 1597 | cflag = tty->termios.c_cflag; |
1598 | iflag = tty->termios->c_iflag; | 1598 | iflag = tty->termios.c_iflag; |
1599 | me->baudrate[p] = tty_get_baud_rate(tty); | 1599 | me->baudrate[p] = tty_get_baud_rate(tty); |
1600 | } | 1600 | } |
1601 | tty_kref_put(tty); | 1601 | tty_kref_put(tty); |
@@ -1853,7 +1853,7 @@ static void mxser_stoprx(struct tty_struct *tty) | |||
1853 | } | 1853 | } |
1854 | } | 1854 | } |
1855 | 1855 | ||
1856 | if (tty->termios->c_cflag & CRTSCTS) { | 1856 | if (tty->termios.c_cflag & CRTSCTS) { |
1857 | info->MCR &= ~UART_MCR_RTS; | 1857 | info->MCR &= ~UART_MCR_RTS; |
1858 | outb(info->MCR, info->ioaddr + UART_MCR); | 1858 | outb(info->MCR, info->ioaddr + UART_MCR); |
1859 | } | 1859 | } |
@@ -1890,7 +1890,7 @@ static void mxser_unthrottle(struct tty_struct *tty) | |||
1890 | } | 1890 | } |
1891 | } | 1891 | } |
1892 | 1892 | ||
1893 | if (tty->termios->c_cflag & CRTSCTS) { | 1893 | if (tty->termios.c_cflag & CRTSCTS) { |
1894 | info->MCR |= UART_MCR_RTS; | 1894 | info->MCR |= UART_MCR_RTS; |
1895 | outb(info->MCR, info->ioaddr + UART_MCR); | 1895 | outb(info->MCR, info->ioaddr + UART_MCR); |
1896 | } | 1896 | } |
@@ -1939,14 +1939,14 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi | |||
1939 | spin_unlock_irqrestore(&info->slock, flags); | 1939 | spin_unlock_irqrestore(&info->slock, flags); |
1940 | 1940 | ||
1941 | if ((old_termios->c_cflag & CRTSCTS) && | 1941 | if ((old_termios->c_cflag & CRTSCTS) && |
1942 | !(tty->termios->c_cflag & CRTSCTS)) { | 1942 | !(tty->termios.c_cflag & CRTSCTS)) { |
1943 | tty->hw_stopped = 0; | 1943 | tty->hw_stopped = 0; |
1944 | mxser_start(tty); | 1944 | mxser_start(tty); |
1945 | } | 1945 | } |
1946 | 1946 | ||
1947 | /* Handle sw stopped */ | 1947 | /* Handle sw stopped */ |
1948 | if ((old_termios->c_iflag & IXON) && | 1948 | if ((old_termios->c_iflag & IXON) && |
1949 | !(tty->termios->c_iflag & IXON)) { | 1949 | !(tty->termios.c_iflag & IXON)) { |
1950 | tty->stopped = 0; | 1950 | tty->stopped = 0; |
1951 | 1951 | ||
1952 | if (info->board->chip_flag) { | 1952 | if (info->board->chip_flag) { |
@@ -2337,11 +2337,36 @@ static struct tty_port_operations mxser_port_ops = { | |||
2337 | * The MOXA Smartio/Industio serial driver boot-time initialization code! | 2337 | * The MOXA Smartio/Industio serial driver boot-time initialization code! |
2338 | */ | 2338 | */ |
2339 | 2339 | ||
2340 | static bool allow_overlapping_vector; | ||
2341 | module_param(allow_overlapping_vector, bool, S_IRUGO); | ||
2342 | MODULE_PARM_DESC(allow_overlapping_vector, "whether we allow ISA cards to be configured such that vector overlabs IO ports (default=no)"); | ||
2343 | |||
2344 | static bool mxser_overlapping_vector(struct mxser_board *brd) | ||
2345 | { | ||
2346 | return allow_overlapping_vector && | ||
2347 | brd->vector >= brd->ports[0].ioaddr && | ||
2348 | brd->vector < brd->ports[0].ioaddr + 8 * brd->info->nports; | ||
2349 | } | ||
2350 | |||
2351 | static int mxser_request_vector(struct mxser_board *brd) | ||
2352 | { | ||
2353 | if (mxser_overlapping_vector(brd)) | ||
2354 | return 0; | ||
2355 | return request_region(brd->vector, 1, "mxser(vector)") ? 0 : -EIO; | ||
2356 | } | ||
2357 | |||
2358 | static void mxser_release_vector(struct mxser_board *brd) | ||
2359 | { | ||
2360 | if (mxser_overlapping_vector(brd)) | ||
2361 | return; | ||
2362 | release_region(brd->vector, 1); | ||
2363 | } | ||
2364 | |||
2340 | static void mxser_release_ISA_res(struct mxser_board *brd) | 2365 | static void mxser_release_ISA_res(struct mxser_board *brd) |
2341 | { | 2366 | { |
2342 | free_irq(brd->irq, brd); | 2367 | free_irq(brd->irq, brd); |
2343 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | 2368 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); |
2344 | release_region(brd->vector, 1); | 2369 | mxser_release_vector(brd); |
2345 | } | 2370 | } |
2346 | 2371 | ||
2347 | static int __devinit mxser_initbrd(struct mxser_board *brd, | 2372 | static int __devinit mxser_initbrd(struct mxser_board *brd, |
@@ -2396,7 +2421,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd, | |||
2396 | 2421 | ||
2397 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | 2422 | static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) |
2398 | { | 2423 | { |
2399 | int id, i, bits; | 2424 | int id, i, bits, ret; |
2400 | unsigned short regs[16], irq; | 2425 | unsigned short regs[16], irq; |
2401 | unsigned char scratch, scratch2; | 2426 | unsigned char scratch, scratch2; |
2402 | 2427 | ||
@@ -2492,13 +2517,15 @@ static int __init mxser_get_ISA_conf(int cap, struct mxser_board *brd) | |||
2492 | 8 * brd->info->nports - 1); | 2517 | 8 * brd->info->nports - 1); |
2493 | return -EIO; | 2518 | return -EIO; |
2494 | } | 2519 | } |
2495 | if (!request_region(brd->vector, 1, "mxser(vector)")) { | 2520 | |
2521 | ret = mxser_request_vector(brd); | ||
2522 | if (ret) { | ||
2496 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); | 2523 | release_region(brd->ports[0].ioaddr, 8 * brd->info->nports); |
2497 | printk(KERN_ERR "mxser: can't request interrupt vector region: " | 2524 | printk(KERN_ERR "mxser: can't request interrupt vector region: " |
2498 | "0x%.8lx-0x%.8lx\n", | 2525 | "0x%.8lx-0x%.8lx\n", |
2499 | brd->ports[0].ioaddr, brd->ports[0].ioaddr + | 2526 | brd->ports[0].ioaddr, brd->ports[0].ioaddr + |
2500 | 8 * brd->info->nports - 1); | 2527 | 8 * brd->info->nports - 1); |
2501 | return -EIO; | 2528 | return ret; |
2502 | } | 2529 | } |
2503 | return brd->info->nports; | 2530 | return brd->info->nports; |
2504 | 2531 | ||
@@ -2598,7 +2625,8 @@ static int __devinit mxser_probe(struct pci_dev *pdev, | |||
2598 | goto err_rel3; | 2625 | goto err_rel3; |
2599 | 2626 | ||
2600 | for (i = 0; i < brd->info->nports; i++) | 2627 | for (i = 0; i < brd->info->nports; i++) |
2601 | tty_register_device(mxvar_sdriver, brd->idx + i, &pdev->dev); | 2628 | tty_port_register_device(&brd->ports[i].port, mxvar_sdriver, |
2629 | brd->idx + i, &pdev->dev); | ||
2602 | 2630 | ||
2603 | pci_set_drvdata(pdev, brd); | 2631 | pci_set_drvdata(pdev, brd); |
2604 | 2632 | ||
@@ -2695,7 +2723,8 @@ static int __init mxser_module_init(void) | |||
2695 | 2723 | ||
2696 | brd->idx = m * MXSER_PORTS_PER_BOARD; | 2724 | brd->idx = m * MXSER_PORTS_PER_BOARD; |
2697 | for (i = 0; i < brd->info->nports; i++) | 2725 | for (i = 0; i < brd->info->nports; i++) |
2698 | tty_register_device(mxvar_sdriver, brd->idx + i, NULL); | 2726 | tty_port_register_device(&brd->ports[i].port, |
2727 | mxvar_sdriver, brd->idx + i, NULL); | ||
2699 | 2728 | ||
2700 | m++; | 2729 | m++; |
2701 | } | 2730 | } |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index c43b683b6eb8..3e210a430fb3 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -108,7 +108,7 @@ struct gsm_mux_net { | |||
108 | */ | 108 | */ |
109 | 109 | ||
110 | struct gsm_msg { | 110 | struct gsm_msg { |
111 | struct gsm_msg *next; | 111 | struct list_head list; |
112 | u8 addr; /* DLCI address + flags */ | 112 | u8 addr; /* DLCI address + flags */ |
113 | u8 ctrl; /* Control byte + flags */ | 113 | u8 ctrl; /* Control byte + flags */ |
114 | unsigned int len; /* Length of data block (can be zero) */ | 114 | unsigned int len; /* Length of data block (can be zero) */ |
@@ -245,8 +245,7 @@ struct gsm_mux { | |||
245 | unsigned int tx_bytes; /* TX data outstanding */ | 245 | unsigned int tx_bytes; /* TX data outstanding */ |
246 | #define TX_THRESH_HI 8192 | 246 | #define TX_THRESH_HI 8192 |
247 | #define TX_THRESH_LO 2048 | 247 | #define TX_THRESH_LO 2048 |
248 | struct gsm_msg *tx_head; /* Pending data packets */ | 248 | struct list_head tx_list; /* Pending data packets */ |
249 | struct gsm_msg *tx_tail; | ||
250 | 249 | ||
251 | /* Control messages */ | 250 | /* Control messages */ |
252 | struct timer_list t2_timer; /* Retransmit timer for commands */ | 251 | struct timer_list t2_timer; /* Retransmit timer for commands */ |
@@ -663,7 +662,7 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, | |||
663 | m->len = len; | 662 | m->len = len; |
664 | m->addr = addr; | 663 | m->addr = addr; |
665 | m->ctrl = ctrl; | 664 | m->ctrl = ctrl; |
666 | m->next = NULL; | 665 | INIT_LIST_HEAD(&m->list); |
667 | return m; | 666 | return m; |
668 | } | 667 | } |
669 | 668 | ||
@@ -673,22 +672,21 @@ static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len, | |||
673 | * | 672 | * |
674 | * The tty device has called us to indicate that room has appeared in | 673 | * The tty device has called us to indicate that room has appeared in |
675 | * the transmit queue. Ram more data into the pipe if we have any | 674 | * the transmit queue. Ram more data into the pipe if we have any |
675 | * If we have been flow-stopped by a CMD_FCOFF, then we can only | ||
676 | * send messages on DLCI0 until CMD_FCON | ||
676 | * | 677 | * |
677 | * FIXME: lock against link layer control transmissions | 678 | * FIXME: lock against link layer control transmissions |
678 | */ | 679 | */ |
679 | 680 | ||
680 | static void gsm_data_kick(struct gsm_mux *gsm) | 681 | static void gsm_data_kick(struct gsm_mux *gsm) |
681 | { | 682 | { |
682 | struct gsm_msg *msg = gsm->tx_head; | 683 | struct gsm_msg *msg, *nmsg; |
683 | int len; | 684 | int len; |
684 | int skip_sof = 0; | 685 | int skip_sof = 0; |
685 | 686 | ||
686 | /* FIXME: We need to apply this solely to data messages */ | 687 | list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) { |
687 | if (gsm->constipated) | 688 | if (gsm->constipated && msg->addr) |
688 | return; | 689 | continue; |
689 | |||
690 | while (gsm->tx_head != NULL) { | ||
691 | msg = gsm->tx_head; | ||
692 | if (gsm->encoding != 0) { | 690 | if (gsm->encoding != 0) { |
693 | gsm->txframe[0] = GSM1_SOF; | 691 | gsm->txframe[0] = GSM1_SOF; |
694 | len = gsm_stuff_frame(msg->data, | 692 | len = gsm_stuff_frame(msg->data, |
@@ -711,14 +709,13 @@ static void gsm_data_kick(struct gsm_mux *gsm) | |||
711 | len - skip_sof) < 0) | 709 | len - skip_sof) < 0) |
712 | break; | 710 | break; |
713 | /* FIXME: Can eliminate one SOF in many more cases */ | 711 | /* FIXME: Can eliminate one SOF in many more cases */ |
714 | gsm->tx_head = msg->next; | ||
715 | if (gsm->tx_head == NULL) | ||
716 | gsm->tx_tail = NULL; | ||
717 | gsm->tx_bytes -= msg->len; | 712 | gsm->tx_bytes -= msg->len; |
718 | kfree(msg); | ||
719 | /* For a burst of frames skip the extra SOF within the | 713 | /* For a burst of frames skip the extra SOF within the |
720 | burst */ | 714 | burst */ |
721 | skip_sof = 1; | 715 | skip_sof = 1; |
716 | |||
717 | list_del(&msg->list); | ||
718 | kfree(msg); | ||
722 | } | 719 | } |
723 | } | 720 | } |
724 | 721 | ||
@@ -768,11 +765,7 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) | |||
768 | msg->data = dp; | 765 | msg->data = dp; |
769 | 766 | ||
770 | /* Add to the actual output queue */ | 767 | /* Add to the actual output queue */ |
771 | if (gsm->tx_tail) | 768 | list_add_tail(&msg->list, &gsm->tx_list); |
772 | gsm->tx_tail->next = msg; | ||
773 | else | ||
774 | gsm->tx_head = msg; | ||
775 | gsm->tx_tail = msg; | ||
776 | gsm->tx_bytes += msg->len; | 769 | gsm->tx_bytes += msg->len; |
777 | gsm_data_kick(gsm); | 770 | gsm_data_kick(gsm); |
778 | } | 771 | } |
@@ -875,7 +868,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
875 | 868 | ||
876 | /* dlci->skb is locked by tx_lock */ | 869 | /* dlci->skb is locked by tx_lock */ |
877 | if (dlci->skb == NULL) { | 870 | if (dlci->skb == NULL) { |
878 | dlci->skb = skb_dequeue(&dlci->skb_list); | 871 | dlci->skb = skb_dequeue_tail(&dlci->skb_list); |
879 | if (dlci->skb == NULL) | 872 | if (dlci->skb == NULL) |
880 | return 0; | 873 | return 0; |
881 | first = 1; | 874 | first = 1; |
@@ -886,7 +879,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
886 | if (len > gsm->mtu) { | 879 | if (len > gsm->mtu) { |
887 | if (dlci->adaption == 3) { | 880 | if (dlci->adaption == 3) { |
888 | /* Over long frame, bin it */ | 881 | /* Over long frame, bin it */ |
889 | kfree_skb(dlci->skb); | 882 | dev_kfree_skb_any(dlci->skb); |
890 | dlci->skb = NULL; | 883 | dlci->skb = NULL; |
891 | return 0; | 884 | return 0; |
892 | } | 885 | } |
@@ -899,8 +892,11 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
899 | 892 | ||
900 | /* FIXME: need a timer or something to kick this so it can't | 893 | /* FIXME: need a timer or something to kick this so it can't |
901 | get stuck with no work outstanding and no buffer free */ | 894 | get stuck with no work outstanding and no buffer free */ |
902 | if (msg == NULL) | 895 | if (msg == NULL) { |
896 | skb_queue_tail(&dlci->skb_list, dlci->skb); | ||
897 | dlci->skb = NULL; | ||
903 | return -ENOMEM; | 898 | return -ENOMEM; |
899 | } | ||
904 | dp = msg->data; | 900 | dp = msg->data; |
905 | 901 | ||
906 | if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */ | 902 | if (dlci->adaption == 4) { /* Interruptible framed (Packetised Data) */ |
@@ -912,7 +908,7 @@ static int gsm_dlci_data_output_framed(struct gsm_mux *gsm, | |||
912 | skb_pull(dlci->skb, len); | 908 | skb_pull(dlci->skb, len); |
913 | __gsm_data_queue(dlci, msg); | 909 | __gsm_data_queue(dlci, msg); |
914 | if (last) { | 910 | if (last) { |
915 | kfree_skb(dlci->skb); | 911 | dev_kfree_skb_any(dlci->skb); |
916 | dlci->skb = NULL; | 912 | dlci->skb = NULL; |
917 | } | 913 | } |
918 | return size; | 914 | return size; |
@@ -971,16 +967,22 @@ static void gsm_dlci_data_sweep(struct gsm_mux *gsm) | |||
971 | static void gsm_dlci_data_kick(struct gsm_dlci *dlci) | 967 | static void gsm_dlci_data_kick(struct gsm_dlci *dlci) |
972 | { | 968 | { |
973 | unsigned long flags; | 969 | unsigned long flags; |
970 | int sweep; | ||
971 | |||
972 | if (dlci->constipated) | ||
973 | return; | ||
974 | 974 | ||
975 | spin_lock_irqsave(&dlci->gsm->tx_lock, flags); | 975 | spin_lock_irqsave(&dlci->gsm->tx_lock, flags); |
976 | /* If we have nothing running then we need to fire up */ | 976 | /* If we have nothing running then we need to fire up */ |
977 | sweep = (dlci->gsm->tx_bytes < TX_THRESH_LO); | ||
977 | if (dlci->gsm->tx_bytes == 0) { | 978 | if (dlci->gsm->tx_bytes == 0) { |
978 | if (dlci->net) | 979 | if (dlci->net) |
979 | gsm_dlci_data_output_framed(dlci->gsm, dlci); | 980 | gsm_dlci_data_output_framed(dlci->gsm, dlci); |
980 | else | 981 | else |
981 | gsm_dlci_data_output(dlci->gsm, dlci); | 982 | gsm_dlci_data_output(dlci->gsm, dlci); |
982 | } else if (dlci->gsm->tx_bytes < TX_THRESH_LO) | 983 | } |
983 | gsm_dlci_data_sweep(dlci->gsm); | 984 | if (sweep) |
985 | gsm_dlci_data_sweep(dlci->gsm); | ||
984 | spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags); | 986 | spin_unlock_irqrestore(&dlci->gsm->tx_lock, flags); |
985 | } | 987 | } |
986 | 988 | ||
@@ -1027,6 +1029,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1027 | { | 1029 | { |
1028 | int mlines = 0; | 1030 | int mlines = 0; |
1029 | u8 brk = 0; | 1031 | u8 brk = 0; |
1032 | int fc; | ||
1030 | 1033 | ||
1031 | /* The modem status command can either contain one octet (v.24 signals) | 1034 | /* The modem status command can either contain one octet (v.24 signals) |
1032 | or two octets (v.24 signals + break signals). The length field will | 1035 | or two octets (v.24 signals + break signals). The length field will |
@@ -1038,19 +1041,21 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1038 | else { | 1041 | else { |
1039 | brk = modem & 0x7f; | 1042 | brk = modem & 0x7f; |
1040 | modem = (modem >> 7) & 0x7f; | 1043 | modem = (modem >> 7) & 0x7f; |
1041 | }; | 1044 | } |
1042 | 1045 | ||
1043 | /* Flow control/ready to communicate */ | 1046 | /* Flow control/ready to communicate */ |
1044 | if (modem & MDM_FC) { | 1047 | fc = (modem & MDM_FC) || !(modem & MDM_RTR); |
1048 | if (fc && !dlci->constipated) { | ||
1045 | /* Need to throttle our output on this device */ | 1049 | /* Need to throttle our output on this device */ |
1046 | dlci->constipated = 1; | 1050 | dlci->constipated = 1; |
1047 | } | 1051 | } else if (!fc && dlci->constipated) { |
1048 | if (modem & MDM_RTC) { | ||
1049 | mlines |= TIOCM_DSR | TIOCM_DTR; | ||
1050 | dlci->constipated = 0; | 1052 | dlci->constipated = 0; |
1051 | gsm_dlci_data_kick(dlci); | 1053 | gsm_dlci_data_kick(dlci); |
1052 | } | 1054 | } |
1055 | |||
1053 | /* Map modem bits */ | 1056 | /* Map modem bits */ |
1057 | if (modem & MDM_RTC) | ||
1058 | mlines |= TIOCM_DSR | TIOCM_DTR; | ||
1054 | if (modem & MDM_RTR) | 1059 | if (modem & MDM_RTR) |
1055 | mlines |= TIOCM_RTS | TIOCM_CTS; | 1060 | mlines |= TIOCM_RTS | TIOCM_CTS; |
1056 | if (modem & MDM_IC) | 1061 | if (modem & MDM_IC) |
@@ -1061,7 +1066,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci, | |||
1061 | /* Carrier drop -> hangup */ | 1066 | /* Carrier drop -> hangup */ |
1062 | if (tty) { | 1067 | if (tty) { |
1063 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) | 1068 | if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD)) |
1064 | if (!(tty->termios->c_cflag & CLOCAL)) | 1069 | if (!(tty->termios.c_cflag & CLOCAL)) |
1065 | tty_hangup(tty); | 1070 | tty_hangup(tty); |
1066 | if (brk & 0x01) | 1071 | if (brk & 0x01) |
1067 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 1072 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
@@ -1190,6 +1195,8 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, | |||
1190 | u8 *data, int clen) | 1195 | u8 *data, int clen) |
1191 | { | 1196 | { |
1192 | u8 buf[1]; | 1197 | u8 buf[1]; |
1198 | unsigned long flags; | ||
1199 | |||
1193 | switch (command) { | 1200 | switch (command) { |
1194 | case CMD_CLD: { | 1201 | case CMD_CLD: { |
1195 | struct gsm_dlci *dlci = gsm->dlci[0]; | 1202 | struct gsm_dlci *dlci = gsm->dlci[0]; |
@@ -1206,16 +1213,18 @@ static void gsm_control_message(struct gsm_mux *gsm, unsigned int command, | |||
1206 | gsm_control_reply(gsm, CMD_TEST, data, clen); | 1213 | gsm_control_reply(gsm, CMD_TEST, data, clen); |
1207 | break; | 1214 | break; |
1208 | case CMD_FCON: | 1215 | case CMD_FCON: |
1209 | /* Modem wants us to STFU */ | ||
1210 | gsm->constipated = 1; | ||
1211 | gsm_control_reply(gsm, CMD_FCON, NULL, 0); | ||
1212 | break; | ||
1213 | case CMD_FCOFF: | ||
1214 | /* Modem can accept data again */ | 1216 | /* Modem can accept data again */ |
1215 | gsm->constipated = 0; | 1217 | gsm->constipated = 0; |
1216 | gsm_control_reply(gsm, CMD_FCOFF, NULL, 0); | 1218 | gsm_control_reply(gsm, CMD_FCON, NULL, 0); |
1217 | /* Kick the link in case it is idling */ | 1219 | /* Kick the link in case it is idling */ |
1220 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
1218 | gsm_data_kick(gsm); | 1221 | gsm_data_kick(gsm); |
1222 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
1223 | break; | ||
1224 | case CMD_FCOFF: | ||
1225 | /* Modem wants us to STFU */ | ||
1226 | gsm->constipated = 1; | ||
1227 | gsm_control_reply(gsm, CMD_FCOFF, NULL, 0); | ||
1219 | break; | 1228 | break; |
1220 | case CMD_MSC: | 1229 | case CMD_MSC: |
1221 | /* Out of band modem line change indicator for a DLCI */ | 1230 | /* Out of band modem line change indicator for a DLCI */ |
@@ -1668,7 +1677,7 @@ static void gsm_dlci_free(struct kref *ref) | |||
1668 | dlci->gsm->dlci[dlci->addr] = NULL; | 1677 | dlci->gsm->dlci[dlci->addr] = NULL; |
1669 | kfifo_free(dlci->fifo); | 1678 | kfifo_free(dlci->fifo); |
1670 | while ((dlci->skb = skb_dequeue(&dlci->skb_list))) | 1679 | while ((dlci->skb = skb_dequeue(&dlci->skb_list))) |
1671 | kfree_skb(dlci->skb); | 1680 | dev_kfree_skb(dlci->skb); |
1672 | kfree(dlci); | 1681 | kfree(dlci); |
1673 | } | 1682 | } |
1674 | 1683 | ||
@@ -2007,7 +2016,7 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
2007 | { | 2016 | { |
2008 | int i; | 2017 | int i; |
2009 | struct gsm_dlci *dlci = gsm->dlci[0]; | 2018 | struct gsm_dlci *dlci = gsm->dlci[0]; |
2010 | struct gsm_msg *txq; | 2019 | struct gsm_msg *txq, *ntxq; |
2011 | struct gsm_control *gc; | 2020 | struct gsm_control *gc; |
2012 | 2021 | ||
2013 | gsm->dead = 1; | 2022 | gsm->dead = 1; |
@@ -2042,11 +2051,9 @@ void gsm_cleanup_mux(struct gsm_mux *gsm) | |||
2042 | if (gsm->dlci[i]) | 2051 | if (gsm->dlci[i]) |
2043 | gsm_dlci_release(gsm->dlci[i]); | 2052 | gsm_dlci_release(gsm->dlci[i]); |
2044 | /* Now wipe the queues */ | 2053 | /* Now wipe the queues */ |
2045 | for (txq = gsm->tx_head; txq != NULL; txq = gsm->tx_head) { | 2054 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list) |
2046 | gsm->tx_head = txq->next; | ||
2047 | kfree(txq); | 2055 | kfree(txq); |
2048 | } | 2056 | INIT_LIST_HEAD(&gsm->tx_list); |
2049 | gsm->tx_tail = NULL; | ||
2050 | } | 2057 | } |
2051 | EXPORT_SYMBOL_GPL(gsm_cleanup_mux); | 2058 | EXPORT_SYMBOL_GPL(gsm_cleanup_mux); |
2052 | 2059 | ||
@@ -2157,6 +2164,7 @@ struct gsm_mux *gsm_alloc_mux(void) | |||
2157 | } | 2164 | } |
2158 | spin_lock_init(&gsm->lock); | 2165 | spin_lock_init(&gsm->lock); |
2159 | kref_init(&gsm->ref); | 2166 | kref_init(&gsm->ref); |
2167 | INIT_LIST_HEAD(&gsm->tx_list); | ||
2160 | 2168 | ||
2161 | gsm->t1 = T1; | 2169 | gsm->t1 = T1; |
2162 | gsm->t2 = T2; | 2170 | gsm->t2 = T2; |
@@ -2273,7 +2281,7 @@ static void gsmld_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
2273 | gsm->error(gsm, *dp, flags); | 2281 | gsm->error(gsm, *dp, flags); |
2274 | break; | 2282 | break; |
2275 | default: | 2283 | default: |
2276 | WARN_ONCE("%s: unknown flag %d\n", | 2284 | WARN_ONCE(1, "%s: unknown flag %d\n", |
2277 | tty_name(tty, buf), flags); | 2285 | tty_name(tty, buf), flags); |
2278 | break; | 2286 | break; |
2279 | } | 2287 | } |
@@ -2377,12 +2385,12 @@ static void gsmld_write_wakeup(struct tty_struct *tty) | |||
2377 | 2385 | ||
2378 | /* Queue poll */ | 2386 | /* Queue poll */ |
2379 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 2387 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
2388 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
2380 | gsm_data_kick(gsm); | 2389 | gsm_data_kick(gsm); |
2381 | if (gsm->tx_bytes < TX_THRESH_LO) { | 2390 | if (gsm->tx_bytes < TX_THRESH_LO) { |
2382 | spin_lock_irqsave(&gsm->tx_lock, flags); | ||
2383 | gsm_dlci_data_sweep(gsm); | 2391 | gsm_dlci_data_sweep(gsm); |
2384 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
2385 | } | 2392 | } |
2393 | spin_unlock_irqrestore(&gsm->tx_lock, flags); | ||
2386 | } | 2394 | } |
2387 | 2395 | ||
2388 | /** | 2396 | /** |
@@ -2868,14 +2876,14 @@ static const struct tty_port_operations gsm_port_ops = { | |||
2868 | .dtr_rts = gsm_dtr_rts, | 2876 | .dtr_rts = gsm_dtr_rts, |
2869 | }; | 2877 | }; |
2870 | 2878 | ||
2871 | 2879 | static int gsmtty_install(struct tty_driver *driver, struct tty_struct *tty) | |
2872 | static int gsmtty_open(struct tty_struct *tty, struct file *filp) | ||
2873 | { | 2880 | { |
2874 | struct gsm_mux *gsm; | 2881 | struct gsm_mux *gsm; |
2875 | struct gsm_dlci *dlci; | 2882 | struct gsm_dlci *dlci; |
2876 | struct tty_port *port; | ||
2877 | unsigned int line = tty->index; | 2883 | unsigned int line = tty->index; |
2878 | unsigned int mux = line >> 6; | 2884 | unsigned int mux = line >> 6; |
2885 | bool alloc = false; | ||
2886 | int ret; | ||
2879 | 2887 | ||
2880 | line = line & 0x3F; | 2888 | line = line & 0x3F; |
2881 | 2889 | ||
@@ -2889,14 +2897,35 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) | |||
2889 | gsm = gsm_mux[mux]; | 2897 | gsm = gsm_mux[mux]; |
2890 | if (gsm->dead) | 2898 | if (gsm->dead) |
2891 | return -EL2HLT; | 2899 | return -EL2HLT; |
2900 | /* If DLCI 0 is not yet fully open return an error. This is ok from a locking | ||
2901 | perspective as we don't have to worry about this if DLCI0 is lost */ | ||
2902 | if (gsm->dlci[0] && gsm->dlci[0]->state != DLCI_OPEN) | ||
2903 | return -EL2NSYNC; | ||
2892 | dlci = gsm->dlci[line]; | 2904 | dlci = gsm->dlci[line]; |
2893 | if (dlci == NULL) | 2905 | if (dlci == NULL) { |
2906 | alloc = true; | ||
2894 | dlci = gsm_dlci_alloc(gsm, line); | 2907 | dlci = gsm_dlci_alloc(gsm, line); |
2908 | } | ||
2895 | if (dlci == NULL) | 2909 | if (dlci == NULL) |
2896 | return -ENOMEM; | 2910 | return -ENOMEM; |
2897 | port = &dlci->port; | 2911 | ret = tty_port_install(&dlci->port, driver, tty); |
2898 | port->count++; | 2912 | if (ret) { |
2913 | if (alloc) | ||
2914 | dlci_put(dlci); | ||
2915 | return ret; | ||
2916 | } | ||
2917 | |||
2899 | tty->driver_data = dlci; | 2918 | tty->driver_data = dlci; |
2919 | |||
2920 | return 0; | ||
2921 | } | ||
2922 | |||
2923 | static int gsmtty_open(struct tty_struct *tty, struct file *filp) | ||
2924 | { | ||
2925 | struct gsm_dlci *dlci = tty->driver_data; | ||
2926 | struct tty_port *port = &dlci->port; | ||
2927 | |||
2928 | port->count++; | ||
2900 | dlci_get(dlci); | 2929 | dlci_get(dlci); |
2901 | dlci_get(dlci->gsm->dlci[0]); | 2930 | dlci_get(dlci->gsm->dlci[0]); |
2902 | mux_get(dlci->gsm); | 2931 | mux_get(dlci->gsm); |
@@ -3043,13 +3072,13 @@ static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
3043 | the RPN control message. This however rapidly gets nasty as we | 3072 | the RPN control message. This however rapidly gets nasty as we |
3044 | then have to remap modem signals each way according to whether | 3073 | then have to remap modem signals each way according to whether |
3045 | our virtual cable is null modem etc .. */ | 3074 | our virtual cable is null modem etc .. */ |
3046 | tty_termios_copy_hw(tty->termios, old); | 3075 | tty_termios_copy_hw(&tty->termios, old); |
3047 | } | 3076 | } |
3048 | 3077 | ||
3049 | static void gsmtty_throttle(struct tty_struct *tty) | 3078 | static void gsmtty_throttle(struct tty_struct *tty) |
3050 | { | 3079 | { |
3051 | struct gsm_dlci *dlci = tty->driver_data; | 3080 | struct gsm_dlci *dlci = tty->driver_data; |
3052 | if (tty->termios->c_cflag & CRTSCTS) | 3081 | if (tty->termios.c_cflag & CRTSCTS) |
3053 | dlci->modem_tx &= ~TIOCM_DTR; | 3082 | dlci->modem_tx &= ~TIOCM_DTR; |
3054 | dlci->throttled = 1; | 3083 | dlci->throttled = 1; |
3055 | /* Send an MSC with DTR cleared */ | 3084 | /* Send an MSC with DTR cleared */ |
@@ -3059,7 +3088,7 @@ static void gsmtty_throttle(struct tty_struct *tty) | |||
3059 | static void gsmtty_unthrottle(struct tty_struct *tty) | 3088 | static void gsmtty_unthrottle(struct tty_struct *tty) |
3060 | { | 3089 | { |
3061 | struct gsm_dlci *dlci = tty->driver_data; | 3090 | struct gsm_dlci *dlci = tty->driver_data; |
3062 | if (tty->termios->c_cflag & CRTSCTS) | 3091 | if (tty->termios.c_cflag & CRTSCTS) |
3063 | dlci->modem_tx |= TIOCM_DTR; | 3092 | dlci->modem_tx |= TIOCM_DTR; |
3064 | dlci->throttled = 0; | 3093 | dlci->throttled = 0; |
3065 | /* Send an MSC with DTR set */ | 3094 | /* Send an MSC with DTR set */ |
@@ -3085,6 +3114,7 @@ static int gsmtty_break_ctl(struct tty_struct *tty, int state) | |||
3085 | 3114 | ||
3086 | /* Virtual ttys for the demux */ | 3115 | /* Virtual ttys for the demux */ |
3087 | static const struct tty_operations gsmtty_ops = { | 3116 | static const struct tty_operations gsmtty_ops = { |
3117 | .install = gsmtty_install, | ||
3088 | .open = gsmtty_open, | 3118 | .open = gsmtty_open, |
3089 | .close = gsmtty_close, | 3119 | .close = gsmtty_close, |
3090 | .write = gsmtty_write, | 3120 | .write = gsmtty_write, |
diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 5c6c31459a2f..1e6405070ce6 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c | |||
@@ -1065,7 +1065,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1065 | 1065 | ||
1066 | TRACE_L("read()"); | 1066 | TRACE_L("read()"); |
1067 | 1067 | ||
1068 | tty_lock(); | 1068 | tty_lock(tty); |
1069 | 1069 | ||
1070 | pClient = findClient(pInfo, task_pid(current)); | 1070 | pClient = findClient(pInfo, task_pid(current)); |
1071 | if (pClient) { | 1071 | if (pClient) { |
@@ -1077,7 +1077,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1077 | goto unlock; | 1077 | goto unlock; |
1078 | } | 1078 | } |
1079 | /* block until there is a message: */ | 1079 | /* block until there is a message: */ |
1080 | wait_event_interruptible_tty(pInfo->read_wait, | 1080 | wait_event_interruptible_tty(tty, pInfo->read_wait, |
1081 | (pMsg = remove_msg(pInfo, pClient))); | 1081 | (pMsg = remove_msg(pInfo, pClient))); |
1082 | } | 1082 | } |
1083 | 1083 | ||
@@ -1107,7 +1107,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, | |||
1107 | } | 1107 | } |
1108 | ret = -EPERM; | 1108 | ret = -EPERM; |
1109 | unlock: | 1109 | unlock: |
1110 | tty_unlock(); | 1110 | tty_unlock(tty); |
1111 | return ret; | 1111 | return ret; |
1112 | } | 1112 | } |
1113 | 1113 | ||
@@ -1156,7 +1156,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1156 | pHeader->locks = 0; | 1156 | pHeader->locks = 0; |
1157 | pHeader->owner = NULL; | 1157 | pHeader->owner = NULL; |
1158 | 1158 | ||
1159 | tty_lock(); | 1159 | tty_lock(tty); |
1160 | 1160 | ||
1161 | pClient = findClient(pInfo, task_pid(current)); | 1161 | pClient = findClient(pInfo, task_pid(current)); |
1162 | if (pClient) { | 1162 | if (pClient) { |
@@ -1175,7 +1175,7 @@ static ssize_t r3964_write(struct tty_struct *tty, struct file *file, | |||
1175 | add_tx_queue(pInfo, pHeader); | 1175 | add_tx_queue(pInfo, pHeader); |
1176 | trigger_transmit(pInfo); | 1176 | trigger_transmit(pInfo); |
1177 | 1177 | ||
1178 | tty_unlock(); | 1178 | tty_unlock(tty); |
1179 | 1179 | ||
1180 | return 0; | 1180 | return 0; |
1181 | } | 1181 | } |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index ee1c268f5f9d..8c0b7b42319c 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -92,10 +92,18 @@ static inline int tty_put_user(struct tty_struct *tty, unsigned char x, | |||
92 | 92 | ||
93 | static void n_tty_set_room(struct tty_struct *tty) | 93 | static void n_tty_set_room(struct tty_struct *tty) |
94 | { | 94 | { |
95 | /* tty->read_cnt is not read locked ? */ | 95 | int left; |
96 | int left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
97 | int old_left; | 96 | int old_left; |
98 | 97 | ||
98 | /* tty->read_cnt is not read locked ? */ | ||
99 | if (I_PARMRK(tty)) { | ||
100 | /* Multiply read_cnt by 3, since each byte might take up to | ||
101 | * three times as many spaces when PARMRK is set (depending on | ||
102 | * its flags, e.g. parity error). */ | ||
103 | left = N_TTY_BUF_SIZE - tty->read_cnt * 3 - 1; | ||
104 | } else | ||
105 | left = N_TTY_BUF_SIZE - tty->read_cnt - 1; | ||
106 | |||
99 | /* | 107 | /* |
100 | * If we are doing input canonicalization, and there are no | 108 | * If we are doing input canonicalization, and there are no |
101 | * pending newlines, let characters through without limit, so | 109 | * pending newlines, let characters through without limit, so |
@@ -1432,6 +1440,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp, | |||
1432 | */ | 1440 | */ |
1433 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) | 1441 | if (tty->receive_room < TTY_THRESHOLD_THROTTLE) |
1434 | tty_throttle(tty); | 1442 | tty_throttle(tty); |
1443 | |||
1444 | /* FIXME: there is a tiny race here if the receive room check runs | ||
1445 | before the other work executes and empties the buffer (upping | ||
1446 | the receiving room and unthrottling. We then throttle and get | ||
1447 | stuck. This has been observed and traced down by Vincent Pillet/ | ||
1448 | We need to address this when we sort out out the rx path locking */ | ||
1435 | } | 1449 | } |
1436 | 1450 | ||
1437 | int is_ignored(int sig) | 1451 | int is_ignored(int sig) |
@@ -1460,7 +1474,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
1460 | BUG_ON(!tty); | 1474 | BUG_ON(!tty); |
1461 | 1475 | ||
1462 | if (old) | 1476 | if (old) |
1463 | canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON; | 1477 | canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON; |
1464 | if (canon_change) { | 1478 | if (canon_change) { |
1465 | memset(&tty->read_flags, 0, sizeof tty->read_flags); | 1479 | memset(&tty->read_flags, 0, sizeof tty->read_flags); |
1466 | tty->canon_head = tty->read_tail; | 1480 | tty->canon_head = tty->read_tail; |
@@ -1728,7 +1742,8 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, | |||
1728 | 1742 | ||
1729 | do_it_again: | 1743 | do_it_again: |
1730 | 1744 | ||
1731 | BUG_ON(!tty->read_buf); | 1745 | if (WARN_ON(!tty->read_buf)) |
1746 | return -EAGAIN; | ||
1732 | 1747 | ||
1733 | c = job_control(tty, file); | 1748 | c = job_control(tty, file); |
1734 | if (c < 0) | 1749 | if (c < 0) |
@@ -1832,13 +1847,13 @@ do_it_again: | |||
1832 | 1847 | ||
1833 | if (tty->icanon && !L_EXTPROC(tty)) { | 1848 | if (tty->icanon && !L_EXTPROC(tty)) { |
1834 | /* N.B. avoid overrun if nr == 0 */ | 1849 | /* N.B. avoid overrun if nr == 0 */ |
1850 | spin_lock_irqsave(&tty->read_lock, flags); | ||
1835 | while (nr && tty->read_cnt) { | 1851 | while (nr && tty->read_cnt) { |
1836 | int eol; | 1852 | int eol; |
1837 | 1853 | ||
1838 | eol = test_and_clear_bit(tty->read_tail, | 1854 | eol = test_and_clear_bit(tty->read_tail, |
1839 | tty->read_flags); | 1855 | tty->read_flags); |
1840 | c = tty->read_buf[tty->read_tail]; | 1856 | c = tty->read_buf[tty->read_tail]; |
1841 | spin_lock_irqsave(&tty->read_lock, flags); | ||
1842 | tty->read_tail = ((tty->read_tail+1) & | 1857 | tty->read_tail = ((tty->read_tail+1) & |
1843 | (N_TTY_BUF_SIZE-1)); | 1858 | (N_TTY_BUF_SIZE-1)); |
1844 | tty->read_cnt--; | 1859 | tty->read_cnt--; |
@@ -1856,15 +1871,19 @@ do_it_again: | |||
1856 | if (tty_put_user(tty, c, b++)) { | 1871 | if (tty_put_user(tty, c, b++)) { |
1857 | retval = -EFAULT; | 1872 | retval = -EFAULT; |
1858 | b--; | 1873 | b--; |
1874 | spin_lock_irqsave(&tty->read_lock, flags); | ||
1859 | break; | 1875 | break; |
1860 | } | 1876 | } |
1861 | nr--; | 1877 | nr--; |
1862 | } | 1878 | } |
1863 | if (eol) { | 1879 | if (eol) { |
1864 | tty_audit_push(tty); | 1880 | tty_audit_push(tty); |
1881 | spin_lock_irqsave(&tty->read_lock, flags); | ||
1865 | break; | 1882 | break; |
1866 | } | 1883 | } |
1884 | spin_lock_irqsave(&tty->read_lock, flags); | ||
1867 | } | 1885 | } |
1886 | spin_unlock_irqrestore(&tty->read_lock, flags); | ||
1868 | if (retval) | 1887 | if (retval) |
1869 | break; | 1888 | break; |
1870 | } else { | 1889 | } else { |
diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index e7592f9037da..b917c9424954 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c | |||
@@ -1473,8 +1473,8 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, | |||
1473 | port->dc = dc; | 1473 | port->dc = dc; |
1474 | tty_port_init(&port->port); | 1474 | tty_port_init(&port->port); |
1475 | port->port.ops = &noz_tty_port_ops; | 1475 | port->port.ops = &noz_tty_port_ops; |
1476 | tty_dev = tty_register_device(ntty_driver, dc->index_start + i, | 1476 | tty_dev = tty_port_register_device(&port->port, ntty_driver, |
1477 | &pdev->dev); | 1477 | dc->index_start + i, &pdev->dev); |
1478 | 1478 | ||
1479 | if (IS_ERR(tty_dev)) { | 1479 | if (IS_ERR(tty_dev)) { |
1480 | ret = PTR_ERR(tty_dev); | 1480 | ret = PTR_ERR(tty_dev); |
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 5505ffc91da4..2bace847eb39 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c | |||
@@ -47,6 +47,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
47 | wake_up_interruptible(&tty->read_wait); | 47 | wake_up_interruptible(&tty->read_wait); |
48 | wake_up_interruptible(&tty->write_wait); | 48 | wake_up_interruptible(&tty->write_wait); |
49 | tty->packet = 0; | 49 | tty->packet = 0; |
50 | /* Review - krefs on tty_link ?? */ | ||
50 | if (!tty->link) | 51 | if (!tty->link) |
51 | return; | 52 | return; |
52 | tty->link->packet = 0; | 53 | tty->link->packet = 0; |
@@ -62,9 +63,9 @@ static void pty_close(struct tty_struct *tty, struct file *filp) | |||
62 | mutex_unlock(&devpts_mutex); | 63 | mutex_unlock(&devpts_mutex); |
63 | } | 64 | } |
64 | #endif | 65 | #endif |
65 | tty_unlock(); | 66 | tty_unlock(tty); |
66 | tty_vhangup(tty->link); | 67 | tty_vhangup(tty->link); |
67 | tty_lock(); | 68 | tty_lock(tty); |
68 | } | 69 | } |
69 | } | 70 | } |
70 | 71 | ||
@@ -231,8 +232,8 @@ out: | |||
231 | static void pty_set_termios(struct tty_struct *tty, | 232 | static void pty_set_termios(struct tty_struct *tty, |
232 | struct ktermios *old_termios) | 233 | struct ktermios *old_termios) |
233 | { | 234 | { |
234 | tty->termios->c_cflag &= ~(CSIZE | PARENB); | 235 | tty->termios.c_cflag &= ~(CSIZE | PARENB); |
235 | tty->termios->c_cflag |= (CS8 | CREAD); | 236 | tty->termios.c_cflag |= (CS8 | CREAD); |
236 | } | 237 | } |
237 | 238 | ||
238 | /** | 239 | /** |
@@ -282,60 +283,110 @@ done: | |||
282 | return 0; | 283 | return 0; |
283 | } | 284 | } |
284 | 285 | ||
285 | /* Traditional BSD devices */ | 286 | /** |
286 | #ifdef CONFIG_LEGACY_PTYS | 287 | * pty_common_install - set up the pty pair |
287 | 288 | * @driver: the pty driver | |
288 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | 289 | * @tty: the tty being instantiated |
290 | * @bool: legacy, true if this is BSD style | ||
291 | * | ||
292 | * Perform the initial set up for the tty/pty pair. Called from the | ||
293 | * tty layer when the port is first opened. | ||
294 | * | ||
295 | * Locking: the caller must hold the tty_mutex | ||
296 | */ | ||
297 | static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty, | ||
298 | bool legacy) | ||
289 | { | 299 | { |
290 | struct tty_struct *o_tty; | 300 | struct tty_struct *o_tty; |
301 | struct tty_port *ports[2]; | ||
291 | int idx = tty->index; | 302 | int idx = tty->index; |
292 | int retval; | 303 | int retval = -ENOMEM; |
293 | 304 | ||
294 | o_tty = alloc_tty_struct(); | 305 | o_tty = alloc_tty_struct(); |
295 | if (!o_tty) | 306 | if (!o_tty) |
296 | return -ENOMEM; | 307 | goto err; |
308 | ports[0] = kmalloc(sizeof **ports, GFP_KERNEL); | ||
309 | ports[1] = kmalloc(sizeof **ports, GFP_KERNEL); | ||
310 | if (!ports[0] || !ports[1]) | ||
311 | goto err_free_tty; | ||
297 | if (!try_module_get(driver->other->owner)) { | 312 | if (!try_module_get(driver->other->owner)) { |
298 | /* This cannot in fact currently happen */ | 313 | /* This cannot in fact currently happen */ |
299 | retval = -ENOMEM; | ||
300 | goto err_free_tty; | 314 | goto err_free_tty; |
301 | } | 315 | } |
302 | initialize_tty_struct(o_tty, driver->other, idx); | 316 | initialize_tty_struct(o_tty, driver->other, idx); |
303 | 317 | ||
304 | /* We always use new tty termios data so we can do this | 318 | if (legacy) { |
305 | the easy way .. */ | 319 | /* We always use new tty termios data so we can do this |
306 | retval = tty_init_termios(tty); | 320 | the easy way .. */ |
307 | if (retval) | 321 | retval = tty_init_termios(tty); |
308 | goto err_deinit_tty; | 322 | if (retval) |
309 | 323 | goto err_deinit_tty; | |
310 | retval = tty_init_termios(o_tty); | 324 | |
311 | if (retval) | 325 | retval = tty_init_termios(o_tty); |
312 | goto err_free_termios; | 326 | if (retval) |
327 | goto err_free_termios; | ||
328 | |||
329 | driver->other->ttys[idx] = o_tty; | ||
330 | driver->ttys[idx] = tty; | ||
331 | } else { | ||
332 | memset(&tty->termios_locked, 0, sizeof(tty->termios_locked)); | ||
333 | tty->termios = driver->init_termios; | ||
334 | memset(&o_tty->termios_locked, 0, sizeof(tty->termios_locked)); | ||
335 | o_tty->termios = driver->other->init_termios; | ||
336 | } | ||
313 | 337 | ||
314 | /* | 338 | /* |
315 | * Everything allocated ... set up the o_tty structure. | 339 | * Everything allocated ... set up the o_tty structure. |
316 | */ | 340 | */ |
317 | driver->other->ttys[idx] = o_tty; | ||
318 | tty_driver_kref_get(driver->other); | 341 | tty_driver_kref_get(driver->other); |
319 | if (driver->subtype == PTY_TYPE_MASTER) | 342 | if (driver->subtype == PTY_TYPE_MASTER) |
320 | o_tty->count++; | 343 | o_tty->count++; |
321 | /* Establish the links in both directions */ | 344 | /* Establish the links in both directions */ |
322 | tty->link = o_tty; | 345 | tty->link = o_tty; |
323 | o_tty->link = tty; | 346 | o_tty->link = tty; |
347 | tty_port_init(ports[0]); | ||
348 | tty_port_init(ports[1]); | ||
349 | o_tty->port = ports[0]; | ||
350 | tty->port = ports[1]; | ||
324 | 351 | ||
325 | tty_driver_kref_get(driver); | 352 | tty_driver_kref_get(driver); |
326 | tty->count++; | 353 | tty->count++; |
327 | driver->ttys[idx] = tty; | ||
328 | return 0; | 354 | return 0; |
329 | err_free_termios: | 355 | err_free_termios: |
330 | tty_free_termios(tty); | 356 | if (legacy) |
357 | tty_free_termios(tty); | ||
331 | err_deinit_tty: | 358 | err_deinit_tty: |
332 | deinitialize_tty_struct(o_tty); | 359 | deinitialize_tty_struct(o_tty); |
333 | module_put(o_tty->driver->owner); | 360 | module_put(o_tty->driver->owner); |
334 | err_free_tty: | 361 | err_free_tty: |
362 | kfree(ports[0]); | ||
363 | kfree(ports[1]); | ||
335 | free_tty_struct(o_tty); | 364 | free_tty_struct(o_tty); |
365 | err: | ||
336 | return retval; | 366 | return retval; |
337 | } | 367 | } |
338 | 368 | ||
369 | static void pty_cleanup(struct tty_struct *tty) | ||
370 | { | ||
371 | kfree(tty->port); | ||
372 | } | ||
373 | |||
374 | /* Traditional BSD devices */ | ||
375 | #ifdef CONFIG_LEGACY_PTYS | ||
376 | |||
377 | static int pty_install(struct tty_driver *driver, struct tty_struct *tty) | ||
378 | { | ||
379 | return pty_common_install(driver, tty, true); | ||
380 | } | ||
381 | |||
382 | static void pty_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
383 | { | ||
384 | struct tty_struct *pair = tty->link; | ||
385 | driver->ttys[tty->index] = NULL; | ||
386 | if (pair) | ||
387 | pair->driver->ttys[pair->index] = NULL; | ||
388 | } | ||
389 | |||
339 | static int pty_bsd_ioctl(struct tty_struct *tty, | 390 | static int pty_bsd_ioctl(struct tty_struct *tty, |
340 | unsigned int cmd, unsigned long arg) | 391 | unsigned int cmd, unsigned long arg) |
341 | { | 392 | { |
@@ -366,7 +417,9 @@ static const struct tty_operations master_pty_ops_bsd = { | |||
366 | .unthrottle = pty_unthrottle, | 417 | .unthrottle = pty_unthrottle, |
367 | .set_termios = pty_set_termios, | 418 | .set_termios = pty_set_termios, |
368 | .ioctl = pty_bsd_ioctl, | 419 | .ioctl = pty_bsd_ioctl, |
369 | .resize = pty_resize | 420 | .cleanup = pty_cleanup, |
421 | .resize = pty_resize, | ||
422 | .remove = pty_remove | ||
370 | }; | 423 | }; |
371 | 424 | ||
372 | static const struct tty_operations slave_pty_ops_bsd = { | 425 | static const struct tty_operations slave_pty_ops_bsd = { |
@@ -379,7 +432,9 @@ static const struct tty_operations slave_pty_ops_bsd = { | |||
379 | .chars_in_buffer = pty_chars_in_buffer, | 432 | .chars_in_buffer = pty_chars_in_buffer, |
380 | .unthrottle = pty_unthrottle, | 433 | .unthrottle = pty_unthrottle, |
381 | .set_termios = pty_set_termios, | 434 | .set_termios = pty_set_termios, |
382 | .resize = pty_resize | 435 | .cleanup = pty_cleanup, |
436 | .resize = pty_resize, | ||
437 | .remove = pty_remove | ||
383 | }; | 438 | }; |
384 | 439 | ||
385 | static void __init legacy_pty_init(void) | 440 | static void __init legacy_pty_init(void) |
@@ -389,12 +444,18 @@ static void __init legacy_pty_init(void) | |||
389 | if (legacy_count <= 0) | 444 | if (legacy_count <= 0) |
390 | return; | 445 | return; |
391 | 446 | ||
392 | pty_driver = alloc_tty_driver(legacy_count); | 447 | pty_driver = tty_alloc_driver(legacy_count, |
393 | if (!pty_driver) | 448 | TTY_DRIVER_RESET_TERMIOS | |
449 | TTY_DRIVER_REAL_RAW | | ||
450 | TTY_DRIVER_DYNAMIC_ALLOC); | ||
451 | if (IS_ERR(pty_driver)) | ||
394 | panic("Couldn't allocate pty driver"); | 452 | panic("Couldn't allocate pty driver"); |
395 | 453 | ||
396 | pty_slave_driver = alloc_tty_driver(legacy_count); | 454 | pty_slave_driver = tty_alloc_driver(legacy_count, |
397 | if (!pty_slave_driver) | 455 | TTY_DRIVER_RESET_TERMIOS | |
456 | TTY_DRIVER_REAL_RAW | | ||
457 | TTY_DRIVER_DYNAMIC_ALLOC); | ||
458 | if (IS_ERR(pty_slave_driver)) | ||
398 | panic("Couldn't allocate pty slave driver"); | 459 | panic("Couldn't allocate pty slave driver"); |
399 | 460 | ||
400 | pty_driver->driver_name = "pty_master"; | 461 | pty_driver->driver_name = "pty_master"; |
@@ -410,7 +471,6 @@ static void __init legacy_pty_init(void) | |||
410 | pty_driver->init_termios.c_lflag = 0; | 471 | pty_driver->init_termios.c_lflag = 0; |
411 | pty_driver->init_termios.c_ispeed = 38400; | 472 | pty_driver->init_termios.c_ispeed = 38400; |
412 | pty_driver->init_termios.c_ospeed = 38400; | 473 | pty_driver->init_termios.c_ospeed = 38400; |
413 | pty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; | ||
414 | pty_driver->other = pty_slave_driver; | 474 | pty_driver->other = pty_slave_driver; |
415 | tty_set_operations(pty_driver, &master_pty_ops_bsd); | 475 | tty_set_operations(pty_driver, &master_pty_ops_bsd); |
416 | 476 | ||
@@ -424,8 +484,6 @@ static void __init legacy_pty_init(void) | |||
424 | pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 484 | pty_slave_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
425 | pty_slave_driver->init_termios.c_ispeed = 38400; | 485 | pty_slave_driver->init_termios.c_ispeed = 38400; |
426 | pty_slave_driver->init_termios.c_ospeed = 38400; | 486 | pty_slave_driver->init_termios.c_ospeed = 38400; |
427 | pty_slave_driver->flags = TTY_DRIVER_RESET_TERMIOS | | ||
428 | TTY_DRIVER_REAL_RAW; | ||
429 | pty_slave_driver->other = pty_driver; | 487 | pty_slave_driver->other = pty_driver; |
430 | tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd); | 488 | tty_set_operations(pty_slave_driver, &slave_pty_ops_bsd); |
431 | 489 | ||
@@ -497,78 +555,22 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver, | |||
497 | return tty; | 555 | return tty; |
498 | } | 556 | } |
499 | 557 | ||
500 | static void pty_unix98_shutdown(struct tty_struct *tty) | ||
501 | { | ||
502 | tty_driver_remove_tty(tty->driver, tty); | ||
503 | /* We have our own method as we don't use the tty index */ | ||
504 | kfree(tty->termios); | ||
505 | } | ||
506 | |||
507 | /* We have no need to install and remove our tty objects as devpts does all | 558 | /* We have no need to install and remove our tty objects as devpts does all |
508 | the work for us */ | 559 | the work for us */ |
509 | 560 | ||
510 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) | 561 | static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) |
511 | { | 562 | { |
512 | struct tty_struct *o_tty; | 563 | return pty_common_install(driver, tty, false); |
513 | int idx = tty->index; | ||
514 | |||
515 | o_tty = alloc_tty_struct(); | ||
516 | if (!o_tty) | ||
517 | return -ENOMEM; | ||
518 | if (!try_module_get(driver->other->owner)) { | ||
519 | /* This cannot in fact currently happen */ | ||
520 | goto err_free_tty; | ||
521 | } | ||
522 | initialize_tty_struct(o_tty, driver->other, idx); | ||
523 | |||
524 | tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
525 | if (tty->termios == NULL) | ||
526 | goto err_free_mem; | ||
527 | *tty->termios = driver->init_termios; | ||
528 | tty->termios_locked = tty->termios + 1; | ||
529 | |||
530 | o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | ||
531 | if (o_tty->termios == NULL) | ||
532 | goto err_free_mem; | ||
533 | *o_tty->termios = driver->other->init_termios; | ||
534 | o_tty->termios_locked = o_tty->termios + 1; | ||
535 | |||
536 | tty_driver_kref_get(driver->other); | ||
537 | if (driver->subtype == PTY_TYPE_MASTER) | ||
538 | o_tty->count++; | ||
539 | /* Establish the links in both directions */ | ||
540 | tty->link = o_tty; | ||
541 | o_tty->link = tty; | ||
542 | /* | ||
543 | * All structures have been allocated, so now we install them. | ||
544 | * Failures after this point use release_tty to clean up, so | ||
545 | * there's no need to null out the local pointers. | ||
546 | */ | ||
547 | tty_driver_kref_get(driver); | ||
548 | tty->count++; | ||
549 | return 0; | ||
550 | err_free_mem: | ||
551 | deinitialize_tty_struct(o_tty); | ||
552 | kfree(o_tty->termios); | ||
553 | kfree(tty->termios); | ||
554 | module_put(o_tty->driver->owner); | ||
555 | err_free_tty: | ||
556 | free_tty_struct(o_tty); | ||
557 | return -ENOMEM; | ||
558 | } | ||
559 | |||
560 | static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | ||
561 | { | ||
562 | } | 564 | } |
563 | 565 | ||
564 | static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) | 566 | static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) |
565 | { | 567 | { |
566 | } | 568 | } |
567 | 569 | ||
568 | static const struct tty_operations ptm_unix98_ops = { | 570 | static const struct tty_operations ptm_unix98_ops = { |
569 | .lookup = ptm_unix98_lookup, | 571 | .lookup = ptm_unix98_lookup, |
570 | .install = pty_unix98_install, | 572 | .install = pty_unix98_install, |
571 | .remove = ptm_unix98_remove, | 573 | .remove = pty_unix98_remove, |
572 | .open = pty_open, | 574 | .open = pty_open, |
573 | .close = pty_close, | 575 | .close = pty_close, |
574 | .write = pty_write, | 576 | .write = pty_write, |
@@ -578,14 +580,14 @@ static const struct tty_operations ptm_unix98_ops = { | |||
578 | .unthrottle = pty_unthrottle, | 580 | .unthrottle = pty_unthrottle, |
579 | .set_termios = pty_set_termios, | 581 | .set_termios = pty_set_termios, |
580 | .ioctl = pty_unix98_ioctl, | 582 | .ioctl = pty_unix98_ioctl, |
581 | .shutdown = pty_unix98_shutdown, | 583 | .resize = pty_resize, |
582 | .resize = pty_resize | 584 | .cleanup = pty_cleanup |
583 | }; | 585 | }; |
584 | 586 | ||
585 | static const struct tty_operations pty_unix98_ops = { | 587 | static const struct tty_operations pty_unix98_ops = { |
586 | .lookup = pts_unix98_lookup, | 588 | .lookup = pts_unix98_lookup, |
587 | .install = pty_unix98_install, | 589 | .install = pty_unix98_install, |
588 | .remove = pts_unix98_remove, | 590 | .remove = pty_unix98_remove, |
589 | .open = pty_open, | 591 | .open = pty_open, |
590 | .close = pty_close, | 592 | .close = pty_close, |
591 | .write = pty_write, | 593 | .write = pty_write, |
@@ -594,7 +596,7 @@ static const struct tty_operations pty_unix98_ops = { | |||
594 | .chars_in_buffer = pty_chars_in_buffer, | 596 | .chars_in_buffer = pty_chars_in_buffer, |
595 | .unthrottle = pty_unthrottle, | 597 | .unthrottle = pty_unthrottle, |
596 | .set_termios = pty_set_termios, | 598 | .set_termios = pty_set_termios, |
597 | .shutdown = pty_unix98_shutdown | 599 | .cleanup = pty_cleanup, |
598 | }; | 600 | }; |
599 | 601 | ||
600 | /** | 602 | /** |
@@ -622,26 +624,27 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
622 | return retval; | 624 | return retval; |
623 | 625 | ||
624 | /* find a device that is not in use. */ | 626 | /* find a device that is not in use. */ |
625 | tty_lock(); | 627 | mutex_lock(&devpts_mutex); |
626 | index = devpts_new_index(inode); | 628 | index = devpts_new_index(inode); |
627 | tty_unlock(); | ||
628 | if (index < 0) { | 629 | if (index < 0) { |
629 | retval = index; | 630 | retval = index; |
630 | goto err_file; | 631 | goto err_file; |
631 | } | 632 | } |
632 | 633 | ||
634 | mutex_unlock(&devpts_mutex); | ||
635 | |||
633 | mutex_lock(&tty_mutex); | 636 | mutex_lock(&tty_mutex); |
634 | mutex_lock(&devpts_mutex); | ||
635 | tty = tty_init_dev(ptm_driver, index); | 637 | tty = tty_init_dev(ptm_driver, index); |
636 | mutex_unlock(&devpts_mutex); | ||
637 | tty_lock(); | ||
638 | mutex_unlock(&tty_mutex); | ||
639 | 638 | ||
640 | if (IS_ERR(tty)) { | 639 | if (IS_ERR(tty)) { |
641 | retval = PTR_ERR(tty); | 640 | retval = PTR_ERR(tty); |
642 | goto out; | 641 | goto out; |
643 | } | 642 | } |
644 | 643 | ||
644 | /* The tty returned here is locked so we can safely | ||
645 | drop the mutex */ | ||
646 | mutex_unlock(&tty_mutex); | ||
647 | |||
645 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ | 648 | set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */ |
646 | 649 | ||
647 | tty_add_file(tty, filp); | 650 | tty_add_file(tty, filp); |
@@ -654,16 +657,17 @@ static int ptmx_open(struct inode *inode, struct file *filp) | |||
654 | if (retval) | 657 | if (retval) |
655 | goto err_release; | 658 | goto err_release; |
656 | 659 | ||
657 | tty_unlock(); | 660 | tty_unlock(tty); |
658 | return 0; | 661 | return 0; |
659 | err_release: | 662 | err_release: |
660 | tty_unlock(); | 663 | tty_unlock(tty); |
661 | tty_release(inode, filp); | 664 | tty_release(inode, filp); |
662 | return retval; | 665 | return retval; |
663 | out: | 666 | out: |
667 | mutex_unlock(&tty_mutex); | ||
664 | devpts_kill_index(inode, index); | 668 | devpts_kill_index(inode, index); |
665 | tty_unlock(); | ||
666 | err_file: | 669 | err_file: |
670 | mutex_unlock(&devpts_mutex); | ||
667 | tty_free_file(filp); | 671 | tty_free_file(filp); |
668 | return retval; | 672 | return retval; |
669 | } | 673 | } |
@@ -672,11 +676,21 @@ static struct file_operations ptmx_fops; | |||
672 | 676 | ||
673 | static void __init unix98_pty_init(void) | 677 | static void __init unix98_pty_init(void) |
674 | { | 678 | { |
675 | ptm_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); | 679 | ptm_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX, |
676 | if (!ptm_driver) | 680 | TTY_DRIVER_RESET_TERMIOS | |
681 | TTY_DRIVER_REAL_RAW | | ||
682 | TTY_DRIVER_DYNAMIC_DEV | | ||
683 | TTY_DRIVER_DEVPTS_MEM | | ||
684 | TTY_DRIVER_DYNAMIC_ALLOC); | ||
685 | if (IS_ERR(ptm_driver)) | ||
677 | panic("Couldn't allocate Unix98 ptm driver"); | 686 | panic("Couldn't allocate Unix98 ptm driver"); |
678 | pts_driver = alloc_tty_driver(NR_UNIX98_PTY_MAX); | 687 | pts_driver = tty_alloc_driver(NR_UNIX98_PTY_MAX, |
679 | if (!pts_driver) | 688 | TTY_DRIVER_RESET_TERMIOS | |
689 | TTY_DRIVER_REAL_RAW | | ||
690 | TTY_DRIVER_DYNAMIC_DEV | | ||
691 | TTY_DRIVER_DEVPTS_MEM | | ||
692 | TTY_DRIVER_DYNAMIC_ALLOC); | ||
693 | if (IS_ERR(pts_driver)) | ||
680 | panic("Couldn't allocate Unix98 pts driver"); | 694 | panic("Couldn't allocate Unix98 pts driver"); |
681 | 695 | ||
682 | ptm_driver->driver_name = "pty_master"; | 696 | ptm_driver->driver_name = "pty_master"; |
@@ -692,8 +706,6 @@ static void __init unix98_pty_init(void) | |||
692 | ptm_driver->init_termios.c_lflag = 0; | 706 | ptm_driver->init_termios.c_lflag = 0; |
693 | ptm_driver->init_termios.c_ispeed = 38400; | 707 | ptm_driver->init_termios.c_ispeed = 38400; |
694 | ptm_driver->init_termios.c_ospeed = 38400; | 708 | ptm_driver->init_termios.c_ospeed = 38400; |
695 | ptm_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | ||
696 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | ||
697 | ptm_driver->other = pts_driver; | 709 | ptm_driver->other = pts_driver; |
698 | tty_set_operations(ptm_driver, &ptm_unix98_ops); | 710 | tty_set_operations(ptm_driver, &ptm_unix98_ops); |
699 | 711 | ||
@@ -707,8 +719,6 @@ static void __init unix98_pty_init(void) | |||
707 | pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; | 719 | pts_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; |
708 | pts_driver->init_termios.c_ispeed = 38400; | 720 | pts_driver->init_termios.c_ispeed = 38400; |
709 | pts_driver->init_termios.c_ospeed = 38400; | 721 | pts_driver->init_termios.c_ospeed = 38400; |
710 | pts_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW | | ||
711 | TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_DEVPTS_MEM; | ||
712 | pts_driver->other = ptm_driver; | 722 | pts_driver->other = ptm_driver; |
713 | tty_set_operations(pts_driver, &pty_unix98_ops); | 723 | tty_set_operations(pts_driver, &pty_unix98_ops); |
714 | 724 | ||
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c index 777d5f9cf6cc..9700d34b20a3 100644 --- a/drivers/tty/rocket.c +++ b/drivers/tty/rocket.c | |||
@@ -704,8 +704,8 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev) | |||
704 | spin_lock_init(&info->slock); | 704 | spin_lock_init(&info->slock); |
705 | mutex_init(&info->write_mtx); | 705 | mutex_init(&info->write_mtx); |
706 | rp_table[line] = info; | 706 | rp_table[line] = info; |
707 | tty_register_device(rocket_driver, line, pci_dev ? &pci_dev->dev : | 707 | tty_port_register_device(&info->port, rocket_driver, line, |
708 | NULL); | 708 | pci_dev ? &pci_dev->dev : NULL); |
709 | } | 709 | } |
710 | 710 | ||
711 | /* | 711 | /* |
@@ -720,7 +720,7 @@ static void configure_r_port(struct tty_struct *tty, struct r_port *info, | |||
720 | unsigned rocketMode; | 720 | unsigned rocketMode; |
721 | int bits, baud, divisor; | 721 | int bits, baud, divisor; |
722 | CHANNEL_t *cp; | 722 | CHANNEL_t *cp; |
723 | struct ktermios *t = tty->termios; | 723 | struct ktermios *t = &tty->termios; |
724 | 724 | ||
725 | cp = &info->channel; | 725 | cp = &info->channel; |
726 | cflag = t->c_cflag; | 726 | cflag = t->c_cflag; |
@@ -978,7 +978,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp) | |||
978 | tty->alt_speed = 460800; | 978 | tty->alt_speed = 460800; |
979 | 979 | ||
980 | configure_r_port(tty, info, NULL); | 980 | configure_r_port(tty, info, NULL); |
981 | if (tty->termios->c_cflag & CBAUD) { | 981 | if (tty->termios.c_cflag & CBAUD) { |
982 | sSetDTR(cp); | 982 | sSetDTR(cp); |
983 | sSetRTS(cp); | 983 | sSetRTS(cp); |
984 | } | 984 | } |
@@ -1089,35 +1089,35 @@ static void rp_set_termios(struct tty_struct *tty, | |||
1089 | if (rocket_paranoia_check(info, "rp_set_termios")) | 1089 | if (rocket_paranoia_check(info, "rp_set_termios")) |
1090 | return; | 1090 | return; |
1091 | 1091 | ||
1092 | cflag = tty->termios->c_cflag; | 1092 | cflag = tty->termios.c_cflag; |
1093 | 1093 | ||
1094 | /* | 1094 | /* |
1095 | * This driver doesn't support CS5 or CS6 | 1095 | * This driver doesn't support CS5 or CS6 |
1096 | */ | 1096 | */ |
1097 | if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6)) | 1097 | if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6)) |
1098 | tty->termios->c_cflag = | 1098 | tty->termios.c_cflag = |
1099 | ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE)); | 1099 | ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE)); |
1100 | /* Or CMSPAR */ | 1100 | /* Or CMSPAR */ |
1101 | tty->termios->c_cflag &= ~CMSPAR; | 1101 | tty->termios.c_cflag &= ~CMSPAR; |
1102 | 1102 | ||
1103 | configure_r_port(tty, info, old_termios); | 1103 | configure_r_port(tty, info, old_termios); |
1104 | 1104 | ||
1105 | cp = &info->channel; | 1105 | cp = &info->channel; |
1106 | 1106 | ||
1107 | /* Handle transition to B0 status */ | 1107 | /* Handle transition to B0 status */ |
1108 | if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) { | 1108 | if ((old_termios->c_cflag & CBAUD) && !(tty->termios.c_cflag & CBAUD)) { |
1109 | sClrDTR(cp); | 1109 | sClrDTR(cp); |
1110 | sClrRTS(cp); | 1110 | sClrRTS(cp); |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | /* Handle transition away from B0 status */ | 1113 | /* Handle transition away from B0 status */ |
1114 | if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) { | 1114 | if (!(old_termios->c_cflag & CBAUD) && (tty->termios.c_cflag & CBAUD)) { |
1115 | if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS)) | 1115 | if (!tty->hw_stopped || !(tty->termios.c_cflag & CRTSCTS)) |
1116 | sSetRTS(cp); | 1116 | sSetRTS(cp); |
1117 | sSetDTR(cp); | 1117 | sSetDTR(cp); |
1118 | } | 1118 | } |
1119 | 1119 | ||
1120 | if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { | 1120 | if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) { |
1121 | tty->hw_stopped = 0; | 1121 | tty->hw_stopped = 0; |
1122 | rp_start(tty); | 1122 | rp_start(tty); |
1123 | } | 1123 | } |
diff --git a/drivers/tty/serial/68328serial.c b/drivers/tty/serial/68328serial.c index 3ed20e435e59..66c38a3f74ce 100644 --- a/drivers/tty/serial/68328serial.c +++ b/drivers/tty/serial/68328serial.c | |||
@@ -515,7 +515,7 @@ static void change_speed(struct m68k_serial *info, struct tty_struct *tty) | |||
515 | unsigned cflag; | 515 | unsigned cflag; |
516 | int i; | 516 | int i; |
517 | 517 | ||
518 | cflag = tty->termios->c_cflag; | 518 | cflag = tty->termios.c_cflag; |
519 | if (!(port = info->port)) | 519 | if (!(port = info->port)) |
520 | return; | 520 | return; |
521 | 521 | ||
@@ -617,7 +617,7 @@ static void rs_set_ldisc(struct tty_struct *tty) | |||
617 | if (serial_paranoia_check(info, tty->name, "rs_set_ldisc")) | 617 | if (serial_paranoia_check(info, tty->name, "rs_set_ldisc")) |
618 | return; | 618 | return; |
619 | 619 | ||
620 | info->is_cons = (tty->termios->c_line == N_TTY); | 620 | info->is_cons = (tty->termios.c_line == N_TTY); |
621 | 621 | ||
622 | printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off"); | 622 | printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off"); |
623 | } | 623 | } |
@@ -985,7 +985,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
985 | change_speed(info, tty); | 985 | change_speed(info, tty); |
986 | 986 | ||
987 | if ((old_termios->c_cflag & CRTSCTS) && | 987 | if ((old_termios->c_cflag & CRTSCTS) && |
988 | !(tty->termios->c_cflag & CRTSCTS)) { | 988 | !(tty->termios.c_cflag & CRTSCTS)) { |
989 | tty->hw_stopped = 0; | 989 | tty->hw_stopped = 0; |
990 | rs_start(tty); | 990 | rs_start(tty); |
991 | } | 991 | } |
@@ -1070,7 +1070,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) | |||
1070 | if (tty->ldisc.close) | 1070 | if (tty->ldisc.close) |
1071 | (tty->ldisc.close)(tty); | 1071 | (tty->ldisc.close)(tty); |
1072 | tty->ldisc = ldiscs[N_TTY]; | 1072 | tty->ldisc = ldiscs[N_TTY]; |
1073 | tty->termios->c_line = N_TTY; | 1073 | tty->termios.c_line = N_TTY; |
1074 | if (tty->ldisc.open) | 1074 | if (tty->ldisc.open) |
1075 | (tty->ldisc.open)(tty); | 1075 | (tty->ldisc.open)(tty); |
1076 | } | 1076 | } |
@@ -1189,12 +1189,6 @@ rs68328_init(void) | |||
1189 | serial_driver->flags = TTY_DRIVER_REAL_RAW; | 1189 | serial_driver->flags = TTY_DRIVER_REAL_RAW; |
1190 | tty_set_operations(serial_driver, &rs_ops); | 1190 | tty_set_operations(serial_driver, &rs_ops); |
1191 | 1191 | ||
1192 | if (tty_register_driver(serial_driver)) { | ||
1193 | put_tty_driver(serial_driver); | ||
1194 | printk(KERN_ERR "Couldn't register serial driver\n"); | ||
1195 | return -ENOMEM; | ||
1196 | } | ||
1197 | |||
1198 | local_irq_save(flags); | 1192 | local_irq_save(flags); |
1199 | 1193 | ||
1200 | for(i=0;i<NR_PORTS;i++) { | 1194 | for(i=0;i<NR_PORTS;i++) { |
@@ -1224,8 +1218,17 @@ rs68328_init(void) | |||
1224 | 0, | 1218 | 0, |
1225 | "M68328_UART", info)) | 1219 | "M68328_UART", info)) |
1226 | panic("Unable to attach 68328 serial interrupt\n"); | 1220 | panic("Unable to attach 68328 serial interrupt\n"); |
1221 | |||
1222 | tty_port_link_device(&info->tport, serial_driver, i); | ||
1227 | } | 1223 | } |
1228 | local_irq_restore(flags); | 1224 | local_irq_restore(flags); |
1225 | |||
1226 | if (tty_register_driver(serial_driver)) { | ||
1227 | put_tty_driver(serial_driver); | ||
1228 | printk(KERN_ERR "Couldn't register serial driver\n"); | ||
1229 | return -ENOMEM; | ||
1230 | } | ||
1231 | |||
1229 | return 0; | 1232 | return 0; |
1230 | } | 1233 | } |
1231 | 1234 | ||
diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 8123f784bcda..d4e0b07cb130 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c | |||
@@ -2202,6 +2202,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2202 | unsigned char cval, fcr = 0; | 2202 | unsigned char cval, fcr = 0; |
2203 | unsigned long flags; | 2203 | unsigned long flags; |
2204 | unsigned int baud, quot; | 2204 | unsigned int baud, quot; |
2205 | int fifo_bug = 0; | ||
2205 | 2206 | ||
2206 | switch (termios->c_cflag & CSIZE) { | 2207 | switch (termios->c_cflag & CSIZE) { |
2207 | case CS5: | 2208 | case CS5: |
@@ -2221,8 +2222,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2221 | 2222 | ||
2222 | if (termios->c_cflag & CSTOPB) | 2223 | if (termios->c_cflag & CSTOPB) |
2223 | cval |= UART_LCR_STOP; | 2224 | cval |= UART_LCR_STOP; |
2224 | if (termios->c_cflag & PARENB) | 2225 | if (termios->c_cflag & PARENB) { |
2225 | cval |= UART_LCR_PARITY; | 2226 | cval |= UART_LCR_PARITY; |
2227 | if (up->bugs & UART_BUG_PARITY) | ||
2228 | fifo_bug = 1; | ||
2229 | } | ||
2226 | if (!(termios->c_cflag & PARODD)) | 2230 | if (!(termios->c_cflag & PARODD)) |
2227 | cval |= UART_LCR_EPAR; | 2231 | cval |= UART_LCR_EPAR; |
2228 | #ifdef CMSPAR | 2232 | #ifdef CMSPAR |
@@ -2246,7 +2250,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2246 | 2250 | ||
2247 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { | 2251 | if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) { |
2248 | fcr = uart_config[port->type].fcr; | 2252 | fcr = uart_config[port->type].fcr; |
2249 | if (baud < 2400) { | 2253 | if (baud < 2400 || fifo_bug) { |
2250 | fcr &= ~UART_FCR_TRIGGER_MASK; | 2254 | fcr &= ~UART_FCR_TRIGGER_MASK; |
2251 | fcr |= UART_FCR_TRIGGER_1; | 2255 | fcr |= UART_FCR_TRIGGER_1; |
2252 | } | 2256 | } |
@@ -2336,7 +2340,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios, | |||
2336 | serial_port_out(port, UART_EFR, efr); | 2340 | serial_port_out(port, UART_EFR, efr); |
2337 | } | 2341 | } |
2338 | 2342 | ||
2339 | #ifdef CONFIG_ARCH_OMAP | 2343 | #ifdef CONFIG_ARCH_OMAP1 |
2340 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ | 2344 | /* Workaround to enable 115200 baud on OMAP1510 internal ports */ |
2341 | if (cpu_is_omap1510() && is_omap_port(up)) { | 2345 | if (cpu_is_omap1510() && is_omap_port(up)) { |
2342 | if (baud == 115200) { | 2346 | if (baud == 115200) { |
@@ -2426,7 +2430,7 @@ static unsigned int serial8250_port_size(struct uart_8250_port *pt) | |||
2426 | { | 2430 | { |
2427 | if (pt->port.iotype == UPIO_AU) | 2431 | if (pt->port.iotype == UPIO_AU) |
2428 | return 0x1000; | 2432 | return 0x1000; |
2429 | #ifdef CONFIG_ARCH_OMAP | 2433 | #ifdef CONFIG_ARCH_OMAP1 |
2430 | if (is_omap_port(pt)) | 2434 | if (is_omap_port(pt)) |
2431 | return 0x16 << pt->port.regshift; | 2435 | return 0x16 << pt->port.regshift; |
2432 | #endif | 2436 | #endif |
@@ -2979,36 +2983,36 @@ void serial8250_resume_port(int line) | |||
2979 | static int __devinit serial8250_probe(struct platform_device *dev) | 2983 | static int __devinit serial8250_probe(struct platform_device *dev) |
2980 | { | 2984 | { |
2981 | struct plat_serial8250_port *p = dev->dev.platform_data; | 2985 | struct plat_serial8250_port *p = dev->dev.platform_data; |
2982 | struct uart_port port; | 2986 | struct uart_8250_port uart; |
2983 | int ret, i, irqflag = 0; | 2987 | int ret, i, irqflag = 0; |
2984 | 2988 | ||
2985 | memset(&port, 0, sizeof(struct uart_port)); | 2989 | memset(&uart, 0, sizeof(uart)); |
2986 | 2990 | ||
2987 | if (share_irqs) | 2991 | if (share_irqs) |
2988 | irqflag = IRQF_SHARED; | 2992 | irqflag = IRQF_SHARED; |
2989 | 2993 | ||
2990 | for (i = 0; p && p->flags != 0; p++, i++) { | 2994 | for (i = 0; p && p->flags != 0; p++, i++) { |
2991 | port.iobase = p->iobase; | 2995 | uart.port.iobase = p->iobase; |
2992 | port.membase = p->membase; | 2996 | uart.port.membase = p->membase; |
2993 | port.irq = p->irq; | 2997 | uart.port.irq = p->irq; |
2994 | port.irqflags = p->irqflags; | 2998 | uart.port.irqflags = p->irqflags; |
2995 | port.uartclk = p->uartclk; | 2999 | uart.port.uartclk = p->uartclk; |
2996 | port.regshift = p->regshift; | 3000 | uart.port.regshift = p->regshift; |
2997 | port.iotype = p->iotype; | 3001 | uart.port.iotype = p->iotype; |
2998 | port.flags = p->flags; | 3002 | uart.port.flags = p->flags; |
2999 | port.mapbase = p->mapbase; | 3003 | uart.port.mapbase = p->mapbase; |
3000 | port.hub6 = p->hub6; | 3004 | uart.port.hub6 = p->hub6; |
3001 | port.private_data = p->private_data; | 3005 | uart.port.private_data = p->private_data; |
3002 | port.type = p->type; | 3006 | uart.port.type = p->type; |
3003 | port.serial_in = p->serial_in; | 3007 | uart.port.serial_in = p->serial_in; |
3004 | port.serial_out = p->serial_out; | 3008 | uart.port.serial_out = p->serial_out; |
3005 | port.handle_irq = p->handle_irq; | 3009 | uart.port.handle_irq = p->handle_irq; |
3006 | port.handle_break = p->handle_break; | 3010 | uart.port.handle_break = p->handle_break; |
3007 | port.set_termios = p->set_termios; | 3011 | uart.port.set_termios = p->set_termios; |
3008 | port.pm = p->pm; | 3012 | uart.port.pm = p->pm; |
3009 | port.dev = &dev->dev; | 3013 | uart.port.dev = &dev->dev; |
3010 | port.irqflags |= irqflag; | 3014 | uart.port.irqflags |= irqflag; |
3011 | ret = serial8250_register_port(&port); | 3015 | ret = serial8250_register_8250_port(&uart); |
3012 | if (ret < 0) { | 3016 | if (ret < 0) { |
3013 | dev_err(&dev->dev, "unable to register port at index %d " | 3017 | dev_err(&dev->dev, "unable to register port at index %d " |
3014 | "(IO%lx MEM%llx IRQ%d): %d\n", i, | 3018 | "(IO%lx MEM%llx IRQ%d): %d\n", i, |
@@ -3081,7 +3085,7 @@ static struct platform_driver serial8250_isa_driver = { | |||
3081 | static struct platform_device *serial8250_isa_devs; | 3085 | static struct platform_device *serial8250_isa_devs; |
3082 | 3086 | ||
3083 | /* | 3087 | /* |
3084 | * serial8250_register_port and serial8250_unregister_port allows for | 3088 | * serial8250_register_8250_port and serial8250_unregister_port allows for |
3085 | * 16x50 serial ports to be configured at run-time, to support PCMCIA | 3089 | * 16x50 serial ports to be configured at run-time, to support PCMCIA |
3086 | * modems and PCI multiport cards. | 3090 | * modems and PCI multiport cards. |
3087 | */ | 3091 | */ |
@@ -3155,6 +3159,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3155 | uart->port.regshift = up->port.regshift; | 3159 | uart->port.regshift = up->port.regshift; |
3156 | uart->port.iotype = up->port.iotype; | 3160 | uart->port.iotype = up->port.iotype; |
3157 | uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF; | 3161 | uart->port.flags = up->port.flags | UPF_BOOT_AUTOCONF; |
3162 | uart->bugs = up->bugs; | ||
3158 | uart->port.mapbase = up->port.mapbase; | 3163 | uart->port.mapbase = up->port.mapbase; |
3159 | uart->port.private_data = up->port.private_data; | 3164 | uart->port.private_data = up->port.private_data; |
3160 | if (up->port.dev) | 3165 | if (up->port.dev) |
@@ -3198,29 +3203,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up) | |||
3198 | EXPORT_SYMBOL(serial8250_register_8250_port); | 3203 | EXPORT_SYMBOL(serial8250_register_8250_port); |
3199 | 3204 | ||
3200 | /** | 3205 | /** |
3201 | * serial8250_register_port - register a serial port | ||
3202 | * @port: serial port template | ||
3203 | * | ||
3204 | * Configure the serial port specified by the request. If the | ||
3205 | * port exists and is in use, it is hung up and unregistered | ||
3206 | * first. | ||
3207 | * | ||
3208 | * The port is then probed and if necessary the IRQ is autodetected | ||
3209 | * If this fails an error is returned. | ||
3210 | * | ||
3211 | * On success the port is ready to use and the line number is returned. | ||
3212 | */ | ||
3213 | int serial8250_register_port(struct uart_port *port) | ||
3214 | { | ||
3215 | struct uart_8250_port up; | ||
3216 | |||
3217 | memset(&up, 0, sizeof(up)); | ||
3218 | memcpy(&up.port, port, sizeof(*port)); | ||
3219 | return serial8250_register_8250_port(&up); | ||
3220 | } | ||
3221 | EXPORT_SYMBOL(serial8250_register_port); | ||
3222 | |||
3223 | /** | ||
3224 | * serial8250_unregister_port - remove a 16x50 serial port at runtime | 3206 | * serial8250_unregister_port - remove a 16x50 serial port at runtime |
3225 | * @line: serial line number | 3207 | * @line: serial line number |
3226 | * | 3208 | * |
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index f9719d167c8d..0c5e908df0b5 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h | |||
@@ -13,36 +13,6 @@ | |||
13 | 13 | ||
14 | #include <linux/serial_8250.h> | 14 | #include <linux/serial_8250.h> |
15 | 15 | ||
16 | struct uart_8250_port { | ||
17 | struct uart_port port; | ||
18 | struct timer_list timer; /* "no irq" timer */ | ||
19 | struct list_head list; /* ports on this IRQ */ | ||
20 | unsigned short capabilities; /* port capabilities */ | ||
21 | unsigned short bugs; /* port bugs */ | ||
22 | unsigned int tx_loadsz; /* transmit fifo load size */ | ||
23 | unsigned char acr; | ||
24 | unsigned char ier; | ||
25 | unsigned char lcr; | ||
26 | unsigned char mcr; | ||
27 | unsigned char mcr_mask; /* mask of user bits */ | ||
28 | unsigned char mcr_force; /* mask of forced bits */ | ||
29 | unsigned char cur_iotype; /* Running I/O type */ | ||
30 | |||
31 | /* | ||
32 | * Some bits in registers are cleared on a read, so they must | ||
33 | * be saved whenever the register is read but the bits will not | ||
34 | * be immediately processed. | ||
35 | */ | ||
36 | #define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS | ||
37 | unsigned char lsr_saved_flags; | ||
38 | #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA | ||
39 | unsigned char msr_saved_flags; | ||
40 | |||
41 | /* 8250 specific callbacks */ | ||
42 | int (*dl_read)(struct uart_8250_port *); | ||
43 | void (*dl_write)(struct uart_8250_port *, int); | ||
44 | }; | ||
45 | |||
46 | struct old_serial_port { | 16 | struct old_serial_port { |
47 | unsigned int uart; | 17 | unsigned int uart; |
48 | unsigned int baud_base; | 18 | unsigned int baud_base; |
@@ -56,9 +26,6 @@ struct old_serial_port { | |||
56 | unsigned long irqflags; | 26 | unsigned long irqflags; |
57 | }; | 27 | }; |
58 | 28 | ||
59 | /* | ||
60 | * This replaces serial_uart_config in include/linux/serial.h | ||
61 | */ | ||
62 | struct serial8250_config { | 29 | struct serial8250_config { |
63 | const char *name; | 30 | const char *name; |
64 | unsigned short fifo_size; | 31 | unsigned short fifo_size; |
@@ -78,6 +45,7 @@ struct serial8250_config { | |||
78 | #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ | 45 | #define UART_BUG_TXEN (1 << 1) /* UART has buggy TX IIR status */ |
79 | #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ | 46 | #define UART_BUG_NOMSR (1 << 2) /* UART has buggy MSR status bits (Au1x00) */ |
80 | #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ | 47 | #define UART_BUG_THRE (1 << 3) /* UART has buggy THRE reassertion */ |
48 | #define UART_BUG_PARITY (1 << 4) /* UART mishandles parity if FIFO enabled */ | ||
81 | 49 | ||
82 | #define PROBE_RSA (1 << 0) | 50 | #define PROBE_RSA (1 << 0) |
83 | #define PROBE_ANY (~0) | 51 | #define PROBE_ANY (~0) |
diff --git a/drivers/tty/serial/8250/8250_acorn.c b/drivers/tty/serial/8250/8250_acorn.c index b0ce8c56f1a4..857498312a9a 100644 --- a/drivers/tty/serial/8250/8250_acorn.c +++ b/drivers/tty/serial/8250/8250_acorn.c | |||
@@ -43,7 +43,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
43 | { | 43 | { |
44 | struct serial_card_info *info; | 44 | struct serial_card_info *info; |
45 | struct serial_card_type *type = id->data; | 45 | struct serial_card_type *type = id->data; |
46 | struct uart_port port; | 46 | struct uart_8250_port uart; |
47 | unsigned long bus_addr; | 47 | unsigned long bus_addr; |
48 | unsigned int i; | 48 | unsigned int i; |
49 | 49 | ||
@@ -62,19 +62,19 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id) | |||
62 | 62 | ||
63 | ecard_set_drvdata(ec, info); | 63 | ecard_set_drvdata(ec, info); |
64 | 64 | ||
65 | memset(&port, 0, sizeof(struct uart_port)); | 65 | memset(&uart, 0, sizeof(struct uart_8250_port)); |
66 | port.irq = ec->irq; | 66 | uart.port.irq = ec->irq; |
67 | port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | 67 | uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; |
68 | port.uartclk = type->uartclk; | 68 | uart.port.uartclk = type->uartclk; |
69 | port.iotype = UPIO_MEM; | 69 | uart.port.iotype = UPIO_MEM; |
70 | port.regshift = 2; | 70 | uart.port.regshift = 2; |
71 | port.dev = &ec->dev; | 71 | uart.port.dev = &ec->dev; |
72 | 72 | ||
73 | for (i = 0; i < info->num_ports; i ++) { | 73 | for (i = 0; i < info->num_ports; i ++) { |
74 | port.membase = info->vaddr + type->offset[i]; | 74 | uart.port.membase = info->vaddr + type->offset[i]; |
75 | port.mapbase = bus_addr + type->offset[i]; | 75 | uart.port.mapbase = bus_addr + type->offset[i]; |
76 | 76 | ||
77 | info->ports[i] = serial8250_register_port(&port); | 77 | info->ports[i] = serial8250_register_8250_port(&uart); |
78 | } | 78 | } |
79 | 79 | ||
80 | return 0; | 80 | return 0; |
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index f574eef3075f..c3b2ec0c8c0b 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c | |||
@@ -89,7 +89,7 @@ static int dw8250_handle_irq(struct uart_port *p) | |||
89 | 89 | ||
90 | static int __devinit dw8250_probe(struct platform_device *pdev) | 90 | static int __devinit dw8250_probe(struct platform_device *pdev) |
91 | { | 91 | { |
92 | struct uart_port port = {}; | 92 | struct uart_8250_port uart = {}; |
93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 93 | struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
94 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 94 | struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
95 | struct device_node *np = pdev->dev.of_node; | 95 | struct device_node *np = pdev->dev.of_node; |
@@ -104,28 +104,28 @@ static int __devinit dw8250_probe(struct platform_device *pdev) | |||
104 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | 104 | data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); |
105 | if (!data) | 105 | if (!data) |
106 | return -ENOMEM; | 106 | return -ENOMEM; |
107 | port.private_data = data; | 107 | uart.port.private_data = data; |
108 | 108 | ||
109 | spin_lock_init(&port.lock); | 109 | spin_lock_init(&uart.port.lock); |
110 | port.mapbase = regs->start; | 110 | uart.port.mapbase = regs->start; |
111 | port.irq = irq->start; | 111 | uart.port.irq = irq->start; |
112 | port.handle_irq = dw8250_handle_irq; | 112 | uart.port.handle_irq = dw8250_handle_irq; |
113 | port.type = PORT_8250; | 113 | uart.port.type = PORT_8250; |
114 | port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | | 114 | uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | |
115 | UPF_FIXED_PORT | UPF_FIXED_TYPE; | 115 | UPF_FIXED_PORT | UPF_FIXED_TYPE; |
116 | port.dev = &pdev->dev; | 116 | uart.port.dev = &pdev->dev; |
117 | 117 | ||
118 | port.iotype = UPIO_MEM; | 118 | uart.port.iotype = UPIO_MEM; |
119 | port.serial_in = dw8250_serial_in; | 119 | uart.port.serial_in = dw8250_serial_in; |
120 | port.serial_out = dw8250_serial_out; | 120 | uart.port.serial_out = dw8250_serial_out; |
121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { | 121 | if (!of_property_read_u32(np, "reg-io-width", &val)) { |
122 | switch (val) { | 122 | switch (val) { |
123 | case 1: | 123 | case 1: |
124 | break; | 124 | break; |
125 | case 4: | 125 | case 4: |
126 | port.iotype = UPIO_MEM32; | 126 | uart.port.iotype = UPIO_MEM32; |
127 | port.serial_in = dw8250_serial_in32; | 127 | uart.port.serial_in = dw8250_serial_in32; |
128 | port.serial_out = dw8250_serial_out32; | 128 | uart.port.serial_out = dw8250_serial_out32; |
129 | break; | 129 | break; |
130 | default: | 130 | default: |
131 | dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n", | 131 | dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n", |
@@ -135,15 +135,15 @@ static int __devinit dw8250_probe(struct platform_device *pdev) | |||
135 | } | 135 | } |
136 | 136 | ||
137 | if (!of_property_read_u32(np, "reg-shift", &val)) | 137 | if (!of_property_read_u32(np, "reg-shift", &val)) |
138 | port.regshift = val; | 138 | uart.port.regshift = val; |
139 | 139 | ||
140 | if (of_property_read_u32(np, "clock-frequency", &val)) { | 140 | if (of_property_read_u32(np, "clock-frequency", &val)) { |
141 | dev_err(&pdev->dev, "no clock-frequency property set\n"); | 141 | dev_err(&pdev->dev, "no clock-frequency property set\n"); |
142 | return -EINVAL; | 142 | return -EINVAL; |
143 | } | 143 | } |
144 | port.uartclk = val; | 144 | uart.port.uartclk = val; |
145 | 145 | ||
146 | data->line = serial8250_register_port(&port); | 146 | data->line = serial8250_register_8250_port(&uart); |
147 | if (data->line < 0) | 147 | if (data->line < 0) |
148 | return data->line; | 148 | return data->line; |
149 | 149 | ||
diff --git a/drivers/tty/serial/8250/8250_gsc.c b/drivers/tty/serial/8250/8250_gsc.c index d8c0ffbfa6e3..097dff9c08ad 100644 --- a/drivers/tty/serial/8250/8250_gsc.c +++ b/drivers/tty/serial/8250/8250_gsc.c | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | static int __init serial_init_chip(struct parisc_device *dev) | 27 | static int __init serial_init_chip(struct parisc_device *dev) |
28 | { | 28 | { |
29 | struct uart_port port; | 29 | struct uart_8250_port uart; |
30 | unsigned long address; | 30 | unsigned long address; |
31 | int err; | 31 | int err; |
32 | 32 | ||
@@ -48,21 +48,21 @@ static int __init serial_init_chip(struct parisc_device *dev) | |||
48 | if (dev->id.sversion != 0x8d) | 48 | if (dev->id.sversion != 0x8d) |
49 | address += 0x800; | 49 | address += 0x800; |
50 | 50 | ||
51 | memset(&port, 0, sizeof(port)); | 51 | memset(&uart, 0, sizeof(uart)); |
52 | port.iotype = UPIO_MEM; | 52 | uart.port.iotype = UPIO_MEM; |
53 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ | 53 | /* 7.272727MHz on Lasi. Assumed the same for Dino, Wax and Timi. */ |
54 | port.uartclk = 7272727; | 54 | uart.port.uartclk = 7272727; |
55 | port.mapbase = address; | 55 | uart.port.mapbase = address; |
56 | port.membase = ioremap_nocache(address, 16); | 56 | uart.port.membase = ioremap_nocache(address, 16); |
57 | port.irq = dev->irq; | 57 | uart.port.irq = dev->irq; |
58 | port.flags = UPF_BOOT_AUTOCONF; | 58 | uart.port.flags = UPF_BOOT_AUTOCONF; |
59 | port.dev = &dev->dev; | 59 | uart.port.dev = &dev->dev; |
60 | 60 | ||
61 | err = serial8250_register_port(&port); | 61 | err = serial8250_register_8250_port(&uart); |
62 | if (err < 0) { | 62 | if (err < 0) { |
63 | printk(KERN_WARNING | 63 | printk(KERN_WARNING |
64 | "serial8250_register_port returned error %d\n", err); | 64 | "serial8250_register_8250_port returned error %d\n", err); |
65 | iounmap(port.membase); | 65 | iounmap(uart.port.membase); |
66 | return err; | 66 | return err; |
67 | } | 67 | } |
68 | 68 | ||
diff --git a/drivers/tty/serial/8250/8250_hp300.c b/drivers/tty/serial/8250/8250_hp300.c index c13438c93012..8f1dd2cc00a8 100644 --- a/drivers/tty/serial/8250/8250_hp300.c +++ b/drivers/tty/serial/8250/8250_hp300.c | |||
@@ -171,7 +171,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d, | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | #endif | 173 | #endif |
174 | memset(&port, 0, sizeof(struct uart_port)); | 174 | memset(&uart, 0, sizeof(uart)); |
175 | 175 | ||
176 | /* Memory mapped I/O */ | 176 | /* Memory mapped I/O */ |
177 | port.iotype = UPIO_MEM; | 177 | port.iotype = UPIO_MEM; |
@@ -182,7 +182,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d, | |||
182 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); | 182 | port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE); |
183 | port.regshift = 1; | 183 | port.regshift = 1; |
184 | port.dev = &d->dev; | 184 | port.dev = &d->dev; |
185 | line = serial8250_register_port(&port); | 185 | line = serial8250_register_8250_port(&uart); |
186 | 186 | ||
187 | if (line < 0) { | 187 | if (line < 0) { |
188 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" | 188 | printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d" |
@@ -210,7 +210,7 @@ static int __init hp300_8250_init(void) | |||
210 | #ifdef CONFIG_HPAPCI | 210 | #ifdef CONFIG_HPAPCI |
211 | int line; | 211 | int line; |
212 | unsigned long base; | 212 | unsigned long base; |
213 | struct uart_port uport; | 213 | struct uart_8250_port uart; |
214 | struct hp300_port *port; | 214 | struct hp300_port *port; |
215 | int i; | 215 | int i; |
216 | #endif | 216 | #endif |
@@ -248,26 +248,26 @@ static int __init hp300_8250_init(void) | |||
248 | if (!port) | 248 | if (!port) |
249 | return -ENOMEM; | 249 | return -ENOMEM; |
250 | 250 | ||
251 | memset(&uport, 0, sizeof(struct uart_port)); | 251 | memset(&uart, 0, sizeof(uart)); |
252 | 252 | ||
253 | base = (FRODO_BASE + FRODO_APCI_OFFSET(i)); | 253 | base = (FRODO_BASE + FRODO_APCI_OFFSET(i)); |
254 | 254 | ||
255 | /* Memory mapped I/O */ | 255 | /* Memory mapped I/O */ |
256 | uport.iotype = UPIO_MEM; | 256 | uart.port.iotype = UPIO_MEM; |
257 | uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \ | 257 | uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \ |
258 | | UPF_BOOT_AUTOCONF; | 258 | | UPF_BOOT_AUTOCONF; |
259 | /* XXX - no interrupt support yet */ | 259 | /* XXX - no interrupt support yet */ |
260 | uport.irq = 0; | 260 | uart.port.irq = 0; |
261 | uport.uartclk = HPAPCI_BAUD_BASE * 16; | 261 | uart.port.uartclk = HPAPCI_BAUD_BASE * 16; |
262 | uport.mapbase = base; | 262 | uart.port.mapbase = base; |
263 | uport.membase = (char *)(base + DIO_VIRADDRBASE); | 263 | uart.port.membase = (char *)(base + DIO_VIRADDRBASE); |
264 | uport.regshift = 2; | 264 | uart.port.regshift = 2; |
265 | 265 | ||
266 | line = serial8250_register_port(&uport); | 266 | line = serial8250_register_8250_port(&uart); |
267 | 267 | ||
268 | if (line < 0) { | 268 | if (line < 0) { |
269 | printk(KERN_NOTICE "8250_hp300: register_serial() APCI" | 269 | printk(KERN_NOTICE "8250_hp300: register_serial() APCI" |
270 | " %d irq %d failed\n", i, uport.irq); | 270 | " %d irq %d failed\n", i, uart.port.irq); |
271 | kfree(port); | 271 | kfree(port); |
272 | continue; | 272 | continue; |
273 | } | 273 | } |
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 28e7c7cce893..fdab80a4e063 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -44,7 +44,7 @@ struct pci_serial_quirk { | |||
44 | int (*init)(struct pci_dev *dev); | 44 | int (*init)(struct pci_dev *dev); |
45 | int (*setup)(struct serial_private *, | 45 | int (*setup)(struct serial_private *, |
46 | const struct pciserial_board *, | 46 | const struct pciserial_board *, |
47 | struct uart_port *, int); | 47 | struct uart_8250_port *, int); |
48 | void (*exit)(struct pci_dev *dev); | 48 | void (*exit)(struct pci_dev *dev); |
49 | }; | 49 | }; |
50 | 50 | ||
@@ -59,7 +59,7 @@ struct serial_private { | |||
59 | }; | 59 | }; |
60 | 60 | ||
61 | static int pci_default_setup(struct serial_private*, | 61 | static int pci_default_setup(struct serial_private*, |
62 | const struct pciserial_board*, struct uart_port*, int); | 62 | const struct pciserial_board*, struct uart_8250_port *, int); |
63 | 63 | ||
64 | static void moan_device(const char *str, struct pci_dev *dev) | 64 | static void moan_device(const char *str, struct pci_dev *dev) |
65 | { | 65 | { |
@@ -74,7 +74,7 @@ static void moan_device(const char *str, struct pci_dev *dev) | |||
74 | } | 74 | } |
75 | 75 | ||
76 | static int | 76 | static int |
77 | setup_port(struct serial_private *priv, struct uart_port *port, | 77 | setup_port(struct serial_private *priv, struct uart_8250_port *port, |
78 | int bar, int offset, int regshift) | 78 | int bar, int offset, int regshift) |
79 | { | 79 | { |
80 | struct pci_dev *dev = priv->dev; | 80 | struct pci_dev *dev = priv->dev; |
@@ -93,17 +93,17 @@ setup_port(struct serial_private *priv, struct uart_port *port, | |||
93 | if (!priv->remapped_bar[bar]) | 93 | if (!priv->remapped_bar[bar]) |
94 | return -ENOMEM; | 94 | return -ENOMEM; |
95 | 95 | ||
96 | port->iotype = UPIO_MEM; | 96 | port->port.iotype = UPIO_MEM; |
97 | port->iobase = 0; | 97 | port->port.iobase = 0; |
98 | port->mapbase = base + offset; | 98 | port->port.mapbase = base + offset; |
99 | port->membase = priv->remapped_bar[bar] + offset; | 99 | port->port.membase = priv->remapped_bar[bar] + offset; |
100 | port->regshift = regshift; | 100 | port->port.regshift = regshift; |
101 | } else { | 101 | } else { |
102 | port->iotype = UPIO_PORT; | 102 | port->port.iotype = UPIO_PORT; |
103 | port->iobase = base + offset; | 103 | port->port.iobase = base + offset; |
104 | port->mapbase = 0; | 104 | port->port.mapbase = 0; |
105 | port->membase = NULL; | 105 | port->port.membase = NULL; |
106 | port->regshift = 0; | 106 | port->port.regshift = 0; |
107 | } | 107 | } |
108 | return 0; | 108 | return 0; |
109 | } | 109 | } |
@@ -113,7 +113,7 @@ setup_port(struct serial_private *priv, struct uart_port *port, | |||
113 | */ | 113 | */ |
114 | static int addidata_apci7800_setup(struct serial_private *priv, | 114 | static int addidata_apci7800_setup(struct serial_private *priv, |
115 | const struct pciserial_board *board, | 115 | const struct pciserial_board *board, |
116 | struct uart_port *port, int idx) | 116 | struct uart_8250_port *port, int idx) |
117 | { | 117 | { |
118 | unsigned int bar = 0, offset = board->first_offset; | 118 | unsigned int bar = 0, offset = board->first_offset; |
119 | bar = FL_GET_BASE(board->flags); | 119 | bar = FL_GET_BASE(board->flags); |
@@ -140,7 +140,7 @@ static int addidata_apci7800_setup(struct serial_private *priv, | |||
140 | */ | 140 | */ |
141 | static int | 141 | static int |
142 | afavlab_setup(struct serial_private *priv, const struct pciserial_board *board, | 142 | afavlab_setup(struct serial_private *priv, const struct pciserial_board *board, |
143 | struct uart_port *port, int idx) | 143 | struct uart_8250_port *port, int idx) |
144 | { | 144 | { |
145 | unsigned int bar, offset = board->first_offset; | 145 | unsigned int bar, offset = board->first_offset; |
146 | 146 | ||
@@ -195,7 +195,7 @@ static int pci_hp_diva_init(struct pci_dev *dev) | |||
195 | static int | 195 | static int |
196 | pci_hp_diva_setup(struct serial_private *priv, | 196 | pci_hp_diva_setup(struct serial_private *priv, |
197 | const struct pciserial_board *board, | 197 | const struct pciserial_board *board, |
198 | struct uart_port *port, int idx) | 198 | struct uart_8250_port *port, int idx) |
199 | { | 199 | { |
200 | unsigned int offset = board->first_offset; | 200 | unsigned int offset = board->first_offset; |
201 | unsigned int bar = FL_GET_BASE(board->flags); | 201 | unsigned int bar = FL_GET_BASE(board->flags); |
@@ -370,7 +370,7 @@ static void __devexit pci_ni8430_exit(struct pci_dev *dev) | |||
370 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ | 370 | /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */ |
371 | static int | 371 | static int |
372 | sbs_setup(struct serial_private *priv, const struct pciserial_board *board, | 372 | sbs_setup(struct serial_private *priv, const struct pciserial_board *board, |
373 | struct uart_port *port, int idx) | 373 | struct uart_8250_port *port, int idx) |
374 | { | 374 | { |
375 | unsigned int bar, offset = board->first_offset; | 375 | unsigned int bar, offset = board->first_offset; |
376 | 376 | ||
@@ -525,7 +525,7 @@ static int pci_siig_init(struct pci_dev *dev) | |||
525 | 525 | ||
526 | static int pci_siig_setup(struct serial_private *priv, | 526 | static int pci_siig_setup(struct serial_private *priv, |
527 | const struct pciserial_board *board, | 527 | const struct pciserial_board *board, |
528 | struct uart_port *port, int idx) | 528 | struct uart_8250_port *port, int idx) |
529 | { | 529 | { |
530 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; | 530 | unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0; |
531 | 531 | ||
@@ -619,7 +619,7 @@ static int pci_timedia_init(struct pci_dev *dev) | |||
619 | static int | 619 | static int |
620 | pci_timedia_setup(struct serial_private *priv, | 620 | pci_timedia_setup(struct serial_private *priv, |
621 | const struct pciserial_board *board, | 621 | const struct pciserial_board *board, |
622 | struct uart_port *port, int idx) | 622 | struct uart_8250_port *port, int idx) |
623 | { | 623 | { |
624 | unsigned int bar = 0, offset = board->first_offset; | 624 | unsigned int bar = 0, offset = board->first_offset; |
625 | 625 | ||
@@ -653,7 +653,7 @@ pci_timedia_setup(struct serial_private *priv, | |||
653 | static int | 653 | static int |
654 | titan_400l_800l_setup(struct serial_private *priv, | 654 | titan_400l_800l_setup(struct serial_private *priv, |
655 | const struct pciserial_board *board, | 655 | const struct pciserial_board *board, |
656 | struct uart_port *port, int idx) | 656 | struct uart_8250_port *port, int idx) |
657 | { | 657 | { |
658 | unsigned int bar, offset = board->first_offset; | 658 | unsigned int bar, offset = board->first_offset; |
659 | 659 | ||
@@ -754,7 +754,7 @@ static int pci_ni8430_init(struct pci_dev *dev) | |||
754 | static int | 754 | static int |
755 | pci_ni8430_setup(struct serial_private *priv, | 755 | pci_ni8430_setup(struct serial_private *priv, |
756 | const struct pciserial_board *board, | 756 | const struct pciserial_board *board, |
757 | struct uart_port *port, int idx) | 757 | struct uart_8250_port *port, int idx) |
758 | { | 758 | { |
759 | void __iomem *p; | 759 | void __iomem *p; |
760 | unsigned long base, len; | 760 | unsigned long base, len; |
@@ -781,7 +781,7 @@ pci_ni8430_setup(struct serial_private *priv, | |||
781 | 781 | ||
782 | static int pci_netmos_9900_setup(struct serial_private *priv, | 782 | static int pci_netmos_9900_setup(struct serial_private *priv, |
783 | const struct pciserial_board *board, | 783 | const struct pciserial_board *board, |
784 | struct uart_port *port, int idx) | 784 | struct uart_8250_port *port, int idx) |
785 | { | 785 | { |
786 | unsigned int bar; | 786 | unsigned int bar; |
787 | 787 | ||
@@ -1032,10 +1032,17 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev) | |||
1032 | return number_uarts; | 1032 | return number_uarts; |
1033 | } | 1033 | } |
1034 | 1034 | ||
1035 | static int | 1035 | static int pci_asix_setup(struct serial_private *priv, |
1036 | pci_default_setup(struct serial_private *priv, | ||
1037 | const struct pciserial_board *board, | 1036 | const struct pciserial_board *board, |
1038 | struct uart_port *port, int idx) | 1037 | struct uart_8250_port *port, int idx) |
1038 | { | ||
1039 | port->bugs |= UART_BUG_PARITY; | ||
1040 | return pci_default_setup(priv, board, port, idx); | ||
1041 | } | ||
1042 | |||
1043 | static int pci_default_setup(struct serial_private *priv, | ||
1044 | const struct pciserial_board *board, | ||
1045 | struct uart_8250_port *port, int idx) | ||
1039 | { | 1046 | { |
1040 | unsigned int bar, offset = board->first_offset, maxnr; | 1047 | unsigned int bar, offset = board->first_offset, maxnr; |
1041 | 1048 | ||
@@ -1057,15 +1064,15 @@ pci_default_setup(struct serial_private *priv, | |||
1057 | static int | 1064 | static int |
1058 | ce4100_serial_setup(struct serial_private *priv, | 1065 | ce4100_serial_setup(struct serial_private *priv, |
1059 | const struct pciserial_board *board, | 1066 | const struct pciserial_board *board, |
1060 | struct uart_port *port, int idx) | 1067 | struct uart_8250_port *port, int idx) |
1061 | { | 1068 | { |
1062 | int ret; | 1069 | int ret; |
1063 | 1070 | ||
1064 | ret = setup_port(priv, port, 0, 0, board->reg_shift); | 1071 | ret = setup_port(priv, port, 0, 0, board->reg_shift); |
1065 | port->iotype = UPIO_MEM32; | 1072 | port->port.iotype = UPIO_MEM32; |
1066 | port->type = PORT_XSCALE; | 1073 | port->port.type = PORT_XSCALE; |
1067 | port->flags = (port->flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | 1074 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); |
1068 | port->regshift = 2; | 1075 | port->port.regshift = 2; |
1069 | 1076 | ||
1070 | return ret; | 1077 | return ret; |
1071 | } | 1078 | } |
@@ -1073,16 +1080,16 @@ ce4100_serial_setup(struct serial_private *priv, | |||
1073 | static int | 1080 | static int |
1074 | pci_omegapci_setup(struct serial_private *priv, | 1081 | pci_omegapci_setup(struct serial_private *priv, |
1075 | const struct pciserial_board *board, | 1082 | const struct pciserial_board *board, |
1076 | struct uart_port *port, int idx) | 1083 | struct uart_8250_port *port, int idx) |
1077 | { | 1084 | { |
1078 | return setup_port(priv, port, 2, idx * 8, 0); | 1085 | return setup_port(priv, port, 2, idx * 8, 0); |
1079 | } | 1086 | } |
1080 | 1087 | ||
1081 | static int skip_tx_en_setup(struct serial_private *priv, | 1088 | static int skip_tx_en_setup(struct serial_private *priv, |
1082 | const struct pciserial_board *board, | 1089 | const struct pciserial_board *board, |
1083 | struct uart_port *port, int idx) | 1090 | struct uart_8250_port *port, int idx) |
1084 | { | 1091 | { |
1085 | port->flags |= UPF_NO_TXEN_TEST; | 1092 | port->port.flags |= UPF_NO_TXEN_TEST; |
1086 | printk(KERN_DEBUG "serial8250: skipping TxEn test for device " | 1093 | printk(KERN_DEBUG "serial8250: skipping TxEn test for device " |
1087 | "[%04x:%04x] subsystem [%04x:%04x]\n", | 1094 | "[%04x:%04x] subsystem [%04x:%04x]\n", |
1088 | priv->dev->vendor, | 1095 | priv->dev->vendor, |
@@ -1131,11 +1138,11 @@ static unsigned int kt_serial_in(struct uart_port *p, int offset) | |||
1131 | 1138 | ||
1132 | static int kt_serial_setup(struct serial_private *priv, | 1139 | static int kt_serial_setup(struct serial_private *priv, |
1133 | const struct pciserial_board *board, | 1140 | const struct pciserial_board *board, |
1134 | struct uart_port *port, int idx) | 1141 | struct uart_8250_port *port, int idx) |
1135 | { | 1142 | { |
1136 | port->flags |= UPF_BUG_THRE; | 1143 | port->port.flags |= UPF_BUG_THRE; |
1137 | port->serial_in = kt_serial_in; | 1144 | port->port.serial_in = kt_serial_in; |
1138 | port->handle_break = kt_handle_break; | 1145 | port->port.handle_break = kt_handle_break; |
1139 | return skip_tx_en_setup(priv, board, port, idx); | 1146 | return skip_tx_en_setup(priv, board, port, idx); |
1140 | } | 1147 | } |
1141 | 1148 | ||
@@ -1151,9 +1158,19 @@ static int pci_eg20t_init(struct pci_dev *dev) | |||
1151 | static int | 1158 | static int |
1152 | pci_xr17c154_setup(struct serial_private *priv, | 1159 | pci_xr17c154_setup(struct serial_private *priv, |
1153 | const struct pciserial_board *board, | 1160 | const struct pciserial_board *board, |
1154 | struct uart_port *port, int idx) | 1161 | struct uart_8250_port *port, int idx) |
1162 | { | ||
1163 | port->port.flags |= UPF_EXAR_EFR; | ||
1164 | return pci_default_setup(priv, board, port, idx); | ||
1165 | } | ||
1166 | |||
1167 | static int | ||
1168 | pci_wch_ch353_setup(struct serial_private *priv, | ||
1169 | const struct pciserial_board *board, | ||
1170 | struct uart_8250_port *port, int idx) | ||
1155 | { | 1171 | { |
1156 | port->flags |= UPF_EXAR_EFR; | 1172 | port->port.flags |= UPF_FIXED_TYPE; |
1173 | port->port.type = PORT_16550A; | ||
1157 | return pci_default_setup(priv, board, port, idx); | 1174 | return pci_default_setup(priv, board, port, idx); |
1158 | } | 1175 | } |
1159 | 1176 | ||
@@ -1187,6 +1204,13 @@ pci_xr17c154_setup(struct serial_private *priv, | |||
1187 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 | 1204 | #define PCIE_DEVICE_ID_NEO_2_OX_IBM 0x00F6 |
1188 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 | 1205 | #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 |
1189 | #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d | 1206 | #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d |
1207 | #define PCI_VENDOR_ID_WCH 0x4348 | ||
1208 | #define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 | ||
1209 | #define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 | ||
1210 | #define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 | ||
1211 | #define PCI_VENDOR_ID_AGESTAR 0x5372 | ||
1212 | #define PCI_DEVICE_ID_AGESTAR_9375 0x6872 | ||
1213 | #define PCI_VENDOR_ID_ASIX 0x9710 | ||
1190 | 1214 | ||
1191 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ | 1215 | /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ |
1192 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 | 1216 | #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 |
@@ -1726,7 +1750,41 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1726 | .subvendor = PCI_ANY_ID, | 1750 | .subvendor = PCI_ANY_ID, |
1727 | .subdevice = PCI_ANY_ID, | 1751 | .subdevice = PCI_ANY_ID, |
1728 | .setup = pci_omegapci_setup, | 1752 | .setup = pci_omegapci_setup, |
1729 | }, | 1753 | }, |
1754 | /* WCH CH353 2S1P card (16550 clone) */ | ||
1755 | { | ||
1756 | .vendor = PCI_VENDOR_ID_WCH, | ||
1757 | .device = PCI_DEVICE_ID_WCH_CH353_2S1P, | ||
1758 | .subvendor = PCI_ANY_ID, | ||
1759 | .subdevice = PCI_ANY_ID, | ||
1760 | .setup = pci_wch_ch353_setup, | ||
1761 | }, | ||
1762 | /* WCH CH353 4S card (16550 clone) */ | ||
1763 | { | ||
1764 | .vendor = PCI_VENDOR_ID_WCH, | ||
1765 | .device = PCI_DEVICE_ID_WCH_CH353_4S, | ||
1766 | .subvendor = PCI_ANY_ID, | ||
1767 | .subdevice = PCI_ANY_ID, | ||
1768 | .setup = pci_wch_ch353_setup, | ||
1769 | }, | ||
1770 | /* WCH CH353 2S1PF card (16550 clone) */ | ||
1771 | { | ||
1772 | .vendor = PCI_VENDOR_ID_WCH, | ||
1773 | .device = PCI_DEVICE_ID_WCH_CH353_2S1PF, | ||
1774 | .subvendor = PCI_ANY_ID, | ||
1775 | .subdevice = PCI_ANY_ID, | ||
1776 | .setup = pci_wch_ch353_setup, | ||
1777 | }, | ||
1778 | /* | ||
1779 | * ASIX devices with FIFO bug | ||
1780 | */ | ||
1781 | { | ||
1782 | .vendor = PCI_VENDOR_ID_ASIX, | ||
1783 | .device = PCI_ANY_ID, | ||
1784 | .subvendor = PCI_ANY_ID, | ||
1785 | .subdevice = PCI_ANY_ID, | ||
1786 | .setup = pci_asix_setup, | ||
1787 | }, | ||
1730 | /* | 1788 | /* |
1731 | * Default "match everything" terminator entry | 1789 | * Default "match everything" terminator entry |
1732 | */ | 1790 | */ |
@@ -1887,7 +1945,6 @@ enum pci_board_num_t { | |||
1887 | pbn_panacom, | 1945 | pbn_panacom, |
1888 | pbn_panacom2, | 1946 | pbn_panacom2, |
1889 | pbn_panacom4, | 1947 | pbn_panacom4, |
1890 | pbn_exsys_4055, | ||
1891 | pbn_plx_romulus, | 1948 | pbn_plx_romulus, |
1892 | pbn_oxsemi, | 1949 | pbn_oxsemi, |
1893 | pbn_oxsemi_1_4000000, | 1950 | pbn_oxsemi_1_4000000, |
@@ -2393,13 +2450,6 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2393 | .reg_shift = 7, | 2450 | .reg_shift = 7, |
2394 | }, | 2451 | }, |
2395 | 2452 | ||
2396 | [pbn_exsys_4055] = { | ||
2397 | .flags = FL_BASE2, | ||
2398 | .num_ports = 4, | ||
2399 | .base_baud = 115200, | ||
2400 | .uart_offset = 8, | ||
2401 | }, | ||
2402 | |||
2403 | /* I think this entry is broken - the first_offset looks wrong --rmk */ | 2453 | /* I think this entry is broken - the first_offset looks wrong --rmk */ |
2404 | [pbn_plx_romulus] = { | 2454 | [pbn_plx_romulus] = { |
2405 | .flags = FL_BASE2, | 2455 | .flags = FL_BASE2, |
@@ -2624,10 +2674,14 @@ static struct pciserial_board pci_boards[] __devinitdata = { | |||
2624 | }, | 2674 | }, |
2625 | }; | 2675 | }; |
2626 | 2676 | ||
2627 | static const struct pci_device_id softmodem_blacklist[] = { | 2677 | static const struct pci_device_id blacklist[] = { |
2678 | /* softmodems */ | ||
2628 | { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ | 2679 | { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */ |
2629 | { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ | 2680 | { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */ |
2630 | { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ | 2681 | { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */ |
2682 | |||
2683 | /* multi-io cards handled by parport_serial */ | ||
2684 | { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */ | ||
2631 | }; | 2685 | }; |
2632 | 2686 | ||
2633 | /* | 2687 | /* |
@@ -2638,7 +2692,7 @@ static const struct pci_device_id softmodem_blacklist[] = { | |||
2638 | static int __devinit | 2692 | static int __devinit |
2639 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | 2693 | serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) |
2640 | { | 2694 | { |
2641 | const struct pci_device_id *blacklist; | 2695 | const struct pci_device_id *bldev; |
2642 | int num_iomem, num_port, first_port = -1, i; | 2696 | int num_iomem, num_port, first_port = -1, i; |
2643 | 2697 | ||
2644 | /* | 2698 | /* |
@@ -2655,13 +2709,13 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) | |||
2655 | 2709 | ||
2656 | /* | 2710 | /* |
2657 | * Do not access blacklisted devices that are known not to | 2711 | * Do not access blacklisted devices that are known not to |
2658 | * feature serial ports. | 2712 | * feature serial ports or are handled by other modules. |
2659 | */ | 2713 | */ |
2660 | for (blacklist = softmodem_blacklist; | 2714 | for (bldev = blacklist; |
2661 | blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist); | 2715 | bldev < blacklist + ARRAY_SIZE(blacklist); |
2662 | blacklist++) { | 2716 | bldev++) { |
2663 | if (dev->vendor == blacklist->vendor && | 2717 | if (dev->vendor == bldev->vendor && |
2664 | dev->device == blacklist->device) | 2718 | dev->device == bldev->device) |
2665 | return -ENODEV; | 2719 | return -ENODEV; |
2666 | } | 2720 | } |
2667 | 2721 | ||
@@ -2728,7 +2782,7 @@ serial_pci_matches(const struct pciserial_board *board, | |||
2728 | struct serial_private * | 2782 | struct serial_private * |
2729 | pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) | 2783 | pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) |
2730 | { | 2784 | { |
2731 | struct uart_port serial_port; | 2785 | struct uart_8250_port uart; |
2732 | struct serial_private *priv; | 2786 | struct serial_private *priv; |
2733 | struct pci_serial_quirk *quirk; | 2787 | struct pci_serial_quirk *quirk; |
2734 | int rc, nr_ports, i; | 2788 | int rc, nr_ports, i; |
@@ -2768,22 +2822,22 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board) | |||
2768 | priv->dev = dev; | 2822 | priv->dev = dev; |
2769 | priv->quirk = quirk; | 2823 | priv->quirk = quirk; |
2770 | 2824 | ||
2771 | memset(&serial_port, 0, sizeof(struct uart_port)); | 2825 | memset(&uart, 0, sizeof(uart)); |
2772 | serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | 2826 | uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; |
2773 | serial_port.uartclk = board->base_baud * 16; | 2827 | uart.port.uartclk = board->base_baud * 16; |
2774 | serial_port.irq = get_pci_irq(dev, board); | 2828 | uart.port.irq = get_pci_irq(dev, board); |
2775 | serial_port.dev = &dev->dev; | 2829 | uart.port.dev = &dev->dev; |
2776 | 2830 | ||
2777 | for (i = 0; i < nr_ports; i++) { | 2831 | for (i = 0; i < nr_ports; i++) { |
2778 | if (quirk->setup(priv, board, &serial_port, i)) | 2832 | if (quirk->setup(priv, board, &uart, i)) |
2779 | break; | 2833 | break; |
2780 | 2834 | ||
2781 | #ifdef SERIAL_DEBUG_PCI | 2835 | #ifdef SERIAL_DEBUG_PCI |
2782 | printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n", | 2836 | printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n", |
2783 | serial_port.iobase, serial_port.irq, serial_port.iotype); | 2837 | uart.port.iobase, uart.port.irq, uart.port.iotype); |
2784 | #endif | 2838 | #endif |
2785 | 2839 | ||
2786 | priv->line[i] = serial8250_register_port(&serial_port); | 2840 | priv->line[i] = serial8250_register_8250_port(&uart); |
2787 | if (priv->line[i] < 0) { | 2841 | if (priv->line[i] < 0) { |
2788 | printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]); | 2842 | printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]); |
2789 | break; | 2843 | break; |
@@ -3193,7 +3247,7 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
3193 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, | 3247 | { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, |
3194 | PCI_SUBVENDOR_ID_EXSYS, | 3248 | PCI_SUBVENDOR_ID_EXSYS, |
3195 | PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0, | 3249 | PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0, |
3196 | pbn_exsys_4055 }, | 3250 | pbn_b2_4_115200 }, |
3197 | /* | 3251 | /* |
3198 | * Megawolf Romulus PCI Serial Card, from Mike Hudson | 3252 | * Megawolf Romulus PCI Serial Card, from Mike Hudson |
3199 | * (Exoray@isys.ca) | 3253 | * (Exoray@isys.ca) |
@@ -4179,6 +4233,25 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
4179 | pbn_omegapci }, | 4233 | pbn_omegapci }, |
4180 | 4234 | ||
4181 | /* | 4235 | /* |
4236 | * AgeStar as-prs2-009 | ||
4237 | */ | ||
4238 | { PCI_VENDOR_ID_AGESTAR, PCI_DEVICE_ID_AGESTAR_9375, | ||
4239 | PCI_ANY_ID, PCI_ANY_ID, | ||
4240 | 0, 0, pbn_b0_bt_2_115200 }, | ||
4241 | |||
4242 | /* | ||
4243 | * WCH CH353 series devices: The 2S1P is handled by parport_serial | ||
4244 | * so not listed here. | ||
4245 | */ | ||
4246 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_4S, | ||
4247 | PCI_ANY_ID, PCI_ANY_ID, | ||
4248 | 0, 0, pbn_b0_bt_4_115200 }, | ||
4249 | |||
4250 | { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH353_2S1PF, | ||
4251 | PCI_ANY_ID, PCI_ANY_ID, | ||
4252 | 0, 0, pbn_b0_bt_2_115200 }, | ||
4253 | |||
4254 | /* | ||
4182 | * These entries match devices with class COMMUNICATION_SERIAL, | 4255 | * These entries match devices with class COMMUNICATION_SERIAL, |
4183 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL | 4256 | * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL |
4184 | */ | 4257 | */ |
diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index a2f236510ff1..fde5aa60d51e 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c | |||
@@ -424,7 +424,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags) | |||
424 | static int __devinit | 424 | static int __devinit |
425 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | 425 | serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) |
426 | { | 426 | { |
427 | struct uart_port port; | 427 | struct uart_8250_port uart; |
428 | int ret, line, flags = dev_id->driver_data; | 428 | int ret, line, flags = dev_id->driver_data; |
429 | 429 | ||
430 | if (flags & UNKNOWN_DEV) { | 430 | if (flags & UNKNOWN_DEV) { |
@@ -433,32 +433,32 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | |||
433 | return ret; | 433 | return ret; |
434 | } | 434 | } |
435 | 435 | ||
436 | memset(&port, 0, sizeof(struct uart_port)); | 436 | memset(&uart, 0, sizeof(uart)); |
437 | if (pnp_irq_valid(dev, 0)) | 437 | if (pnp_irq_valid(dev, 0)) |
438 | port.irq = pnp_irq(dev, 0); | 438 | uart.port.irq = pnp_irq(dev, 0); |
439 | if (pnp_port_valid(dev, 0)) { | 439 | if (pnp_port_valid(dev, 0)) { |
440 | port.iobase = pnp_port_start(dev, 0); | 440 | uart.port.iobase = pnp_port_start(dev, 0); |
441 | port.iotype = UPIO_PORT; | 441 | uart.port.iotype = UPIO_PORT; |
442 | } else if (pnp_mem_valid(dev, 0)) { | 442 | } else if (pnp_mem_valid(dev, 0)) { |
443 | port.mapbase = pnp_mem_start(dev, 0); | 443 | uart.port.mapbase = pnp_mem_start(dev, 0); |
444 | port.iotype = UPIO_MEM; | 444 | uart.port.iotype = UPIO_MEM; |
445 | port.flags = UPF_IOREMAP; | 445 | uart.port.flags = UPF_IOREMAP; |
446 | } else | 446 | } else |
447 | return -ENODEV; | 447 | return -ENODEV; |
448 | 448 | ||
449 | #ifdef SERIAL_DEBUG_PNP | 449 | #ifdef SERIAL_DEBUG_PNP |
450 | printk(KERN_DEBUG | 450 | printk(KERN_DEBUG |
451 | "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", | 451 | "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n", |
452 | port.iobase, port.mapbase, port.irq, port.iotype); | 452 | uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype); |
453 | #endif | 453 | #endif |
454 | 454 | ||
455 | port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | 455 | uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; |
456 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) | 456 | if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE) |
457 | port.flags |= UPF_SHARE_IRQ; | 457 | uart.port.flags |= UPF_SHARE_IRQ; |
458 | port.uartclk = 1843200; | 458 | uart.port.uartclk = 1843200; |
459 | port.dev = &dev->dev; | 459 | uart.port.dev = &dev->dev; |
460 | 460 | ||
461 | line = serial8250_register_port(&port); | 461 | line = serial8250_register_8250_port(&uart); |
462 | if (line < 0) | 462 | if (line < 0) |
463 | return -ENODEV; | 463 | return -ENODEV; |
464 | 464 | ||
diff --git a/drivers/tty/serial/8250/serial_cs.c b/drivers/tty/serial/8250/serial_cs.c index 29b695d041ec..b7d48b346393 100644 --- a/drivers/tty/serial/8250/serial_cs.c +++ b/drivers/tty/serial/8250/serial_cs.c | |||
@@ -73,7 +73,7 @@ struct serial_quirk { | |||
73 | unsigned int prodid; | 73 | unsigned int prodid; |
74 | int multi; /* 1 = multifunction, > 1 = # ports */ | 74 | int multi; /* 1 = multifunction, > 1 = # ports */ |
75 | void (*config)(struct pcmcia_device *); | 75 | void (*config)(struct pcmcia_device *); |
76 | void (*setup)(struct pcmcia_device *, struct uart_port *); | 76 | void (*setup)(struct pcmcia_device *, struct uart_8250_port *); |
77 | void (*wakeup)(struct pcmcia_device *); | 77 | void (*wakeup)(struct pcmcia_device *); |
78 | int (*post)(struct pcmcia_device *); | 78 | int (*post)(struct pcmcia_device *); |
79 | }; | 79 | }; |
@@ -105,9 +105,9 @@ struct serial_cfg_mem { | |||
105 | * Elan VPU16551 UART with 14.7456MHz oscillator | 105 | * Elan VPU16551 UART with 14.7456MHz oscillator |
106 | * manfid 0x015D, 0x4C45 | 106 | * manfid 0x015D, 0x4C45 |
107 | */ | 107 | */ |
108 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port) | 108 | static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_8250_port *uart) |
109 | { | 109 | { |
110 | port->uartclk = 14745600; | 110 | uart->port.uartclk = 14745600; |
111 | } | 111 | } |
112 | 112 | ||
113 | static int quirk_post_ibm(struct pcmcia_device *link) | 113 | static int quirk_post_ibm(struct pcmcia_device *link) |
@@ -343,25 +343,25 @@ static void serial_detach(struct pcmcia_device *link) | |||
343 | static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, | 343 | static int setup_serial(struct pcmcia_device *handle, struct serial_info * info, |
344 | unsigned int iobase, int irq) | 344 | unsigned int iobase, int irq) |
345 | { | 345 | { |
346 | struct uart_port port; | 346 | struct uart_8250_port uart; |
347 | int line; | 347 | int line; |
348 | 348 | ||
349 | memset(&port, 0, sizeof (struct uart_port)); | 349 | memset(&uart, 0, sizeof(uart)); |
350 | port.iobase = iobase; | 350 | uart.port.iobase = iobase; |
351 | port.irq = irq; | 351 | uart.port.irq = irq; |
352 | port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; | 352 | uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ; |
353 | port.uartclk = 1843200; | 353 | uart.port.uartclk = 1843200; |
354 | port.dev = &handle->dev; | 354 | uart.port.dev = &handle->dev; |
355 | if (buggy_uart) | 355 | if (buggy_uart) |
356 | port.flags |= UPF_BUGGY_UART; | 356 | uart.port.flags |= UPF_BUGGY_UART; |
357 | 357 | ||
358 | if (info->quirk && info->quirk->setup) | 358 | if (info->quirk && info->quirk->setup) |
359 | info->quirk->setup(handle, &port); | 359 | info->quirk->setup(handle, &uart); |
360 | 360 | ||
361 | line = serial8250_register_port(&port); | 361 | line = serial8250_register_8250_port(&uart); |
362 | if (line < 0) { | 362 | if (line < 0) { |
363 | printk(KERN_NOTICE "serial_cs: serial8250_register_port() at " | 363 | pr_err("serial_cs: serial8250_register_8250_port() at 0x%04lx, irq %d failed\n", |
364 | "0x%04lx, irq %d failed\n", (u_long)iobase, irq); | 364 | (unsigned long)iobase, irq); |
365 | return -EINVAL; | 365 | return -EINVAL; |
366 | } | 366 | } |
367 | 367 | ||
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 4720b4ba096a..26907cf25744 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -257,12 +257,19 @@ config SERIAL_MAX3100 | |||
257 | help | 257 | help |
258 | MAX3100 chip support | 258 | MAX3100 chip support |
259 | 259 | ||
260 | config SERIAL_MAX3107 | 260 | config SERIAL_MAX310X |
261 | tristate "MAX3107 support" | 261 | bool "MAX310X support" |
262 | depends on SPI | 262 | depends on SPI |
263 | select SERIAL_CORE | 263 | select SERIAL_CORE |
264 | select REGMAP_SPI if SPI | ||
265 | default n | ||
264 | help | 266 | help |
265 | MAX3107 chip support | 267 | This selects support for an advanced UART from Maxim (Dallas). |
268 | Supported ICs are MAX3107, MAX3108. | ||
269 | Each IC contains 128 words each of receive and transmit FIFO | ||
270 | that can be controlled through I2C or high-speed SPI. | ||
271 | |||
272 | Say Y here if you want to support this ICs. | ||
266 | 273 | ||
267 | config SERIAL_DZ | 274 | config SERIAL_DZ |
268 | bool "DECstation DZ serial driver" | 275 | bool "DECstation DZ serial driver" |
@@ -704,6 +711,25 @@ config SERIAL_PNX8XXX_CONSOLE | |||
704 | If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330 | 711 | If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330 |
705 | and you want to use serial console, say Y. Otherwise, say N. | 712 | and you want to use serial console, say Y. Otherwise, say N. |
706 | 713 | ||
714 | config SERIAL_HS_LPC32XX | ||
715 | tristate "LPC32XX high speed serial port support" | ||
716 | depends on ARCH_LPC32XX && OF | ||
717 | select SERIAL_CORE | ||
718 | help | ||
719 | Support for the LPC32XX high speed serial ports (up to 900kbps). | ||
720 | Those are UARTs completely different from the Standard UARTs on the | ||
721 | LPC32XX SoC. | ||
722 | Choose M or Y here to build this driver. | ||
723 | |||
724 | config SERIAL_HS_LPC32XX_CONSOLE | ||
725 | bool "Enable LPC32XX high speed UART serial console" | ||
726 | depends on SERIAL_HS_LPC32XX | ||
727 | select SERIAL_CORE_CONSOLE | ||
728 | help | ||
729 | If you would like to be able to use one of the high speed serial | ||
730 | ports on the LPC32XX as the console, you can do so by answering | ||
731 | Y to this option. | ||
732 | |||
707 | config SERIAL_CORE | 733 | config SERIAL_CORE |
708 | tristate | 734 | tristate |
709 | 735 | ||
@@ -1104,6 +1130,24 @@ config SERIAL_SC26XX_CONSOLE | |||
1104 | help | 1130 | help |
1105 | Support for Console on SC2681/SC2692 serial ports. | 1131 | Support for Console on SC2681/SC2692 serial ports. |
1106 | 1132 | ||
1133 | config SERIAL_SCCNXP | ||
1134 | bool "SCCNXP serial port support" | ||
1135 | depends on !SERIAL_SC26XX | ||
1136 | select SERIAL_CORE | ||
1137 | default n | ||
1138 | help | ||
1139 | This selects support for an advanced UART from NXP (Philips). | ||
1140 | Supported ICs are SCC2681, SCC2691, SCC2692, SC28L91, SC28L92, | ||
1141 | SC28L202, SCC68681 and SCC68692. | ||
1142 | Positioned as a replacement for the driver SC26XX. | ||
1143 | |||
1144 | config SERIAL_SCCNXP_CONSOLE | ||
1145 | bool "Console on SCCNXP serial port" | ||
1146 | depends on SERIAL_SCCNXP | ||
1147 | select SERIAL_CORE_CONSOLE | ||
1148 | help | ||
1149 | Support for console on SCCNXP serial ports. | ||
1150 | |||
1107 | config SERIAL_BFIN_SPORT | 1151 | config SERIAL_BFIN_SPORT |
1108 | tristate "Blackfin SPORT emulate UART" | 1152 | tristate "Blackfin SPORT emulate UART" |
1109 | depends on BLACKFIN | 1153 | depends on BLACKFIN |
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index 7257c5d898ae..ce88667cfd17 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile | |||
@@ -28,12 +28,13 @@ obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o | |||
28 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o | 28 | obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o |
29 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o | 29 | obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o |
30 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o | 30 | obj-$(CONFIG_SERIAL_MAX3100) += max3100.o |
31 | obj-$(CONFIG_SERIAL_MAX3107) += max3107.o | 31 | obj-$(CONFIG_SERIAL_MAX310X) += max310x.o |
32 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o | 32 | obj-$(CONFIG_SERIAL_IP22_ZILOG) += ip22zilog.o |
33 | obj-$(CONFIG_SERIAL_MUX) += mux.o | 33 | obj-$(CONFIG_SERIAL_MUX) += mux.o |
34 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o | 34 | obj-$(CONFIG_SERIAL_68328) += 68328serial.o |
35 | obj-$(CONFIG_SERIAL_MCF) += mcf.o | 35 | obj-$(CONFIG_SERIAL_MCF) += mcf.o |
36 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o | 36 | obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o |
37 | obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o | ||
37 | obj-$(CONFIG_SERIAL_DZ) += dz.o | 38 | obj-$(CONFIG_SERIAL_DZ) += dz.o |
38 | obj-$(CONFIG_SERIAL_ZS) += zs.o | 39 | obj-$(CONFIG_SERIAL_ZS) += zs.o |
39 | obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o | 40 | obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o |
@@ -47,6 +48,7 @@ obj-$(CONFIG_SERIAL_MPSC) += mpsc.o | |||
47 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o | 48 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o |
48 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o | 49 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o |
49 | obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o | 50 | obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o |
51 | obj-$(CONFIG_SERIAL_SCCNXP) += sccnxp.o | ||
50 | obj-$(CONFIG_SERIAL_JSM) += jsm/ | 52 | obj-$(CONFIG_SERIAL_JSM) += jsm/ |
51 | obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o | 53 | obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o |
52 | obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o | 54 | obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o |
diff --git a/drivers/tty/serial/altera_uart.c b/drivers/tty/serial/altera_uart.c index 1f0330915d5a..15d80b9fb303 100644 --- a/drivers/tty/serial/altera_uart.c +++ b/drivers/tty/serial/altera_uart.c | |||
@@ -591,7 +591,7 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
591 | port->ops = &altera_uart_ops; | 591 | port->ops = &altera_uart_ops; |
592 | port->flags = UPF_BOOT_AUTOCONF; | 592 | port->flags = UPF_BOOT_AUTOCONF; |
593 | 593 | ||
594 | dev_set_drvdata(&pdev->dev, port); | 594 | platform_set_drvdata(pdev, port); |
595 | 595 | ||
596 | uart_add_one_port(&altera_uart_driver, port); | 596 | uart_add_one_port(&altera_uart_driver, port); |
597 | 597 | ||
@@ -600,11 +600,11 @@ static int __devinit altera_uart_probe(struct platform_device *pdev) | |||
600 | 600 | ||
601 | static int __devexit altera_uart_remove(struct platform_device *pdev) | 601 | static int __devexit altera_uart_remove(struct platform_device *pdev) |
602 | { | 602 | { |
603 | struct uart_port *port = dev_get_drvdata(&pdev->dev); | 603 | struct uart_port *port = platform_get_drvdata(pdev); |
604 | 604 | ||
605 | if (port) { | 605 | if (port) { |
606 | uart_remove_one_port(&altera_uart_driver, port); | 606 | uart_remove_one_port(&altera_uart_driver, port); |
607 | dev_set_drvdata(&pdev->dev, NULL); | 607 | platform_set_drvdata(pdev, NULL); |
608 | port->mapbase = 0; | 608 | port->mapbase = 0; |
609 | } | 609 | } |
610 | 610 | ||
diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c index 0d91a540bf11..22317dd16474 100644 --- a/drivers/tty/serial/amba-pl010.c +++ b/drivers/tty/serial/amba-pl010.c | |||
@@ -312,16 +312,12 @@ static int pl010_startup(struct uart_port *port) | |||
312 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 312 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
313 | int retval; | 313 | int retval; |
314 | 314 | ||
315 | retval = clk_prepare(uap->clk); | ||
316 | if (retval) | ||
317 | goto out; | ||
318 | |||
319 | /* | 315 | /* |
320 | * Try to enable the clock producer. | 316 | * Try to enable the clock producer. |
321 | */ | 317 | */ |
322 | retval = clk_enable(uap->clk); | 318 | retval = clk_prepare_enable(uap->clk); |
323 | if (retval) | 319 | if (retval) |
324 | goto clk_unprep; | 320 | goto out; |
325 | 321 | ||
326 | uap->port.uartclk = clk_get_rate(uap->clk); | 322 | uap->port.uartclk = clk_get_rate(uap->clk); |
327 | 323 | ||
@@ -346,9 +342,7 @@ static int pl010_startup(struct uart_port *port) | |||
346 | return 0; | 342 | return 0; |
347 | 343 | ||
348 | clk_dis: | 344 | clk_dis: |
349 | clk_disable(uap->clk); | 345 | clk_disable_unprepare(uap->clk); |
350 | clk_unprep: | ||
351 | clk_unprepare(uap->clk); | ||
352 | out: | 346 | out: |
353 | return retval; | 347 | return retval; |
354 | } | 348 | } |
@@ -375,8 +369,7 @@ static void pl010_shutdown(struct uart_port *port) | |||
375 | /* | 369 | /* |
376 | * Shut down the clock producer | 370 | * Shut down the clock producer |
377 | */ | 371 | */ |
378 | clk_disable(uap->clk); | 372 | clk_disable_unprepare(uap->clk); |
379 | clk_unprepare(uap->clk); | ||
380 | } | 373 | } |
381 | 374 | ||
382 | static void | 375 | static void |
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d3553b5d3fca..cede93876649 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <linux/scatterlist.h> | 52 | #include <linux/scatterlist.h> |
53 | #include <linux/delay.h> | 53 | #include <linux/delay.h> |
54 | #include <linux/types.h> | 54 | #include <linux/types.h> |
55 | #include <linux/of.h> | ||
56 | #include <linux/of_device.h> | ||
55 | #include <linux/pinctrl/consumer.h> | 57 | #include <linux/pinctrl/consumer.h> |
56 | #include <linux/sizes.h> | 58 | #include <linux/sizes.h> |
57 | 59 | ||
@@ -75,7 +77,6 @@ struct vendor_data { | |||
75 | unsigned int lcrh_tx; | 77 | unsigned int lcrh_tx; |
76 | unsigned int lcrh_rx; | 78 | unsigned int lcrh_rx; |
77 | bool oversampling; | 79 | bool oversampling; |
78 | bool interrupt_may_hang; /* vendor-specific */ | ||
79 | bool dma_threshold; | 80 | bool dma_threshold; |
80 | bool cts_event_workaround; | 81 | bool cts_event_workaround; |
81 | }; | 82 | }; |
@@ -96,7 +97,6 @@ static struct vendor_data vendor_st = { | |||
96 | .lcrh_tx = ST_UART011_LCRH_TX, | 97 | .lcrh_tx = ST_UART011_LCRH_TX, |
97 | .lcrh_rx = ST_UART011_LCRH_RX, | 98 | .lcrh_rx = ST_UART011_LCRH_RX, |
98 | .oversampling = true, | 99 | .oversampling = true, |
99 | .interrupt_may_hang = true, | ||
100 | .dma_threshold = true, | 100 | .dma_threshold = true, |
101 | .cts_event_workaround = true, | 101 | .cts_event_workaround = true, |
102 | }; | 102 | }; |
@@ -147,7 +147,6 @@ struct uart_amba_port { | |||
147 | unsigned int old_cr; /* state during shutdown */ | 147 | unsigned int old_cr; /* state during shutdown */ |
148 | bool autorts; | 148 | bool autorts; |
149 | char type[12]; | 149 | char type[12]; |
150 | bool interrupt_may_hang; /* vendor-specific */ | ||
151 | #ifdef CONFIG_DMA_ENGINE | 150 | #ifdef CONFIG_DMA_ENGINE |
152 | /* DMA stuff */ | 151 | /* DMA stuff */ |
153 | bool using_tx_dma; | 152 | bool using_tx_dma; |
@@ -1215,14 +1214,14 @@ static irqreturn_t pl011_int(int irq, void *dev_id) | |||
1215 | return IRQ_RETVAL(handled); | 1214 | return IRQ_RETVAL(handled); |
1216 | } | 1215 | } |
1217 | 1216 | ||
1218 | static unsigned int pl01x_tx_empty(struct uart_port *port) | 1217 | static unsigned int pl011_tx_empty(struct uart_port *port) |
1219 | { | 1218 | { |
1220 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1219 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
1221 | unsigned int status = readw(uap->port.membase + UART01x_FR); | 1220 | unsigned int status = readw(uap->port.membase + UART01x_FR); |
1222 | return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; | 1221 | return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; |
1223 | } | 1222 | } |
1224 | 1223 | ||
1225 | static unsigned int pl01x_get_mctrl(struct uart_port *port) | 1224 | static unsigned int pl011_get_mctrl(struct uart_port *port) |
1226 | { | 1225 | { |
1227 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1226 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
1228 | unsigned int result = 0; | 1227 | unsigned int result = 0; |
@@ -1285,7 +1284,7 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) | |||
1285 | } | 1284 | } |
1286 | 1285 | ||
1287 | #ifdef CONFIG_CONSOLE_POLL | 1286 | #ifdef CONFIG_CONSOLE_POLL |
1288 | static int pl010_get_poll_char(struct uart_port *port) | 1287 | static int pl011_get_poll_char(struct uart_port *port) |
1289 | { | 1288 | { |
1290 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1289 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
1291 | unsigned int status; | 1290 | unsigned int status; |
@@ -1297,7 +1296,7 @@ static int pl010_get_poll_char(struct uart_port *port) | |||
1297 | return readw(uap->port.membase + UART01x_DR); | 1296 | return readw(uap->port.membase + UART01x_DR); |
1298 | } | 1297 | } |
1299 | 1298 | ||
1300 | static void pl010_put_poll_char(struct uart_port *port, | 1299 | static void pl011_put_poll_char(struct uart_port *port, |
1301 | unsigned char ch) | 1300 | unsigned char ch) |
1302 | { | 1301 | { |
1303 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 1302 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
@@ -1324,16 +1323,12 @@ static int pl011_startup(struct uart_port *port) | |||
1324 | "could not set default pins\n"); | 1323 | "could not set default pins\n"); |
1325 | } | 1324 | } |
1326 | 1325 | ||
1327 | retval = clk_prepare(uap->clk); | ||
1328 | if (retval) | ||
1329 | goto out; | ||
1330 | |||
1331 | /* | 1326 | /* |
1332 | * Try to enable the clock producer. | 1327 | * Try to enable the clock producer. |
1333 | */ | 1328 | */ |
1334 | retval = clk_enable(uap->clk); | 1329 | retval = clk_prepare_enable(uap->clk); |
1335 | if (retval) | 1330 | if (retval) |
1336 | goto clk_unprep; | 1331 | goto out; |
1337 | 1332 | ||
1338 | uap->port.uartclk = clk_get_rate(uap->clk); | 1333 | uap->port.uartclk = clk_get_rate(uap->clk); |
1339 | 1334 | ||
@@ -1411,9 +1406,7 @@ static int pl011_startup(struct uart_port *port) | |||
1411 | return 0; | 1406 | return 0; |
1412 | 1407 | ||
1413 | clk_dis: | 1408 | clk_dis: |
1414 | clk_disable(uap->clk); | 1409 | clk_disable_unprepare(uap->clk); |
1415 | clk_unprep: | ||
1416 | clk_unprepare(uap->clk); | ||
1417 | out: | 1410 | out: |
1418 | return retval; | 1411 | return retval; |
1419 | } | 1412 | } |
@@ -1473,8 +1466,7 @@ static void pl011_shutdown(struct uart_port *port) | |||
1473 | /* | 1466 | /* |
1474 | * Shut down the clock producer | 1467 | * Shut down the clock producer |
1475 | */ | 1468 | */ |
1476 | clk_disable(uap->clk); | 1469 | clk_disable_unprepare(uap->clk); |
1477 | clk_unprepare(uap->clk); | ||
1478 | /* Optionally let pins go into sleep states */ | 1470 | /* Optionally let pins go into sleep states */ |
1479 | if (!IS_ERR(uap->pins_sleep)) { | 1471 | if (!IS_ERR(uap->pins_sleep)) { |
1480 | retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); | 1472 | retval = pinctrl_select_state(uap->pinctrl, uap->pins_sleep); |
@@ -1637,7 +1629,7 @@ static const char *pl011_type(struct uart_port *port) | |||
1637 | /* | 1629 | /* |
1638 | * Release the memory region(s) being used by 'port' | 1630 | * Release the memory region(s) being used by 'port' |
1639 | */ | 1631 | */ |
1640 | static void pl010_release_port(struct uart_port *port) | 1632 | static void pl011_release_port(struct uart_port *port) |
1641 | { | 1633 | { |
1642 | release_mem_region(port->mapbase, SZ_4K); | 1634 | release_mem_region(port->mapbase, SZ_4K); |
1643 | } | 1635 | } |
@@ -1645,7 +1637,7 @@ static void pl010_release_port(struct uart_port *port) | |||
1645 | /* | 1637 | /* |
1646 | * Request the memory region(s) being used by 'port' | 1638 | * Request the memory region(s) being used by 'port' |
1647 | */ | 1639 | */ |
1648 | static int pl010_request_port(struct uart_port *port) | 1640 | static int pl011_request_port(struct uart_port *port) |
1649 | { | 1641 | { |
1650 | return request_mem_region(port->mapbase, SZ_4K, "uart-pl011") | 1642 | return request_mem_region(port->mapbase, SZ_4K, "uart-pl011") |
1651 | != NULL ? 0 : -EBUSY; | 1643 | != NULL ? 0 : -EBUSY; |
@@ -1654,18 +1646,18 @@ static int pl010_request_port(struct uart_port *port) | |||
1654 | /* | 1646 | /* |
1655 | * Configure/autoconfigure the port. | 1647 | * Configure/autoconfigure the port. |
1656 | */ | 1648 | */ |
1657 | static void pl010_config_port(struct uart_port *port, int flags) | 1649 | static void pl011_config_port(struct uart_port *port, int flags) |
1658 | { | 1650 | { |
1659 | if (flags & UART_CONFIG_TYPE) { | 1651 | if (flags & UART_CONFIG_TYPE) { |
1660 | port->type = PORT_AMBA; | 1652 | port->type = PORT_AMBA; |
1661 | pl010_request_port(port); | 1653 | pl011_request_port(port); |
1662 | } | 1654 | } |
1663 | } | 1655 | } |
1664 | 1656 | ||
1665 | /* | 1657 | /* |
1666 | * verify the new serial_struct (for TIOCSSERIAL). | 1658 | * verify the new serial_struct (for TIOCSSERIAL). |
1667 | */ | 1659 | */ |
1668 | static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) | 1660 | static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser) |
1669 | { | 1661 | { |
1670 | int ret = 0; | 1662 | int ret = 0; |
1671 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) | 1663 | if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) |
@@ -1678,9 +1670,9 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1678 | } | 1670 | } |
1679 | 1671 | ||
1680 | static struct uart_ops amba_pl011_pops = { | 1672 | static struct uart_ops amba_pl011_pops = { |
1681 | .tx_empty = pl01x_tx_empty, | 1673 | .tx_empty = pl011_tx_empty, |
1682 | .set_mctrl = pl011_set_mctrl, | 1674 | .set_mctrl = pl011_set_mctrl, |
1683 | .get_mctrl = pl01x_get_mctrl, | 1675 | .get_mctrl = pl011_get_mctrl, |
1684 | .stop_tx = pl011_stop_tx, | 1676 | .stop_tx = pl011_stop_tx, |
1685 | .start_tx = pl011_start_tx, | 1677 | .start_tx = pl011_start_tx, |
1686 | .stop_rx = pl011_stop_rx, | 1678 | .stop_rx = pl011_stop_rx, |
@@ -1691,13 +1683,13 @@ static struct uart_ops amba_pl011_pops = { | |||
1691 | .flush_buffer = pl011_dma_flush_buffer, | 1683 | .flush_buffer = pl011_dma_flush_buffer, |
1692 | .set_termios = pl011_set_termios, | 1684 | .set_termios = pl011_set_termios, |
1693 | .type = pl011_type, | 1685 | .type = pl011_type, |
1694 | .release_port = pl010_release_port, | 1686 | .release_port = pl011_release_port, |
1695 | .request_port = pl010_request_port, | 1687 | .request_port = pl011_request_port, |
1696 | .config_port = pl010_config_port, | 1688 | .config_port = pl011_config_port, |
1697 | .verify_port = pl010_verify_port, | 1689 | .verify_port = pl011_verify_port, |
1698 | #ifdef CONFIG_CONSOLE_POLL | 1690 | #ifdef CONFIG_CONSOLE_POLL |
1699 | .poll_get_char = pl010_get_poll_char, | 1691 | .poll_get_char = pl011_get_poll_char, |
1700 | .poll_put_char = pl010_put_poll_char, | 1692 | .poll_put_char = pl011_put_poll_char, |
1701 | #endif | 1693 | #endif |
1702 | }; | 1694 | }; |
1703 | 1695 | ||
@@ -1869,6 +1861,38 @@ static struct uart_driver amba_reg = { | |||
1869 | .cons = AMBA_CONSOLE, | 1861 | .cons = AMBA_CONSOLE, |
1870 | }; | 1862 | }; |
1871 | 1863 | ||
1864 | static int pl011_probe_dt_alias(int index, struct device *dev) | ||
1865 | { | ||
1866 | struct device_node *np; | ||
1867 | static bool seen_dev_with_alias = false; | ||
1868 | static bool seen_dev_without_alias = false; | ||
1869 | int ret = index; | ||
1870 | |||
1871 | if (!IS_ENABLED(CONFIG_OF)) | ||
1872 | return ret; | ||
1873 | |||
1874 | np = dev->of_node; | ||
1875 | if (!np) | ||
1876 | return ret; | ||
1877 | |||
1878 | ret = of_alias_get_id(np, "serial"); | ||
1879 | if (IS_ERR_VALUE(ret)) { | ||
1880 | seen_dev_without_alias = true; | ||
1881 | ret = index; | ||
1882 | } else { | ||
1883 | seen_dev_with_alias = true; | ||
1884 | if (ret >= ARRAY_SIZE(amba_ports) || amba_ports[ret] != NULL) { | ||
1885 | dev_warn(dev, "requested serial port %d not available.\n", ret); | ||
1886 | ret = index; | ||
1887 | } | ||
1888 | } | ||
1889 | |||
1890 | if (seen_dev_with_alias && seen_dev_without_alias) | ||
1891 | dev_warn(dev, "aliased and non-aliased serial devices found in device tree. Serial port enumeration may be unpredictable.\n"); | ||
1892 | |||
1893 | return ret; | ||
1894 | } | ||
1895 | |||
1872 | static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | 1896 | static int pl011_probe(struct amba_device *dev, const struct amba_id *id) |
1873 | { | 1897 | { |
1874 | struct uart_amba_port *uap; | 1898 | struct uart_amba_port *uap; |
@@ -1891,6 +1915,8 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
1891 | goto out; | 1915 | goto out; |
1892 | } | 1916 | } |
1893 | 1917 | ||
1918 | i = pl011_probe_dt_alias(i, &dev->dev); | ||
1919 | |||
1894 | base = ioremap(dev->res.start, resource_size(&dev->res)); | 1920 | base = ioremap(dev->res.start, resource_size(&dev->res)); |
1895 | if (!base) { | 1921 | if (!base) { |
1896 | ret = -ENOMEM; | 1922 | ret = -ENOMEM; |
@@ -1923,7 +1949,6 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
1923 | uap->lcrh_tx = vendor->lcrh_tx; | 1949 | uap->lcrh_tx = vendor->lcrh_tx; |
1924 | uap->old_cr = 0; | 1950 | uap->old_cr = 0; |
1925 | uap->fifosize = vendor->fifosize; | 1951 | uap->fifosize = vendor->fifosize; |
1926 | uap->interrupt_may_hang = vendor->interrupt_may_hang; | ||
1927 | uap->port.dev = &dev->dev; | 1952 | uap->port.dev = &dev->dev; |
1928 | uap->port.mapbase = dev->res.start; | 1953 | uap->port.mapbase = dev->res.start; |
1929 | uap->port.membase = base; | 1954 | uap->port.membase = base; |
diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c index bd97db23985b..9242d56ba267 100644 --- a/drivers/tty/serial/bfin_uart.c +++ b/drivers/tty/serial/bfin_uart.c | |||
@@ -182,7 +182,7 @@ static void bfin_serial_start_tx(struct uart_port *port) | |||
182 | * To avoid losting RX interrupt, we reset IR function | 182 | * To avoid losting RX interrupt, we reset IR function |
183 | * before sending data. | 183 | * before sending data. |
184 | */ | 184 | */ |
185 | if (tty->termios->c_line == N_IRDA) | 185 | if (tty->termios.c_line == N_IRDA) |
186 | bfin_serial_reset_irda(port); | 186 | bfin_serial_reset_irda(port); |
187 | 187 | ||
188 | #ifdef CONFIG_SERIAL_BFIN_DMA | 188 | #ifdef CONFIG_SERIAL_BFIN_DMA |
diff --git a/drivers/tty/serial/crisv10.c b/drivers/tty/serial/crisv10.c index 80b6b1b1f725..35ee6a2c6877 100644 --- a/drivers/tty/serial/crisv10.c +++ b/drivers/tty/serial/crisv10.c | |||
@@ -955,7 +955,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] = | |||
955 | /* Calculate the chartime depending on baudrate, numbor of bits etc. */ | 955 | /* Calculate the chartime depending on baudrate, numbor of bits etc. */ |
956 | static void update_char_time(struct e100_serial * info) | 956 | static void update_char_time(struct e100_serial * info) |
957 | { | 957 | { |
958 | tcflag_t cflags = info->port.tty->termios->c_cflag; | 958 | tcflag_t cflags = info->port.tty->termios.c_cflag; |
959 | int bits; | 959 | int bits; |
960 | 960 | ||
961 | /* calc. number of bits / data byte */ | 961 | /* calc. number of bits / data byte */ |
@@ -1473,7 +1473,7 @@ rs_stop(struct tty_struct *tty) | |||
1473 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, | 1473 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, |
1474 | STOP_CHAR(info->port.tty)); | 1474 | STOP_CHAR(info->port.tty)); |
1475 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); | 1475 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop); |
1476 | if (tty->termios->c_iflag & IXON ) { | 1476 | if (tty->termios.c_iflag & IXON ) { |
1477 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 1477 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
1478 | } | 1478 | } |
1479 | 1479 | ||
@@ -1496,7 +1496,7 @@ rs_start(struct tty_struct *tty) | |||
1496 | info->xmit.tail,SERIAL_XMIT_SIZE))); | 1496 | info->xmit.tail,SERIAL_XMIT_SIZE))); |
1497 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); | 1497 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty)); |
1498 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); | 1498 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); |
1499 | if (tty->termios->c_iflag & IXON ) { | 1499 | if (tty->termios.c_iflag & IXON ) { |
1500 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 1500 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
1501 | } | 1501 | } |
1502 | 1502 | ||
@@ -2929,7 +2929,7 @@ shutdown(struct e100_serial * info) | |||
2929 | descr[i].buf = 0; | 2929 | descr[i].buf = 0; |
2930 | } | 2930 | } |
2931 | 2931 | ||
2932 | if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) { | 2932 | if (!info->port.tty || (info->port.tty->termios.c_cflag & HUPCL)) { |
2933 | /* hang up DTR and RTS if HUPCL is enabled */ | 2933 | /* hang up DTR and RTS if HUPCL is enabled */ |
2934 | e100_dtr(info, 0); | 2934 | e100_dtr(info, 0); |
2935 | e100_rts(info, 0); /* could check CRTSCTS before doing this */ | 2935 | e100_rts(info, 0); /* could check CRTSCTS before doing this */ |
@@ -2953,12 +2953,12 @@ change_speed(struct e100_serial *info) | |||
2953 | unsigned long flags; | 2953 | unsigned long flags; |
2954 | /* first some safety checks */ | 2954 | /* first some safety checks */ |
2955 | 2955 | ||
2956 | if (!info->port.tty || !info->port.tty->termios) | 2956 | if (!info->port.tty) |
2957 | return; | 2957 | return; |
2958 | if (!info->ioport) | 2958 | if (!info->ioport) |
2959 | return; | 2959 | return; |
2960 | 2960 | ||
2961 | cflag = info->port.tty->termios->c_cflag; | 2961 | cflag = info->port.tty->termios.c_cflag; |
2962 | 2962 | ||
2963 | /* possibly, the tx/rx should be disabled first to do this safely */ | 2963 | /* possibly, the tx/rx should be disabled first to do this safely */ |
2964 | 2964 | ||
@@ -3088,7 +3088,7 @@ change_speed(struct e100_serial *info) | |||
3088 | info->ioport[REG_REC_CTRL] = info->rx_ctrl; | 3088 | info->ioport[REG_REC_CTRL] = info->rx_ctrl; |
3089 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty)); | 3089 | xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty)); |
3090 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); | 3090 | xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable); |
3091 | if (info->port.tty->termios->c_iflag & IXON ) { | 3091 | if (info->port.tty->termios.c_iflag & IXON ) { |
3092 | DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", | 3092 | DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n", |
3093 | STOP_CHAR(info->port.tty))); | 3093 | STOP_CHAR(info->port.tty))); |
3094 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); | 3094 | xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable); |
@@ -3355,7 +3355,7 @@ rs_throttle(struct tty_struct * tty) | |||
3355 | DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); | 3355 | DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty))); |
3356 | 3356 | ||
3357 | /* Do RTS before XOFF since XOFF might take some time */ | 3357 | /* Do RTS before XOFF since XOFF might take some time */ |
3358 | if (tty->termios->c_cflag & CRTSCTS) { | 3358 | if (tty->termios.c_cflag & CRTSCTS) { |
3359 | /* Turn off RTS line */ | 3359 | /* Turn off RTS line */ |
3360 | e100_rts(info, 0); | 3360 | e100_rts(info, 0); |
3361 | } | 3361 | } |
@@ -3377,7 +3377,7 @@ rs_unthrottle(struct tty_struct * tty) | |||
3377 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); | 3377 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty))); |
3378 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); | 3378 | DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count)); |
3379 | /* Do RTS before XOFF since XOFF might take some time */ | 3379 | /* Do RTS before XOFF since XOFF might take some time */ |
3380 | if (tty->termios->c_cflag & CRTSCTS) { | 3380 | if (tty->termios.c_cflag & CRTSCTS) { |
3381 | /* Assert RTS line */ | 3381 | /* Assert RTS line */ |
3382 | e100_rts(info, 1); | 3382 | e100_rts(info, 1); |
3383 | } | 3383 | } |
@@ -3748,7 +3748,7 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
3748 | 3748 | ||
3749 | /* Handle turning off CRTSCTS */ | 3749 | /* Handle turning off CRTSCTS */ |
3750 | if ((old_termios->c_cflag & CRTSCTS) && | 3750 | if ((old_termios->c_cflag & CRTSCTS) && |
3751 | !(tty->termios->c_cflag & CRTSCTS)) { | 3751 | !(tty->termios.c_cflag & CRTSCTS)) { |
3752 | tty->hw_stopped = 0; | 3752 | tty->hw_stopped = 0; |
3753 | rs_start(tty); | 3753 | rs_start(tty); |
3754 | } | 3754 | } |
@@ -3815,7 +3815,7 @@ rs_close(struct tty_struct *tty, struct file * filp) | |||
3815 | * separate termios for callout and dialin. | 3815 | * separate termios for callout and dialin. |
3816 | */ | 3816 | */ |
3817 | if (info->flags & ASYNC_NORMAL_ACTIVE) | 3817 | if (info->flags & ASYNC_NORMAL_ACTIVE) |
3818 | info->normal_termios = *tty->termios; | 3818 | info->normal_termios = tty->termios; |
3819 | /* | 3819 | /* |
3820 | * Now we wait for the transmit buffer to clear; and we notify | 3820 | * Now we wait for the transmit buffer to clear; and we notify |
3821 | * the line discipline to only process XON/XOFF characters. | 3821 | * the line discipline to only process XON/XOFF characters. |
@@ -3976,7 +3976,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3976 | */ | 3976 | */ |
3977 | if (tty_hung_up_p(filp) || | 3977 | if (tty_hung_up_p(filp) || |
3978 | (info->flags & ASYNC_CLOSING)) { | 3978 | (info->flags & ASYNC_CLOSING)) { |
3979 | wait_event_interruptible_tty(info->close_wait, | 3979 | wait_event_interruptible_tty(tty, info->close_wait, |
3980 | !(info->flags & ASYNC_CLOSING)); | 3980 | !(info->flags & ASYNC_CLOSING)); |
3981 | #ifdef SERIAL_DO_RESTART | 3981 | #ifdef SERIAL_DO_RESTART |
3982 | if (info->flags & ASYNC_HUP_NOTIFY) | 3982 | if (info->flags & ASYNC_HUP_NOTIFY) |
@@ -3998,7 +3998,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3998 | return 0; | 3998 | return 0; |
3999 | } | 3999 | } |
4000 | 4000 | ||
4001 | if (tty->termios->c_cflag & CLOCAL) { | 4001 | if (tty->termios.c_cflag & CLOCAL) { |
4002 | do_clocal = 1; | 4002 | do_clocal = 1; |
4003 | } | 4003 | } |
4004 | 4004 | ||
@@ -4052,9 +4052,9 @@ block_til_ready(struct tty_struct *tty, struct file * filp, | |||
4052 | printk("block_til_ready blocking: ttyS%d, count = %d\n", | 4052 | printk("block_til_ready blocking: ttyS%d, count = %d\n", |
4053 | info->line, info->count); | 4053 | info->line, info->count); |
4054 | #endif | 4054 | #endif |
4055 | tty_unlock(); | 4055 | tty_unlock(tty); |
4056 | schedule(); | 4056 | schedule(); |
4057 | tty_lock(); | 4057 | tty_lock(tty); |
4058 | } | 4058 | } |
4059 | set_current_state(TASK_RUNNING); | 4059 | set_current_state(TASK_RUNNING); |
4060 | remove_wait_queue(&info->open_wait, &wait); | 4060 | remove_wait_queue(&info->open_wait, &wait); |
@@ -4115,7 +4115,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4115 | */ | 4115 | */ |
4116 | if (tty_hung_up_p(filp) || | 4116 | if (tty_hung_up_p(filp) || |
4117 | (info->flags & ASYNC_CLOSING)) { | 4117 | (info->flags & ASYNC_CLOSING)) { |
4118 | wait_event_interruptible_tty(info->close_wait, | 4118 | wait_event_interruptible_tty(tty, info->close_wait, |
4119 | !(info->flags & ASYNC_CLOSING)); | 4119 | !(info->flags & ASYNC_CLOSING)); |
4120 | #ifdef SERIAL_DO_RESTART | 4120 | #ifdef SERIAL_DO_RESTART |
4121 | return ((info->flags & ASYNC_HUP_NOTIFY) ? | 4121 | return ((info->flags & ASYNC_HUP_NOTIFY) ? |
@@ -4219,7 +4219,7 @@ rs_open(struct tty_struct *tty, struct file * filp) | |||
4219 | } | 4219 | } |
4220 | 4220 | ||
4221 | if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { | 4221 | if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { |
4222 | *tty->termios = info->normal_termios; | 4222 | tty->termios = info->normal_termios; |
4223 | change_speed(info); | 4223 | change_speed(info); |
4224 | } | 4224 | } |
4225 | 4225 | ||
@@ -4443,14 +4443,12 @@ static int __init rs_init(void) | |||
4443 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ | 4443 | B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */ |
4444 | driver->init_termios.c_ispeed = 115200; | 4444 | driver->init_termios.c_ispeed = 115200; |
4445 | driver->init_termios.c_ospeed = 115200; | 4445 | driver->init_termios.c_ospeed = 115200; |
4446 | driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 4446 | driver->flags = TTY_DRIVER_REAL_RAW; |
4447 | 4447 | ||
4448 | tty_set_operations(driver, &rs_ops); | 4448 | tty_set_operations(driver, &rs_ops); |
4449 | serial_driver = driver; | 4449 | serial_driver = driver; |
4450 | if (tty_register_driver(driver)) | ||
4451 | panic("Couldn't register serial driver\n"); | ||
4452 | /* do some initializing for the separate ports */ | ||
4453 | 4450 | ||
4451 | /* do some initializing for the separate ports */ | ||
4454 | for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) { | 4452 | for (i = 0, info = rs_table; i < NR_PORTS; i++,info++) { |
4455 | if (info->enabled) { | 4453 | if (info->enabled) { |
4456 | if (cris_request_io_interface(info->io_if, | 4454 | if (cris_request_io_interface(info->io_if, |
@@ -4502,7 +4500,12 @@ static int __init rs_init(void) | |||
4502 | printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n", | 4500 | printk(KERN_INFO "%s%d at %p is a builtin UART with DMA\n", |
4503 | serial_driver->name, info->line, info->ioport); | 4501 | serial_driver->name, info->line, info->ioport); |
4504 | } | 4502 | } |
4503 | tty_port_link_device(&info->port, driver, i); | ||
4505 | } | 4504 | } |
4505 | |||
4506 | if (tty_register_driver(driver)) | ||
4507 | panic("Couldn't register serial driver\n"); | ||
4508 | |||
4506 | #ifdef CONFIG_ETRAX_FAST_TIMER | 4509 | #ifdef CONFIG_ETRAX_FAST_TIMER |
4507 | #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER | 4510 | #ifdef CONFIG_ETRAX_SERIAL_FAST_TIMER |
4508 | memset(fast_timers, 0, sizeof(fast_timers)); | 4511 | memset(fast_timers, 0, sizeof(fast_timers)); |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 3ad079ffd049..5b9bc19ed134 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -800,8 +800,8 @@ static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev) | |||
800 | tty_port_init(pport); | 800 | tty_port_init(pport); |
801 | pport->ops = &ifx_tty_port_ops; | 801 | pport->ops = &ifx_tty_port_ops; |
802 | ifx_dev->minor = IFX_SPI_TTY_ID; | 802 | ifx_dev->minor = IFX_SPI_TTY_ID; |
803 | ifx_dev->tty_dev = tty_register_device(tty_drv, ifx_dev->minor, | 803 | ifx_dev->tty_dev = tty_port_register_device(pport, tty_drv, |
804 | &ifx_dev->spi_dev->dev); | 804 | ifx_dev->minor, &ifx_dev->spi_dev->dev); |
805 | if (IS_ERR(ifx_dev->tty_dev)) { | 805 | if (IS_ERR(ifx_dev->tty_dev)) { |
806 | dev_dbg(&ifx_dev->spi_dev->dev, | 806 | dev_dbg(&ifx_dev->spi_dev->dev, |
807 | "%s: registering tty device failed", __func__); | 807 | "%s: registering tty device failed", __func__); |
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index d5c689d6217e..2a093a42512f 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c | |||
@@ -51,7 +51,7 @@ | |||
51 | 51 | ||
52 | #include <asm/io.h> | 52 | #include <asm/io.h> |
53 | #include <asm/irq.h> | 53 | #include <asm/irq.h> |
54 | #include <mach/imx-uart.h> | 54 | #include <linux/platform_data/serial-imx.h> |
55 | 55 | ||
56 | /* Register definitions */ | 56 | /* Register definitions */ |
57 | #define URXD0 0x0 /* Receiver Register */ | 57 | #define URXD0 0x0 /* Receiver Register */ |
@@ -132,6 +132,7 @@ | |||
132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ | 132 | #define UCR4_OREN (1<<1) /* Receiver overrun interrupt enable */ |
133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ | 133 | #define UCR4_DREN (1<<0) /* Recv data ready interrupt enable */ |
134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ | 134 | #define UFCR_RXTL_SHF 0 /* Receiver trigger level shift */ |
135 | #define UFCR_DCEDTE (1<<6) /* DCE/DTE mode select */ | ||
135 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ | 136 | #define UFCR_RFDIV (7<<7) /* Reference freq divider mask */ |
136 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) | 137 | #define UFCR_RFDIV_REG(x) (((x) < 7 ? 6 - (x) : 6) << 7) |
137 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ | 138 | #define UFCR_TXTL_SHF 10 /* Transmitter trigger level shift */ |
@@ -206,7 +207,7 @@ struct imx_port { | |||
206 | unsigned short trcv_delay; /* transceiver delay */ | 207 | unsigned short trcv_delay; /* transceiver delay */ |
207 | struct clk *clk_ipg; | 208 | struct clk *clk_ipg; |
208 | struct clk *clk_per; | 209 | struct clk *clk_per; |
209 | struct imx_uart_data *devdata; | 210 | const struct imx_uart_data *devdata; |
210 | }; | 211 | }; |
211 | 212 | ||
212 | struct imx_port_ucrs { | 213 | struct imx_port_ucrs { |
@@ -667,22 +668,11 @@ static void imx_break_ctl(struct uart_port *port, int break_state) | |||
667 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) | 668 | static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) |
668 | { | 669 | { |
669 | unsigned int val; | 670 | unsigned int val; |
670 | unsigned int ufcr_rfdiv; | ||
671 | |||
672 | /* set receiver / transmitter trigger level. | ||
673 | * RFDIV is set such way to satisfy requested uartclk value | ||
674 | */ | ||
675 | val = TXTL << 10 | RXTL; | ||
676 | ufcr_rfdiv = (clk_get_rate(sport->clk_per) + sport->port.uartclk / 2) | ||
677 | / sport->port.uartclk; | ||
678 | |||
679 | if(!ufcr_rfdiv) | ||
680 | ufcr_rfdiv = 1; | ||
681 | |||
682 | val |= UFCR_RFDIV_REG(ufcr_rfdiv); | ||
683 | 671 | ||
672 | /* set receiver / transmitter trigger level */ | ||
673 | val = readl(sport->port.membase + UFCR) & (UFCR_RFDIV | UFCR_DCEDTE); | ||
674 | val |= TXTL << UFCR_TXTL_SHF | RXTL; | ||
684 | writel(val, sport->port.membase + UFCR); | 675 | writel(val, sport->port.membase + UFCR); |
685 | |||
686 | return 0; | 676 | return 0; |
687 | } | 677 | } |
688 | 678 | ||
@@ -754,6 +744,7 @@ static int imx_startup(struct uart_port *port) | |||
754 | } | 744 | } |
755 | } | 745 | } |
756 | 746 | ||
747 | spin_lock_irqsave(&sport->port.lock, flags); | ||
757 | /* | 748 | /* |
758 | * Finally, clear and enable interrupts | 749 | * Finally, clear and enable interrupts |
759 | */ | 750 | */ |
@@ -807,7 +798,6 @@ static int imx_startup(struct uart_port *port) | |||
807 | /* | 798 | /* |
808 | * Enable modem status interrupts | 799 | * Enable modem status interrupts |
809 | */ | 800 | */ |
810 | spin_lock_irqsave(&sport->port.lock,flags); | ||
811 | imx_enable_ms(&sport->port); | 801 | imx_enable_ms(&sport->port); |
812 | spin_unlock_irqrestore(&sport->port.lock,flags); | 802 | spin_unlock_irqrestore(&sport->port.lock,flags); |
813 | 803 | ||
@@ -837,10 +827,13 @@ static void imx_shutdown(struct uart_port *port) | |||
837 | { | 827 | { |
838 | struct imx_port *sport = (struct imx_port *)port; | 828 | struct imx_port *sport = (struct imx_port *)port; |
839 | unsigned long temp; | 829 | unsigned long temp; |
830 | unsigned long flags; | ||
840 | 831 | ||
832 | spin_lock_irqsave(&sport->port.lock, flags); | ||
841 | temp = readl(sport->port.membase + UCR2); | 833 | temp = readl(sport->port.membase + UCR2); |
842 | temp &= ~(UCR2_TXEN); | 834 | temp &= ~(UCR2_TXEN); |
843 | writel(temp, sport->port.membase + UCR2); | 835 | writel(temp, sport->port.membase + UCR2); |
836 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
844 | 837 | ||
845 | if (USE_IRDA(sport)) { | 838 | if (USE_IRDA(sport)) { |
846 | struct imxuart_platform_data *pdata; | 839 | struct imxuart_platform_data *pdata; |
@@ -869,12 +862,14 @@ static void imx_shutdown(struct uart_port *port) | |||
869 | * Disable all interrupts, port and break condition. | 862 | * Disable all interrupts, port and break condition. |
870 | */ | 863 | */ |
871 | 864 | ||
865 | spin_lock_irqsave(&sport->port.lock, flags); | ||
872 | temp = readl(sport->port.membase + UCR1); | 866 | temp = readl(sport->port.membase + UCR1); |
873 | temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); | 867 | temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN); |
874 | if (USE_IRDA(sport)) | 868 | if (USE_IRDA(sport)) |
875 | temp &= ~(UCR1_IREN); | 869 | temp &= ~(UCR1_IREN); |
876 | 870 | ||
877 | writel(temp, sport->port.membase + UCR1); | 871 | writel(temp, sport->port.membase + UCR1); |
872 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
878 | } | 873 | } |
879 | 874 | ||
880 | static void | 875 | static void |
@@ -1217,6 +1212,9 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1217 | struct imx_port *sport = imx_ports[co->index]; | 1212 | struct imx_port *sport = imx_ports[co->index]; |
1218 | struct imx_port_ucrs old_ucr; | 1213 | struct imx_port_ucrs old_ucr; |
1219 | unsigned int ucr1; | 1214 | unsigned int ucr1; |
1215 | unsigned long flags; | ||
1216 | |||
1217 | spin_lock_irqsave(&sport->port.lock, flags); | ||
1220 | 1218 | ||
1221 | /* | 1219 | /* |
1222 | * First, save UCR1/2/3 and then disable interrupts | 1220 | * First, save UCR1/2/3 and then disable interrupts |
@@ -1242,6 +1240,8 @@ imx_console_write(struct console *co, const char *s, unsigned int count) | |||
1242 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); | 1240 | while (!(readl(sport->port.membase + USR2) & USR2_TXDC)); |
1243 | 1241 | ||
1244 | imx_port_ucrs_restore(&sport->port, &old_ucr); | 1242 | imx_port_ucrs_restore(&sport->port, &old_ucr); |
1243 | |||
1244 | spin_unlock_irqrestore(&sport->port.lock, flags); | ||
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | /* | 1247 | /* |
@@ -1505,18 +1505,21 @@ static int serial_imx_probe(struct platform_device *pdev) | |||
1505 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); | 1505 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
1506 | if (IS_ERR(pinctrl)) { | 1506 | if (IS_ERR(pinctrl)) { |
1507 | ret = PTR_ERR(pinctrl); | 1507 | ret = PTR_ERR(pinctrl); |
1508 | dev_err(&pdev->dev, "failed to get default pinctrl: %d\n", ret); | ||
1508 | goto unmap; | 1509 | goto unmap; |
1509 | } | 1510 | } |
1510 | 1511 | ||
1511 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); | 1512 | sport->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
1512 | if (IS_ERR(sport->clk_ipg)) { | 1513 | if (IS_ERR(sport->clk_ipg)) { |
1513 | ret = PTR_ERR(sport->clk_ipg); | 1514 | ret = PTR_ERR(sport->clk_ipg); |
1515 | dev_err(&pdev->dev, "failed to get ipg clk: %d\n", ret); | ||
1514 | goto unmap; | 1516 | goto unmap; |
1515 | } | 1517 | } |
1516 | 1518 | ||
1517 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); | 1519 | sport->clk_per = devm_clk_get(&pdev->dev, "per"); |
1518 | if (IS_ERR(sport->clk_per)) { | 1520 | if (IS_ERR(sport->clk_per)) { |
1519 | ret = PTR_ERR(sport->clk_per); | 1521 | ret = PTR_ERR(sport->clk_per); |
1522 | dev_err(&pdev->dev, "failed to get per clk: %d\n", ret); | ||
1520 | goto unmap; | 1523 | goto unmap; |
1521 | } | 1524 | } |
1522 | 1525 | ||
diff --git a/drivers/tty/serial/ioc3_serial.c b/drivers/tty/serial/ioc3_serial.c index 758ff310f7f8..5ac52898a0bb 100644 --- a/drivers/tty/serial/ioc3_serial.c +++ b/drivers/tty/serial/ioc3_serial.c | |||
@@ -1120,13 +1120,14 @@ static inline int do_read(struct uart_port *the_port, char *buf, int len) | |||
1120 | struct ioc3_port *port = get_ioc3_port(the_port); | 1120 | struct ioc3_port *port = get_ioc3_port(the_port); |
1121 | struct ring *inring; | 1121 | struct ring *inring; |
1122 | struct ring_entry *entry; | 1122 | struct ring_entry *entry; |
1123 | struct port_hooks *hooks = port->ip_hooks; | 1123 | struct port_hooks *hooks; |
1124 | int byte_num; | 1124 | int byte_num; |
1125 | char *sc; | 1125 | char *sc; |
1126 | int loop_counter; | 1126 | int loop_counter; |
1127 | 1127 | ||
1128 | BUG_ON(!(len >= 0)); | 1128 | BUG_ON(!(len >= 0)); |
1129 | BUG_ON(!port); | 1129 | BUG_ON(!port); |
1130 | hooks = port->ip_hooks; | ||
1130 | 1131 | ||
1131 | /* There is a nasty timing issue in the IOC3. When the rx_timer | 1132 | /* There is a nasty timing issue in the IOC3. When the rx_timer |
1132 | * expires or the rx_high condition arises, we take an interrupt. | 1133 | * expires or the rx_high condition arises, we take an interrupt. |
diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index e16894fb2ca3..3e7da10cebba 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c | |||
@@ -1803,7 +1803,7 @@ static inline int ic4_startup_local(struct uart_port *the_port) | |||
1803 | ioc4_set_proto(port, the_port->mapbase); | 1803 | ioc4_set_proto(port, the_port->mapbase); |
1804 | 1804 | ||
1805 | /* set the speed of the serial port */ | 1805 | /* set the speed of the serial port */ |
1806 | ioc4_change_speed(the_port, state->port.tty->termios, | 1806 | ioc4_change_speed(the_port, &state->port.tty->termios, |
1807 | (struct ktermios *)0); | 1807 | (struct ktermios *)0); |
1808 | 1808 | ||
1809 | return 0; | 1809 | return 0; |
@@ -2069,13 +2069,14 @@ static inline int do_read(struct uart_port *the_port, unsigned char *buf, | |||
2069 | struct ioc4_port *port = get_ioc4_port(the_port, 0); | 2069 | struct ioc4_port *port = get_ioc4_port(the_port, 0); |
2070 | struct ring *inring; | 2070 | struct ring *inring; |
2071 | struct ring_entry *entry; | 2071 | struct ring_entry *entry; |
2072 | struct hooks *hooks = port->ip_hooks; | 2072 | struct hooks *hooks; |
2073 | int byte_num; | 2073 | int byte_num; |
2074 | char *sc; | 2074 | char *sc; |
2075 | int loop_counter; | 2075 | int loop_counter; |
2076 | 2076 | ||
2077 | BUG_ON(!(len >= 0)); | 2077 | BUG_ON(!(len >= 0)); |
2078 | BUG_ON(!port); | 2078 | BUG_ON(!port); |
2079 | hooks = port->ip_hooks; | ||
2079 | 2080 | ||
2080 | /* There is a nasty timing issue in the IOC4. When the rx_timer | 2081 | /* There is a nasty timing issue in the IOC4. When the rx_timer |
2081 | * expires or the rx_high condition arises, we take an interrupt. | 2082 | * expires or the rx_high condition arises, we take an interrupt. |
diff --git a/drivers/tty/serial/jsm/jsm_tty.c b/drivers/tty/serial/jsm/jsm_tty.c index 434bd881fcae..71397961773c 100644 --- a/drivers/tty/serial/jsm/jsm_tty.c +++ b/drivers/tty/serial/jsm/jsm_tty.c | |||
@@ -161,7 +161,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch) | |||
161 | struct ktermios *termios; | 161 | struct ktermios *termios; |
162 | 162 | ||
163 | spin_lock_irqsave(&port->lock, lock_flags); | 163 | spin_lock_irqsave(&port->lock, lock_flags); |
164 | termios = port->state->port.tty->termios; | 164 | termios = &port->state->port.tty->termios; |
165 | if (ch == termios->c_cc[VSTART]) | 165 | if (ch == termios->c_cc[VSTART]) |
166 | channel->ch_bd->bd_ops->send_start_character(channel); | 166 | channel->ch_bd->bd_ops->send_start_character(channel); |
167 | 167 | ||
@@ -250,7 +250,7 @@ static int jsm_tty_open(struct uart_port *port) | |||
250 | channel->ch_cached_lsr = 0; | 250 | channel->ch_cached_lsr = 0; |
251 | channel->ch_stops_sent = 0; | 251 | channel->ch_stops_sent = 0; |
252 | 252 | ||
253 | termios = port->state->port.tty->termios; | 253 | termios = &port->state->port.tty->termios; |
254 | channel->ch_c_cflag = termios->c_cflag; | 254 | channel->ch_c_cflag = termios->c_cflag; |
255 | channel->ch_c_iflag = termios->c_iflag; | 255 | channel->ch_c_iflag = termios->c_iflag; |
256 | channel->ch_c_oflag = termios->c_oflag; | 256 | channel->ch_c_oflag = termios->c_oflag; |
@@ -283,7 +283,7 @@ static void jsm_tty_close(struct uart_port *port) | |||
283 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); | 283 | jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n"); |
284 | 284 | ||
285 | bd = channel->ch_bd; | 285 | bd = channel->ch_bd; |
286 | ts = port->state->port.tty->termios; | 286 | ts = &port->state->port.tty->termios; |
287 | 287 | ||
288 | channel->ch_flags &= ~(CH_STOPI); | 288 | channel->ch_flags &= ~(CH_STOPI); |
289 | 289 | ||
@@ -567,7 +567,7 @@ void jsm_input(struct jsm_channel *ch) | |||
567 | *input data and return immediately. | 567 | *input data and return immediately. |
568 | */ | 568 | */ |
569 | if (!tp || | 569 | if (!tp || |
570 | !(tp->termios->c_cflag & CREAD) ) { | 570 | !(tp->termios.c_cflag & CREAD) ) { |
571 | 571 | ||
572 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, | 572 | jsm_printk(READ, INFO, &ch->ch_bd->pci_dev, |
573 | "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum); | 573 | "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum); |
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c new file mode 100644 index 000000000000..ba3af3bf6d43 --- /dev/null +++ b/drivers/tty/serial/lpc32xx_hs.c | |||
@@ -0,0 +1,823 @@ | |||
1 | /* | ||
2 | * High Speed Serial Ports on NXP LPC32xx SoC | ||
3 | * | ||
4 | * Authors: Kevin Wells <kevin.wells@nxp.com> | ||
5 | * Roland Stigge <stigge@antcom.de> | ||
6 | * | ||
7 | * Copyright (C) 2010 NXP Semiconductors | ||
8 | * Copyright (C) 2012 Roland Stigge | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/ioport.h> | ||
23 | #include <linux/init.h> | ||
24 | #include <linux/console.h> | ||
25 | #include <linux/sysrq.h> | ||
26 | #include <linux/tty.h> | ||
27 | #include <linux/tty_flip.h> | ||
28 | #include <linux/serial_core.h> | ||
29 | #include <linux/serial.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/nmi.h> | ||
33 | #include <linux/io.h> | ||
34 | #include <linux/irq.h> | ||
35 | #include <linux/gpio.h> | ||
36 | #include <linux/of.h> | ||
37 | #include <mach/platform.h> | ||
38 | #include <mach/hardware.h> | ||
39 | |||
40 | /* | ||
41 | * High Speed UART register offsets | ||
42 | */ | ||
43 | #define LPC32XX_HSUART_FIFO(x) ((x) + 0x00) | ||
44 | #define LPC32XX_HSUART_LEVEL(x) ((x) + 0x04) | ||
45 | #define LPC32XX_HSUART_IIR(x) ((x) + 0x08) | ||
46 | #define LPC32XX_HSUART_CTRL(x) ((x) + 0x0C) | ||
47 | #define LPC32XX_HSUART_RATE(x) ((x) + 0x10) | ||
48 | |||
49 | #define LPC32XX_HSU_BREAK_DATA (1 << 10) | ||
50 | #define LPC32XX_HSU_ERROR_DATA (1 << 9) | ||
51 | #define LPC32XX_HSU_RX_EMPTY (1 << 8) | ||
52 | |||
53 | #define LPC32XX_HSU_TX_LEV(n) (((n) >> 8) & 0xFF) | ||
54 | #define LPC32XX_HSU_RX_LEV(n) ((n) & 0xFF) | ||
55 | |||
56 | #define LPC32XX_HSU_TX_INT_SET (1 << 6) | ||
57 | #define LPC32XX_HSU_RX_OE_INT (1 << 5) | ||
58 | #define LPC32XX_HSU_BRK_INT (1 << 4) | ||
59 | #define LPC32XX_HSU_FE_INT (1 << 3) | ||
60 | #define LPC32XX_HSU_RX_TIMEOUT_INT (1 << 2) | ||
61 | #define LPC32XX_HSU_RX_TRIG_INT (1 << 1) | ||
62 | #define LPC32XX_HSU_TX_INT (1 << 0) | ||
63 | |||
64 | #define LPC32XX_HSU_HRTS_INV (1 << 21) | ||
65 | #define LPC32XX_HSU_HRTS_TRIG_8B (0x0 << 19) | ||
66 | #define LPC32XX_HSU_HRTS_TRIG_16B (0x1 << 19) | ||
67 | #define LPC32XX_HSU_HRTS_TRIG_32B (0x2 << 19) | ||
68 | #define LPC32XX_HSU_HRTS_TRIG_48B (0x3 << 19) | ||
69 | #define LPC32XX_HSU_HRTS_EN (1 << 18) | ||
70 | #define LPC32XX_HSU_TMO_DISABLED (0x0 << 16) | ||
71 | #define LPC32XX_HSU_TMO_INACT_4B (0x1 << 16) | ||
72 | #define LPC32XX_HSU_TMO_INACT_8B (0x2 << 16) | ||
73 | #define LPC32XX_HSU_TMO_INACT_16B (0x3 << 16) | ||
74 | #define LPC32XX_HSU_HCTS_INV (1 << 15) | ||
75 | #define LPC32XX_HSU_HCTS_EN (1 << 14) | ||
76 | #define LPC32XX_HSU_OFFSET(n) ((n) << 9) | ||
77 | #define LPC32XX_HSU_BREAK (1 << 8) | ||
78 | #define LPC32XX_HSU_ERR_INT_EN (1 << 7) | ||
79 | #define LPC32XX_HSU_RX_INT_EN (1 << 6) | ||
80 | #define LPC32XX_HSU_TX_INT_EN (1 << 5) | ||
81 | #define LPC32XX_HSU_RX_TL1B (0x0 << 2) | ||
82 | #define LPC32XX_HSU_RX_TL4B (0x1 << 2) | ||
83 | #define LPC32XX_HSU_RX_TL8B (0x2 << 2) | ||
84 | #define LPC32XX_HSU_RX_TL16B (0x3 << 2) | ||
85 | #define LPC32XX_HSU_RX_TL32B (0x4 << 2) | ||
86 | #define LPC32XX_HSU_RX_TL48B (0x5 << 2) | ||
87 | #define LPC32XX_HSU_TX_TLEMPTY (0x0 << 0) | ||
88 | #define LPC32XX_HSU_TX_TL0B (0x0 << 0) | ||
89 | #define LPC32XX_HSU_TX_TL4B (0x1 << 0) | ||
90 | #define LPC32XX_HSU_TX_TL8B (0x2 << 0) | ||
91 | #define LPC32XX_HSU_TX_TL16B (0x3 << 0) | ||
92 | |||
93 | #define MODNAME "lpc32xx_hsuart" | ||
94 | |||
95 | struct lpc32xx_hsuart_port { | ||
96 | struct uart_port port; | ||
97 | }; | ||
98 | |||
99 | #define FIFO_READ_LIMIT 128 | ||
100 | #define MAX_PORTS 3 | ||
101 | #define LPC32XX_TTY_NAME "ttyTX" | ||
102 | static struct lpc32xx_hsuart_port lpc32xx_hs_ports[MAX_PORTS]; | ||
103 | |||
104 | #ifdef CONFIG_SERIAL_HS_LPC32XX_CONSOLE | ||
105 | static void wait_for_xmit_empty(struct uart_port *port) | ||
106 | { | ||
107 | unsigned int timeout = 10000; | ||
108 | |||
109 | do { | ||
110 | if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL( | ||
111 | port->membase))) == 0) | ||
112 | break; | ||
113 | if (--timeout == 0) | ||
114 | break; | ||
115 | udelay(1); | ||
116 | } while (1); | ||
117 | } | ||
118 | |||
119 | static void wait_for_xmit_ready(struct uart_port *port) | ||
120 | { | ||
121 | unsigned int timeout = 10000; | ||
122 | |||
123 | while (1) { | ||
124 | if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL( | ||
125 | port->membase))) < 32) | ||
126 | break; | ||
127 | if (--timeout == 0) | ||
128 | break; | ||
129 | udelay(1); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | static void lpc32xx_hsuart_console_putchar(struct uart_port *port, int ch) | ||
134 | { | ||
135 | wait_for_xmit_ready(port); | ||
136 | writel((u32)ch, LPC32XX_HSUART_FIFO(port->membase)); | ||
137 | } | ||
138 | |||
139 | static void lpc32xx_hsuart_console_write(struct console *co, const char *s, | ||
140 | unsigned int count) | ||
141 | { | ||
142 | struct lpc32xx_hsuart_port *up = &lpc32xx_hs_ports[co->index]; | ||
143 | unsigned long flags; | ||
144 | int locked = 1; | ||
145 | |||
146 | touch_nmi_watchdog(); | ||
147 | local_irq_save(flags); | ||
148 | if (up->port.sysrq) | ||
149 | locked = 0; | ||
150 | else if (oops_in_progress) | ||
151 | locked = spin_trylock(&up->port.lock); | ||
152 | else | ||
153 | spin_lock(&up->port.lock); | ||
154 | |||
155 | uart_console_write(&up->port, s, count, lpc32xx_hsuart_console_putchar); | ||
156 | wait_for_xmit_empty(&up->port); | ||
157 | |||
158 | if (locked) | ||
159 | spin_unlock(&up->port.lock); | ||
160 | local_irq_restore(flags); | ||
161 | } | ||
162 | |||
163 | static int __init lpc32xx_hsuart_console_setup(struct console *co, | ||
164 | char *options) | ||
165 | { | ||
166 | struct uart_port *port; | ||
167 | int baud = 115200; | ||
168 | int bits = 8; | ||
169 | int parity = 'n'; | ||
170 | int flow = 'n'; | ||
171 | |||
172 | if (co->index >= MAX_PORTS) | ||
173 | co->index = 0; | ||
174 | |||
175 | port = &lpc32xx_hs_ports[co->index].port; | ||
176 | if (!port->membase) | ||
177 | return -ENODEV; | ||
178 | |||
179 | if (options) | ||
180 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
181 | |||
182 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
183 | } | ||
184 | |||
185 | static struct uart_driver lpc32xx_hsuart_reg; | ||
186 | static struct console lpc32xx_hsuart_console = { | ||
187 | .name = LPC32XX_TTY_NAME, | ||
188 | .write = lpc32xx_hsuart_console_write, | ||
189 | .device = uart_console_device, | ||
190 | .setup = lpc32xx_hsuart_console_setup, | ||
191 | .flags = CON_PRINTBUFFER, | ||
192 | .index = -1, | ||
193 | .data = &lpc32xx_hsuart_reg, | ||
194 | }; | ||
195 | |||
196 | static int __init lpc32xx_hsuart_console_init(void) | ||
197 | { | ||
198 | register_console(&lpc32xx_hsuart_console); | ||
199 | return 0; | ||
200 | } | ||
201 | console_initcall(lpc32xx_hsuart_console_init); | ||
202 | |||
203 | #define LPC32XX_HSUART_CONSOLE (&lpc32xx_hsuart_console) | ||
204 | #else | ||
205 | #define LPC32XX_HSUART_CONSOLE NULL | ||
206 | #endif | ||
207 | |||
208 | static struct uart_driver lpc32xx_hs_reg = { | ||
209 | .owner = THIS_MODULE, | ||
210 | .driver_name = MODNAME, | ||
211 | .dev_name = LPC32XX_TTY_NAME, | ||
212 | .nr = MAX_PORTS, | ||
213 | .cons = LPC32XX_HSUART_CONSOLE, | ||
214 | }; | ||
215 | static int uarts_registered; | ||
216 | |||
217 | static unsigned int __serial_get_clock_div(unsigned long uartclk, | ||
218 | unsigned long rate) | ||
219 | { | ||
220 | u32 div, goodrate, hsu_rate, l_hsu_rate, comprate; | ||
221 | u32 rate_diff; | ||
222 | |||
223 | /* Find the closest divider to get the desired clock rate */ | ||
224 | div = uartclk / rate; | ||
225 | goodrate = hsu_rate = (div / 14) - 1; | ||
226 | if (hsu_rate != 0) | ||
227 | hsu_rate--; | ||
228 | |||
229 | /* Tweak divider */ | ||
230 | l_hsu_rate = hsu_rate + 3; | ||
231 | rate_diff = 0xFFFFFFFF; | ||
232 | |||
233 | while (hsu_rate < l_hsu_rate) { | ||
234 | comprate = uartclk / ((hsu_rate + 1) * 14); | ||
235 | if (abs(comprate - rate) < rate_diff) { | ||
236 | goodrate = hsu_rate; | ||
237 | rate_diff = abs(comprate - rate); | ||
238 | } | ||
239 | |||
240 | hsu_rate++; | ||
241 | } | ||
242 | if (hsu_rate > 0xFF) | ||
243 | hsu_rate = 0xFF; | ||
244 | |||
245 | return goodrate; | ||
246 | } | ||
247 | |||
248 | static void __serial_uart_flush(struct uart_port *port) | ||
249 | { | ||
250 | u32 tmp; | ||
251 | int cnt = 0; | ||
252 | |||
253 | while ((readl(LPC32XX_HSUART_LEVEL(port->membase)) > 0) && | ||
254 | (cnt++ < FIFO_READ_LIMIT)) | ||
255 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | ||
256 | } | ||
257 | |||
258 | static void __serial_lpc32xx_rx(struct uart_port *port) | ||
259 | { | ||
260 | unsigned int tmp, flag; | ||
261 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
262 | |||
263 | if (!tty) { | ||
264 | /* Discard data: no tty available */ | ||
265 | while (!(readl(LPC32XX_HSUART_FIFO(port->membase)) & | ||
266 | LPC32XX_HSU_RX_EMPTY)) | ||
267 | ; | ||
268 | |||
269 | return; | ||
270 | } | ||
271 | |||
272 | /* Read data from FIFO and push into terminal */ | ||
273 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | ||
274 | while (!(tmp & LPC32XX_HSU_RX_EMPTY)) { | ||
275 | flag = TTY_NORMAL; | ||
276 | port->icount.rx++; | ||
277 | |||
278 | if (tmp & LPC32XX_HSU_ERROR_DATA) { | ||
279 | /* Framing error */ | ||
280 | writel(LPC32XX_HSU_FE_INT, | ||
281 | LPC32XX_HSUART_IIR(port->membase)); | ||
282 | port->icount.frame++; | ||
283 | flag = TTY_FRAME; | ||
284 | tty_insert_flip_char(tty, 0, TTY_FRAME); | ||
285 | } | ||
286 | |||
287 | tty_insert_flip_char(tty, (tmp & 0xFF), flag); | ||
288 | |||
289 | tmp = readl(LPC32XX_HSUART_FIFO(port->membase)); | ||
290 | } | ||
291 | tty_flip_buffer_push(tty); | ||
292 | tty_kref_put(tty); | ||
293 | } | ||
294 | |||
295 | static void __serial_lpc32xx_tx(struct uart_port *port) | ||
296 | { | ||
297 | struct circ_buf *xmit = &port->state->xmit; | ||
298 | unsigned int tmp; | ||
299 | |||
300 | if (port->x_char) { | ||
301 | writel((u32)port->x_char, LPC32XX_HSUART_FIFO(port->membase)); | ||
302 | port->icount.tx++; | ||
303 | port->x_char = 0; | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) | ||
308 | goto exit_tx; | ||
309 | |||
310 | /* Transfer data */ | ||
311 | while (LPC32XX_HSU_TX_LEV(readl( | ||
312 | LPC32XX_HSUART_LEVEL(port->membase))) < 64) { | ||
313 | writel((u32) xmit->buf[xmit->tail], | ||
314 | LPC32XX_HSUART_FIFO(port->membase)); | ||
315 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
316 | port->icount.tx++; | ||
317 | if (uart_circ_empty(xmit)) | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
322 | uart_write_wakeup(port); | ||
323 | |||
324 | exit_tx: | ||
325 | if (uart_circ_empty(xmit)) { | ||
326 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
327 | tmp &= ~LPC32XX_HSU_TX_INT_EN; | ||
328 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
329 | } | ||
330 | } | ||
331 | |||
332 | static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id) | ||
333 | { | ||
334 | struct uart_port *port = dev_id; | ||
335 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
336 | u32 status; | ||
337 | |||
338 | spin_lock(&port->lock); | ||
339 | |||
340 | /* Read UART status and clear latched interrupts */ | ||
341 | status = readl(LPC32XX_HSUART_IIR(port->membase)); | ||
342 | |||
343 | if (status & LPC32XX_HSU_BRK_INT) { | ||
344 | /* Break received */ | ||
345 | writel(LPC32XX_HSU_BRK_INT, LPC32XX_HSUART_IIR(port->membase)); | ||
346 | port->icount.brk++; | ||
347 | uart_handle_break(port); | ||
348 | } | ||
349 | |||
350 | /* Framing error */ | ||
351 | if (status & LPC32XX_HSU_FE_INT) | ||
352 | writel(LPC32XX_HSU_FE_INT, LPC32XX_HSUART_IIR(port->membase)); | ||
353 | |||
354 | if (status & LPC32XX_HSU_RX_OE_INT) { | ||
355 | /* Receive FIFO overrun */ | ||
356 | writel(LPC32XX_HSU_RX_OE_INT, | ||
357 | LPC32XX_HSUART_IIR(port->membase)); | ||
358 | port->icount.overrun++; | ||
359 | if (tty) { | ||
360 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
361 | tty_schedule_flip(tty); | ||
362 | } | ||
363 | } | ||
364 | |||
365 | /* Data received? */ | ||
366 | if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) { | ||
367 | __serial_lpc32xx_rx(port); | ||
368 | if (tty) | ||
369 | tty_flip_buffer_push(tty); | ||
370 | } | ||
371 | |||
372 | /* Transmit data request? */ | ||
373 | if ((status & LPC32XX_HSU_TX_INT) && (!uart_tx_stopped(port))) { | ||
374 | writel(LPC32XX_HSU_TX_INT, LPC32XX_HSUART_IIR(port->membase)); | ||
375 | __serial_lpc32xx_tx(port); | ||
376 | } | ||
377 | |||
378 | spin_unlock(&port->lock); | ||
379 | tty_kref_put(tty); | ||
380 | |||
381 | return IRQ_HANDLED; | ||
382 | } | ||
383 | |||
384 | /* port->lock is not held. */ | ||
385 | static unsigned int serial_lpc32xx_tx_empty(struct uart_port *port) | ||
386 | { | ||
387 | unsigned int ret = 0; | ||
388 | |||
389 | if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL(port->membase))) == 0) | ||
390 | ret = TIOCSER_TEMT; | ||
391 | |||
392 | return ret; | ||
393 | } | ||
394 | |||
395 | /* port->lock held by caller. */ | ||
396 | static void serial_lpc32xx_set_mctrl(struct uart_port *port, | ||
397 | unsigned int mctrl) | ||
398 | { | ||
399 | /* No signals are supported on HS UARTs */ | ||
400 | } | ||
401 | |||
402 | /* port->lock is held by caller and interrupts are disabled. */ | ||
403 | static unsigned int serial_lpc32xx_get_mctrl(struct uart_port *port) | ||
404 | { | ||
405 | /* No signals are supported on HS UARTs */ | ||
406 | return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS; | ||
407 | } | ||
408 | |||
409 | /* port->lock held by caller. */ | ||
410 | static void serial_lpc32xx_stop_tx(struct uart_port *port) | ||
411 | { | ||
412 | u32 tmp; | ||
413 | |||
414 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
415 | tmp &= ~LPC32XX_HSU_TX_INT_EN; | ||
416 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
417 | } | ||
418 | |||
419 | /* port->lock held by caller. */ | ||
420 | static void serial_lpc32xx_start_tx(struct uart_port *port) | ||
421 | { | ||
422 | u32 tmp; | ||
423 | |||
424 | __serial_lpc32xx_tx(port); | ||
425 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
426 | tmp |= LPC32XX_HSU_TX_INT_EN; | ||
427 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
428 | } | ||
429 | |||
430 | /* port->lock held by caller. */ | ||
431 | static void serial_lpc32xx_stop_rx(struct uart_port *port) | ||
432 | { | ||
433 | u32 tmp; | ||
434 | |||
435 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
436 | tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN); | ||
437 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
438 | |||
439 | writel((LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT | | ||
440 | LPC32XX_HSU_FE_INT), LPC32XX_HSUART_IIR(port->membase)); | ||
441 | } | ||
442 | |||
443 | /* port->lock held by caller. */ | ||
444 | static void serial_lpc32xx_enable_ms(struct uart_port *port) | ||
445 | { | ||
446 | /* Modem status is not supported */ | ||
447 | } | ||
448 | |||
449 | /* port->lock is not held. */ | ||
450 | static void serial_lpc32xx_break_ctl(struct uart_port *port, | ||
451 | int break_state) | ||
452 | { | ||
453 | unsigned long flags; | ||
454 | u32 tmp; | ||
455 | |||
456 | spin_lock_irqsave(&port->lock, flags); | ||
457 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
458 | if (break_state != 0) | ||
459 | tmp |= LPC32XX_HSU_BREAK; | ||
460 | else | ||
461 | tmp &= ~LPC32XX_HSU_BREAK; | ||
462 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
463 | spin_unlock_irqrestore(&port->lock, flags); | ||
464 | } | ||
465 | |||
466 | /* LPC3250 Errata HSUART.1: Hang workaround via loopback mode on inactivity */ | ||
467 | static void lpc32xx_loopback_set(resource_size_t mapbase, int state) | ||
468 | { | ||
469 | int bit; | ||
470 | u32 tmp; | ||
471 | |||
472 | switch (mapbase) { | ||
473 | case LPC32XX_HS_UART1_BASE: | ||
474 | bit = 0; | ||
475 | break; | ||
476 | case LPC32XX_HS_UART2_BASE: | ||
477 | bit = 1; | ||
478 | break; | ||
479 | case LPC32XX_HS_UART7_BASE: | ||
480 | bit = 6; | ||
481 | break; | ||
482 | default: | ||
483 | WARN(1, "lpc32xx_hs: Warning: Unknown port at %08x\n", mapbase); | ||
484 | return; | ||
485 | } | ||
486 | |||
487 | tmp = readl(LPC32XX_UARTCTL_CLOOP); | ||
488 | if (state) | ||
489 | tmp |= (1 << bit); | ||
490 | else | ||
491 | tmp &= ~(1 << bit); | ||
492 | writel(tmp, LPC32XX_UARTCTL_CLOOP); | ||
493 | } | ||
494 | |||
495 | /* port->lock is not held. */ | ||
496 | static int serial_lpc32xx_startup(struct uart_port *port) | ||
497 | { | ||
498 | int retval; | ||
499 | unsigned long flags; | ||
500 | u32 tmp; | ||
501 | |||
502 | spin_lock_irqsave(&port->lock, flags); | ||
503 | |||
504 | __serial_uart_flush(port); | ||
505 | |||
506 | writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT | | ||
507 | LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT), | ||
508 | LPC32XX_HSUART_IIR(port->membase)); | ||
509 | |||
510 | writel(0xFF, LPC32XX_HSUART_RATE(port->membase)); | ||
511 | |||
512 | /* | ||
513 | * Set receiver timeout, HSU offset of 20, no break, no interrupts, | ||
514 | * and default FIFO trigger levels | ||
515 | */ | ||
516 | tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | | ||
517 | LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B; | ||
518 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
519 | |||
520 | lpc32xx_loopback_set(port->mapbase, 0); /* get out of loopback mode */ | ||
521 | |||
522 | spin_unlock_irqrestore(&port->lock, flags); | ||
523 | |||
524 | retval = request_irq(port->irq, serial_lpc32xx_interrupt, | ||
525 | 0, MODNAME, port); | ||
526 | if (!retval) | ||
527 | writel((tmp | LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN), | ||
528 | LPC32XX_HSUART_CTRL(port->membase)); | ||
529 | |||
530 | return retval; | ||
531 | } | ||
532 | |||
533 | /* port->lock is not held. */ | ||
534 | static void serial_lpc32xx_shutdown(struct uart_port *port) | ||
535 | { | ||
536 | u32 tmp; | ||
537 | unsigned long flags; | ||
538 | |||
539 | spin_lock_irqsave(&port->lock, flags); | ||
540 | |||
541 | tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | | ||
542 | LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B; | ||
543 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
544 | |||
545 | lpc32xx_loopback_set(port->mapbase, 1); /* go to loopback mode */ | ||
546 | |||
547 | spin_unlock_irqrestore(&port->lock, flags); | ||
548 | |||
549 | free_irq(port->irq, port); | ||
550 | } | ||
551 | |||
552 | /* port->lock is not held. */ | ||
553 | static void serial_lpc32xx_set_termios(struct uart_port *port, | ||
554 | struct ktermios *termios, | ||
555 | struct ktermios *old) | ||
556 | { | ||
557 | unsigned long flags; | ||
558 | unsigned int baud, quot; | ||
559 | u32 tmp; | ||
560 | |||
561 | /* Always 8-bit, no parity, 1 stop bit */ | ||
562 | termios->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD); | ||
563 | termios->c_cflag |= CS8; | ||
564 | |||
565 | termios->c_cflag &= ~(HUPCL | CMSPAR | CLOCAL | CRTSCTS); | ||
566 | |||
567 | baud = uart_get_baud_rate(port, termios, old, 0, | ||
568 | port->uartclk / 14); | ||
569 | |||
570 | quot = __serial_get_clock_div(port->uartclk, baud); | ||
571 | |||
572 | spin_lock_irqsave(&port->lock, flags); | ||
573 | |||
574 | /* Ignore characters? */ | ||
575 | tmp = readl(LPC32XX_HSUART_CTRL(port->membase)); | ||
576 | if ((termios->c_cflag & CREAD) == 0) | ||
577 | tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN); | ||
578 | else | ||
579 | tmp |= LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN; | ||
580 | writel(tmp, LPC32XX_HSUART_CTRL(port->membase)); | ||
581 | |||
582 | writel(quot, LPC32XX_HSUART_RATE(port->membase)); | ||
583 | |||
584 | uart_update_timeout(port, termios->c_cflag, baud); | ||
585 | |||
586 | spin_unlock_irqrestore(&port->lock, flags); | ||
587 | |||
588 | /* Don't rewrite B0 */ | ||
589 | if (tty_termios_baud_rate(termios)) | ||
590 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
591 | } | ||
592 | |||
593 | static const char *serial_lpc32xx_type(struct uart_port *port) | ||
594 | { | ||
595 | return MODNAME; | ||
596 | } | ||
597 | |||
598 | static void serial_lpc32xx_release_port(struct uart_port *port) | ||
599 | { | ||
600 | if ((port->iotype == UPIO_MEM32) && (port->mapbase)) { | ||
601 | if (port->flags & UPF_IOREMAP) { | ||
602 | iounmap(port->membase); | ||
603 | port->membase = NULL; | ||
604 | } | ||
605 | |||
606 | release_mem_region(port->mapbase, SZ_4K); | ||
607 | } | ||
608 | } | ||
609 | |||
610 | static int serial_lpc32xx_request_port(struct uart_port *port) | ||
611 | { | ||
612 | int ret = -ENODEV; | ||
613 | |||
614 | if ((port->iotype == UPIO_MEM32) && (port->mapbase)) { | ||
615 | ret = 0; | ||
616 | |||
617 | if (!request_mem_region(port->mapbase, SZ_4K, MODNAME)) | ||
618 | ret = -EBUSY; | ||
619 | else if (port->flags & UPF_IOREMAP) { | ||
620 | port->membase = ioremap(port->mapbase, SZ_4K); | ||
621 | if (!port->membase) { | ||
622 | release_mem_region(port->mapbase, SZ_4K); | ||
623 | ret = -ENOMEM; | ||
624 | } | ||
625 | } | ||
626 | } | ||
627 | |||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | static void serial_lpc32xx_config_port(struct uart_port *port, int uflags) | ||
632 | { | ||
633 | int ret; | ||
634 | |||
635 | ret = serial_lpc32xx_request_port(port); | ||
636 | if (ret < 0) | ||
637 | return; | ||
638 | port->type = PORT_UART00; | ||
639 | port->fifosize = 64; | ||
640 | |||
641 | __serial_uart_flush(port); | ||
642 | |||
643 | writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT | | ||
644 | LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT), | ||
645 | LPC32XX_HSUART_IIR(port->membase)); | ||
646 | |||
647 | writel(0xFF, LPC32XX_HSUART_RATE(port->membase)); | ||
648 | |||
649 | /* Set receiver timeout, HSU offset of 20, no break, no interrupts, | ||
650 | and default FIFO trigger levels */ | ||
651 | writel(LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B | | ||
652 | LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B, | ||
653 | LPC32XX_HSUART_CTRL(port->membase)); | ||
654 | } | ||
655 | |||
656 | static int serial_lpc32xx_verify_port(struct uart_port *port, | ||
657 | struct serial_struct *ser) | ||
658 | { | ||
659 | int ret = 0; | ||
660 | |||
661 | if (ser->type != PORT_UART00) | ||
662 | ret = -EINVAL; | ||
663 | |||
664 | return ret; | ||
665 | } | ||
666 | |||
667 | static struct uart_ops serial_lpc32xx_pops = { | ||
668 | .tx_empty = serial_lpc32xx_tx_empty, | ||
669 | .set_mctrl = serial_lpc32xx_set_mctrl, | ||
670 | .get_mctrl = serial_lpc32xx_get_mctrl, | ||
671 | .stop_tx = serial_lpc32xx_stop_tx, | ||
672 | .start_tx = serial_lpc32xx_start_tx, | ||
673 | .stop_rx = serial_lpc32xx_stop_rx, | ||
674 | .enable_ms = serial_lpc32xx_enable_ms, | ||
675 | .break_ctl = serial_lpc32xx_break_ctl, | ||
676 | .startup = serial_lpc32xx_startup, | ||
677 | .shutdown = serial_lpc32xx_shutdown, | ||
678 | .set_termios = serial_lpc32xx_set_termios, | ||
679 | .type = serial_lpc32xx_type, | ||
680 | .release_port = serial_lpc32xx_release_port, | ||
681 | .request_port = serial_lpc32xx_request_port, | ||
682 | .config_port = serial_lpc32xx_config_port, | ||
683 | .verify_port = serial_lpc32xx_verify_port, | ||
684 | }; | ||
685 | |||
686 | /* | ||
687 | * Register a set of serial devices attached to a platform device | ||
688 | */ | ||
689 | static int __devinit serial_hs_lpc32xx_probe(struct platform_device *pdev) | ||
690 | { | ||
691 | struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[uarts_registered]; | ||
692 | int ret = 0; | ||
693 | struct resource *res; | ||
694 | |||
695 | if (uarts_registered >= MAX_PORTS) { | ||
696 | dev_err(&pdev->dev, | ||
697 | "Error: Number of possible ports exceeded (%d)!\n", | ||
698 | uarts_registered + 1); | ||
699 | return -ENXIO; | ||
700 | } | ||
701 | |||
702 | memset(p, 0, sizeof(*p)); | ||
703 | |||
704 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
705 | if (!res) { | ||
706 | dev_err(&pdev->dev, | ||
707 | "Error getting mem resource for HS UART port %d\n", | ||
708 | uarts_registered); | ||
709 | return -ENXIO; | ||
710 | } | ||
711 | p->port.mapbase = res->start; | ||
712 | p->port.membase = NULL; | ||
713 | |||
714 | p->port.irq = platform_get_irq(pdev, 0); | ||
715 | if (p->port.irq < 0) { | ||
716 | dev_err(&pdev->dev, "Error getting irq for HS UART port %d\n", | ||
717 | uarts_registered); | ||
718 | return p->port.irq; | ||
719 | } | ||
720 | |||
721 | p->port.iotype = UPIO_MEM32; | ||
722 | p->port.uartclk = LPC32XX_MAIN_OSC_FREQ; | ||
723 | p->port.regshift = 2; | ||
724 | p->port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP; | ||
725 | p->port.dev = &pdev->dev; | ||
726 | p->port.ops = &serial_lpc32xx_pops; | ||
727 | p->port.line = uarts_registered++; | ||
728 | spin_lock_init(&p->port.lock); | ||
729 | |||
730 | /* send port to loopback mode by default */ | ||
731 | lpc32xx_loopback_set(p->port.mapbase, 1); | ||
732 | |||
733 | ret = uart_add_one_port(&lpc32xx_hs_reg, &p->port); | ||
734 | |||
735 | platform_set_drvdata(pdev, p); | ||
736 | |||
737 | return ret; | ||
738 | } | ||
739 | |||
740 | /* | ||
741 | * Remove serial ports registered against a platform device. | ||
742 | */ | ||
743 | static int __devexit serial_hs_lpc32xx_remove(struct platform_device *pdev) | ||
744 | { | ||
745 | struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev); | ||
746 | |||
747 | uart_remove_one_port(&lpc32xx_hs_reg, &p->port); | ||
748 | |||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | |||
753 | #ifdef CONFIG_PM | ||
754 | static int serial_hs_lpc32xx_suspend(struct platform_device *pdev, | ||
755 | pm_message_t state) | ||
756 | { | ||
757 | struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev); | ||
758 | |||
759 | uart_suspend_port(&lpc32xx_hs_reg, &p->port); | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static int serial_hs_lpc32xx_resume(struct platform_device *pdev) | ||
765 | { | ||
766 | struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev); | ||
767 | |||
768 | uart_resume_port(&lpc32xx_hs_reg, &p->port); | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | #else | ||
773 | #define serial_hs_lpc32xx_suspend NULL | ||
774 | #define serial_hs_lpc32xx_resume NULL | ||
775 | #endif | ||
776 | |||
777 | static const struct of_device_id serial_hs_lpc32xx_dt_ids[] = { | ||
778 | { .compatible = "nxp,lpc3220-hsuart" }, | ||
779 | { /* sentinel */ } | ||
780 | }; | ||
781 | |||
782 | MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids); | ||
783 | |||
784 | static struct platform_driver serial_hs_lpc32xx_driver = { | ||
785 | .probe = serial_hs_lpc32xx_probe, | ||
786 | .remove = __devexit_p(serial_hs_lpc32xx_remove), | ||
787 | .suspend = serial_hs_lpc32xx_suspend, | ||
788 | .resume = serial_hs_lpc32xx_resume, | ||
789 | .driver = { | ||
790 | .name = MODNAME, | ||
791 | .owner = THIS_MODULE, | ||
792 | .of_match_table = serial_hs_lpc32xx_dt_ids, | ||
793 | }, | ||
794 | }; | ||
795 | |||
796 | static int __init lpc32xx_hsuart_init(void) | ||
797 | { | ||
798 | int ret; | ||
799 | |||
800 | ret = uart_register_driver(&lpc32xx_hs_reg); | ||
801 | if (ret) | ||
802 | return ret; | ||
803 | |||
804 | ret = platform_driver_register(&serial_hs_lpc32xx_driver); | ||
805 | if (ret) | ||
806 | uart_unregister_driver(&lpc32xx_hs_reg); | ||
807 | |||
808 | return ret; | ||
809 | } | ||
810 | |||
811 | static void __exit lpc32xx_hsuart_exit(void) | ||
812 | { | ||
813 | platform_driver_unregister(&serial_hs_lpc32xx_driver); | ||
814 | uart_unregister_driver(&lpc32xx_hs_reg); | ||
815 | } | ||
816 | |||
817 | module_init(lpc32xx_hsuart_init); | ||
818 | module_exit(lpc32xx_hsuart_exit); | ||
819 | |||
820 | MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>"); | ||
821 | MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>"); | ||
822 | MODULE_DESCRIPTION("NXP LPC32XX High Speed UART driver"); | ||
823 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index a0703624d5e5..b13949ad3408 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c | |||
@@ -44,8 +44,6 @@ | |||
44 | #include <asm/io.h> | 44 | #include <asm/io.h> |
45 | #include <asm/irq.h> | 45 | #include <asm/irq.h> |
46 | 46 | ||
47 | #define PORT_M32R_BASE PORT_M32R_SIO | ||
48 | #define PORT_INDEX(x) (x - PORT_M32R_BASE + 1) | ||
49 | #define BAUD_RATE 115200 | 47 | #define BAUD_RATE 115200 |
50 | 48 | ||
51 | #include <linux/serial_core.h> | 49 | #include <linux/serial_core.h> |
@@ -132,22 +130,6 @@ struct irq_info { | |||
132 | 130 | ||
133 | static struct irq_info irq_lists[NR_IRQS]; | 131 | static struct irq_info irq_lists[NR_IRQS]; |
134 | 132 | ||
135 | /* | ||
136 | * Here we define the default xmit fifo size used for each type of UART. | ||
137 | */ | ||
138 | static const struct serial_uart_config uart_config[] = { | ||
139 | [PORT_UNKNOWN] = { | ||
140 | .name = "unknown", | ||
141 | .dfl_xmit_fifo_size = 1, | ||
142 | .flags = 0, | ||
143 | }, | ||
144 | [PORT_INDEX(PORT_M32R_SIO)] = { | ||
145 | .name = "M32RSIO", | ||
146 | .dfl_xmit_fifo_size = 1, | ||
147 | .flags = 0, | ||
148 | }, | ||
149 | }; | ||
150 | |||
151 | #ifdef CONFIG_SERIAL_M32R_PLDSIO | 133 | #ifdef CONFIG_SERIAL_M32R_PLDSIO |
152 | 134 | ||
153 | #define __sio_in(x) inw((unsigned long)(x)) | 135 | #define __sio_in(x) inw((unsigned long)(x)) |
@@ -907,8 +889,7 @@ static void m32r_sio_config_port(struct uart_port *port, int unused) | |||
907 | 889 | ||
908 | spin_lock_irqsave(&up->port.lock, flags); | 890 | spin_lock_irqsave(&up->port.lock, flags); |
909 | 891 | ||
910 | up->port.type = (PORT_M32R_SIO - PORT_M32R_BASE + 1); | 892 | up->port.fifosize = 1; |
911 | up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size; | ||
912 | 893 | ||
913 | spin_unlock_irqrestore(&up->port.lock, flags); | 894 | spin_unlock_irqrestore(&up->port.lock, flags); |
914 | } | 895 | } |
@@ -916,23 +897,11 @@ static void m32r_sio_config_port(struct uart_port *port, int unused) | |||
916 | static int | 897 | static int |
917 | m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) | 898 | m32r_sio_verify_port(struct uart_port *port, struct serial_struct *ser) |
918 | { | 899 | { |
919 | if (ser->irq >= nr_irqs || ser->irq < 0 || | 900 | if (ser->irq >= nr_irqs || ser->irq < 0 || ser->baud_base < 9600) |
920 | ser->baud_base < 9600 || ser->type < PORT_UNKNOWN || | ||
921 | ser->type >= ARRAY_SIZE(uart_config)) | ||
922 | return -EINVAL; | 901 | return -EINVAL; |
923 | return 0; | 902 | return 0; |
924 | } | 903 | } |
925 | 904 | ||
926 | static const char * | ||
927 | m32r_sio_type(struct uart_port *port) | ||
928 | { | ||
929 | int type = port->type; | ||
930 | |||
931 | if (type >= ARRAY_SIZE(uart_config)) | ||
932 | type = 0; | ||
933 | return uart_config[type].name; | ||
934 | } | ||
935 | |||
936 | static struct uart_ops m32r_sio_pops = { | 905 | static struct uart_ops m32r_sio_pops = { |
937 | .tx_empty = m32r_sio_tx_empty, | 906 | .tx_empty = m32r_sio_tx_empty, |
938 | .set_mctrl = m32r_sio_set_mctrl, | 907 | .set_mctrl = m32r_sio_set_mctrl, |
@@ -946,7 +915,6 @@ static struct uart_ops m32r_sio_pops = { | |||
946 | .shutdown = m32r_sio_shutdown, | 915 | .shutdown = m32r_sio_shutdown, |
947 | .set_termios = m32r_sio_set_termios, | 916 | .set_termios = m32r_sio_set_termios, |
948 | .pm = m32r_sio_pm, | 917 | .pm = m32r_sio_pm, |
949 | .type = m32r_sio_type, | ||
950 | .release_port = m32r_sio_release_port, | 918 | .release_port = m32r_sio_release_port, |
951 | .request_port = m32r_sio_request_port, | 919 | .request_port = m32r_sio_request_port, |
952 | .config_port = m32r_sio_config_port, | 920 | .config_port = m32r_sio_config_port, |
diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c index b4902b99cfd2..46043c2521ce 100644 --- a/drivers/tty/serial/max3100.c +++ b/drivers/tty/serial/max3100.c | |||
@@ -910,17 +910,7 @@ static struct spi_driver max3100_driver = { | |||
910 | .resume = max3100_resume, | 910 | .resume = max3100_resume, |
911 | }; | 911 | }; |
912 | 912 | ||
913 | static int __init max3100_init(void) | 913 | module_spi_driver(max3100_driver); |
914 | { | ||
915 | return spi_register_driver(&max3100_driver); | ||
916 | } | ||
917 | module_init(max3100_init); | ||
918 | |||
919 | static void __exit max3100_exit(void) | ||
920 | { | ||
921 | spi_unregister_driver(&max3100_driver); | ||
922 | } | ||
923 | module_exit(max3100_exit); | ||
924 | 914 | ||
925 | MODULE_DESCRIPTION("MAX3100 driver"); | 915 | MODULE_DESCRIPTION("MAX3100 driver"); |
926 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); | 916 | MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); |
diff --git a/drivers/tty/serial/max3107.c b/drivers/tty/serial/max3107.c deleted file mode 100644 index 17c7ba805d98..000000000000 --- a/drivers/tty/serial/max3107.c +++ /dev/null | |||
@@ -1,1215 +0,0 @@ | |||
1 | /* | ||
2 | * max3107.c - spi uart protocol driver for Maxim 3107 | ||
3 | * Based on max3100.c | ||
4 | * by Christian Pellegrin <chripell@evolware.org> | ||
5 | * and max3110.c | ||
6 | * by Feng Tang <feng.tang@intel.com> | ||
7 | * | ||
8 | * Copyright (C) Aavamobile 2009 | ||
9 | * | ||
10 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | * | ||
26 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
27 | * | ||
28 | */ | ||
29 | |||
30 | #include <linux/delay.h> | ||
31 | #include <linux/device.h> | ||
32 | #include <linux/serial_core.h> | ||
33 | #include <linux/serial.h> | ||
34 | #include <linux/tty.h> | ||
35 | #include <linux/tty_flip.h> | ||
36 | #include <linux/gpio.h> | ||
37 | #include <linux/spi/spi.h> | ||
38 | #include <linux/freezer.h> | ||
39 | #include <linux/module.h> | ||
40 | #include "max3107.h" | ||
41 | |||
42 | static const struct baud_table brg26_ext[] = { | ||
43 | { 300, MAX3107_BRG26_B300 }, | ||
44 | { 600, MAX3107_BRG26_B600 }, | ||
45 | { 1200, MAX3107_BRG26_B1200 }, | ||
46 | { 2400, MAX3107_BRG26_B2400 }, | ||
47 | { 4800, MAX3107_BRG26_B4800 }, | ||
48 | { 9600, MAX3107_BRG26_B9600 }, | ||
49 | { 19200, MAX3107_BRG26_B19200 }, | ||
50 | { 57600, MAX3107_BRG26_B57600 }, | ||
51 | { 115200, MAX3107_BRG26_B115200 }, | ||
52 | { 230400, MAX3107_BRG26_B230400 }, | ||
53 | { 460800, MAX3107_BRG26_B460800 }, | ||
54 | { 921600, MAX3107_BRG26_B921600 }, | ||
55 | { 0, 0 } | ||
56 | }; | ||
57 | |||
58 | static const struct baud_table brg13_int[] = { | ||
59 | { 300, MAX3107_BRG13_IB300 }, | ||
60 | { 600, MAX3107_BRG13_IB600 }, | ||
61 | { 1200, MAX3107_BRG13_IB1200 }, | ||
62 | { 2400, MAX3107_BRG13_IB2400 }, | ||
63 | { 4800, MAX3107_BRG13_IB4800 }, | ||
64 | { 9600, MAX3107_BRG13_IB9600 }, | ||
65 | { 19200, MAX3107_BRG13_IB19200 }, | ||
66 | { 57600, MAX3107_BRG13_IB57600 }, | ||
67 | { 115200, MAX3107_BRG13_IB115200 }, | ||
68 | { 230400, MAX3107_BRG13_IB230400 }, | ||
69 | { 460800, MAX3107_BRG13_IB460800 }, | ||
70 | { 921600, MAX3107_BRG13_IB921600 }, | ||
71 | { 0, 0 } | ||
72 | }; | ||
73 | |||
74 | static u32 get_new_brg(int baud, struct max3107_port *s) | ||
75 | { | ||
76 | int i; | ||
77 | const struct baud_table *baud_tbl = s->baud_tbl; | ||
78 | |||
79 | for (i = 0; i < 13; i++) { | ||
80 | if (baud == baud_tbl[i].baud) | ||
81 | return baud_tbl[i].new_brg; | ||
82 | } | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* Perform SPI transfer for write/read of device register(s) */ | ||
88 | int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len) | ||
89 | { | ||
90 | struct spi_message spi_msg; | ||
91 | struct spi_transfer spi_xfer; | ||
92 | |||
93 | /* Initialize SPI ,message */ | ||
94 | spi_message_init(&spi_msg); | ||
95 | |||
96 | /* Initialize SPI transfer */ | ||
97 | memset(&spi_xfer, 0, sizeof spi_xfer); | ||
98 | spi_xfer.len = len; | ||
99 | spi_xfer.tx_buf = tx; | ||
100 | spi_xfer.rx_buf = rx; | ||
101 | spi_xfer.speed_hz = MAX3107_SPI_SPEED; | ||
102 | |||
103 | /* Add SPI transfer to SPI message */ | ||
104 | spi_message_add_tail(&spi_xfer, &spi_msg); | ||
105 | |||
106 | #ifdef DBG_TRACE_SPI_DATA | ||
107 | { | ||
108 | int i; | ||
109 | pr_info("tx len %d:\n", spi_xfer.len); | ||
110 | for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) | ||
111 | pr_info(" %x", ((u8 *)spi_xfer.tx_buf)[i]); | ||
112 | pr_info("\n"); | ||
113 | } | ||
114 | #endif | ||
115 | |||
116 | /* Perform synchronous SPI transfer */ | ||
117 | if (spi_sync(s->spi, &spi_msg)) { | ||
118 | dev_err(&s->spi->dev, "spi_sync failure\n"); | ||
119 | return -EIO; | ||
120 | } | ||
121 | |||
122 | #ifdef DBG_TRACE_SPI_DATA | ||
123 | if (spi_xfer.rx_buf) { | ||
124 | int i; | ||
125 | pr_info("rx len %d:\n", spi_xfer.len); | ||
126 | for (i = 0 ; i < spi_xfer.len && i < 32 ; i++) | ||
127 | pr_info(" %x", ((u8 *)spi_xfer.rx_buf)[i]); | ||
128 | pr_info("\n"); | ||
129 | } | ||
130 | #endif | ||
131 | return 0; | ||
132 | } | ||
133 | EXPORT_SYMBOL_GPL(max3107_rw); | ||
134 | |||
135 | /* Puts received data to circular buffer */ | ||
136 | static void put_data_to_circ_buf(struct max3107_port *s, unsigned char *data, | ||
137 | int len) | ||
138 | { | ||
139 | struct uart_port *port = &s->port; | ||
140 | struct tty_struct *tty; | ||
141 | |||
142 | if (!port->state) | ||
143 | return; | ||
144 | |||
145 | tty = port->state->port.tty; | ||
146 | if (!tty) | ||
147 | return; | ||
148 | |||
149 | /* Insert received data */ | ||
150 | tty_insert_flip_string(tty, data, len); | ||
151 | /* Update RX counter */ | ||
152 | port->icount.rx += len; | ||
153 | } | ||
154 | |||
155 | /* Handle data receiving */ | ||
156 | static void max3107_handlerx(struct max3107_port *s, u16 rxlvl) | ||
157 | { | ||
158 | int i; | ||
159 | int j; | ||
160 | int len; /* SPI transfer buffer length */ | ||
161 | u16 *buf; | ||
162 | u8 *valid_str; | ||
163 | |||
164 | if (!s->rx_enabled) | ||
165 | /* RX is disabled */ | ||
166 | return; | ||
167 | |||
168 | if (rxlvl == 0) { | ||
169 | /* RX fifo is empty */ | ||
170 | return; | ||
171 | } else if (rxlvl >= MAX3107_RX_FIFO_SIZE) { | ||
172 | dev_warn(&s->spi->dev, "Possible RX FIFO overrun %d\n", rxlvl); | ||
173 | /* Ensure sanity of RX level */ | ||
174 | rxlvl = MAX3107_RX_FIFO_SIZE; | ||
175 | } | ||
176 | if ((s->rxbuf == 0) || (s->rxstr == 0)) { | ||
177 | dev_warn(&s->spi->dev, "Rx buffer/str isn't ready\n"); | ||
178 | return; | ||
179 | } | ||
180 | buf = s->rxbuf; | ||
181 | valid_str = s->rxstr; | ||
182 | while (rxlvl) { | ||
183 | pr_debug("rxlvl %d\n", rxlvl); | ||
184 | /* Clear buffer */ | ||
185 | memset(buf, 0, sizeof(u16) * (MAX3107_RX_FIFO_SIZE + 2)); | ||
186 | len = 0; | ||
187 | if (s->irqen_reg & MAX3107_IRQ_RXFIFO_BIT) { | ||
188 | /* First disable RX FIFO interrupt */ | ||
189 | pr_debug("Disabling RX INT\n"); | ||
190 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
191 | s->irqen_reg &= ~MAX3107_IRQ_RXFIFO_BIT; | ||
192 | buf[0] |= s->irqen_reg; | ||
193 | len++; | ||
194 | } | ||
195 | /* Just increase the length by amount of words in FIFO since | ||
196 | * buffer was zeroed and SPI transfer of 0x0000 means reading | ||
197 | * from RX FIFO | ||
198 | */ | ||
199 | len += rxlvl; | ||
200 | /* Append RX level query */ | ||
201 | buf[len] = MAX3107_RXFIFOLVL_REG; | ||
202 | len++; | ||
203 | |||
204 | /* Perform the SPI transfer */ | ||
205 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, len * 2)) { | ||
206 | dev_err(&s->spi->dev, "SPI transfer for RX h failed\n"); | ||
207 | return; | ||
208 | } | ||
209 | |||
210 | /* Skip RX FIFO interrupt disabling word if it was added */ | ||
211 | j = ((len - 1) - rxlvl); | ||
212 | /* Read received words */ | ||
213 | for (i = 0; i < rxlvl; i++, j++) | ||
214 | valid_str[i] = (u8)buf[j]; | ||
215 | put_data_to_circ_buf(s, valid_str, rxlvl); | ||
216 | /* Get new RX level */ | ||
217 | rxlvl = (buf[len - 1] & MAX3107_SPI_RX_DATA_MASK); | ||
218 | } | ||
219 | |||
220 | if (s->rx_enabled) { | ||
221 | /* RX still enabled, re-enable RX FIFO interrupt */ | ||
222 | pr_debug("Enabling RX INT\n"); | ||
223 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
224 | s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; | ||
225 | buf[0] |= s->irqen_reg; | ||
226 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
227 | dev_err(&s->spi->dev, "RX FIFO INT enabling failed\n"); | ||
228 | } | ||
229 | |||
230 | /* Push the received data to receivers */ | ||
231 | if (s->port.state->port.tty) | ||
232 | tty_flip_buffer_push(s->port.state->port.tty); | ||
233 | } | ||
234 | |||
235 | |||
236 | /* Handle data sending */ | ||
237 | static void max3107_handletx(struct max3107_port *s) | ||
238 | { | ||
239 | struct circ_buf *xmit = &s->port.state->xmit; | ||
240 | int i; | ||
241 | unsigned long flags; | ||
242 | int len; /* SPI transfer buffer length */ | ||
243 | u16 *buf; | ||
244 | |||
245 | if (!s->tx_fifo_empty) | ||
246 | /* Don't send more data before previous data is sent */ | ||
247 | return; | ||
248 | |||
249 | if (uart_circ_empty(xmit) || uart_tx_stopped(&s->port)) | ||
250 | /* No data to send or TX is stopped */ | ||
251 | return; | ||
252 | |||
253 | if (!s->txbuf) { | ||
254 | dev_warn(&s->spi->dev, "Txbuf isn't ready\n"); | ||
255 | return; | ||
256 | } | ||
257 | buf = s->txbuf; | ||
258 | /* Get length of data pending in circular buffer */ | ||
259 | len = uart_circ_chars_pending(xmit); | ||
260 | if (len) { | ||
261 | /* Limit to size of TX FIFO */ | ||
262 | if (len > MAX3107_TX_FIFO_SIZE) | ||
263 | len = MAX3107_TX_FIFO_SIZE; | ||
264 | |||
265 | pr_debug("txlen %d\n", len); | ||
266 | |||
267 | /* Update TX counter */ | ||
268 | s->port.icount.tx += len; | ||
269 | |||
270 | /* TX FIFO will no longer be empty */ | ||
271 | s->tx_fifo_empty = 0; | ||
272 | |||
273 | i = 0; | ||
274 | if (s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT) { | ||
275 | /* First disable TX empty interrupt */ | ||
276 | pr_debug("Disabling TE INT\n"); | ||
277 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
278 | s->irqen_reg &= ~MAX3107_IRQ_TXEMPTY_BIT; | ||
279 | buf[i] |= s->irqen_reg; | ||
280 | i++; | ||
281 | len++; | ||
282 | } | ||
283 | /* Add data to send */ | ||
284 | spin_lock_irqsave(&s->port.lock, flags); | ||
285 | for ( ; i < len ; i++) { | ||
286 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_THR_REG); | ||
287 | buf[i] |= ((u16)xmit->buf[xmit->tail] & | ||
288 | MAX3107_SPI_TX_DATA_MASK); | ||
289 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
290 | } | ||
291 | spin_unlock_irqrestore(&s->port.lock, flags); | ||
292 | if (!(s->irqen_reg & MAX3107_IRQ_TXEMPTY_BIT)) { | ||
293 | /* Enable TX empty interrupt */ | ||
294 | pr_debug("Enabling TE INT\n"); | ||
295 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG); | ||
296 | s->irqen_reg |= MAX3107_IRQ_TXEMPTY_BIT; | ||
297 | buf[i] |= s->irqen_reg; | ||
298 | i++; | ||
299 | len++; | ||
300 | } | ||
301 | if (!s->tx_enabled) { | ||
302 | /* Enable TX */ | ||
303 | pr_debug("Enable TX\n"); | ||
304 | buf[i] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
305 | spin_lock_irqsave(&s->data_lock, flags); | ||
306 | s->mode1_reg &= ~MAX3107_MODE1_TXDIS_BIT; | ||
307 | buf[i] |= s->mode1_reg; | ||
308 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
309 | s->tx_enabled = 1; | ||
310 | i++; | ||
311 | len++; | ||
312 | } | ||
313 | |||
314 | /* Perform the SPI transfer */ | ||
315 | if (max3107_rw(s, (u8 *)buf, NULL, len*2)) { | ||
316 | dev_err(&s->spi->dev, | ||
317 | "SPI transfer TX handling failed\n"); | ||
318 | return; | ||
319 | } | ||
320 | } | ||
321 | |||
322 | /* Indicate wake up if circular buffer is getting low on data */ | ||
323 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
324 | uart_write_wakeup(&s->port); | ||
325 | |||
326 | } | ||
327 | |||
328 | /* Handle interrupts | ||
329 | * Also reads and returns current RX FIFO level | ||
330 | */ | ||
331 | static u16 handle_interrupt(struct max3107_port *s) | ||
332 | { | ||
333 | u16 buf[4]; /* Buffer for SPI transfers */ | ||
334 | u8 irq_status; | ||
335 | u16 rx_level; | ||
336 | unsigned long flags; | ||
337 | |||
338 | /* Read IRQ status register */ | ||
339 | buf[0] = MAX3107_IRQSTS_REG; | ||
340 | /* Read status IRQ status register */ | ||
341 | buf[1] = MAX3107_STS_IRQSTS_REG; | ||
342 | /* Read LSR IRQ status register */ | ||
343 | buf[2] = MAX3107_LSR_IRQSTS_REG; | ||
344 | /* Query RX level */ | ||
345 | buf[3] = MAX3107_RXFIFOLVL_REG; | ||
346 | |||
347 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 8)) { | ||
348 | dev_err(&s->spi->dev, | ||
349 | "SPI transfer for INTR handling failed\n"); | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | irq_status = (u8)buf[0]; | ||
354 | pr_debug("IRQSTS %x\n", irq_status); | ||
355 | rx_level = (buf[3] & MAX3107_SPI_RX_DATA_MASK); | ||
356 | |||
357 | if (irq_status & MAX3107_IRQ_LSR_BIT) { | ||
358 | /* LSR interrupt */ | ||
359 | if (buf[2] & MAX3107_LSR_RXTO_BIT) | ||
360 | /* RX timeout interrupt, | ||
361 | * handled by normal RX handling | ||
362 | */ | ||
363 | pr_debug("RX TO INT\n"); | ||
364 | } | ||
365 | |||
366 | if (irq_status & MAX3107_IRQ_TXEMPTY_BIT) { | ||
367 | /* Tx empty interrupt, | ||
368 | * disable TX and set tx_fifo_empty flag | ||
369 | */ | ||
370 | pr_debug("TE INT, disabling TX\n"); | ||
371 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
372 | spin_lock_irqsave(&s->data_lock, flags); | ||
373 | s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; | ||
374 | buf[0] |= s->mode1_reg; | ||
375 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
376 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
377 | dev_err(&s->spi->dev, "SPI transfer TX dis failed\n"); | ||
378 | s->tx_enabled = 0; | ||
379 | s->tx_fifo_empty = 1; | ||
380 | } | ||
381 | |||
382 | if (irq_status & MAX3107_IRQ_RXFIFO_BIT) | ||
383 | /* RX FIFO interrupt, | ||
384 | * handled by normal RX handling | ||
385 | */ | ||
386 | pr_debug("RFIFO INT\n"); | ||
387 | |||
388 | /* Return RX level */ | ||
389 | return rx_level; | ||
390 | } | ||
391 | |||
392 | /* Trigger work thread*/ | ||
393 | static void max3107_dowork(struct max3107_port *s) | ||
394 | { | ||
395 | if (!work_pending(&s->work) && !freezing(current) && !s->suspended) | ||
396 | queue_work(s->workqueue, &s->work); | ||
397 | else | ||
398 | dev_warn(&s->spi->dev, "interrup isn't serviced normally!\n"); | ||
399 | } | ||
400 | |||
401 | /* Work thread */ | ||
402 | static void max3107_work(struct work_struct *w) | ||
403 | { | ||
404 | struct max3107_port *s = container_of(w, struct max3107_port, work); | ||
405 | u16 rxlvl = 0; | ||
406 | int len; /* SPI transfer buffer length */ | ||
407 | u16 buf[5]; /* Buffer for SPI transfers */ | ||
408 | unsigned long flags; | ||
409 | |||
410 | /* Start by reading current RX FIFO level */ | ||
411 | buf[0] = MAX3107_RXFIFOLVL_REG; | ||
412 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { | ||
413 | dev_err(&s->spi->dev, "SPI transfer RX lev failed\n"); | ||
414 | rxlvl = 0; | ||
415 | } else { | ||
416 | rxlvl = (buf[0] & MAX3107_SPI_RX_DATA_MASK); | ||
417 | } | ||
418 | |||
419 | do { | ||
420 | pr_debug("rxlvl %d\n", rxlvl); | ||
421 | |||
422 | /* Handle RX */ | ||
423 | max3107_handlerx(s, rxlvl); | ||
424 | rxlvl = 0; | ||
425 | |||
426 | if (s->handle_irq) { | ||
427 | /* Handle pending interrupts | ||
428 | * We also get new RX FIFO level since new data may | ||
429 | * have been received while pushing received data to | ||
430 | * receivers | ||
431 | */ | ||
432 | s->handle_irq = 0; | ||
433 | rxlvl = handle_interrupt(s); | ||
434 | } | ||
435 | |||
436 | /* Handle TX */ | ||
437 | max3107_handletx(s); | ||
438 | |||
439 | /* Handle configuration changes */ | ||
440 | len = 0; | ||
441 | spin_lock_irqsave(&s->data_lock, flags); | ||
442 | if (s->mode1_commit) { | ||
443 | pr_debug("mode1_commit\n"); | ||
444 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
445 | buf[len++] |= s->mode1_reg; | ||
446 | s->mode1_commit = 0; | ||
447 | } | ||
448 | if (s->lcr_commit) { | ||
449 | pr_debug("lcr_commit\n"); | ||
450 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG); | ||
451 | buf[len++] |= s->lcr_reg; | ||
452 | s->lcr_commit = 0; | ||
453 | } | ||
454 | if (s->brg_commit) { | ||
455 | pr_debug("brg_commit\n"); | ||
456 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG); | ||
457 | buf[len++] |= ((s->brg_cfg >> 16) & | ||
458 | MAX3107_SPI_TX_DATA_MASK); | ||
459 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG); | ||
460 | buf[len++] |= ((s->brg_cfg >> 8) & | ||
461 | MAX3107_SPI_TX_DATA_MASK); | ||
462 | buf[len] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG); | ||
463 | buf[len++] |= ((s->brg_cfg) & 0xff); | ||
464 | s->brg_commit = 0; | ||
465 | } | ||
466 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
467 | |||
468 | if (len > 0) { | ||
469 | if (max3107_rw(s, (u8 *)buf, NULL, len * 2)) | ||
470 | dev_err(&s->spi->dev, | ||
471 | "SPI transfer config failed\n"); | ||
472 | } | ||
473 | |||
474 | /* Reloop if interrupt handling indicated data in RX FIFO */ | ||
475 | } while (rxlvl); | ||
476 | |||
477 | } | ||
478 | |||
479 | /* Set sleep mode */ | ||
480 | static void max3107_set_sleep(struct max3107_port *s, int mode) | ||
481 | { | ||
482 | u16 buf[1]; /* Buffer for SPI transfer */ | ||
483 | unsigned long flags; | ||
484 | pr_debug("enter, mode %d\n", mode); | ||
485 | |||
486 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG); | ||
487 | spin_lock_irqsave(&s->data_lock, flags); | ||
488 | switch (mode) { | ||
489 | case MAX3107_DISABLE_FORCED_SLEEP: | ||
490 | s->mode1_reg &= ~MAX3107_MODE1_FORCESLEEP_BIT; | ||
491 | break; | ||
492 | case MAX3107_ENABLE_FORCED_SLEEP: | ||
493 | s->mode1_reg |= MAX3107_MODE1_FORCESLEEP_BIT; | ||
494 | break; | ||
495 | case MAX3107_DISABLE_AUTOSLEEP: | ||
496 | s->mode1_reg &= ~MAX3107_MODE1_AUTOSLEEP_BIT; | ||
497 | break; | ||
498 | case MAX3107_ENABLE_AUTOSLEEP: | ||
499 | s->mode1_reg |= MAX3107_MODE1_AUTOSLEEP_BIT; | ||
500 | break; | ||
501 | default: | ||
502 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
503 | dev_warn(&s->spi->dev, "invalid sleep mode\n"); | ||
504 | return; | ||
505 | } | ||
506 | buf[0] |= s->mode1_reg; | ||
507 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
508 | |||
509 | if (max3107_rw(s, (u8 *)buf, NULL, 2)) | ||
510 | dev_err(&s->spi->dev, "SPI transfer sleep mode failed\n"); | ||
511 | |||
512 | if (mode == MAX3107_DISABLE_AUTOSLEEP || | ||
513 | mode == MAX3107_DISABLE_FORCED_SLEEP) | ||
514 | msleep(MAX3107_WAKEUP_DELAY); | ||
515 | } | ||
516 | |||
517 | /* Perform full register initialization */ | ||
518 | static void max3107_register_init(struct max3107_port *s) | ||
519 | { | ||
520 | u16 buf[11]; /* Buffer for SPI transfers */ | ||
521 | |||
522 | /* 1. Configure baud rate, 9600 as default */ | ||
523 | s->baud = 9600; | ||
524 | /* the below is default*/ | ||
525 | if (s->ext_clk) { | ||
526 | s->brg_cfg = MAX3107_BRG26_B9600; | ||
527 | s->baud_tbl = (struct baud_table *)brg26_ext; | ||
528 | } else { | ||
529 | s->brg_cfg = MAX3107_BRG13_IB9600; | ||
530 | s->baud_tbl = (struct baud_table *)brg13_int; | ||
531 | } | ||
532 | |||
533 | if (s->pdata->init) | ||
534 | s->pdata->init(s); | ||
535 | |||
536 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVMSB_REG) | ||
537 | | ((s->brg_cfg >> 16) & MAX3107_SPI_TX_DATA_MASK); | ||
538 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_BRGDIVLSB_REG) | ||
539 | | ((s->brg_cfg >> 8) & MAX3107_SPI_TX_DATA_MASK); | ||
540 | buf[2] = (MAX3107_WRITE_BIT | MAX3107_BRGCFG_REG) | ||
541 | | ((s->brg_cfg) & 0xff); | ||
542 | |||
543 | /* 2. Configure LCR register, 8N1 mode by default */ | ||
544 | s->lcr_reg = MAX3107_LCR_WORD_LEN_8; | ||
545 | buf[3] = (MAX3107_WRITE_BIT | MAX3107_LCR_REG) | ||
546 | | s->lcr_reg; | ||
547 | |||
548 | /* 3. Configure MODE 1 register */ | ||
549 | s->mode1_reg = 0; | ||
550 | /* Enable IRQ pin */ | ||
551 | s->mode1_reg |= MAX3107_MODE1_IRQSEL_BIT; | ||
552 | /* Disable TX */ | ||
553 | s->mode1_reg |= MAX3107_MODE1_TXDIS_BIT; | ||
554 | s->tx_enabled = 0; | ||
555 | /* RX is enabled */ | ||
556 | s->rx_enabled = 1; | ||
557 | buf[4] = (MAX3107_WRITE_BIT | MAX3107_MODE1_REG) | ||
558 | | s->mode1_reg; | ||
559 | |||
560 | /* 4. Configure MODE 2 register */ | ||
561 | buf[5] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); | ||
562 | if (s->loopback) { | ||
563 | /* Enable loopback */ | ||
564 | buf[5] |= MAX3107_MODE2_LOOPBACK_BIT; | ||
565 | } | ||
566 | /* Reset FIFOs */ | ||
567 | buf[5] |= MAX3107_MODE2_FIFORST_BIT; | ||
568 | s->tx_fifo_empty = 1; | ||
569 | |||
570 | /* 5. Configure FIFO trigger level register */ | ||
571 | buf[6] = (MAX3107_WRITE_BIT | MAX3107_FIFOTRIGLVL_REG); | ||
572 | /* RX FIFO trigger for 16 words, TX FIFO trigger not used */ | ||
573 | buf[6] |= (MAX3107_FIFOTRIGLVL_RX(16) | MAX3107_FIFOTRIGLVL_TX(0)); | ||
574 | |||
575 | /* 6. Configure flow control levels */ | ||
576 | buf[7] = (MAX3107_WRITE_BIT | MAX3107_FLOWLVL_REG); | ||
577 | /* Flow control halt level 96, resume level 48 */ | ||
578 | buf[7] |= (MAX3107_FLOWLVL_RES(48) | MAX3107_FLOWLVL_HALT(96)); | ||
579 | |||
580 | /* 7. Configure flow control */ | ||
581 | buf[8] = (MAX3107_WRITE_BIT | MAX3107_FLOWCTRL_REG); | ||
582 | /* Enable auto CTS and auto RTS flow control */ | ||
583 | buf[8] |= (MAX3107_FLOWCTRL_AUTOCTS_BIT | MAX3107_FLOWCTRL_AUTORTS_BIT); | ||
584 | |||
585 | /* 8. Configure RX timeout register */ | ||
586 | buf[9] = (MAX3107_WRITE_BIT | MAX3107_RXTO_REG); | ||
587 | /* Timeout after 48 character intervals */ | ||
588 | buf[9] |= 0x0030; | ||
589 | |||
590 | /* 9. Configure LSR interrupt enable register */ | ||
591 | buf[10] = (MAX3107_WRITE_BIT | MAX3107_LSR_IRQEN_REG); | ||
592 | /* Enable RX timeout interrupt */ | ||
593 | buf[10] |= MAX3107_LSR_RXTO_BIT; | ||
594 | |||
595 | /* Perform SPI transfer */ | ||
596 | if (max3107_rw(s, (u8 *)buf, NULL, 22)) | ||
597 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
598 | |||
599 | /* 10. Clear IRQ status register by reading it */ | ||
600 | buf[0] = MAX3107_IRQSTS_REG; | ||
601 | |||
602 | /* 11. Configure interrupt enable register */ | ||
603 | /* Enable LSR interrupt */ | ||
604 | s->irqen_reg = MAX3107_IRQ_LSR_BIT; | ||
605 | /* Enable RX FIFO interrupt */ | ||
606 | s->irqen_reg |= MAX3107_IRQ_RXFIFO_BIT; | ||
607 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG) | ||
608 | | s->irqen_reg; | ||
609 | |||
610 | /* 12. Clear FIFO reset that was set in step 6 */ | ||
611 | buf[2] = (MAX3107_WRITE_BIT | MAX3107_MODE2_REG); | ||
612 | if (s->loopback) { | ||
613 | /* Keep loopback enabled */ | ||
614 | buf[2] |= MAX3107_MODE2_LOOPBACK_BIT; | ||
615 | } | ||
616 | |||
617 | /* Perform SPI transfer */ | ||
618 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 6)) | ||
619 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
620 | |||
621 | } | ||
622 | |||
623 | /* IRQ handler */ | ||
624 | static irqreturn_t max3107_irq(int irqno, void *dev_id) | ||
625 | { | ||
626 | struct max3107_port *s = dev_id; | ||
627 | |||
628 | if (irqno != s->spi->irq) { | ||
629 | /* Unexpected IRQ */ | ||
630 | return IRQ_NONE; | ||
631 | } | ||
632 | |||
633 | /* Indicate irq */ | ||
634 | s->handle_irq = 1; | ||
635 | |||
636 | /* Trigger work thread */ | ||
637 | max3107_dowork(s); | ||
638 | |||
639 | return IRQ_HANDLED; | ||
640 | } | ||
641 | |||
642 | /* HW suspension function | ||
643 | * | ||
644 | * Currently autosleep is used to decrease current consumption, alternative | ||
645 | * approach would be to set the chip to reset mode if UART is not being | ||
646 | * used but that would mess the GPIOs | ||
647 | * | ||
648 | */ | ||
649 | void max3107_hw_susp(struct max3107_port *s, int suspend) | ||
650 | { | ||
651 | pr_debug("enter, suspend %d\n", suspend); | ||
652 | |||
653 | if (suspend) { | ||
654 | /* Suspend requested, | ||
655 | * enable autosleep to decrease current consumption | ||
656 | */ | ||
657 | s->suspended = 1; | ||
658 | max3107_set_sleep(s, MAX3107_ENABLE_AUTOSLEEP); | ||
659 | } else { | ||
660 | /* Resume requested, | ||
661 | * disable autosleep | ||
662 | */ | ||
663 | s->suspended = 0; | ||
664 | max3107_set_sleep(s, MAX3107_DISABLE_AUTOSLEEP); | ||
665 | } | ||
666 | } | ||
667 | EXPORT_SYMBOL_GPL(max3107_hw_susp); | ||
668 | |||
669 | /* Modem status IRQ enabling */ | ||
670 | static void max3107_enable_ms(struct uart_port *port) | ||
671 | { | ||
672 | /* Modem status not supported */ | ||
673 | } | ||
674 | |||
675 | /* Data send function */ | ||
676 | static void max3107_start_tx(struct uart_port *port) | ||
677 | { | ||
678 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
679 | |||
680 | /* Trigger work thread for sending data */ | ||
681 | max3107_dowork(s); | ||
682 | } | ||
683 | |||
684 | /* Function for checking that there is no pending transfers */ | ||
685 | static unsigned int max3107_tx_empty(struct uart_port *port) | ||
686 | { | ||
687 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
688 | |||
689 | pr_debug("returning %d\n", | ||
690 | (s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit))); | ||
691 | return s->tx_fifo_empty && uart_circ_empty(&s->port.state->xmit); | ||
692 | } | ||
693 | |||
694 | /* Function for stopping RX */ | ||
695 | static void max3107_stop_rx(struct uart_port *port) | ||
696 | { | ||
697 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
698 | unsigned long flags; | ||
699 | |||
700 | /* Set RX disabled in MODE 1 register */ | ||
701 | spin_lock_irqsave(&s->data_lock, flags); | ||
702 | s->mode1_reg |= MAX3107_MODE1_RXDIS_BIT; | ||
703 | s->mode1_commit = 1; | ||
704 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
705 | /* Set RX disabled */ | ||
706 | s->rx_enabled = 0; | ||
707 | /* Trigger work thread for doing the actual configuration change */ | ||
708 | max3107_dowork(s); | ||
709 | } | ||
710 | |||
711 | /* Function for returning control pin states */ | ||
712 | static unsigned int max3107_get_mctrl(struct uart_port *port) | ||
713 | { | ||
714 | /* DCD and DSR are not wired and CTS/RTS is handled automatically | ||
715 | * so just indicate DSR and CAR asserted | ||
716 | */ | ||
717 | return TIOCM_DSR | TIOCM_CAR; | ||
718 | } | ||
719 | |||
720 | /* Function for setting control pin states */ | ||
721 | static void max3107_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
722 | { | ||
723 | /* DCD and DSR are not wired and CTS/RTS is hadnled automatically | ||
724 | * so do nothing | ||
725 | */ | ||
726 | } | ||
727 | |||
728 | /* Function for configuring UART parameters */ | ||
729 | static void max3107_set_termios(struct uart_port *port, | ||
730 | struct ktermios *termios, | ||
731 | struct ktermios *old) | ||
732 | { | ||
733 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
734 | struct tty_struct *tty; | ||
735 | int baud; | ||
736 | u16 new_lcr = 0; | ||
737 | u32 new_brg = 0; | ||
738 | unsigned long flags; | ||
739 | |||
740 | if (!port->state) | ||
741 | return; | ||
742 | |||
743 | tty = port->state->port.tty; | ||
744 | if (!tty) | ||
745 | return; | ||
746 | |||
747 | /* Get new LCR register values */ | ||
748 | /* Word size */ | ||
749 | if ((termios->c_cflag & CSIZE) == CS7) | ||
750 | new_lcr |= MAX3107_LCR_WORD_LEN_7; | ||
751 | else | ||
752 | new_lcr |= MAX3107_LCR_WORD_LEN_8; | ||
753 | |||
754 | /* Parity */ | ||
755 | if (termios->c_cflag & PARENB) { | ||
756 | new_lcr |= MAX3107_LCR_PARITY_BIT; | ||
757 | if (!(termios->c_cflag & PARODD)) | ||
758 | new_lcr |= MAX3107_LCR_EVENPARITY_BIT; | ||
759 | } | ||
760 | |||
761 | /* Stop bits */ | ||
762 | if (termios->c_cflag & CSTOPB) { | ||
763 | /* 2 stop bits */ | ||
764 | new_lcr |= MAX3107_LCR_STOPLEN_BIT; | ||
765 | } | ||
766 | |||
767 | /* Mask termios capabilities we don't support */ | ||
768 | termios->c_cflag &= ~CMSPAR; | ||
769 | |||
770 | /* Set status ignore mask */ | ||
771 | s->port.ignore_status_mask = 0; | ||
772 | if (termios->c_iflag & IGNPAR) | ||
773 | s->port.ignore_status_mask |= MAX3107_ALL_ERRORS; | ||
774 | |||
775 | /* Set low latency to immediately handle pushed data */ | ||
776 | s->port.state->port.tty->low_latency = 1; | ||
777 | |||
778 | /* Get new baud rate generator configuration */ | ||
779 | baud = tty_get_baud_rate(tty); | ||
780 | |||
781 | spin_lock_irqsave(&s->data_lock, flags); | ||
782 | new_brg = get_new_brg(baud, s); | ||
783 | /* if can't find the corrent config, use previous */ | ||
784 | if (!new_brg) { | ||
785 | baud = s->baud; | ||
786 | new_brg = s->brg_cfg; | ||
787 | } | ||
788 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
789 | tty_termios_encode_baud_rate(termios, baud, baud); | ||
790 | s->baud = baud; | ||
791 | |||
792 | /* Update timeout according to new baud rate */ | ||
793 | uart_update_timeout(port, termios->c_cflag, baud); | ||
794 | |||
795 | spin_lock_irqsave(&s->data_lock, flags); | ||
796 | if (s->lcr_reg != new_lcr) { | ||
797 | s->lcr_reg = new_lcr; | ||
798 | s->lcr_commit = 1; | ||
799 | } | ||
800 | if (s->brg_cfg != new_brg) { | ||
801 | s->brg_cfg = new_brg; | ||
802 | s->brg_commit = 1; | ||
803 | } | ||
804 | spin_unlock_irqrestore(&s->data_lock, flags); | ||
805 | |||
806 | /* Trigger work thread for doing the actual configuration change */ | ||
807 | max3107_dowork(s); | ||
808 | } | ||
809 | |||
810 | /* Port shutdown function */ | ||
811 | static void max3107_shutdown(struct uart_port *port) | ||
812 | { | ||
813 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
814 | |||
815 | if (s->suspended && s->pdata->hw_suspend) | ||
816 | s->pdata->hw_suspend(s, 0); | ||
817 | |||
818 | /* Free the interrupt */ | ||
819 | free_irq(s->spi->irq, s); | ||
820 | |||
821 | if (s->workqueue) { | ||
822 | /* Flush and destroy work queue */ | ||
823 | flush_workqueue(s->workqueue); | ||
824 | destroy_workqueue(s->workqueue); | ||
825 | s->workqueue = NULL; | ||
826 | } | ||
827 | |||
828 | /* Suspend HW */ | ||
829 | if (s->pdata->hw_suspend) | ||
830 | s->pdata->hw_suspend(s, 1); | ||
831 | } | ||
832 | |||
833 | /* Port startup function */ | ||
834 | static int max3107_startup(struct uart_port *port) | ||
835 | { | ||
836 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
837 | |||
838 | /* Initialize work queue */ | ||
839 | s->workqueue = create_freezable_workqueue("max3107"); | ||
840 | if (!s->workqueue) { | ||
841 | dev_err(&s->spi->dev, "Workqueue creation failed\n"); | ||
842 | return -EBUSY; | ||
843 | } | ||
844 | INIT_WORK(&s->work, max3107_work); | ||
845 | |||
846 | /* Setup IRQ */ | ||
847 | if (request_irq(s->spi->irq, max3107_irq, IRQF_TRIGGER_FALLING, | ||
848 | "max3107", s)) { | ||
849 | dev_err(&s->spi->dev, "IRQ reguest failed\n"); | ||
850 | destroy_workqueue(s->workqueue); | ||
851 | s->workqueue = NULL; | ||
852 | return -EBUSY; | ||
853 | } | ||
854 | |||
855 | /* Resume HW */ | ||
856 | if (s->pdata->hw_suspend) | ||
857 | s->pdata->hw_suspend(s, 0); | ||
858 | |||
859 | /* Init registers */ | ||
860 | max3107_register_init(s); | ||
861 | |||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | /* Port type function */ | ||
866 | static const char *max3107_type(struct uart_port *port) | ||
867 | { | ||
868 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
869 | return s->spi->modalias; | ||
870 | } | ||
871 | |||
872 | /* Port release function */ | ||
873 | static void max3107_release_port(struct uart_port *port) | ||
874 | { | ||
875 | /* Do nothing */ | ||
876 | } | ||
877 | |||
878 | /* Port request function */ | ||
879 | static int max3107_request_port(struct uart_port *port) | ||
880 | { | ||
881 | /* Do nothing */ | ||
882 | return 0; | ||
883 | } | ||
884 | |||
885 | /* Port config function */ | ||
886 | static void max3107_config_port(struct uart_port *port, int flags) | ||
887 | { | ||
888 | struct max3107_port *s = container_of(port, struct max3107_port, port); | ||
889 | s->port.type = PORT_MAX3107; | ||
890 | } | ||
891 | |||
892 | /* Port verify function */ | ||
893 | static int max3107_verify_port(struct uart_port *port, | ||
894 | struct serial_struct *ser) | ||
895 | { | ||
896 | if (ser->type == PORT_UNKNOWN || ser->type == PORT_MAX3107) | ||
897 | return 0; | ||
898 | |||
899 | return -EINVAL; | ||
900 | } | ||
901 | |||
902 | /* Port stop TX function */ | ||
903 | static void max3107_stop_tx(struct uart_port *port) | ||
904 | { | ||
905 | /* Do nothing */ | ||
906 | } | ||
907 | |||
908 | /* Port break control function */ | ||
909 | static void max3107_break_ctl(struct uart_port *port, int break_state) | ||
910 | { | ||
911 | /* We don't support break control, do nothing */ | ||
912 | } | ||
913 | |||
914 | |||
915 | /* Port functions */ | ||
916 | static struct uart_ops max3107_ops = { | ||
917 | .tx_empty = max3107_tx_empty, | ||
918 | .set_mctrl = max3107_set_mctrl, | ||
919 | .get_mctrl = max3107_get_mctrl, | ||
920 | .stop_tx = max3107_stop_tx, | ||
921 | .start_tx = max3107_start_tx, | ||
922 | .stop_rx = max3107_stop_rx, | ||
923 | .enable_ms = max3107_enable_ms, | ||
924 | .break_ctl = max3107_break_ctl, | ||
925 | .startup = max3107_startup, | ||
926 | .shutdown = max3107_shutdown, | ||
927 | .set_termios = max3107_set_termios, | ||
928 | .type = max3107_type, | ||
929 | .release_port = max3107_release_port, | ||
930 | .request_port = max3107_request_port, | ||
931 | .config_port = max3107_config_port, | ||
932 | .verify_port = max3107_verify_port, | ||
933 | }; | ||
934 | |||
935 | /* UART driver data */ | ||
936 | static struct uart_driver max3107_uart_driver = { | ||
937 | .owner = THIS_MODULE, | ||
938 | .driver_name = "ttyMAX", | ||
939 | .dev_name = "ttyMAX", | ||
940 | .nr = 1, | ||
941 | }; | ||
942 | |||
943 | static int driver_registered = 0; | ||
944 | |||
945 | |||
946 | |||
947 | /* 'Generic' platform data */ | ||
948 | static struct max3107_plat generic_plat_data = { | ||
949 | .loopback = 0, | ||
950 | .ext_clk = 1, | ||
951 | .hw_suspend = max3107_hw_susp, | ||
952 | .polled_mode = 0, | ||
953 | .poll_time = 0, | ||
954 | }; | ||
955 | |||
956 | |||
957 | /*******************************************************************/ | ||
958 | |||
959 | /** | ||
960 | * max3107_probe - SPI bus probe entry point | ||
961 | * @spi: the spi device | ||
962 | * | ||
963 | * SPI wants us to probe this device and if appropriate claim it. | ||
964 | * Perform any platform specific requirements and then initialise | ||
965 | * the device. | ||
966 | */ | ||
967 | |||
968 | int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata) | ||
969 | { | ||
970 | struct max3107_port *s; | ||
971 | u16 buf[2]; /* Buffer for SPI transfers */ | ||
972 | int retval; | ||
973 | |||
974 | pr_info("enter max3107 probe\n"); | ||
975 | |||
976 | /* Allocate port structure */ | ||
977 | s = kzalloc(sizeof(*s), GFP_KERNEL); | ||
978 | if (!s) { | ||
979 | pr_err("Allocating port structure failed\n"); | ||
980 | return -ENOMEM; | ||
981 | } | ||
982 | |||
983 | s->pdata = pdata; | ||
984 | |||
985 | /* SPI Rx buffer | ||
986 | * +2 for RX FIFO interrupt | ||
987 | * disabling and RX level query | ||
988 | */ | ||
989 | s->rxbuf = kzalloc(sizeof(u16) * (MAX3107_RX_FIFO_SIZE+2), GFP_KERNEL); | ||
990 | if (!s->rxbuf) { | ||
991 | pr_err("Allocating RX buffer failed\n"); | ||
992 | retval = -ENOMEM; | ||
993 | goto err_free4; | ||
994 | } | ||
995 | s->rxstr = kzalloc(sizeof(u8) * MAX3107_RX_FIFO_SIZE, GFP_KERNEL); | ||
996 | if (!s->rxstr) { | ||
997 | pr_err("Allocating RX buffer failed\n"); | ||
998 | retval = -ENOMEM; | ||
999 | goto err_free3; | ||
1000 | } | ||
1001 | /* SPI Tx buffer | ||
1002 | * SPI transfer buffer | ||
1003 | * +3 for TX FIFO empty | ||
1004 | * interrupt disabling and | ||
1005 | * enabling and TX enabling | ||
1006 | */ | ||
1007 | s->txbuf = kzalloc(sizeof(u16) * MAX3107_TX_FIFO_SIZE + 3, GFP_KERNEL); | ||
1008 | if (!s->txbuf) { | ||
1009 | pr_err("Allocating TX buffer failed\n"); | ||
1010 | retval = -ENOMEM; | ||
1011 | goto err_free2; | ||
1012 | } | ||
1013 | /* Initialize shared data lock */ | ||
1014 | spin_lock_init(&s->data_lock); | ||
1015 | |||
1016 | /* SPI intializations */ | ||
1017 | dev_set_drvdata(&spi->dev, s); | ||
1018 | spi->mode = SPI_MODE_0; | ||
1019 | spi->dev.platform_data = pdata; | ||
1020 | spi->bits_per_word = 16; | ||
1021 | s->ext_clk = pdata->ext_clk; | ||
1022 | s->loopback = pdata->loopback; | ||
1023 | spi_setup(spi); | ||
1024 | s->spi = spi; | ||
1025 | |||
1026 | /* Check REV ID to ensure we are talking to what we expect */ | ||
1027 | buf[0] = MAX3107_REVID_REG; | ||
1028 | if (max3107_rw(s, (u8 *)buf, (u8 *)buf, 2)) { | ||
1029 | dev_err(&s->spi->dev, "SPI transfer for REVID read failed\n"); | ||
1030 | retval = -EIO; | ||
1031 | goto err_free1; | ||
1032 | } | ||
1033 | if ((buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID1 && | ||
1034 | (buf[0] & MAX3107_SPI_RX_DATA_MASK) != MAX3107_REVID2) { | ||
1035 | dev_err(&s->spi->dev, "REVID %x does not match\n", | ||
1036 | (buf[0] & MAX3107_SPI_RX_DATA_MASK)); | ||
1037 | retval = -ENODEV; | ||
1038 | goto err_free1; | ||
1039 | } | ||
1040 | |||
1041 | /* Disable all interrupts */ | ||
1042 | buf[0] = (MAX3107_WRITE_BIT | MAX3107_IRQEN_REG | 0x0000); | ||
1043 | buf[0] |= 0x0000; | ||
1044 | |||
1045 | /* Configure clock source */ | ||
1046 | buf[1] = (MAX3107_WRITE_BIT | MAX3107_CLKSRC_REG); | ||
1047 | if (s->ext_clk) { | ||
1048 | /* External clock */ | ||
1049 | buf[1] |= MAX3107_CLKSRC_EXTCLK_BIT; | ||
1050 | } | ||
1051 | |||
1052 | /* PLL bypass ON */ | ||
1053 | buf[1] |= MAX3107_CLKSRC_PLLBYP_BIT; | ||
1054 | |||
1055 | /* Perform SPI transfer */ | ||
1056 | if (max3107_rw(s, (u8 *)buf, NULL, 4)) { | ||
1057 | dev_err(&s->spi->dev, "SPI transfer for init failed\n"); | ||
1058 | retval = -EIO; | ||
1059 | goto err_free1; | ||
1060 | } | ||
1061 | |||
1062 | /* Register UART driver */ | ||
1063 | if (!driver_registered) { | ||
1064 | retval = uart_register_driver(&max3107_uart_driver); | ||
1065 | if (retval) { | ||
1066 | dev_err(&s->spi->dev, "Registering UART driver failed\n"); | ||
1067 | goto err_free1; | ||
1068 | } | ||
1069 | driver_registered = 1; | ||
1070 | } | ||
1071 | |||
1072 | /* Initialize UART port data */ | ||
1073 | s->port.fifosize = 128; | ||
1074 | s->port.ops = &max3107_ops; | ||
1075 | s->port.line = 0; | ||
1076 | s->port.dev = &spi->dev; | ||
1077 | s->port.uartclk = 9600; | ||
1078 | s->port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF; | ||
1079 | s->port.irq = s->spi->irq; | ||
1080 | s->port.type = PORT_MAX3107; | ||
1081 | |||
1082 | /* Add UART port */ | ||
1083 | retval = uart_add_one_port(&max3107_uart_driver, &s->port); | ||
1084 | if (retval < 0) { | ||
1085 | dev_err(&s->spi->dev, "Adding UART port failed\n"); | ||
1086 | goto err_free1; | ||
1087 | } | ||
1088 | |||
1089 | if (pdata->configure) { | ||
1090 | retval = pdata->configure(s); | ||
1091 | if (retval < 0) | ||
1092 | goto err_free1; | ||
1093 | } | ||
1094 | |||
1095 | /* Go to suspend mode */ | ||
1096 | if (pdata->hw_suspend) | ||
1097 | pdata->hw_suspend(s, 1); | ||
1098 | |||
1099 | return 0; | ||
1100 | |||
1101 | err_free1: | ||
1102 | kfree(s->txbuf); | ||
1103 | err_free2: | ||
1104 | kfree(s->rxstr); | ||
1105 | err_free3: | ||
1106 | kfree(s->rxbuf); | ||
1107 | err_free4: | ||
1108 | kfree(s); | ||
1109 | return retval; | ||
1110 | } | ||
1111 | EXPORT_SYMBOL_GPL(max3107_probe); | ||
1112 | |||
1113 | /* Driver remove function */ | ||
1114 | int max3107_remove(struct spi_device *spi) | ||
1115 | { | ||
1116 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
1117 | |||
1118 | pr_info("enter max3107 remove\n"); | ||
1119 | |||
1120 | /* Remove port */ | ||
1121 | if (uart_remove_one_port(&max3107_uart_driver, &s->port)) | ||
1122 | dev_warn(&s->spi->dev, "Removing UART port failed\n"); | ||
1123 | |||
1124 | |||
1125 | /* Free TxRx buffer */ | ||
1126 | kfree(s->rxbuf); | ||
1127 | kfree(s->rxstr); | ||
1128 | kfree(s->txbuf); | ||
1129 | |||
1130 | /* Free port structure */ | ||
1131 | kfree(s); | ||
1132 | |||
1133 | return 0; | ||
1134 | } | ||
1135 | EXPORT_SYMBOL_GPL(max3107_remove); | ||
1136 | |||
1137 | /* Driver suspend function */ | ||
1138 | int max3107_suspend(struct spi_device *spi, pm_message_t state) | ||
1139 | { | ||
1140 | #ifdef CONFIG_PM | ||
1141 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
1142 | |||
1143 | pr_debug("enter suspend\n"); | ||
1144 | |||
1145 | /* Suspend UART port */ | ||
1146 | uart_suspend_port(&max3107_uart_driver, &s->port); | ||
1147 | |||
1148 | /* Go to suspend mode */ | ||
1149 | if (s->pdata->hw_suspend) | ||
1150 | s->pdata->hw_suspend(s, 1); | ||
1151 | #endif /* CONFIG_PM */ | ||
1152 | return 0; | ||
1153 | } | ||
1154 | EXPORT_SYMBOL_GPL(max3107_suspend); | ||
1155 | |||
1156 | /* Driver resume function */ | ||
1157 | int max3107_resume(struct spi_device *spi) | ||
1158 | { | ||
1159 | #ifdef CONFIG_PM | ||
1160 | struct max3107_port *s = dev_get_drvdata(&spi->dev); | ||
1161 | |||
1162 | pr_debug("enter resume\n"); | ||
1163 | |||
1164 | /* Resume from suspend */ | ||
1165 | if (s->pdata->hw_suspend) | ||
1166 | s->pdata->hw_suspend(s, 0); | ||
1167 | |||
1168 | /* Resume UART port */ | ||
1169 | uart_resume_port(&max3107_uart_driver, &s->port); | ||
1170 | #endif /* CONFIG_PM */ | ||
1171 | return 0; | ||
1172 | } | ||
1173 | EXPORT_SYMBOL_GPL(max3107_resume); | ||
1174 | |||
1175 | static int max3107_probe_generic(struct spi_device *spi) | ||
1176 | { | ||
1177 | return max3107_probe(spi, &generic_plat_data); | ||
1178 | } | ||
1179 | |||
1180 | /* Spi driver data */ | ||
1181 | static struct spi_driver max3107_driver = { | ||
1182 | .driver = { | ||
1183 | .name = "max3107", | ||
1184 | .owner = THIS_MODULE, | ||
1185 | }, | ||
1186 | .probe = max3107_probe_generic, | ||
1187 | .remove = __devexit_p(max3107_remove), | ||
1188 | .suspend = max3107_suspend, | ||
1189 | .resume = max3107_resume, | ||
1190 | }; | ||
1191 | |||
1192 | /* Driver init function */ | ||
1193 | static int __init max3107_init(void) | ||
1194 | { | ||
1195 | pr_info("enter max3107 init\n"); | ||
1196 | return spi_register_driver(&max3107_driver); | ||
1197 | } | ||
1198 | |||
1199 | /* Driver exit function */ | ||
1200 | static void __exit max3107_exit(void) | ||
1201 | { | ||
1202 | pr_info("enter max3107 exit\n"); | ||
1203 | /* Unregister UART driver */ | ||
1204 | if (driver_registered) | ||
1205 | uart_unregister_driver(&max3107_uart_driver); | ||
1206 | spi_unregister_driver(&max3107_driver); | ||
1207 | } | ||
1208 | |||
1209 | module_init(max3107_init); | ||
1210 | module_exit(max3107_exit); | ||
1211 | |||
1212 | MODULE_DESCRIPTION("MAX3107 driver"); | ||
1213 | MODULE_AUTHOR("Aavamobile"); | ||
1214 | MODULE_ALIAS("spi:max3107"); | ||
1215 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/tty/serial/max3107.h b/drivers/tty/serial/max3107.h deleted file mode 100644 index 8415fc723b96..000000000000 --- a/drivers/tty/serial/max3107.h +++ /dev/null | |||
@@ -1,441 +0,0 @@ | |||
1 | /* | ||
2 | * max3107.h - spi uart protocol driver header for Maxim 3107 | ||
3 | * | ||
4 | * Copyright (C) Aavamobile 2009 | ||
5 | * Based on serial_max3100.h by Christian Pellegrin | ||
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 as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | */ | ||
12 | |||
13 | #ifndef _MAX3107_H | ||
14 | #define _MAX3107_H | ||
15 | |||
16 | /* Serial error status definitions */ | ||
17 | #define MAX3107_PARITY_ERROR 1 | ||
18 | #define MAX3107_FRAME_ERROR 2 | ||
19 | #define MAX3107_OVERRUN_ERROR 4 | ||
20 | #define MAX3107_ALL_ERRORS (MAX3107_PARITY_ERROR | \ | ||
21 | MAX3107_FRAME_ERROR | \ | ||
22 | MAX3107_OVERRUN_ERROR) | ||
23 | |||
24 | /* GPIO definitions */ | ||
25 | #define MAX3107_GPIO_BASE 88 | ||
26 | #define MAX3107_GPIO_COUNT 4 | ||
27 | |||
28 | |||
29 | /* GPIO connected to chip's reset pin */ | ||
30 | #define MAX3107_RESET_GPIO 87 | ||
31 | |||
32 | |||
33 | /* Chip reset delay */ | ||
34 | #define MAX3107_RESET_DELAY 10 | ||
35 | |||
36 | /* Chip wakeup delay */ | ||
37 | #define MAX3107_WAKEUP_DELAY 50 | ||
38 | |||
39 | |||
40 | /* Sleep mode definitions */ | ||
41 | #define MAX3107_DISABLE_FORCED_SLEEP 0 | ||
42 | #define MAX3107_ENABLE_FORCED_SLEEP 1 | ||
43 | #define MAX3107_DISABLE_AUTOSLEEP 2 | ||
44 | #define MAX3107_ENABLE_AUTOSLEEP 3 | ||
45 | |||
46 | |||
47 | /* Definitions for register access with SPI transfers | ||
48 | * | ||
49 | * SPI transfer format: | ||
50 | * | ||
51 | * Master to slave bits xzzzzzzzyyyyyyyy | ||
52 | * Slave to master bits aaaaaaaabbbbbbbb | ||
53 | * | ||
54 | * where: | ||
55 | * x = 0 for reads, 1 for writes | ||
56 | * z = register address | ||
57 | * y = new register value if write, 0 if read | ||
58 | * a = unspecified | ||
59 | * b = register value if read, unspecified if write | ||
60 | */ | ||
61 | |||
62 | /* SPI speed */ | ||
63 | #define MAX3107_SPI_SPEED (3125000 * 2) | ||
64 | |||
65 | /* Write bit */ | ||
66 | #define MAX3107_WRITE_BIT (1 << 15) | ||
67 | |||
68 | /* SPI TX data mask */ | ||
69 | #define MAX3107_SPI_RX_DATA_MASK (0x00ff) | ||
70 | |||
71 | /* SPI RX data mask */ | ||
72 | #define MAX3107_SPI_TX_DATA_MASK (0x00ff) | ||
73 | |||
74 | /* Register access masks */ | ||
75 | #define MAX3107_RHR_REG (0x0000) /* RX FIFO */ | ||
76 | #define MAX3107_THR_REG (0x0000) /* TX FIFO */ | ||
77 | #define MAX3107_IRQEN_REG (0x0100) /* IRQ enable */ | ||
78 | #define MAX3107_IRQSTS_REG (0x0200) /* IRQ status */ | ||
79 | #define MAX3107_LSR_IRQEN_REG (0x0300) /* LSR IRQ enable */ | ||
80 | #define MAX3107_LSR_IRQSTS_REG (0x0400) /* LSR IRQ status */ | ||
81 | #define MAX3107_SPCHR_IRQEN_REG (0x0500) /* Special char IRQ enable */ | ||
82 | #define MAX3107_SPCHR_IRQSTS_REG (0x0600) /* Special char IRQ status */ | ||
83 | #define MAX3107_STS_IRQEN_REG (0x0700) /* Status IRQ enable */ | ||
84 | #define MAX3107_STS_IRQSTS_REG (0x0800) /* Status IRQ status */ | ||
85 | #define MAX3107_MODE1_REG (0x0900) /* MODE1 */ | ||
86 | #define MAX3107_MODE2_REG (0x0a00) /* MODE2 */ | ||
87 | #define MAX3107_LCR_REG (0x0b00) /* LCR */ | ||
88 | #define MAX3107_RXTO_REG (0x0c00) /* RX timeout */ | ||
89 | #define MAX3107_HDPIXDELAY_REG (0x0d00) /* Auto transceiver delays */ | ||
90 | #define MAX3107_IRDA_REG (0x0e00) /* IRDA settings */ | ||
91 | #define MAX3107_FLOWLVL_REG (0x0f00) /* Flow control levels */ | ||
92 | #define MAX3107_FIFOTRIGLVL_REG (0x1000) /* FIFO IRQ trigger levels */ | ||
93 | #define MAX3107_TXFIFOLVL_REG (0x1100) /* TX FIFO level */ | ||
94 | #define MAX3107_RXFIFOLVL_REG (0x1200) /* RX FIFO level */ | ||
95 | #define MAX3107_FLOWCTRL_REG (0x1300) /* Flow control */ | ||
96 | #define MAX3107_XON1_REG (0x1400) /* XON1 character */ | ||
97 | #define MAX3107_XON2_REG (0x1500) /* XON2 character */ | ||
98 | #define MAX3107_XOFF1_REG (0x1600) /* XOFF1 character */ | ||
99 | #define MAX3107_XOFF2_REG (0x1700) /* XOFF2 character */ | ||
100 | #define MAX3107_GPIOCFG_REG (0x1800) /* GPIO config */ | ||
101 | #define MAX3107_GPIODATA_REG (0x1900) /* GPIO data */ | ||
102 | #define MAX3107_PLLCFG_REG (0x1a00) /* PLL config */ | ||
103 | #define MAX3107_BRGCFG_REG (0x1b00) /* Baud rate generator conf */ | ||
104 | #define MAX3107_BRGDIVLSB_REG (0x1c00) /* Baud rate divisor LSB */ | ||
105 | #define MAX3107_BRGDIVMSB_REG (0x1d00) /* Baud rate divisor MSB */ | ||
106 | #define MAX3107_CLKSRC_REG (0x1e00) /* Clock source */ | ||
107 | #define MAX3107_REVID_REG (0x1f00) /* Revision identification */ | ||
108 | |||
109 | /* IRQ register bits */ | ||
110 | #define MAX3107_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */ | ||
111 | #define MAX3107_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */ | ||
112 | #define MAX3107_IRQ_STS_BIT (1 << 2) /* Status interrupt */ | ||
113 | #define MAX3107_IRQ_RXFIFO_BIT (1 << 3) /* RX FIFO interrupt */ | ||
114 | #define MAX3107_IRQ_TXFIFO_BIT (1 << 4) /* TX FIFO interrupt */ | ||
115 | #define MAX3107_IRQ_TXEMPTY_BIT (1 << 5) /* TX FIFO empty interrupt */ | ||
116 | #define MAX3107_IRQ_RXEMPTY_BIT (1 << 6) /* RX FIFO empty interrupt */ | ||
117 | #define MAX3107_IRQ_CTS_BIT (1 << 7) /* CTS interrupt */ | ||
118 | |||
119 | /* LSR register bits */ | ||
120 | #define MAX3107_LSR_RXTO_BIT (1 << 0) /* RX timeout */ | ||
121 | #define MAX3107_LSR_RXOVR_BIT (1 << 1) /* RX overrun */ | ||
122 | #define MAX3107_LSR_RXPAR_BIT (1 << 2) /* RX parity error */ | ||
123 | #define MAX3107_LSR_FRERR_BIT (1 << 3) /* Frame error */ | ||
124 | #define MAX3107_LSR_RXBRK_BIT (1 << 4) /* RX break */ | ||
125 | #define MAX3107_LSR_RXNOISE_BIT (1 << 5) /* RX noise */ | ||
126 | #define MAX3107_LSR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
127 | #define MAX3107_LSR_CTS_BIT (1 << 7) /* CTS pin state */ | ||
128 | |||
129 | /* Special character register bits */ | ||
130 | #define MAX3107_SPCHR_XON1_BIT (1 << 0) /* XON1 character */ | ||
131 | #define MAX3107_SPCHR_XON2_BIT (1 << 1) /* XON2 character */ | ||
132 | #define MAX3107_SPCHR_XOFF1_BIT (1 << 2) /* XOFF1 character */ | ||
133 | #define MAX3107_SPCHR_XOFF2_BIT (1 << 3) /* XOFF2 character */ | ||
134 | #define MAX3107_SPCHR_BREAK_BIT (1 << 4) /* RX break */ | ||
135 | #define MAX3107_SPCHR_MULTIDROP_BIT (1 << 5) /* 9-bit multidrop addr char */ | ||
136 | #define MAX3107_SPCHR_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
137 | #define MAX3107_SPCHR_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
138 | |||
139 | /* Status register bits */ | ||
140 | #define MAX3107_STS_GPIO0_BIT (1 << 0) /* GPIO 0 interrupt */ | ||
141 | #define MAX3107_STS_GPIO1_BIT (1 << 1) /* GPIO 1 interrupt */ | ||
142 | #define MAX3107_STS_GPIO2_BIT (1 << 2) /* GPIO 2 interrupt */ | ||
143 | #define MAX3107_STS_GPIO3_BIT (1 << 3) /* GPIO 3 interrupt */ | ||
144 | #define MAX3107_STS_UNDEF4_BIT (1 << 4) /* Undefined/not used */ | ||
145 | #define MAX3107_STS_CLKREADY_BIT (1 << 5) /* Clock ready */ | ||
146 | #define MAX3107_STS_SLEEP_BIT (1 << 6) /* Sleep interrupt */ | ||
147 | #define MAX3107_STS_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
148 | |||
149 | /* MODE1 register bits */ | ||
150 | #define MAX3107_MODE1_RXDIS_BIT (1 << 0) /* RX disable */ | ||
151 | #define MAX3107_MODE1_TXDIS_BIT (1 << 1) /* TX disable */ | ||
152 | #define MAX3107_MODE1_TXHIZ_BIT (1 << 2) /* TX pin three-state */ | ||
153 | #define MAX3107_MODE1_RTSHIZ_BIT (1 << 3) /* RTS pin three-state */ | ||
154 | #define MAX3107_MODE1_TRNSCVCTRL_BIT (1 << 4) /* Transceiver ctrl enable */ | ||
155 | #define MAX3107_MODE1_FORCESLEEP_BIT (1 << 5) /* Force sleep mode */ | ||
156 | #define MAX3107_MODE1_AUTOSLEEP_BIT (1 << 6) /* Auto sleep enable */ | ||
157 | #define MAX3107_MODE1_IRQSEL_BIT (1 << 7) /* IRQ pin enable */ | ||
158 | |||
159 | /* MODE2 register bits */ | ||
160 | #define MAX3107_MODE2_RST_BIT (1 << 0) /* Chip reset */ | ||
161 | #define MAX3107_MODE2_FIFORST_BIT (1 << 1) /* FIFO reset */ | ||
162 | #define MAX3107_MODE2_RXTRIGINV_BIT (1 << 2) /* RX FIFO INT invert */ | ||
163 | #define MAX3107_MODE2_RXEMPTINV_BIT (1 << 3) /* RX FIFO empty INT invert */ | ||
164 | #define MAX3107_MODE2_SPCHR_BIT (1 << 4) /* Special chr detect enable */ | ||
165 | #define MAX3107_MODE2_LOOPBACK_BIT (1 << 5) /* Internal loopback enable */ | ||
166 | #define MAX3107_MODE2_MULTIDROP_BIT (1 << 6) /* 9-bit multidrop enable */ | ||
167 | #define MAX3107_MODE2_ECHOSUPR_BIT (1 << 7) /* ECHO suppression enable */ | ||
168 | |||
169 | /* LCR register bits */ | ||
170 | #define MAX3107_LCR_LENGTH0_BIT (1 << 0) /* Word length bit 0 */ | ||
171 | #define MAX3107_LCR_LENGTH1_BIT (1 << 1) /* Word length bit 1 | ||
172 | * | ||
173 | * Word length bits table: | ||
174 | * 00 -> 5 bit words | ||
175 | * 01 -> 6 bit words | ||
176 | * 10 -> 7 bit words | ||
177 | * 11 -> 8 bit words | ||
178 | */ | ||
179 | #define MAX3107_LCR_STOPLEN_BIT (1 << 2) /* STOP length bit | ||
180 | * | ||
181 | * STOP length bit table: | ||
182 | * 0 -> 1 stop bit | ||
183 | * 1 -> 1-1.5 stop bits if | ||
184 | * word length is 5, | ||
185 | * 2 stop bits otherwise | ||
186 | */ | ||
187 | #define MAX3107_LCR_PARITY_BIT (1 << 3) /* Parity bit enable */ | ||
188 | #define MAX3107_LCR_EVENPARITY_BIT (1 << 4) /* Even parity bit enable */ | ||
189 | #define MAX3107_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ | ||
190 | #define MAX3107_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ | ||
191 | #define MAX3107_LCR_RTS_BIT (1 << 7) /* RTS pin control */ | ||
192 | #define MAX3107_LCR_WORD_LEN_5 (0x0000) | ||
193 | #define MAX3107_LCR_WORD_LEN_6 (0x0001) | ||
194 | #define MAX3107_LCR_WORD_LEN_7 (0x0002) | ||
195 | #define MAX3107_LCR_WORD_LEN_8 (0x0003) | ||
196 | |||
197 | |||
198 | /* IRDA register bits */ | ||
199 | #define MAX3107_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ | ||
200 | #define MAX3107_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */ | ||
201 | #define MAX3107_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */ | ||
202 | #define MAX3107_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */ | ||
203 | #define MAX3107_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */ | ||
204 | #define MAX3107_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */ | ||
205 | #define MAX3107_IRDA_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
206 | #define MAX3107_IRDA_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
207 | |||
208 | /* Flow control trigger level register masks */ | ||
209 | #define MAX3107_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */ | ||
210 | #define MAX3107_FLOWLVL_RES_MASK (0x00f0) /* Flow control resume level */ | ||
211 | #define MAX3107_FLOWLVL_HALT(words) ((words/8) & 0x000f) | ||
212 | #define MAX3107_FLOWLVL_RES(words) (((words/8) & 0x000f) << 4) | ||
213 | |||
214 | /* FIFO interrupt trigger level register masks */ | ||
215 | #define MAX3107_FIFOTRIGLVL_TX_MASK (0x000f) /* TX FIFO trigger level */ | ||
216 | #define MAX3107_FIFOTRIGLVL_RX_MASK (0x00f0) /* RX FIFO trigger level */ | ||
217 | #define MAX3107_FIFOTRIGLVL_TX(words) ((words/8) & 0x000f) | ||
218 | #define MAX3107_FIFOTRIGLVL_RX(words) (((words/8) & 0x000f) << 4) | ||
219 | |||
220 | /* Flow control register bits */ | ||
221 | #define MAX3107_FLOWCTRL_AUTORTS_BIT (1 << 0) /* Auto RTS flow ctrl enable */ | ||
222 | #define MAX3107_FLOWCTRL_AUTOCTS_BIT (1 << 1) /* Auto CTS flow ctrl enable */ | ||
223 | #define MAX3107_FLOWCTRL_GPIADDR_BIT (1 << 2) /* Enables that GPIO inputs | ||
224 | * are used in conjunction with | ||
225 | * XOFF2 for definition of | ||
226 | * special character */ | ||
227 | #define MAX3107_FLOWCTRL_SWFLOWEN_BIT (1 << 3) /* Auto SW flow ctrl enable */ | ||
228 | #define MAX3107_FLOWCTRL_SWFLOW0_BIT (1 << 4) /* SWFLOW bit 0 */ | ||
229 | #define MAX3107_FLOWCTRL_SWFLOW1_BIT (1 << 5) /* SWFLOW bit 1 | ||
230 | * | ||
231 | * SWFLOW bits 1 & 0 table: | ||
232 | * 00 -> no transmitter flow | ||
233 | * control | ||
234 | * 01 -> receiver compares | ||
235 | * XON2 and XOFF2 | ||
236 | * and controls | ||
237 | * transmitter | ||
238 | * 10 -> receiver compares | ||
239 | * XON1 and XOFF1 | ||
240 | * and controls | ||
241 | * transmitter | ||
242 | * 11 -> receiver compares | ||
243 | * XON1, XON2, XOFF1 and | ||
244 | * XOFF2 and controls | ||
245 | * transmitter | ||
246 | */ | ||
247 | #define MAX3107_FLOWCTRL_SWFLOW2_BIT (1 << 6) /* SWFLOW bit 2 */ | ||
248 | #define MAX3107_FLOWCTRL_SWFLOW3_BIT (1 << 7) /* SWFLOW bit 3 | ||
249 | * | ||
250 | * SWFLOW bits 3 & 2 table: | ||
251 | * 00 -> no received flow | ||
252 | * control | ||
253 | * 01 -> transmitter generates | ||
254 | * XON2 and XOFF2 | ||
255 | * 10 -> transmitter generates | ||
256 | * XON1 and XOFF1 | ||
257 | * 11 -> transmitter generates | ||
258 | * XON1, XON2, XOFF1 and | ||
259 | * XOFF2 | ||
260 | */ | ||
261 | |||
262 | /* GPIO configuration register bits */ | ||
263 | #define MAX3107_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */ | ||
264 | #define MAX3107_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */ | ||
265 | #define MAX3107_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */ | ||
266 | #define MAX3107_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */ | ||
267 | #define MAX3107_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */ | ||
268 | #define MAX3107_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */ | ||
269 | #define MAX3107_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */ | ||
270 | #define MAX3107_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */ | ||
271 | |||
272 | /* GPIO DATA register bits */ | ||
273 | #define MAX3107_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */ | ||
274 | #define MAX3107_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */ | ||
275 | #define MAX3107_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */ | ||
276 | #define MAX3107_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */ | ||
277 | #define MAX3107_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */ | ||
278 | #define MAX3107_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */ | ||
279 | #define MAX3107_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */ | ||
280 | #define MAX3107_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */ | ||
281 | |||
282 | /* PLL configuration register masks */ | ||
283 | #define MAX3107_PLLCFG_PREDIV_MASK (0x003f) /* PLL predivision value */ | ||
284 | #define MAX3107_PLLCFG_PLLFACTOR_MASK (0x00c0) /* PLL multiplication factor */ | ||
285 | |||
286 | /* Baud rate generator configuration register masks and bits */ | ||
287 | #define MAX3107_BRGCFG_FRACT_MASK (0x000f) /* Fractional portion of | ||
288 | * Baud rate generator divisor | ||
289 | */ | ||
290 | #define MAX3107_BRGCFG_2XMODE_BIT (1 << 4) /* Double baud rate */ | ||
291 | #define MAX3107_BRGCFG_4XMODE_BIT (1 << 5) /* Quadruple baud rate */ | ||
292 | #define MAX3107_BRGCFG_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
293 | #define MAX3107_BRGCFG_UNDEF7_BIT (1 << 7) /* Undefined/not used */ | ||
294 | |||
295 | /* Clock source register bits */ | ||
296 | #define MAX3107_CLKSRC_INTOSC_BIT (1 << 0) /* Internal osc enable */ | ||
297 | #define MAX3107_CLKSRC_CRYST_BIT (1 << 1) /* Crystal osc enable */ | ||
298 | #define MAX3107_CLKSRC_PLL_BIT (1 << 2) /* PLL enable */ | ||
299 | #define MAX3107_CLKSRC_PLLBYP_BIT (1 << 3) /* PLL bypass */ | ||
300 | #define MAX3107_CLKSRC_EXTCLK_BIT (1 << 4) /* External clock enable */ | ||
301 | #define MAX3107_CLKSRC_UNDEF5_BIT (1 << 5) /* Undefined/not used */ | ||
302 | #define MAX3107_CLKSRC_UNDEF6_BIT (1 << 6) /* Undefined/not used */ | ||
303 | #define MAX3107_CLKSRC_CLK2RTS_BIT (1 << 7) /* Baud clk to RTS pin */ | ||
304 | |||
305 | |||
306 | /* HW definitions */ | ||
307 | #define MAX3107_RX_FIFO_SIZE 128 | ||
308 | #define MAX3107_TX_FIFO_SIZE 128 | ||
309 | #define MAX3107_REVID1 0x00a0 | ||
310 | #define MAX3107_REVID2 0x00a1 | ||
311 | |||
312 | |||
313 | /* Baud rate generator configuration values for external clock 13MHz */ | ||
314 | #define MAX3107_BRG13_B300 (0x0A9400 | 0x05) | ||
315 | #define MAX3107_BRG13_B600 (0x054A00 | 0x03) | ||
316 | #define MAX3107_BRG13_B1200 (0x02A500 | 0x01) | ||
317 | #define MAX3107_BRG13_B2400 (0x015200 | 0x09) | ||
318 | #define MAX3107_BRG13_B4800 (0x00A900 | 0x04) | ||
319 | #define MAX3107_BRG13_B9600 (0x005400 | 0x0A) | ||
320 | #define MAX3107_BRG13_B19200 (0x002A00 | 0x05) | ||
321 | #define MAX3107_BRG13_B38400 (0x001500 | 0x03) | ||
322 | #define MAX3107_BRG13_B57600 (0x000E00 | 0x02) | ||
323 | #define MAX3107_BRG13_B115200 (0x000700 | 0x01) | ||
324 | #define MAX3107_BRG13_B230400 (0x000300 | 0x08) | ||
325 | #define MAX3107_BRG13_B460800 (0x000100 | 0x0c) | ||
326 | #define MAX3107_BRG13_B921600 (0x000100 | 0x1c) | ||
327 | |||
328 | /* Baud rate generator configuration values for external clock 26MHz */ | ||
329 | #define MAX3107_BRG26_B300 (0x152800 | 0x0A) | ||
330 | #define MAX3107_BRG26_B600 (0x0A9400 | 0x05) | ||
331 | #define MAX3107_BRG26_B1200 (0x054A00 | 0x03) | ||
332 | #define MAX3107_BRG26_B2400 (0x02A500 | 0x01) | ||
333 | #define MAX3107_BRG26_B4800 (0x015200 | 0x09) | ||
334 | #define MAX3107_BRG26_B9600 (0x00A900 | 0x04) | ||
335 | #define MAX3107_BRG26_B19200 (0x005400 | 0x0A) | ||
336 | #define MAX3107_BRG26_B38400 (0x002A00 | 0x05) | ||
337 | #define MAX3107_BRG26_B57600 (0x001C00 | 0x03) | ||
338 | #define MAX3107_BRG26_B115200 (0x000E00 | 0x02) | ||
339 | #define MAX3107_BRG26_B230400 (0x000700 | 0x01) | ||
340 | #define MAX3107_BRG26_B460800 (0x000300 | 0x08) | ||
341 | #define MAX3107_BRG26_B921600 (0x000100 | 0x0C) | ||
342 | |||
343 | /* Baud rate generator configuration values for internal clock */ | ||
344 | #define MAX3107_BRG13_IB300 (0x008000 | 0x00) | ||
345 | #define MAX3107_BRG13_IB600 (0x004000 | 0x00) | ||
346 | #define MAX3107_BRG13_IB1200 (0x002000 | 0x00) | ||
347 | #define MAX3107_BRG13_IB2400 (0x001000 | 0x00) | ||
348 | #define MAX3107_BRG13_IB4800 (0x000800 | 0x00) | ||
349 | #define MAX3107_BRG13_IB9600 (0x000400 | 0x00) | ||
350 | #define MAX3107_BRG13_IB19200 (0x000200 | 0x00) | ||
351 | #define MAX3107_BRG13_IB38400 (0x000100 | 0x00) | ||
352 | #define MAX3107_BRG13_IB57600 (0x000000 | 0x0B) | ||
353 | #define MAX3107_BRG13_IB115200 (0x000000 | 0x05) | ||
354 | #define MAX3107_BRG13_IB230400 (0x000000 | 0x03) | ||
355 | #define MAX3107_BRG13_IB460800 (0x000000 | 0x00) | ||
356 | #define MAX3107_BRG13_IB921600 (0x000000 | 0x00) | ||
357 | |||
358 | |||
359 | struct baud_table { | ||
360 | int baud; | ||
361 | u32 new_brg; | ||
362 | }; | ||
363 | |||
364 | struct max3107_port { | ||
365 | /* UART port structure */ | ||
366 | struct uart_port port; | ||
367 | |||
368 | /* SPI device structure */ | ||
369 | struct spi_device *spi; | ||
370 | |||
371 | #if defined(CONFIG_GPIOLIB) | ||
372 | /* GPIO chip structure */ | ||
373 | struct gpio_chip chip; | ||
374 | #endif | ||
375 | |||
376 | /* Workqueue that does all the magic */ | ||
377 | struct workqueue_struct *workqueue; | ||
378 | struct work_struct work; | ||
379 | |||
380 | /* Lock for shared data */ | ||
381 | spinlock_t data_lock; | ||
382 | |||
383 | /* Device configuration */ | ||
384 | int ext_clk; /* 1 if external clock used */ | ||
385 | int loopback; /* Current loopback mode state */ | ||
386 | int baud; /* Current baud rate */ | ||
387 | |||
388 | /* State flags */ | ||
389 | int suspended; /* Indicates suspend mode */ | ||
390 | int tx_fifo_empty; /* Flag for TX FIFO state */ | ||
391 | int rx_enabled; /* Flag for receiver state */ | ||
392 | int tx_enabled; /* Flag for transmitter state */ | ||
393 | |||
394 | u16 irqen_reg; /* Current IRQ enable register value */ | ||
395 | /* Shared data */ | ||
396 | u16 mode1_reg; /* Current mode1 register value*/ | ||
397 | int mode1_commit; /* Flag for setting new mode1 register value */ | ||
398 | u16 lcr_reg; /* Current LCR register value */ | ||
399 | int lcr_commit; /* Flag for setting new LCR register value */ | ||
400 | u32 brg_cfg; /* Current Baud rate generator config */ | ||
401 | int brg_commit; /* Flag for setting new baud rate generator | ||
402 | * config | ||
403 | */ | ||
404 | struct baud_table *baud_tbl; | ||
405 | int handle_irq; /* Indicates that IRQ should be handled */ | ||
406 | |||
407 | /* Rx buffer and str*/ | ||
408 | u16 *rxbuf; | ||
409 | u8 *rxstr; | ||
410 | /* Tx buffer*/ | ||
411 | u16 *txbuf; | ||
412 | |||
413 | struct max3107_plat *pdata; /* Platform data */ | ||
414 | }; | ||
415 | |||
416 | /* Platform data structure */ | ||
417 | struct max3107_plat { | ||
418 | /* Loopback mode enable */ | ||
419 | int loopback; | ||
420 | /* External clock enable */ | ||
421 | int ext_clk; | ||
422 | /* Called during the register initialisation */ | ||
423 | void (*init)(struct max3107_port *s); | ||
424 | /* Called when the port is found and configured */ | ||
425 | int (*configure)(struct max3107_port *s); | ||
426 | /* HW suspend function */ | ||
427 | void (*hw_suspend) (struct max3107_port *s, int suspend); | ||
428 | /* Polling mode enable */ | ||
429 | int polled_mode; | ||
430 | /* Polling period if polling mode enabled */ | ||
431 | int poll_time; | ||
432 | }; | ||
433 | |||
434 | extern int max3107_rw(struct max3107_port *s, u8 *tx, u8 *rx, int len); | ||
435 | extern void max3107_hw_susp(struct max3107_port *s, int suspend); | ||
436 | extern int max3107_probe(struct spi_device *spi, struct max3107_plat *pdata); | ||
437 | extern int max3107_remove(struct spi_device *spi); | ||
438 | extern int max3107_suspend(struct spi_device *spi, pm_message_t state); | ||
439 | extern int max3107_resume(struct spi_device *spi); | ||
440 | |||
441 | #endif /* _LINUX_SERIAL_MAX3107_H */ | ||
diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c new file mode 100644 index 000000000000..2bc28a59d385 --- /dev/null +++ b/drivers/tty/serial/max310x.c | |||
@@ -0,0 +1,1260 @@ | |||
1 | /* | ||
2 | * Maxim (Dallas) MAX3107/8 serial driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
5 | * | ||
6 | * Based on max3100.c, by Christian Pellegrin <chripell@evolware.org> | ||
7 | * Based on max3110.c, by Feng Tang <feng.tang@intel.com> | ||
8 | * Based on max3107.c, by Aavamobile | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | /* TODO: MAX3109 support (Dual) */ | ||
17 | /* TODO: MAX14830 support (Quad) */ | ||
18 | |||
19 | #include <linux/module.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/serial_core.h> | ||
22 | #include <linux/serial.h> | ||
23 | #include <linux/tty.h> | ||
24 | #include <linux/tty_flip.h> | ||
25 | #include <linux/regmap.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/spi/spi.h> | ||
28 | #include <linux/platform_data/max310x.h> | ||
29 | |||
30 | #define MAX310X_MAJOR 204 | ||
31 | #define MAX310X_MINOR 209 | ||
32 | |||
33 | /* MAX310X register definitions */ | ||
34 | #define MAX310X_RHR_REG (0x00) /* RX FIFO */ | ||
35 | #define MAX310X_THR_REG (0x00) /* TX FIFO */ | ||
36 | #define MAX310X_IRQEN_REG (0x01) /* IRQ enable */ | ||
37 | #define MAX310X_IRQSTS_REG (0x02) /* IRQ status */ | ||
38 | #define MAX310X_LSR_IRQEN_REG (0x03) /* LSR IRQ enable */ | ||
39 | #define MAX310X_LSR_IRQSTS_REG (0x04) /* LSR IRQ status */ | ||
40 | #define MAX310X_SPCHR_IRQEN_REG (0x05) /* Special char IRQ enable */ | ||
41 | #define MAX310X_SPCHR_IRQSTS_REG (0x06) /* Special char IRQ status */ | ||
42 | #define MAX310X_STS_IRQEN_REG (0x07) /* Status IRQ enable */ | ||
43 | #define MAX310X_STS_IRQSTS_REG (0x08) /* Status IRQ status */ | ||
44 | #define MAX310X_MODE1_REG (0x09) /* MODE1 */ | ||
45 | #define MAX310X_MODE2_REG (0x0a) /* MODE2 */ | ||
46 | #define MAX310X_LCR_REG (0x0b) /* LCR */ | ||
47 | #define MAX310X_RXTO_REG (0x0c) /* RX timeout */ | ||
48 | #define MAX310X_HDPIXDELAY_REG (0x0d) /* Auto transceiver delays */ | ||
49 | #define MAX310X_IRDA_REG (0x0e) /* IRDA settings */ | ||
50 | #define MAX310X_FLOWLVL_REG (0x0f) /* Flow control levels */ | ||
51 | #define MAX310X_FIFOTRIGLVL_REG (0x10) /* FIFO IRQ trigger levels */ | ||
52 | #define MAX310X_TXFIFOLVL_REG (0x11) /* TX FIFO level */ | ||
53 | #define MAX310X_RXFIFOLVL_REG (0x12) /* RX FIFO level */ | ||
54 | #define MAX310X_FLOWCTRL_REG (0x13) /* Flow control */ | ||
55 | #define MAX310X_XON1_REG (0x14) /* XON1 character */ | ||
56 | #define MAX310X_XON2_REG (0x15) /* XON2 character */ | ||
57 | #define MAX310X_XOFF1_REG (0x16) /* XOFF1 character */ | ||
58 | #define MAX310X_XOFF2_REG (0x17) /* XOFF2 character */ | ||
59 | #define MAX310X_GPIOCFG_REG (0x18) /* GPIO config */ | ||
60 | #define MAX310X_GPIODATA_REG (0x19) /* GPIO data */ | ||
61 | #define MAX310X_PLLCFG_REG (0x1a) /* PLL config */ | ||
62 | #define MAX310X_BRGCFG_REG (0x1b) /* Baud rate generator conf */ | ||
63 | #define MAX310X_BRGDIVLSB_REG (0x1c) /* Baud rate divisor LSB */ | ||
64 | #define MAX310X_BRGDIVMSB_REG (0x1d) /* Baud rate divisor MSB */ | ||
65 | #define MAX310X_CLKSRC_REG (0x1e) /* Clock source */ | ||
66 | /* Only present in MAX3107 */ | ||
67 | #define MAX3107_REVID_REG (0x1f) /* Revision identification */ | ||
68 | |||
69 | /* IRQ register bits */ | ||
70 | #define MAX310X_IRQ_LSR_BIT (1 << 0) /* LSR interrupt */ | ||
71 | #define MAX310X_IRQ_SPCHR_BIT (1 << 1) /* Special char interrupt */ | ||
72 | #define MAX310X_IRQ_STS_BIT (1 << 2) /* Status interrupt */ | ||
73 | #define MAX310X_IRQ_RXFIFO_BIT (1 << 3) /* RX FIFO interrupt */ | ||
74 | #define MAX310X_IRQ_TXFIFO_BIT (1 << 4) /* TX FIFO interrupt */ | ||
75 | #define MAX310X_IRQ_TXEMPTY_BIT (1 << 5) /* TX FIFO empty interrupt */ | ||
76 | #define MAX310X_IRQ_RXEMPTY_BIT (1 << 6) /* RX FIFO empty interrupt */ | ||
77 | #define MAX310X_IRQ_CTS_BIT (1 << 7) /* CTS interrupt */ | ||
78 | |||
79 | /* LSR register bits */ | ||
80 | #define MAX310X_LSR_RXTO_BIT (1 << 0) /* RX timeout */ | ||
81 | #define MAX310X_LSR_RXOVR_BIT (1 << 1) /* RX overrun */ | ||
82 | #define MAX310X_LSR_RXPAR_BIT (1 << 2) /* RX parity error */ | ||
83 | #define MAX310X_LSR_FRERR_BIT (1 << 3) /* Frame error */ | ||
84 | #define MAX310X_LSR_RXBRK_BIT (1 << 4) /* RX break */ | ||
85 | #define MAX310X_LSR_RXNOISE_BIT (1 << 5) /* RX noise */ | ||
86 | #define MAX310X_LSR_CTS_BIT (1 << 7) /* CTS pin state */ | ||
87 | |||
88 | /* Special character register bits */ | ||
89 | #define MAX310X_SPCHR_XON1_BIT (1 << 0) /* XON1 character */ | ||
90 | #define MAX310X_SPCHR_XON2_BIT (1 << 1) /* XON2 character */ | ||
91 | #define MAX310X_SPCHR_XOFF1_BIT (1 << 2) /* XOFF1 character */ | ||
92 | #define MAX310X_SPCHR_XOFF2_BIT (1 << 3) /* XOFF2 character */ | ||
93 | #define MAX310X_SPCHR_BREAK_BIT (1 << 4) /* RX break */ | ||
94 | #define MAX310X_SPCHR_MULTIDROP_BIT (1 << 5) /* 9-bit multidrop addr char */ | ||
95 | |||
96 | /* Status register bits */ | ||
97 | #define MAX310X_STS_GPIO0_BIT (1 << 0) /* GPIO 0 interrupt */ | ||
98 | #define MAX310X_STS_GPIO1_BIT (1 << 1) /* GPIO 1 interrupt */ | ||
99 | #define MAX310X_STS_GPIO2_BIT (1 << 2) /* GPIO 2 interrupt */ | ||
100 | #define MAX310X_STS_GPIO3_BIT (1 << 3) /* GPIO 3 interrupt */ | ||
101 | #define MAX310X_STS_CLKREADY_BIT (1 << 5) /* Clock ready */ | ||
102 | #define MAX310X_STS_SLEEP_BIT (1 << 6) /* Sleep interrupt */ | ||
103 | |||
104 | /* MODE1 register bits */ | ||
105 | #define MAX310X_MODE1_RXDIS_BIT (1 << 0) /* RX disable */ | ||
106 | #define MAX310X_MODE1_TXDIS_BIT (1 << 1) /* TX disable */ | ||
107 | #define MAX310X_MODE1_TXHIZ_BIT (1 << 2) /* TX pin three-state */ | ||
108 | #define MAX310X_MODE1_RTSHIZ_BIT (1 << 3) /* RTS pin three-state */ | ||
109 | #define MAX310X_MODE1_TRNSCVCTRL_BIT (1 << 4) /* Transceiver ctrl enable */ | ||
110 | #define MAX310X_MODE1_FORCESLEEP_BIT (1 << 5) /* Force sleep mode */ | ||
111 | #define MAX310X_MODE1_AUTOSLEEP_BIT (1 << 6) /* Auto sleep enable */ | ||
112 | #define MAX310X_MODE1_IRQSEL_BIT (1 << 7) /* IRQ pin enable */ | ||
113 | |||
114 | /* MODE2 register bits */ | ||
115 | #define MAX310X_MODE2_RST_BIT (1 << 0) /* Chip reset */ | ||
116 | #define MAX310X_MODE2_FIFORST_BIT (1 << 1) /* FIFO reset */ | ||
117 | #define MAX310X_MODE2_RXTRIGINV_BIT (1 << 2) /* RX FIFO INT invert */ | ||
118 | #define MAX310X_MODE2_RXEMPTINV_BIT (1 << 3) /* RX FIFO empty INT invert */ | ||
119 | #define MAX310X_MODE2_SPCHR_BIT (1 << 4) /* Special chr detect enable */ | ||
120 | #define MAX310X_MODE2_LOOPBACK_BIT (1 << 5) /* Internal loopback enable */ | ||
121 | #define MAX310X_MODE2_MULTIDROP_BIT (1 << 6) /* 9-bit multidrop enable */ | ||
122 | #define MAX310X_MODE2_ECHOSUPR_BIT (1 << 7) /* ECHO suppression enable */ | ||
123 | |||
124 | /* LCR register bits */ | ||
125 | #define MAX310X_LCR_LENGTH0_BIT (1 << 0) /* Word length bit 0 */ | ||
126 | #define MAX310X_LCR_LENGTH1_BIT (1 << 1) /* Word length bit 1 | ||
127 | * | ||
128 | * Word length bits table: | ||
129 | * 00 -> 5 bit words | ||
130 | * 01 -> 6 bit words | ||
131 | * 10 -> 7 bit words | ||
132 | * 11 -> 8 bit words | ||
133 | */ | ||
134 | #define MAX310X_LCR_STOPLEN_BIT (1 << 2) /* STOP length bit | ||
135 | * | ||
136 | * STOP length bit table: | ||
137 | * 0 -> 1 stop bit | ||
138 | * 1 -> 1-1.5 stop bits if | ||
139 | * word length is 5, | ||
140 | * 2 stop bits otherwise | ||
141 | */ | ||
142 | #define MAX310X_LCR_PARITY_BIT (1 << 3) /* Parity bit enable */ | ||
143 | #define MAX310X_LCR_EVENPARITY_BIT (1 << 4) /* Even parity bit enable */ | ||
144 | #define MAX310X_LCR_FORCEPARITY_BIT (1 << 5) /* 9-bit multidrop parity */ | ||
145 | #define MAX310X_LCR_TXBREAK_BIT (1 << 6) /* TX break enable */ | ||
146 | #define MAX310X_LCR_RTS_BIT (1 << 7) /* RTS pin control */ | ||
147 | #define MAX310X_LCR_WORD_LEN_5 (0x00) | ||
148 | #define MAX310X_LCR_WORD_LEN_6 (0x01) | ||
149 | #define MAX310X_LCR_WORD_LEN_7 (0x02) | ||
150 | #define MAX310X_LCR_WORD_LEN_8 (0x03) | ||
151 | |||
152 | /* IRDA register bits */ | ||
153 | #define MAX310X_IRDA_IRDAEN_BIT (1 << 0) /* IRDA mode enable */ | ||
154 | #define MAX310X_IRDA_SIR_BIT (1 << 1) /* SIR mode enable */ | ||
155 | #define MAX310X_IRDA_SHORTIR_BIT (1 << 2) /* Short SIR mode enable */ | ||
156 | #define MAX310X_IRDA_MIR_BIT (1 << 3) /* MIR mode enable */ | ||
157 | #define MAX310X_IRDA_RXINV_BIT (1 << 4) /* RX logic inversion enable */ | ||
158 | #define MAX310X_IRDA_TXINV_BIT (1 << 5) /* TX logic inversion enable */ | ||
159 | |||
160 | /* Flow control trigger level register masks */ | ||
161 | #define MAX310X_FLOWLVL_HALT_MASK (0x000f) /* Flow control halt level */ | ||
162 | #define MAX310X_FLOWLVL_RES_MASK (0x00f0) /* Flow control resume level */ | ||
163 | #define MAX310X_FLOWLVL_HALT(words) ((words / 8) & 0x0f) | ||
164 | #define MAX310X_FLOWLVL_RES(words) (((words / 8) & 0x0f) << 4) | ||
165 | |||
166 | /* FIFO interrupt trigger level register masks */ | ||
167 | #define MAX310X_FIFOTRIGLVL_TX_MASK (0x0f) /* TX FIFO trigger level */ | ||
168 | #define MAX310X_FIFOTRIGLVL_RX_MASK (0xf0) /* RX FIFO trigger level */ | ||
169 | #define MAX310X_FIFOTRIGLVL_TX(words) ((words / 8) & 0x0f) | ||
170 | #define MAX310X_FIFOTRIGLVL_RX(words) (((words / 8) & 0x0f) << 4) | ||
171 | |||
172 | /* Flow control register bits */ | ||
173 | #define MAX310X_FLOWCTRL_AUTORTS_BIT (1 << 0) /* Auto RTS flow ctrl enable */ | ||
174 | #define MAX310X_FLOWCTRL_AUTOCTS_BIT (1 << 1) /* Auto CTS flow ctrl enable */ | ||
175 | #define MAX310X_FLOWCTRL_GPIADDR_BIT (1 << 2) /* Enables that GPIO inputs | ||
176 | * are used in conjunction with | ||
177 | * XOFF2 for definition of | ||
178 | * special character */ | ||
179 | #define MAX310X_FLOWCTRL_SWFLOWEN_BIT (1 << 3) /* Auto SW flow ctrl enable */ | ||
180 | #define MAX310X_FLOWCTRL_SWFLOW0_BIT (1 << 4) /* SWFLOW bit 0 */ | ||
181 | #define MAX310X_FLOWCTRL_SWFLOW1_BIT (1 << 5) /* SWFLOW bit 1 | ||
182 | * | ||
183 | * SWFLOW bits 1 & 0 table: | ||
184 | * 00 -> no transmitter flow | ||
185 | * control | ||
186 | * 01 -> receiver compares | ||
187 | * XON2 and XOFF2 | ||
188 | * and controls | ||
189 | * transmitter | ||
190 | * 10 -> receiver compares | ||
191 | * XON1 and XOFF1 | ||
192 | * and controls | ||
193 | * transmitter | ||
194 | * 11 -> receiver compares | ||
195 | * XON1, XON2, XOFF1 and | ||
196 | * XOFF2 and controls | ||
197 | * transmitter | ||
198 | */ | ||
199 | #define MAX310X_FLOWCTRL_SWFLOW2_BIT (1 << 6) /* SWFLOW bit 2 */ | ||
200 | #define MAX310X_FLOWCTRL_SWFLOW3_BIT (1 << 7) /* SWFLOW bit 3 | ||
201 | * | ||
202 | * SWFLOW bits 3 & 2 table: | ||
203 | * 00 -> no received flow | ||
204 | * control | ||
205 | * 01 -> transmitter generates | ||
206 | * XON2 and XOFF2 | ||
207 | * 10 -> transmitter generates | ||
208 | * XON1 and XOFF1 | ||
209 | * 11 -> transmitter generates | ||
210 | * XON1, XON2, XOFF1 and | ||
211 | * XOFF2 | ||
212 | */ | ||
213 | |||
214 | /* GPIO configuration register bits */ | ||
215 | #define MAX310X_GPIOCFG_GP0OUT_BIT (1 << 0) /* GPIO 0 output enable */ | ||
216 | #define MAX310X_GPIOCFG_GP1OUT_BIT (1 << 1) /* GPIO 1 output enable */ | ||
217 | #define MAX310X_GPIOCFG_GP2OUT_BIT (1 << 2) /* GPIO 2 output enable */ | ||
218 | #define MAX310X_GPIOCFG_GP3OUT_BIT (1 << 3) /* GPIO 3 output enable */ | ||
219 | #define MAX310X_GPIOCFG_GP0OD_BIT (1 << 4) /* GPIO 0 open-drain enable */ | ||
220 | #define MAX310X_GPIOCFG_GP1OD_BIT (1 << 5) /* GPIO 1 open-drain enable */ | ||
221 | #define MAX310X_GPIOCFG_GP2OD_BIT (1 << 6) /* GPIO 2 open-drain enable */ | ||
222 | #define MAX310X_GPIOCFG_GP3OD_BIT (1 << 7) /* GPIO 3 open-drain enable */ | ||
223 | |||
224 | /* GPIO DATA register bits */ | ||
225 | #define MAX310X_GPIODATA_GP0OUT_BIT (1 << 0) /* GPIO 0 output value */ | ||
226 | #define MAX310X_GPIODATA_GP1OUT_BIT (1 << 1) /* GPIO 1 output value */ | ||
227 | #define MAX310X_GPIODATA_GP2OUT_BIT (1 << 2) /* GPIO 2 output value */ | ||
228 | #define MAX310X_GPIODATA_GP3OUT_BIT (1 << 3) /* GPIO 3 output value */ | ||
229 | #define MAX310X_GPIODATA_GP0IN_BIT (1 << 4) /* GPIO 0 input value */ | ||
230 | #define MAX310X_GPIODATA_GP1IN_BIT (1 << 5) /* GPIO 1 input value */ | ||
231 | #define MAX310X_GPIODATA_GP2IN_BIT (1 << 6) /* GPIO 2 input value */ | ||
232 | #define MAX310X_GPIODATA_GP3IN_BIT (1 << 7) /* GPIO 3 input value */ | ||
233 | |||
234 | /* PLL configuration register masks */ | ||
235 | #define MAX310X_PLLCFG_PREDIV_MASK (0x3f) /* PLL predivision value */ | ||
236 | #define MAX310X_PLLCFG_PLLFACTOR_MASK (0xc0) /* PLL multiplication factor */ | ||
237 | |||
238 | /* Baud rate generator configuration register bits */ | ||
239 | #define MAX310X_BRGCFG_2XMODE_BIT (1 << 4) /* Double baud rate */ | ||
240 | #define MAX310X_BRGCFG_4XMODE_BIT (1 << 5) /* Quadruple baud rate */ | ||
241 | |||
242 | /* Clock source register bits */ | ||
243 | #define MAX310X_CLKSRC_CRYST_BIT (1 << 1) /* Crystal osc enable */ | ||
244 | #define MAX310X_CLKSRC_PLL_BIT (1 << 2) /* PLL enable */ | ||
245 | #define MAX310X_CLKSRC_PLLBYP_BIT (1 << 3) /* PLL bypass */ | ||
246 | #define MAX310X_CLKSRC_EXTCLK_BIT (1 << 4) /* External clock enable */ | ||
247 | #define MAX310X_CLKSRC_CLK2RTS_BIT (1 << 7) /* Baud clk to RTS pin */ | ||
248 | |||
249 | /* Misc definitions */ | ||
250 | #define MAX310X_FIFO_SIZE (128) | ||
251 | |||
252 | /* MAX3107 specific */ | ||
253 | #define MAX3107_REV_ID (0xa0) | ||
254 | #define MAX3107_REV_MASK (0xfe) | ||
255 | |||
256 | /* IRQ status bits definitions */ | ||
257 | #define MAX310X_IRQ_TX (MAX310X_IRQ_TXFIFO_BIT | \ | ||
258 | MAX310X_IRQ_TXEMPTY_BIT) | ||
259 | #define MAX310X_IRQ_RX (MAX310X_IRQ_RXFIFO_BIT | \ | ||
260 | MAX310X_IRQ_RXEMPTY_BIT) | ||
261 | |||
262 | /* Supported chip types */ | ||
263 | enum { | ||
264 | MAX310X_TYPE_MAX3107 = 3107, | ||
265 | MAX310X_TYPE_MAX3108 = 3108, | ||
266 | }; | ||
267 | |||
268 | struct max310x_port { | ||
269 | struct uart_driver uart; | ||
270 | struct uart_port port; | ||
271 | |||
272 | const char *name; | ||
273 | int uartclk; | ||
274 | |||
275 | unsigned int nr_gpio; | ||
276 | #ifdef CONFIG_GPIOLIB | ||
277 | struct gpio_chip gpio; | ||
278 | #endif | ||
279 | |||
280 | struct regmap *regmap; | ||
281 | struct regmap_config regcfg; | ||
282 | |||
283 | struct workqueue_struct *wq; | ||
284 | struct work_struct tx_work; | ||
285 | |||
286 | struct mutex max310x_mutex; | ||
287 | |||
288 | struct max310x_pdata *pdata; | ||
289 | }; | ||
290 | |||
291 | static bool max3107_8_reg_writeable(struct device *dev, unsigned int reg) | ||
292 | { | ||
293 | switch (reg) { | ||
294 | case MAX310X_IRQSTS_REG: | ||
295 | case MAX310X_LSR_IRQSTS_REG: | ||
296 | case MAX310X_SPCHR_IRQSTS_REG: | ||
297 | case MAX310X_STS_IRQSTS_REG: | ||
298 | case MAX310X_TXFIFOLVL_REG: | ||
299 | case MAX310X_RXFIFOLVL_REG: | ||
300 | case MAX3107_REVID_REG: /* Only available on MAX3107 */ | ||
301 | return false; | ||
302 | default: | ||
303 | break; | ||
304 | } | ||
305 | |||
306 | return true; | ||
307 | } | ||
308 | |||
309 | static bool max310x_reg_volatile(struct device *dev, unsigned int reg) | ||
310 | { | ||
311 | switch (reg) { | ||
312 | case MAX310X_RHR_REG: | ||
313 | case MAX310X_IRQSTS_REG: | ||
314 | case MAX310X_LSR_IRQSTS_REG: | ||
315 | case MAX310X_SPCHR_IRQSTS_REG: | ||
316 | case MAX310X_STS_IRQSTS_REG: | ||
317 | case MAX310X_TXFIFOLVL_REG: | ||
318 | case MAX310X_RXFIFOLVL_REG: | ||
319 | case MAX310X_GPIODATA_REG: | ||
320 | return true; | ||
321 | default: | ||
322 | break; | ||
323 | } | ||
324 | |||
325 | return false; | ||
326 | } | ||
327 | |||
328 | static bool max310x_reg_precious(struct device *dev, unsigned int reg) | ||
329 | { | ||
330 | switch (reg) { | ||
331 | case MAX310X_RHR_REG: | ||
332 | case MAX310X_IRQSTS_REG: | ||
333 | case MAX310X_SPCHR_IRQSTS_REG: | ||
334 | case MAX310X_STS_IRQSTS_REG: | ||
335 | return true; | ||
336 | default: | ||
337 | break; | ||
338 | } | ||
339 | |||
340 | return false; | ||
341 | } | ||
342 | |||
343 | static void max310x_set_baud(struct max310x_port *s, int baud) | ||
344 | { | ||
345 | unsigned int mode = 0, div = s->uartclk / baud; | ||
346 | |||
347 | if (!(div / 16)) { | ||
348 | /* Mode x2 */ | ||
349 | mode = MAX310X_BRGCFG_2XMODE_BIT; | ||
350 | div = (s->uartclk * 2) / baud; | ||
351 | } | ||
352 | |||
353 | if (!(div / 16)) { | ||
354 | /* Mode x4 */ | ||
355 | mode = MAX310X_BRGCFG_4XMODE_BIT; | ||
356 | div = (s->uartclk * 4) / baud; | ||
357 | } | ||
358 | |||
359 | regmap_write(s->regmap, MAX310X_BRGDIVMSB_REG, | ||
360 | ((div / 16) >> 8) & 0xff); | ||
361 | regmap_write(s->regmap, MAX310X_BRGDIVLSB_REG, (div / 16) & 0xff); | ||
362 | regmap_write(s->regmap, MAX310X_BRGCFG_REG, (div % 16) | mode); | ||
363 | } | ||
364 | |||
365 | static void max310x_wait_pll(struct max310x_port *s) | ||
366 | { | ||
367 | int tryes = 1000; | ||
368 | |||
369 | /* Wait for PLL only if crystal is used */ | ||
370 | if (!(s->pdata->driver_flags & MAX310X_EXT_CLK)) { | ||
371 | unsigned int sts = 0; | ||
372 | |||
373 | while (tryes--) { | ||
374 | regmap_read(s->regmap, MAX310X_STS_IRQSTS_REG, &sts); | ||
375 | if (sts & MAX310X_STS_CLKREADY_BIT) | ||
376 | break; | ||
377 | } | ||
378 | } | ||
379 | } | ||
380 | |||
381 | static int __devinit max310x_update_best_err(unsigned long f, long *besterr) | ||
382 | { | ||
383 | /* Use baudrate 115200 for calculate error */ | ||
384 | long err = f % (115200 * 16); | ||
385 | |||
386 | if ((*besterr < 0) || (*besterr > err)) { | ||
387 | *besterr = err; | ||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | return 1; | ||
392 | } | ||
393 | |||
394 | static int __devinit max310x_set_ref_clk(struct max310x_port *s) | ||
395 | { | ||
396 | unsigned int div, clksrc, pllcfg = 0; | ||
397 | long besterr = -1; | ||
398 | unsigned long fdiv, fmul, bestfreq = s->pdata->frequency; | ||
399 | |||
400 | /* First, update error without PLL */ | ||
401 | max310x_update_best_err(s->pdata->frequency, &besterr); | ||
402 | |||
403 | /* Try all possible PLL dividers */ | ||
404 | for (div = 1; (div <= 63) && besterr; div++) { | ||
405 | fdiv = DIV_ROUND_CLOSEST(s->pdata->frequency, div); | ||
406 | |||
407 | /* Try multiplier 6 */ | ||
408 | fmul = fdiv * 6; | ||
409 | if ((fdiv >= 500000) && (fdiv <= 800000)) | ||
410 | if (!max310x_update_best_err(fmul, &besterr)) { | ||
411 | pllcfg = (0 << 6) | div; | ||
412 | bestfreq = fmul; | ||
413 | } | ||
414 | /* Try multiplier 48 */ | ||
415 | fmul = fdiv * 48; | ||
416 | if ((fdiv >= 850000) && (fdiv <= 1200000)) | ||
417 | if (!max310x_update_best_err(fmul, &besterr)) { | ||
418 | pllcfg = (1 << 6) | div; | ||
419 | bestfreq = fmul; | ||
420 | } | ||
421 | /* Try multiplier 96 */ | ||
422 | fmul = fdiv * 96; | ||
423 | if ((fdiv >= 425000) && (fdiv <= 1000000)) | ||
424 | if (!max310x_update_best_err(fmul, &besterr)) { | ||
425 | pllcfg = (2 << 6) | div; | ||
426 | bestfreq = fmul; | ||
427 | } | ||
428 | /* Try multiplier 144 */ | ||
429 | fmul = fdiv * 144; | ||
430 | if ((fdiv >= 390000) && (fdiv <= 667000)) | ||
431 | if (!max310x_update_best_err(fmul, &besterr)) { | ||
432 | pllcfg = (3 << 6) | div; | ||
433 | bestfreq = fmul; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | /* Configure clock source */ | ||
438 | if (s->pdata->driver_flags & MAX310X_EXT_CLK) | ||
439 | clksrc = MAX310X_CLKSRC_EXTCLK_BIT; | ||
440 | else | ||
441 | clksrc = MAX310X_CLKSRC_CRYST_BIT; | ||
442 | |||
443 | /* Configure PLL */ | ||
444 | if (pllcfg) { | ||
445 | clksrc |= MAX310X_CLKSRC_PLL_BIT; | ||
446 | regmap_write(s->regmap, MAX310X_PLLCFG_REG, pllcfg); | ||
447 | } else | ||
448 | clksrc |= MAX310X_CLKSRC_PLLBYP_BIT; | ||
449 | |||
450 | regmap_write(s->regmap, MAX310X_CLKSRC_REG, clksrc); | ||
451 | |||
452 | if (pllcfg) | ||
453 | max310x_wait_pll(s); | ||
454 | |||
455 | dev_dbg(s->port.dev, "Reference clock set to %lu Hz\n", bestfreq); | ||
456 | |||
457 | return (int)bestfreq; | ||
458 | } | ||
459 | |||
460 | static void max310x_handle_rx(struct max310x_port *s, unsigned int rxlen) | ||
461 | { | ||
462 | unsigned int sts = 0, ch = 0, flag; | ||
463 | struct tty_struct *tty = tty_port_tty_get(&s->port.state->port); | ||
464 | |||
465 | if (!tty) | ||
466 | return; | ||
467 | |||
468 | if (unlikely(rxlen >= MAX310X_FIFO_SIZE)) { | ||
469 | dev_warn(s->port.dev, "Possible RX FIFO overrun %d\n", rxlen); | ||
470 | /* Ensure sanity of RX level */ | ||
471 | rxlen = MAX310X_FIFO_SIZE; | ||
472 | } | ||
473 | |||
474 | dev_dbg(s->port.dev, "RX Len = %u\n", rxlen); | ||
475 | |||
476 | while (rxlen--) { | ||
477 | regmap_read(s->regmap, MAX310X_RHR_REG, &ch); | ||
478 | regmap_read(s->regmap, MAX310X_LSR_IRQSTS_REG, &sts); | ||
479 | |||
480 | sts &= MAX310X_LSR_RXPAR_BIT | MAX310X_LSR_FRERR_BIT | | ||
481 | MAX310X_LSR_RXOVR_BIT | MAX310X_LSR_RXBRK_BIT; | ||
482 | |||
483 | s->port.icount.rx++; | ||
484 | flag = TTY_NORMAL; | ||
485 | |||
486 | if (unlikely(sts)) { | ||
487 | if (sts & MAX310X_LSR_RXBRK_BIT) { | ||
488 | s->port.icount.brk++; | ||
489 | if (uart_handle_break(&s->port)) | ||
490 | continue; | ||
491 | } else if (sts & MAX310X_LSR_RXPAR_BIT) | ||
492 | s->port.icount.parity++; | ||
493 | else if (sts & MAX310X_LSR_FRERR_BIT) | ||
494 | s->port.icount.frame++; | ||
495 | else if (sts & MAX310X_LSR_RXOVR_BIT) | ||
496 | s->port.icount.overrun++; | ||
497 | |||
498 | sts &= s->port.read_status_mask; | ||
499 | if (sts & MAX310X_LSR_RXBRK_BIT) | ||
500 | flag = TTY_BREAK; | ||
501 | else if (sts & MAX310X_LSR_RXPAR_BIT) | ||
502 | flag = TTY_PARITY; | ||
503 | else if (sts & MAX310X_LSR_FRERR_BIT) | ||
504 | flag = TTY_FRAME; | ||
505 | else if (sts & MAX310X_LSR_RXOVR_BIT) | ||
506 | flag = TTY_OVERRUN; | ||
507 | } | ||
508 | |||
509 | if (uart_handle_sysrq_char(s->port, ch)) | ||
510 | continue; | ||
511 | |||
512 | if (sts & s->port.ignore_status_mask) | ||
513 | continue; | ||
514 | |||
515 | uart_insert_char(&s->port, sts, MAX310X_LSR_RXOVR_BIT, | ||
516 | ch, flag); | ||
517 | } | ||
518 | |||
519 | tty_flip_buffer_push(tty); | ||
520 | |||
521 | tty_kref_put(tty); | ||
522 | } | ||
523 | |||
524 | static void max310x_handle_tx(struct max310x_port *s) | ||
525 | { | ||
526 | struct circ_buf *xmit = &s->port.state->xmit; | ||
527 | unsigned int txlen = 0, to_send; | ||
528 | |||
529 | if (unlikely(s->port.x_char)) { | ||
530 | regmap_write(s->regmap, MAX310X_THR_REG, s->port.x_char); | ||
531 | s->port.icount.tx++; | ||
532 | s->port.x_char = 0; | ||
533 | return; | ||
534 | } | ||
535 | |||
536 | if (uart_circ_empty(xmit) || uart_tx_stopped(&s->port)) | ||
537 | return; | ||
538 | |||
539 | /* Get length of data pending in circular buffer */ | ||
540 | to_send = uart_circ_chars_pending(xmit); | ||
541 | if (likely(to_send)) { | ||
542 | /* Limit to size of TX FIFO */ | ||
543 | regmap_read(s->regmap, MAX310X_TXFIFOLVL_REG, &txlen); | ||
544 | txlen = MAX310X_FIFO_SIZE - txlen; | ||
545 | to_send = (to_send > txlen) ? txlen : to_send; | ||
546 | |||
547 | dev_dbg(s->port.dev, "TX Len = %u\n", to_send); | ||
548 | |||
549 | /* Add data to send */ | ||
550 | s->port.icount.tx += to_send; | ||
551 | while (to_send--) { | ||
552 | regmap_write(s->regmap, MAX310X_THR_REG, | ||
553 | xmit->buf[xmit->tail]); | ||
554 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
555 | }; | ||
556 | } | ||
557 | |||
558 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
559 | uart_write_wakeup(&s->port); | ||
560 | } | ||
561 | |||
562 | static irqreturn_t max310x_ist(int irq, void *dev_id) | ||
563 | { | ||
564 | struct max310x_port *s = (struct max310x_port *)dev_id; | ||
565 | unsigned int ists = 0, lsr = 0, rxlen = 0; | ||
566 | |||
567 | mutex_lock(&s->max310x_mutex); | ||
568 | |||
569 | for (;;) { | ||
570 | /* Read IRQ status & RX FIFO level */ | ||
571 | regmap_read(s->regmap, MAX310X_IRQSTS_REG, &ists); | ||
572 | regmap_read(s->regmap, MAX310X_LSR_IRQSTS_REG, &lsr); | ||
573 | regmap_read(s->regmap, MAX310X_RXFIFOLVL_REG, &rxlen); | ||
574 | if (!ists && !(lsr & MAX310X_LSR_RXTO_BIT) && !rxlen) | ||
575 | break; | ||
576 | |||
577 | dev_dbg(s->port.dev, "IRQ status: 0x%02x\n", ists); | ||
578 | |||
579 | if (rxlen) | ||
580 | max310x_handle_rx(s, rxlen); | ||
581 | if (ists & MAX310X_IRQ_TX) | ||
582 | max310x_handle_tx(s); | ||
583 | if (ists & MAX310X_IRQ_CTS_BIT) | ||
584 | uart_handle_cts_change(&s->port, | ||
585 | !!(lsr & MAX310X_LSR_CTS_BIT)); | ||
586 | } | ||
587 | |||
588 | mutex_unlock(&s->max310x_mutex); | ||
589 | |||
590 | return IRQ_HANDLED; | ||
591 | } | ||
592 | |||
593 | static void max310x_wq_proc(struct work_struct *ws) | ||
594 | { | ||
595 | struct max310x_port *s = container_of(ws, struct max310x_port, tx_work); | ||
596 | |||
597 | mutex_lock(&s->max310x_mutex); | ||
598 | max310x_handle_tx(s); | ||
599 | mutex_unlock(&s->max310x_mutex); | ||
600 | } | ||
601 | |||
602 | static void max310x_start_tx(struct uart_port *port) | ||
603 | { | ||
604 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
605 | |||
606 | queue_work(s->wq, &s->tx_work); | ||
607 | } | ||
608 | |||
609 | static void max310x_stop_tx(struct uart_port *port) | ||
610 | { | ||
611 | /* Do nothing */ | ||
612 | } | ||
613 | |||
614 | static void max310x_stop_rx(struct uart_port *port) | ||
615 | { | ||
616 | /* Do nothing */ | ||
617 | } | ||
618 | |||
619 | static unsigned int max310x_tx_empty(struct uart_port *port) | ||
620 | { | ||
621 | unsigned int val = 0; | ||
622 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
623 | |||
624 | mutex_lock(&s->max310x_mutex); | ||
625 | regmap_read(s->regmap, MAX310X_TXFIFOLVL_REG, &val); | ||
626 | mutex_unlock(&s->max310x_mutex); | ||
627 | |||
628 | return val ? 0 : TIOCSER_TEMT; | ||
629 | } | ||
630 | |||
631 | static void max310x_enable_ms(struct uart_port *port) | ||
632 | { | ||
633 | /* Modem status not supported */ | ||
634 | } | ||
635 | |||
636 | static unsigned int max310x_get_mctrl(struct uart_port *port) | ||
637 | { | ||
638 | /* DCD and DSR are not wired and CTS/RTS is handled automatically | ||
639 | * so just indicate DSR and CAR asserted | ||
640 | */ | ||
641 | return TIOCM_DSR | TIOCM_CAR; | ||
642 | } | ||
643 | |||
644 | static void max310x_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
645 | { | ||
646 | /* DCD and DSR are not wired and CTS/RTS is hadnled automatically | ||
647 | * so do nothing | ||
648 | */ | ||
649 | } | ||
650 | |||
651 | static void max310x_break_ctl(struct uart_port *port, int break_state) | ||
652 | { | ||
653 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
654 | |||
655 | mutex_lock(&s->max310x_mutex); | ||
656 | regmap_update_bits(s->regmap, MAX310X_LCR_REG, | ||
657 | MAX310X_LCR_TXBREAK_BIT, | ||
658 | break_state ? MAX310X_LCR_TXBREAK_BIT : 0); | ||
659 | mutex_unlock(&s->max310x_mutex); | ||
660 | } | ||
661 | |||
662 | static void max310x_set_termios(struct uart_port *port, | ||
663 | struct ktermios *termios, | ||
664 | struct ktermios *old) | ||
665 | { | ||
666 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
667 | unsigned int lcr, flow = 0; | ||
668 | int baud; | ||
669 | |||
670 | mutex_lock(&s->max310x_mutex); | ||
671 | |||
672 | /* Mask termios capabilities we don't support */ | ||
673 | termios->c_cflag &= ~CMSPAR; | ||
674 | termios->c_iflag &= ~IXANY; | ||
675 | |||
676 | /* Word size */ | ||
677 | switch (termios->c_cflag & CSIZE) { | ||
678 | case CS5: | ||
679 | lcr = MAX310X_LCR_WORD_LEN_5; | ||
680 | break; | ||
681 | case CS6: | ||
682 | lcr = MAX310X_LCR_WORD_LEN_6; | ||
683 | break; | ||
684 | case CS7: | ||
685 | lcr = MAX310X_LCR_WORD_LEN_7; | ||
686 | break; | ||
687 | case CS8: | ||
688 | default: | ||
689 | lcr = MAX310X_LCR_WORD_LEN_8; | ||
690 | break; | ||
691 | } | ||
692 | |||
693 | /* Parity */ | ||
694 | if (termios->c_cflag & PARENB) { | ||
695 | lcr |= MAX310X_LCR_PARITY_BIT; | ||
696 | if (!(termios->c_cflag & PARODD)) | ||
697 | lcr |= MAX310X_LCR_EVENPARITY_BIT; | ||
698 | } | ||
699 | |||
700 | /* Stop bits */ | ||
701 | if (termios->c_cflag & CSTOPB) | ||
702 | lcr |= MAX310X_LCR_STOPLEN_BIT; /* 2 stops */ | ||
703 | |||
704 | /* Update LCR register */ | ||
705 | regmap_write(s->regmap, MAX310X_LCR_REG, lcr); | ||
706 | |||
707 | /* Set read status mask */ | ||
708 | port->read_status_mask = MAX310X_LSR_RXOVR_BIT; | ||
709 | if (termios->c_iflag & INPCK) | ||
710 | port->read_status_mask |= MAX310X_LSR_RXPAR_BIT | | ||
711 | MAX310X_LSR_FRERR_BIT; | ||
712 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
713 | port->read_status_mask |= MAX310X_LSR_RXBRK_BIT; | ||
714 | |||
715 | /* Set status ignore mask */ | ||
716 | port->ignore_status_mask = 0; | ||
717 | if (termios->c_iflag & IGNBRK) | ||
718 | port->ignore_status_mask |= MAX310X_LSR_RXBRK_BIT; | ||
719 | if (!(termios->c_cflag & CREAD)) | ||
720 | port->ignore_status_mask |= MAX310X_LSR_RXPAR_BIT | | ||
721 | MAX310X_LSR_RXOVR_BIT | | ||
722 | MAX310X_LSR_FRERR_BIT | | ||
723 | MAX310X_LSR_RXBRK_BIT; | ||
724 | |||
725 | /* Configure flow control */ | ||
726 | regmap_write(s->regmap, MAX310X_XON1_REG, termios->c_cc[VSTART]); | ||
727 | regmap_write(s->regmap, MAX310X_XOFF1_REG, termios->c_cc[VSTOP]); | ||
728 | if (termios->c_cflag & CRTSCTS) | ||
729 | flow |= MAX310X_FLOWCTRL_AUTOCTS_BIT | | ||
730 | MAX310X_FLOWCTRL_AUTORTS_BIT; | ||
731 | if (termios->c_iflag & IXON) | ||
732 | flow |= MAX310X_FLOWCTRL_SWFLOW3_BIT | | ||
733 | MAX310X_FLOWCTRL_SWFLOWEN_BIT; | ||
734 | if (termios->c_iflag & IXOFF) | ||
735 | flow |= MAX310X_FLOWCTRL_SWFLOW1_BIT | | ||
736 | MAX310X_FLOWCTRL_SWFLOWEN_BIT; | ||
737 | regmap_write(s->regmap, MAX310X_FLOWCTRL_REG, flow); | ||
738 | |||
739 | /* Get baud rate generator configuration */ | ||
740 | baud = uart_get_baud_rate(port, termios, old, | ||
741 | port->uartclk / 16 / 0xffff, | ||
742 | port->uartclk / 4); | ||
743 | |||
744 | /* Setup baudrate generator */ | ||
745 | max310x_set_baud(s, baud); | ||
746 | |||
747 | /* Update timeout according to new baud rate */ | ||
748 | uart_update_timeout(port, termios->c_cflag, baud); | ||
749 | |||
750 | mutex_unlock(&s->max310x_mutex); | ||
751 | } | ||
752 | |||
753 | static int max310x_startup(struct uart_port *port) | ||
754 | { | ||
755 | unsigned int val, line = port->line; | ||
756 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
757 | |||
758 | if (s->pdata->suspend) | ||
759 | s->pdata->suspend(0); | ||
760 | |||
761 | mutex_lock(&s->max310x_mutex); | ||
762 | |||
763 | /* Configure baud rate, 9600 as default */ | ||
764 | max310x_set_baud(s, 9600); | ||
765 | |||
766 | /* Configure LCR register, 8N1 mode by default */ | ||
767 | val = MAX310X_LCR_WORD_LEN_8; | ||
768 | regmap_write(s->regmap, MAX310X_LCR_REG, val); | ||
769 | |||
770 | /* Configure MODE1 register */ | ||
771 | regmap_update_bits(s->regmap, MAX310X_MODE1_REG, | ||
772 | MAX310X_MODE1_TRNSCVCTRL_BIT, | ||
773 | (s->pdata->uart_flags[line] & MAX310X_AUTO_DIR_CTRL) | ||
774 | ? MAX310X_MODE1_TRNSCVCTRL_BIT : 0); | ||
775 | |||
776 | /* Configure MODE2 register */ | ||
777 | val = MAX310X_MODE2_RXEMPTINV_BIT; | ||
778 | if (s->pdata->uart_flags[line] & MAX310X_LOOPBACK) | ||
779 | val |= MAX310X_MODE2_LOOPBACK_BIT; | ||
780 | if (s->pdata->uart_flags[line] & MAX310X_ECHO_SUPRESS) | ||
781 | val |= MAX310X_MODE2_ECHOSUPR_BIT; | ||
782 | |||
783 | /* Reset FIFOs */ | ||
784 | val |= MAX310X_MODE2_FIFORST_BIT; | ||
785 | regmap_write(s->regmap, MAX310X_MODE2_REG, val); | ||
786 | |||
787 | /* Configure FIFO trigger level register */ | ||
788 | /* RX FIFO trigger for 16 words, TX FIFO trigger for 64 words */ | ||
789 | val = MAX310X_FIFOTRIGLVL_RX(16) | MAX310X_FIFOTRIGLVL_TX(64); | ||
790 | regmap_write(s->regmap, MAX310X_FIFOTRIGLVL_REG, val); | ||
791 | |||
792 | /* Configure flow control levels */ | ||
793 | /* Flow control halt level 96, resume level 48 */ | ||
794 | val = MAX310X_FLOWLVL_RES(48) | MAX310X_FLOWLVL_HALT(96); | ||
795 | regmap_write(s->regmap, MAX310X_FLOWLVL_REG, val); | ||
796 | |||
797 | /* Clear timeout register */ | ||
798 | regmap_write(s->regmap, MAX310X_RXTO_REG, 0); | ||
799 | |||
800 | /* Configure LSR interrupt enable register */ | ||
801 | /* Enable RX timeout interrupt */ | ||
802 | val = MAX310X_LSR_RXTO_BIT; | ||
803 | regmap_write(s->regmap, MAX310X_LSR_IRQEN_REG, val); | ||
804 | |||
805 | /* Clear FIFO reset */ | ||
806 | regmap_update_bits(s->regmap, MAX310X_MODE2_REG, | ||
807 | MAX310X_MODE2_FIFORST_BIT, 0); | ||
808 | |||
809 | /* Clear IRQ status register by reading it */ | ||
810 | regmap_read(s->regmap, MAX310X_IRQSTS_REG, &val); | ||
811 | |||
812 | /* Configure interrupt enable register */ | ||
813 | /* Enable CTS change interrupt */ | ||
814 | val = MAX310X_IRQ_CTS_BIT; | ||
815 | /* Enable RX, TX interrupts */ | ||
816 | val |= MAX310X_IRQ_RX | MAX310X_IRQ_TX; | ||
817 | regmap_write(s->regmap, MAX310X_IRQEN_REG, val); | ||
818 | |||
819 | mutex_unlock(&s->max310x_mutex); | ||
820 | |||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | static void max310x_shutdown(struct uart_port *port) | ||
825 | { | ||
826 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
827 | |||
828 | /* Disable all interrupts */ | ||
829 | mutex_lock(&s->max310x_mutex); | ||
830 | regmap_write(s->regmap, MAX310X_IRQEN_REG, 0); | ||
831 | mutex_unlock(&s->max310x_mutex); | ||
832 | |||
833 | if (s->pdata->suspend) | ||
834 | s->pdata->suspend(1); | ||
835 | } | ||
836 | |||
837 | static const char *max310x_type(struct uart_port *port) | ||
838 | { | ||
839 | struct max310x_port *s = container_of(port, struct max310x_port, port); | ||
840 | |||
841 | return (port->type == PORT_MAX310X) ? s->name : NULL; | ||
842 | } | ||
843 | |||
844 | static int max310x_request_port(struct uart_port *port) | ||
845 | { | ||
846 | /* Do nothing */ | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | static void max310x_release_port(struct uart_port *port) | ||
851 | { | ||
852 | /* Do nothing */ | ||
853 | } | ||
854 | |||
855 | static void max310x_config_port(struct uart_port *port, int flags) | ||
856 | { | ||
857 | if (flags & UART_CONFIG_TYPE) | ||
858 | port->type = PORT_MAX310X; | ||
859 | } | ||
860 | |||
861 | static int max310x_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
862 | { | ||
863 | if ((ser->type == PORT_UNKNOWN) || (ser->type == PORT_MAX310X)) | ||
864 | return 0; | ||
865 | if (ser->irq == port->irq) | ||
866 | return 0; | ||
867 | |||
868 | return -EINVAL; | ||
869 | } | ||
870 | |||
871 | static struct uart_ops max310x_ops = { | ||
872 | .tx_empty = max310x_tx_empty, | ||
873 | .set_mctrl = max310x_set_mctrl, | ||
874 | .get_mctrl = max310x_get_mctrl, | ||
875 | .stop_tx = max310x_stop_tx, | ||
876 | .start_tx = max310x_start_tx, | ||
877 | .stop_rx = max310x_stop_rx, | ||
878 | .enable_ms = max310x_enable_ms, | ||
879 | .break_ctl = max310x_break_ctl, | ||
880 | .startup = max310x_startup, | ||
881 | .shutdown = max310x_shutdown, | ||
882 | .set_termios = max310x_set_termios, | ||
883 | .type = max310x_type, | ||
884 | .request_port = max310x_request_port, | ||
885 | .release_port = max310x_release_port, | ||
886 | .config_port = max310x_config_port, | ||
887 | .verify_port = max310x_verify_port, | ||
888 | }; | ||
889 | |||
890 | static int max310x_suspend(struct spi_device *spi, pm_message_t state) | ||
891 | { | ||
892 | int ret; | ||
893 | struct max310x_port *s = dev_get_drvdata(&spi->dev); | ||
894 | |||
895 | dev_dbg(&spi->dev, "Suspend\n"); | ||
896 | |||
897 | ret = uart_suspend_port(&s->uart, &s->port); | ||
898 | |||
899 | mutex_lock(&s->max310x_mutex); | ||
900 | |||
901 | /* Enable sleep mode */ | ||
902 | regmap_update_bits(s->regmap, MAX310X_MODE1_REG, | ||
903 | MAX310X_MODE1_FORCESLEEP_BIT, | ||
904 | MAX310X_MODE1_FORCESLEEP_BIT); | ||
905 | |||
906 | mutex_unlock(&s->max310x_mutex); | ||
907 | |||
908 | if (s->pdata->suspend) | ||
909 | s->pdata->suspend(1); | ||
910 | |||
911 | return ret; | ||
912 | } | ||
913 | |||
914 | static int max310x_resume(struct spi_device *spi) | ||
915 | { | ||
916 | struct max310x_port *s = dev_get_drvdata(&spi->dev); | ||
917 | |||
918 | dev_dbg(&spi->dev, "Resume\n"); | ||
919 | |||
920 | if (s->pdata->suspend) | ||
921 | s->pdata->suspend(0); | ||
922 | |||
923 | mutex_lock(&s->max310x_mutex); | ||
924 | |||
925 | /* Disable sleep mode */ | ||
926 | regmap_update_bits(s->regmap, MAX310X_MODE1_REG, | ||
927 | MAX310X_MODE1_FORCESLEEP_BIT, | ||
928 | 0); | ||
929 | |||
930 | max310x_wait_pll(s); | ||
931 | |||
932 | mutex_unlock(&s->max310x_mutex); | ||
933 | |||
934 | return uart_resume_port(&s->uart, &s->port); | ||
935 | } | ||
936 | |||
937 | #ifdef CONFIG_GPIOLIB | ||
938 | static int max310x_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
939 | { | ||
940 | unsigned int val = 0; | ||
941 | struct max310x_port *s = container_of(chip, struct max310x_port, gpio); | ||
942 | |||
943 | mutex_lock(&s->max310x_mutex); | ||
944 | regmap_read(s->regmap, MAX310X_GPIODATA_REG, &val); | ||
945 | mutex_unlock(&s->max310x_mutex); | ||
946 | |||
947 | return !!((val >> 4) & (1 << offset)); | ||
948 | } | ||
949 | |||
950 | static void max310x_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
951 | { | ||
952 | struct max310x_port *s = container_of(chip, struct max310x_port, gpio); | ||
953 | |||
954 | mutex_lock(&s->max310x_mutex); | ||
955 | regmap_update_bits(s->regmap, MAX310X_GPIODATA_REG, 1 << offset, value ? | ||
956 | 1 << offset : 0); | ||
957 | mutex_unlock(&s->max310x_mutex); | ||
958 | } | ||
959 | |||
960 | static int max310x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
961 | { | ||
962 | struct max310x_port *s = container_of(chip, struct max310x_port, gpio); | ||
963 | |||
964 | mutex_lock(&s->max310x_mutex); | ||
965 | |||
966 | regmap_update_bits(s->regmap, MAX310X_GPIOCFG_REG, 1 << offset, 0); | ||
967 | |||
968 | mutex_unlock(&s->max310x_mutex); | ||
969 | |||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | static int max310x_gpio_direction_output(struct gpio_chip *chip, | ||
974 | unsigned offset, int value) | ||
975 | { | ||
976 | struct max310x_port *s = container_of(chip, struct max310x_port, gpio); | ||
977 | |||
978 | mutex_lock(&s->max310x_mutex); | ||
979 | |||
980 | regmap_update_bits(s->regmap, MAX310X_GPIOCFG_REG, 1 << offset, | ||
981 | 1 << offset); | ||
982 | regmap_update_bits(s->regmap, MAX310X_GPIODATA_REG, 1 << offset, value ? | ||
983 | 1 << offset : 0); | ||
984 | |||
985 | mutex_unlock(&s->max310x_mutex); | ||
986 | |||
987 | return 0; | ||
988 | } | ||
989 | #endif | ||
990 | |||
991 | /* Generic platform data */ | ||
992 | static struct max310x_pdata generic_plat_data = { | ||
993 | .driver_flags = MAX310X_EXT_CLK, | ||
994 | .uart_flags[0] = MAX310X_ECHO_SUPRESS, | ||
995 | .frequency = 26000000, | ||
996 | }; | ||
997 | |||
998 | static int __devinit max310x_probe(struct spi_device *spi) | ||
999 | { | ||
1000 | struct max310x_port *s; | ||
1001 | struct device *dev = &spi->dev; | ||
1002 | int chiptype = spi_get_device_id(spi)->driver_data; | ||
1003 | struct max310x_pdata *pdata = dev->platform_data; | ||
1004 | unsigned int val = 0; | ||
1005 | int ret; | ||
1006 | |||
1007 | /* Check for IRQ */ | ||
1008 | if (spi->irq <= 0) { | ||
1009 | dev_err(dev, "No IRQ specified\n"); | ||
1010 | return -ENOTSUPP; | ||
1011 | } | ||
1012 | |||
1013 | /* Alloc port structure */ | ||
1014 | s = devm_kzalloc(dev, sizeof(struct max310x_port), GFP_KERNEL); | ||
1015 | if (!s) { | ||
1016 | dev_err(dev, "Error allocating port structure\n"); | ||
1017 | return -ENOMEM; | ||
1018 | } | ||
1019 | dev_set_drvdata(dev, s); | ||
1020 | |||
1021 | if (!pdata) { | ||
1022 | dev_warn(dev, "No platform data supplied, using defaults\n"); | ||
1023 | pdata = &generic_plat_data; | ||
1024 | } | ||
1025 | s->pdata = pdata; | ||
1026 | |||
1027 | /* Individual chip settings */ | ||
1028 | switch (chiptype) { | ||
1029 | case MAX310X_TYPE_MAX3107: | ||
1030 | s->name = "MAX3107"; | ||
1031 | s->nr_gpio = 4; | ||
1032 | s->uart.nr = 1; | ||
1033 | s->regcfg.max_register = 0x1f; | ||
1034 | break; | ||
1035 | case MAX310X_TYPE_MAX3108: | ||
1036 | s->name = "MAX3108"; | ||
1037 | s->nr_gpio = 4; | ||
1038 | s->uart.nr = 1; | ||
1039 | s->regcfg.max_register = 0x1e; | ||
1040 | break; | ||
1041 | default: | ||
1042 | dev_err(dev, "Unsupported chip type %i\n", chiptype); | ||
1043 | return -ENOTSUPP; | ||
1044 | } | ||
1045 | |||
1046 | /* Check input frequency */ | ||
1047 | if ((pdata->driver_flags & MAX310X_EXT_CLK) && | ||
1048 | ((pdata->frequency < 500000) || (pdata->frequency > 35000000))) | ||
1049 | goto err_freq; | ||
1050 | /* Check frequency for quartz */ | ||
1051 | if (!(pdata->driver_flags & MAX310X_EXT_CLK) && | ||
1052 | ((pdata->frequency < 1000000) || (pdata->frequency > 4000000))) | ||
1053 | goto err_freq; | ||
1054 | |||
1055 | mutex_init(&s->max310x_mutex); | ||
1056 | |||
1057 | /* Setup SPI bus */ | ||
1058 | spi->mode = SPI_MODE_0; | ||
1059 | spi->bits_per_word = 8; | ||
1060 | spi->max_speed_hz = 26000000; | ||
1061 | spi_setup(spi); | ||
1062 | |||
1063 | /* Setup regmap */ | ||
1064 | s->regcfg.reg_bits = 8; | ||
1065 | s->regcfg.val_bits = 8; | ||
1066 | s->regcfg.read_flag_mask = 0x00; | ||
1067 | s->regcfg.write_flag_mask = 0x80; | ||
1068 | s->regcfg.cache_type = REGCACHE_RBTREE; | ||
1069 | s->regcfg.writeable_reg = max3107_8_reg_writeable; | ||
1070 | s->regcfg.volatile_reg = max310x_reg_volatile; | ||
1071 | s->regcfg.precious_reg = max310x_reg_precious; | ||
1072 | s->regmap = devm_regmap_init_spi(spi, &s->regcfg); | ||
1073 | if (IS_ERR(s->regmap)) { | ||
1074 | ret = PTR_ERR(s->regmap); | ||
1075 | dev_err(dev, "Failed to initialize register map\n"); | ||
1076 | goto err_out; | ||
1077 | } | ||
1078 | |||
1079 | /* Reset chip & check SPI function */ | ||
1080 | ret = regmap_write(s->regmap, MAX310X_MODE2_REG, MAX310X_MODE2_RST_BIT); | ||
1081 | if (ret) { | ||
1082 | dev_err(dev, "SPI transfer failed\n"); | ||
1083 | goto err_out; | ||
1084 | } | ||
1085 | /* Clear chip reset */ | ||
1086 | regmap_write(s->regmap, MAX310X_MODE2_REG, 0); | ||
1087 | |||
1088 | switch (chiptype) { | ||
1089 | case MAX310X_TYPE_MAX3107: | ||
1090 | /* Check REV ID to ensure we are talking to what we expect */ | ||
1091 | regmap_read(s->regmap, MAX3107_REVID_REG, &val); | ||
1092 | if (((val & MAX3107_REV_MASK) != MAX3107_REV_ID)) { | ||
1093 | dev_err(dev, "%s ID 0x%02x does not match\n", | ||
1094 | s->name, val); | ||
1095 | ret = -ENODEV; | ||
1096 | goto err_out; | ||
1097 | } | ||
1098 | break; | ||
1099 | case MAX310X_TYPE_MAX3108: | ||
1100 | /* MAX3108 have not REV ID register, we just check default value | ||
1101 | * from clocksource register to make sure everything works. | ||
1102 | */ | ||
1103 | regmap_read(s->regmap, MAX310X_CLKSRC_REG, &val); | ||
1104 | if (val != (MAX310X_CLKSRC_EXTCLK_BIT | | ||
1105 | MAX310X_CLKSRC_PLLBYP_BIT)) { | ||
1106 | dev_err(dev, "%s not present\n", s->name); | ||
1107 | ret = -ENODEV; | ||
1108 | goto err_out; | ||
1109 | } | ||
1110 | break; | ||
1111 | } | ||
1112 | |||
1113 | /* Board specific configure */ | ||
1114 | if (pdata->init) | ||
1115 | pdata->init(); | ||
1116 | if (pdata->suspend) | ||
1117 | pdata->suspend(0); | ||
1118 | |||
1119 | /* Calculate referecne clock */ | ||
1120 | s->uartclk = max310x_set_ref_clk(s); | ||
1121 | |||
1122 | /* Disable all interrupts */ | ||
1123 | regmap_write(s->regmap, MAX310X_IRQEN_REG, 0); | ||
1124 | |||
1125 | /* Setup MODE1 register */ | ||
1126 | val = MAX310X_MODE1_IRQSEL_BIT; /* Enable IRQ pin */ | ||
1127 | if (pdata->driver_flags & MAX310X_AUTOSLEEP) | ||
1128 | val = MAX310X_MODE1_AUTOSLEEP_BIT; | ||
1129 | regmap_write(s->regmap, MAX310X_MODE1_REG, val); | ||
1130 | |||
1131 | /* Setup interrupt */ | ||
1132 | ret = devm_request_threaded_irq(dev, spi->irq, NULL, max310x_ist, | ||
1133 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
1134 | dev_name(dev), s); | ||
1135 | if (ret) { | ||
1136 | dev_err(dev, "Unable to reguest IRQ %i\n", spi->irq); | ||
1137 | goto err_out; | ||
1138 | } | ||
1139 | |||
1140 | /* Register UART driver */ | ||
1141 | s->uart.owner = THIS_MODULE; | ||
1142 | s->uart.driver_name = dev_name(dev); | ||
1143 | s->uart.dev_name = "ttyMAX"; | ||
1144 | s->uart.major = MAX310X_MAJOR; | ||
1145 | s->uart.minor = MAX310X_MINOR; | ||
1146 | ret = uart_register_driver(&s->uart); | ||
1147 | if (ret) { | ||
1148 | dev_err(dev, "Registering UART driver failed\n"); | ||
1149 | goto err_out; | ||
1150 | } | ||
1151 | |||
1152 | /* Initialize workqueue for start TX */ | ||
1153 | s->wq = create_freezable_workqueue(dev_name(dev)); | ||
1154 | INIT_WORK(&s->tx_work, max310x_wq_proc); | ||
1155 | |||
1156 | /* Initialize UART port data */ | ||
1157 | s->port.line = 0; | ||
1158 | s->port.dev = dev; | ||
1159 | s->port.irq = spi->irq; | ||
1160 | s->port.type = PORT_MAX310X; | ||
1161 | s->port.fifosize = MAX310X_FIFO_SIZE; | ||
1162 | s->port.flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; | ||
1163 | s->port.iotype = UPIO_PORT; | ||
1164 | s->port.membase = (void __iomem *)0xffffffff; /* Bogus value */ | ||
1165 | s->port.uartclk = s->uartclk; | ||
1166 | s->port.ops = &max310x_ops; | ||
1167 | uart_add_one_port(&s->uart, &s->port); | ||
1168 | |||
1169 | #ifdef CONFIG_GPIOLIB | ||
1170 | /* Setup GPIO cotroller */ | ||
1171 | if (pdata->gpio_base) { | ||
1172 | s->gpio.owner = THIS_MODULE; | ||
1173 | s->gpio.dev = dev; | ||
1174 | s->gpio.label = dev_name(dev); | ||
1175 | s->gpio.direction_input = max310x_gpio_direction_input; | ||
1176 | s->gpio.get = max310x_gpio_get; | ||
1177 | s->gpio.direction_output= max310x_gpio_direction_output; | ||
1178 | s->gpio.set = max310x_gpio_set; | ||
1179 | s->gpio.base = pdata->gpio_base; | ||
1180 | s->gpio.ngpio = s->nr_gpio; | ||
1181 | if (gpiochip_add(&s->gpio)) { | ||
1182 | /* Indicate that we should not call gpiochip_remove */ | ||
1183 | s->gpio.base = 0; | ||
1184 | } | ||
1185 | } else | ||
1186 | dev_info(dev, "GPIO support not enabled\n"); | ||
1187 | #endif | ||
1188 | |||
1189 | /* Go to suspend mode */ | ||
1190 | if (pdata->suspend) | ||
1191 | pdata->suspend(1); | ||
1192 | |||
1193 | return 0; | ||
1194 | |||
1195 | err_freq: | ||
1196 | dev_err(dev, "Frequency parameter incorrect\n"); | ||
1197 | ret = -EINVAL; | ||
1198 | |||
1199 | err_out: | ||
1200 | dev_set_drvdata(dev, NULL); | ||
1201 | |||
1202 | return ret; | ||
1203 | } | ||
1204 | |||
1205 | static int __devexit max310x_remove(struct spi_device *spi) | ||
1206 | { | ||
1207 | struct device *dev = &spi->dev; | ||
1208 | struct max310x_port *s = dev_get_drvdata(dev); | ||
1209 | int ret = 0; | ||
1210 | |||
1211 | dev_dbg(dev, "Removing port\n"); | ||
1212 | |||
1213 | devm_free_irq(dev, s->port.irq, s); | ||
1214 | |||
1215 | destroy_workqueue(s->wq); | ||
1216 | |||
1217 | uart_remove_one_port(&s->uart, &s->port); | ||
1218 | |||
1219 | uart_unregister_driver(&s->uart); | ||
1220 | |||
1221 | #ifdef CONFIG_GPIOLIB | ||
1222 | if (s->pdata->gpio_base) { | ||
1223 | ret = gpiochip_remove(&s->gpio); | ||
1224 | if (ret) | ||
1225 | dev_err(dev, "Failed to remove gpio chip: %d\n", ret); | ||
1226 | } | ||
1227 | #endif | ||
1228 | |||
1229 | dev_set_drvdata(dev, NULL); | ||
1230 | |||
1231 | if (s->pdata->suspend) | ||
1232 | s->pdata->suspend(1); | ||
1233 | if (s->pdata->exit) | ||
1234 | s->pdata->exit(); | ||
1235 | |||
1236 | return ret; | ||
1237 | } | ||
1238 | |||
1239 | static const struct spi_device_id max310x_id_table[] = { | ||
1240 | { "max3107", MAX310X_TYPE_MAX3107 }, | ||
1241 | { "max3108", MAX310X_TYPE_MAX3108 }, | ||
1242 | }; | ||
1243 | MODULE_DEVICE_TABLE(spi, max310x_id_table); | ||
1244 | |||
1245 | static struct spi_driver max310x_driver = { | ||
1246 | .driver = { | ||
1247 | .name = "max310x", | ||
1248 | .owner = THIS_MODULE, | ||
1249 | }, | ||
1250 | .probe = max310x_probe, | ||
1251 | .remove = __devexit_p(max310x_remove), | ||
1252 | .suspend = max310x_suspend, | ||
1253 | .resume = max310x_resume, | ||
1254 | .id_table = max310x_id_table, | ||
1255 | }; | ||
1256 | module_spi_driver(max310x_driver); | ||
1257 | |||
1258 | MODULE_LICENSE("GPL v2"); | ||
1259 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | ||
1260 | MODULE_DESCRIPTION("MAX310X serial driver"); | ||
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index bedac0d4c9ce..f19d04ed8586 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c | |||
@@ -775,11 +775,15 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, | |||
775 | } | 775 | } |
776 | 776 | ||
777 | if (new->c_cflag & PARENB) { | 777 | if (new->c_cflag & PARENB) { |
778 | if (new->c_cflag & CMSPAR) | ||
779 | mr1 |= MPC52xx_PSC_MODE_PARFORCE; | ||
780 | |||
781 | /* With CMSPAR, PARODD also means high parity (same as termios) */ | ||
778 | mr1 |= (new->c_cflag & PARODD) ? | 782 | mr1 |= (new->c_cflag & PARODD) ? |
779 | MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN; | 783 | MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN; |
780 | } else | 784 | } else { |
781 | mr1 |= MPC52xx_PSC_MODE_PARNONE; | 785 | mr1 |= MPC52xx_PSC_MODE_PARNONE; |
782 | 786 | } | |
783 | 787 | ||
784 | mr2 = 0; | 788 | mr2 = 0; |
785 | 789 | ||
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c index 8131e2c28015..033e0bc9ebab 100644 --- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c | |||
@@ -896,7 +896,7 @@ static int __init msm_serial_probe(struct platform_device *pdev) | |||
896 | return PTR_ERR(msm_port->clk); | 896 | return PTR_ERR(msm_port->clk); |
897 | 897 | ||
898 | if (msm_port->is_uartdm) | 898 | if (msm_port->is_uartdm) |
899 | clk_set_rate(msm_port->clk, 7372800); | 899 | clk_set_rate(msm_port->clk, 1843200); |
900 | 900 | ||
901 | port->uartclk = clk_get_rate(msm_port->clk); | 901 | port->uartclk = clk_get_rate(msm_port->clk); |
902 | printk(KERN_INFO "uartclk = %d\n", port->uartclk); | 902 | printk(KERN_INFO "uartclk = %d\n", port->uartclk); |
diff --git a/drivers/tty/serial/msm_smd_tty.c b/drivers/tty/serial/msm_smd_tty.c index b25e6ee71443..925d1fa153db 100644 --- a/drivers/tty/serial/msm_smd_tty.c +++ b/drivers/tty/serial/msm_smd_tty.c | |||
@@ -223,9 +223,11 @@ static int __init smd_tty_init(void) | |||
223 | return ret; | 223 | return ret; |
224 | 224 | ||
225 | for (i = 0; i < smd_tty_channels_len; i++) { | 225 | for (i = 0; i < smd_tty_channels_len; i++) { |
226 | tty_port_init(&smd_tty[smd_tty_channels[i].id].port); | 226 | struct tty_port *port = &smd_tty[smd_tty_channels[i].id].port; |
227 | smd_tty[smd_tty_channels[i].id].port.ops = &smd_tty_port_ops; | 227 | tty_port_init(port); |
228 | tty_register_device(smd_tty_driver, smd_tty_channels[i].id, 0); | 228 | port->ops = &smd_tty_port_ops; |
229 | tty_port_register_device(port, smd_tty_driver, | ||
230 | smd_tty_channels[i].id, NULL); | ||
229 | } | 231 | } |
230 | 232 | ||
231 | return 0; | 233 | return 0; |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 3a667eed63d6..68984136bfb1 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -262,7 +262,7 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
262 | 262 | ||
263 | ctrl &= ~AUART_CTRL2_RTSEN; | 263 | ctrl &= ~AUART_CTRL2_RTSEN; |
264 | if (mctrl & TIOCM_RTS) { | 264 | if (mctrl & TIOCM_RTS) { |
265 | if (u->state->port.flags & ASYNC_CTS_FLOW) | 265 | if (tty_port_cts_enabled(&u->state->port)) |
266 | ctrl |= AUART_CTRL2_RTSEN; | 266 | ctrl |= AUART_CTRL2_RTSEN; |
267 | } | 267 | } |
268 | 268 | ||
@@ -457,11 +457,11 @@ static void mxs_auart_shutdown(struct uart_port *u) | |||
457 | 457 | ||
458 | writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); | 458 | writel(AUART_CTRL2_UARTEN, u->membase + AUART_CTRL2_CLR); |
459 | 459 | ||
460 | writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); | ||
461 | |||
462 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, | 460 | writel(AUART_INTR_RXIEN | AUART_INTR_RTIEN | AUART_INTR_CTSMIEN, |
463 | u->membase + AUART_INTR_CLR); | 461 | u->membase + AUART_INTR_CLR); |
464 | 462 | ||
463 | writel(AUART_CTRL0_CLKGATE, u->membase + AUART_CTRL0_SET); | ||
464 | |||
465 | clk_disable_unprepare(s->clk); | 465 | clk_disable_unprepare(s->clk); |
466 | } | 466 | } |
467 | 467 | ||
@@ -796,6 +796,7 @@ static int __devexit mxs_auart_remove(struct platform_device *pdev) | |||
796 | 796 | ||
797 | auart_port[pdev->id] = NULL; | 797 | auart_port[pdev->id] = NULL; |
798 | 798 | ||
799 | put_device(s->dev); | ||
799 | clk_put(s->clk); | 800 | clk_put(s->clk); |
800 | free_irq(s->irq, s); | 801 | free_irq(s->irq, s); |
801 | kfree(s); | 802 | kfree(s); |
diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index 34e71874a892..df443b908ca3 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c | |||
@@ -105,6 +105,10 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev, | |||
105 | port->uartclk = clk; | 105 | port->uartclk = clk; |
106 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP | 106 | port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
107 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; | 107 | | UPF_FIXED_PORT | UPF_FIXED_TYPE; |
108 | |||
109 | if (of_find_property(np, "no-loopback-test", NULL)) | ||
110 | port->flags |= UPF_SKIP_TEST; | ||
111 | |||
108 | port->dev = &ofdev->dev; | 112 | port->dev = &ofdev->dev; |
109 | 113 | ||
110 | if (type == PORT_TEGRA) | 114 | if (type == PORT_TEGRA) |
@@ -144,8 +148,15 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev) | |||
144 | switch (port_type) { | 148 | switch (port_type) { |
145 | #ifdef CONFIG_SERIAL_8250 | 149 | #ifdef CONFIG_SERIAL_8250 |
146 | case PORT_8250 ... PORT_MAX_8250: | 150 | case PORT_8250 ... PORT_MAX_8250: |
147 | ret = serial8250_register_port(&port); | 151 | { |
152 | /* For now the of bindings don't support the extra | ||
153 | 8250 specific bits */ | ||
154 | struct uart_8250_port port8250; | ||
155 | memset(&port8250, 0, sizeof(port8250)); | ||
156 | port8250.port = port; | ||
157 | ret = serial8250_register_8250_port(&port8250); | ||
148 | break; | 158 | break; |
159 | } | ||
149 | #endif | 160 | #endif |
150 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL | 161 | #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL |
151 | case PORT_NWPSERIAL: | 162 | case PORT_NWPSERIAL: |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d3cda0cb2df0..f175385bb304 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -32,16 +32,16 @@ | |||
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/tty.h> | 33 | #include <linux/tty.h> |
34 | #include <linux/tty_flip.h> | 34 | #include <linux/tty_flip.h> |
35 | #include <linux/platform_device.h> | ||
35 | #include <linux/io.h> | 36 | #include <linux/io.h> |
36 | #include <linux/dma-mapping.h> | ||
37 | #include <linux/clk.h> | 37 | #include <linux/clk.h> |
38 | #include <linux/serial_core.h> | 38 | #include <linux/serial_core.h> |
39 | #include <linux/irq.h> | 39 | #include <linux/irq.h> |
40 | #include <linux/pm_runtime.h> | 40 | #include <linux/pm_runtime.h> |
41 | #include <linux/of.h> | 41 | #include <linux/of.h> |
42 | #include <linux/gpio.h> | ||
43 | #include <linux/pinctrl/consumer.h> | ||
42 | 44 | ||
43 | #include <plat/dma.h> | ||
44 | #include <plat/dmtimer.h> | ||
45 | #include <plat/omap-serial.h> | 45 | #include <plat/omap-serial.h> |
46 | 46 | ||
47 | #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) | 47 | #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) |
@@ -57,8 +57,8 @@ | |||
57 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) | 57 | #define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) |
58 | 58 | ||
59 | /* FCR register bitmasks */ | 59 | /* FCR register bitmasks */ |
60 | #define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6 | ||
61 | #define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6) | 60 | #define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6) |
61 | #define OMAP_UART_FCR_TX_FIFO_TRIG_MASK (0x3 << 4) | ||
62 | 62 | ||
63 | /* MVR register bitmasks */ | 63 | /* MVR register bitmasks */ |
64 | #define OMAP_UART_MVR_SCHEME_SHIFT 30 | 64 | #define OMAP_UART_MVR_SCHEME_SHIFT 30 |
@@ -71,12 +71,52 @@ | |||
71 | #define OMAP_UART_MVR_MAJ_SHIFT 8 | 71 | #define OMAP_UART_MVR_MAJ_SHIFT 8 |
72 | #define OMAP_UART_MVR_MIN_MASK 0x3f | 72 | #define OMAP_UART_MVR_MIN_MASK 0x3f |
73 | 73 | ||
74 | struct uart_omap_port { | ||
75 | struct uart_port port; | ||
76 | struct uart_omap_dma uart_dma; | ||
77 | struct device *dev; | ||
78 | |||
79 | unsigned char ier; | ||
80 | unsigned char lcr; | ||
81 | unsigned char mcr; | ||
82 | unsigned char fcr; | ||
83 | unsigned char efr; | ||
84 | unsigned char dll; | ||
85 | unsigned char dlh; | ||
86 | unsigned char mdr1; | ||
87 | unsigned char scr; | ||
88 | |||
89 | int use_dma; | ||
90 | /* | ||
91 | * Some bits in registers are cleared on a read, so they must | ||
92 | * be saved whenever the register is read but the bits will not | ||
93 | * be immediately processed. | ||
94 | */ | ||
95 | unsigned int lsr_break_flag; | ||
96 | unsigned char msr_saved_flags; | ||
97 | char name[20]; | ||
98 | unsigned long port_activity; | ||
99 | u32 context_loss_cnt; | ||
100 | u32 errata; | ||
101 | u8 wakeups_enabled; | ||
102 | unsigned int irq_pending:1; | ||
103 | |||
104 | int DTR_gpio; | ||
105 | int DTR_inverted; | ||
106 | int DTR_active; | ||
107 | |||
108 | struct pm_qos_request pm_qos_request; | ||
109 | u32 latency; | ||
110 | u32 calc_latency; | ||
111 | struct work_struct qos_work; | ||
112 | struct pinctrl *pins; | ||
113 | }; | ||
114 | |||
115 | #define to_uart_omap_port(p) ((container_of((p), struct uart_omap_port, port))) | ||
116 | |||
74 | static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; | 117 | static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; |
75 | 118 | ||
76 | /* Forward declaration of functions */ | 119 | /* Forward declaration of functions */ |
77 | static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); | ||
78 | static void serial_omap_rxdma_poll(unsigned long uart_no); | ||
79 | static int serial_omap_start_rxdma(struct uart_omap_port *up); | ||
80 | static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); | 120 | static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1); |
81 | 121 | ||
82 | static struct workqueue_struct *serial_omap_uart_wq; | 122 | static struct workqueue_struct *serial_omap_uart_wq; |
@@ -101,6 +141,46 @@ static inline void serial_omap_clear_fifos(struct uart_omap_port *up) | |||
101 | serial_out(up, UART_FCR, 0); | 141 | serial_out(up, UART_FCR, 0); |
102 | } | 142 | } |
103 | 143 | ||
144 | static int serial_omap_get_context_loss_count(struct uart_omap_port *up) | ||
145 | { | ||
146 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
147 | |||
148 | if (!pdata || !pdata->get_context_loss_count) | ||
149 | return 0; | ||
150 | |||
151 | return pdata->get_context_loss_count(up->dev); | ||
152 | } | ||
153 | |||
154 | static void serial_omap_set_forceidle(struct uart_omap_port *up) | ||
155 | { | ||
156 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
157 | |||
158 | if (!pdata || !pdata->set_forceidle) | ||
159 | return; | ||
160 | |||
161 | pdata->set_forceidle(up->dev); | ||
162 | } | ||
163 | |||
164 | static void serial_omap_set_noidle(struct uart_omap_port *up) | ||
165 | { | ||
166 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
167 | |||
168 | if (!pdata || !pdata->set_noidle) | ||
169 | return; | ||
170 | |||
171 | pdata->set_noidle(up->dev); | ||
172 | } | ||
173 | |||
174 | static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | ||
175 | { | ||
176 | struct omap_uart_port_info *pdata = up->dev->platform_data; | ||
177 | |||
178 | if (!pdata || !pdata->enable_wakeup) | ||
179 | return; | ||
180 | |||
181 | pdata->enable_wakeup(up->dev, enable); | ||
182 | } | ||
183 | |||
104 | /* | 184 | /* |
105 | * serial_omap_get_divisor - calculate divisor value | 185 | * serial_omap_get_divisor - calculate divisor value |
106 | * @port: uart port info | 186 | * @port: uart port info |
@@ -126,151 +206,55 @@ serial_omap_get_divisor(struct uart_port *port, unsigned int baud) | |||
126 | return port->uartclk/(baud * divisor); | 206 | return port->uartclk/(baud * divisor); |
127 | } | 207 | } |
128 | 208 | ||
129 | static void serial_omap_stop_rxdma(struct uart_omap_port *up) | ||
130 | { | ||
131 | if (up->uart_dma.rx_dma_used) { | ||
132 | del_timer(&up->uart_dma.rx_timer); | ||
133 | omap_stop_dma(up->uart_dma.rx_dma_channel); | ||
134 | omap_free_dma(up->uart_dma.rx_dma_channel); | ||
135 | up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
136 | up->uart_dma.rx_dma_used = false; | ||
137 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
138 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
139 | } | ||
140 | } | ||
141 | |||
142 | static void serial_omap_enable_ms(struct uart_port *port) | 209 | static void serial_omap_enable_ms(struct uart_port *port) |
143 | { | 210 | { |
144 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 211 | struct uart_omap_port *up = to_uart_omap_port(port); |
145 | 212 | ||
146 | dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->port.line); | 213 | dev_dbg(up->port.dev, "serial_omap_enable_ms+%d\n", up->port.line); |
147 | 214 | ||
148 | pm_runtime_get_sync(&up->pdev->dev); | 215 | pm_runtime_get_sync(up->dev); |
149 | up->ier |= UART_IER_MSI; | 216 | up->ier |= UART_IER_MSI; |
150 | serial_out(up, UART_IER, up->ier); | 217 | serial_out(up, UART_IER, up->ier); |
151 | pm_runtime_put(&up->pdev->dev); | 218 | pm_runtime_mark_last_busy(up->dev); |
219 | pm_runtime_put_autosuspend(up->dev); | ||
152 | } | 220 | } |
153 | 221 | ||
154 | static void serial_omap_stop_tx(struct uart_port *port) | 222 | static void serial_omap_stop_tx(struct uart_port *port) |
155 | { | 223 | { |
156 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 224 | struct uart_omap_port *up = to_uart_omap_port(port); |
157 | struct omap_uart_port_info *pdata = up->pdev->dev.platform_data; | ||
158 | 225 | ||
159 | if (up->use_dma && | 226 | pm_runtime_get_sync(up->dev); |
160 | up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) { | ||
161 | /* | ||
162 | * Check if dma is still active. If yes do nothing, | ||
163 | * return. Else stop dma | ||
164 | */ | ||
165 | if (omap_get_dma_active_status(up->uart_dma.tx_dma_channel)) | ||
166 | return; | ||
167 | omap_stop_dma(up->uart_dma.tx_dma_channel); | ||
168 | omap_free_dma(up->uart_dma.tx_dma_channel); | ||
169 | up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
170 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
171 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
172 | } | ||
173 | |||
174 | pm_runtime_get_sync(&up->pdev->dev); | ||
175 | if (up->ier & UART_IER_THRI) { | 227 | if (up->ier & UART_IER_THRI) { |
176 | up->ier &= ~UART_IER_THRI; | 228 | up->ier &= ~UART_IER_THRI; |
177 | serial_out(up, UART_IER, up->ier); | 229 | serial_out(up, UART_IER, up->ier); |
178 | } | 230 | } |
179 | 231 | ||
180 | if (!up->use_dma && pdata && pdata->set_forceidle) | 232 | serial_omap_set_forceidle(up); |
181 | pdata->set_forceidle(up->pdev); | ||
182 | 233 | ||
183 | pm_runtime_mark_last_busy(&up->pdev->dev); | 234 | pm_runtime_mark_last_busy(up->dev); |
184 | pm_runtime_put_autosuspend(&up->pdev->dev); | 235 | pm_runtime_put_autosuspend(up->dev); |
185 | } | 236 | } |
186 | 237 | ||
187 | static void serial_omap_stop_rx(struct uart_port *port) | 238 | static void serial_omap_stop_rx(struct uart_port *port) |
188 | { | 239 | { |
189 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 240 | struct uart_omap_port *up = to_uart_omap_port(port); |
190 | 241 | ||
191 | pm_runtime_get_sync(&up->pdev->dev); | 242 | pm_runtime_get_sync(up->dev); |
192 | if (up->use_dma) | ||
193 | serial_omap_stop_rxdma(up); | ||
194 | up->ier &= ~UART_IER_RLSI; | 243 | up->ier &= ~UART_IER_RLSI; |
195 | up->port.read_status_mask &= ~UART_LSR_DR; | 244 | up->port.read_status_mask &= ~UART_LSR_DR; |
196 | serial_out(up, UART_IER, up->ier); | 245 | serial_out(up, UART_IER, up->ier); |
197 | pm_runtime_mark_last_busy(&up->pdev->dev); | 246 | pm_runtime_mark_last_busy(up->dev); |
198 | pm_runtime_put_autosuspend(&up->pdev->dev); | 247 | pm_runtime_put_autosuspend(up->dev); |
199 | } | ||
200 | |||
201 | static inline void receive_chars(struct uart_omap_port *up, | ||
202 | unsigned int *status) | ||
203 | { | ||
204 | struct tty_struct *tty = up->port.state->port.tty; | ||
205 | unsigned int flag, lsr = *status; | ||
206 | unsigned char ch = 0; | ||
207 | int max_count = 256; | ||
208 | |||
209 | do { | ||
210 | if (likely(lsr & UART_LSR_DR)) | ||
211 | ch = serial_in(up, UART_RX); | ||
212 | flag = TTY_NORMAL; | ||
213 | up->port.icount.rx++; | ||
214 | |||
215 | if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { | ||
216 | /* | ||
217 | * For statistics only | ||
218 | */ | ||
219 | if (lsr & UART_LSR_BI) { | ||
220 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | ||
221 | up->port.icount.brk++; | ||
222 | /* | ||
223 | * We do the SysRQ and SAK checking | ||
224 | * here because otherwise the break | ||
225 | * may get masked by ignore_status_mask | ||
226 | * or read_status_mask. | ||
227 | */ | ||
228 | if (uart_handle_break(&up->port)) | ||
229 | goto ignore_char; | ||
230 | } else if (lsr & UART_LSR_PE) { | ||
231 | up->port.icount.parity++; | ||
232 | } else if (lsr & UART_LSR_FE) { | ||
233 | up->port.icount.frame++; | ||
234 | } | ||
235 | |||
236 | if (lsr & UART_LSR_OE) | ||
237 | up->port.icount.overrun++; | ||
238 | |||
239 | /* | ||
240 | * Mask off conditions which should be ignored. | ||
241 | */ | ||
242 | lsr &= up->port.read_status_mask; | ||
243 | |||
244 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | ||
245 | if (up->port.line == up->port.cons->index) { | ||
246 | /* Recover the break flag from console xmit */ | ||
247 | lsr |= up->lsr_break_flag; | ||
248 | } | ||
249 | #endif | ||
250 | if (lsr & UART_LSR_BI) | ||
251 | flag = TTY_BREAK; | ||
252 | else if (lsr & UART_LSR_PE) | ||
253 | flag = TTY_PARITY; | ||
254 | else if (lsr & UART_LSR_FE) | ||
255 | flag = TTY_FRAME; | ||
256 | } | ||
257 | |||
258 | if (uart_handle_sysrq_char(&up->port, ch)) | ||
259 | goto ignore_char; | ||
260 | uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); | ||
261 | ignore_char: | ||
262 | lsr = serial_in(up, UART_LSR); | ||
263 | } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0)); | ||
264 | spin_unlock(&up->port.lock); | ||
265 | tty_flip_buffer_push(tty); | ||
266 | spin_lock(&up->port.lock); | ||
267 | } | 248 | } |
268 | 249 | ||
269 | static void transmit_chars(struct uart_omap_port *up) | 250 | static void transmit_chars(struct uart_omap_port *up, unsigned int lsr) |
270 | { | 251 | { |
271 | struct circ_buf *xmit = &up->port.state->xmit; | 252 | struct circ_buf *xmit = &up->port.state->xmit; |
272 | int count; | 253 | int count; |
273 | 254 | ||
255 | if (!(lsr & UART_LSR_THRE)) | ||
256 | return; | ||
257 | |||
274 | if (up->port.x_char) { | 258 | if (up->port.x_char) { |
275 | serial_out(up, UART_TX, up->port.x_char); | 259 | serial_out(up, UART_TX, up->port.x_char); |
276 | up->port.icount.tx++; | 260 | up->port.icount.tx++; |
@@ -290,8 +274,11 @@ static void transmit_chars(struct uart_omap_port *up) | |||
290 | break; | 274 | break; |
291 | } while (--count > 0); | 275 | } while (--count > 0); |
292 | 276 | ||
293 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | 277 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { |
278 | spin_unlock(&up->port.lock); | ||
294 | uart_write_wakeup(&up->port); | 279 | uart_write_wakeup(&up->port); |
280 | spin_lock(&up->port.lock); | ||
281 | } | ||
295 | 282 | ||
296 | if (uart_circ_empty(xmit)) | 283 | if (uart_circ_empty(xmit)) |
297 | serial_omap_stop_tx(&up->port); | 284 | serial_omap_stop_tx(&up->port); |
@@ -307,70 +294,13 @@ static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up) | |||
307 | 294 | ||
308 | static void serial_omap_start_tx(struct uart_port *port) | 295 | static void serial_omap_start_tx(struct uart_port *port) |
309 | { | 296 | { |
310 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 297 | struct uart_omap_port *up = to_uart_omap_port(port); |
311 | struct omap_uart_port_info *pdata = up->pdev->dev.platform_data; | ||
312 | struct circ_buf *xmit; | ||
313 | unsigned int start; | ||
314 | int ret = 0; | ||
315 | |||
316 | if (!up->use_dma) { | ||
317 | pm_runtime_get_sync(&up->pdev->dev); | ||
318 | serial_omap_enable_ier_thri(up); | ||
319 | if (pdata && pdata->set_noidle) | ||
320 | pdata->set_noidle(up->pdev); | ||
321 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
322 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
323 | return; | ||
324 | } | ||
325 | |||
326 | if (up->uart_dma.tx_dma_used) | ||
327 | return; | ||
328 | |||
329 | xmit = &up->port.state->xmit; | ||
330 | |||
331 | if (up->uart_dma.tx_dma_channel == OMAP_UART_DMA_CH_FREE) { | ||
332 | pm_runtime_get_sync(&up->pdev->dev); | ||
333 | ret = omap_request_dma(up->uart_dma.uart_dma_tx, | ||
334 | "UART Tx DMA", | ||
335 | (void *)uart_tx_dma_callback, up, | ||
336 | &(up->uart_dma.tx_dma_channel)); | ||
337 | 298 | ||
338 | if (ret < 0) { | 299 | pm_runtime_get_sync(up->dev); |
339 | serial_omap_enable_ier_thri(up); | 300 | serial_omap_enable_ier_thri(up); |
340 | return; | 301 | serial_omap_set_noidle(up); |
341 | } | 302 | pm_runtime_mark_last_busy(up->dev); |
342 | } | 303 | pm_runtime_put_autosuspend(up->dev); |
343 | spin_lock(&(up->uart_dma.tx_lock)); | ||
344 | up->uart_dma.tx_dma_used = true; | ||
345 | spin_unlock(&(up->uart_dma.tx_lock)); | ||
346 | |||
347 | start = up->uart_dma.tx_buf_dma_phys + | ||
348 | (xmit->tail & (UART_XMIT_SIZE - 1)); | ||
349 | |||
350 | up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); | ||
351 | /* | ||
352 | * It is a circular buffer. See if the buffer has wounded back. | ||
353 | * If yes it will have to be transferred in two separate dma | ||
354 | * transfers | ||
355 | */ | ||
356 | if (start + up->uart_dma.tx_buf_size >= | ||
357 | up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) | ||
358 | up->uart_dma.tx_buf_size = | ||
359 | (up->uart_dma.tx_buf_dma_phys + | ||
360 | UART_XMIT_SIZE) - start; | ||
361 | |||
362 | omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, | ||
363 | OMAP_DMA_AMODE_CONSTANT, | ||
364 | up->uart_dma.uart_base, 0, 0); | ||
365 | omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, | ||
366 | OMAP_DMA_AMODE_POST_INC, start, 0, 0); | ||
367 | omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, | ||
368 | OMAP_DMA_DATA_TYPE_S8, | ||
369 | up->uart_dma.tx_buf_size, 1, | ||
370 | OMAP_DMA_SYNC_ELEMENT, | ||
371 | up->uart_dma.uart_dma_tx, 0); | ||
372 | /* FIXME: Cache maintenance needed here? */ | ||
373 | omap_start_dma(up->uart_dma.tx_dma_channel); | ||
374 | } | 304 | } |
375 | 305 | ||
376 | static unsigned int check_modem_status(struct uart_omap_port *up) | 306 | static unsigned int check_modem_status(struct uart_omap_port *up) |
@@ -401,76 +331,158 @@ static unsigned int check_modem_status(struct uart_omap_port *up) | |||
401 | return status; | 331 | return status; |
402 | } | 332 | } |
403 | 333 | ||
334 | static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr) | ||
335 | { | ||
336 | unsigned int flag; | ||
337 | |||
338 | up->port.icount.rx++; | ||
339 | flag = TTY_NORMAL; | ||
340 | |||
341 | if (lsr & UART_LSR_BI) { | ||
342 | flag = TTY_BREAK; | ||
343 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | ||
344 | up->port.icount.brk++; | ||
345 | /* | ||
346 | * We do the SysRQ and SAK checking | ||
347 | * here because otherwise the break | ||
348 | * may get masked by ignore_status_mask | ||
349 | * or read_status_mask. | ||
350 | */ | ||
351 | if (uart_handle_break(&up->port)) | ||
352 | return; | ||
353 | |||
354 | } | ||
355 | |||
356 | if (lsr & UART_LSR_PE) { | ||
357 | flag = TTY_PARITY; | ||
358 | up->port.icount.parity++; | ||
359 | } | ||
360 | |||
361 | if (lsr & UART_LSR_FE) { | ||
362 | flag = TTY_FRAME; | ||
363 | up->port.icount.frame++; | ||
364 | } | ||
365 | |||
366 | if (lsr & UART_LSR_OE) | ||
367 | up->port.icount.overrun++; | ||
368 | |||
369 | #ifdef CONFIG_SERIAL_OMAP_CONSOLE | ||
370 | if (up->port.line == up->port.cons->index) { | ||
371 | /* Recover the break flag from console xmit */ | ||
372 | lsr |= up->lsr_break_flag; | ||
373 | } | ||
374 | #endif | ||
375 | uart_insert_char(&up->port, lsr, UART_LSR_OE, 0, flag); | ||
376 | } | ||
377 | |||
378 | static void serial_omap_rdi(struct uart_omap_port *up, unsigned int lsr) | ||
379 | { | ||
380 | unsigned char ch = 0; | ||
381 | unsigned int flag; | ||
382 | |||
383 | if (!(lsr & UART_LSR_DR)) | ||
384 | return; | ||
385 | |||
386 | ch = serial_in(up, UART_RX); | ||
387 | flag = TTY_NORMAL; | ||
388 | up->port.icount.rx++; | ||
389 | |||
390 | if (uart_handle_sysrq_char(&up->port, ch)) | ||
391 | return; | ||
392 | |||
393 | uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); | ||
394 | } | ||
395 | |||
404 | /** | 396 | /** |
405 | * serial_omap_irq() - This handles the interrupt from one port | 397 | * serial_omap_irq() - This handles the interrupt from one port |
406 | * @irq: uart port irq number | 398 | * @irq: uart port irq number |
407 | * @dev_id: uart port info | 399 | * @dev_id: uart port info |
408 | */ | 400 | */ |
409 | static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) | 401 | static irqreturn_t serial_omap_irq(int irq, void *dev_id) |
410 | { | 402 | { |
411 | struct uart_omap_port *up = dev_id; | 403 | struct uart_omap_port *up = dev_id; |
404 | struct tty_struct *tty = up->port.state->port.tty; | ||
412 | unsigned int iir, lsr; | 405 | unsigned int iir, lsr; |
413 | unsigned long flags; | 406 | unsigned int type; |
407 | irqreturn_t ret = IRQ_NONE; | ||
408 | int max_count = 256; | ||
414 | 409 | ||
415 | pm_runtime_get_sync(&up->pdev->dev); | 410 | spin_lock(&up->port.lock); |
416 | iir = serial_in(up, UART_IIR); | 411 | pm_runtime_get_sync(up->dev); |
417 | if (iir & UART_IIR_NO_INT) { | ||
418 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
419 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
420 | return IRQ_NONE; | ||
421 | } | ||
422 | 412 | ||
423 | spin_lock_irqsave(&up->port.lock, flags); | 413 | do { |
424 | lsr = serial_in(up, UART_LSR); | 414 | iir = serial_in(up, UART_IIR); |
425 | if (iir & UART_IIR_RLSI) { | 415 | if (iir & UART_IIR_NO_INT) |
426 | if (!up->use_dma) { | 416 | break; |
427 | if (lsr & UART_LSR_DR) | 417 | |
428 | receive_chars(up, &lsr); | 418 | ret = IRQ_HANDLED; |
429 | } else { | 419 | lsr = serial_in(up, UART_LSR); |
430 | up->ier &= ~(UART_IER_RDI | UART_IER_RLSI); | 420 | |
431 | serial_out(up, UART_IER, up->ier); | 421 | /* extract IRQ type from IIR register */ |
432 | if ((serial_omap_start_rxdma(up) != 0) && | 422 | type = iir & 0x3e; |
433 | (lsr & UART_LSR_DR)) | 423 | |
434 | receive_chars(up, &lsr); | 424 | switch (type) { |
425 | case UART_IIR_MSI: | ||
426 | check_modem_status(up); | ||
427 | break; | ||
428 | case UART_IIR_THRI: | ||
429 | transmit_chars(up, lsr); | ||
430 | break; | ||
431 | case UART_IIR_RX_TIMEOUT: | ||
432 | /* FALLTHROUGH */ | ||
433 | case UART_IIR_RDI: | ||
434 | serial_omap_rdi(up, lsr); | ||
435 | break; | ||
436 | case UART_IIR_RLSI: | ||
437 | serial_omap_rlsi(up, lsr); | ||
438 | break; | ||
439 | case UART_IIR_CTS_RTS_DSR: | ||
440 | /* simply try again */ | ||
441 | break; | ||
442 | case UART_IIR_XOFF: | ||
443 | /* FALLTHROUGH */ | ||
444 | default: | ||
445 | break; | ||
435 | } | 446 | } |
436 | } | 447 | } while (!(iir & UART_IIR_NO_INT) && max_count--); |
437 | 448 | ||
438 | check_modem_status(up); | 449 | spin_unlock(&up->port.lock); |
439 | if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI)) | ||
440 | transmit_chars(up); | ||
441 | 450 | ||
442 | spin_unlock_irqrestore(&up->port.lock, flags); | 451 | tty_flip_buffer_push(tty); |
443 | pm_runtime_mark_last_busy(&up->pdev->dev); | ||
444 | pm_runtime_put_autosuspend(&up->pdev->dev); | ||
445 | 452 | ||
453 | pm_runtime_mark_last_busy(up->dev); | ||
454 | pm_runtime_put_autosuspend(up->dev); | ||
446 | up->port_activity = jiffies; | 455 | up->port_activity = jiffies; |
447 | return IRQ_HANDLED; | 456 | |
457 | return ret; | ||
448 | } | 458 | } |
449 | 459 | ||
450 | static unsigned int serial_omap_tx_empty(struct uart_port *port) | 460 | static unsigned int serial_omap_tx_empty(struct uart_port *port) |
451 | { | 461 | { |
452 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 462 | struct uart_omap_port *up = to_uart_omap_port(port); |
453 | unsigned long flags = 0; | 463 | unsigned long flags = 0; |
454 | unsigned int ret = 0; | 464 | unsigned int ret = 0; |
455 | 465 | ||
456 | pm_runtime_get_sync(&up->pdev->dev); | 466 | pm_runtime_get_sync(up->dev); |
457 | dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->port.line); | 467 | dev_dbg(up->port.dev, "serial_omap_tx_empty+%d\n", up->port.line); |
458 | spin_lock_irqsave(&up->port.lock, flags); | 468 | spin_lock_irqsave(&up->port.lock, flags); |
459 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; | 469 | ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; |
460 | spin_unlock_irqrestore(&up->port.lock, flags); | 470 | spin_unlock_irqrestore(&up->port.lock, flags); |
461 | pm_runtime_put(&up->pdev->dev); | 471 | pm_runtime_mark_last_busy(up->dev); |
472 | pm_runtime_put_autosuspend(up->dev); | ||
462 | return ret; | 473 | return ret; |
463 | } | 474 | } |
464 | 475 | ||
465 | static unsigned int serial_omap_get_mctrl(struct uart_port *port) | 476 | static unsigned int serial_omap_get_mctrl(struct uart_port *port) |
466 | { | 477 | { |
467 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 478 | struct uart_omap_port *up = to_uart_omap_port(port); |
468 | unsigned int status; | 479 | unsigned int status; |
469 | unsigned int ret = 0; | 480 | unsigned int ret = 0; |
470 | 481 | ||
471 | pm_runtime_get_sync(&up->pdev->dev); | 482 | pm_runtime_get_sync(up->dev); |
472 | status = check_modem_status(up); | 483 | status = check_modem_status(up); |
473 | pm_runtime_put(&up->pdev->dev); | 484 | pm_runtime_mark_last_busy(up->dev); |
485 | pm_runtime_put_autosuspend(up->dev); | ||
474 | 486 | ||
475 | dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->port.line); | 487 | dev_dbg(up->port.dev, "serial_omap_get_mctrl+%d\n", up->port.line); |
476 | 488 | ||
@@ -487,7 +499,7 @@ static unsigned int serial_omap_get_mctrl(struct uart_port *port) | |||
487 | 499 | ||
488 | static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) | 500 | static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) |
489 | { | 501 | { |
490 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 502 | struct uart_omap_port *up = to_uart_omap_port(port); |
491 | unsigned char mcr = 0; | 503 | unsigned char mcr = 0; |
492 | 504 | ||
493 | dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line); | 505 | dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line); |
@@ -502,20 +514,31 @@ static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
502 | if (mctrl & TIOCM_LOOP) | 514 | if (mctrl & TIOCM_LOOP) |
503 | mcr |= UART_MCR_LOOP; | 515 | mcr |= UART_MCR_LOOP; |
504 | 516 | ||
505 | pm_runtime_get_sync(&up->pdev->dev); | 517 | pm_runtime_get_sync(up->dev); |
506 | up->mcr = serial_in(up, UART_MCR); | 518 | up->mcr = serial_in(up, UART_MCR); |
507 | up->mcr |= mcr; | 519 | up->mcr |= mcr; |
508 | serial_out(up, UART_MCR, up->mcr); | 520 | serial_out(up, UART_MCR, up->mcr); |
509 | pm_runtime_put(&up->pdev->dev); | 521 | pm_runtime_mark_last_busy(up->dev); |
522 | pm_runtime_put_autosuspend(up->dev); | ||
523 | |||
524 | if (gpio_is_valid(up->DTR_gpio) && | ||
525 | !!(mctrl & TIOCM_DTR) != up->DTR_active) { | ||
526 | up->DTR_active = !up->DTR_active; | ||
527 | if (gpio_cansleep(up->DTR_gpio)) | ||
528 | schedule_work(&up->qos_work); | ||
529 | else | ||
530 | gpio_set_value(up->DTR_gpio, | ||
531 | up->DTR_active != up->DTR_inverted); | ||
532 | } | ||
510 | } | 533 | } |
511 | 534 | ||
512 | static void serial_omap_break_ctl(struct uart_port *port, int break_state) | 535 | static void serial_omap_break_ctl(struct uart_port *port, int break_state) |
513 | { | 536 | { |
514 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 537 | struct uart_omap_port *up = to_uart_omap_port(port); |
515 | unsigned long flags = 0; | 538 | unsigned long flags = 0; |
516 | 539 | ||
517 | dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line); | 540 | dev_dbg(up->port.dev, "serial_omap_break_ctl+%d\n", up->port.line); |
518 | pm_runtime_get_sync(&up->pdev->dev); | 541 | pm_runtime_get_sync(up->dev); |
519 | spin_lock_irqsave(&up->port.lock, flags); | 542 | spin_lock_irqsave(&up->port.lock, flags); |
520 | if (break_state == -1) | 543 | if (break_state == -1) |
521 | up->lcr |= UART_LCR_SBC; | 544 | up->lcr |= UART_LCR_SBC; |
@@ -523,12 +546,13 @@ static void serial_omap_break_ctl(struct uart_port *port, int break_state) | |||
523 | up->lcr &= ~UART_LCR_SBC; | 546 | up->lcr &= ~UART_LCR_SBC; |
524 | serial_out(up, UART_LCR, up->lcr); | 547 | serial_out(up, UART_LCR, up->lcr); |
525 | spin_unlock_irqrestore(&up->port.lock, flags); | 548 | spin_unlock_irqrestore(&up->port.lock, flags); |
526 | pm_runtime_put(&up->pdev->dev); | 549 | pm_runtime_mark_last_busy(up->dev); |
550 | pm_runtime_put_autosuspend(up->dev); | ||
527 | } | 551 | } |
528 | 552 | ||
529 | static int serial_omap_startup(struct uart_port *port) | 553 | static int serial_omap_startup(struct uart_port *port) |
530 | { | 554 | { |
531 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 555 | struct uart_omap_port *up = to_uart_omap_port(port); |
532 | unsigned long flags = 0; | 556 | unsigned long flags = 0; |
533 | int retval; | 557 | int retval; |
534 | 558 | ||
@@ -542,7 +566,7 @@ static int serial_omap_startup(struct uart_port *port) | |||
542 | 566 | ||
543 | dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); | 567 | dev_dbg(up->port.dev, "serial_omap_startup+%d\n", up->port.line); |
544 | 568 | ||
545 | pm_runtime_get_sync(&up->pdev->dev); | 569 | pm_runtime_get_sync(up->dev); |
546 | /* | 570 | /* |
547 | * Clear the FIFO buffers and disable them. | 571 | * Clear the FIFO buffers and disable them. |
548 | * (they will be reenabled in set_termios()) | 572 | * (they will be reenabled in set_termios()) |
@@ -573,20 +597,6 @@ static int serial_omap_startup(struct uart_port *port) | |||
573 | spin_unlock_irqrestore(&up->port.lock, flags); | 597 | spin_unlock_irqrestore(&up->port.lock, flags); |
574 | 598 | ||
575 | up->msr_saved_flags = 0; | 599 | up->msr_saved_flags = 0; |
576 | if (up->use_dma) { | ||
577 | free_page((unsigned long)up->port.state->xmit.buf); | ||
578 | up->port.state->xmit.buf = dma_alloc_coherent(NULL, | ||
579 | UART_XMIT_SIZE, | ||
580 | (dma_addr_t *)&(up->uart_dma.tx_buf_dma_phys), | ||
581 | 0); | ||
582 | init_timer(&(up->uart_dma.rx_timer)); | ||
583 | up->uart_dma.rx_timer.function = serial_omap_rxdma_poll; | ||
584 | up->uart_dma.rx_timer.data = up->port.line; | ||
585 | /* Currently the buffer size is 4KB. Can increase it */ | ||
586 | up->uart_dma.rx_buf = dma_alloc_coherent(NULL, | ||
587 | up->uart_dma.rx_buf_size, | ||
588 | (dma_addr_t *)&(up->uart_dma.rx_buf_dma_phys), 0); | ||
589 | } | ||
590 | /* | 600 | /* |
591 | * Finally, enable interrupts. Note: Modem status interrupts | 601 | * Finally, enable interrupts. Note: Modem status interrupts |
592 | * are set via set_termios(), which will be occurring imminently | 602 | * are set via set_termios(), which will be occurring imminently |
@@ -598,20 +608,20 @@ static int serial_omap_startup(struct uart_port *port) | |||
598 | /* Enable module level wake up */ | 608 | /* Enable module level wake up */ |
599 | serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP); | 609 | serial_out(up, UART_OMAP_WER, OMAP_UART_WER_MOD_WKUP); |
600 | 610 | ||
601 | pm_runtime_mark_last_busy(&up->pdev->dev); | 611 | pm_runtime_mark_last_busy(up->dev); |
602 | pm_runtime_put_autosuspend(&up->pdev->dev); | 612 | pm_runtime_put_autosuspend(up->dev); |
603 | up->port_activity = jiffies; | 613 | up->port_activity = jiffies; |
604 | return 0; | 614 | return 0; |
605 | } | 615 | } |
606 | 616 | ||
607 | static void serial_omap_shutdown(struct uart_port *port) | 617 | static void serial_omap_shutdown(struct uart_port *port) |
608 | { | 618 | { |
609 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 619 | struct uart_omap_port *up = to_uart_omap_port(port); |
610 | unsigned long flags = 0; | 620 | unsigned long flags = 0; |
611 | 621 | ||
612 | dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line); | 622 | dev_dbg(up->port.dev, "serial_omap_shutdown+%d\n", up->port.line); |
613 | 623 | ||
614 | pm_runtime_get_sync(&up->pdev->dev); | 624 | pm_runtime_get_sync(up->dev); |
615 | /* | 625 | /* |
616 | * Disable interrupts from this port | 626 | * Disable interrupts from this port |
617 | */ | 627 | */ |
@@ -634,19 +644,9 @@ static void serial_omap_shutdown(struct uart_port *port) | |||
634 | */ | 644 | */ |
635 | if (serial_in(up, UART_LSR) & UART_LSR_DR) | 645 | if (serial_in(up, UART_LSR) & UART_LSR_DR) |
636 | (void) serial_in(up, UART_RX); | 646 | (void) serial_in(up, UART_RX); |
637 | if (up->use_dma) { | ||
638 | dma_free_coherent(up->port.dev, | ||
639 | UART_XMIT_SIZE, up->port.state->xmit.buf, | ||
640 | up->uart_dma.tx_buf_dma_phys); | ||
641 | up->port.state->xmit.buf = NULL; | ||
642 | serial_omap_stop_rx(port); | ||
643 | dma_free_coherent(up->port.dev, | ||
644 | up->uart_dma.rx_buf_size, up->uart_dma.rx_buf, | ||
645 | up->uart_dma.rx_buf_dma_phys); | ||
646 | up->uart_dma.rx_buf = NULL; | ||
647 | } | ||
648 | 647 | ||
649 | pm_runtime_put(&up->pdev->dev); | 648 | pm_runtime_mark_last_busy(up->dev); |
649 | pm_runtime_put_autosuspend(up->dev); | ||
650 | free_irq(up->port.irq, up); | 650 | free_irq(up->port.irq, up); |
651 | } | 651 | } |
652 | 652 | ||
@@ -667,19 +667,19 @@ serial_omap_configure_xonxoff | |||
667 | 667 | ||
668 | /* | 668 | /* |
669 | * IXON Flag: | 669 | * IXON Flag: |
670 | * Enable XON/XOFF flow control on output. | 670 | * Flow control for OMAP.TX |
671 | * Transmit XON1, XOFF1 | 671 | * OMAP.RX should listen for XON/XOFF |
672 | */ | 672 | */ |
673 | if (termios->c_iflag & IXON) | 673 | if (termios->c_iflag & IXON) |
674 | up->efr |= OMAP_UART_SW_TX; | 674 | up->efr |= OMAP_UART_SW_RX; |
675 | 675 | ||
676 | /* | 676 | /* |
677 | * IXOFF Flag: | 677 | * IXOFF Flag: |
678 | * Enable XON/XOFF flow control on input. | 678 | * Flow control for OMAP.RX |
679 | * Receiver compares XON1, XOFF1. | 679 | * OMAP.TX should send XON/XOFF |
680 | */ | 680 | */ |
681 | if (termios->c_iflag & IXOFF) | 681 | if (termios->c_iflag & IXOFF) |
682 | up->efr |= OMAP_UART_SW_RX; | 682 | up->efr |= OMAP_UART_SW_TX; |
683 | 683 | ||
684 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); | 684 | serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); |
685 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); | 685 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); |
@@ -715,13 +715,16 @@ static void serial_omap_uart_qos_work(struct work_struct *work) | |||
715 | qos_work); | 715 | qos_work); |
716 | 716 | ||
717 | pm_qos_update_request(&up->pm_qos_request, up->latency); | 717 | pm_qos_update_request(&up->pm_qos_request, up->latency); |
718 | if (gpio_is_valid(up->DTR_gpio)) | ||
719 | gpio_set_value_cansleep(up->DTR_gpio, | ||
720 | up->DTR_active != up->DTR_inverted); | ||
718 | } | 721 | } |
719 | 722 | ||
720 | static void | 723 | static void |
721 | serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | 724 | serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, |
722 | struct ktermios *old) | 725 | struct ktermios *old) |
723 | { | 726 | { |
724 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 727 | struct uart_omap_port *up = to_uart_omap_port(port); |
725 | unsigned char cval = 0; | 728 | unsigned char cval = 0; |
726 | unsigned char efr = 0; | 729 | unsigned char efr = 0; |
727 | unsigned long flags = 0; | 730 | unsigned long flags = 0; |
@@ -768,14 +771,12 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
768 | 771 | ||
769 | up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | | 772 | up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | |
770 | UART_FCR_ENABLE_FIFO; | 773 | UART_FCR_ENABLE_FIFO; |
771 | if (up->use_dma) | ||
772 | up->fcr |= UART_FCR_DMA_SELECT; | ||
773 | 774 | ||
774 | /* | 775 | /* |
775 | * Ok, we're now changing the port state. Do it with | 776 | * Ok, we're now changing the port state. Do it with |
776 | * interrupts disabled. | 777 | * interrupts disabled. |
777 | */ | 778 | */ |
778 | pm_runtime_get_sync(&up->pdev->dev); | 779 | pm_runtime_get_sync(up->dev); |
779 | spin_lock_irqsave(&up->port.lock, flags); | 780 | spin_lock_irqsave(&up->port.lock, flags); |
780 | 781 | ||
781 | /* | 782 | /* |
@@ -845,14 +846,13 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
845 | 846 | ||
846 | up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; | 847 | up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; |
847 | 848 | ||
848 | if (up->use_dma) { | 849 | /* Set receive FIFO threshold to 16 characters and |
849 | serial_out(up, UART_TI752_TLR, 0); | 850 | * transmit FIFO threshold to 16 spaces |
850 | up->scr |= UART_FCR_TRIGGER_4; | 851 | */ |
851 | } else { | 852 | up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; |
852 | /* Set receive FIFO threshold to 1 byte */ | 853 | up->fcr &= ~OMAP_UART_FCR_TX_FIFO_TRIG_MASK; |
853 | up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; | 854 | up->fcr |= UART_FCR6_R_TRIGGER_16 | UART_FCR6_T_TRIGGER_24 | |
854 | up->fcr |= (0x1 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT); | 855 | UART_FCR_ENABLE_FIFO; |
855 | } | ||
856 | 856 | ||
857 | serial_out(up, UART_FCR, up->fcr); | 857 | serial_out(up, UART_FCR, up->fcr); |
858 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 858 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
@@ -924,20 +924,30 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, | |||
924 | serial_omap_configure_xonxoff(up, termios); | 924 | serial_omap_configure_xonxoff(up, termios); |
925 | 925 | ||
926 | spin_unlock_irqrestore(&up->port.lock, flags); | 926 | spin_unlock_irqrestore(&up->port.lock, flags); |
927 | pm_runtime_put(&up->pdev->dev); | 927 | pm_runtime_mark_last_busy(up->dev); |
928 | pm_runtime_put_autosuspend(up->dev); | ||
928 | dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); | 929 | dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); |
929 | } | 930 | } |
930 | 931 | ||
932 | static int serial_omap_set_wake(struct uart_port *port, unsigned int state) | ||
933 | { | ||
934 | struct uart_omap_port *up = to_uart_omap_port(port); | ||
935 | |||
936 | serial_omap_enable_wakeup(up, state); | ||
937 | |||
938 | return 0; | ||
939 | } | ||
940 | |||
931 | static void | 941 | static void |
932 | serial_omap_pm(struct uart_port *port, unsigned int state, | 942 | serial_omap_pm(struct uart_port *port, unsigned int state, |
933 | unsigned int oldstate) | 943 | unsigned int oldstate) |
934 | { | 944 | { |
935 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 945 | struct uart_omap_port *up = to_uart_omap_port(port); |
936 | unsigned char efr; | 946 | unsigned char efr; |
937 | 947 | ||
938 | dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->port.line); | 948 | dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->port.line); |
939 | 949 | ||
940 | pm_runtime_get_sync(&up->pdev->dev); | 950 | pm_runtime_get_sync(up->dev); |
941 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); | 951 | serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); |
942 | efr = serial_in(up, UART_EFR); | 952 | efr = serial_in(up, UART_EFR); |
943 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); | 953 | serial_out(up, UART_EFR, efr | UART_EFR_ECB); |
@@ -948,14 +958,15 @@ serial_omap_pm(struct uart_port *port, unsigned int state, | |||
948 | serial_out(up, UART_EFR, efr); | 958 | serial_out(up, UART_EFR, efr); |
949 | serial_out(up, UART_LCR, 0); | 959 | serial_out(up, UART_LCR, 0); |
950 | 960 | ||
951 | if (!device_may_wakeup(&up->pdev->dev)) { | 961 | if (!device_may_wakeup(up->dev)) { |
952 | if (!state) | 962 | if (!state) |
953 | pm_runtime_forbid(&up->pdev->dev); | 963 | pm_runtime_forbid(up->dev); |
954 | else | 964 | else |
955 | pm_runtime_allow(&up->pdev->dev); | 965 | pm_runtime_allow(up->dev); |
956 | } | 966 | } |
957 | 967 | ||
958 | pm_runtime_put(&up->pdev->dev); | 968 | pm_runtime_mark_last_busy(up->dev); |
969 | pm_runtime_put_autosuspend(up->dev); | ||
959 | } | 970 | } |
960 | 971 | ||
961 | static void serial_omap_release_port(struct uart_port *port) | 972 | static void serial_omap_release_port(struct uart_port *port) |
@@ -971,7 +982,7 @@ static int serial_omap_request_port(struct uart_port *port) | |||
971 | 982 | ||
972 | static void serial_omap_config_port(struct uart_port *port, int flags) | 983 | static void serial_omap_config_port(struct uart_port *port, int flags) |
973 | { | 984 | { |
974 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 985 | struct uart_omap_port *up = to_uart_omap_port(port); |
975 | 986 | ||
976 | dev_dbg(up->port.dev, "serial_omap_config_port+%d\n", | 987 | dev_dbg(up->port.dev, "serial_omap_config_port+%d\n", |
977 | up->port.line); | 988 | up->port.line); |
@@ -989,7 +1000,7 @@ serial_omap_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
989 | static const char * | 1000 | static const char * |
990 | serial_omap_type(struct uart_port *port) | 1001 | serial_omap_type(struct uart_port *port) |
991 | { | 1002 | { |
992 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 1003 | struct uart_omap_port *up = to_uart_omap_port(port); |
993 | 1004 | ||
994 | dev_dbg(up->port.dev, "serial_omap_type+%d\n", up->port.line); | 1005 | dev_dbg(up->port.dev, "serial_omap_type+%d\n", up->port.line); |
995 | return up->name; | 1006 | return up->name; |
@@ -1032,26 +1043,33 @@ static inline void wait_for_xmitr(struct uart_omap_port *up) | |||
1032 | 1043 | ||
1033 | static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch) | 1044 | static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch) |
1034 | { | 1045 | { |
1035 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 1046 | struct uart_omap_port *up = to_uart_omap_port(port); |
1036 | 1047 | ||
1037 | pm_runtime_get_sync(&up->pdev->dev); | 1048 | pm_runtime_get_sync(up->dev); |
1038 | wait_for_xmitr(up); | 1049 | wait_for_xmitr(up); |
1039 | serial_out(up, UART_TX, ch); | 1050 | serial_out(up, UART_TX, ch); |
1040 | pm_runtime_put(&up->pdev->dev); | 1051 | pm_runtime_mark_last_busy(up->dev); |
1052 | pm_runtime_put_autosuspend(up->dev); | ||
1041 | } | 1053 | } |
1042 | 1054 | ||
1043 | static int serial_omap_poll_get_char(struct uart_port *port) | 1055 | static int serial_omap_poll_get_char(struct uart_port *port) |
1044 | { | 1056 | { |
1045 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 1057 | struct uart_omap_port *up = to_uart_omap_port(port); |
1046 | unsigned int status; | 1058 | unsigned int status; |
1047 | 1059 | ||
1048 | pm_runtime_get_sync(&up->pdev->dev); | 1060 | pm_runtime_get_sync(up->dev); |
1049 | status = serial_in(up, UART_LSR); | 1061 | status = serial_in(up, UART_LSR); |
1050 | if (!(status & UART_LSR_DR)) | 1062 | if (!(status & UART_LSR_DR)) { |
1051 | return NO_POLL_CHAR; | 1063 | status = NO_POLL_CHAR; |
1064 | goto out; | ||
1065 | } | ||
1052 | 1066 | ||
1053 | status = serial_in(up, UART_RX); | 1067 | status = serial_in(up, UART_RX); |
1054 | pm_runtime_put(&up->pdev->dev); | 1068 | |
1069 | out: | ||
1070 | pm_runtime_mark_last_busy(up->dev); | ||
1071 | pm_runtime_put_autosuspend(up->dev); | ||
1072 | |||
1055 | return status; | 1073 | return status; |
1056 | } | 1074 | } |
1057 | 1075 | ||
@@ -1065,7 +1083,7 @@ static struct uart_driver serial_omap_reg; | |||
1065 | 1083 | ||
1066 | static void serial_omap_console_putchar(struct uart_port *port, int ch) | 1084 | static void serial_omap_console_putchar(struct uart_port *port, int ch) |
1067 | { | 1085 | { |
1068 | struct uart_omap_port *up = (struct uart_omap_port *)port; | 1086 | struct uart_omap_port *up = to_uart_omap_port(port); |
1069 | 1087 | ||
1070 | wait_for_xmitr(up); | 1088 | wait_for_xmitr(up); |
1071 | serial_out(up, UART_TX, ch); | 1089 | serial_out(up, UART_TX, ch); |
@@ -1080,7 +1098,7 @@ serial_omap_console_write(struct console *co, const char *s, | |||
1080 | unsigned int ier; | 1098 | unsigned int ier; |
1081 | int locked = 1; | 1099 | int locked = 1; |
1082 | 1100 | ||
1083 | pm_runtime_get_sync(&up->pdev->dev); | 1101 | pm_runtime_get_sync(up->dev); |
1084 | 1102 | ||
1085 | local_irq_save(flags); | 1103 | local_irq_save(flags); |
1086 | if (up->port.sysrq) | 1104 | if (up->port.sysrq) |
@@ -1114,8 +1132,8 @@ serial_omap_console_write(struct console *co, const char *s, | |||
1114 | if (up->msr_saved_flags) | 1132 | if (up->msr_saved_flags) |
1115 | check_modem_status(up); | 1133 | check_modem_status(up); |
1116 | 1134 | ||
1117 | pm_runtime_mark_last_busy(&up->pdev->dev); | 1135 | pm_runtime_mark_last_busy(up->dev); |
1118 | pm_runtime_put_autosuspend(&up->pdev->dev); | 1136 | pm_runtime_put_autosuspend(up->dev); |
1119 | if (locked) | 1137 | if (locked) |
1120 | spin_unlock(&up->port.lock); | 1138 | spin_unlock(&up->port.lock); |
1121 | local_irq_restore(flags); | 1139 | local_irq_restore(flags); |
@@ -1179,6 +1197,7 @@ static struct uart_ops serial_omap_pops = { | |||
1179 | .shutdown = serial_omap_shutdown, | 1197 | .shutdown = serial_omap_shutdown, |
1180 | .set_termios = serial_omap_set_termios, | 1198 | .set_termios = serial_omap_set_termios, |
1181 | .pm = serial_omap_pm, | 1199 | .pm = serial_omap_pm, |
1200 | .set_wake = serial_omap_set_wake, | ||
1182 | .type = serial_omap_type, | 1201 | .type = serial_omap_type, |
1183 | .release_port = serial_omap_release_port, | 1202 | .release_port = serial_omap_release_port, |
1184 | .request_port = serial_omap_request_port, | 1203 | .request_port = serial_omap_request_port, |
@@ -1221,150 +1240,7 @@ static int serial_omap_resume(struct device *dev) | |||
1221 | } | 1240 | } |
1222 | #endif | 1241 | #endif |
1223 | 1242 | ||
1224 | static void serial_omap_rxdma_poll(unsigned long uart_no) | 1243 | static void __devinit omap_serial_fill_features_erratas(struct uart_omap_port *up) |
1225 | { | ||
1226 | struct uart_omap_port *up = ui[uart_no]; | ||
1227 | unsigned int curr_dma_pos, curr_transmitted_size; | ||
1228 | int ret = 0; | ||
1229 | |||
1230 | curr_dma_pos = omap_get_dma_dst_pos(up->uart_dma.rx_dma_channel); | ||
1231 | if ((curr_dma_pos == up->uart_dma.prev_rx_dma_pos) || | ||
1232 | (curr_dma_pos == 0)) { | ||
1233 | if (jiffies_to_msecs(jiffies - up->port_activity) < | ||
1234 | up->uart_dma.rx_timeout) { | ||
1235 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
1236 | usecs_to_jiffies(up->uart_dma.rx_poll_rate)); | ||
1237 | } else { | ||
1238 | serial_omap_stop_rxdma(up); | ||
1239 | up->ier |= (UART_IER_RDI | UART_IER_RLSI); | ||
1240 | serial_out(up, UART_IER, up->ier); | ||
1241 | } | ||
1242 | return; | ||
1243 | } | ||
1244 | |||
1245 | curr_transmitted_size = curr_dma_pos - | ||
1246 | up->uart_dma.prev_rx_dma_pos; | ||
1247 | up->port.icount.rx += curr_transmitted_size; | ||
1248 | tty_insert_flip_string(up->port.state->port.tty, | ||
1249 | up->uart_dma.rx_buf + | ||
1250 | (up->uart_dma.prev_rx_dma_pos - | ||
1251 | up->uart_dma.rx_buf_dma_phys), | ||
1252 | curr_transmitted_size); | ||
1253 | tty_flip_buffer_push(up->port.state->port.tty); | ||
1254 | up->uart_dma.prev_rx_dma_pos = curr_dma_pos; | ||
1255 | if (up->uart_dma.rx_buf_size + | ||
1256 | up->uart_dma.rx_buf_dma_phys == curr_dma_pos) { | ||
1257 | ret = serial_omap_start_rxdma(up); | ||
1258 | if (ret < 0) { | ||
1259 | serial_omap_stop_rxdma(up); | ||
1260 | up->ier |= (UART_IER_RDI | UART_IER_RLSI); | ||
1261 | serial_out(up, UART_IER, up->ier); | ||
1262 | } | ||
1263 | } else { | ||
1264 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
1265 | usecs_to_jiffies(up->uart_dma.rx_poll_rate)); | ||
1266 | } | ||
1267 | up->port_activity = jiffies; | ||
1268 | } | ||
1269 | |||
1270 | static void uart_rx_dma_callback(int lch, u16 ch_status, void *data) | ||
1271 | { | ||
1272 | return; | ||
1273 | } | ||
1274 | |||
1275 | static int serial_omap_start_rxdma(struct uart_omap_port *up) | ||
1276 | { | ||
1277 | int ret = 0; | ||
1278 | |||
1279 | if (up->uart_dma.rx_dma_channel == -1) { | ||
1280 | pm_runtime_get_sync(&up->pdev->dev); | ||
1281 | ret = omap_request_dma(up->uart_dma.uart_dma_rx, | ||
1282 | "UART Rx DMA", | ||
1283 | (void *)uart_rx_dma_callback, up, | ||
1284 | &(up->uart_dma.rx_dma_channel)); | ||
1285 | if (ret < 0) | ||
1286 | return ret; | ||
1287 | |||
1288 | omap_set_dma_src_params(up->uart_dma.rx_dma_channel, 0, | ||
1289 | OMAP_DMA_AMODE_CONSTANT, | ||
1290 | up->uart_dma.uart_base, 0, 0); | ||
1291 | omap_set_dma_dest_params(up->uart_dma.rx_dma_channel, 0, | ||
1292 | OMAP_DMA_AMODE_POST_INC, | ||
1293 | up->uart_dma.rx_buf_dma_phys, 0, 0); | ||
1294 | omap_set_dma_transfer_params(up->uart_dma.rx_dma_channel, | ||
1295 | OMAP_DMA_DATA_TYPE_S8, | ||
1296 | up->uart_dma.rx_buf_size, 1, | ||
1297 | OMAP_DMA_SYNC_ELEMENT, | ||
1298 | up->uart_dma.uart_dma_rx, 0); | ||
1299 | } | ||
1300 | up->uart_dma.prev_rx_dma_pos = up->uart_dma.rx_buf_dma_phys; | ||
1301 | /* FIXME: Cache maintenance needed here? */ | ||
1302 | omap_start_dma(up->uart_dma.rx_dma_channel); | ||
1303 | mod_timer(&up->uart_dma.rx_timer, jiffies + | ||
1304 | usecs_to_jiffies(up->uart_dma.rx_poll_rate)); | ||
1305 | up->uart_dma.rx_dma_used = true; | ||
1306 | return ret; | ||
1307 | } | ||
1308 | |||
1309 | static void serial_omap_continue_tx(struct uart_omap_port *up) | ||
1310 | { | ||
1311 | struct circ_buf *xmit = &up->port.state->xmit; | ||
1312 | unsigned int start = up->uart_dma.tx_buf_dma_phys | ||
1313 | + (xmit->tail & (UART_XMIT_SIZE - 1)); | ||
1314 | |||
1315 | if (uart_circ_empty(xmit)) | ||
1316 | return; | ||
1317 | |||
1318 | up->uart_dma.tx_buf_size = uart_circ_chars_pending(xmit); | ||
1319 | /* | ||
1320 | * It is a circular buffer. See if the buffer has wounded back. | ||
1321 | * If yes it will have to be transferred in two separate dma | ||
1322 | * transfers | ||
1323 | */ | ||
1324 | if (start + up->uart_dma.tx_buf_size >= | ||
1325 | up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) | ||
1326 | up->uart_dma.tx_buf_size = | ||
1327 | (up->uart_dma.tx_buf_dma_phys + UART_XMIT_SIZE) - start; | ||
1328 | omap_set_dma_dest_params(up->uart_dma.tx_dma_channel, 0, | ||
1329 | OMAP_DMA_AMODE_CONSTANT, | ||
1330 | up->uart_dma.uart_base, 0, 0); | ||
1331 | omap_set_dma_src_params(up->uart_dma.tx_dma_channel, 0, | ||
1332 | OMAP_DMA_AMODE_POST_INC, start, 0, 0); | ||
1333 | omap_set_dma_transfer_params(up->uart_dma.tx_dma_channel, | ||
1334 | OMAP_DMA_DATA_TYPE_S8, | ||
1335 | up->uart_dma.tx_buf_size, 1, | ||
1336 | OMAP_DMA_SYNC_ELEMENT, | ||
1337 | up->uart_dma.uart_dma_tx, 0); | ||
1338 | /* FIXME: Cache maintenance needed here? */ | ||
1339 | omap_start_dma(up->uart_dma.tx_dma_channel); | ||
1340 | } | ||
1341 | |||
1342 | static void uart_tx_dma_callback(int lch, u16 ch_status, void *data) | ||
1343 | { | ||
1344 | struct uart_omap_port *up = (struct uart_omap_port *)data; | ||
1345 | struct circ_buf *xmit = &up->port.state->xmit; | ||
1346 | |||
1347 | xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \ | ||
1348 | (UART_XMIT_SIZE - 1); | ||
1349 | up->port.icount.tx += up->uart_dma.tx_buf_size; | ||
1350 | |||
1351 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
1352 | uart_write_wakeup(&up->port); | ||
1353 | |||
1354 | if (uart_circ_empty(xmit)) { | ||
1355 | spin_lock(&(up->uart_dma.tx_lock)); | ||
1356 | serial_omap_stop_tx(&up->port); | ||
1357 | up->uart_dma.tx_dma_used = false; | ||
1358 | spin_unlock(&(up->uart_dma.tx_lock)); | ||
1359 | } else { | ||
1360 | omap_stop_dma(up->uart_dma.tx_dma_channel); | ||
1361 | serial_omap_continue_tx(up); | ||
1362 | } | ||
1363 | up->port_activity = jiffies; | ||
1364 | return; | ||
1365 | } | ||
1366 | |||
1367 | static void omap_serial_fill_features_erratas(struct uart_omap_port *up) | ||
1368 | { | 1244 | { |
1369 | u32 mvr, scheme; | 1245 | u32 mvr, scheme; |
1370 | u16 revision, major, minor; | 1246 | u16 revision, major, minor; |
@@ -1389,7 +1265,7 @@ static void omap_serial_fill_features_erratas(struct uart_omap_port *up) | |||
1389 | minor = (mvr & OMAP_UART_MVR_MIN_MASK); | 1265 | minor = (mvr & OMAP_UART_MVR_MIN_MASK); |
1390 | break; | 1266 | break; |
1391 | default: | 1267 | default: |
1392 | dev_warn(&up->pdev->dev, | 1268 | dev_warn(up->dev, |
1393 | "Unknown %s revision, defaulting to highest\n", | 1269 | "Unknown %s revision, defaulting to highest\n", |
1394 | up->name); | 1270 | up->name); |
1395 | /* highest possible revision */ | 1271 | /* highest possible revision */ |
@@ -1417,7 +1293,7 @@ static void omap_serial_fill_features_erratas(struct uart_omap_port *up) | |||
1417 | } | 1293 | } |
1418 | } | 1294 | } |
1419 | 1295 | ||
1420 | static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) | 1296 | static __devinit struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) |
1421 | { | 1297 | { |
1422 | struct omap_uart_port_info *omap_up_info; | 1298 | struct omap_uart_port_info *omap_up_info; |
1423 | 1299 | ||
@@ -1430,12 +1306,12 @@ static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) | |||
1430 | return omap_up_info; | 1306 | return omap_up_info; |
1431 | } | 1307 | } |
1432 | 1308 | ||
1433 | static int serial_omap_probe(struct platform_device *pdev) | 1309 | static int __devinit serial_omap_probe(struct platform_device *pdev) |
1434 | { | 1310 | { |
1435 | struct uart_omap_port *up; | 1311 | struct uart_omap_port *up; |
1436 | struct resource *mem, *irq, *dma_tx, *dma_rx; | 1312 | struct resource *mem, *irq; |
1437 | struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; | 1313 | struct omap_uart_port_info *omap_up_info = pdev->dev.platform_data; |
1438 | int ret = -ENOSPC; | 1314 | int ret; |
1439 | 1315 | ||
1440 | if (pdev->dev.of_node) | 1316 | if (pdev->dev.of_node) |
1441 | omap_up_info = of_get_uart_port_info(&pdev->dev); | 1317 | omap_up_info = of_get_uart_port_info(&pdev->dev); |
@@ -1458,19 +1334,30 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1458 | return -EBUSY; | 1334 | return -EBUSY; |
1459 | } | 1335 | } |
1460 | 1336 | ||
1461 | dma_rx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx"); | 1337 | if (gpio_is_valid(omap_up_info->DTR_gpio) && |
1462 | if (!dma_rx) | 1338 | omap_up_info->DTR_present) { |
1463 | return -ENXIO; | 1339 | ret = gpio_request(omap_up_info->DTR_gpio, "omap-serial"); |
1464 | 1340 | if (ret < 0) | |
1465 | dma_tx = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx"); | 1341 | return ret; |
1466 | if (!dma_tx) | 1342 | ret = gpio_direction_output(omap_up_info->DTR_gpio, |
1467 | return -ENXIO; | 1343 | omap_up_info->DTR_inverted); |
1344 | if (ret < 0) | ||
1345 | return ret; | ||
1346 | } | ||
1468 | 1347 | ||
1469 | up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); | 1348 | up = devm_kzalloc(&pdev->dev, sizeof(*up), GFP_KERNEL); |
1470 | if (!up) | 1349 | if (!up) |
1471 | return -ENOMEM; | 1350 | return -ENOMEM; |
1472 | 1351 | ||
1473 | up->pdev = pdev; | 1352 | if (gpio_is_valid(omap_up_info->DTR_gpio) && |
1353 | omap_up_info->DTR_present) { | ||
1354 | up->DTR_gpio = omap_up_info->DTR_gpio; | ||
1355 | up->DTR_inverted = omap_up_info->DTR_inverted; | ||
1356 | } else | ||
1357 | up->DTR_gpio = -EINVAL; | ||
1358 | up->DTR_active = 0; | ||
1359 | |||
1360 | up->dev = &pdev->dev; | ||
1474 | up->port.dev = &pdev->dev; | 1361 | up->port.dev = &pdev->dev; |
1475 | up->port.type = PORT_OMAP; | 1362 | up->port.type = PORT_OMAP; |
1476 | up->port.iotype = UPIO_MEM; | 1363 | up->port.iotype = UPIO_MEM; |
@@ -1492,6 +1379,13 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1492 | goto err_port_line; | 1379 | goto err_port_line; |
1493 | } | 1380 | } |
1494 | 1381 | ||
1382 | up->pins = devm_pinctrl_get_select_default(&pdev->dev); | ||
1383 | if (IS_ERR(up->pins)) { | ||
1384 | dev_warn(&pdev->dev, "did not get pins for uart%i error: %li\n", | ||
1385 | up->port.line, PTR_ERR(up->pins)); | ||
1386 | up->pins = NULL; | ||
1387 | } | ||
1388 | |||
1495 | sprintf(up->name, "OMAP UART%d", up->port.line); | 1389 | sprintf(up->name, "OMAP UART%d", up->port.line); |
1496 | up->port.mapbase = mem->start; | 1390 | up->port.mapbase = mem->start; |
1497 | up->port.membase = devm_ioremap(&pdev->dev, mem->start, | 1391 | up->port.membase = devm_ioremap(&pdev->dev, mem->start, |
@@ -1509,20 +1403,6 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1509 | dev_warn(&pdev->dev, "No clock speed specified: using default:" | 1403 | dev_warn(&pdev->dev, "No clock speed specified: using default:" |
1510 | "%d\n", DEFAULT_CLK_SPEED); | 1404 | "%d\n", DEFAULT_CLK_SPEED); |
1511 | } | 1405 | } |
1512 | up->uart_dma.uart_base = mem->start; | ||
1513 | |||
1514 | if (omap_up_info->dma_enabled) { | ||
1515 | up->uart_dma.uart_dma_tx = dma_tx->start; | ||
1516 | up->uart_dma.uart_dma_rx = dma_rx->start; | ||
1517 | up->use_dma = 1; | ||
1518 | up->uart_dma.rx_buf_size = omap_up_info->dma_rx_buf_size; | ||
1519 | up->uart_dma.rx_timeout = omap_up_info->dma_rx_timeout; | ||
1520 | up->uart_dma.rx_poll_rate = omap_up_info->dma_rx_poll_rate; | ||
1521 | spin_lock_init(&(up->uart_dma.tx_lock)); | ||
1522 | spin_lock_init(&(up->uart_dma.rx_lock)); | ||
1523 | up->uart_dma.tx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
1524 | up->uart_dma.rx_dma_channel = OMAP_UART_DMA_CH_FREE; | ||
1525 | } | ||
1526 | 1406 | ||
1527 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | 1407 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; |
1528 | up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | 1408 | up->calc_latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; |
@@ -1531,12 +1411,13 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1531 | serial_omap_uart_wq = create_singlethread_workqueue(up->name); | 1411 | serial_omap_uart_wq = create_singlethread_workqueue(up->name); |
1532 | INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); | 1412 | INIT_WORK(&up->qos_work, serial_omap_uart_qos_work); |
1533 | 1413 | ||
1414 | platform_set_drvdata(pdev, up); | ||
1415 | pm_runtime_enable(&pdev->dev); | ||
1534 | pm_runtime_use_autosuspend(&pdev->dev); | 1416 | pm_runtime_use_autosuspend(&pdev->dev); |
1535 | pm_runtime_set_autosuspend_delay(&pdev->dev, | 1417 | pm_runtime_set_autosuspend_delay(&pdev->dev, |
1536 | omap_up_info->autosuspend_timeout); | 1418 | omap_up_info->autosuspend_timeout); |
1537 | 1419 | ||
1538 | pm_runtime_irq_safe(&pdev->dev); | 1420 | pm_runtime_irq_safe(&pdev->dev); |
1539 | pm_runtime_enable(&pdev->dev); | ||
1540 | pm_runtime_get_sync(&pdev->dev); | 1421 | pm_runtime_get_sync(&pdev->dev); |
1541 | 1422 | ||
1542 | omap_serial_fill_features_erratas(up); | 1423 | omap_serial_fill_features_erratas(up); |
@@ -1548,8 +1429,8 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1548 | if (ret != 0) | 1429 | if (ret != 0) |
1549 | goto err_add_port; | 1430 | goto err_add_port; |
1550 | 1431 | ||
1551 | pm_runtime_put(&pdev->dev); | 1432 | pm_runtime_mark_last_busy(up->dev); |
1552 | platform_set_drvdata(pdev, up); | 1433 | pm_runtime_put_autosuspend(up->dev); |
1553 | return 0; | 1434 | return 0; |
1554 | 1435 | ||
1555 | err_add_port: | 1436 | err_add_port: |
@@ -1562,17 +1443,15 @@ err_port_line: | |||
1562 | return ret; | 1443 | return ret; |
1563 | } | 1444 | } |
1564 | 1445 | ||
1565 | static int serial_omap_remove(struct platform_device *dev) | 1446 | static int __devexit serial_omap_remove(struct platform_device *dev) |
1566 | { | 1447 | { |
1567 | struct uart_omap_port *up = platform_get_drvdata(dev); | 1448 | struct uart_omap_port *up = platform_get_drvdata(dev); |
1568 | 1449 | ||
1569 | if (up) { | 1450 | pm_runtime_put_sync(up->dev); |
1570 | pm_runtime_disable(&up->pdev->dev); | 1451 | pm_runtime_disable(up->dev); |
1571 | uart_remove_one_port(&serial_omap_reg, &up->port); | 1452 | uart_remove_one_port(&serial_omap_reg, &up->port); |
1572 | pm_qos_remove_request(&up->pm_qos_request); | 1453 | pm_qos_remove_request(&up->pm_qos_request); |
1573 | } | ||
1574 | 1454 | ||
1575 | platform_set_drvdata(dev, NULL); | ||
1576 | return 0; | 1455 | return 0; |
1577 | } | 1456 | } |
1578 | 1457 | ||
@@ -1602,7 +1481,7 @@ static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1) | |||
1602 | timeout--; | 1481 | timeout--; |
1603 | if (!timeout) { | 1482 | if (!timeout) { |
1604 | /* Should *never* happen. we warn and carry on */ | 1483 | /* Should *never* happen. we warn and carry on */ |
1605 | dev_crit(&up->pdev->dev, "Errata i202: timedout %x\n", | 1484 | dev_crit(up->dev, "Errata i202: timedout %x\n", |
1606 | serial_in(up, UART_LSR)); | 1485 | serial_in(up, UART_LSR)); |
1607 | break; | 1486 | break; |
1608 | } | 1487 | } |
@@ -1648,29 +1527,23 @@ static int serial_omap_runtime_suspend(struct device *dev) | |||
1648 | if (!up) | 1527 | if (!up) |
1649 | return -EINVAL; | 1528 | return -EINVAL; |
1650 | 1529 | ||
1651 | if (!pdata || !pdata->enable_wakeup) | 1530 | if (!pdata) |
1652 | return 0; | 1531 | return 0; |
1653 | 1532 | ||
1654 | if (pdata->get_context_loss_count) | 1533 | up->context_loss_cnt = serial_omap_get_context_loss_count(up); |
1655 | up->context_loss_cnt = pdata->get_context_loss_count(dev); | ||
1656 | 1534 | ||
1657 | if (device_may_wakeup(dev)) { | 1535 | if (device_may_wakeup(dev)) { |
1658 | if (!up->wakeups_enabled) { | 1536 | if (!up->wakeups_enabled) { |
1659 | pdata->enable_wakeup(up->pdev, true); | 1537 | serial_omap_enable_wakeup(up, true); |
1660 | up->wakeups_enabled = true; | 1538 | up->wakeups_enabled = true; |
1661 | } | 1539 | } |
1662 | } else { | 1540 | } else { |
1663 | if (up->wakeups_enabled) { | 1541 | if (up->wakeups_enabled) { |
1664 | pdata->enable_wakeup(up->pdev, false); | 1542 | serial_omap_enable_wakeup(up, false); |
1665 | up->wakeups_enabled = false; | 1543 | up->wakeups_enabled = false; |
1666 | } | 1544 | } |
1667 | } | 1545 | } |
1668 | 1546 | ||
1669 | /* Errata i291 */ | ||
1670 | if (up->use_dma && pdata->set_forceidle && | ||
1671 | (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) | ||
1672 | pdata->set_forceidle(up->pdev); | ||
1673 | |||
1674 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | 1547 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; |
1675 | schedule_work(&up->qos_work); | 1548 | schedule_work(&up->qos_work); |
1676 | 1549 | ||
@@ -1683,17 +1556,10 @@ static int serial_omap_runtime_resume(struct device *dev) | |||
1683 | struct omap_uart_port_info *pdata = dev->platform_data; | 1556 | struct omap_uart_port_info *pdata = dev->platform_data; |
1684 | 1557 | ||
1685 | if (up && pdata) { | 1558 | if (up && pdata) { |
1686 | if (pdata->get_context_loss_count) { | 1559 | u32 loss_cnt = serial_omap_get_context_loss_count(up); |
1687 | u32 loss_cnt = pdata->get_context_loss_count(dev); | ||
1688 | 1560 | ||
1689 | if (up->context_loss_cnt != loss_cnt) | 1561 | if (up->context_loss_cnt != loss_cnt) |
1690 | serial_omap_restore_context(up); | 1562 | serial_omap_restore_context(up); |
1691 | } | ||
1692 | |||
1693 | /* Errata i291 */ | ||
1694 | if (up->use_dma && pdata->set_noidle && | ||
1695 | (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE)) | ||
1696 | pdata->set_noidle(up->pdev); | ||
1697 | 1563 | ||
1698 | up->latency = up->calc_latency; | 1564 | up->latency = up->calc_latency; |
1699 | schedule_work(&up->qos_work); | 1565 | schedule_work(&up->qos_work); |
@@ -1721,7 +1587,7 @@ MODULE_DEVICE_TABLE(of, omap_serial_of_match); | |||
1721 | 1587 | ||
1722 | static struct platform_driver serial_omap_driver = { | 1588 | static struct platform_driver serial_omap_driver = { |
1723 | .probe = serial_omap_probe, | 1589 | .probe = serial_omap_probe, |
1724 | .remove = serial_omap_remove, | 1590 | .remove = __devexit_p(serial_omap_remove), |
1725 | .driver = { | 1591 | .driver = { |
1726 | .name = DRIVER_NAME, | 1592 | .name = DRIVER_NAME, |
1727 | .pm = &serial_omap_dev_pm_ops, | 1593 | .pm = &serial_omap_dev_pm_ops, |
diff --git a/drivers/tty/serial/pch_uart.c b/drivers/tty/serial/pch_uart.c index 558ce8509a9a..4cd6c2381528 100644 --- a/drivers/tty/serial/pch_uart.c +++ b/drivers/tty/serial/pch_uart.c | |||
@@ -979,6 +979,10 @@ static unsigned int dma_handle_tx(struct eg20t_port *priv) | |||
979 | priv->tx_dma_use = 1; | 979 | priv->tx_dma_use = 1; |
980 | 980 | ||
981 | priv->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); | 981 | priv->sg_tx_p = kzalloc(sizeof(struct scatterlist)*num, GFP_ATOMIC); |
982 | if (!priv->sg_tx_p) { | ||
983 | dev_err(priv->port.dev, "%s:kzalloc Failed\n", __func__); | ||
984 | return 0; | ||
985 | } | ||
982 | 986 | ||
983 | sg_init_table(priv->sg_tx_p, num); /* Initialize SG table */ | 987 | sg_init_table(priv->sg_tx_p, num); /* Initialize SG table */ |
984 | sg = priv->sg_tx_p; | 988 | sg = priv->sg_tx_p; |
diff --git a/drivers/tty/serial/pxa.c b/drivers/tty/serial/pxa.c index 5847a4b855f7..9033fc6e0e4e 100644 --- a/drivers/tty/serial/pxa.c +++ b/drivers/tty/serial/pxa.c | |||
@@ -670,9 +670,19 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
670 | { | 670 | { |
671 | struct uart_pxa_port *up = serial_pxa_ports[co->index]; | 671 | struct uart_pxa_port *up = serial_pxa_ports[co->index]; |
672 | unsigned int ier; | 672 | unsigned int ier; |
673 | unsigned long flags; | ||
674 | int locked = 1; | ||
673 | 675 | ||
674 | clk_prepare_enable(up->clk); | 676 | clk_prepare_enable(up->clk); |
675 | 677 | ||
678 | local_irq_save(flags); | ||
679 | if (up->port.sysrq) | ||
680 | locked = 0; | ||
681 | else if (oops_in_progress) | ||
682 | locked = spin_trylock(&up->port.lock); | ||
683 | else | ||
684 | spin_lock(&up->port.lock); | ||
685 | |||
676 | /* | 686 | /* |
677 | * First save the IER then disable the interrupts | 687 | * First save the IER then disable the interrupts |
678 | */ | 688 | */ |
@@ -688,6 +698,10 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count) | |||
688 | wait_for_xmitr(up); | 698 | wait_for_xmitr(up); |
689 | serial_out(up, UART_IER, ier); | 699 | serial_out(up, UART_IER, ier); |
690 | 700 | ||
701 | if (locked) | ||
702 | spin_unlock(&up->port.lock); | ||
703 | local_irq_restore(flags); | ||
704 | |||
691 | clk_disable_unprepare(up->clk); | 705 | clk_disable_unprepare(up->clk); |
692 | } | 706 | } |
693 | 707 | ||
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 02d07bfcfa8a..bdaa06f3ab69 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c | |||
@@ -82,7 +82,7 @@ static inline const char *s3c24xx_serial_portname(struct uart_port *port) | |||
82 | 82 | ||
83 | static int s3c24xx_serial_txempty_nofifo(struct uart_port *port) | 83 | static int s3c24xx_serial_txempty_nofifo(struct uart_port *port) |
84 | { | 84 | { |
85 | return (rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE); | 85 | return rd_regl(port, S3C2410_UTRSTAT) & S3C2410_UTRSTAT_TXE; |
86 | } | 86 | } |
87 | 87 | ||
88 | /* | 88 | /* |
@@ -268,7 +268,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) | |||
268 | dbg("break!\n"); | 268 | dbg("break!\n"); |
269 | port->icount.brk++; | 269 | port->icount.brk++; |
270 | if (uart_handle_break(port)) | 270 | if (uart_handle_break(port)) |
271 | goto ignore_char; | 271 | goto ignore_char; |
272 | } | 272 | } |
273 | 273 | ||
274 | if (uerstat & S3C2410_UERSTAT_FRAME) | 274 | if (uerstat & S3C2410_UERSTAT_FRAME) |
@@ -459,7 +459,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) | |||
459 | s3c24xx_serial_portname(port), ourport); | 459 | s3c24xx_serial_portname(port), ourport); |
460 | 460 | ||
461 | if (ret != 0) { | 461 | if (ret != 0) { |
462 | printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq); | 462 | dev_err(port->dev, "cannot get irq %d\n", ourport->rx_irq); |
463 | return ret; | 463 | return ret; |
464 | } | 464 | } |
465 | 465 | ||
@@ -473,7 +473,7 @@ static int s3c24xx_serial_startup(struct uart_port *port) | |||
473 | s3c24xx_serial_portname(port), ourport); | 473 | s3c24xx_serial_portname(port), ourport); |
474 | 474 | ||
475 | if (ret) { | 475 | if (ret) { |
476 | printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq); | 476 | dev_err(port->dev, "cannot get irq %d\n", ourport->tx_irq); |
477 | goto err; | 477 | goto err; |
478 | } | 478 | } |
479 | 479 | ||
@@ -502,7 +502,7 @@ static int s3c64xx_serial_startup(struct uart_port *port) | |||
502 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, | 502 | ret = request_irq(port->irq, s3c64xx_serial_handle_irq, IRQF_SHARED, |
503 | s3c24xx_serial_portname(port), ourport); | 503 | s3c24xx_serial_portname(port), ourport); |
504 | if (ret) { | 504 | if (ret) { |
505 | printk(KERN_ERR "cannot get irq %d\n", port->irq); | 505 | dev_err(port->dev, "cannot get irq %d\n", port->irq); |
506 | return ret; | 506 | return ret; |
507 | } | 507 | } |
508 | 508 | ||
@@ -529,7 +529,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, | |||
529 | 529 | ||
530 | switch (level) { | 530 | switch (level) { |
531 | case 3: | 531 | case 3: |
532 | if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL) | 532 | if (!IS_ERR(ourport->baudclk)) |
533 | clk_disable(ourport->baudclk); | 533 | clk_disable(ourport->baudclk); |
534 | 534 | ||
535 | clk_disable(ourport->clk); | 535 | clk_disable(ourport->clk); |
@@ -538,12 +538,12 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level, | |||
538 | case 0: | 538 | case 0: |
539 | clk_enable(ourport->clk); | 539 | clk_enable(ourport->clk); |
540 | 540 | ||
541 | if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL) | 541 | if (!IS_ERR(ourport->baudclk)) |
542 | clk_enable(ourport->baudclk); | 542 | clk_enable(ourport->baudclk); |
543 | 543 | ||
544 | break; | 544 | break; |
545 | default: | 545 | default: |
546 | printk(KERN_ERR "s3c24xx_serial: unknown pm %d\n", level); | 546 | dev_err(port->dev, "s3c24xx_serial: unknown pm %d\n", level); |
547 | } | 547 | } |
548 | } | 548 | } |
549 | 549 | ||
@@ -604,7 +604,6 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, | |||
604 | char clkname[MAX_CLK_NAME_LENGTH]; | 604 | char clkname[MAX_CLK_NAME_LENGTH]; |
605 | int calc_deviation, deviation = (1 << 30) - 1; | 605 | int calc_deviation, deviation = (1 << 30) - 1; |
606 | 606 | ||
607 | *best_clk = NULL; | ||
608 | clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel : | 607 | clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel : |
609 | ourport->info->def_clk_sel; | 608 | ourport->info->def_clk_sel; |
610 | for (cnt = 0; cnt < info->num_clks; cnt++) { | 609 | for (cnt = 0; cnt < info->num_clks; cnt++) { |
@@ -613,7 +612,7 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport, | |||
613 | 612 | ||
614 | sprintf(clkname, "clk_uart_baud%d", cnt); | 613 | sprintf(clkname, "clk_uart_baud%d", cnt); |
615 | clk = clk_get(ourport->port.dev, clkname); | 614 | clk = clk_get(ourport->port.dev, clkname); |
616 | if (IS_ERR_OR_NULL(clk)) | 615 | if (IS_ERR(clk)) |
617 | continue; | 616 | continue; |
618 | 617 | ||
619 | rate = clk_get_rate(clk); | 618 | rate = clk_get_rate(clk); |
@@ -684,7 +683,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
684 | { | 683 | { |
685 | struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); | 684 | struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); |
686 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 685 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
687 | struct clk *clk = NULL; | 686 | struct clk *clk = ERR_PTR(-EINVAL); |
688 | unsigned long flags; | 687 | unsigned long flags; |
689 | unsigned int baud, quot, clk_sel = 0; | 688 | unsigned int baud, quot, clk_sel = 0; |
690 | unsigned int ulcon; | 689 | unsigned int ulcon; |
@@ -705,7 +704,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
705 | quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel); | 704 | quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel); |
706 | if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) | 705 | if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) |
707 | quot = port->custom_divisor; | 706 | quot = port->custom_divisor; |
708 | if (!clk) | 707 | if (IS_ERR(clk)) |
709 | return; | 708 | return; |
710 | 709 | ||
711 | /* check to see if we need to change clock source */ | 710 | /* check to see if we need to change clock source */ |
@@ -713,9 +712,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port, | |||
713 | if (ourport->baudclk != clk) { | 712 | if (ourport->baudclk != clk) { |
714 | s3c24xx_serial_setsource(port, clk_sel); | 713 | s3c24xx_serial_setsource(port, clk_sel); |
715 | 714 | ||
716 | if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { | 715 | if (!IS_ERR(ourport->baudclk)) { |
717 | clk_disable(ourport->baudclk); | 716 | clk_disable(ourport->baudclk); |
718 | ourport->baudclk = NULL; | 717 | ourport->baudclk = ERR_PTR(-EINVAL); |
719 | } | 718 | } |
720 | 719 | ||
721 | clk_enable(clk); | 720 | clk_enable(clk); |
@@ -1036,10 +1035,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb, | |||
1036 | if (tty == NULL) | 1035 | if (tty == NULL) |
1037 | goto exit; | 1036 | goto exit; |
1038 | 1037 | ||
1039 | termios = tty->termios; | 1038 | termios = &tty->termios; |
1040 | 1039 | ||
1041 | if (termios == NULL) { | 1040 | if (termios == NULL) { |
1042 | printk(KERN_WARNING "%s: no termios?\n", __func__); | 1041 | dev_warn(uport->dev, "%s: no termios?\n", __func__); |
1043 | goto exit; | 1042 | goto exit; |
1044 | } | 1043 | } |
1045 | 1044 | ||
@@ -1114,7 +1113,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1114 | 1113 | ||
1115 | res = platform_get_resource(platdev, IORESOURCE_MEM, 0); | 1114 | res = platform_get_resource(platdev, IORESOURCE_MEM, 0); |
1116 | if (res == NULL) { | 1115 | if (res == NULL) { |
1117 | printk(KERN_ERR "failed to find memory resource for uart\n"); | 1116 | dev_err(port->dev, "failed to find memory resource for uart\n"); |
1118 | return -EINVAL; | 1117 | return -EINVAL; |
1119 | } | 1118 | } |
1120 | 1119 | ||
@@ -1130,7 +1129,7 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, | |||
1130 | ourport->rx_irq = ret; | 1129 | ourport->rx_irq = ret; |
1131 | ourport->tx_irq = ret + 1; | 1130 | ourport->tx_irq = ret + 1; |
1132 | } | 1131 | } |
1133 | 1132 | ||
1134 | ret = platform_get_irq(platdev, 1); | 1133 | ret = platform_get_irq(platdev, 1); |
1135 | if (ret > 0) | 1134 | if (ret > 0) |
1136 | ourport->tx_irq = ret; | 1135 | ourport->tx_irq = ret; |
@@ -1160,7 +1159,11 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev, | |||
1160 | struct uart_port *port = s3c24xx_dev_to_port(dev); | 1159 | struct uart_port *port = s3c24xx_dev_to_port(dev); |
1161 | struct s3c24xx_uart_port *ourport = to_ourport(port); | 1160 | struct s3c24xx_uart_port *ourport = to_ourport(port); |
1162 | 1161 | ||
1163 | return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name); | 1162 | if (IS_ERR(ourport->baudclk)) |
1163 | return -EINVAL; | ||
1164 | |||
1165 | return snprintf(buf, PAGE_SIZE, "* %s\n", | ||
1166 | ourport->baudclk->name ?: "(null)"); | ||
1164 | } | 1167 | } |
1165 | 1168 | ||
1166 | static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); | 1169 | static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); |
@@ -1200,6 +1203,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev) | |||
1200 | return -ENODEV; | 1203 | return -ENODEV; |
1201 | } | 1204 | } |
1202 | 1205 | ||
1206 | ourport->baudclk = ERR_PTR(-EINVAL); | ||
1203 | ourport->info = ourport->drv_data->info; | 1207 | ourport->info = ourport->drv_data->info; |
1204 | ourport->cfg = (pdev->dev.platform_data) ? | 1208 | ourport->cfg = (pdev->dev.platform_data) ? |
1205 | (struct s3c2410_uartcfg *)pdev->dev.platform_data : | 1209 | (struct s3c2410_uartcfg *)pdev->dev.platform_data : |
@@ -1387,7 +1391,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud, | |||
1387 | sprintf(clk_name, "clk_uart_baud%d", clk_sel); | 1391 | sprintf(clk_name, "clk_uart_baud%d", clk_sel); |
1388 | 1392 | ||
1389 | clk = clk_get(port->dev, clk_name); | 1393 | clk = clk_get(port->dev, clk_name); |
1390 | if (!IS_ERR(clk) && clk != NULL) | 1394 | if (!IS_ERR(clk)) |
1391 | rate = clk_get_rate(clk); | 1395 | rate = clk_get_rate(clk); |
1392 | else | 1396 | else |
1393 | rate = 1; | 1397 | rate = 1; |
@@ -1679,7 +1683,7 @@ static int __init s3c24xx_serial_modinit(void) | |||
1679 | 1683 | ||
1680 | ret = uart_register_driver(&s3c24xx_uart_drv); | 1684 | ret = uart_register_driver(&s3c24xx_uart_drv); |
1681 | if (ret < 0) { | 1685 | if (ret < 0) { |
1682 | printk(KERN_ERR "failed to register UART driver\n"); | 1686 | pr_err("Failed to register Samsung UART driver\n"); |
1683 | return -1; | 1687 | return -1; |
1684 | } | 1688 | } |
1685 | 1689 | ||
diff --git a/drivers/tty/serial/sc26xx.c b/drivers/tty/serial/sc26xx.c index e0b4b0a30a5a..9d664242b312 100644 --- a/drivers/tty/serial/sc26xx.c +++ b/drivers/tty/serial/sc26xx.c | |||
@@ -20,6 +20,10 @@ | |||
20 | #include <linux/init.h> | 20 | #include <linux/init.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/io.h> | ||
24 | |||
25 | #warning "Please try migrate to use new driver SCCNXP and report the status" \ | ||
26 | "in the linux-serial mailing list." | ||
23 | 27 | ||
24 | #if defined(CONFIG_MAGIC_SYSRQ) | 28 | #if defined(CONFIG_MAGIC_SYSRQ) |
25 | #define SUPPORT_SYSRQ | 29 | #define SUPPORT_SYSRQ |
diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c new file mode 100644 index 000000000000..05d767cf82a7 --- /dev/null +++ b/drivers/tty/serial/sccnxp.c | |||
@@ -0,0 +1,985 @@ | |||
1 | /* | ||
2 | * NXP (Philips) SCC+++(SCN+++) serial driver | ||
3 | * | ||
4 | * Copyright (C) 2012 Alexander Shiyan <shc_work@mail.ru> | ||
5 | * | ||
6 | * Based on sc26xx.c, by Thomas Bogendörfer (tsbogend@alpha.franken.de) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #if defined(CONFIG_SERIAL_SCCNXP_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | ||
15 | #define SUPPORT_SYSRQ | ||
16 | #endif | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/console.h> | ||
21 | #include <linux/serial_core.h> | ||
22 | #include <linux/serial.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/tty.h> | ||
25 | #include <linux/tty_flip.h> | ||
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/platform_data/sccnxp.h> | ||
28 | |||
29 | #define SCCNXP_NAME "uart-sccnxp" | ||
30 | #define SCCNXP_MAJOR 204 | ||
31 | #define SCCNXP_MINOR 205 | ||
32 | |||
33 | #define SCCNXP_MR_REG (0x00) | ||
34 | # define MR0_BAUD_NORMAL (0 << 0) | ||
35 | # define MR0_BAUD_EXT1 (1 << 0) | ||
36 | # define MR0_BAUD_EXT2 (5 << 0) | ||
37 | # define MR0_FIFO (1 << 3) | ||
38 | # define MR0_TXLVL (1 << 4) | ||
39 | # define MR1_BITS_5 (0 << 0) | ||
40 | # define MR1_BITS_6 (1 << 0) | ||
41 | # define MR1_BITS_7 (2 << 0) | ||
42 | # define MR1_BITS_8 (3 << 0) | ||
43 | # define MR1_PAR_EVN (0 << 2) | ||
44 | # define MR1_PAR_ODD (1 << 2) | ||
45 | # define MR1_PAR_NO (4 << 2) | ||
46 | # define MR2_STOP1 (7 << 0) | ||
47 | # define MR2_STOP2 (0xf << 0) | ||
48 | #define SCCNXP_SR_REG (0x01) | ||
49 | #define SCCNXP_CSR_REG SCCNXP_SR_REG | ||
50 | # define SR_RXRDY (1 << 0) | ||
51 | # define SR_FULL (1 << 1) | ||
52 | # define SR_TXRDY (1 << 2) | ||
53 | # define SR_TXEMT (1 << 3) | ||
54 | # define SR_OVR (1 << 4) | ||
55 | # define SR_PE (1 << 5) | ||
56 | # define SR_FE (1 << 6) | ||
57 | # define SR_BRK (1 << 7) | ||
58 | #define SCCNXP_CR_REG (0x02) | ||
59 | # define CR_RX_ENABLE (1 << 0) | ||
60 | # define CR_RX_DISABLE (1 << 1) | ||
61 | # define CR_TX_ENABLE (1 << 2) | ||
62 | # define CR_TX_DISABLE (1 << 3) | ||
63 | # define CR_CMD_MRPTR1 (0x01 << 4) | ||
64 | # define CR_CMD_RX_RESET (0x02 << 4) | ||
65 | # define CR_CMD_TX_RESET (0x03 << 4) | ||
66 | # define CR_CMD_STATUS_RESET (0x04 << 4) | ||
67 | # define CR_CMD_BREAK_RESET (0x05 << 4) | ||
68 | # define CR_CMD_START_BREAK (0x06 << 4) | ||
69 | # define CR_CMD_STOP_BREAK (0x07 << 4) | ||
70 | # define CR_CMD_MRPTR0 (0x0b << 4) | ||
71 | #define SCCNXP_RHR_REG (0x03) | ||
72 | #define SCCNXP_THR_REG SCCNXP_RHR_REG | ||
73 | #define SCCNXP_IPCR_REG (0x04) | ||
74 | #define SCCNXP_ACR_REG SCCNXP_IPCR_REG | ||
75 | # define ACR_BAUD0 (0 << 7) | ||
76 | # define ACR_BAUD1 (1 << 7) | ||
77 | # define ACR_TIMER_MODE (6 << 4) | ||
78 | #define SCCNXP_ISR_REG (0x05) | ||
79 | #define SCCNXP_IMR_REG SCCNXP_ISR_REG | ||
80 | # define IMR_TXRDY (1 << 0) | ||
81 | # define IMR_RXRDY (1 << 1) | ||
82 | # define ISR_TXRDY(x) (1 << ((x * 4) + 0)) | ||
83 | # define ISR_RXRDY(x) (1 << ((x * 4) + 1)) | ||
84 | #define SCCNXP_IPR_REG (0x0d) | ||
85 | #define SCCNXP_OPCR_REG SCCNXP_IPR_REG | ||
86 | #define SCCNXP_SOP_REG (0x0e) | ||
87 | #define SCCNXP_ROP_REG (0x0f) | ||
88 | |||
89 | /* Route helpers */ | ||
90 | #define MCTRL_MASK(sig) (0xf << (sig)) | ||
91 | #define MCTRL_IBIT(cfg, sig) ((((cfg) >> (sig)) & 0xf) - LINE_IP0) | ||
92 | #define MCTRL_OBIT(cfg, sig) ((((cfg) >> (sig)) & 0xf) - LINE_OP0) | ||
93 | |||
94 | /* Supported chip types */ | ||
95 | enum { | ||
96 | SCCNXP_TYPE_SC2681 = 2681, | ||
97 | SCCNXP_TYPE_SC2691 = 2691, | ||
98 | SCCNXP_TYPE_SC2692 = 2692, | ||
99 | SCCNXP_TYPE_SC2891 = 2891, | ||
100 | SCCNXP_TYPE_SC2892 = 2892, | ||
101 | SCCNXP_TYPE_SC28202 = 28202, | ||
102 | SCCNXP_TYPE_SC68681 = 68681, | ||
103 | SCCNXP_TYPE_SC68692 = 68692, | ||
104 | }; | ||
105 | |||
106 | struct sccnxp_port { | ||
107 | struct uart_driver uart; | ||
108 | struct uart_port port[SCCNXP_MAX_UARTS]; | ||
109 | |||
110 | const char *name; | ||
111 | int irq; | ||
112 | |||
113 | u8 imr; | ||
114 | u8 addr_mask; | ||
115 | int freq_std; | ||
116 | |||
117 | int flags; | ||
118 | #define SCCNXP_HAVE_IO 0x00000001 | ||
119 | #define SCCNXP_HAVE_MR0 0x00000002 | ||
120 | |||
121 | #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE | ||
122 | struct console console; | ||
123 | #endif | ||
124 | |||
125 | struct mutex sccnxp_mutex; | ||
126 | |||
127 | struct sccnxp_pdata pdata; | ||
128 | }; | ||
129 | |||
130 | static inline u8 sccnxp_raw_read(void __iomem *base, u8 reg, u8 shift) | ||
131 | { | ||
132 | return readb(base + (reg << shift)); | ||
133 | } | ||
134 | |||
135 | static inline void sccnxp_raw_write(void __iomem *base, u8 reg, u8 shift, u8 v) | ||
136 | { | ||
137 | writeb(v, base + (reg << shift)); | ||
138 | } | ||
139 | |||
140 | static inline u8 sccnxp_read(struct uart_port *port, u8 reg) | ||
141 | { | ||
142 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
143 | |||
144 | return sccnxp_raw_read(port->membase, reg & s->addr_mask, | ||
145 | port->regshift); | ||
146 | } | ||
147 | |||
148 | static inline void sccnxp_write(struct uart_port *port, u8 reg, u8 v) | ||
149 | { | ||
150 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
151 | |||
152 | sccnxp_raw_write(port->membase, reg & s->addr_mask, port->regshift, v); | ||
153 | } | ||
154 | |||
155 | static inline u8 sccnxp_port_read(struct uart_port *port, u8 reg) | ||
156 | { | ||
157 | return sccnxp_read(port, (port->line << 3) + reg); | ||
158 | } | ||
159 | |||
160 | static inline void sccnxp_port_write(struct uart_port *port, u8 reg, u8 v) | ||
161 | { | ||
162 | sccnxp_write(port, (port->line << 3) + reg, v); | ||
163 | } | ||
164 | |||
165 | static int sccnxp_update_best_err(int a, int b, int *besterr) | ||
166 | { | ||
167 | int err = abs(a - b); | ||
168 | |||
169 | if ((*besterr < 0) || (*besterr > err)) { | ||
170 | *besterr = err; | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | return 1; | ||
175 | } | ||
176 | |||
177 | struct baud_table { | ||
178 | u8 csr; | ||
179 | u8 acr; | ||
180 | u8 mr0; | ||
181 | int baud; | ||
182 | }; | ||
183 | |||
184 | const struct baud_table baud_std[] = { | ||
185 | { 0, ACR_BAUD0, MR0_BAUD_NORMAL, 50, }, | ||
186 | { 0, ACR_BAUD1, MR0_BAUD_NORMAL, 75, }, | ||
187 | { 1, ACR_BAUD0, MR0_BAUD_NORMAL, 110, }, | ||
188 | { 2, ACR_BAUD0, MR0_BAUD_NORMAL, 134, }, | ||
189 | { 3, ACR_BAUD1, MR0_BAUD_NORMAL, 150, }, | ||
190 | { 3, ACR_BAUD0, MR0_BAUD_NORMAL, 200, }, | ||
191 | { 4, ACR_BAUD0, MR0_BAUD_NORMAL, 300, }, | ||
192 | { 0, ACR_BAUD1, MR0_BAUD_EXT1, 450, }, | ||
193 | { 1, ACR_BAUD0, MR0_BAUD_EXT2, 880, }, | ||
194 | { 3, ACR_BAUD1, MR0_BAUD_EXT1, 900, }, | ||
195 | { 5, ACR_BAUD0, MR0_BAUD_NORMAL, 600, }, | ||
196 | { 7, ACR_BAUD0, MR0_BAUD_NORMAL, 1050, }, | ||
197 | { 2, ACR_BAUD0, MR0_BAUD_EXT2, 1076, }, | ||
198 | { 6, ACR_BAUD0, MR0_BAUD_NORMAL, 1200, }, | ||
199 | { 10, ACR_BAUD1, MR0_BAUD_NORMAL, 1800, }, | ||
200 | { 7, ACR_BAUD1, MR0_BAUD_NORMAL, 2000, }, | ||
201 | { 8, ACR_BAUD0, MR0_BAUD_NORMAL, 2400, }, | ||
202 | { 5, ACR_BAUD1, MR0_BAUD_EXT1, 3600, }, | ||
203 | { 9, ACR_BAUD0, MR0_BAUD_NORMAL, 4800, }, | ||
204 | { 10, ACR_BAUD0, MR0_BAUD_NORMAL, 7200, }, | ||
205 | { 11, ACR_BAUD0, MR0_BAUD_NORMAL, 9600, }, | ||
206 | { 8, ACR_BAUD0, MR0_BAUD_EXT1, 14400, }, | ||
207 | { 12, ACR_BAUD1, MR0_BAUD_NORMAL, 19200, }, | ||
208 | { 9, ACR_BAUD0, MR0_BAUD_EXT1, 28800, }, | ||
209 | { 12, ACR_BAUD0, MR0_BAUD_NORMAL, 38400, }, | ||
210 | { 11, ACR_BAUD0, MR0_BAUD_EXT1, 57600, }, | ||
211 | { 12, ACR_BAUD1, MR0_BAUD_EXT1, 115200, }, | ||
212 | { 12, ACR_BAUD0, MR0_BAUD_EXT1, 230400, }, | ||
213 | { 0, 0, 0, 0 } | ||
214 | }; | ||
215 | |||
216 | static void sccnxp_set_baud(struct uart_port *port, int baud) | ||
217 | { | ||
218 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
219 | int div_std, tmp_baud, bestbaud = baud, besterr = -1; | ||
220 | u8 i, acr = 0, csr = 0, mr0 = 0; | ||
221 | |||
222 | /* Find best baud from table */ | ||
223 | for (i = 0; baud_std[i].baud && besterr; i++) { | ||
224 | if (baud_std[i].mr0 && !(s->flags & SCCNXP_HAVE_MR0)) | ||
225 | continue; | ||
226 | div_std = DIV_ROUND_CLOSEST(s->freq_std, baud_std[i].baud); | ||
227 | tmp_baud = DIV_ROUND_CLOSEST(port->uartclk, div_std); | ||
228 | if (!sccnxp_update_best_err(baud, tmp_baud, &besterr)) { | ||
229 | acr = baud_std[i].acr; | ||
230 | csr = baud_std[i].csr; | ||
231 | mr0 = baud_std[i].mr0; | ||
232 | bestbaud = tmp_baud; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | if (s->flags & SCCNXP_HAVE_MR0) { | ||
237 | /* Enable FIFO, set half level for TX */ | ||
238 | mr0 |= MR0_FIFO | MR0_TXLVL; | ||
239 | /* Update MR0 */ | ||
240 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_MRPTR0); | ||
241 | sccnxp_port_write(port, SCCNXP_MR_REG, mr0); | ||
242 | } | ||
243 | |||
244 | sccnxp_port_write(port, SCCNXP_ACR_REG, acr | ACR_TIMER_MODE); | ||
245 | sccnxp_port_write(port, SCCNXP_CSR_REG, (csr << 4) | csr); | ||
246 | |||
247 | dev_dbg(port->dev, "Baudrate desired: %i, calculated: %i\n", | ||
248 | baud, bestbaud); | ||
249 | } | ||
250 | |||
251 | static void sccnxp_enable_irq(struct uart_port *port, int mask) | ||
252 | { | ||
253 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
254 | |||
255 | s->imr |= mask << (port->line * 4); | ||
256 | sccnxp_write(port, SCCNXP_IMR_REG, s->imr); | ||
257 | } | ||
258 | |||
259 | static void sccnxp_disable_irq(struct uart_port *port, int mask) | ||
260 | { | ||
261 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
262 | |||
263 | s->imr &= ~(mask << (port->line * 4)); | ||
264 | sccnxp_write(port, SCCNXP_IMR_REG, s->imr); | ||
265 | } | ||
266 | |||
267 | static void sccnxp_set_bit(struct uart_port *port, int sig, int state) | ||
268 | { | ||
269 | u8 bitmask; | ||
270 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
271 | |||
272 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(sig)) { | ||
273 | bitmask = 1 << MCTRL_OBIT(s->pdata.mctrl_cfg[port->line], sig); | ||
274 | if (state) | ||
275 | sccnxp_write(port, SCCNXP_SOP_REG, bitmask); | ||
276 | else | ||
277 | sccnxp_write(port, SCCNXP_ROP_REG, bitmask); | ||
278 | } | ||
279 | } | ||
280 | |||
281 | static void sccnxp_handle_rx(struct uart_port *port) | ||
282 | { | ||
283 | u8 sr; | ||
284 | unsigned int ch, flag; | ||
285 | struct tty_struct *tty = tty_port_tty_get(&port->state->port); | ||
286 | |||
287 | if (!tty) | ||
288 | return; | ||
289 | |||
290 | for (;;) { | ||
291 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); | ||
292 | if (!(sr & SR_RXRDY)) | ||
293 | break; | ||
294 | sr &= SR_PE | SR_FE | SR_OVR | SR_BRK; | ||
295 | |||
296 | ch = sccnxp_port_read(port, SCCNXP_RHR_REG); | ||
297 | |||
298 | port->icount.rx++; | ||
299 | flag = TTY_NORMAL; | ||
300 | |||
301 | if (unlikely(sr)) { | ||
302 | if (sr & SR_BRK) { | ||
303 | port->icount.brk++; | ||
304 | if (uart_handle_break(port)) | ||
305 | continue; | ||
306 | } else if (sr & SR_PE) | ||
307 | port->icount.parity++; | ||
308 | else if (sr & SR_FE) | ||
309 | port->icount.frame++; | ||
310 | else if (sr & SR_OVR) | ||
311 | port->icount.overrun++; | ||
312 | |||
313 | sr &= port->read_status_mask; | ||
314 | if (sr & SR_BRK) | ||
315 | flag = TTY_BREAK; | ||
316 | else if (sr & SR_PE) | ||
317 | flag = TTY_PARITY; | ||
318 | else if (sr & SR_FE) | ||
319 | flag = TTY_FRAME; | ||
320 | else if (sr & SR_OVR) | ||
321 | flag = TTY_OVERRUN; | ||
322 | } | ||
323 | |||
324 | if (uart_handle_sysrq_char(port, ch)) | ||
325 | continue; | ||
326 | |||
327 | if (sr & port->ignore_status_mask) | ||
328 | continue; | ||
329 | |||
330 | uart_insert_char(port, sr, SR_OVR, ch, flag); | ||
331 | } | ||
332 | |||
333 | tty_flip_buffer_push(tty); | ||
334 | |||
335 | tty_kref_put(tty); | ||
336 | } | ||
337 | |||
338 | static void sccnxp_handle_tx(struct uart_port *port) | ||
339 | { | ||
340 | u8 sr; | ||
341 | struct circ_buf *xmit = &port->state->xmit; | ||
342 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
343 | |||
344 | if (unlikely(port->x_char)) { | ||
345 | sccnxp_port_write(port, SCCNXP_THR_REG, port->x_char); | ||
346 | port->icount.tx++; | ||
347 | port->x_char = 0; | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
352 | /* Disable TX if FIFO is empty */ | ||
353 | if (sccnxp_port_read(port, SCCNXP_SR_REG) & SR_TXEMT) { | ||
354 | sccnxp_disable_irq(port, IMR_TXRDY); | ||
355 | |||
356 | /* Set direction to input */ | ||
357 | if (s->flags & SCCNXP_HAVE_IO) | ||
358 | sccnxp_set_bit(port, DIR_OP, 0); | ||
359 | } | ||
360 | return; | ||
361 | } | ||
362 | |||
363 | while (!uart_circ_empty(xmit)) { | ||
364 | sr = sccnxp_port_read(port, SCCNXP_SR_REG); | ||
365 | if (!(sr & SR_TXRDY)) | ||
366 | break; | ||
367 | |||
368 | sccnxp_port_write(port, SCCNXP_THR_REG, xmit->buf[xmit->tail]); | ||
369 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
370 | port->icount.tx++; | ||
371 | } | ||
372 | |||
373 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
374 | uart_write_wakeup(port); | ||
375 | } | ||
376 | |||
377 | static irqreturn_t sccnxp_ist(int irq, void *dev_id) | ||
378 | { | ||
379 | int i; | ||
380 | u8 isr; | ||
381 | struct sccnxp_port *s = (struct sccnxp_port *)dev_id; | ||
382 | |||
383 | mutex_lock(&s->sccnxp_mutex); | ||
384 | |||
385 | for (;;) { | ||
386 | isr = sccnxp_read(&s->port[0], SCCNXP_ISR_REG); | ||
387 | isr &= s->imr; | ||
388 | if (!isr) | ||
389 | break; | ||
390 | |||
391 | dev_dbg(s->port[0].dev, "IRQ status: 0x%02x\n", isr); | ||
392 | |||
393 | for (i = 0; i < s->uart.nr; i++) { | ||
394 | if (isr & ISR_RXRDY(i)) | ||
395 | sccnxp_handle_rx(&s->port[i]); | ||
396 | if (isr & ISR_TXRDY(i)) | ||
397 | sccnxp_handle_tx(&s->port[i]); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | mutex_unlock(&s->sccnxp_mutex); | ||
402 | |||
403 | return IRQ_HANDLED; | ||
404 | } | ||
405 | |||
406 | static void sccnxp_start_tx(struct uart_port *port) | ||
407 | { | ||
408 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
409 | |||
410 | mutex_lock(&s->sccnxp_mutex); | ||
411 | |||
412 | /* Set direction to output */ | ||
413 | if (s->flags & SCCNXP_HAVE_IO) | ||
414 | sccnxp_set_bit(port, DIR_OP, 1); | ||
415 | |||
416 | sccnxp_enable_irq(port, IMR_TXRDY); | ||
417 | |||
418 | mutex_unlock(&s->sccnxp_mutex); | ||
419 | } | ||
420 | |||
421 | static void sccnxp_stop_tx(struct uart_port *port) | ||
422 | { | ||
423 | /* Do nothing */ | ||
424 | } | ||
425 | |||
426 | static void sccnxp_stop_rx(struct uart_port *port) | ||
427 | { | ||
428 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
429 | |||
430 | mutex_lock(&s->sccnxp_mutex); | ||
431 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE); | ||
432 | mutex_unlock(&s->sccnxp_mutex); | ||
433 | } | ||
434 | |||
435 | static unsigned int sccnxp_tx_empty(struct uart_port *port) | ||
436 | { | ||
437 | u8 val; | ||
438 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
439 | |||
440 | mutex_lock(&s->sccnxp_mutex); | ||
441 | val = sccnxp_port_read(port, SCCNXP_SR_REG); | ||
442 | mutex_unlock(&s->sccnxp_mutex); | ||
443 | |||
444 | return (val & SR_TXEMT) ? TIOCSER_TEMT : 0; | ||
445 | } | ||
446 | |||
447 | static void sccnxp_enable_ms(struct uart_port *port) | ||
448 | { | ||
449 | /* Do nothing */ | ||
450 | } | ||
451 | |||
452 | static void sccnxp_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
453 | { | ||
454 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
455 | |||
456 | if (!(s->flags & SCCNXP_HAVE_IO)) | ||
457 | return; | ||
458 | |||
459 | mutex_lock(&s->sccnxp_mutex); | ||
460 | |||
461 | sccnxp_set_bit(port, DTR_OP, mctrl & TIOCM_DTR); | ||
462 | sccnxp_set_bit(port, RTS_OP, mctrl & TIOCM_RTS); | ||
463 | |||
464 | mutex_unlock(&s->sccnxp_mutex); | ||
465 | } | ||
466 | |||
467 | static unsigned int sccnxp_get_mctrl(struct uart_port *port) | ||
468 | { | ||
469 | u8 bitmask, ipr; | ||
470 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
471 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | ||
472 | |||
473 | if (!(s->flags & SCCNXP_HAVE_IO)) | ||
474 | return mctrl; | ||
475 | |||
476 | mutex_lock(&s->sccnxp_mutex); | ||
477 | |||
478 | ipr = ~sccnxp_read(port, SCCNXP_IPCR_REG); | ||
479 | |||
480 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(DSR_IP)) { | ||
481 | bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line], | ||
482 | DSR_IP); | ||
483 | mctrl &= ~TIOCM_DSR; | ||
484 | mctrl |= (ipr & bitmask) ? TIOCM_DSR : 0; | ||
485 | } | ||
486 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(CTS_IP)) { | ||
487 | bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line], | ||
488 | CTS_IP); | ||
489 | mctrl &= ~TIOCM_CTS; | ||
490 | mctrl |= (ipr & bitmask) ? TIOCM_CTS : 0; | ||
491 | } | ||
492 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(DCD_IP)) { | ||
493 | bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line], | ||
494 | DCD_IP); | ||
495 | mctrl &= ~TIOCM_CAR; | ||
496 | mctrl |= (ipr & bitmask) ? TIOCM_CAR : 0; | ||
497 | } | ||
498 | if (s->pdata.mctrl_cfg[port->line] & MCTRL_MASK(RNG_IP)) { | ||
499 | bitmask = 1 << MCTRL_IBIT(s->pdata.mctrl_cfg[port->line], | ||
500 | RNG_IP); | ||
501 | mctrl &= ~TIOCM_RNG; | ||
502 | mctrl |= (ipr & bitmask) ? TIOCM_RNG : 0; | ||
503 | } | ||
504 | |||
505 | mutex_unlock(&s->sccnxp_mutex); | ||
506 | |||
507 | return mctrl; | ||
508 | } | ||
509 | |||
510 | static void sccnxp_break_ctl(struct uart_port *port, int break_state) | ||
511 | { | ||
512 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
513 | |||
514 | mutex_lock(&s->sccnxp_mutex); | ||
515 | sccnxp_port_write(port, SCCNXP_CR_REG, break_state ? | ||
516 | CR_CMD_START_BREAK : CR_CMD_STOP_BREAK); | ||
517 | mutex_unlock(&s->sccnxp_mutex); | ||
518 | } | ||
519 | |||
520 | static void sccnxp_set_termios(struct uart_port *port, | ||
521 | struct ktermios *termios, struct ktermios *old) | ||
522 | { | ||
523 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
524 | u8 mr1, mr2; | ||
525 | int baud; | ||
526 | |||
527 | mutex_lock(&s->sccnxp_mutex); | ||
528 | |||
529 | /* Mask termios capabilities we don't support */ | ||
530 | termios->c_cflag &= ~CMSPAR; | ||
531 | termios->c_iflag &= ~(IXON | IXOFF | IXANY); | ||
532 | |||
533 | /* Disable RX & TX, reset break condition, status and FIFOs */ | ||
534 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_RX_RESET | | ||
535 | CR_RX_DISABLE | CR_TX_DISABLE); | ||
536 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_TX_RESET); | ||
537 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_STATUS_RESET); | ||
538 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_BREAK_RESET); | ||
539 | |||
540 | /* Word size */ | ||
541 | switch (termios->c_cflag & CSIZE) { | ||
542 | case CS5: | ||
543 | mr1 = MR1_BITS_5; | ||
544 | break; | ||
545 | case CS6: | ||
546 | mr1 = MR1_BITS_6; | ||
547 | break; | ||
548 | case CS7: | ||
549 | mr1 = MR1_BITS_7; | ||
550 | break; | ||
551 | default: | ||
552 | case CS8: | ||
553 | mr1 = MR1_BITS_8; | ||
554 | break; | ||
555 | } | ||
556 | |||
557 | /* Parity */ | ||
558 | if (termios->c_cflag & PARENB) { | ||
559 | if (termios->c_cflag & PARODD) | ||
560 | mr1 |= MR1_PAR_ODD; | ||
561 | } else | ||
562 | mr1 |= MR1_PAR_NO; | ||
563 | |||
564 | /* Stop bits */ | ||
565 | mr2 = (termios->c_cflag & CSTOPB) ? MR2_STOP2 : MR2_STOP1; | ||
566 | |||
567 | /* Update desired format */ | ||
568 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_MRPTR1); | ||
569 | sccnxp_port_write(port, SCCNXP_MR_REG, mr1); | ||
570 | sccnxp_port_write(port, SCCNXP_MR_REG, mr2); | ||
571 | |||
572 | /* Set read status mask */ | ||
573 | port->read_status_mask = SR_OVR; | ||
574 | if (termios->c_iflag & INPCK) | ||
575 | port->read_status_mask |= SR_PE | SR_FE; | ||
576 | if (termios->c_iflag & (BRKINT | PARMRK)) | ||
577 | port->read_status_mask |= SR_BRK; | ||
578 | |||
579 | /* Set status ignore mask */ | ||
580 | port->ignore_status_mask = 0; | ||
581 | if (termios->c_iflag & IGNBRK) | ||
582 | port->ignore_status_mask |= SR_BRK; | ||
583 | if (!(termios->c_cflag & CREAD)) | ||
584 | port->ignore_status_mask |= SR_PE | SR_OVR | SR_FE | SR_BRK; | ||
585 | |||
586 | /* Setup baudrate */ | ||
587 | baud = uart_get_baud_rate(port, termios, old, 50, | ||
588 | (s->flags & SCCNXP_HAVE_MR0) ? | ||
589 | 230400 : 38400); | ||
590 | sccnxp_set_baud(port, baud); | ||
591 | |||
592 | /* Update timeout according to new baud rate */ | ||
593 | uart_update_timeout(port, termios->c_cflag, baud); | ||
594 | |||
595 | /* Enable RX & TX */ | ||
596 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); | ||
597 | |||
598 | mutex_unlock(&s->sccnxp_mutex); | ||
599 | } | ||
600 | |||
601 | static int sccnxp_startup(struct uart_port *port) | ||
602 | { | ||
603 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
604 | |||
605 | mutex_lock(&s->sccnxp_mutex); | ||
606 | |||
607 | if (s->flags & SCCNXP_HAVE_IO) { | ||
608 | /* Outputs are controlled manually */ | ||
609 | sccnxp_write(port, SCCNXP_OPCR_REG, 0); | ||
610 | } | ||
611 | |||
612 | /* Reset break condition, status and FIFOs */ | ||
613 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_RX_RESET); | ||
614 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_TX_RESET); | ||
615 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_STATUS_RESET); | ||
616 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_CMD_BREAK_RESET); | ||
617 | |||
618 | /* Enable RX & TX */ | ||
619 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_ENABLE | CR_TX_ENABLE); | ||
620 | |||
621 | /* Enable RX interrupt */ | ||
622 | sccnxp_enable_irq(port, IMR_RXRDY); | ||
623 | |||
624 | mutex_unlock(&s->sccnxp_mutex); | ||
625 | |||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static void sccnxp_shutdown(struct uart_port *port) | ||
630 | { | ||
631 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
632 | |||
633 | mutex_lock(&s->sccnxp_mutex); | ||
634 | |||
635 | /* Disable interrupts */ | ||
636 | sccnxp_disable_irq(port, IMR_TXRDY | IMR_RXRDY); | ||
637 | |||
638 | /* Disable TX & RX */ | ||
639 | sccnxp_port_write(port, SCCNXP_CR_REG, CR_RX_DISABLE | CR_TX_DISABLE); | ||
640 | |||
641 | /* Leave direction to input */ | ||
642 | if (s->flags & SCCNXP_HAVE_IO) | ||
643 | sccnxp_set_bit(port, DIR_OP, 0); | ||
644 | |||
645 | mutex_unlock(&s->sccnxp_mutex); | ||
646 | } | ||
647 | |||
648 | static const char *sccnxp_type(struct uart_port *port) | ||
649 | { | ||
650 | struct sccnxp_port *s = dev_get_drvdata(port->dev); | ||
651 | |||
652 | return (port->type == PORT_SC26XX) ? s->name : NULL; | ||
653 | } | ||
654 | |||
655 | static void sccnxp_release_port(struct uart_port *port) | ||
656 | { | ||
657 | /* Do nothing */ | ||
658 | } | ||
659 | |||
660 | static int sccnxp_request_port(struct uart_port *port) | ||
661 | { | ||
662 | /* Do nothing */ | ||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static void sccnxp_config_port(struct uart_port *port, int flags) | ||
667 | { | ||
668 | if (flags & UART_CONFIG_TYPE) | ||
669 | port->type = PORT_SC26XX; | ||
670 | } | ||
671 | |||
672 | static int sccnxp_verify_port(struct uart_port *port, struct serial_struct *s) | ||
673 | { | ||
674 | if ((s->type == PORT_UNKNOWN) || (s->type == PORT_SC26XX)) | ||
675 | return 0; | ||
676 | if (s->irq == port->irq) | ||
677 | return 0; | ||
678 | |||
679 | return -EINVAL; | ||
680 | } | ||
681 | |||
682 | static const struct uart_ops sccnxp_ops = { | ||
683 | .tx_empty = sccnxp_tx_empty, | ||
684 | .set_mctrl = sccnxp_set_mctrl, | ||
685 | .get_mctrl = sccnxp_get_mctrl, | ||
686 | .stop_tx = sccnxp_stop_tx, | ||
687 | .start_tx = sccnxp_start_tx, | ||
688 | .stop_rx = sccnxp_stop_rx, | ||
689 | .enable_ms = sccnxp_enable_ms, | ||
690 | .break_ctl = sccnxp_break_ctl, | ||
691 | .startup = sccnxp_startup, | ||
692 | .shutdown = sccnxp_shutdown, | ||
693 | .set_termios = sccnxp_set_termios, | ||
694 | .type = sccnxp_type, | ||
695 | .release_port = sccnxp_release_port, | ||
696 | .request_port = sccnxp_request_port, | ||
697 | .config_port = sccnxp_config_port, | ||
698 | .verify_port = sccnxp_verify_port, | ||
699 | }; | ||
700 | |||
701 | #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE | ||
702 | static void sccnxp_console_putchar(struct uart_port *port, int c) | ||
703 | { | ||
704 | int tryes = 100000; | ||
705 | |||
706 | while (tryes--) { | ||
707 | if (sccnxp_port_read(port, SCCNXP_SR_REG) & SR_TXRDY) { | ||
708 | sccnxp_port_write(port, SCCNXP_THR_REG, c); | ||
709 | break; | ||
710 | } | ||
711 | barrier(); | ||
712 | } | ||
713 | } | ||
714 | |||
715 | static void sccnxp_console_write(struct console *co, const char *c, unsigned n) | ||
716 | { | ||
717 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; | ||
718 | struct uart_port *port = &s->port[co->index]; | ||
719 | |||
720 | mutex_lock(&s->sccnxp_mutex); | ||
721 | uart_console_write(port, c, n, sccnxp_console_putchar); | ||
722 | mutex_unlock(&s->sccnxp_mutex); | ||
723 | } | ||
724 | |||
725 | static int sccnxp_console_setup(struct console *co, char *options) | ||
726 | { | ||
727 | struct sccnxp_port *s = (struct sccnxp_port *)co->data; | ||
728 | struct uart_port *port = &s->port[(co->index > 0) ? co->index : 0]; | ||
729 | int baud = 9600, bits = 8, parity = 'n', flow = 'n'; | ||
730 | |||
731 | if (options) | ||
732 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
733 | |||
734 | return uart_set_options(port, co, baud, parity, bits, flow); | ||
735 | } | ||
736 | #endif | ||
737 | |||
738 | static int __devinit sccnxp_probe(struct platform_device *pdev) | ||
739 | { | ||
740 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
741 | int chiptype = pdev->id_entry->driver_data; | ||
742 | struct sccnxp_pdata *pdata = dev_get_platdata(&pdev->dev); | ||
743 | int i, ret, fifosize, freq_min, freq_max; | ||
744 | struct sccnxp_port *s; | ||
745 | void __iomem *membase; | ||
746 | |||
747 | if (!res) { | ||
748 | dev_err(&pdev->dev, "Missing memory resource data\n"); | ||
749 | return -EADDRNOTAVAIL; | ||
750 | } | ||
751 | |||
752 | dev_set_name(&pdev->dev, SCCNXP_NAME); | ||
753 | |||
754 | s = devm_kzalloc(&pdev->dev, sizeof(struct sccnxp_port), GFP_KERNEL); | ||
755 | if (!s) { | ||
756 | dev_err(&pdev->dev, "Error allocating port structure\n"); | ||
757 | return -ENOMEM; | ||
758 | } | ||
759 | platform_set_drvdata(pdev, s); | ||
760 | |||
761 | mutex_init(&s->sccnxp_mutex); | ||
762 | |||
763 | /* Individual chip settings */ | ||
764 | switch (chiptype) { | ||
765 | case SCCNXP_TYPE_SC2681: | ||
766 | s->name = "SC2681"; | ||
767 | s->uart.nr = 2; | ||
768 | s->freq_std = 3686400; | ||
769 | s->addr_mask = 0x0f; | ||
770 | s->flags = SCCNXP_HAVE_IO; | ||
771 | fifosize = 3; | ||
772 | freq_min = 1000000; | ||
773 | freq_max = 4000000; | ||
774 | break; | ||
775 | case SCCNXP_TYPE_SC2691: | ||
776 | s->name = "SC2691"; | ||
777 | s->uart.nr = 1; | ||
778 | s->freq_std = 3686400; | ||
779 | s->addr_mask = 0x07; | ||
780 | s->flags = 0; | ||
781 | fifosize = 3; | ||
782 | freq_min = 1000000; | ||
783 | freq_max = 4000000; | ||
784 | break; | ||
785 | case SCCNXP_TYPE_SC2692: | ||
786 | s->name = "SC2692"; | ||
787 | s->uart.nr = 2; | ||
788 | s->freq_std = 3686400; | ||
789 | s->addr_mask = 0x0f; | ||
790 | s->flags = SCCNXP_HAVE_IO; | ||
791 | fifosize = 3; | ||
792 | freq_min = 1000000; | ||
793 | freq_max = 4000000; | ||
794 | break; | ||
795 | case SCCNXP_TYPE_SC2891: | ||
796 | s->name = "SC2891"; | ||
797 | s->uart.nr = 1; | ||
798 | s->freq_std = 3686400; | ||
799 | s->addr_mask = 0x0f; | ||
800 | s->flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0; | ||
801 | fifosize = 16; | ||
802 | freq_min = 100000; | ||
803 | freq_max = 8000000; | ||
804 | break; | ||
805 | case SCCNXP_TYPE_SC2892: | ||
806 | s->name = "SC2892"; | ||
807 | s->uart.nr = 2; | ||
808 | s->freq_std = 3686400; | ||
809 | s->addr_mask = 0x0f; | ||
810 | s->flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0; | ||
811 | fifosize = 16; | ||
812 | freq_min = 100000; | ||
813 | freq_max = 8000000; | ||
814 | break; | ||
815 | case SCCNXP_TYPE_SC28202: | ||
816 | s->name = "SC28202"; | ||
817 | s->uart.nr = 2; | ||
818 | s->freq_std = 14745600; | ||
819 | s->addr_mask = 0x7f; | ||
820 | s->flags = SCCNXP_HAVE_IO | SCCNXP_HAVE_MR0; | ||
821 | fifosize = 256; | ||
822 | freq_min = 1000000; | ||
823 | freq_max = 50000000; | ||
824 | break; | ||
825 | case SCCNXP_TYPE_SC68681: | ||
826 | s->name = "SC68681"; | ||
827 | s->uart.nr = 2; | ||
828 | s->freq_std = 3686400; | ||
829 | s->addr_mask = 0x0f; | ||
830 | s->flags = SCCNXP_HAVE_IO; | ||
831 | fifosize = 3; | ||
832 | freq_min = 1000000; | ||
833 | freq_max = 4000000; | ||
834 | break; | ||
835 | case SCCNXP_TYPE_SC68692: | ||
836 | s->name = "SC68692"; | ||
837 | s->uart.nr = 2; | ||
838 | s->freq_std = 3686400; | ||
839 | s->addr_mask = 0x0f; | ||
840 | s->flags = SCCNXP_HAVE_IO; | ||
841 | fifosize = 3; | ||
842 | freq_min = 1000000; | ||
843 | freq_max = 4000000; | ||
844 | break; | ||
845 | default: | ||
846 | dev_err(&pdev->dev, "Unsupported chip type %i\n", chiptype); | ||
847 | ret = -ENOTSUPP; | ||
848 | goto err_out; | ||
849 | } | ||
850 | |||
851 | if (!pdata) { | ||
852 | dev_warn(&pdev->dev, | ||
853 | "No platform data supplied, using defaults\n"); | ||
854 | s->pdata.frequency = s->freq_std; | ||
855 | } else | ||
856 | memcpy(&s->pdata, pdata, sizeof(struct sccnxp_pdata)); | ||
857 | |||
858 | s->irq = platform_get_irq(pdev, 0); | ||
859 | if (s->irq <= 0) { | ||
860 | dev_err(&pdev->dev, "Missing irq resource data\n"); | ||
861 | ret = -ENXIO; | ||
862 | goto err_out; | ||
863 | } | ||
864 | |||
865 | /* Check input frequency */ | ||
866 | if ((s->pdata.frequency < freq_min) || | ||
867 | (s->pdata.frequency > freq_max)) { | ||
868 | dev_err(&pdev->dev, "Frequency out of bounds\n"); | ||
869 | ret = -EINVAL; | ||
870 | goto err_out; | ||
871 | } | ||
872 | |||
873 | membase = devm_request_and_ioremap(&pdev->dev, res); | ||
874 | if (!membase) { | ||
875 | dev_err(&pdev->dev, "Failed to ioremap\n"); | ||
876 | ret = -EIO; | ||
877 | goto err_out; | ||
878 | } | ||
879 | |||
880 | s->uart.owner = THIS_MODULE; | ||
881 | s->uart.dev_name = "ttySC"; | ||
882 | s->uart.major = SCCNXP_MAJOR; | ||
883 | s->uart.minor = SCCNXP_MINOR; | ||
884 | #ifdef CONFIG_SERIAL_SCCNXP_CONSOLE | ||
885 | s->uart.cons = &s->console; | ||
886 | s->uart.cons->device = uart_console_device; | ||
887 | s->uart.cons->write = sccnxp_console_write; | ||
888 | s->uart.cons->setup = sccnxp_console_setup; | ||
889 | s->uart.cons->flags = CON_PRINTBUFFER; | ||
890 | s->uart.cons->index = -1; | ||
891 | s->uart.cons->data = s; | ||
892 | strcpy(s->uart.cons->name, "ttySC"); | ||
893 | #endif | ||
894 | ret = uart_register_driver(&s->uart); | ||
895 | if (ret) { | ||
896 | dev_err(&pdev->dev, "Registering UART driver failed\n"); | ||
897 | goto err_out; | ||
898 | } | ||
899 | |||
900 | for (i = 0; i < s->uart.nr; i++) { | ||
901 | s->port[i].line = i; | ||
902 | s->port[i].dev = &pdev->dev; | ||
903 | s->port[i].irq = s->irq; | ||
904 | s->port[i].type = PORT_SC26XX; | ||
905 | s->port[i].fifosize = fifosize; | ||
906 | s->port[i].flags = UPF_SKIP_TEST | UPF_FIXED_TYPE; | ||
907 | s->port[i].iotype = UPIO_MEM; | ||
908 | s->port[i].mapbase = res->start; | ||
909 | s->port[i].membase = membase; | ||
910 | s->port[i].regshift = s->pdata.reg_shift; | ||
911 | s->port[i].uartclk = s->pdata.frequency; | ||
912 | s->port[i].ops = &sccnxp_ops; | ||
913 | uart_add_one_port(&s->uart, &s->port[i]); | ||
914 | /* Set direction to input */ | ||
915 | if (s->flags & SCCNXP_HAVE_IO) | ||
916 | sccnxp_set_bit(&s->port[i], DIR_OP, 0); | ||
917 | } | ||
918 | |||
919 | /* Disable interrupts */ | ||
920 | s->imr = 0; | ||
921 | sccnxp_write(&s->port[0], SCCNXP_IMR_REG, 0); | ||
922 | |||
923 | /* Board specific configure */ | ||
924 | if (s->pdata.init) | ||
925 | s->pdata.init(); | ||
926 | |||
927 | ret = devm_request_threaded_irq(&pdev->dev, s->irq, NULL, sccnxp_ist, | ||
928 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
929 | dev_name(&pdev->dev), s); | ||
930 | if (!ret) | ||
931 | return 0; | ||
932 | |||
933 | dev_err(&pdev->dev, "Unable to reguest IRQ %i\n", s->irq); | ||
934 | |||
935 | err_out: | ||
936 | platform_set_drvdata(pdev, NULL); | ||
937 | |||
938 | return ret; | ||
939 | } | ||
940 | |||
941 | static int __devexit sccnxp_remove(struct platform_device *pdev) | ||
942 | { | ||
943 | int i; | ||
944 | struct sccnxp_port *s = platform_get_drvdata(pdev); | ||
945 | |||
946 | devm_free_irq(&pdev->dev, s->irq, s); | ||
947 | |||
948 | for (i = 0; i < s->uart.nr; i++) | ||
949 | uart_remove_one_port(&s->uart, &s->port[i]); | ||
950 | |||
951 | uart_unregister_driver(&s->uart); | ||
952 | platform_set_drvdata(pdev, NULL); | ||
953 | |||
954 | if (s->pdata.exit) | ||
955 | s->pdata.exit(); | ||
956 | |||
957 | return 0; | ||
958 | } | ||
959 | |||
960 | static const struct platform_device_id sccnxp_id_table[] = { | ||
961 | { "sc2681", SCCNXP_TYPE_SC2681 }, | ||
962 | { "sc2691", SCCNXP_TYPE_SC2691 }, | ||
963 | { "sc2692", SCCNXP_TYPE_SC2692 }, | ||
964 | { "sc2891", SCCNXP_TYPE_SC2891 }, | ||
965 | { "sc2892", SCCNXP_TYPE_SC2892 }, | ||
966 | { "sc28202", SCCNXP_TYPE_SC28202 }, | ||
967 | { "sc68681", SCCNXP_TYPE_SC68681 }, | ||
968 | { "sc68692", SCCNXP_TYPE_SC68692 }, | ||
969 | }; | ||
970 | MODULE_DEVICE_TABLE(platform, sccnxp_id_table); | ||
971 | |||
972 | static struct platform_driver sccnxp_uart_driver = { | ||
973 | .driver = { | ||
974 | .name = SCCNXP_NAME, | ||
975 | .owner = THIS_MODULE, | ||
976 | }, | ||
977 | .probe = sccnxp_probe, | ||
978 | .remove = __devexit_p(sccnxp_remove), | ||
979 | .id_table = sccnxp_id_table, | ||
980 | }; | ||
981 | module_platform_driver(sccnxp_uart_driver); | ||
982 | |||
983 | MODULE_LICENSE("GPL v2"); | ||
984 | MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>"); | ||
985 | MODULE_DESCRIPTION("SCCNXP serial driver"); | ||
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index a21dc8e3b7c0..046279ce3e8d 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -159,7 +159,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
159 | retval = uport->ops->startup(uport); | 159 | retval = uport->ops->startup(uport); |
160 | if (retval == 0) { | 160 | if (retval == 0) { |
161 | if (uart_console(uport) && uport->cons->cflag) { | 161 | if (uart_console(uport) && uport->cons->cflag) { |
162 | tty->termios->c_cflag = uport->cons->cflag; | 162 | tty->termios.c_cflag = uport->cons->cflag; |
163 | uport->cons->cflag = 0; | 163 | uport->cons->cflag = 0; |
164 | } | 164 | } |
165 | /* | 165 | /* |
@@ -172,11 +172,11 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
172 | * Setup the RTS and DTR signals once the | 172 | * Setup the RTS and DTR signals once the |
173 | * port is open and ready to respond. | 173 | * port is open and ready to respond. |
174 | */ | 174 | */ |
175 | if (tty->termios->c_cflag & CBAUD) | 175 | if (tty->termios.c_cflag & CBAUD) |
176 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); | 176 | uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR); |
177 | } | 177 | } |
178 | 178 | ||
179 | if (port->flags & ASYNC_CTS_FLOW) { | 179 | if (tty_port_cts_enabled(port)) { |
180 | spin_lock_irq(&uport->lock); | 180 | spin_lock_irq(&uport->lock); |
181 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) | 181 | if (!(uport->ops->get_mctrl(uport) & TIOCM_CTS)) |
182 | tty->hw_stopped = 1; | 182 | tty->hw_stopped = 1; |
@@ -240,7 +240,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state) | |||
240 | /* | 240 | /* |
241 | * Turn off DTR and RTS early. | 241 | * Turn off DTR and RTS early. |
242 | */ | 242 | */ |
243 | if (!tty || (tty->termios->c_cflag & HUPCL)) | 243 | if (!tty || (tty->termios.c_cflag & HUPCL)) |
244 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); | 244 | uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS); |
245 | 245 | ||
246 | uart_port_shutdown(port); | 246 | uart_port_shutdown(port); |
@@ -440,10 +440,10 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state, | |||
440 | * If we have no tty, termios, or the port does not exist, | 440 | * If we have no tty, termios, or the port does not exist, |
441 | * then we can't set the parameters for this port. | 441 | * then we can't set the parameters for this port. |
442 | */ | 442 | */ |
443 | if (!tty || !tty->termios || uport->type == PORT_UNKNOWN) | 443 | if (!tty || uport->type == PORT_UNKNOWN) |
444 | return; | 444 | return; |
445 | 445 | ||
446 | termios = tty->termios; | 446 | termios = &tty->termios; |
447 | 447 | ||
448 | /* | 448 | /* |
449 | * Set flags based on termios cflag | 449 | * Set flags based on termios cflag |
@@ -614,7 +614,7 @@ static void uart_throttle(struct tty_struct *tty) | |||
614 | if (I_IXOFF(tty)) | 614 | if (I_IXOFF(tty)) |
615 | uart_send_xchar(tty, STOP_CHAR(tty)); | 615 | uart_send_xchar(tty, STOP_CHAR(tty)); |
616 | 616 | ||
617 | if (tty->termios->c_cflag & CRTSCTS) | 617 | if (tty->termios.c_cflag & CRTSCTS) |
618 | uart_clear_mctrl(state->uart_port, TIOCM_RTS); | 618 | uart_clear_mctrl(state->uart_port, TIOCM_RTS); |
619 | } | 619 | } |
620 | 620 | ||
@@ -630,42 +630,48 @@ static void uart_unthrottle(struct tty_struct *tty) | |||
630 | uart_send_xchar(tty, START_CHAR(tty)); | 630 | uart_send_xchar(tty, START_CHAR(tty)); |
631 | } | 631 | } |
632 | 632 | ||
633 | if (tty->termios->c_cflag & CRTSCTS) | 633 | if (tty->termios.c_cflag & CRTSCTS) |
634 | uart_set_mctrl(port, TIOCM_RTS); | 634 | uart_set_mctrl(port, TIOCM_RTS); |
635 | } | 635 | } |
636 | 636 | ||
637 | static int uart_get_info(struct uart_state *state, | 637 | static void uart_get_info(struct tty_port *port, |
638 | struct serial_struct __user *retinfo) | 638 | struct uart_state *state, |
639 | struct serial_struct *retinfo) | ||
639 | { | 640 | { |
640 | struct uart_port *uport = state->uart_port; | 641 | struct uart_port *uport = state->uart_port; |
641 | struct tty_port *port = &state->port; | ||
642 | struct serial_struct tmp; | ||
643 | |||
644 | memset(&tmp, 0, sizeof(tmp)); | ||
645 | 642 | ||
646 | /* Ensure the state we copy is consistent and no hardware changes | 643 | memset(retinfo, 0, sizeof(*retinfo)); |
647 | occur as we go */ | ||
648 | mutex_lock(&port->mutex); | ||
649 | 644 | ||
650 | tmp.type = uport->type; | 645 | retinfo->type = uport->type; |
651 | tmp.line = uport->line; | 646 | retinfo->line = uport->line; |
652 | tmp.port = uport->iobase; | 647 | retinfo->port = uport->iobase; |
653 | if (HIGH_BITS_OFFSET) | 648 | if (HIGH_BITS_OFFSET) |
654 | tmp.port_high = (long) uport->iobase >> HIGH_BITS_OFFSET; | 649 | retinfo->port_high = (long) uport->iobase >> HIGH_BITS_OFFSET; |
655 | tmp.irq = uport->irq; | 650 | retinfo->irq = uport->irq; |
656 | tmp.flags = uport->flags; | 651 | retinfo->flags = uport->flags; |
657 | tmp.xmit_fifo_size = uport->fifosize; | 652 | retinfo->xmit_fifo_size = uport->fifosize; |
658 | tmp.baud_base = uport->uartclk / 16; | 653 | retinfo->baud_base = uport->uartclk / 16; |
659 | tmp.close_delay = jiffies_to_msecs(port->close_delay) / 10; | 654 | retinfo->close_delay = jiffies_to_msecs(port->close_delay) / 10; |
660 | tmp.closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 655 | retinfo->closing_wait = port->closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
661 | ASYNC_CLOSING_WAIT_NONE : | 656 | ASYNC_CLOSING_WAIT_NONE : |
662 | jiffies_to_msecs(port->closing_wait) / 10; | 657 | jiffies_to_msecs(port->closing_wait) / 10; |
663 | tmp.custom_divisor = uport->custom_divisor; | 658 | retinfo->custom_divisor = uport->custom_divisor; |
664 | tmp.hub6 = uport->hub6; | 659 | retinfo->hub6 = uport->hub6; |
665 | tmp.io_type = uport->iotype; | 660 | retinfo->io_type = uport->iotype; |
666 | tmp.iomem_reg_shift = uport->regshift; | 661 | retinfo->iomem_reg_shift = uport->regshift; |
667 | tmp.iomem_base = (void *)(unsigned long)uport->mapbase; | 662 | retinfo->iomem_base = (void *)(unsigned long)uport->mapbase; |
663 | } | ||
668 | 664 | ||
665 | static int uart_get_info_user(struct uart_state *state, | ||
666 | struct serial_struct __user *retinfo) | ||
667 | { | ||
668 | struct tty_port *port = &state->port; | ||
669 | struct serial_struct tmp; | ||
670 | |||
671 | /* Ensure the state we copy is consistent and no hardware changes | ||
672 | occur as we go */ | ||
673 | mutex_lock(&port->mutex); | ||
674 | uart_get_info(port, state, &tmp); | ||
669 | mutex_unlock(&port->mutex); | 675 | mutex_unlock(&port->mutex); |
670 | 676 | ||
671 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) | 677 | if (copy_to_user(retinfo, &tmp, sizeof(*retinfo))) |
@@ -673,42 +679,30 @@ static int uart_get_info(struct uart_state *state, | |||
673 | return 0; | 679 | return 0; |
674 | } | 680 | } |
675 | 681 | ||
676 | static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | 682 | static int uart_set_info(struct tty_struct *tty, struct tty_port *port, |
677 | struct serial_struct __user *newinfo) | 683 | struct uart_state *state, |
684 | struct serial_struct *new_info) | ||
678 | { | 685 | { |
679 | struct serial_struct new_serial; | ||
680 | struct uart_port *uport = state->uart_port; | 686 | struct uart_port *uport = state->uart_port; |
681 | struct tty_port *port = &state->port; | ||
682 | unsigned long new_port; | 687 | unsigned long new_port; |
683 | unsigned int change_irq, change_port, closing_wait; | 688 | unsigned int change_irq, change_port, closing_wait; |
684 | unsigned int old_custom_divisor, close_delay; | 689 | unsigned int old_custom_divisor, close_delay; |
685 | upf_t old_flags, new_flags; | 690 | upf_t old_flags, new_flags; |
686 | int retval = 0; | 691 | int retval = 0; |
687 | 692 | ||
688 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | 693 | new_port = new_info->port; |
689 | return -EFAULT; | ||
690 | |||
691 | new_port = new_serial.port; | ||
692 | if (HIGH_BITS_OFFSET) | 694 | if (HIGH_BITS_OFFSET) |
693 | new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET; | 695 | new_port += (unsigned long) new_info->port_high << HIGH_BITS_OFFSET; |
694 | 696 | ||
695 | new_serial.irq = irq_canonicalize(new_serial.irq); | 697 | new_info->irq = irq_canonicalize(new_info->irq); |
696 | close_delay = msecs_to_jiffies(new_serial.close_delay * 10); | 698 | close_delay = msecs_to_jiffies(new_info->close_delay * 10); |
697 | closing_wait = new_serial.closing_wait == ASYNC_CLOSING_WAIT_NONE ? | 699 | closing_wait = new_info->closing_wait == ASYNC_CLOSING_WAIT_NONE ? |
698 | ASYNC_CLOSING_WAIT_NONE : | 700 | ASYNC_CLOSING_WAIT_NONE : |
699 | msecs_to_jiffies(new_serial.closing_wait * 10); | 701 | msecs_to_jiffies(new_info->closing_wait * 10); |
700 | 702 | ||
701 | /* | ||
702 | * This semaphore protects port->count. It is also | ||
703 | * very useful to prevent opens. Also, take the | ||
704 | * port configuration semaphore to make sure that a | ||
705 | * module insertion/removal doesn't change anything | ||
706 | * under us. | ||
707 | */ | ||
708 | mutex_lock(&port->mutex); | ||
709 | 703 | ||
710 | change_irq = !(uport->flags & UPF_FIXED_PORT) | 704 | change_irq = !(uport->flags & UPF_FIXED_PORT) |
711 | && new_serial.irq != uport->irq; | 705 | && new_info->irq != uport->irq; |
712 | 706 | ||
713 | /* | 707 | /* |
714 | * Since changing the 'type' of the port changes its resource | 708 | * Since changing the 'type' of the port changes its resource |
@@ -717,29 +711,29 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
717 | */ | 711 | */ |
718 | change_port = !(uport->flags & UPF_FIXED_PORT) | 712 | change_port = !(uport->flags & UPF_FIXED_PORT) |
719 | && (new_port != uport->iobase || | 713 | && (new_port != uport->iobase || |
720 | (unsigned long)new_serial.iomem_base != uport->mapbase || | 714 | (unsigned long)new_info->iomem_base != uport->mapbase || |
721 | new_serial.hub6 != uport->hub6 || | 715 | new_info->hub6 != uport->hub6 || |
722 | new_serial.io_type != uport->iotype || | 716 | new_info->io_type != uport->iotype || |
723 | new_serial.iomem_reg_shift != uport->regshift || | 717 | new_info->iomem_reg_shift != uport->regshift || |
724 | new_serial.type != uport->type); | 718 | new_info->type != uport->type); |
725 | 719 | ||
726 | old_flags = uport->flags; | 720 | old_flags = uport->flags; |
727 | new_flags = new_serial.flags; | 721 | new_flags = new_info->flags; |
728 | old_custom_divisor = uport->custom_divisor; | 722 | old_custom_divisor = uport->custom_divisor; |
729 | 723 | ||
730 | if (!capable(CAP_SYS_ADMIN)) { | 724 | if (!capable(CAP_SYS_ADMIN)) { |
731 | retval = -EPERM; | 725 | retval = -EPERM; |
732 | if (change_irq || change_port || | 726 | if (change_irq || change_port || |
733 | (new_serial.baud_base != uport->uartclk / 16) || | 727 | (new_info->baud_base != uport->uartclk / 16) || |
734 | (close_delay != port->close_delay) || | 728 | (close_delay != port->close_delay) || |
735 | (closing_wait != port->closing_wait) || | 729 | (closing_wait != port->closing_wait) || |
736 | (new_serial.xmit_fifo_size && | 730 | (new_info->xmit_fifo_size && |
737 | new_serial.xmit_fifo_size != uport->fifosize) || | 731 | new_info->xmit_fifo_size != uport->fifosize) || |
738 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) | 732 | (((new_flags ^ old_flags) & ~UPF_USR_MASK) != 0)) |
739 | goto exit; | 733 | goto exit; |
740 | uport->flags = ((uport->flags & ~UPF_USR_MASK) | | 734 | uport->flags = ((uport->flags & ~UPF_USR_MASK) | |
741 | (new_flags & UPF_USR_MASK)); | 735 | (new_flags & UPF_USR_MASK)); |
742 | uport->custom_divisor = new_serial.custom_divisor; | 736 | uport->custom_divisor = new_info->custom_divisor; |
743 | goto check_and_exit; | 737 | goto check_and_exit; |
744 | } | 738 | } |
745 | 739 | ||
@@ -747,10 +741,10 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
747 | * Ask the low level driver to verify the settings. | 741 | * Ask the low level driver to verify the settings. |
748 | */ | 742 | */ |
749 | if (uport->ops->verify_port) | 743 | if (uport->ops->verify_port) |
750 | retval = uport->ops->verify_port(uport, &new_serial); | 744 | retval = uport->ops->verify_port(uport, new_info); |
751 | 745 | ||
752 | if ((new_serial.irq >= nr_irqs) || (new_serial.irq < 0) || | 746 | if ((new_info->irq >= nr_irqs) || (new_info->irq < 0) || |
753 | (new_serial.baud_base < 9600)) | 747 | (new_info->baud_base < 9600)) |
754 | retval = -EINVAL; | 748 | retval = -EINVAL; |
755 | 749 | ||
756 | if (retval) | 750 | if (retval) |
@@ -790,11 +784,11 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
790 | uport->ops->release_port(uport); | 784 | uport->ops->release_port(uport); |
791 | 785 | ||
792 | uport->iobase = new_port; | 786 | uport->iobase = new_port; |
793 | uport->type = new_serial.type; | 787 | uport->type = new_info->type; |
794 | uport->hub6 = new_serial.hub6; | 788 | uport->hub6 = new_info->hub6; |
795 | uport->iotype = new_serial.io_type; | 789 | uport->iotype = new_info->io_type; |
796 | uport->regshift = new_serial.iomem_reg_shift; | 790 | uport->regshift = new_info->iomem_reg_shift; |
797 | uport->mapbase = (unsigned long)new_serial.iomem_base; | 791 | uport->mapbase = (unsigned long)new_info->iomem_base; |
798 | 792 | ||
799 | /* | 793 | /* |
800 | * Claim and map the new regions | 794 | * Claim and map the new regions |
@@ -835,16 +829,16 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
835 | } | 829 | } |
836 | 830 | ||
837 | if (change_irq) | 831 | if (change_irq) |
838 | uport->irq = new_serial.irq; | 832 | uport->irq = new_info->irq; |
839 | if (!(uport->flags & UPF_FIXED_PORT)) | 833 | if (!(uport->flags & UPF_FIXED_PORT)) |
840 | uport->uartclk = new_serial.baud_base * 16; | 834 | uport->uartclk = new_info->baud_base * 16; |
841 | uport->flags = (uport->flags & ~UPF_CHANGE_MASK) | | 835 | uport->flags = (uport->flags & ~UPF_CHANGE_MASK) | |
842 | (new_flags & UPF_CHANGE_MASK); | 836 | (new_flags & UPF_CHANGE_MASK); |
843 | uport->custom_divisor = new_serial.custom_divisor; | 837 | uport->custom_divisor = new_info->custom_divisor; |
844 | port->close_delay = close_delay; | 838 | port->close_delay = close_delay; |
845 | port->closing_wait = closing_wait; | 839 | port->closing_wait = closing_wait; |
846 | if (new_serial.xmit_fifo_size) | 840 | if (new_info->xmit_fifo_size) |
847 | uport->fifosize = new_serial.xmit_fifo_size; | 841 | uport->fifosize = new_info->xmit_fifo_size; |
848 | if (port->tty) | 842 | if (port->tty) |
849 | port->tty->low_latency = | 843 | port->tty->low_latency = |
850 | (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; | 844 | (uport->flags & UPF_LOW_LATENCY) ? 1 : 0; |
@@ -873,6 +867,28 @@ static int uart_set_info(struct tty_struct *tty, struct uart_state *state, | |||
873 | } else | 867 | } else |
874 | retval = uart_startup(tty, state, 1); | 868 | retval = uart_startup(tty, state, 1); |
875 | exit: | 869 | exit: |
870 | return retval; | ||
871 | } | ||
872 | |||
873 | static int uart_set_info_user(struct tty_struct *tty, struct uart_state *state, | ||
874 | struct serial_struct __user *newinfo) | ||
875 | { | ||
876 | struct serial_struct new_serial; | ||
877 | struct tty_port *port = &state->port; | ||
878 | int retval; | ||
879 | |||
880 | if (copy_from_user(&new_serial, newinfo, sizeof(new_serial))) | ||
881 | return -EFAULT; | ||
882 | |||
883 | /* | ||
884 | * This semaphore protects port->count. It is also | ||
885 | * very useful to prevent opens. Also, take the | ||
886 | * port configuration semaphore to make sure that a | ||
887 | * module insertion/removal doesn't change anything | ||
888 | * under us. | ||
889 | */ | ||
890 | mutex_lock(&port->mutex); | ||
891 | retval = uart_set_info(tty, port, state, &new_serial); | ||
876 | mutex_unlock(&port->mutex); | 892 | mutex_unlock(&port->mutex); |
877 | return retval; | 893 | return retval; |
878 | } | 894 | } |
@@ -1115,11 +1131,11 @@ uart_ioctl(struct tty_struct *tty, unsigned int cmd, | |||
1115 | */ | 1131 | */ |
1116 | switch (cmd) { | 1132 | switch (cmd) { |
1117 | case TIOCGSERIAL: | 1133 | case TIOCGSERIAL: |
1118 | ret = uart_get_info(state, uarg); | 1134 | ret = uart_get_info_user(state, uarg); |
1119 | break; | 1135 | break; |
1120 | 1136 | ||
1121 | case TIOCSSERIAL: | 1137 | case TIOCSSERIAL: |
1122 | ret = uart_set_info(tty, state, uarg); | 1138 | ret = uart_set_info_user(tty, state, uarg); |
1123 | break; | 1139 | break; |
1124 | 1140 | ||
1125 | case TIOCSERCONFIG: | 1141 | case TIOCSERCONFIG: |
@@ -1187,7 +1203,7 @@ static void uart_set_ldisc(struct tty_struct *tty) | |||
1187 | struct uart_port *uport = state->uart_port; | 1203 | struct uart_port *uport = state->uart_port; |
1188 | 1204 | ||
1189 | if (uport->ops->set_ldisc) | 1205 | if (uport->ops->set_ldisc) |
1190 | uport->ops->set_ldisc(uport, tty->termios->c_line); | 1206 | uport->ops->set_ldisc(uport, tty->termios.c_line); |
1191 | } | 1207 | } |
1192 | 1208 | ||
1193 | static void uart_set_termios(struct tty_struct *tty, | 1209 | static void uart_set_termios(struct tty_struct *tty, |
@@ -1195,7 +1211,7 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1195 | { | 1211 | { |
1196 | struct uart_state *state = tty->driver_data; | 1212 | struct uart_state *state = tty->driver_data; |
1197 | unsigned long flags; | 1213 | unsigned long flags; |
1198 | unsigned int cflag = tty->termios->c_cflag; | 1214 | unsigned int cflag = tty->termios.c_cflag; |
1199 | 1215 | ||
1200 | 1216 | ||
1201 | /* | 1217 | /* |
@@ -1206,9 +1222,9 @@ static void uart_set_termios(struct tty_struct *tty, | |||
1206 | */ | 1222 | */ |
1207 | #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) | 1223 | #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) |
1208 | if ((cflag ^ old_termios->c_cflag) == 0 && | 1224 | if ((cflag ^ old_termios->c_cflag) == 0 && |
1209 | tty->termios->c_ospeed == old_termios->c_ospeed && | 1225 | tty->termios.c_ospeed == old_termios->c_ospeed && |
1210 | tty->termios->c_ispeed == old_termios->c_ispeed && | 1226 | tty->termios.c_ispeed == old_termios->c_ispeed && |
1211 | RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) { | 1227 | RELEVANT_IFLAG(tty->termios.c_iflag ^ old_termios->c_iflag) == 0) { |
1212 | return; | 1228 | return; |
1213 | } | 1229 | } |
1214 | 1230 | ||
@@ -1960,8 +1976,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport) | |||
1960 | /* | 1976 | /* |
1961 | * If that's unset, use the tty termios setting. | 1977 | * If that's unset, use the tty termios setting. |
1962 | */ | 1978 | */ |
1963 | if (port->tty && port->tty->termios && termios.c_cflag == 0) | 1979 | if (port->tty && termios.c_cflag == 0) |
1964 | termios = *(port->tty->termios); | 1980 | termios = port->tty->termios; |
1965 | 1981 | ||
1966 | if (console_suspend_enabled) | 1982 | if (console_suspend_enabled) |
1967 | uart_change_pm(state, 0); | 1983 | uart_change_pm(state, 0); |
@@ -2293,6 +2309,36 @@ struct tty_driver *uart_console_device(struct console *co, int *index) | |||
2293 | return p->tty_driver; | 2309 | return p->tty_driver; |
2294 | } | 2310 | } |
2295 | 2311 | ||
2312 | static ssize_t uart_get_attr_uartclk(struct device *dev, | ||
2313 | struct device_attribute *attr, char *buf) | ||
2314 | { | ||
2315 | int ret; | ||
2316 | struct tty_port *port = dev_get_drvdata(dev); | ||
2317 | struct uart_state *state = container_of(port, struct uart_state, port); | ||
2318 | |||
2319 | mutex_lock(&state->port.mutex); | ||
2320 | ret = snprintf(buf, PAGE_SIZE, "%d\n", state->uart_port->uartclk); | ||
2321 | mutex_unlock(&state->port.mutex); | ||
2322 | |||
2323 | return ret; | ||
2324 | } | ||
2325 | |||
2326 | static DEVICE_ATTR(uartclk, S_IRUSR | S_IRGRP, uart_get_attr_uartclk, NULL); | ||
2327 | |||
2328 | static struct attribute *tty_dev_attrs[] = { | ||
2329 | &dev_attr_uartclk.attr, | ||
2330 | NULL, | ||
2331 | }; | ||
2332 | |||
2333 | static const struct attribute_group tty_dev_attr_group = { | ||
2334 | .attrs = tty_dev_attrs, | ||
2335 | }; | ||
2336 | |||
2337 | static const struct attribute_group *tty_dev_attr_groups[] = { | ||
2338 | &tty_dev_attr_group, | ||
2339 | NULL | ||
2340 | }; | ||
2341 | |||
2296 | /** | 2342 | /** |
2297 | * uart_add_one_port - attach a driver-defined port structure | 2343 | * uart_add_one_port - attach a driver-defined port structure |
2298 | * @drv: pointer to the uart low level driver structure for this port | 2344 | * @drv: pointer to the uart low level driver structure for this port |
@@ -2346,7 +2392,8 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *uport) | |||
2346 | * Register the port whether it's detected or not. This allows | 2392 | * Register the port whether it's detected or not. This allows |
2347 | * setserial to be used to alter this ports parameters. | 2393 | * setserial to be used to alter this ports parameters. |
2348 | */ | 2394 | */ |
2349 | tty_dev = tty_register_device(drv->tty_driver, uport->line, uport->dev); | 2395 | tty_dev = tty_port_register_device_attr(port, drv->tty_driver, |
2396 | uport->line, uport->dev, port, tty_dev_attr_groups); | ||
2350 | if (likely(!IS_ERR(tty_dev))) { | 2397 | if (likely(!IS_ERR(tty_dev))) { |
2351 | device_set_wakeup_capable(tty_dev, 1); | 2398 | device_set_wakeup_capable(tty_dev, 1); |
2352 | } else { | 2399 | } else { |
@@ -2492,7 +2539,7 @@ void uart_handle_cts_change(struct uart_port *uport, unsigned int status) | |||
2492 | 2539 | ||
2493 | uport->icount.cts++; | 2540 | uport->icount.cts++; |
2494 | 2541 | ||
2495 | if (port->flags & ASYNC_CTS_FLOW) { | 2542 | if (tty_port_cts_enabled(port)) { |
2496 | if (tty->hw_stopped) { | 2543 | if (tty->hw_stopped) { |
2497 | if (status) { | 2544 | if (status) { |
2498 | tty->hw_stopped = 0; | 2545 | tty->hw_stopped = 0; |
diff --git a/drivers/tty/serial/serial_ks8695.c b/drivers/tty/serial/serial_ks8695.c index 7c13639c597e..9bd004f9da89 100644 --- a/drivers/tty/serial/serial_ks8695.c +++ b/drivers/tty/serial/serial_ks8695.c | |||
@@ -548,8 +548,8 @@ static struct uart_ops ks8695uart_pops = { | |||
548 | 548 | ||
549 | static struct uart_port ks8695uart_ports[SERIAL_KS8695_NR] = { | 549 | static struct uart_port ks8695uart_ports[SERIAL_KS8695_NR] = { |
550 | { | 550 | { |
551 | .membase = (void *) KS8695_UART_VA, | 551 | .membase = KS8695_UART_VA, |
552 | .mapbase = KS8695_UART_VA, | 552 | .mapbase = KS8695_UART_PA, |
553 | .iotype = SERIAL_IO_MEM, | 553 | .iotype = SERIAL_IO_MEM, |
554 | .irq = KS8695_IRQ_UART_TX, | 554 | .irq = KS8695_IRQ_UART_TX, |
555 | .uartclk = KS8695_CLOCK_RATE * 16, | 555 | .uartclk = KS8695_CLOCK_RATE * 16, |
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 5b3eda2024fe..a9e2bd1ab534 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
@@ -668,7 +668,7 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
668 | if (res == NULL) { | 668 | if (res == NULL) { |
669 | dev_err(&pdev->dev, "Insufficient resources.\n"); | 669 | dev_err(&pdev->dev, "Insufficient resources.\n"); |
670 | ret = -EFAULT; | 670 | ret = -EFAULT; |
671 | goto irq_err; | 671 | goto err; |
672 | } | 672 | } |
673 | port->irq = res->start; | 673 | port->irq = res->start; |
674 | 674 | ||
@@ -676,7 +676,7 @@ int sirfsoc_uart_probe(struct platform_device *pdev) | |||
676 | sirfport->p = pinctrl_get_select_default(&pdev->dev); | 676 | sirfport->p = pinctrl_get_select_default(&pdev->dev); |
677 | ret = IS_ERR(sirfport->p); | 677 | ret = IS_ERR(sirfport->p); |
678 | if (ret) | 678 | if (ret) |
679 | goto pin_err; | 679 | goto err; |
680 | } | 680 | } |
681 | 681 | ||
682 | port->ops = &sirfsoc_uart_ops; | 682 | port->ops = &sirfsoc_uart_ops; |
@@ -695,9 +695,6 @@ port_err: | |||
695 | platform_set_drvdata(pdev, NULL); | 695 | platform_set_drvdata(pdev, NULL); |
696 | if (sirfport->hw_flow_ctrl) | 696 | if (sirfport->hw_flow_ctrl) |
697 | pinctrl_put(sirfport->p); | 697 | pinctrl_put(sirfport->p); |
698 | pin_err: | ||
699 | irq_err: | ||
700 | devm_iounmap(&pdev->dev, port->membase); | ||
701 | err: | 698 | err: |
702 | return ret; | 699 | return ret; |
703 | } | 700 | } |
@@ -709,7 +706,6 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) | |||
709 | platform_set_drvdata(pdev, NULL); | 706 | platform_set_drvdata(pdev, NULL); |
710 | if (sirfport->hw_flow_ctrl) | 707 | if (sirfport->hw_flow_ctrl) |
711 | pinctrl_put(sirfport->p); | 708 | pinctrl_put(sirfport->p); |
712 | devm_iounmap(&pdev->dev, port->membase); | ||
713 | uart_remove_one_port(&sirfsoc_uart_drv, port); | 709 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
714 | return 0; | 710 | return 0; |
715 | } | 711 | } |
diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index 675303b8ed84..b97913dcdbff 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c | |||
@@ -58,10 +58,16 @@ | |||
58 | enum su_type { SU_PORT_NONE, SU_PORT_MS, SU_PORT_KBD, SU_PORT_PORT }; | 58 | enum su_type { SU_PORT_NONE, SU_PORT_MS, SU_PORT_KBD, SU_PORT_PORT }; |
59 | static char *su_typev[] = { "su(???)", "su(mouse)", "su(kbd)", "su(serial)" }; | 59 | static char *su_typev[] = { "su(???)", "su(mouse)", "su(kbd)", "su(serial)" }; |
60 | 60 | ||
61 | struct serial_uart_config { | ||
62 | char *name; | ||
63 | int dfl_xmit_fifo_size; | ||
64 | int flags; | ||
65 | }; | ||
66 | |||
61 | /* | 67 | /* |
62 | * Here we define the default xmit fifo size used for each type of UART. | 68 | * Here we define the default xmit fifo size used for each type of UART. |
63 | */ | 69 | */ |
64 | static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = { | 70 | static const struct serial_uart_config uart_config[] = { |
65 | { "unknown", 1, 0 }, | 71 | { "unknown", 1, 0 }, |
66 | { "8250", 1, 0 }, | 72 | { "8250", 1, 0 }, |
67 | { "16450", 1, 0 }, | 73 | { "16450", 1, 0 }, |
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c index 593d40ad0a6b..70e3a525bc82 100644 --- a/drivers/tty/synclink.c +++ b/drivers/tty/synclink.c | |||
@@ -1359,7 +1359,7 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info ) | |||
1359 | } | 1359 | } |
1360 | } | 1360 | } |
1361 | 1361 | ||
1362 | if ( (info->port.flags & ASYNC_CTS_FLOW) && | 1362 | if (tty_port_cts_enabled(&info->port) && |
1363 | (status & MISCSTATUS_CTS_LATCHED) ) { | 1363 | (status & MISCSTATUS_CTS_LATCHED) ) { |
1364 | if (info->port.tty->hw_stopped) { | 1364 | if (info->port.tty->hw_stopped) { |
1365 | if (status & MISCSTATUS_CTS) { | 1365 | if (status & MISCSTATUS_CTS) { |
@@ -1840,22 +1840,22 @@ static void shutdown(struct mgsl_struct * info) | |||
1840 | usc_DisableInterrupts(info,RECEIVE_DATA + RECEIVE_STATUS + | 1840 | usc_DisableInterrupts(info,RECEIVE_DATA + RECEIVE_STATUS + |
1841 | TRANSMIT_DATA + TRANSMIT_STATUS + IO_PIN + MISC ); | 1841 | TRANSMIT_DATA + TRANSMIT_STATUS + IO_PIN + MISC ); |
1842 | usc_DisableDmaInterrupts(info,DICR_MASTER + DICR_TRANSMIT + DICR_RECEIVE); | 1842 | usc_DisableDmaInterrupts(info,DICR_MASTER + DICR_TRANSMIT + DICR_RECEIVE); |
1843 | 1843 | ||
1844 | /* Disable DMAEN (Port 7, Bit 14) */ | 1844 | /* Disable DMAEN (Port 7, Bit 14) */ |
1845 | /* This disconnects the DMA request signal from the ISA bus */ | 1845 | /* This disconnects the DMA request signal from the ISA bus */ |
1846 | /* on the ISA adapter. This has no effect for the PCI adapter */ | 1846 | /* on the ISA adapter. This has no effect for the PCI adapter */ |
1847 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) | BIT14)); | 1847 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) | BIT14)); |
1848 | 1848 | ||
1849 | /* Disable INTEN (Port 6, Bit12) */ | 1849 | /* Disable INTEN (Port 6, Bit12) */ |
1850 | /* This disconnects the IRQ request signal to the ISA bus */ | 1850 | /* This disconnects the IRQ request signal to the ISA bus */ |
1851 | /* on the ISA adapter. This has no effect for the PCI adapter */ | 1851 | /* on the ISA adapter. This has no effect for the PCI adapter */ |
1852 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); | 1852 | usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); |
1853 | 1853 | ||
1854 | if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { | 1854 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
1855 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 1855 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); |
1856 | usc_set_serial_signals(info); | 1856 | usc_set_serial_signals(info); |
1857 | } | 1857 | } |
1858 | 1858 | ||
1859 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 1859 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
1860 | 1860 | ||
1861 | mgsl_release_resources(info); | 1861 | mgsl_release_resources(info); |
@@ -1895,7 +1895,7 @@ static void mgsl_program_hw(struct mgsl_struct *info) | |||
1895 | usc_EnableInterrupts(info, IO_PIN); | 1895 | usc_EnableInterrupts(info, IO_PIN); |
1896 | usc_get_serial_signals(info); | 1896 | usc_get_serial_signals(info); |
1897 | 1897 | ||
1898 | if (info->netcount || info->port.tty->termios->c_cflag & CREAD) | 1898 | if (info->netcount || info->port.tty->termios.c_cflag & CREAD) |
1899 | usc_start_receiver(info); | 1899 | usc_start_receiver(info); |
1900 | 1900 | ||
1901 | spin_unlock_irqrestore(&info->irq_spinlock,flags); | 1901 | spin_unlock_irqrestore(&info->irq_spinlock,flags); |
@@ -1908,14 +1908,14 @@ static void mgsl_change_params(struct mgsl_struct *info) | |||
1908 | unsigned cflag; | 1908 | unsigned cflag; |
1909 | int bits_per_char; | 1909 | int bits_per_char; |
1910 | 1910 | ||
1911 | if (!info->port.tty || !info->port.tty->termios) | 1911 | if (!info->port.tty) |
1912 | return; | 1912 | return; |
1913 | 1913 | ||
1914 | if (debug_level >= DEBUG_LEVEL_INFO) | 1914 | if (debug_level >= DEBUG_LEVEL_INFO) |
1915 | printk("%s(%d):mgsl_change_params(%s)\n", | 1915 | printk("%s(%d):mgsl_change_params(%s)\n", |
1916 | __FILE__,__LINE__, info->device_name ); | 1916 | __FILE__,__LINE__, info->device_name ); |
1917 | 1917 | ||
1918 | cflag = info->port.tty->termios->c_cflag; | 1918 | cflag = info->port.tty->termios.c_cflag; |
1919 | 1919 | ||
1920 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 1920 | /* if B0 rate (hangup) specified then negate DTR and RTS */ |
1921 | /* otherwise assert DTR and RTS */ | 1921 | /* otherwise assert DTR and RTS */ |
@@ -2367,8 +2367,8 @@ static void mgsl_throttle(struct tty_struct * tty) | |||
2367 | 2367 | ||
2368 | if (I_IXOFF(tty)) | 2368 | if (I_IXOFF(tty)) |
2369 | mgsl_send_xchar(tty, STOP_CHAR(tty)); | 2369 | mgsl_send_xchar(tty, STOP_CHAR(tty)); |
2370 | 2370 | ||
2371 | if (tty->termios->c_cflag & CRTSCTS) { | 2371 | if (tty->termios.c_cflag & CRTSCTS) { |
2372 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2372 | spin_lock_irqsave(&info->irq_spinlock,flags); |
2373 | info->serial_signals &= ~SerialSignal_RTS; | 2373 | info->serial_signals &= ~SerialSignal_RTS; |
2374 | usc_set_serial_signals(info); | 2374 | usc_set_serial_signals(info); |
@@ -2401,8 +2401,8 @@ static void mgsl_unthrottle(struct tty_struct * tty) | |||
2401 | else | 2401 | else |
2402 | mgsl_send_xchar(tty, START_CHAR(tty)); | 2402 | mgsl_send_xchar(tty, START_CHAR(tty)); |
2403 | } | 2403 | } |
2404 | 2404 | ||
2405 | if (tty->termios->c_cflag & CRTSCTS) { | 2405 | if (tty->termios.c_cflag & CRTSCTS) { |
2406 | spin_lock_irqsave(&info->irq_spinlock,flags); | 2406 | spin_lock_irqsave(&info->irq_spinlock,flags); |
2407 | info->serial_signals |= SerialSignal_RTS; | 2407 | info->serial_signals |= SerialSignal_RTS; |
2408 | usc_set_serial_signals(info); | 2408 | usc_set_serial_signals(info); |
@@ -3045,7 +3045,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
3045 | 3045 | ||
3046 | /* Handle transition to B0 status */ | 3046 | /* Handle transition to B0 status */ |
3047 | if (old_termios->c_cflag & CBAUD && | 3047 | if (old_termios->c_cflag & CBAUD && |
3048 | !(tty->termios->c_cflag & CBAUD)) { | 3048 | !(tty->termios.c_cflag & CBAUD)) { |
3049 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 3049 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); |
3050 | spin_lock_irqsave(&info->irq_spinlock,flags); | 3050 | spin_lock_irqsave(&info->irq_spinlock,flags); |
3051 | usc_set_serial_signals(info); | 3051 | usc_set_serial_signals(info); |
@@ -3054,9 +3054,9 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
3054 | 3054 | ||
3055 | /* Handle transition away from B0 status */ | 3055 | /* Handle transition away from B0 status */ |
3056 | if (!(old_termios->c_cflag & CBAUD) && | 3056 | if (!(old_termios->c_cflag & CBAUD) && |
3057 | tty->termios->c_cflag & CBAUD) { | 3057 | tty->termios.c_cflag & CBAUD) { |
3058 | info->serial_signals |= SerialSignal_DTR; | 3058 | info->serial_signals |= SerialSignal_DTR; |
3059 | if (!(tty->termios->c_cflag & CRTSCTS) || | 3059 | if (!(tty->termios.c_cflag & CRTSCTS) || |
3060 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 3060 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
3061 | info->serial_signals |= SerialSignal_RTS; | 3061 | info->serial_signals |= SerialSignal_RTS; |
3062 | } | 3062 | } |
@@ -3067,7 +3067,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio | |||
3067 | 3067 | ||
3068 | /* Handle turning off CRTSCTS */ | 3068 | /* Handle turning off CRTSCTS */ |
3069 | if (old_termios->c_cflag & CRTSCTS && | 3069 | if (old_termios->c_cflag & CRTSCTS && |
3070 | !(tty->termios->c_cflag & CRTSCTS)) { | 3070 | !(tty->termios.c_cflag & CRTSCTS)) { |
3071 | tty->hw_stopped = 0; | 3071 | tty->hw_stopped = 0; |
3072 | mgsl_start(tty); | 3072 | mgsl_start(tty); |
3073 | } | 3073 | } |
@@ -3287,7 +3287,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3287 | return 0; | 3287 | return 0; |
3288 | } | 3288 | } |
3289 | 3289 | ||
3290 | if (tty->termios->c_cflag & CLOCAL) | 3290 | if (tty->termios.c_cflag & CLOCAL) |
3291 | do_clocal = true; | 3291 | do_clocal = true; |
3292 | 3292 | ||
3293 | /* Wait for carrier detect and the line to become | 3293 | /* Wait for carrier detect and the line to become |
@@ -3313,7 +3313,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3313 | port->blocked_open++; | 3313 | port->blocked_open++; |
3314 | 3314 | ||
3315 | while (1) { | 3315 | while (1) { |
3316 | if (tty->termios->c_cflag & CBAUD) | 3316 | if (tty->termios.c_cflag & CBAUD) |
3317 | tty_port_raise_dtr_rts(port); | 3317 | tty_port_raise_dtr_rts(port); |
3318 | 3318 | ||
3319 | set_current_state(TASK_INTERRUPTIBLE); | 3319 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -3338,9 +3338,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3338 | printk("%s(%d):block_til_ready blocking on %s count=%d\n", | 3338 | printk("%s(%d):block_til_ready blocking on %s count=%d\n", |
3339 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3339 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3340 | 3340 | ||
3341 | tty_unlock(); | 3341 | tty_unlock(tty); |
3342 | schedule(); | 3342 | schedule(); |
3343 | tty_lock(); | 3343 | tty_lock(tty); |
3344 | } | 3344 | } |
3345 | 3345 | ||
3346 | set_current_state(TASK_RUNNING); | 3346 | set_current_state(TASK_RUNNING); |
@@ -3362,6 +3362,29 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3362 | 3362 | ||
3363 | } /* end of block_til_ready() */ | 3363 | } /* end of block_til_ready() */ |
3364 | 3364 | ||
3365 | static int mgsl_install(struct tty_driver *driver, struct tty_struct *tty) | ||
3366 | { | ||
3367 | struct mgsl_struct *info; | ||
3368 | int line = tty->index; | ||
3369 | |||
3370 | /* verify range of specified line number */ | ||
3371 | if (line >= mgsl_device_count) { | ||
3372 | printk("%s(%d):mgsl_open with invalid line #%d.\n", | ||
3373 | __FILE__, __LINE__, line); | ||
3374 | return -ENODEV; | ||
3375 | } | ||
3376 | |||
3377 | /* find the info structure for the specified line */ | ||
3378 | info = mgsl_device_list; | ||
3379 | while (info && info->line != line) | ||
3380 | info = info->next_device; | ||
3381 | if (mgsl_paranoia_check(info, tty->name, "mgsl_open")) | ||
3382 | return -ENODEV; | ||
3383 | tty->driver_data = info; | ||
3384 | |||
3385 | return tty_port_install(&info->port, driver, tty); | ||
3386 | } | ||
3387 | |||
3365 | /* mgsl_open() | 3388 | /* mgsl_open() |
3366 | * | 3389 | * |
3367 | * Called when a port is opened. Init and enable port. | 3390 | * Called when a port is opened. Init and enable port. |
@@ -3374,26 +3397,10 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
3374 | */ | 3397 | */ |
3375 | static int mgsl_open(struct tty_struct *tty, struct file * filp) | 3398 | static int mgsl_open(struct tty_struct *tty, struct file * filp) |
3376 | { | 3399 | { |
3377 | struct mgsl_struct *info; | 3400 | struct mgsl_struct *info = tty->driver_data; |
3378 | int retval, line; | ||
3379 | unsigned long flags; | 3401 | unsigned long flags; |
3402 | int retval; | ||
3380 | 3403 | ||
3381 | /* verify range of specified line number */ | ||
3382 | line = tty->index; | ||
3383 | if (line >= mgsl_device_count) { | ||
3384 | printk("%s(%d):mgsl_open with invalid line #%d.\n", | ||
3385 | __FILE__,__LINE__,line); | ||
3386 | return -ENODEV; | ||
3387 | } | ||
3388 | |||
3389 | /* find the info structure for the specified line */ | ||
3390 | info = mgsl_device_list; | ||
3391 | while(info && info->line != line) | ||
3392 | info = info->next_device; | ||
3393 | if (mgsl_paranoia_check(info, tty->name, "mgsl_open")) | ||
3394 | return -ENODEV; | ||
3395 | |||
3396 | tty->driver_data = info; | ||
3397 | info->port.tty = tty; | 3404 | info->port.tty = tty; |
3398 | 3405 | ||
3399 | if (debug_level >= DEBUG_LEVEL_INFO) | 3406 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -4297,6 +4304,7 @@ static struct mgsl_struct* mgsl_allocate_device(void) | |||
4297 | } /* end of mgsl_allocate_device()*/ | 4304 | } /* end of mgsl_allocate_device()*/ |
4298 | 4305 | ||
4299 | static const struct tty_operations mgsl_ops = { | 4306 | static const struct tty_operations mgsl_ops = { |
4307 | .install = mgsl_install, | ||
4300 | .open = mgsl_open, | 4308 | .open = mgsl_open, |
4301 | .close = mgsl_close, | 4309 | .close = mgsl_close, |
4302 | .write = mgsl_write, | 4310 | .write = mgsl_write, |
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c index aa1debf97cc7..b38e954eedd3 100644 --- a/drivers/tty/synclink_gt.c +++ b/drivers/tty/synclink_gt.c | |||
@@ -785,7 +785,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
785 | 785 | ||
786 | /* Handle transition to B0 status */ | 786 | /* Handle transition to B0 status */ |
787 | if (old_termios->c_cflag & CBAUD && | 787 | if (old_termios->c_cflag & CBAUD && |
788 | !(tty->termios->c_cflag & CBAUD)) { | 788 | !(tty->termios.c_cflag & CBAUD)) { |
789 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 789 | info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR); |
790 | spin_lock_irqsave(&info->lock,flags); | 790 | spin_lock_irqsave(&info->lock,flags); |
791 | set_signals(info); | 791 | set_signals(info); |
@@ -794,9 +794,9 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
794 | 794 | ||
795 | /* Handle transition away from B0 status */ | 795 | /* Handle transition away from B0 status */ |
796 | if (!(old_termios->c_cflag & CBAUD) && | 796 | if (!(old_termios->c_cflag & CBAUD) && |
797 | tty->termios->c_cflag & CBAUD) { | 797 | tty->termios.c_cflag & CBAUD) { |
798 | info->signals |= SerialSignal_DTR; | 798 | info->signals |= SerialSignal_DTR; |
799 | if (!(tty->termios->c_cflag & CRTSCTS) || | 799 | if (!(tty->termios.c_cflag & CRTSCTS) || |
800 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 800 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
801 | info->signals |= SerialSignal_RTS; | 801 | info->signals |= SerialSignal_RTS; |
802 | } | 802 | } |
@@ -807,7 +807,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
807 | 807 | ||
808 | /* Handle turning off CRTSCTS */ | 808 | /* Handle turning off CRTSCTS */ |
809 | if (old_termios->c_cflag & CRTSCTS && | 809 | if (old_termios->c_cflag & CRTSCTS && |
810 | !(tty->termios->c_cflag & CRTSCTS)) { | 810 | !(tty->termios.c_cflag & CRTSCTS)) { |
811 | tty->hw_stopped = 0; | 811 | tty->hw_stopped = 0; |
812 | tx_release(tty); | 812 | tx_release(tty); |
813 | } | 813 | } |
@@ -1372,7 +1372,7 @@ static void throttle(struct tty_struct * tty) | |||
1372 | DBGINFO(("%s throttle\n", info->device_name)); | 1372 | DBGINFO(("%s throttle\n", info->device_name)); |
1373 | if (I_IXOFF(tty)) | 1373 | if (I_IXOFF(tty)) |
1374 | send_xchar(tty, STOP_CHAR(tty)); | 1374 | send_xchar(tty, STOP_CHAR(tty)); |
1375 | if (tty->termios->c_cflag & CRTSCTS) { | 1375 | if (tty->termios.c_cflag & CRTSCTS) { |
1376 | spin_lock_irqsave(&info->lock,flags); | 1376 | spin_lock_irqsave(&info->lock,flags); |
1377 | info->signals &= ~SerialSignal_RTS; | 1377 | info->signals &= ~SerialSignal_RTS; |
1378 | set_signals(info); | 1378 | set_signals(info); |
@@ -1397,7 +1397,7 @@ static void unthrottle(struct tty_struct * tty) | |||
1397 | else | 1397 | else |
1398 | send_xchar(tty, START_CHAR(tty)); | 1398 | send_xchar(tty, START_CHAR(tty)); |
1399 | } | 1399 | } |
1400 | if (tty->termios->c_cflag & CRTSCTS) { | 1400 | if (tty->termios.c_cflag & CRTSCTS) { |
1401 | spin_lock_irqsave(&info->lock,flags); | 1401 | spin_lock_irqsave(&info->lock,flags); |
1402 | info->signals |= SerialSignal_RTS; | 1402 | info->signals |= SerialSignal_RTS; |
1403 | set_signals(info); | 1403 | set_signals(info); |
@@ -2053,7 +2053,7 @@ static void cts_change(struct slgt_info *info, unsigned short status) | |||
2053 | wake_up_interruptible(&info->event_wait_q); | 2053 | wake_up_interruptible(&info->event_wait_q); |
2054 | info->pending_bh |= BH_STATUS; | 2054 | info->pending_bh |= BH_STATUS; |
2055 | 2055 | ||
2056 | if (info->port.flags & ASYNC_CTS_FLOW) { | 2056 | if (tty_port_cts_enabled(&info->port)) { |
2057 | if (info->port.tty) { | 2057 | if (info->port.tty) { |
2058 | if (info->port.tty->hw_stopped) { | 2058 | if (info->port.tty->hw_stopped) { |
2059 | if (info->signals & SerialSignal_CTS) { | 2059 | if (info->signals & SerialSignal_CTS) { |
@@ -2493,7 +2493,7 @@ static void shutdown(struct slgt_info *info) | |||
2493 | 2493 | ||
2494 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); | 2494 | slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); |
2495 | 2495 | ||
2496 | if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { | 2496 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
2497 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2497 | info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); |
2498 | set_signals(info); | 2498 | set_signals(info); |
2499 | } | 2499 | } |
@@ -2534,7 +2534,7 @@ static void program_hw(struct slgt_info *info) | |||
2534 | get_signals(info); | 2534 | get_signals(info); |
2535 | 2535 | ||
2536 | if (info->netcount || | 2536 | if (info->netcount || |
2537 | (info->port.tty && info->port.tty->termios->c_cflag & CREAD)) | 2537 | (info->port.tty && info->port.tty->termios.c_cflag & CREAD)) |
2538 | rx_start(info); | 2538 | rx_start(info); |
2539 | 2539 | ||
2540 | spin_unlock_irqrestore(&info->lock,flags); | 2540 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -2548,11 +2548,11 @@ static void change_params(struct slgt_info *info) | |||
2548 | unsigned cflag; | 2548 | unsigned cflag; |
2549 | int bits_per_char; | 2549 | int bits_per_char; |
2550 | 2550 | ||
2551 | if (!info->port.tty || !info->port.tty->termios) | 2551 | if (!info->port.tty) |
2552 | return; | 2552 | return; |
2553 | DBGINFO(("%s change_params\n", info->device_name)); | 2553 | DBGINFO(("%s change_params\n", info->device_name)); |
2554 | 2554 | ||
2555 | cflag = info->port.tty->termios->c_cflag; | 2555 | cflag = info->port.tty->termios.c_cflag; |
2556 | 2556 | ||
2557 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2557 | /* if B0 rate (hangup) specified then negate DTR and RTS */ |
2558 | /* otherwise assert DTR and RTS */ | 2558 | /* otherwise assert DTR and RTS */ |
@@ -3292,7 +3292,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3292 | return 0; | 3292 | return 0; |
3293 | } | 3293 | } |
3294 | 3294 | ||
3295 | if (tty->termios->c_cflag & CLOCAL) | 3295 | if (tty->termios.c_cflag & CLOCAL) |
3296 | do_clocal = true; | 3296 | do_clocal = true; |
3297 | 3297 | ||
3298 | /* Wait for carrier detect and the line to become | 3298 | /* Wait for carrier detect and the line to become |
@@ -3314,7 +3314,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3314 | port->blocked_open++; | 3314 | port->blocked_open++; |
3315 | 3315 | ||
3316 | while (1) { | 3316 | while (1) { |
3317 | if ((tty->termios->c_cflag & CBAUD)) | 3317 | if ((tty->termios.c_cflag & CBAUD)) |
3318 | tty_port_raise_dtr_rts(port); | 3318 | tty_port_raise_dtr_rts(port); |
3319 | 3319 | ||
3320 | set_current_state(TASK_INTERRUPTIBLE); | 3320 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -3336,9 +3336,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3336 | } | 3336 | } |
3337 | 3337 | ||
3338 | DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); | 3338 | DBGINFO(("%s block_til_ready wait\n", tty->driver->name)); |
3339 | tty_unlock(); | 3339 | tty_unlock(tty); |
3340 | schedule(); | 3340 | schedule(); |
3341 | tty_lock(); | 3341 | tty_lock(tty); |
3342 | } | 3342 | } |
3343 | 3343 | ||
3344 | set_current_state(TASK_RUNNING); | 3344 | set_current_state(TASK_RUNNING); |
@@ -3689,8 +3689,11 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3689 | } | 3689 | } |
3690 | } | 3690 | } |
3691 | 3691 | ||
3692 | for (i=0; i < port_count; ++i) | 3692 | for (i = 0; i < port_count; ++i) { |
3693 | tty_register_device(serial_driver, port_array[i]->line, &(port_array[i]->pdev->dev)); | 3693 | struct slgt_info *info = port_array[i]; |
3694 | tty_port_register_device(&info->port, serial_driver, info->line, | ||
3695 | &info->pdev->dev); | ||
3696 | } | ||
3694 | } | 3697 | } |
3695 | 3698 | ||
3696 | static int __devinit init_one(struct pci_dev *dev, | 3699 | static int __devinit init_one(struct pci_dev *dev, |
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c index a3dddc12d2fe..f17d9f3d84a2 100644 --- a/drivers/tty/synclinkmp.c +++ b/drivers/tty/synclinkmp.c | |||
@@ -711,15 +711,11 @@ static void ldisc_receive_buf(struct tty_struct *tty, | |||
711 | 711 | ||
712 | /* tty callbacks */ | 712 | /* tty callbacks */ |
713 | 713 | ||
714 | /* Called when a port is opened. Init and enable port. | 714 | static int install(struct tty_driver *driver, struct tty_struct *tty) |
715 | */ | ||
716 | static int open(struct tty_struct *tty, struct file *filp) | ||
717 | { | 715 | { |
718 | SLMP_INFO *info; | 716 | SLMP_INFO *info; |
719 | int retval, line; | 717 | int line = tty->index; |
720 | unsigned long flags; | ||
721 | 718 | ||
722 | line = tty->index; | ||
723 | if (line >= synclinkmp_device_count) { | 719 | if (line >= synclinkmp_device_count) { |
724 | printk("%s(%d): open with invalid line #%d.\n", | 720 | printk("%s(%d): open with invalid line #%d.\n", |
725 | __FILE__,__LINE__,line); | 721 | __FILE__,__LINE__,line); |
@@ -727,17 +723,30 @@ static int open(struct tty_struct *tty, struct file *filp) | |||
727 | } | 723 | } |
728 | 724 | ||
729 | info = synclinkmp_device_list; | 725 | info = synclinkmp_device_list; |
730 | while(info && info->line != line) | 726 | while (info && info->line != line) |
731 | info = info->next_device; | 727 | info = info->next_device; |
732 | if (sanity_check(info, tty->name, "open")) | 728 | if (sanity_check(info, tty->name, "open")) |
733 | return -ENODEV; | 729 | return -ENODEV; |
734 | if ( info->init_error ) { | 730 | if (info->init_error) { |
735 | printk("%s(%d):%s device is not allocated, init error=%d\n", | 731 | printk("%s(%d):%s device is not allocated, init error=%d\n", |
736 | __FILE__,__LINE__,info->device_name,info->init_error); | 732 | __FILE__, __LINE__, info->device_name, |
733 | info->init_error); | ||
737 | return -ENODEV; | 734 | return -ENODEV; |
738 | } | 735 | } |
739 | 736 | ||
740 | tty->driver_data = info; | 737 | tty->driver_data = info; |
738 | |||
739 | return tty_port_install(&info->port, driver, tty); | ||
740 | } | ||
741 | |||
742 | /* Called when a port is opened. Init and enable port. | ||
743 | */ | ||
744 | static int open(struct tty_struct *tty, struct file *filp) | ||
745 | { | ||
746 | SLMP_INFO *info = tty->driver_data; | ||
747 | unsigned long flags; | ||
748 | int retval; | ||
749 | |||
741 | info->port.tty = tty; | 750 | info->port.tty = tty; |
742 | 751 | ||
743 | if (debug_level >= DEBUG_LEVEL_INFO) | 752 | if (debug_level >= DEBUG_LEVEL_INFO) |
@@ -873,7 +882,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
873 | 882 | ||
874 | /* Handle transition to B0 status */ | 883 | /* Handle transition to B0 status */ |
875 | if (old_termios->c_cflag & CBAUD && | 884 | if (old_termios->c_cflag & CBAUD && |
876 | !(tty->termios->c_cflag & CBAUD)) { | 885 | !(tty->termios.c_cflag & CBAUD)) { |
877 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); | 886 | info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); |
878 | spin_lock_irqsave(&info->lock,flags); | 887 | spin_lock_irqsave(&info->lock,flags); |
879 | set_signals(info); | 888 | set_signals(info); |
@@ -882,9 +891,9 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
882 | 891 | ||
883 | /* Handle transition away from B0 status */ | 892 | /* Handle transition away from B0 status */ |
884 | if (!(old_termios->c_cflag & CBAUD) && | 893 | if (!(old_termios->c_cflag & CBAUD) && |
885 | tty->termios->c_cflag & CBAUD) { | 894 | tty->termios.c_cflag & CBAUD) { |
886 | info->serial_signals |= SerialSignal_DTR; | 895 | info->serial_signals |= SerialSignal_DTR; |
887 | if (!(tty->termios->c_cflag & CRTSCTS) || | 896 | if (!(tty->termios.c_cflag & CRTSCTS) || |
888 | !test_bit(TTY_THROTTLED, &tty->flags)) { | 897 | !test_bit(TTY_THROTTLED, &tty->flags)) { |
889 | info->serial_signals |= SerialSignal_RTS; | 898 | info->serial_signals |= SerialSignal_RTS; |
890 | } | 899 | } |
@@ -895,7 +904,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) | |||
895 | 904 | ||
896 | /* Handle turning off CRTSCTS */ | 905 | /* Handle turning off CRTSCTS */ |
897 | if (old_termios->c_cflag & CRTSCTS && | 906 | if (old_termios->c_cflag & CRTSCTS && |
898 | !(tty->termios->c_cflag & CRTSCTS)) { | 907 | !(tty->termios.c_cflag & CRTSCTS)) { |
899 | tty->hw_stopped = 0; | 908 | tty->hw_stopped = 0; |
900 | tx_release(tty); | 909 | tx_release(tty); |
901 | } | 910 | } |
@@ -1473,7 +1482,7 @@ static void throttle(struct tty_struct * tty) | |||
1473 | if (I_IXOFF(tty)) | 1482 | if (I_IXOFF(tty)) |
1474 | send_xchar(tty, STOP_CHAR(tty)); | 1483 | send_xchar(tty, STOP_CHAR(tty)); |
1475 | 1484 | ||
1476 | if (tty->termios->c_cflag & CRTSCTS) { | 1485 | if (tty->termios.c_cflag & CRTSCTS) { |
1477 | spin_lock_irqsave(&info->lock,flags); | 1486 | spin_lock_irqsave(&info->lock,flags); |
1478 | info->serial_signals &= ~SerialSignal_RTS; | 1487 | info->serial_signals &= ~SerialSignal_RTS; |
1479 | set_signals(info); | 1488 | set_signals(info); |
@@ -1502,7 +1511,7 @@ static void unthrottle(struct tty_struct * tty) | |||
1502 | send_xchar(tty, START_CHAR(tty)); | 1511 | send_xchar(tty, START_CHAR(tty)); |
1503 | } | 1512 | } |
1504 | 1513 | ||
1505 | if (tty->termios->c_cflag & CRTSCTS) { | 1514 | if (tty->termios.c_cflag & CRTSCTS) { |
1506 | spin_lock_irqsave(&info->lock,flags); | 1515 | spin_lock_irqsave(&info->lock,flags); |
1507 | info->serial_signals |= SerialSignal_RTS; | 1516 | info->serial_signals |= SerialSignal_RTS; |
1508 | set_signals(info); | 1517 | set_signals(info); |
@@ -2491,7 +2500,7 @@ static void isr_io_pin( SLMP_INFO *info, u16 status ) | |||
2491 | } | 2500 | } |
2492 | } | 2501 | } |
2493 | 2502 | ||
2494 | if ( (info->port.flags & ASYNC_CTS_FLOW) && | 2503 | if (tty_port_cts_enabled(&info->port) && |
2495 | (status & MISCSTATUS_CTS_LATCHED) ) { | 2504 | (status & MISCSTATUS_CTS_LATCHED) ) { |
2496 | if ( info->port.tty ) { | 2505 | if ( info->port.tty ) { |
2497 | if (info->port.tty->hw_stopped) { | 2506 | if (info->port.tty->hw_stopped) { |
@@ -2708,7 +2717,7 @@ static void shutdown(SLMP_INFO * info) | |||
2708 | 2717 | ||
2709 | reset_port(info); | 2718 | reset_port(info); |
2710 | 2719 | ||
2711 | if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) { | 2720 | if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) { |
2712 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); | 2721 | info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); |
2713 | set_signals(info); | 2722 | set_signals(info); |
2714 | } | 2723 | } |
@@ -2749,7 +2758,7 @@ static void program_hw(SLMP_INFO *info) | |||
2749 | 2758 | ||
2750 | get_signals(info); | 2759 | get_signals(info); |
2751 | 2760 | ||
2752 | if (info->netcount || (info->port.tty && info->port.tty->termios->c_cflag & CREAD) ) | 2761 | if (info->netcount || (info->port.tty && info->port.tty->termios.c_cflag & CREAD) ) |
2753 | rx_start(info); | 2762 | rx_start(info); |
2754 | 2763 | ||
2755 | spin_unlock_irqrestore(&info->lock,flags); | 2764 | spin_unlock_irqrestore(&info->lock,flags); |
@@ -2762,14 +2771,14 @@ static void change_params(SLMP_INFO *info) | |||
2762 | unsigned cflag; | 2771 | unsigned cflag; |
2763 | int bits_per_char; | 2772 | int bits_per_char; |
2764 | 2773 | ||
2765 | if (!info->port.tty || !info->port.tty->termios) | 2774 | if (!info->port.tty) |
2766 | return; | 2775 | return; |
2767 | 2776 | ||
2768 | if (debug_level >= DEBUG_LEVEL_INFO) | 2777 | if (debug_level >= DEBUG_LEVEL_INFO) |
2769 | printk("%s(%d):%s change_params()\n", | 2778 | printk("%s(%d):%s change_params()\n", |
2770 | __FILE__,__LINE__, info->device_name ); | 2779 | __FILE__,__LINE__, info->device_name ); |
2771 | 2780 | ||
2772 | cflag = info->port.tty->termios->c_cflag; | 2781 | cflag = info->port.tty->termios.c_cflag; |
2773 | 2782 | ||
2774 | /* if B0 rate (hangup) specified then negate DTR and RTS */ | 2783 | /* if B0 rate (hangup) specified then negate DTR and RTS */ |
2775 | /* otherwise assert DTR and RTS */ | 2784 | /* otherwise assert DTR and RTS */ |
@@ -3306,7 +3315,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3306 | return 0; | 3315 | return 0; |
3307 | } | 3316 | } |
3308 | 3317 | ||
3309 | if (tty->termios->c_cflag & CLOCAL) | 3318 | if (tty->termios.c_cflag & CLOCAL) |
3310 | do_clocal = true; | 3319 | do_clocal = true; |
3311 | 3320 | ||
3312 | /* Wait for carrier detect and the line to become | 3321 | /* Wait for carrier detect and the line to become |
@@ -3332,7 +3341,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3332 | port->blocked_open++; | 3341 | port->blocked_open++; |
3333 | 3342 | ||
3334 | while (1) { | 3343 | while (1) { |
3335 | if (tty->termios->c_cflag & CBAUD) | 3344 | if (tty->termios.c_cflag & CBAUD) |
3336 | tty_port_raise_dtr_rts(port); | 3345 | tty_port_raise_dtr_rts(port); |
3337 | 3346 | ||
3338 | set_current_state(TASK_INTERRUPTIBLE); | 3347 | set_current_state(TASK_INTERRUPTIBLE); |
@@ -3357,9 +3366,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp, | |||
3357 | printk("%s(%d):%s block_til_ready() count=%d\n", | 3366 | printk("%s(%d):%s block_til_ready() count=%d\n", |
3358 | __FILE__,__LINE__, tty->driver->name, port->count ); | 3367 | __FILE__,__LINE__, tty->driver->name, port->count ); |
3359 | 3368 | ||
3360 | tty_unlock(); | 3369 | tty_unlock(tty); |
3361 | schedule(); | 3370 | schedule(); |
3362 | tty_lock(); | 3371 | tty_lock(tty); |
3363 | } | 3372 | } |
3364 | 3373 | ||
3365 | set_current_state(TASK_RUNNING); | 3374 | set_current_state(TASK_RUNNING); |
@@ -3881,6 +3890,7 @@ static void device_init(int adapter_num, struct pci_dev *pdev) | |||
3881 | } | 3890 | } |
3882 | 3891 | ||
3883 | static const struct tty_operations ops = { | 3892 | static const struct tty_operations ops = { |
3893 | .install = install, | ||
3884 | .open = open, | 3894 | .open = open, |
3885 | .close = close, | 3895 | .close = close, |
3886 | .write = write, | 3896 | .write = write, |
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index b425c79675ad..8a5a8b064616 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c | |||
@@ -181,10 +181,13 @@ struct tty_struct *alloc_tty_struct(void) | |||
181 | 181 | ||
182 | void free_tty_struct(struct tty_struct *tty) | 182 | void free_tty_struct(struct tty_struct *tty) |
183 | { | 183 | { |
184 | if (!tty) | ||
185 | return; | ||
184 | if (tty->dev) | 186 | if (tty->dev) |
185 | put_device(tty->dev); | 187 | put_device(tty->dev); |
186 | kfree(tty->write_buf); | 188 | kfree(tty->write_buf); |
187 | tty_buffer_free_all(tty); | 189 | tty_buffer_free_all(tty); |
190 | tty->magic = 0xDEADDEAD; | ||
188 | kfree(tty); | 191 | kfree(tty); |
189 | } | 192 | } |
190 | 193 | ||
@@ -573,7 +576,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
573 | } | 576 | } |
574 | spin_unlock(&redirect_lock); | 577 | spin_unlock(&redirect_lock); |
575 | 578 | ||
576 | tty_lock(); | 579 | tty_lock(tty); |
577 | 580 | ||
578 | /* some functions below drop BTM, so we need this bit */ | 581 | /* some functions below drop BTM, so we need this bit */ |
579 | set_bit(TTY_HUPPING, &tty->flags); | 582 | set_bit(TTY_HUPPING, &tty->flags); |
@@ -666,7 +669,7 @@ void __tty_hangup(struct tty_struct *tty) | |||
666 | clear_bit(TTY_HUPPING, &tty->flags); | 669 | clear_bit(TTY_HUPPING, &tty->flags); |
667 | tty_ldisc_enable(tty); | 670 | tty_ldisc_enable(tty); |
668 | 671 | ||
669 | tty_unlock(); | 672 | tty_unlock(tty); |
670 | 673 | ||
671 | if (f) | 674 | if (f) |
672 | fput(f); | 675 | fput(f); |
@@ -1103,12 +1106,12 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1103 | { | 1106 | { |
1104 | if (tty) { | 1107 | if (tty) { |
1105 | mutex_lock(&tty->atomic_write_lock); | 1108 | mutex_lock(&tty->atomic_write_lock); |
1106 | tty_lock(); | 1109 | tty_lock(tty); |
1107 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { | 1110 | if (tty->ops->write && !test_bit(TTY_CLOSING, &tty->flags)) { |
1108 | tty_unlock(); | 1111 | tty_unlock(tty); |
1109 | tty->ops->write(tty, msg, strlen(msg)); | 1112 | tty->ops->write(tty, msg, strlen(msg)); |
1110 | } else | 1113 | } else |
1111 | tty_unlock(); | 1114 | tty_unlock(tty); |
1112 | tty_write_unlock(tty); | 1115 | tty_write_unlock(tty); |
1113 | } | 1116 | } |
1114 | return; | 1117 | return; |
@@ -1213,7 +1216,10 @@ static void pty_line_name(struct tty_driver *driver, int index, char *p) | |||
1213 | */ | 1216 | */ |
1214 | static void tty_line_name(struct tty_driver *driver, int index, char *p) | 1217 | static void tty_line_name(struct tty_driver *driver, int index, char *p) |
1215 | { | 1218 | { |
1216 | sprintf(p, "%s%d", driver->name, index + driver->name_base); | 1219 | if (driver->flags & TTY_DRIVER_UNNUMBERED_NODE) |
1220 | strcpy(p, driver->name); | ||
1221 | else | ||
1222 | sprintf(p, "%s%d", driver->name, index + driver->name_base); | ||
1217 | } | 1223 | } |
1218 | 1224 | ||
1219 | /** | 1225 | /** |
@@ -1249,21 +1255,19 @@ int tty_init_termios(struct tty_struct *tty) | |||
1249 | struct ktermios *tp; | 1255 | struct ktermios *tp; |
1250 | int idx = tty->index; | 1256 | int idx = tty->index; |
1251 | 1257 | ||
1252 | tp = tty->driver->termios[idx]; | 1258 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1253 | if (tp == NULL) { | 1259 | tty->termios = tty->driver->init_termios; |
1254 | tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL); | 1260 | else { |
1255 | if (tp == NULL) | 1261 | /* Check for lazy saved data */ |
1256 | return -ENOMEM; | 1262 | tp = tty->driver->termios[idx]; |
1257 | memcpy(tp, &tty->driver->init_termios, | 1263 | if (tp != NULL) |
1258 | sizeof(struct ktermios)); | 1264 | tty->termios = *tp; |
1259 | tty->driver->termios[idx] = tp; | 1265 | else |
1266 | tty->termios = tty->driver->init_termios; | ||
1260 | } | 1267 | } |
1261 | tty->termios = tp; | ||
1262 | tty->termios_locked = tp + 1; | ||
1263 | |||
1264 | /* Compatibility until drivers always set this */ | 1268 | /* Compatibility until drivers always set this */ |
1265 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | 1269 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); |
1266 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | 1270 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); |
1267 | return 0; | 1271 | return 0; |
1268 | } | 1272 | } |
1269 | EXPORT_SYMBOL_GPL(tty_init_termios); | 1273 | EXPORT_SYMBOL_GPL(tty_init_termios); |
@@ -1403,10 +1407,18 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1403 | } | 1407 | } |
1404 | initialize_tty_struct(tty, driver, idx); | 1408 | initialize_tty_struct(tty, driver, idx); |
1405 | 1409 | ||
1410 | tty_lock(tty); | ||
1406 | retval = tty_driver_install_tty(driver, tty); | 1411 | retval = tty_driver_install_tty(driver, tty); |
1407 | if (retval < 0) | 1412 | if (retval < 0) |
1408 | goto err_deinit_tty; | 1413 | goto err_deinit_tty; |
1409 | 1414 | ||
1415 | if (!tty->port) | ||
1416 | tty->port = driver->ports[idx]; | ||
1417 | |||
1418 | WARN_RATELIMIT(!tty->port, | ||
1419 | "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", | ||
1420 | __func__, tty->driver->name); | ||
1421 | |||
1410 | /* | 1422 | /* |
1411 | * Structures all installed ... call the ldisc open routines. | 1423 | * Structures all installed ... call the ldisc open routines. |
1412 | * If we fail here just call release_tty to clean up. No need | 1424 | * If we fail here just call release_tty to clean up. No need |
@@ -1415,9 +1427,11 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) | |||
1415 | retval = tty_ldisc_setup(tty, tty->link); | 1427 | retval = tty_ldisc_setup(tty, tty->link); |
1416 | if (retval) | 1428 | if (retval) |
1417 | goto err_release_tty; | 1429 | goto err_release_tty; |
1430 | /* Return the tty locked so that it cannot vanish under the caller */ | ||
1418 | return tty; | 1431 | return tty; |
1419 | 1432 | ||
1420 | err_deinit_tty: | 1433 | err_deinit_tty: |
1434 | tty_unlock(tty); | ||
1421 | deinitialize_tty_struct(tty); | 1435 | deinitialize_tty_struct(tty); |
1422 | free_tty_struct(tty); | 1436 | free_tty_struct(tty); |
1423 | err_module_put: | 1437 | err_module_put: |
@@ -1426,6 +1440,7 @@ err_module_put: | |||
1426 | 1440 | ||
1427 | /* call the tty release_tty routine to clean out this slot */ | 1441 | /* call the tty release_tty routine to clean out this slot */ |
1428 | err_release_tty: | 1442 | err_release_tty: |
1443 | tty_unlock(tty); | ||
1429 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " | 1444 | printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " |
1430 | "clearing slot %d\n", idx); | 1445 | "clearing slot %d\n", idx); |
1431 | release_tty(tty, idx); | 1446 | release_tty(tty, idx); |
@@ -1436,22 +1451,25 @@ void tty_free_termios(struct tty_struct *tty) | |||
1436 | { | 1451 | { |
1437 | struct ktermios *tp; | 1452 | struct ktermios *tp; |
1438 | int idx = tty->index; | 1453 | int idx = tty->index; |
1439 | /* Kill this flag and push into drivers for locking etc */ | 1454 | |
1440 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 1455 | /* If the port is going to reset then it has no termios to save */ |
1441 | /* FIXME: Locking on ->termios array */ | 1456 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1442 | tp = tty->termios; | 1457 | return; |
1443 | tty->driver->termios[idx] = NULL; | 1458 | |
1444 | kfree(tp); | 1459 | /* Stash the termios data */ |
1460 | tp = tty->driver->termios[idx]; | ||
1461 | if (tp == NULL) { | ||
1462 | tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); | ||
1463 | if (tp == NULL) { | ||
1464 | pr_warn("tty: no memory to save termios state.\n"); | ||
1465 | return; | ||
1466 | } | ||
1467 | tty->driver->termios[idx] = tp; | ||
1445 | } | 1468 | } |
1469 | *tp = tty->termios; | ||
1446 | } | 1470 | } |
1447 | EXPORT_SYMBOL(tty_free_termios); | 1471 | EXPORT_SYMBOL(tty_free_termios); |
1448 | 1472 | ||
1449 | void tty_shutdown(struct tty_struct *tty) | ||
1450 | { | ||
1451 | tty_driver_remove_tty(tty->driver, tty); | ||
1452 | tty_free_termios(tty); | ||
1453 | } | ||
1454 | EXPORT_SYMBOL(tty_shutdown); | ||
1455 | 1473 | ||
1456 | /** | 1474 | /** |
1457 | * release_one_tty - release tty structure memory | 1475 | * release_one_tty - release tty structure memory |
@@ -1462,7 +1480,6 @@ EXPORT_SYMBOL(tty_shutdown); | |||
1462 | * in use. It also gets called when setup of a device fails. | 1480 | * in use. It also gets called when setup of a device fails. |
1463 | * | 1481 | * |
1464 | * Locking: | 1482 | * Locking: |
1465 | * tty_mutex - sometimes only | ||
1466 | * takes the file list lock internally when working on the list | 1483 | * takes the file list lock internally when working on the list |
1467 | * of ttys that the driver keeps. | 1484 | * of ttys that the driver keeps. |
1468 | * | 1485 | * |
@@ -1495,11 +1512,6 @@ static void queue_release_one_tty(struct kref *kref) | |||
1495 | { | 1512 | { |
1496 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); | 1513 | struct tty_struct *tty = container_of(kref, struct tty_struct, kref); |
1497 | 1514 | ||
1498 | if (tty->ops->shutdown) | ||
1499 | tty->ops->shutdown(tty); | ||
1500 | else | ||
1501 | tty_shutdown(tty); | ||
1502 | |||
1503 | /* The hangup queue is now free so we can reuse it rather than | 1515 | /* The hangup queue is now free so we can reuse it rather than |
1504 | waste a chunk of memory for each port */ | 1516 | waste a chunk of memory for each port */ |
1505 | INIT_WORK(&tty->hangup_work, release_one_tty); | 1517 | INIT_WORK(&tty->hangup_work, release_one_tty); |
@@ -1528,16 +1540,20 @@ EXPORT_SYMBOL(tty_kref_put); | |||
1528 | * and decrement the refcount of the backing module. | 1540 | * and decrement the refcount of the backing module. |
1529 | * | 1541 | * |
1530 | * Locking: | 1542 | * Locking: |
1531 | * tty_mutex - sometimes only | 1543 | * tty_mutex |
1532 | * takes the file list lock internally when working on the list | 1544 | * takes the file list lock internally when working on the list |
1533 | * of ttys that the driver keeps. | 1545 | * of ttys that the driver keeps. |
1534 | * FIXME: should we require tty_mutex is held here ?? | ||
1535 | * | 1546 | * |
1536 | */ | 1547 | */ |
1537 | static void release_tty(struct tty_struct *tty, int idx) | 1548 | static void release_tty(struct tty_struct *tty, int idx) |
1538 | { | 1549 | { |
1539 | /* This should always be true but check for the moment */ | 1550 | /* This should always be true but check for the moment */ |
1540 | WARN_ON(tty->index != idx); | 1551 | WARN_ON(tty->index != idx); |
1552 | WARN_ON(!mutex_is_locked(&tty_mutex)); | ||
1553 | if (tty->ops->shutdown) | ||
1554 | tty->ops->shutdown(tty); | ||
1555 | tty_free_termios(tty); | ||
1556 | tty_driver_remove_tty(tty->driver, tty); | ||
1541 | 1557 | ||
1542 | if (tty->link) | 1558 | if (tty->link) |
1543 | tty_kref_put(tty->link); | 1559 | tty_kref_put(tty->link); |
@@ -1572,22 +1588,12 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty, | |||
1572 | __func__, idx, tty->name); | 1588 | __func__, idx, tty->name); |
1573 | return -1; | 1589 | return -1; |
1574 | } | 1590 | } |
1575 | if (tty->termios != tty->driver->termios[idx]) { | ||
1576 | printk(KERN_DEBUG "%s: driver.termios[%d] not termios for (%s)\n", | ||
1577 | __func__, idx, tty->name); | ||
1578 | return -1; | ||
1579 | } | ||
1580 | if (tty->driver->other) { | 1591 | if (tty->driver->other) { |
1581 | if (o_tty != tty->driver->other->ttys[idx]) { | 1592 | if (o_tty != tty->driver->other->ttys[idx]) { |
1582 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", | 1593 | printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n", |
1583 | __func__, idx, tty->name); | 1594 | __func__, idx, tty->name); |
1584 | return -1; | 1595 | return -1; |
1585 | } | 1596 | } |
1586 | if (o_tty->termios != tty->driver->other->termios[idx]) { | ||
1587 | printk(KERN_DEBUG "%s: other->termios[%d] not o_termios for (%s)\n", | ||
1588 | __func__, idx, tty->name); | ||
1589 | return -1; | ||
1590 | } | ||
1591 | if (o_tty->link != tty) { | 1597 | if (o_tty->link != tty) { |
1592 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); | 1598 | printk(KERN_DEBUG "%s: bad pty pointers\n", __func__); |
1593 | return -1; | 1599 | return -1; |
@@ -1628,7 +1634,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1628 | if (tty_paranoia_check(tty, inode, __func__)) | 1634 | if (tty_paranoia_check(tty, inode, __func__)) |
1629 | return 0; | 1635 | return 0; |
1630 | 1636 | ||
1631 | tty_lock(); | 1637 | tty_lock(tty); |
1632 | check_tty_count(tty, __func__); | 1638 | check_tty_count(tty, __func__); |
1633 | 1639 | ||
1634 | __tty_fasync(-1, filp, 0); | 1640 | __tty_fasync(-1, filp, 0); |
@@ -1637,10 +1643,11 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1637 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && | 1643 | pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && |
1638 | tty->driver->subtype == PTY_TYPE_MASTER); | 1644 | tty->driver->subtype == PTY_TYPE_MASTER); |
1639 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; | 1645 | devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; |
1646 | /* Review: parallel close */ | ||
1640 | o_tty = tty->link; | 1647 | o_tty = tty->link; |
1641 | 1648 | ||
1642 | if (tty_release_checks(tty, o_tty, idx)) { | 1649 | if (tty_release_checks(tty, o_tty, idx)) { |
1643 | tty_unlock(); | 1650 | tty_unlock(tty); |
1644 | return 0; | 1651 | return 0; |
1645 | } | 1652 | } |
1646 | 1653 | ||
@@ -1652,7 +1659,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1652 | if (tty->ops->close) | 1659 | if (tty->ops->close) |
1653 | tty->ops->close(tty, filp); | 1660 | tty->ops->close(tty, filp); |
1654 | 1661 | ||
1655 | tty_unlock(); | 1662 | tty_unlock(tty); |
1656 | /* | 1663 | /* |
1657 | * Sanity check: if tty->count is going to zero, there shouldn't be | 1664 | * Sanity check: if tty->count is going to zero, there shouldn't be |
1658 | * any waiters on tty->read_wait or tty->write_wait. We test the | 1665 | * any waiters on tty->read_wait or tty->write_wait. We test the |
@@ -1675,7 +1682,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1675 | opens on /dev/tty */ | 1682 | opens on /dev/tty */ |
1676 | 1683 | ||
1677 | mutex_lock(&tty_mutex); | 1684 | mutex_lock(&tty_mutex); |
1678 | tty_lock(); | 1685 | tty_lock_pair(tty, o_tty); |
1679 | tty_closing = tty->count <= 1; | 1686 | tty_closing = tty->count <= 1; |
1680 | o_tty_closing = o_tty && | 1687 | o_tty_closing = o_tty && |
1681 | (o_tty->count <= (pty_master ? 1 : 0)); | 1688 | (o_tty->count <= (pty_master ? 1 : 0)); |
@@ -1706,7 +1713,7 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1706 | 1713 | ||
1707 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", | 1714 | printk(KERN_WARNING "%s: %s: read/write wait queue active!\n", |
1708 | __func__, tty_name(tty, buf)); | 1715 | __func__, tty_name(tty, buf)); |
1709 | tty_unlock(); | 1716 | tty_unlock_pair(tty, o_tty); |
1710 | mutex_unlock(&tty_mutex); | 1717 | mutex_unlock(&tty_mutex); |
1711 | schedule(); | 1718 | schedule(); |
1712 | } | 1719 | } |
@@ -1715,6 +1722,9 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1715 | * The closing flags are now consistent with the open counts on | 1722 | * The closing flags are now consistent with the open counts on |
1716 | * both sides, and we've completed the last operation that could | 1723 | * both sides, and we've completed the last operation that could |
1717 | * block, so it's safe to proceed with closing. | 1724 | * block, so it's safe to proceed with closing. |
1725 | * | ||
1726 | * We must *not* drop the tty_mutex until we ensure that a further | ||
1727 | * entry into tty_open can not pick up this tty. | ||
1718 | */ | 1728 | */ |
1719 | if (pty_master) { | 1729 | if (pty_master) { |
1720 | if (--o_tty->count < 0) { | 1730 | if (--o_tty->count < 0) { |
@@ -1766,12 +1776,13 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1766 | } | 1776 | } |
1767 | 1777 | ||
1768 | mutex_unlock(&tty_mutex); | 1778 | mutex_unlock(&tty_mutex); |
1779 | tty_unlock_pair(tty, o_tty); | ||
1780 | /* At this point the TTY_CLOSING flag should ensure a dead tty | ||
1781 | cannot be re-opened by a racing opener */ | ||
1769 | 1782 | ||
1770 | /* check whether both sides are closing ... */ | 1783 | /* check whether both sides are closing ... */ |
1771 | if (!tty_closing || (o_tty && !o_tty_closing)) { | 1784 | if (!tty_closing || (o_tty && !o_tty_closing)) |
1772 | tty_unlock(); | ||
1773 | return 0; | 1785 | return 0; |
1774 | } | ||
1775 | 1786 | ||
1776 | #ifdef TTY_DEBUG_HANGUP | 1787 | #ifdef TTY_DEBUG_HANGUP |
1777 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); | 1788 | printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__); |
@@ -1782,14 +1793,17 @@ int tty_release(struct inode *inode, struct file *filp) | |||
1782 | tty_ldisc_release(tty, o_tty); | 1793 | tty_ldisc_release(tty, o_tty); |
1783 | /* | 1794 | /* |
1784 | * The release_tty function takes care of the details of clearing | 1795 | * The release_tty function takes care of the details of clearing |
1785 | * the slots and preserving the termios structure. | 1796 | * the slots and preserving the termios structure. The tty_unlock_pair |
1797 | * should be safe as we keep a kref while the tty is locked (so the | ||
1798 | * unlock never unlocks a freed tty). | ||
1786 | */ | 1799 | */ |
1800 | mutex_lock(&tty_mutex); | ||
1787 | release_tty(tty, idx); | 1801 | release_tty(tty, idx); |
1802 | mutex_unlock(&tty_mutex); | ||
1788 | 1803 | ||
1789 | /* Make this pty number available for reallocation */ | 1804 | /* Make this pty number available for reallocation */ |
1790 | if (devpts) | 1805 | if (devpts) |
1791 | devpts_kill_index(inode, idx); | 1806 | devpts_kill_index(inode, idx); |
1792 | tty_unlock(); | ||
1793 | return 0; | 1807 | return 0; |
1794 | } | 1808 | } |
1795 | 1809 | ||
@@ -1893,6 +1907,9 @@ static struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, | |||
1893 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. | 1907 | * Locking: tty_mutex protects tty, tty_lookup_driver and tty_init_dev. |
1894 | * tty->count should protect the rest. | 1908 | * tty->count should protect the rest. |
1895 | * ->siglock protects ->signal/->sighand | 1909 | * ->siglock protects ->signal/->sighand |
1910 | * | ||
1911 | * Note: the tty_unlock/lock cases without a ref are only safe due to | ||
1912 | * tty_mutex | ||
1896 | */ | 1913 | */ |
1897 | 1914 | ||
1898 | static int tty_open(struct inode *inode, struct file *filp) | 1915 | static int tty_open(struct inode *inode, struct file *filp) |
@@ -1916,8 +1933,7 @@ retry_open: | |||
1916 | retval = 0; | 1933 | retval = 0; |
1917 | 1934 | ||
1918 | mutex_lock(&tty_mutex); | 1935 | mutex_lock(&tty_mutex); |
1919 | tty_lock(); | 1936 | /* This is protected by the tty_mutex */ |
1920 | |||
1921 | tty = tty_open_current_tty(device, filp); | 1937 | tty = tty_open_current_tty(device, filp); |
1922 | if (IS_ERR(tty)) { | 1938 | if (IS_ERR(tty)) { |
1923 | retval = PTR_ERR(tty); | 1939 | retval = PTR_ERR(tty); |
@@ -1938,17 +1954,19 @@ retry_open: | |||
1938 | } | 1954 | } |
1939 | 1955 | ||
1940 | if (tty) { | 1956 | if (tty) { |
1957 | tty_lock(tty); | ||
1941 | retval = tty_reopen(tty); | 1958 | retval = tty_reopen(tty); |
1942 | if (retval) | 1959 | if (retval < 0) { |
1960 | tty_unlock(tty); | ||
1943 | tty = ERR_PTR(retval); | 1961 | tty = ERR_PTR(retval); |
1944 | } else | 1962 | } |
1963 | } else /* Returns with the tty_lock held for now */ | ||
1945 | tty = tty_init_dev(driver, index); | 1964 | tty = tty_init_dev(driver, index); |
1946 | 1965 | ||
1947 | mutex_unlock(&tty_mutex); | 1966 | mutex_unlock(&tty_mutex); |
1948 | if (driver) | 1967 | if (driver) |
1949 | tty_driver_kref_put(driver); | 1968 | tty_driver_kref_put(driver); |
1950 | if (IS_ERR(tty)) { | 1969 | if (IS_ERR(tty)) { |
1951 | tty_unlock(); | ||
1952 | retval = PTR_ERR(tty); | 1970 | retval = PTR_ERR(tty); |
1953 | goto err_file; | 1971 | goto err_file; |
1954 | } | 1972 | } |
@@ -1977,7 +1995,7 @@ retry_open: | |||
1977 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, | 1995 | printk(KERN_DEBUG "%s: error %d in opening %s...\n", __func__, |
1978 | retval, tty->name); | 1996 | retval, tty->name); |
1979 | #endif | 1997 | #endif |
1980 | tty_unlock(); /* need to call tty_release without BTM */ | 1998 | tty_unlock(tty); /* need to call tty_release without BTM */ |
1981 | tty_release(inode, filp); | 1999 | tty_release(inode, filp); |
1982 | if (retval != -ERESTARTSYS) | 2000 | if (retval != -ERESTARTSYS) |
1983 | return retval; | 2001 | return retval; |
@@ -1989,17 +2007,15 @@ retry_open: | |||
1989 | /* | 2007 | /* |
1990 | * Need to reset f_op in case a hangup happened. | 2008 | * Need to reset f_op in case a hangup happened. |
1991 | */ | 2009 | */ |
1992 | tty_lock(); | ||
1993 | if (filp->f_op == &hung_up_tty_fops) | 2010 | if (filp->f_op == &hung_up_tty_fops) |
1994 | filp->f_op = &tty_fops; | 2011 | filp->f_op = &tty_fops; |
1995 | tty_unlock(); | ||
1996 | goto retry_open; | 2012 | goto retry_open; |
1997 | } | 2013 | } |
1998 | tty_unlock(); | 2014 | tty_unlock(tty); |
1999 | 2015 | ||
2000 | 2016 | ||
2001 | mutex_lock(&tty_mutex); | 2017 | mutex_lock(&tty_mutex); |
2002 | tty_lock(); | 2018 | tty_lock(tty); |
2003 | spin_lock_irq(¤t->sighand->siglock); | 2019 | spin_lock_irq(¤t->sighand->siglock); |
2004 | if (!noctty && | 2020 | if (!noctty && |
2005 | current->signal->leader && | 2021 | current->signal->leader && |
@@ -2007,11 +2023,10 @@ retry_open: | |||
2007 | tty->session == NULL) | 2023 | tty->session == NULL) |
2008 | __proc_set_tty(current, tty); | 2024 | __proc_set_tty(current, tty); |
2009 | spin_unlock_irq(¤t->sighand->siglock); | 2025 | spin_unlock_irq(¤t->sighand->siglock); |
2010 | tty_unlock(); | 2026 | tty_unlock(tty); |
2011 | mutex_unlock(&tty_mutex); | 2027 | mutex_unlock(&tty_mutex); |
2012 | return 0; | 2028 | return 0; |
2013 | err_unlock: | 2029 | err_unlock: |
2014 | tty_unlock(); | ||
2015 | mutex_unlock(&tty_mutex); | 2030 | mutex_unlock(&tty_mutex); |
2016 | /* after locks to avoid deadlock */ | 2031 | /* after locks to avoid deadlock */ |
2017 | if (!IS_ERR_OR_NULL(driver)) | 2032 | if (!IS_ERR_OR_NULL(driver)) |
@@ -2094,10 +2109,13 @@ out: | |||
2094 | 2109 | ||
2095 | static int tty_fasync(int fd, struct file *filp, int on) | 2110 | static int tty_fasync(int fd, struct file *filp, int on) |
2096 | { | 2111 | { |
2112 | struct tty_struct *tty = file_tty(filp); | ||
2097 | int retval; | 2113 | int retval; |
2098 | tty_lock(); | 2114 | |
2115 | tty_lock(tty); | ||
2099 | retval = __tty_fasync(fd, filp, on); | 2116 | retval = __tty_fasync(fd, filp, on); |
2100 | tty_unlock(); | 2117 | tty_unlock(tty); |
2118 | |||
2101 | return retval; | 2119 | return retval; |
2102 | } | 2120 | } |
2103 | 2121 | ||
@@ -2756,7 +2774,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
2756 | if (ld->ops->ioctl) { | 2774 | if (ld->ops->ioctl) { |
2757 | retval = ld->ops->ioctl(tty, file, cmd, arg); | 2775 | retval = ld->ops->ioctl(tty, file, cmd, arg); |
2758 | if (retval == -ENOIOCTLCMD) | 2776 | if (retval == -ENOIOCTLCMD) |
2759 | retval = -EINVAL; | 2777 | retval = -ENOTTY; |
2760 | } | 2778 | } |
2761 | tty_ldisc_deref(ld); | 2779 | tty_ldisc_deref(ld); |
2762 | return retval; | 2780 | return retval; |
@@ -2934,6 +2952,7 @@ void initialize_tty_struct(struct tty_struct *tty, | |||
2934 | tty->pgrp = NULL; | 2952 | tty->pgrp = NULL; |
2935 | tty->overrun_time = jiffies; | 2953 | tty->overrun_time = jiffies; |
2936 | tty_buffer_init(tty); | 2954 | tty_buffer_init(tty); |
2955 | mutex_init(&tty->legacy_mutex); | ||
2937 | mutex_init(&tty->termios_mutex); | 2956 | mutex_init(&tty->termios_mutex); |
2938 | mutex_init(&tty->ldisc_mutex); | 2957 | mutex_init(&tty->ldisc_mutex); |
2939 | init_waitqueue_head(&tty->write_wait); | 2958 | init_waitqueue_head(&tty->write_wait); |
@@ -2991,6 +3010,15 @@ EXPORT_SYMBOL_GPL(tty_put_char); | |||
2991 | 3010 | ||
2992 | struct class *tty_class; | 3011 | struct class *tty_class; |
2993 | 3012 | ||
3013 | static int tty_cdev_add(struct tty_driver *driver, dev_t dev, | ||
3014 | unsigned int index, unsigned int count) | ||
3015 | { | ||
3016 | /* init here, since reused cdevs cause crashes */ | ||
3017 | cdev_init(&driver->cdevs[index], &tty_fops); | ||
3018 | driver->cdevs[index].owner = driver->owner; | ||
3019 | return cdev_add(&driver->cdevs[index], dev, count); | ||
3020 | } | ||
3021 | |||
2994 | /** | 3022 | /** |
2995 | * tty_register_device - register a tty device | 3023 | * tty_register_device - register a tty device |
2996 | * @driver: the tty driver that describes the tty device | 3024 | * @driver: the tty driver that describes the tty device |
@@ -3013,8 +3041,46 @@ struct class *tty_class; | |||
3013 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, | 3041 | struct device *tty_register_device(struct tty_driver *driver, unsigned index, |
3014 | struct device *device) | 3042 | struct device *device) |
3015 | { | 3043 | { |
3044 | return tty_register_device_attr(driver, index, device, NULL, NULL); | ||
3045 | } | ||
3046 | EXPORT_SYMBOL(tty_register_device); | ||
3047 | |||
3048 | static void tty_device_create_release(struct device *dev) | ||
3049 | { | ||
3050 | pr_debug("device: '%s': %s\n", dev_name(dev), __func__); | ||
3051 | kfree(dev); | ||
3052 | } | ||
3053 | |||
3054 | /** | ||
3055 | * tty_register_device_attr - register a tty device | ||
3056 | * @driver: the tty driver that describes the tty device | ||
3057 | * @index: the index in the tty driver for this tty device | ||
3058 | * @device: a struct device that is associated with this tty device. | ||
3059 | * This field is optional, if there is no known struct device | ||
3060 | * for this tty device it can be set to NULL safely. | ||
3061 | * @drvdata: Driver data to be set to device. | ||
3062 | * @attr_grp: Attribute group to be set on device. | ||
3063 | * | ||
3064 | * Returns a pointer to the struct device for this tty device | ||
3065 | * (or ERR_PTR(-EFOO) on error). | ||
3066 | * | ||
3067 | * This call is required to be made to register an individual tty device | ||
3068 | * if the tty driver's flags have the TTY_DRIVER_DYNAMIC_DEV bit set. If | ||
3069 | * that bit is not set, this function should not be called by a tty | ||
3070 | * driver. | ||
3071 | * | ||
3072 | * Locking: ?? | ||
3073 | */ | ||
3074 | struct device *tty_register_device_attr(struct tty_driver *driver, | ||
3075 | unsigned index, struct device *device, | ||
3076 | void *drvdata, | ||
3077 | const struct attribute_group **attr_grp) | ||
3078 | { | ||
3016 | char name[64]; | 3079 | char name[64]; |
3017 | dev_t dev = MKDEV(driver->major, driver->minor_start) + index; | 3080 | dev_t devt = MKDEV(driver->major, driver->minor_start) + index; |
3081 | struct device *dev = NULL; | ||
3082 | int retval = -ENODEV; | ||
3083 | bool cdev = false; | ||
3018 | 3084 | ||
3019 | if (index >= driver->num) { | 3085 | if (index >= driver->num) { |
3020 | printk(KERN_ERR "Attempt to register invalid tty line number " | 3086 | printk(KERN_ERR "Attempt to register invalid tty line number " |
@@ -3027,9 +3093,40 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index, | |||
3027 | else | 3093 | else |
3028 | tty_line_name(driver, index, name); | 3094 | tty_line_name(driver, index, name); |
3029 | 3095 | ||
3030 | return device_create(tty_class, device, dev, NULL, name); | 3096 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) { |
3097 | retval = tty_cdev_add(driver, devt, index, 1); | ||
3098 | if (retval) | ||
3099 | goto error; | ||
3100 | cdev = true; | ||
3101 | } | ||
3102 | |||
3103 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
3104 | if (!dev) { | ||
3105 | retval = -ENOMEM; | ||
3106 | goto error; | ||
3107 | } | ||
3108 | |||
3109 | dev->devt = devt; | ||
3110 | dev->class = tty_class; | ||
3111 | dev->parent = device; | ||
3112 | dev->release = tty_device_create_release; | ||
3113 | dev_set_name(dev, "%s", name); | ||
3114 | dev->groups = attr_grp; | ||
3115 | dev_set_drvdata(dev, drvdata); | ||
3116 | |||
3117 | retval = device_register(dev); | ||
3118 | if (retval) | ||
3119 | goto error; | ||
3120 | |||
3121 | return dev; | ||
3122 | |||
3123 | error: | ||
3124 | put_device(dev); | ||
3125 | if (cdev) | ||
3126 | cdev_del(&driver->cdevs[index]); | ||
3127 | return ERR_PTR(retval); | ||
3031 | } | 3128 | } |
3032 | EXPORT_SYMBOL(tty_register_device); | 3129 | EXPORT_SYMBOL_GPL(tty_register_device_attr); |
3033 | 3130 | ||
3034 | /** | 3131 | /** |
3035 | * tty_unregister_device - unregister a tty device | 3132 | * tty_unregister_device - unregister a tty device |
@@ -3046,31 +3143,82 @@ void tty_unregister_device(struct tty_driver *driver, unsigned index) | |||
3046 | { | 3143 | { |
3047 | device_destroy(tty_class, | 3144 | device_destroy(tty_class, |
3048 | MKDEV(driver->major, driver->minor_start) + index); | 3145 | MKDEV(driver->major, driver->minor_start) + index); |
3146 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_ALLOC)) | ||
3147 | cdev_del(&driver->cdevs[index]); | ||
3049 | } | 3148 | } |
3050 | EXPORT_SYMBOL(tty_unregister_device); | 3149 | EXPORT_SYMBOL(tty_unregister_device); |
3051 | 3150 | ||
3052 | struct tty_driver *__alloc_tty_driver(int lines, struct module *owner) | 3151 | /** |
3152 | * __tty_alloc_driver -- allocate tty driver | ||
3153 | * @lines: count of lines this driver can handle at most | ||
3154 | * @owner: module which is repsonsible for this driver | ||
3155 | * @flags: some of TTY_DRIVER_* flags, will be set in driver->flags | ||
3156 | * | ||
3157 | * This should not be called directly, some of the provided macros should be | ||
3158 | * used instead. Use IS_ERR and friends on @retval. | ||
3159 | */ | ||
3160 | struct tty_driver *__tty_alloc_driver(unsigned int lines, struct module *owner, | ||
3161 | unsigned long flags) | ||
3053 | { | 3162 | { |
3054 | struct tty_driver *driver; | 3163 | struct tty_driver *driver; |
3164 | unsigned int cdevs = 1; | ||
3165 | int err; | ||
3166 | |||
3167 | if (!lines || (flags & TTY_DRIVER_UNNUMBERED_NODE && lines > 1)) | ||
3168 | return ERR_PTR(-EINVAL); | ||
3055 | 3169 | ||
3056 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); | 3170 | driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL); |
3057 | if (driver) { | 3171 | if (!driver) |
3058 | kref_init(&driver->kref); | 3172 | return ERR_PTR(-ENOMEM); |
3059 | driver->magic = TTY_DRIVER_MAGIC; | 3173 | |
3060 | driver->num = lines; | 3174 | kref_init(&driver->kref); |
3061 | driver->owner = owner; | 3175 | driver->magic = TTY_DRIVER_MAGIC; |
3062 | /* later we'll move allocation of tables here */ | 3176 | driver->num = lines; |
3177 | driver->owner = owner; | ||
3178 | driver->flags = flags; | ||
3179 | |||
3180 | if (!(flags & TTY_DRIVER_DEVPTS_MEM)) { | ||
3181 | driver->ttys = kcalloc(lines, sizeof(*driver->ttys), | ||
3182 | GFP_KERNEL); | ||
3183 | driver->termios = kcalloc(lines, sizeof(*driver->termios), | ||
3184 | GFP_KERNEL); | ||
3185 | if (!driver->ttys || !driver->termios) { | ||
3186 | err = -ENOMEM; | ||
3187 | goto err_free_all; | ||
3188 | } | ||
3063 | } | 3189 | } |
3190 | |||
3191 | if (!(flags & TTY_DRIVER_DYNAMIC_ALLOC)) { | ||
3192 | driver->ports = kcalloc(lines, sizeof(*driver->ports), | ||
3193 | GFP_KERNEL); | ||
3194 | if (!driver->ports) { | ||
3195 | err = -ENOMEM; | ||
3196 | goto err_free_all; | ||
3197 | } | ||
3198 | cdevs = lines; | ||
3199 | } | ||
3200 | |||
3201 | driver->cdevs = kcalloc(cdevs, sizeof(*driver->cdevs), GFP_KERNEL); | ||
3202 | if (!driver->cdevs) { | ||
3203 | err = -ENOMEM; | ||
3204 | goto err_free_all; | ||
3205 | } | ||
3206 | |||
3064 | return driver; | 3207 | return driver; |
3208 | err_free_all: | ||
3209 | kfree(driver->ports); | ||
3210 | kfree(driver->ttys); | ||
3211 | kfree(driver->termios); | ||
3212 | kfree(driver); | ||
3213 | return ERR_PTR(err); | ||
3065 | } | 3214 | } |
3066 | EXPORT_SYMBOL(__alloc_tty_driver); | 3215 | EXPORT_SYMBOL(__tty_alloc_driver); |
3067 | 3216 | ||
3068 | static void destruct_tty_driver(struct kref *kref) | 3217 | static void destruct_tty_driver(struct kref *kref) |
3069 | { | 3218 | { |
3070 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); | 3219 | struct tty_driver *driver = container_of(kref, struct tty_driver, kref); |
3071 | int i; | 3220 | int i; |
3072 | struct ktermios *tp; | 3221 | struct ktermios *tp; |
3073 | void *p; | ||
3074 | 3222 | ||
3075 | if (driver->flags & TTY_DRIVER_INSTALLED) { | 3223 | if (driver->flags & TTY_DRIVER_INSTALLED) { |
3076 | /* | 3224 | /* |
@@ -3087,13 +3235,14 @@ static void destruct_tty_driver(struct kref *kref) | |||
3087 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) | 3235 | if (!(driver->flags & TTY_DRIVER_DYNAMIC_DEV)) |
3088 | tty_unregister_device(driver, i); | 3236 | tty_unregister_device(driver, i); |
3089 | } | 3237 | } |
3090 | p = driver->ttys; | ||
3091 | proc_tty_unregister_driver(driver); | 3238 | proc_tty_unregister_driver(driver); |
3092 | driver->ttys = NULL; | 3239 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) |
3093 | driver->termios = NULL; | 3240 | cdev_del(&driver->cdevs[0]); |
3094 | kfree(p); | ||
3095 | cdev_del(&driver->cdev); | ||
3096 | } | 3241 | } |
3242 | kfree(driver->cdevs); | ||
3243 | kfree(driver->ports); | ||
3244 | kfree(driver->termios); | ||
3245 | kfree(driver->ttys); | ||
3097 | kfree(driver); | 3246 | kfree(driver); |
3098 | } | 3247 | } |
3099 | 3248 | ||
@@ -3124,15 +3273,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3124 | int error; | 3273 | int error; |
3125 | int i; | 3274 | int i; |
3126 | dev_t dev; | 3275 | dev_t dev; |
3127 | void **p = NULL; | ||
3128 | struct device *d; | 3276 | struct device *d; |
3129 | 3277 | ||
3130 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM) && driver->num) { | ||
3131 | p = kzalloc(driver->num * 2 * sizeof(void *), GFP_KERNEL); | ||
3132 | if (!p) | ||
3133 | return -ENOMEM; | ||
3134 | } | ||
3135 | |||
3136 | if (!driver->major) { | 3278 | if (!driver->major) { |
3137 | error = alloc_chrdev_region(&dev, driver->minor_start, | 3279 | error = alloc_chrdev_region(&dev, driver->minor_start, |
3138 | driver->num, driver->name); | 3280 | driver->num, driver->name); |
@@ -3144,28 +3286,13 @@ int tty_register_driver(struct tty_driver *driver) | |||
3144 | dev = MKDEV(driver->major, driver->minor_start); | 3286 | dev = MKDEV(driver->major, driver->minor_start); |
3145 | error = register_chrdev_region(dev, driver->num, driver->name); | 3287 | error = register_chrdev_region(dev, driver->num, driver->name); |
3146 | } | 3288 | } |
3147 | if (error < 0) { | 3289 | if (error < 0) |
3148 | kfree(p); | 3290 | goto err; |
3149 | return error; | ||
3150 | } | ||
3151 | 3291 | ||
3152 | if (p) { | 3292 | if (driver->flags & TTY_DRIVER_DYNAMIC_ALLOC) { |
3153 | driver->ttys = (struct tty_struct **)p; | 3293 | error = tty_cdev_add(driver, dev, 0, driver->num); |
3154 | driver->termios = (struct ktermios **)(p + driver->num); | 3294 | if (error) |
3155 | } else { | 3295 | goto err_unreg_char; |
3156 | driver->ttys = NULL; | ||
3157 | driver->termios = NULL; | ||
3158 | } | ||
3159 | |||
3160 | cdev_init(&driver->cdev, &tty_fops); | ||
3161 | driver->cdev.owner = driver->owner; | ||
3162 | error = cdev_add(&driver->cdev, dev, driver->num); | ||
3163 | if (error) { | ||
3164 | unregister_chrdev_region(dev, driver->num); | ||
3165 | driver->ttys = NULL; | ||
3166 | driver->termios = NULL; | ||
3167 | kfree(p); | ||
3168 | return error; | ||
3169 | } | 3296 | } |
3170 | 3297 | ||
3171 | mutex_lock(&tty_mutex); | 3298 | mutex_lock(&tty_mutex); |
@@ -3177,7 +3304,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3177 | d = tty_register_device(driver, i, NULL); | 3304 | d = tty_register_device(driver, i, NULL); |
3178 | if (IS_ERR(d)) { | 3305 | if (IS_ERR(d)) { |
3179 | error = PTR_ERR(d); | 3306 | error = PTR_ERR(d); |
3180 | goto err; | 3307 | goto err_unreg_devs; |
3181 | } | 3308 | } |
3182 | } | 3309 | } |
3183 | } | 3310 | } |
@@ -3185,7 +3312,7 @@ int tty_register_driver(struct tty_driver *driver) | |||
3185 | driver->flags |= TTY_DRIVER_INSTALLED; | 3312 | driver->flags |= TTY_DRIVER_INSTALLED; |
3186 | return 0; | 3313 | return 0; |
3187 | 3314 | ||
3188 | err: | 3315 | err_unreg_devs: |
3189 | for (i--; i >= 0; i--) | 3316 | for (i--; i >= 0; i--) |
3190 | tty_unregister_device(driver, i); | 3317 | tty_unregister_device(driver, i); |
3191 | 3318 | ||
@@ -3193,13 +3320,11 @@ err: | |||
3193 | list_del(&driver->tty_drivers); | 3320 | list_del(&driver->tty_drivers); |
3194 | mutex_unlock(&tty_mutex); | 3321 | mutex_unlock(&tty_mutex); |
3195 | 3322 | ||
3323 | err_unreg_char: | ||
3196 | unregister_chrdev_region(dev, driver->num); | 3324 | unregister_chrdev_region(dev, driver->num); |
3197 | driver->ttys = NULL; | 3325 | err: |
3198 | driver->termios = NULL; | ||
3199 | kfree(p); | ||
3200 | return error; | 3326 | return error; |
3201 | } | 3327 | } |
3202 | |||
3203 | EXPORT_SYMBOL(tty_register_driver); | 3328 | EXPORT_SYMBOL(tty_register_driver); |
3204 | 3329 | ||
3205 | /* | 3330 | /* |
diff --git a/drivers/tty/tty_ioctl.c b/drivers/tty/tty_ioctl.c index a1b9a2f68567..12b1fa0f4f86 100644 --- a/drivers/tty/tty_ioctl.c +++ b/drivers/tty/tty_ioctl.c | |||
@@ -410,7 +410,7 @@ EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate); | |||
410 | 410 | ||
411 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) | 411 | void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud) |
412 | { | 412 | { |
413 | tty_termios_encode_baud_rate(tty->termios, ibaud, obaud); | 413 | tty_termios_encode_baud_rate(&tty->termios, ibaud, obaud); |
414 | } | 414 | } |
415 | EXPORT_SYMBOL_GPL(tty_encode_baud_rate); | 415 | EXPORT_SYMBOL_GPL(tty_encode_baud_rate); |
416 | 416 | ||
@@ -427,7 +427,7 @@ EXPORT_SYMBOL_GPL(tty_encode_baud_rate); | |||
427 | 427 | ||
428 | speed_t tty_get_baud_rate(struct tty_struct *tty) | 428 | speed_t tty_get_baud_rate(struct tty_struct *tty) |
429 | { | 429 | { |
430 | speed_t baud = tty_termios_baud_rate(tty->termios); | 430 | speed_t baud = tty_termios_baud_rate(&tty->termios); |
431 | 431 | ||
432 | if (baud == 38400 && tty->alt_speed) { | 432 | if (baud == 38400 && tty->alt_speed) { |
433 | if (!tty->warned) { | 433 | if (!tty->warned) { |
@@ -509,14 +509,14 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
509 | /* FIXME: we need to decide on some locking/ordering semantics | 509 | /* FIXME: we need to decide on some locking/ordering semantics |
510 | for the set_termios notification eventually */ | 510 | for the set_termios notification eventually */ |
511 | mutex_lock(&tty->termios_mutex); | 511 | mutex_lock(&tty->termios_mutex); |
512 | old_termios = *tty->termios; | 512 | old_termios = tty->termios; |
513 | *tty->termios = *new_termios; | 513 | tty->termios = *new_termios; |
514 | unset_locked_termios(tty->termios, &old_termios, tty->termios_locked); | 514 | unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked); |
515 | 515 | ||
516 | /* See if packet mode change of state. */ | 516 | /* See if packet mode change of state. */ |
517 | if (tty->link && tty->link->packet) { | 517 | if (tty->link && tty->link->packet) { |
518 | int extproc = (old_termios.c_lflag & EXTPROC) | | 518 | int extproc = (old_termios.c_lflag & EXTPROC) | |
519 | (tty->termios->c_lflag & EXTPROC); | 519 | (tty->termios.c_lflag & EXTPROC); |
520 | int old_flow = ((old_termios.c_iflag & IXON) && | 520 | int old_flow = ((old_termios.c_iflag & IXON) && |
521 | (old_termios.c_cc[VSTOP] == '\023') && | 521 | (old_termios.c_cc[VSTOP] == '\023') && |
522 | (old_termios.c_cc[VSTART] == '\021')); | 522 | (old_termios.c_cc[VSTART] == '\021')); |
@@ -542,7 +542,7 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios) | |||
542 | if (tty->ops->set_termios) | 542 | if (tty->ops->set_termios) |
543 | (*tty->ops->set_termios)(tty, &old_termios); | 543 | (*tty->ops->set_termios)(tty, &old_termios); |
544 | else | 544 | else |
545 | tty_termios_copy_hw(tty->termios, &old_termios); | 545 | tty_termios_copy_hw(&tty->termios, &old_termios); |
546 | 546 | ||
547 | ld = tty_ldisc_ref(tty); | 547 | ld = tty_ldisc_ref(tty); |
548 | if (ld != NULL) { | 548 | if (ld != NULL) { |
@@ -578,7 +578,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | |||
578 | return retval; | 578 | return retval; |
579 | 579 | ||
580 | mutex_lock(&tty->termios_mutex); | 580 | mutex_lock(&tty->termios_mutex); |
581 | memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios)); | 581 | tmp_termios = tty->termios; |
582 | mutex_unlock(&tty->termios_mutex); | 582 | mutex_unlock(&tty->termios_mutex); |
583 | 583 | ||
584 | if (opt & TERMIOS_TERMIO) { | 584 | if (opt & TERMIOS_TERMIO) { |
@@ -632,14 +632,14 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt) | |||
632 | static void copy_termios(struct tty_struct *tty, struct ktermios *kterm) | 632 | static void copy_termios(struct tty_struct *tty, struct ktermios *kterm) |
633 | { | 633 | { |
634 | mutex_lock(&tty->termios_mutex); | 634 | mutex_lock(&tty->termios_mutex); |
635 | memcpy(kterm, tty->termios, sizeof(struct ktermios)); | 635 | *kterm = tty->termios; |
636 | mutex_unlock(&tty->termios_mutex); | 636 | mutex_unlock(&tty->termios_mutex); |
637 | } | 637 | } |
638 | 638 | ||
639 | static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm) | 639 | static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm) |
640 | { | 640 | { |
641 | mutex_lock(&tty->termios_mutex); | 641 | mutex_lock(&tty->termios_mutex); |
642 | memcpy(kterm, tty->termios_locked, sizeof(struct ktermios)); | 642 | *kterm = tty->termios_locked; |
643 | mutex_unlock(&tty->termios_mutex); | 643 | mutex_unlock(&tty->termios_mutex); |
644 | } | 644 | } |
645 | 645 | ||
@@ -707,16 +707,16 @@ static int get_sgflags(struct tty_struct *tty) | |||
707 | { | 707 | { |
708 | int flags = 0; | 708 | int flags = 0; |
709 | 709 | ||
710 | if (!(tty->termios->c_lflag & ICANON)) { | 710 | if (!(tty->termios.c_lflag & ICANON)) { |
711 | if (tty->termios->c_lflag & ISIG) | 711 | if (tty->termios.c_lflag & ISIG) |
712 | flags |= 0x02; /* cbreak */ | 712 | flags |= 0x02; /* cbreak */ |
713 | else | 713 | else |
714 | flags |= 0x20; /* raw */ | 714 | flags |= 0x20; /* raw */ |
715 | } | 715 | } |
716 | if (tty->termios->c_lflag & ECHO) | 716 | if (tty->termios.c_lflag & ECHO) |
717 | flags |= 0x08; /* echo */ | 717 | flags |= 0x08; /* echo */ |
718 | if (tty->termios->c_oflag & OPOST) | 718 | if (tty->termios.c_oflag & OPOST) |
719 | if (tty->termios->c_oflag & ONLCR) | 719 | if (tty->termios.c_oflag & ONLCR) |
720 | flags |= 0x10; /* crmod */ | 720 | flags |= 0x10; /* crmod */ |
721 | return flags; | 721 | return flags; |
722 | } | 722 | } |
@@ -726,10 +726,10 @@ static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | |||
726 | struct sgttyb tmp; | 726 | struct sgttyb tmp; |
727 | 727 | ||
728 | mutex_lock(&tty->termios_mutex); | 728 | mutex_lock(&tty->termios_mutex); |
729 | tmp.sg_ispeed = tty->termios->c_ispeed; | 729 | tmp.sg_ispeed = tty->termios.c_ispeed; |
730 | tmp.sg_ospeed = tty->termios->c_ospeed; | 730 | tmp.sg_ospeed = tty->termios.c_ospeed; |
731 | tmp.sg_erase = tty->termios->c_cc[VERASE]; | 731 | tmp.sg_erase = tty->termios.c_cc[VERASE]; |
732 | tmp.sg_kill = tty->termios->c_cc[VKILL]; | 732 | tmp.sg_kill = tty->termios.c_cc[VKILL]; |
733 | tmp.sg_flags = get_sgflags(tty); | 733 | tmp.sg_flags = get_sgflags(tty); |
734 | mutex_unlock(&tty->termios_mutex); | 734 | mutex_unlock(&tty->termios_mutex); |
735 | 735 | ||
@@ -787,7 +787,7 @@ static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb) | |||
787 | return -EFAULT; | 787 | return -EFAULT; |
788 | 788 | ||
789 | mutex_lock(&tty->termios_mutex); | 789 | mutex_lock(&tty->termios_mutex); |
790 | termios = *tty->termios; | 790 | termios = tty->termios; |
791 | termios.c_cc[VERASE] = tmp.sg_erase; | 791 | termios.c_cc[VERASE] = tmp.sg_erase; |
792 | termios.c_cc[VKILL] = tmp.sg_kill; | 792 | termios.c_cc[VKILL] = tmp.sg_kill; |
793 | set_sgflags(&termios, tmp.sg_flags); | 793 | set_sgflags(&termios, tmp.sg_flags); |
@@ -808,12 +808,12 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars) | |||
808 | struct tchars tmp; | 808 | struct tchars tmp; |
809 | 809 | ||
810 | mutex_lock(&tty->termios_mutex); | 810 | mutex_lock(&tty->termios_mutex); |
811 | tmp.t_intrc = tty->termios->c_cc[VINTR]; | 811 | tmp.t_intrc = tty->termios.c_cc[VINTR]; |
812 | tmp.t_quitc = tty->termios->c_cc[VQUIT]; | 812 | tmp.t_quitc = tty->termios.c_cc[VQUIT]; |
813 | tmp.t_startc = tty->termios->c_cc[VSTART]; | 813 | tmp.t_startc = tty->termios.c_cc[VSTART]; |
814 | tmp.t_stopc = tty->termios->c_cc[VSTOP]; | 814 | tmp.t_stopc = tty->termios.c_cc[VSTOP]; |
815 | tmp.t_eofc = tty->termios->c_cc[VEOF]; | 815 | tmp.t_eofc = tty->termios.c_cc[VEOF]; |
816 | tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */ | 816 | tmp.t_brkc = tty->termios.c_cc[VEOL2]; /* what is brkc anyway? */ |
817 | mutex_unlock(&tty->termios_mutex); | 817 | mutex_unlock(&tty->termios_mutex); |
818 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 818 | return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
819 | } | 819 | } |
@@ -825,12 +825,12 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars) | |||
825 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) | 825 | if (copy_from_user(&tmp, tchars, sizeof(tmp))) |
826 | return -EFAULT; | 826 | return -EFAULT; |
827 | mutex_lock(&tty->termios_mutex); | 827 | mutex_lock(&tty->termios_mutex); |
828 | tty->termios->c_cc[VINTR] = tmp.t_intrc; | 828 | tty->termios.c_cc[VINTR] = tmp.t_intrc; |
829 | tty->termios->c_cc[VQUIT] = tmp.t_quitc; | 829 | tty->termios.c_cc[VQUIT] = tmp.t_quitc; |
830 | tty->termios->c_cc[VSTART] = tmp.t_startc; | 830 | tty->termios.c_cc[VSTART] = tmp.t_startc; |
831 | tty->termios->c_cc[VSTOP] = tmp.t_stopc; | 831 | tty->termios.c_cc[VSTOP] = tmp.t_stopc; |
832 | tty->termios->c_cc[VEOF] = tmp.t_eofc; | 832 | tty->termios.c_cc[VEOF] = tmp.t_eofc; |
833 | tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ | 833 | tty->termios.c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */ |
834 | mutex_unlock(&tty->termios_mutex); | 834 | mutex_unlock(&tty->termios_mutex); |
835 | return 0; | 835 | return 0; |
836 | } | 836 | } |
@@ -842,14 +842,14 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
842 | struct ltchars tmp; | 842 | struct ltchars tmp; |
843 | 843 | ||
844 | mutex_lock(&tty->termios_mutex); | 844 | mutex_lock(&tty->termios_mutex); |
845 | tmp.t_suspc = tty->termios->c_cc[VSUSP]; | 845 | tmp.t_suspc = tty->termios.c_cc[VSUSP]; |
846 | /* what is dsuspc anyway? */ | 846 | /* what is dsuspc anyway? */ |
847 | tmp.t_dsuspc = tty->termios->c_cc[VSUSP]; | 847 | tmp.t_dsuspc = tty->termios.c_cc[VSUSP]; |
848 | tmp.t_rprntc = tty->termios->c_cc[VREPRINT]; | 848 | tmp.t_rprntc = tty->termios.c_cc[VREPRINT]; |
849 | /* what is flushc anyway? */ | 849 | /* what is flushc anyway? */ |
850 | tmp.t_flushc = tty->termios->c_cc[VEOL2]; | 850 | tmp.t_flushc = tty->termios.c_cc[VEOL2]; |
851 | tmp.t_werasc = tty->termios->c_cc[VWERASE]; | 851 | tmp.t_werasc = tty->termios.c_cc[VWERASE]; |
852 | tmp.t_lnextc = tty->termios->c_cc[VLNEXT]; | 852 | tmp.t_lnextc = tty->termios.c_cc[VLNEXT]; |
853 | mutex_unlock(&tty->termios_mutex); | 853 | mutex_unlock(&tty->termios_mutex); |
854 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; | 854 | return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0; |
855 | } | 855 | } |
@@ -862,14 +862,14 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars) | |||
862 | return -EFAULT; | 862 | return -EFAULT; |
863 | 863 | ||
864 | mutex_lock(&tty->termios_mutex); | 864 | mutex_lock(&tty->termios_mutex); |
865 | tty->termios->c_cc[VSUSP] = tmp.t_suspc; | 865 | tty->termios.c_cc[VSUSP] = tmp.t_suspc; |
866 | /* what is dsuspc anyway? */ | 866 | /* what is dsuspc anyway? */ |
867 | tty->termios->c_cc[VEOL2] = tmp.t_dsuspc; | 867 | tty->termios.c_cc[VEOL2] = tmp.t_dsuspc; |
868 | tty->termios->c_cc[VREPRINT] = tmp.t_rprntc; | 868 | tty->termios.c_cc[VREPRINT] = tmp.t_rprntc; |
869 | /* what is flushc anyway? */ | 869 | /* what is flushc anyway? */ |
870 | tty->termios->c_cc[VEOL2] = tmp.t_flushc; | 870 | tty->termios.c_cc[VEOL2] = tmp.t_flushc; |
871 | tty->termios->c_cc[VWERASE] = tmp.t_werasc; | 871 | tty->termios.c_cc[VWERASE] = tmp.t_werasc; |
872 | tty->termios->c_cc[VLNEXT] = tmp.t_lnextc; | 872 | tty->termios.c_cc[VLNEXT] = tmp.t_lnextc; |
873 | mutex_unlock(&tty->termios_mutex); | 873 | mutex_unlock(&tty->termios_mutex); |
874 | return 0; | 874 | return 0; |
875 | } | 875 | } |
@@ -920,12 +920,12 @@ static int tty_change_softcar(struct tty_struct *tty, int arg) | |||
920 | struct ktermios old; | 920 | struct ktermios old; |
921 | 921 | ||
922 | mutex_lock(&tty->termios_mutex); | 922 | mutex_lock(&tty->termios_mutex); |
923 | old = *tty->termios; | 923 | old = tty->termios; |
924 | tty->termios->c_cflag &= ~CLOCAL; | 924 | tty->termios.c_cflag &= ~CLOCAL; |
925 | tty->termios->c_cflag |= bit; | 925 | tty->termios.c_cflag |= bit; |
926 | if (tty->ops->set_termios) | 926 | if (tty->ops->set_termios) |
927 | tty->ops->set_termios(tty, &old); | 927 | tty->ops->set_termios(tty, &old); |
928 | if ((tty->termios->c_cflag & CLOCAL) != bit) | 928 | if ((tty->termios.c_cflag & CLOCAL) != bit) |
929 | ret = -EINVAL; | 929 | ret = -EINVAL; |
930 | mutex_unlock(&tty->termios_mutex); | 930 | mutex_unlock(&tty->termios_mutex); |
931 | return ret; | 931 | return ret; |
@@ -1031,7 +1031,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
1031 | (struct termios __user *) arg)) | 1031 | (struct termios __user *) arg)) |
1032 | return -EFAULT; | 1032 | return -EFAULT; |
1033 | mutex_lock(&real_tty->termios_mutex); | 1033 | mutex_lock(&real_tty->termios_mutex); |
1034 | memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios)); | 1034 | real_tty->termios_locked = kterm; |
1035 | mutex_unlock(&real_tty->termios_mutex); | 1035 | mutex_unlock(&real_tty->termios_mutex); |
1036 | return 0; | 1036 | return 0; |
1037 | #else | 1037 | #else |
@@ -1048,7 +1048,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file, | |||
1048 | (struct termios __user *) arg)) | 1048 | (struct termios __user *) arg)) |
1049 | return -EFAULT; | 1049 | return -EFAULT; |
1050 | mutex_lock(&real_tty->termios_mutex); | 1050 | mutex_lock(&real_tty->termios_mutex); |
1051 | memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios)); | 1051 | real_tty->termios_locked = kterm; |
1052 | mutex_unlock(&real_tty->termios_mutex); | 1052 | mutex_unlock(&real_tty->termios_mutex); |
1053 | return ret; | 1053 | return ret; |
1054 | #endif | 1054 | #endif |
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 6f99c9959f0c..4d7b56268c79 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c | |||
@@ -413,7 +413,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); | |||
413 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | 413 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) |
414 | { | 414 | { |
415 | mutex_lock(&tty->termios_mutex); | 415 | mutex_lock(&tty->termios_mutex); |
416 | tty->termios->c_line = num; | 416 | tty->termios.c_line = num; |
417 | mutex_unlock(&tty->termios_mutex); | 417 | mutex_unlock(&tty->termios_mutex); |
418 | } | 418 | } |
419 | 419 | ||
@@ -568,7 +568,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
568 | if (IS_ERR(new_ldisc)) | 568 | if (IS_ERR(new_ldisc)) |
569 | return PTR_ERR(new_ldisc); | 569 | return PTR_ERR(new_ldisc); |
570 | 570 | ||
571 | tty_lock(); | 571 | tty_lock(tty); |
572 | /* | 572 | /* |
573 | * We need to look at the tty locking here for pty/tty pairs | 573 | * We need to look at the tty locking here for pty/tty pairs |
574 | * when both sides try to change in parallel. | 574 | * when both sides try to change in parallel. |
@@ -582,12 +582,12 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
582 | */ | 582 | */ |
583 | 583 | ||
584 | if (tty->ldisc->ops->num == ldisc) { | 584 | if (tty->ldisc->ops->num == ldisc) { |
585 | tty_unlock(); | 585 | tty_unlock(tty); |
586 | tty_ldisc_put(new_ldisc); | 586 | tty_ldisc_put(new_ldisc); |
587 | return 0; | 587 | return 0; |
588 | } | 588 | } |
589 | 589 | ||
590 | tty_unlock(); | 590 | tty_unlock(tty); |
591 | /* | 591 | /* |
592 | * Problem: What do we do if this blocks ? | 592 | * Problem: What do we do if this blocks ? |
593 | * We could deadlock here | 593 | * We could deadlock here |
@@ -595,7 +595,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
595 | 595 | ||
596 | tty_wait_until_sent(tty, 0); | 596 | tty_wait_until_sent(tty, 0); |
597 | 597 | ||
598 | tty_lock(); | 598 | tty_lock(tty); |
599 | mutex_lock(&tty->ldisc_mutex); | 599 | mutex_lock(&tty->ldisc_mutex); |
600 | 600 | ||
601 | /* | 601 | /* |
@@ -605,10 +605,10 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
605 | 605 | ||
606 | while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { | 606 | while (test_bit(TTY_LDISC_CHANGING, &tty->flags)) { |
607 | mutex_unlock(&tty->ldisc_mutex); | 607 | mutex_unlock(&tty->ldisc_mutex); |
608 | tty_unlock(); | 608 | tty_unlock(tty); |
609 | wait_event(tty_ldisc_wait, | 609 | wait_event(tty_ldisc_wait, |
610 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); | 610 | test_bit(TTY_LDISC_CHANGING, &tty->flags) == 0); |
611 | tty_lock(); | 611 | tty_lock(tty); |
612 | mutex_lock(&tty->ldisc_mutex); | 612 | mutex_lock(&tty->ldisc_mutex); |
613 | } | 613 | } |
614 | 614 | ||
@@ -623,7 +623,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
623 | 623 | ||
624 | o_ldisc = tty->ldisc; | 624 | o_ldisc = tty->ldisc; |
625 | 625 | ||
626 | tty_unlock(); | 626 | tty_unlock(tty); |
627 | /* | 627 | /* |
628 | * Make sure we don't change while someone holds a | 628 | * Make sure we don't change while someone holds a |
629 | * reference to the line discipline. The TTY_LDISC bit | 629 | * reference to the line discipline. The TTY_LDISC bit |
@@ -650,7 +650,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
650 | 650 | ||
651 | retval = tty_ldisc_wait_idle(tty, 5 * HZ); | 651 | retval = tty_ldisc_wait_idle(tty, 5 * HZ); |
652 | 652 | ||
653 | tty_lock(); | 653 | tty_lock(tty); |
654 | mutex_lock(&tty->ldisc_mutex); | 654 | mutex_lock(&tty->ldisc_mutex); |
655 | 655 | ||
656 | /* handle wait idle failure locked */ | 656 | /* handle wait idle failure locked */ |
@@ -665,7 +665,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc) | |||
665 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); | 665 | clear_bit(TTY_LDISC_CHANGING, &tty->flags); |
666 | mutex_unlock(&tty->ldisc_mutex); | 666 | mutex_unlock(&tty->ldisc_mutex); |
667 | tty_ldisc_put(new_ldisc); | 667 | tty_ldisc_put(new_ldisc); |
668 | tty_unlock(); | 668 | tty_unlock(tty); |
669 | return -EIO; | 669 | return -EIO; |
670 | } | 670 | } |
671 | 671 | ||
@@ -708,7 +708,7 @@ enable: | |||
708 | if (o_work) | 708 | if (o_work) |
709 | schedule_work(&o_tty->buf.work); | 709 | schedule_work(&o_tty->buf.work); |
710 | mutex_unlock(&tty->ldisc_mutex); | 710 | mutex_unlock(&tty->ldisc_mutex); |
711 | tty_unlock(); | 711 | tty_unlock(tty); |
712 | return retval; | 712 | return retval; |
713 | } | 713 | } |
714 | 714 | ||
@@ -722,9 +722,9 @@ enable: | |||
722 | static void tty_reset_termios(struct tty_struct *tty) | 722 | static void tty_reset_termios(struct tty_struct *tty) |
723 | { | 723 | { |
724 | mutex_lock(&tty->termios_mutex); | 724 | mutex_lock(&tty->termios_mutex); |
725 | *tty->termios = tty->driver->init_termios; | 725 | tty->termios = tty->driver->init_termios; |
726 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | 726 | tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios); |
727 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | 727 | tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios); |
728 | mutex_unlock(&tty->termios_mutex); | 728 | mutex_unlock(&tty->termios_mutex); |
729 | } | 729 | } |
730 | 730 | ||
@@ -816,11 +816,11 @@ void tty_ldisc_hangup(struct tty_struct *tty) | |||
816 | * need to wait for another function taking the BTM | 816 | * need to wait for another function taking the BTM |
817 | */ | 817 | */ |
818 | clear_bit(TTY_LDISC, &tty->flags); | 818 | clear_bit(TTY_LDISC, &tty->flags); |
819 | tty_unlock(); | 819 | tty_unlock(tty); |
820 | cancel_work_sync(&tty->buf.work); | 820 | cancel_work_sync(&tty->buf.work); |
821 | mutex_unlock(&tty->ldisc_mutex); | 821 | mutex_unlock(&tty->ldisc_mutex); |
822 | retry: | 822 | retry: |
823 | tty_lock(); | 823 | tty_lock(tty); |
824 | mutex_lock(&tty->ldisc_mutex); | 824 | mutex_lock(&tty->ldisc_mutex); |
825 | 825 | ||
826 | /* At this point we have a closed ldisc and we want to | 826 | /* At this point we have a closed ldisc and we want to |
@@ -831,7 +831,7 @@ retry: | |||
831 | if (atomic_read(&tty->ldisc->users) != 1) { | 831 | if (atomic_read(&tty->ldisc->users) != 1) { |
832 | char cur_n[TASK_COMM_LEN], tty_n[64]; | 832 | char cur_n[TASK_COMM_LEN], tty_n[64]; |
833 | long timeout = 3 * HZ; | 833 | long timeout = 3 * HZ; |
834 | tty_unlock(); | 834 | tty_unlock(tty); |
835 | 835 | ||
836 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { | 836 | while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) { |
837 | timeout = MAX_SCHEDULE_TIMEOUT; | 837 | timeout = MAX_SCHEDULE_TIMEOUT; |
@@ -846,7 +846,7 @@ retry: | |||
846 | 846 | ||
847 | if (reset == 0) { | 847 | if (reset == 0) { |
848 | 848 | ||
849 | if (!tty_ldisc_reinit(tty, tty->termios->c_line)) | 849 | if (!tty_ldisc_reinit(tty, tty->termios.c_line)) |
850 | err = tty_ldisc_open(tty, tty->ldisc); | 850 | err = tty_ldisc_open(tty, tty->ldisc); |
851 | else | 851 | else |
852 | err = 1; | 852 | err = 1; |
@@ -894,6 +894,23 @@ int tty_ldisc_setup(struct tty_struct *tty, struct tty_struct *o_tty) | |||
894 | tty_ldisc_enable(tty); | 894 | tty_ldisc_enable(tty); |
895 | return 0; | 895 | return 0; |
896 | } | 896 | } |
897 | |||
898 | static void tty_ldisc_kill(struct tty_struct *tty) | ||
899 | { | ||
900 | mutex_lock(&tty->ldisc_mutex); | ||
901 | /* | ||
902 | * Now kill off the ldisc | ||
903 | */ | ||
904 | tty_ldisc_close(tty, tty->ldisc); | ||
905 | tty_ldisc_put(tty->ldisc); | ||
906 | /* Force an oops if we mess this up */ | ||
907 | tty->ldisc = NULL; | ||
908 | |||
909 | /* Ensure the next open requests the N_TTY ldisc */ | ||
910 | tty_set_termios_ldisc(tty, N_TTY); | ||
911 | mutex_unlock(&tty->ldisc_mutex); | ||
912 | } | ||
913 | |||
897 | /** | 914 | /** |
898 | * tty_ldisc_release - release line discipline | 915 | * tty_ldisc_release - release line discipline |
899 | * @tty: tty being shut down | 916 | * @tty: tty being shut down |
@@ -912,28 +929,21 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty) | |||
912 | * race with the set_ldisc code path. | 929 | * race with the set_ldisc code path. |
913 | */ | 930 | */ |
914 | 931 | ||
915 | tty_unlock(); | 932 | tty_lock_pair(tty, o_tty); |
916 | tty_ldisc_halt(tty); | 933 | tty_ldisc_halt(tty); |
917 | tty_ldisc_flush_works(tty); | 934 | tty_ldisc_flush_works(tty); |
918 | tty_lock(); | 935 | if (o_tty) { |
919 | 936 | tty_ldisc_halt(o_tty); | |
920 | mutex_lock(&tty->ldisc_mutex); | 937 | tty_ldisc_flush_works(o_tty); |
921 | /* | 938 | } |
922 | * Now kill off the ldisc | ||
923 | */ | ||
924 | tty_ldisc_close(tty, tty->ldisc); | ||
925 | tty_ldisc_put(tty->ldisc); | ||
926 | /* Force an oops if we mess this up */ | ||
927 | tty->ldisc = NULL; | ||
928 | |||
929 | /* Ensure the next open requests the N_TTY ldisc */ | ||
930 | tty_set_termios_ldisc(tty, N_TTY); | ||
931 | mutex_unlock(&tty->ldisc_mutex); | ||
932 | 939 | ||
933 | /* This will need doing differently if we need to lock */ | 940 | /* This will need doing differently if we need to lock */ |
941 | tty_ldisc_kill(tty); | ||
942 | |||
934 | if (o_tty) | 943 | if (o_tty) |
935 | tty_ldisc_release(o_tty, NULL); | 944 | tty_ldisc_kill(o_tty); |
936 | 945 | ||
946 | tty_unlock_pair(tty, o_tty); | ||
937 | /* And the memory resources remaining (buffers, termios) will be | 947 | /* And the memory resources remaining (buffers, termios) will be |
938 | disposed of when the kref hits zero */ | 948 | disposed of when the kref hits zero */ |
939 | } | 949 | } |
diff --git a/drivers/tty/tty_mutex.c b/drivers/tty/tty_mutex.c index 9ff986c32a21..67feac9e6ebb 100644 --- a/drivers/tty/tty_mutex.c +++ b/drivers/tty/tty_mutex.c | |||
@@ -4,29 +4,70 @@ | |||
4 | #include <linux/semaphore.h> | 4 | #include <linux/semaphore.h> |
5 | #include <linux/sched.h> | 5 | #include <linux/sched.h> |
6 | 6 | ||
7 | /* | 7 | /* Legacy tty mutex glue */ |
8 | * The 'big tty mutex' | 8 | |
9 | * | 9 | enum { |
10 | * This mutex is taken and released by tty_lock() and tty_unlock(), | 10 | TTY_MUTEX_NORMAL, |
11 | * replacing the older big kernel lock. | 11 | TTY_MUTEX_NESTED, |
12 | * It can no longer be taken recursively, and does not get | 12 | }; |
13 | * released implicitly while sleeping. | ||
14 | * | ||
15 | * Don't use in new code. | ||
16 | */ | ||
17 | static DEFINE_MUTEX(big_tty_mutex); | ||
18 | 13 | ||
19 | /* | 14 | /* |
20 | * Getting the big tty mutex. | 15 | * Getting the big tty mutex. |
21 | */ | 16 | */ |
22 | void __lockfunc tty_lock(void) | 17 | |
18 | static void __lockfunc tty_lock_nested(struct tty_struct *tty, | ||
19 | unsigned int subclass) | ||
23 | { | 20 | { |
24 | mutex_lock(&big_tty_mutex); | 21 | if (tty->magic != TTY_MAGIC) { |
22 | printk(KERN_ERR "L Bad %p\n", tty); | ||
23 | WARN_ON(1); | ||
24 | return; | ||
25 | } | ||
26 | tty_kref_get(tty); | ||
27 | mutex_lock_nested(&tty->legacy_mutex, subclass); | ||
28 | } | ||
29 | |||
30 | void __lockfunc tty_lock(struct tty_struct *tty) | ||
31 | { | ||
32 | return tty_lock_nested(tty, TTY_MUTEX_NORMAL); | ||
25 | } | 33 | } |
26 | EXPORT_SYMBOL(tty_lock); | 34 | EXPORT_SYMBOL(tty_lock); |
27 | 35 | ||
28 | void __lockfunc tty_unlock(void) | 36 | void __lockfunc tty_unlock(struct tty_struct *tty) |
29 | { | 37 | { |
30 | mutex_unlock(&big_tty_mutex); | 38 | if (tty->magic != TTY_MAGIC) { |
39 | printk(KERN_ERR "U Bad %p\n", tty); | ||
40 | WARN_ON(1); | ||
41 | return; | ||
42 | } | ||
43 | mutex_unlock(&tty->legacy_mutex); | ||
44 | tty_kref_put(tty); | ||
31 | } | 45 | } |
32 | EXPORT_SYMBOL(tty_unlock); | 46 | EXPORT_SYMBOL(tty_unlock); |
47 | |||
48 | /* | ||
49 | * Getting the big tty mutex for a pair of ttys with lock ordering | ||
50 | * On a non pty/tty pair tty2 can be NULL which is just fine. | ||
51 | */ | ||
52 | void __lockfunc tty_lock_pair(struct tty_struct *tty, | ||
53 | struct tty_struct *tty2) | ||
54 | { | ||
55 | if (tty < tty2) { | ||
56 | tty_lock(tty); | ||
57 | tty_lock_nested(tty2, TTY_MUTEX_NESTED); | ||
58 | } else { | ||
59 | if (tty2 && tty2 != tty) | ||
60 | tty_lock(tty2); | ||
61 | tty_lock_nested(tty, TTY_MUTEX_NESTED); | ||
62 | } | ||
63 | } | ||
64 | EXPORT_SYMBOL(tty_lock_pair); | ||
65 | |||
66 | void __lockfunc tty_unlock_pair(struct tty_struct *tty, | ||
67 | struct tty_struct *tty2) | ||
68 | { | ||
69 | tty_unlock(tty); | ||
70 | if (tty2 && tty2 != tty) | ||
71 | tty_unlock(tty2); | ||
72 | } | ||
73 | EXPORT_SYMBOL(tty_unlock_pair); | ||
diff --git a/drivers/tty/tty_port.c b/drivers/tty/tty_port.c index bf6e238146ae..d7bdd8d0c23f 100644 --- a/drivers/tty/tty_port.c +++ b/drivers/tty/tty_port.c | |||
@@ -33,6 +33,70 @@ void tty_port_init(struct tty_port *port) | |||
33 | } | 33 | } |
34 | EXPORT_SYMBOL(tty_port_init); | 34 | EXPORT_SYMBOL(tty_port_init); |
35 | 35 | ||
36 | /** | ||
37 | * tty_port_link_device - link tty and tty_port | ||
38 | * @port: tty_port of the device | ||
39 | * @driver: tty_driver for this device | ||
40 | * @index: index of the tty | ||
41 | * | ||
42 | * Provide the tty layer wit ha link from a tty (specified by @index) to a | ||
43 | * tty_port (@port). Use this only if neither tty_port_register_device nor | ||
44 | * tty_port_install is used in the driver. If used, this has to be called before | ||
45 | * tty_register_driver. | ||
46 | */ | ||
47 | void tty_port_link_device(struct tty_port *port, | ||
48 | struct tty_driver *driver, unsigned index) | ||
49 | { | ||
50 | if (WARN_ON(index >= driver->num)) | ||
51 | return; | ||
52 | driver->ports[index] = port; | ||
53 | } | ||
54 | EXPORT_SYMBOL_GPL(tty_port_link_device); | ||
55 | |||
56 | /** | ||
57 | * tty_port_register_device - register tty device | ||
58 | * @port: tty_port of the device | ||
59 | * @driver: tty_driver for this device | ||
60 | * @index: index of the tty | ||
61 | * @device: parent if exists, otherwise NULL | ||
62 | * | ||
63 | * It is the same as tty_register_device except the provided @port is linked to | ||
64 | * a concrete tty specified by @index. Use this or tty_port_install (or both). | ||
65 | * Call tty_port_link_device as a last resort. | ||
66 | */ | ||
67 | struct device *tty_port_register_device(struct tty_port *port, | ||
68 | struct tty_driver *driver, unsigned index, | ||
69 | struct device *device) | ||
70 | { | ||
71 | tty_port_link_device(port, driver, index); | ||
72 | return tty_register_device(driver, index, device); | ||
73 | } | ||
74 | EXPORT_SYMBOL_GPL(tty_port_register_device); | ||
75 | |||
76 | /** | ||
77 | * tty_port_register_device_attr - register tty device | ||
78 | * @port: tty_port of the device | ||
79 | * @driver: tty_driver for this device | ||
80 | * @index: index of the tty | ||
81 | * @device: parent if exists, otherwise NULL | ||
82 | * @drvdata: Driver data to be set to device. | ||
83 | * @attr_grp: Attribute group to be set on device. | ||
84 | * | ||
85 | * It is the same as tty_register_device_attr except the provided @port is | ||
86 | * linked to a concrete tty specified by @index. Use this or tty_port_install | ||
87 | * (or both). Call tty_port_link_device as a last resort. | ||
88 | */ | ||
89 | struct device *tty_port_register_device_attr(struct tty_port *port, | ||
90 | struct tty_driver *driver, unsigned index, | ||
91 | struct device *device, void *drvdata, | ||
92 | const struct attribute_group **attr_grp) | ||
93 | { | ||
94 | tty_port_link_device(port, driver, index); | ||
95 | return tty_register_device_attr(driver, index, device, drvdata, | ||
96 | attr_grp); | ||
97 | } | ||
98 | EXPORT_SYMBOL_GPL(tty_port_register_device_attr); | ||
99 | |||
36 | int tty_port_alloc_xmit_buf(struct tty_port *port) | 100 | int tty_port_alloc_xmit_buf(struct tty_port *port) |
37 | { | 101 | { |
38 | /* We may sleep in get_zeroed_page() */ | 102 | /* We may sleep in get_zeroed_page() */ |
@@ -230,7 +294,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
230 | 294 | ||
231 | /* block if port is in the process of being closed */ | 295 | /* block if port is in the process of being closed */ |
232 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { | 296 | if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { |
233 | wait_event_interruptible_tty(port->close_wait, | 297 | wait_event_interruptible_tty(tty, port->close_wait, |
234 | !(port->flags & ASYNC_CLOSING)); | 298 | !(port->flags & ASYNC_CLOSING)); |
235 | if (port->flags & ASYNC_HUP_NOTIFY) | 299 | if (port->flags & ASYNC_HUP_NOTIFY) |
236 | return -EAGAIN; | 300 | return -EAGAIN; |
@@ -246,7 +310,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
246 | } | 310 | } |
247 | if (filp->f_flags & O_NONBLOCK) { | 311 | if (filp->f_flags & O_NONBLOCK) { |
248 | /* Indicate we are open */ | 312 | /* Indicate we are open */ |
249 | if (tty->termios->c_cflag & CBAUD) | 313 | if (tty->termios.c_cflag & CBAUD) |
250 | tty_port_raise_dtr_rts(port); | 314 | tty_port_raise_dtr_rts(port); |
251 | port->flags |= ASYNC_NORMAL_ACTIVE; | 315 | port->flags |= ASYNC_NORMAL_ACTIVE; |
252 | return 0; | 316 | return 0; |
@@ -270,7 +334,7 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
270 | 334 | ||
271 | while (1) { | 335 | while (1) { |
272 | /* Indicate we are open */ | 336 | /* Indicate we are open */ |
273 | if (tty->termios->c_cflag & CBAUD) | 337 | if (tty->termios.c_cflag & CBAUD) |
274 | tty_port_raise_dtr_rts(port); | 338 | tty_port_raise_dtr_rts(port); |
275 | 339 | ||
276 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); | 340 | prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE); |
@@ -296,9 +360,9 @@ int tty_port_block_til_ready(struct tty_port *port, | |||
296 | retval = -ERESTARTSYS; | 360 | retval = -ERESTARTSYS; |
297 | break; | 361 | break; |
298 | } | 362 | } |
299 | tty_unlock(); | 363 | tty_unlock(tty); |
300 | schedule(); | 364 | schedule(); |
301 | tty_lock(); | 365 | tty_lock(tty); |
302 | } | 366 | } |
303 | finish_wait(&port->open_wait, &wait); | 367 | finish_wait(&port->open_wait, &wait); |
304 | 368 | ||
@@ -369,7 +433,7 @@ int tty_port_close_start(struct tty_port *port, | |||
369 | 433 | ||
370 | /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to | 434 | /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to |
371 | hang up the line */ | 435 | hang up the line */ |
372 | if (tty->termios->c_cflag & HUPCL) | 436 | if (tty->termios.c_cflag & HUPCL) |
373 | tty_port_lower_dtr_rts(port); | 437 | tty_port_lower_dtr_rts(port); |
374 | 438 | ||
375 | /* Don't call port->drop for the last reference. Callers will want | 439 | /* Don't call port->drop for the last reference. Callers will want |
@@ -413,6 +477,24 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty, | |||
413 | } | 477 | } |
414 | EXPORT_SYMBOL(tty_port_close); | 478 | EXPORT_SYMBOL(tty_port_close); |
415 | 479 | ||
480 | /** | ||
481 | * tty_port_install - generic tty->ops->install handler | ||
482 | * @port: tty_port of the device | ||
483 | * @driver: tty_driver for this device | ||
484 | * @tty: tty to be installed | ||
485 | * | ||
486 | * It is the same as tty_standard_install except the provided @port is linked | ||
487 | * to a concrete tty specified by @tty. Use this or tty_port_register_device | ||
488 | * (or both). Call tty_port_link_device as a last resort. | ||
489 | */ | ||
490 | int tty_port_install(struct tty_port *port, struct tty_driver *driver, | ||
491 | struct tty_struct *tty) | ||
492 | { | ||
493 | tty->port = port; | ||
494 | return tty_standard_install(driver, tty); | ||
495 | } | ||
496 | EXPORT_SYMBOL_GPL(tty_port_install); | ||
497 | |||
416 | int tty_port_open(struct tty_port *port, struct tty_struct *tty, | 498 | int tty_port_open(struct tty_port *port, struct tty_struct *tty, |
417 | struct file *filp) | 499 | struct file *filp) |
418 | { | 500 | { |
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c index 48cc6f25cfd3..681765baef69 100644 --- a/drivers/tty/vt/keyboard.c +++ b/drivers/tty/vt/keyboard.c | |||
@@ -119,6 +119,7 @@ static const int NR_TYPES = ARRAY_SIZE(max_vals); | |||
119 | 119 | ||
120 | static struct input_handler kbd_handler; | 120 | static struct input_handler kbd_handler; |
121 | static DEFINE_SPINLOCK(kbd_event_lock); | 121 | static DEFINE_SPINLOCK(kbd_event_lock); |
122 | static DEFINE_SPINLOCK(led_lock); | ||
122 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ | 123 | static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ |
123 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ | 124 | static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ |
124 | static bool dead_key_next; | 125 | static bool dead_key_next; |
@@ -310,7 +311,7 @@ static void put_queue(struct vc_data *vc, int ch) | |||
310 | 311 | ||
311 | if (tty) { | 312 | if (tty) { |
312 | tty_insert_flip_char(tty, ch, 0); | 313 | tty_insert_flip_char(tty, ch, 0); |
313 | con_schedule_flip(tty); | 314 | tty_schedule_flip(tty); |
314 | } | 315 | } |
315 | } | 316 | } |
316 | 317 | ||
@@ -325,7 +326,7 @@ static void puts_queue(struct vc_data *vc, char *cp) | |||
325 | tty_insert_flip_char(tty, *cp, 0); | 326 | tty_insert_flip_char(tty, *cp, 0); |
326 | cp++; | 327 | cp++; |
327 | } | 328 | } |
328 | con_schedule_flip(tty); | 329 | tty_schedule_flip(tty); |
329 | } | 330 | } |
330 | 331 | ||
331 | static void applkey(struct vc_data *vc, int key, char mode) | 332 | static void applkey(struct vc_data *vc, int key, char mode) |
@@ -586,7 +587,7 @@ static void fn_send_intr(struct vc_data *vc) | |||
586 | if (!tty) | 587 | if (!tty) |
587 | return; | 588 | return; |
588 | tty_insert_flip_char(tty, 0, TTY_BREAK); | 589 | tty_insert_flip_char(tty, 0, TTY_BREAK); |
589 | con_schedule_flip(tty); | 590 | tty_schedule_flip(tty); |
590 | } | 591 | } |
591 | 592 | ||
592 | static void fn_scroll_forw(struct vc_data *vc) | 593 | static void fn_scroll_forw(struct vc_data *vc) |
@@ -984,7 +985,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) | |||
984 | * or (ii) whatever pattern of lights people want to show using KDSETLED, | 985 | * or (ii) whatever pattern of lights people want to show using KDSETLED, |
985 | * or (iii) specified bits of specified words in kernel memory. | 986 | * or (iii) specified bits of specified words in kernel memory. |
986 | */ | 987 | */ |
987 | unsigned char getledstate(void) | 988 | static unsigned char getledstate(void) |
988 | { | 989 | { |
989 | return ledstate; | 990 | return ledstate; |
990 | } | 991 | } |
@@ -992,7 +993,7 @@ unsigned char getledstate(void) | |||
992 | void setledstate(struct kbd_struct *kbd, unsigned int led) | 993 | void setledstate(struct kbd_struct *kbd, unsigned int led) |
993 | { | 994 | { |
994 | unsigned long flags; | 995 | unsigned long flags; |
995 | spin_lock_irqsave(&kbd_event_lock, flags); | 996 | spin_lock_irqsave(&led_lock, flags); |
996 | if (!(led & ~7)) { | 997 | if (!(led & ~7)) { |
997 | ledioctl = led; | 998 | ledioctl = led; |
998 | kbd->ledmode = LED_SHOW_IOCTL; | 999 | kbd->ledmode = LED_SHOW_IOCTL; |
@@ -1000,7 +1001,7 @@ void setledstate(struct kbd_struct *kbd, unsigned int led) | |||
1000 | kbd->ledmode = LED_SHOW_FLAGS; | 1001 | kbd->ledmode = LED_SHOW_FLAGS; |
1001 | 1002 | ||
1002 | set_leds(); | 1003 | set_leds(); |
1003 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 1004 | spin_unlock_irqrestore(&led_lock, flags); |
1004 | } | 1005 | } |
1005 | 1006 | ||
1006 | static inline unsigned char getleds(void) | 1007 | static inline unsigned char getleds(void) |
@@ -1049,13 +1050,13 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data) | |||
1049 | */ | 1050 | */ |
1050 | int vt_get_leds(int console, int flag) | 1051 | int vt_get_leds(int console, int flag) |
1051 | { | 1052 | { |
1052 | unsigned long flags; | ||
1053 | struct kbd_struct * kbd = kbd_table + console; | 1053 | struct kbd_struct * kbd = kbd_table + console; |
1054 | int ret; | 1054 | int ret; |
1055 | unsigned long flags; | ||
1055 | 1056 | ||
1056 | spin_lock_irqsave(&kbd_event_lock, flags); | 1057 | spin_lock_irqsave(&led_lock, flags); |
1057 | ret = vc_kbd_led(kbd, flag); | 1058 | ret = vc_kbd_led(kbd, flag); |
1058 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 1059 | spin_unlock_irqrestore(&led_lock, flags); |
1059 | 1060 | ||
1060 | return ret; | 1061 | return ret; |
1061 | } | 1062 | } |
@@ -1091,11 +1092,11 @@ void vt_set_led_state(int console, int leds) | |||
1091 | void vt_kbd_con_start(int console) | 1092 | void vt_kbd_con_start(int console) |
1092 | { | 1093 | { |
1093 | struct kbd_struct * kbd = kbd_table + console; | 1094 | struct kbd_struct * kbd = kbd_table + console; |
1094 | /* unsigned long flags; */ | 1095 | unsigned long flags; |
1095 | /* spin_lock_irqsave(&kbd_event_lock, flags); */ | 1096 | spin_lock_irqsave(&led_lock, flags); |
1096 | clr_vc_kbd_led(kbd, VC_SCROLLOCK); | 1097 | clr_vc_kbd_led(kbd, VC_SCROLLOCK); |
1097 | set_leds(); | 1098 | set_leds(); |
1098 | /* spin_unlock_irqrestore(&kbd_event_lock, flags); */ | 1099 | spin_unlock_irqrestore(&led_lock, flags); |
1099 | } | 1100 | } |
1100 | 1101 | ||
1101 | /** | 1102 | /** |
@@ -1104,21 +1105,15 @@ void vt_kbd_con_start(int console) | |||
1104 | * | 1105 | * |
1105 | * Handle console stop. This is a wrapper for the VT layer | 1106 | * Handle console stop. This is a wrapper for the VT layer |
1106 | * so that we can keep kbd knowledge internal | 1107 | * so that we can keep kbd knowledge internal |
1107 | * | ||
1108 | * FIXME: We eventually need to hold the kbd lock here to protect | ||
1109 | * the LED updating. We can't do it yet because fn_hold calls stop_tty | ||
1110 | * and start_tty under the kbd_event_lock, while normal tty paths | ||
1111 | * don't hold the lock. We probably need to split out an LED lock | ||
1112 | * but not during an -rc release! | ||
1113 | */ | 1108 | */ |
1114 | void vt_kbd_con_stop(int console) | 1109 | void vt_kbd_con_stop(int console) |
1115 | { | 1110 | { |
1116 | struct kbd_struct * kbd = kbd_table + console; | 1111 | struct kbd_struct * kbd = kbd_table + console; |
1117 | /* unsigned long flags; */ | 1112 | unsigned long flags; |
1118 | /* spin_lock_irqsave(&kbd_event_lock, flags); */ | 1113 | spin_lock_irqsave(&led_lock, flags); |
1119 | set_vc_kbd_led(kbd, VC_SCROLLOCK); | 1114 | set_vc_kbd_led(kbd, VC_SCROLLOCK); |
1120 | set_leds(); | 1115 | set_leds(); |
1121 | /* spin_unlock_irqrestore(&kbd_event_lock, flags); */ | 1116 | spin_unlock_irqrestore(&led_lock, flags); |
1122 | } | 1117 | } |
1123 | 1118 | ||
1124 | /* | 1119 | /* |
@@ -1130,7 +1125,12 @@ void vt_kbd_con_stop(int console) | |||
1130 | */ | 1125 | */ |
1131 | static void kbd_bh(unsigned long dummy) | 1126 | static void kbd_bh(unsigned long dummy) |
1132 | { | 1127 | { |
1133 | unsigned char leds = getleds(); | 1128 | unsigned char leds; |
1129 | unsigned long flags; | ||
1130 | |||
1131 | spin_lock_irqsave(&led_lock, flags); | ||
1132 | leds = getleds(); | ||
1133 | spin_unlock_irqrestore(&led_lock, flags); | ||
1134 | 1134 | ||
1135 | if (leds != ledstate) { | 1135 | if (leds != ledstate) { |
1136 | input_handler_for_each_handle(&kbd_handler, &leds, | 1136 | input_handler_for_each_handle(&kbd_handler, &leds, |
@@ -2035,11 +2035,11 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm) | |||
2035 | return -EPERM; | 2035 | return -EPERM; |
2036 | if (arg & ~0x77) | 2036 | if (arg & ~0x77) |
2037 | return -EINVAL; | 2037 | return -EINVAL; |
2038 | spin_lock_irqsave(&kbd_event_lock, flags); | 2038 | spin_lock_irqsave(&led_lock, flags); |
2039 | kbd->ledflagstate = (arg & 7); | 2039 | kbd->ledflagstate = (arg & 7); |
2040 | kbd->default_ledflagstate = ((arg >> 4) & 7); | 2040 | kbd->default_ledflagstate = ((arg >> 4) & 7); |
2041 | set_leds(); | 2041 | set_leds(); |
2042 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 2042 | spin_unlock_irqrestore(&led_lock, flags); |
2043 | return 0; | 2043 | return 0; |
2044 | 2044 | ||
2045 | /* the ioctls below only set the lights, not the functions */ | 2045 | /* the ioctls below only set the lights, not the functions */ |
@@ -2134,8 +2134,10 @@ void vt_reset_keyboard(int console) | |||
2134 | clr_vc_kbd_mode(kbd, VC_CRLF); | 2134 | clr_vc_kbd_mode(kbd, VC_CRLF); |
2135 | kbd->lockstate = 0; | 2135 | kbd->lockstate = 0; |
2136 | kbd->slockstate = 0; | 2136 | kbd->slockstate = 0; |
2137 | spin_lock(&led_lock); | ||
2137 | kbd->ledmode = LED_SHOW_FLAGS; | 2138 | kbd->ledmode = LED_SHOW_FLAGS; |
2138 | kbd->ledflagstate = kbd->default_ledflagstate; | 2139 | kbd->ledflagstate = kbd->default_ledflagstate; |
2140 | spin_unlock(&led_lock); | ||
2139 | /* do not do set_leds here because this causes an endless tasklet loop | 2141 | /* do not do set_leds here because this causes an endless tasklet loop |
2140 | when the keyboard hasn't been initialized yet */ | 2142 | when the keyboard hasn't been initialized yet */ |
2141 | spin_unlock_irqrestore(&kbd_event_lock, flags); | 2143 | spin_unlock_irqrestore(&kbd_event_lock, flags); |
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 84cbf298c094..999ca63afdef 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c | |||
@@ -537,45 +537,27 @@ void complement_pos(struct vc_data *vc, int offset) | |||
537 | 537 | ||
538 | static void insert_char(struct vc_data *vc, unsigned int nr) | 538 | static void insert_char(struct vc_data *vc, unsigned int nr) |
539 | { | 539 | { |
540 | unsigned short *p, *q = (unsigned short *)vc->vc_pos; | 540 | unsigned short *p = (unsigned short *) vc->vc_pos; |
541 | 541 | ||
542 | p = q + vc->vc_cols - nr - vc->vc_x; | 542 | scr_memmovew(p + nr, p, vc->vc_cols - vc->vc_x); |
543 | while (--p >= q) | 543 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); |
544 | scr_writew(scr_readw(p), p + nr); | ||
545 | scr_memsetw(q, vc->vc_video_erase_char, nr * 2); | ||
546 | vc->vc_need_wrap = 0; | 544 | vc->vc_need_wrap = 0; |
547 | if (DO_UPDATE(vc)) { | 545 | if (DO_UPDATE(vc)) |
548 | unsigned short oldattr = vc->vc_attr; | 546 | do_update_region(vc, (unsigned long) p, |
549 | vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x, vc->vc_y, vc->vc_x + nr, 1, | 547 | (vc->vc_cols - vc->vc_x) / 2 + 1); |
550 | vc->vc_cols - vc->vc_x - nr); | ||
551 | vc->vc_attr = vc->vc_video_erase_char >> 8; | ||
552 | while (nr--) | ||
553 | vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, vc->vc_x + nr); | ||
554 | vc->vc_attr = oldattr; | ||
555 | } | ||
556 | } | 548 | } |
557 | 549 | ||
558 | static void delete_char(struct vc_data *vc, unsigned int nr) | 550 | static void delete_char(struct vc_data *vc, unsigned int nr) |
559 | { | 551 | { |
560 | unsigned int i = vc->vc_x; | 552 | unsigned short *p = (unsigned short *) vc->vc_pos; |
561 | unsigned short *p = (unsigned short *)vc->vc_pos; | ||
562 | 553 | ||
563 | while (++i <= vc->vc_cols - nr) { | 554 | scr_memcpyw(p, p + nr, vc->vc_cols - vc->vc_x - nr); |
564 | scr_writew(scr_readw(p+nr), p); | 555 | scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char, |
565 | p++; | 556 | nr * 2); |
566 | } | ||
567 | scr_memsetw(p, vc->vc_video_erase_char, nr * 2); | ||
568 | vc->vc_need_wrap = 0; | 557 | vc->vc_need_wrap = 0; |
569 | if (DO_UPDATE(vc)) { | 558 | if (DO_UPDATE(vc)) |
570 | unsigned short oldattr = vc->vc_attr; | 559 | do_update_region(vc, (unsigned long) p, |
571 | vc->vc_sw->con_bmove(vc, vc->vc_y, vc->vc_x + nr, vc->vc_y, vc->vc_x, 1, | 560 | (vc->vc_cols - vc->vc_x) / 2); |
572 | vc->vc_cols - vc->vc_x - nr); | ||
573 | vc->vc_attr = vc->vc_video_erase_char >> 8; | ||
574 | while (nr--) | ||
575 | vc->vc_sw->con_putc(vc, vc->vc_video_erase_char, vc->vc_y, | ||
576 | vc->vc_cols - 1 - nr); | ||
577 | vc->vc_attr = oldattr; | ||
578 | } | ||
579 | } | 561 | } |
580 | 562 | ||
581 | static int softcursor_original; | 563 | static int softcursor_original; |
@@ -1172,45 +1154,26 @@ static void csi_J(struct vc_data *vc, int vpar) | |||
1172 | case 0: /* erase from cursor to end of display */ | 1154 | case 0: /* erase from cursor to end of display */ |
1173 | count = (vc->vc_scr_end - vc->vc_pos) >> 1; | 1155 | count = (vc->vc_scr_end - vc->vc_pos) >> 1; |
1174 | start = (unsigned short *)vc->vc_pos; | 1156 | start = (unsigned short *)vc->vc_pos; |
1175 | if (DO_UPDATE(vc)) { | ||
1176 | /* do in two stages */ | ||
1177 | vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, | ||
1178 | vc->vc_cols - vc->vc_x); | ||
1179 | vc->vc_sw->con_clear(vc, vc->vc_y + 1, 0, | ||
1180 | vc->vc_rows - vc->vc_y - 1, | ||
1181 | vc->vc_cols); | ||
1182 | } | ||
1183 | break; | 1157 | break; |
1184 | case 1: /* erase from start to cursor */ | 1158 | case 1: /* erase from start to cursor */ |
1185 | count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; | 1159 | count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1; |
1186 | start = (unsigned short *)vc->vc_origin; | 1160 | start = (unsigned short *)vc->vc_origin; |
1187 | if (DO_UPDATE(vc)) { | ||
1188 | /* do in two stages */ | ||
1189 | vc->vc_sw->con_clear(vc, 0, 0, vc->vc_y, | ||
1190 | vc->vc_cols); | ||
1191 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
1192 | vc->vc_x + 1); | ||
1193 | } | ||
1194 | break; | 1161 | break; |
1195 | case 3: /* erase scroll-back buffer (and whole display) */ | 1162 | case 3: /* erase scroll-back buffer (and whole display) */ |
1196 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, | 1163 | scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, |
1197 | vc->vc_screenbuf_size >> 1); | 1164 | vc->vc_screenbuf_size >> 1); |
1198 | set_origin(vc); | 1165 | set_origin(vc); |
1199 | if (CON_IS_VISIBLE(vc)) | ||
1200 | update_screen(vc); | ||
1201 | /* fall through */ | 1166 | /* fall through */ |
1202 | case 2: /* erase whole display */ | 1167 | case 2: /* erase whole display */ |
1203 | count = vc->vc_cols * vc->vc_rows; | 1168 | count = vc->vc_cols * vc->vc_rows; |
1204 | start = (unsigned short *)vc->vc_origin; | 1169 | start = (unsigned short *)vc->vc_origin; |
1205 | if (DO_UPDATE(vc)) | ||
1206 | vc->vc_sw->con_clear(vc, 0, 0, | ||
1207 | vc->vc_rows, | ||
1208 | vc->vc_cols); | ||
1209 | break; | 1170 | break; |
1210 | default: | 1171 | default: |
1211 | return; | 1172 | return; |
1212 | } | 1173 | } |
1213 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); | 1174 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); |
1175 | if (DO_UPDATE(vc)) | ||
1176 | do_update_region(vc, (unsigned long) start, count); | ||
1214 | vc->vc_need_wrap = 0; | 1177 | vc->vc_need_wrap = 0; |
1215 | } | 1178 | } |
1216 | 1179 | ||
@@ -1223,29 +1186,22 @@ static void csi_K(struct vc_data *vc, int vpar) | |||
1223 | case 0: /* erase from cursor to end of line */ | 1186 | case 0: /* erase from cursor to end of line */ |
1224 | count = vc->vc_cols - vc->vc_x; | 1187 | count = vc->vc_cols - vc->vc_x; |
1225 | start = (unsigned short *)vc->vc_pos; | 1188 | start = (unsigned short *)vc->vc_pos; |
1226 | if (DO_UPDATE(vc)) | ||
1227 | vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, | ||
1228 | vc->vc_cols - vc->vc_x); | ||
1229 | break; | 1189 | break; |
1230 | case 1: /* erase from start of line to cursor */ | 1190 | case 1: /* erase from start of line to cursor */ |
1231 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); | 1191 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); |
1232 | count = vc->vc_x + 1; | 1192 | count = vc->vc_x + 1; |
1233 | if (DO_UPDATE(vc)) | ||
1234 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
1235 | vc->vc_x + 1); | ||
1236 | break; | 1193 | break; |
1237 | case 2: /* erase whole line */ | 1194 | case 2: /* erase whole line */ |
1238 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); | 1195 | start = (unsigned short *)(vc->vc_pos - (vc->vc_x << 1)); |
1239 | count = vc->vc_cols; | 1196 | count = vc->vc_cols; |
1240 | if (DO_UPDATE(vc)) | ||
1241 | vc->vc_sw->con_clear(vc, vc->vc_y, 0, 1, | ||
1242 | vc->vc_cols); | ||
1243 | break; | 1197 | break; |
1244 | default: | 1198 | default: |
1245 | return; | 1199 | return; |
1246 | } | 1200 | } |
1247 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); | 1201 | scr_memsetw(start, vc->vc_video_erase_char, 2 * count); |
1248 | vc->vc_need_wrap = 0; | 1202 | vc->vc_need_wrap = 0; |
1203 | if (DO_UPDATE(vc)) | ||
1204 | do_update_region(vc, (unsigned long) start, count); | ||
1249 | } | 1205 | } |
1250 | 1206 | ||
1251 | static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ | 1207 | static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */ |
@@ -1380,7 +1336,7 @@ static void respond_string(const char *p, struct tty_struct *tty) | |||
1380 | tty_insert_flip_char(tty, *p, 0); | 1336 | tty_insert_flip_char(tty, *p, 0); |
1381 | p++; | 1337 | p++; |
1382 | } | 1338 | } |
1383 | con_schedule_flip(tty); | 1339 | tty_schedule_flip(tty); |
1384 | } | 1340 | } |
1385 | 1341 | ||
1386 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) | 1342 | static void cursor_report(struct vc_data *vc, struct tty_struct *tty) |
@@ -2792,41 +2748,52 @@ static void con_flush_chars(struct tty_struct *tty) | |||
2792 | /* | 2748 | /* |
2793 | * Allocate the console screen memory. | 2749 | * Allocate the console screen memory. |
2794 | */ | 2750 | */ |
2795 | static int con_open(struct tty_struct *tty, struct file *filp) | 2751 | static int con_install(struct tty_driver *driver, struct tty_struct *tty) |
2796 | { | 2752 | { |
2797 | unsigned int currcons = tty->index; | 2753 | unsigned int currcons = tty->index; |
2798 | int ret = 0; | 2754 | struct vc_data *vc; |
2755 | int ret; | ||
2799 | 2756 | ||
2800 | console_lock(); | 2757 | console_lock(); |
2801 | if (tty->driver_data == NULL) { | 2758 | ret = vc_allocate(currcons); |
2802 | ret = vc_allocate(currcons); | 2759 | if (ret) |
2803 | if (ret == 0) { | 2760 | goto unlock; |
2804 | struct vc_data *vc = vc_cons[currcons].d; | ||
2805 | 2761 | ||
2806 | /* Still being freed */ | 2762 | vc = vc_cons[currcons].d; |
2807 | if (vc->port.tty) { | ||
2808 | console_unlock(); | ||
2809 | return -ERESTARTSYS; | ||
2810 | } | ||
2811 | tty->driver_data = vc; | ||
2812 | vc->port.tty = tty; | ||
2813 | 2763 | ||
2814 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | 2764 | /* Still being freed */ |
2815 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; | 2765 | if (vc->port.tty) { |
2816 | tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; | 2766 | ret = -ERESTARTSYS; |
2817 | } | 2767 | goto unlock; |
2818 | if (vc->vc_utf) | ||
2819 | tty->termios->c_iflag |= IUTF8; | ||
2820 | else | ||
2821 | tty->termios->c_iflag &= ~IUTF8; | ||
2822 | console_unlock(); | ||
2823 | return ret; | ||
2824 | } | ||
2825 | } | 2768 | } |
2769 | |||
2770 | ret = tty_port_install(&vc->port, driver, tty); | ||
2771 | if (ret) | ||
2772 | goto unlock; | ||
2773 | |||
2774 | tty->driver_data = vc; | ||
2775 | vc->port.tty = tty; | ||
2776 | |||
2777 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | ||
2778 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; | ||
2779 | tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; | ||
2780 | } | ||
2781 | if (vc->vc_utf) | ||
2782 | tty->termios.c_iflag |= IUTF8; | ||
2783 | else | ||
2784 | tty->termios.c_iflag &= ~IUTF8; | ||
2785 | unlock: | ||
2826 | console_unlock(); | 2786 | console_unlock(); |
2827 | return ret; | 2787 | return ret; |
2828 | } | 2788 | } |
2829 | 2789 | ||
2790 | static int con_open(struct tty_struct *tty, struct file *filp) | ||
2791 | { | ||
2792 | /* everything done in install */ | ||
2793 | return 0; | ||
2794 | } | ||
2795 | |||
2796 | |||
2830 | static void con_close(struct tty_struct *tty, struct file *filp) | 2797 | static void con_close(struct tty_struct *tty, struct file *filp) |
2831 | { | 2798 | { |
2832 | /* Nothing to do - we defer to shutdown */ | 2799 | /* Nothing to do - we defer to shutdown */ |
@@ -2839,7 +2806,6 @@ static void con_shutdown(struct tty_struct *tty) | |||
2839 | console_lock(); | 2806 | console_lock(); |
2840 | vc->port.tty = NULL; | 2807 | vc->port.tty = NULL; |
2841 | console_unlock(); | 2808 | console_unlock(); |
2842 | tty_shutdown(tty); | ||
2843 | } | 2809 | } |
2844 | 2810 | ||
2845 | static int default_italic_color = 2; // green (ASCII) | 2811 | static int default_italic_color = 2; // green (ASCII) |
@@ -2947,6 +2913,7 @@ static int __init con_init(void) | |||
2947 | console_initcall(con_init); | 2913 | console_initcall(con_init); |
2948 | 2914 | ||
2949 | static const struct tty_operations con_ops = { | 2915 | static const struct tty_operations con_ops = { |
2916 | .install = con_install, | ||
2950 | .open = con_open, | 2917 | .open = con_open, |
2951 | .close = con_close, | 2918 | .close = con_close, |
2952 | .write = con_write, | 2919 | .write = con_write, |
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7065df6036ca..7de2285d9fa9 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -13,7 +13,6 @@ config USB_ARCH_HAS_OHCI | |||
13 | default y if PXA3xx | 13 | default y if PXA3xx |
14 | default y if ARCH_EP93XX | 14 | default y if ARCH_EP93XX |
15 | default y if ARCH_AT91 | 15 | default y if ARCH_AT91 |
16 | default y if ARCH_PNX4008 | ||
17 | default y if MFD_TC6393XB | 16 | default y if MFD_TC6393XB |
18 | default y if ARCH_W90X900 | 17 | default y if ARCH_W90X900 |
19 | default y if ARCH_DAVINCI_DA8XX | 18 | default y if ARCH_DAVINCI_DA8XX |
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index c7a032a4f0c5..d214448b677e 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c | |||
@@ -78,8 +78,7 @@ static inline int ep_to_bit(struct ci13xxx *ci, int n) | |||
78 | } | 78 | } |
79 | 79 | ||
80 | /** | 80 | /** |
81 | * hw_device_state: enables/disables interrupts & starts/stops device (execute | 81 | * hw_device_state: enables/disables interrupts (execute without interruption) |
82 | * without interruption) | ||
83 | * @dma: 0 => disable, !0 => enable and set dma engine | 82 | * @dma: 0 => disable, !0 => enable and set dma engine |
84 | * | 83 | * |
85 | * This function returns an error code | 84 | * This function returns an error code |
@@ -91,9 +90,7 @@ static int hw_device_state(struct ci13xxx *ci, u32 dma) | |||
91 | /* interrupt, error, port change, reset, sleep/suspend */ | 90 | /* interrupt, error, port change, reset, sleep/suspend */ |
92 | hw_write(ci, OP_USBINTR, ~0, | 91 | hw_write(ci, OP_USBINTR, ~0, |
93 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); | 92 | USBi_UI|USBi_UEI|USBi_PCI|USBi_URI|USBi_SLI); |
94 | hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
95 | } else { | 93 | } else { |
96 | hw_write(ci, OP_USBCMD, USBCMD_RS, 0); | ||
97 | hw_write(ci, OP_USBINTR, ~0, 0); | 94 | hw_write(ci, OP_USBINTR, ~0, 0); |
98 | } | 95 | } |
99 | return 0; | 96 | return 0; |
@@ -774,10 +771,7 @@ __acquires(mEp->lock) | |||
774 | { | 771 | { |
775 | struct ci13xxx_req *mReq, *mReqTemp; | 772 | struct ci13xxx_req *mReq, *mReqTemp; |
776 | struct ci13xxx_ep *mEpTemp = mEp; | 773 | struct ci13xxx_ep *mEpTemp = mEp; |
777 | int uninitialized_var(retval); | 774 | int retval = 0; |
778 | |||
779 | if (list_empty(&mEp->qh.queue)) | ||
780 | return -EINVAL; | ||
781 | 775 | ||
782 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, | 776 | list_for_each_entry_safe(mReq, mReqTemp, &mEp->qh.queue, |
783 | queue) { | 777 | queue) { |
@@ -1420,6 +1414,21 @@ static int ci13xxx_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | |||
1420 | return -ENOTSUPP; | 1414 | return -ENOTSUPP; |
1421 | } | 1415 | } |
1422 | 1416 | ||
1417 | /* Change Data+ pullup status | ||
1418 | * this func is used by usb_gadget_connect/disconnet | ||
1419 | */ | ||
1420 | static int ci13xxx_pullup(struct usb_gadget *_gadget, int is_on) | ||
1421 | { | ||
1422 | struct ci13xxx *ci = container_of(_gadget, struct ci13xxx, gadget); | ||
1423 | |||
1424 | if (is_on) | ||
1425 | hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS); | ||
1426 | else | ||
1427 | hw_write(ci, OP_USBCMD, USBCMD_RS, 0); | ||
1428 | |||
1429 | return 0; | ||
1430 | } | ||
1431 | |||
1423 | static int ci13xxx_start(struct usb_gadget *gadget, | 1432 | static int ci13xxx_start(struct usb_gadget *gadget, |
1424 | struct usb_gadget_driver *driver); | 1433 | struct usb_gadget_driver *driver); |
1425 | static int ci13xxx_stop(struct usb_gadget *gadget, | 1434 | static int ci13xxx_stop(struct usb_gadget *gadget, |
@@ -1432,6 +1441,7 @@ static int ci13xxx_stop(struct usb_gadget *gadget, | |||
1432 | static const struct usb_gadget_ops usb_gadget_ops = { | 1441 | static const struct usb_gadget_ops usb_gadget_ops = { |
1433 | .vbus_session = ci13xxx_vbus_session, | 1442 | .vbus_session = ci13xxx_vbus_session, |
1434 | .wakeup = ci13xxx_wakeup, | 1443 | .wakeup = ci13xxx_wakeup, |
1444 | .pullup = ci13xxx_pullup, | ||
1435 | .vbus_draw = ci13xxx_vbus_draw, | 1445 | .vbus_draw = ci13xxx_vbus_draw, |
1436 | .udc_start = ci13xxx_start, | 1446 | .udc_start = ci13xxx_start, |
1437 | .udc_stop = ci13xxx_stop, | 1447 | .udc_stop = ci13xxx_stop, |
@@ -1455,7 +1465,12 @@ static int init_eps(struct ci13xxx *ci) | |||
1455 | 1465 | ||
1456 | mEp->ep.name = mEp->name; | 1466 | mEp->ep.name = mEp->name; |
1457 | mEp->ep.ops = &usb_ep_ops; | 1467 | mEp->ep.ops = &usb_ep_ops; |
1458 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | 1468 | /* |
1469 | * for ep0: maxP defined in desc, for other | ||
1470 | * eps, maxP is set by epautoconfig() called | ||
1471 | * by gadget layer | ||
1472 | */ | ||
1473 | mEp->ep.maxpacket = (unsigned short)~0; | ||
1459 | 1474 | ||
1460 | INIT_LIST_HEAD(&mEp->qh.queue); | 1475 | INIT_LIST_HEAD(&mEp->qh.queue); |
1461 | mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, | 1476 | mEp->qh.ptr = dma_pool_alloc(ci->qh_pool, GFP_KERNEL, |
@@ -1475,6 +1490,7 @@ static int init_eps(struct ci13xxx *ci) | |||
1475 | else | 1490 | else |
1476 | ci->ep0in = mEp; | 1491 | ci->ep0in = mEp; |
1477 | 1492 | ||
1493 | mEp->ep.maxpacket = CTRL_PAYLOAD_MAX; | ||
1478 | continue; | 1494 | continue; |
1479 | } | 1495 | } |
1480 | 1496 | ||
@@ -1484,6 +1500,17 @@ static int init_eps(struct ci13xxx *ci) | |||
1484 | return retval; | 1500 | return retval; |
1485 | } | 1501 | } |
1486 | 1502 | ||
1503 | static void destroy_eps(struct ci13xxx *ci) | ||
1504 | { | ||
1505 | int i; | ||
1506 | |||
1507 | for (i = 0; i < ci->hw_ep_max; i++) { | ||
1508 | struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; | ||
1509 | |||
1510 | dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
1511 | } | ||
1512 | } | ||
1513 | |||
1487 | /** | 1514 | /** |
1488 | * ci13xxx_start: register a gadget driver | 1515 | * ci13xxx_start: register a gadget driver |
1489 | * @gadget: our gadget | 1516 | * @gadget: our gadget |
@@ -1691,7 +1718,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1691 | if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { | 1718 | if (ci->platdata->flags & CI13XXX_REQUIRE_TRANSCEIVER) { |
1692 | if (ci->transceiver == NULL) { | 1719 | if (ci->transceiver == NULL) { |
1693 | retval = -ENODEV; | 1720 | retval = -ENODEV; |
1694 | goto free_pools; | 1721 | goto destroy_eps; |
1695 | } | 1722 | } |
1696 | } | 1723 | } |
1697 | 1724 | ||
@@ -1729,7 +1756,7 @@ static int udc_start(struct ci13xxx *ci) | |||
1729 | 1756 | ||
1730 | remove_trans: | 1757 | remove_trans: |
1731 | if (!IS_ERR_OR_NULL(ci->transceiver)) { | 1758 | if (!IS_ERR_OR_NULL(ci->transceiver)) { |
1732 | otg_set_peripheral(ci->transceiver->otg, &ci->gadget); | 1759 | otg_set_peripheral(ci->transceiver->otg, NULL); |
1733 | if (ci->global_phy) | 1760 | if (ci->global_phy) |
1734 | usb_put_phy(ci->transceiver); | 1761 | usb_put_phy(ci->transceiver); |
1735 | } | 1762 | } |
@@ -1742,6 +1769,8 @@ unreg_device: | |||
1742 | put_transceiver: | 1769 | put_transceiver: |
1743 | if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) | 1770 | if (!IS_ERR_OR_NULL(ci->transceiver) && ci->global_phy) |
1744 | usb_put_phy(ci->transceiver); | 1771 | usb_put_phy(ci->transceiver); |
1772 | destroy_eps: | ||
1773 | destroy_eps(ci); | ||
1745 | free_pools: | 1774 | free_pools: |
1746 | dma_pool_destroy(ci->td_pool); | 1775 | dma_pool_destroy(ci->td_pool); |
1747 | free_qh_pool: | 1776 | free_qh_pool: |
@@ -1756,18 +1785,12 @@ free_qh_pool: | |||
1756 | */ | 1785 | */ |
1757 | static void udc_stop(struct ci13xxx *ci) | 1786 | static void udc_stop(struct ci13xxx *ci) |
1758 | { | 1787 | { |
1759 | int i; | ||
1760 | |||
1761 | if (ci == NULL) | 1788 | if (ci == NULL) |
1762 | return; | 1789 | return; |
1763 | 1790 | ||
1764 | usb_del_gadget_udc(&ci->gadget); | 1791 | usb_del_gadget_udc(&ci->gadget); |
1765 | 1792 | ||
1766 | for (i = 0; i < ci->hw_ep_max; i++) { | 1793 | destroy_eps(ci); |
1767 | struct ci13xxx_ep *mEp = &ci->ci13xxx_ep[i]; | ||
1768 | |||
1769 | dma_pool_free(ci->qh_pool, mEp->qh.ptr, mEp->qh.dma); | ||
1770 | } | ||
1771 | 1794 | ||
1772 | dma_pool_destroy(ci->td_pool); | 1795 | dma_pool_destroy(ci->td_pool); |
1773 | dma_pool_destroy(ci->qh_pool); | 1796 | dma_pool_destroy(ci->qh_pool); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index f763ed7ba91e..ff7b5a8d501c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -826,7 +826,7 @@ static void acm_tty_set_termios(struct tty_struct *tty, | |||
826 | struct ktermios *termios_old) | 826 | struct ktermios *termios_old) |
827 | { | 827 | { |
828 | struct acm *acm = tty->driver_data; | 828 | struct acm *acm = tty->driver_data; |
829 | struct ktermios *termios = tty->termios; | 829 | struct ktermios *termios = &tty->termios; |
830 | struct usb_cdc_line_coding newline; | 830 | struct usb_cdc_line_coding newline; |
831 | int newctrl = acm->ctrlout; | 831 | int newctrl = acm->ctrlout; |
832 | 832 | ||
@@ -1299,7 +1299,8 @@ skip_countries: | |||
1299 | usb_set_intfdata(data_interface, acm); | 1299 | usb_set_intfdata(data_interface, acm); |
1300 | 1300 | ||
1301 | usb_get_intf(control_interface); | 1301 | usb_get_intf(control_interface); |
1302 | tty_register_device(acm_tty_driver, minor, &control_interface->dev); | 1302 | tty_port_register_device(&acm->port, acm_tty_driver, minor, |
1303 | &control_interface->dev); | ||
1303 | 1304 | ||
1304 | return 0; | 1305 | return 0; |
1305 | alloc_fail7: | 1306 | alloc_fail7: |
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 65a55abb791f..5f0cb417b736 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c | |||
@@ -109,12 +109,14 @@ static struct usb_driver wdm_driver; | |||
109 | /* return intfdata if we own the interface, else look up intf in the list */ | 109 | /* return intfdata if we own the interface, else look up intf in the list */ |
110 | static struct wdm_device *wdm_find_device(struct usb_interface *intf) | 110 | static struct wdm_device *wdm_find_device(struct usb_interface *intf) |
111 | { | 111 | { |
112 | struct wdm_device *desc = NULL; | 112 | struct wdm_device *desc; |
113 | 113 | ||
114 | spin_lock(&wdm_device_list_lock); | 114 | spin_lock(&wdm_device_list_lock); |
115 | list_for_each_entry(desc, &wdm_device_list, device_list) | 115 | list_for_each_entry(desc, &wdm_device_list, device_list) |
116 | if (desc->intf == intf) | 116 | if (desc->intf == intf) |
117 | break; | 117 | goto found; |
118 | desc = NULL; | ||
119 | found: | ||
118 | spin_unlock(&wdm_device_list_lock); | 120 | spin_unlock(&wdm_device_list_lock); |
119 | 121 | ||
120 | return desc; | 122 | return desc; |
@@ -122,12 +124,14 @@ static struct wdm_device *wdm_find_device(struct usb_interface *intf) | |||
122 | 124 | ||
123 | static struct wdm_device *wdm_find_device_by_minor(int minor) | 125 | static struct wdm_device *wdm_find_device_by_minor(int minor) |
124 | { | 126 | { |
125 | struct wdm_device *desc = NULL; | 127 | struct wdm_device *desc; |
126 | 128 | ||
127 | spin_lock(&wdm_device_list_lock); | 129 | spin_lock(&wdm_device_list_lock); |
128 | list_for_each_entry(desc, &wdm_device_list, device_list) | 130 | list_for_each_entry(desc, &wdm_device_list, device_list) |
129 | if (desc->intf->minor == minor) | 131 | if (desc->intf->minor == minor) |
130 | break; | 132 | goto found; |
133 | desc = NULL; | ||
134 | found: | ||
131 | spin_unlock(&wdm_device_list_lock); | 135 | spin_unlock(&wdm_device_list_lock); |
132 | 136 | ||
133 | return desc; | 137 | return desc; |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index f15501f4c585..e77a8e8eaa23 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -71,6 +71,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
71 | { USB_DEVICE(0x04b4, 0x0526), .driver_info = | 71 | { USB_DEVICE(0x04b4, 0x0526), .driver_info = |
72 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 72 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
73 | 73 | ||
74 | /* Microchip Joss Optical infrared touchboard device */ | ||
75 | { USB_DEVICE(0x04d8, 0x000c), .driver_info = | ||
76 | USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
77 | |||
74 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ | 78 | /* Samsung Android phone modem - ID conflict with SPH-I500 */ |
75 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = | 79 | { USB_DEVICE(0x04e8, 0x6601), .driver_info = |
76 | USB_QUIRK_CONFIG_INTF_STRINGS }, | 80 | USB_QUIRK_CONFIG_INTF_STRINGS }, |
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index c34452a7304f..a68ff53124dc 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c | |||
@@ -436,16 +436,21 @@ static int __devinit dwc3_probe(struct platform_device *pdev) | |||
436 | dev_err(dev, "missing IRQ\n"); | 436 | dev_err(dev, "missing IRQ\n"); |
437 | return -ENODEV; | 437 | return -ENODEV; |
438 | } | 438 | } |
439 | dwc->xhci_resources[1] = *res; | 439 | dwc->xhci_resources[1].start = res->start; |
440 | dwc->xhci_resources[1].end = res->end; | ||
441 | dwc->xhci_resources[1].flags = res->flags; | ||
442 | dwc->xhci_resources[1].name = res->name; | ||
440 | 443 | ||
441 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 444 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
442 | if (!res) { | 445 | if (!res) { |
443 | dev_err(dev, "missing memory resource\n"); | 446 | dev_err(dev, "missing memory resource\n"); |
444 | return -ENODEV; | 447 | return -ENODEV; |
445 | } | 448 | } |
446 | dwc->xhci_resources[0] = *res; | 449 | dwc->xhci_resources[0].start = res->start; |
447 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + | 450 | dwc->xhci_resources[0].end = dwc->xhci_resources[0].start + |
448 | DWC3_XHCI_REGS_END; | 451 | DWC3_XHCI_REGS_END; |
452 | dwc->xhci_resources[0].flags = res->flags; | ||
453 | dwc->xhci_resources[0].name = res->name; | ||
449 | 454 | ||
450 | /* | 455 | /* |
451 | * Request memory region but exclude xHCI regs, | 456 | * Request memory region but exclude xHCI regs, |
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 9b94886b66e5..e4d5ca86b9da 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c | |||
@@ -720,7 +720,6 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc, | |||
720 | transferred = min_t(u32, ur->length, | 720 | transferred = min_t(u32, ur->length, |
721 | transfer_size - length); | 721 | transfer_size - length); |
722 | memcpy(ur->buf, dwc->ep0_bounce, transferred); | 722 | memcpy(ur->buf, dwc->ep0_bounce, transferred); |
723 | dwc->ep0_bounced = false; | ||
724 | } else { | 723 | } else { |
725 | transferred = ur->length - length; | 724 | transferred = ur->length - length; |
726 | } | 725 | } |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 58fdfad96b4d..c2813c2b005a 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -263,8 +263,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, | |||
263 | if (req->request.status == -EINPROGRESS) | 263 | if (req->request.status == -EINPROGRESS) |
264 | req->request.status = status; | 264 | req->request.status = status; |
265 | 265 | ||
266 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | 266 | if (dwc->ep0_bounced && dep->number == 0) |
267 | req->direction); | 267 | dwc->ep0_bounced = false; |
268 | else | ||
269 | usb_gadget_unmap_request(&dwc->gadget, &req->request, | ||
270 | req->direction); | ||
268 | 271 | ||
269 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", | 272 | dev_dbg(dwc->dev, "request %p from %s completed %d/%d ===> %d\n", |
270 | req, dep->name, req->request.actual, | 273 | req, dep->name, req->request.actual, |
@@ -1026,6 +1029,7 @@ static void __dwc3_gadget_start_isoc(struct dwc3 *dwc, | |||
1026 | if (list_empty(&dep->request_list)) { | 1029 | if (list_empty(&dep->request_list)) { |
1027 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", | 1030 | dev_vdbg(dwc->dev, "ISOC ep %s run out for requests.\n", |
1028 | dep->name); | 1031 | dep->name); |
1032 | dep->flags |= DWC3_EP_PENDING_REQUEST; | ||
1029 | return; | 1033 | return; |
1030 | } | 1034 | } |
1031 | 1035 | ||
@@ -1089,6 +1093,17 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req) | |||
1089 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { | 1093 | if (dep->flags & DWC3_EP_PENDING_REQUEST) { |
1090 | int ret; | 1094 | int ret; |
1091 | 1095 | ||
1096 | /* | ||
1097 | * If xfernotready is already elapsed and it is a case | ||
1098 | * of isoc transfer, then issue END TRANSFER, so that | ||
1099 | * you can receive xfernotready again and can have | ||
1100 | * notion of current microframe. | ||
1101 | */ | ||
1102 | if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { | ||
1103 | dwc3_stop_active_transfer(dwc, dep->number); | ||
1104 | return 0; | ||
1105 | } | ||
1106 | |||
1092 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); | 1107 | ret = __dwc3_gadget_kick_transfer(dep, 0, true); |
1093 | if (ret && ret != -EBUSY) { | 1108 | if (ret && ret != -EBUSY) { |
1094 | struct dwc3 *dwc = dep->dwc; | 1109 | struct dwc3 *dwc = dep->dwc; |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index c9e66dfb02e6..1e35963bd4ed 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -475,8 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep, | |||
475 | unsigned long flags; | 475 | unsigned long flags; |
476 | 476 | ||
477 | if (!_ep || !ep | 477 | if (!_ep || !ep |
478 | || !desc || ep->ep.desc | 478 | || !desc || _ep->name == ep0name |
479 | || _ep->name == ep0name | ||
480 | || desc->bDescriptorType != USB_DT_ENDPOINT | 479 | || desc->bDescriptorType != USB_DT_ENDPOINT |
481 | || (maxpacket = usb_endpoint_maxp(desc)) == 0 | 480 | || (maxpacket = usb_endpoint_maxp(desc)) == 0 |
482 | || maxpacket > ep->maxpacket) { | 481 | || maxpacket > ep->maxpacket) { |
@@ -530,7 +529,6 @@ ok: | |||
530 | tmp |= AT91_UDP_EPEDS; | 529 | tmp |= AT91_UDP_EPEDS; |
531 | __raw_writel(tmp, ep->creg); | 530 | __raw_writel(tmp, ep->creg); |
532 | 531 | ||
533 | ep->ep.desc = desc; | ||
534 | ep->ep.maxpacket = maxpacket; | 532 | ep->ep.maxpacket = maxpacket; |
535 | 533 | ||
536 | /* | 534 | /* |
@@ -1635,7 +1633,6 @@ static int at91_start(struct usb_gadget *gadget, | |||
1635 | udc->driver = driver; | 1633 | udc->driver = driver; |
1636 | udc->gadget.dev.driver = &driver->driver; | 1634 | udc->gadget.dev.driver = &driver->driver; |
1637 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; | 1635 | udc->gadget.dev.of_node = udc->pdev->dev.of_node; |
1638 | dev_set_drvdata(&udc->gadget.dev, &driver->driver); | ||
1639 | udc->enabled = 1; | 1636 | udc->enabled = 1; |
1640 | udc->selfpowered = 1; | 1637 | udc->selfpowered = 1; |
1641 | 1638 | ||
@@ -1656,7 +1653,6 @@ static int at91_stop(struct usb_gadget *gadget, | |||
1656 | spin_unlock_irqrestore(&udc->lock, flags); | 1653 | spin_unlock_irqrestore(&udc->lock, flags); |
1657 | 1654 | ||
1658 | udc->gadget.dev.driver = NULL; | 1655 | udc->gadget.dev.driver = NULL; |
1659 | dev_set_drvdata(&udc->gadget.dev, NULL); | ||
1660 | udc->driver = NULL; | 1656 | udc->driver = NULL; |
1661 | 1657 | ||
1662 | DBG("unbound from %s\n", driver->driver.name); | 1658 | DBG("unbound from %s\n", driver->driver.name); |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index b799106027ad..afdbb1cbf5d9 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -1916,6 +1916,27 @@ done: | |||
1916 | return retval; | 1916 | return retval; |
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | /* usb 3.0 root hub device descriptor */ | ||
1920 | struct { | ||
1921 | struct usb_bos_descriptor bos; | ||
1922 | struct usb_ss_cap_descriptor ss_cap; | ||
1923 | } __packed usb3_bos_desc = { | ||
1924 | |||
1925 | .bos = { | ||
1926 | .bLength = USB_DT_BOS_SIZE, | ||
1927 | .bDescriptorType = USB_DT_BOS, | ||
1928 | .wTotalLength = cpu_to_le16(sizeof(usb3_bos_desc)), | ||
1929 | .bNumDeviceCaps = 1, | ||
1930 | }, | ||
1931 | .ss_cap = { | ||
1932 | .bLength = USB_DT_USB_SS_CAP_SIZE, | ||
1933 | .bDescriptorType = USB_DT_DEVICE_CAPABILITY, | ||
1934 | .bDevCapabilityType = USB_SS_CAP_TYPE, | ||
1935 | .wSpeedSupported = cpu_to_le16(USB_5GBPS_OPERATION), | ||
1936 | .bFunctionalitySupport = ilog2(USB_5GBPS_OPERATION), | ||
1937 | }, | ||
1938 | }; | ||
1939 | |||
1919 | static inline void | 1940 | static inline void |
1920 | ss_hub_descriptor(struct usb_hub_descriptor *desc) | 1941 | ss_hub_descriptor(struct usb_hub_descriptor *desc) |
1921 | { | 1942 | { |
@@ -2006,6 +2027,18 @@ static int dummy_hub_control( | |||
2006 | else | 2027 | else |
2007 | hub_descriptor((struct usb_hub_descriptor *) buf); | 2028 | hub_descriptor((struct usb_hub_descriptor *) buf); |
2008 | break; | 2029 | break; |
2030 | |||
2031 | case DeviceRequest | USB_REQ_GET_DESCRIPTOR: | ||
2032 | if (hcd->speed != HCD_USB3) | ||
2033 | goto error; | ||
2034 | |||
2035 | if ((wValue >> 8) != USB_DT_BOS) | ||
2036 | goto error; | ||
2037 | |||
2038 | memcpy(buf, &usb3_bos_desc, sizeof(usb3_bos_desc)); | ||
2039 | retval = sizeof(usb3_bos_desc); | ||
2040 | break; | ||
2041 | |||
2009 | case GetHubStatus: | 2042 | case GetHubStatus: |
2010 | *(__le32 *) buf = cpu_to_le32(0); | 2043 | *(__le32 *) buf = cpu_to_le32(0); |
2011 | break; | 2044 | break; |
@@ -2503,10 +2536,8 @@ static int dummy_hcd_probe(struct platform_device *pdev) | |||
2503 | hs_hcd->has_tt = 1; | 2536 | hs_hcd->has_tt = 1; |
2504 | 2537 | ||
2505 | retval = usb_add_hcd(hs_hcd, 0, 0); | 2538 | retval = usb_add_hcd(hs_hcd, 0, 0); |
2506 | if (retval != 0) { | 2539 | if (retval) |
2507 | usb_put_hcd(hs_hcd); | 2540 | goto put_usb2_hcd; |
2508 | return retval; | ||
2509 | } | ||
2510 | 2541 | ||
2511 | if (mod_data.is_super_speed) { | 2542 | if (mod_data.is_super_speed) { |
2512 | ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, | 2543 | ss_hcd = usb_create_shared_hcd(&dummy_hcd, &pdev->dev, |
@@ -2525,6 +2556,8 @@ static int dummy_hcd_probe(struct platform_device *pdev) | |||
2525 | put_usb3_hcd: | 2556 | put_usb3_hcd: |
2526 | usb_put_hcd(ss_hcd); | 2557 | usb_put_hcd(ss_hcd); |
2527 | dealloc_usb2_hcd: | 2558 | dealloc_usb2_hcd: |
2559 | usb_remove_hcd(hs_hcd); | ||
2560 | put_usb2_hcd: | ||
2528 | usb_put_hcd(hs_hcd); | 2561 | usb_put_hcd(hs_hcd); |
2529 | the_controller.hs_hcd = the_controller.ss_hcd = NULL; | 2562 | the_controller.hs_hcd = the_controller.ss_hcd = NULL; |
2530 | return retval; | 2563 | return retval; |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 8adc79d1b402..829aba75a6df 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -34,11 +34,15 @@ | |||
34 | /* Debugging ****************************************************************/ | 34 | /* Debugging ****************************************************************/ |
35 | 35 | ||
36 | #ifdef VERBOSE_DEBUG | 36 | #ifdef VERBOSE_DEBUG |
37 | #ifndef pr_vdebug | ||
37 | # define pr_vdebug pr_debug | 38 | # define pr_vdebug pr_debug |
39 | #endif /* pr_vdebug */ | ||
38 | # define ffs_dump_mem(prefix, ptr, len) \ | 40 | # define ffs_dump_mem(prefix, ptr, len) \ |
39 | print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) | 41 | print_hex_dump_bytes(pr_fmt(prefix ": "), DUMP_PREFIX_NONE, ptr, len) |
40 | #else | 42 | #else |
43 | #ifndef pr_vdebug | ||
41 | # define pr_vdebug(...) do { } while (0) | 44 | # define pr_vdebug(...) do { } while (0) |
45 | #endif /* pr_vdebug */ | ||
42 | # define ffs_dump_mem(prefix, ptr, len) do { } while (0) | 46 | # define ffs_dump_mem(prefix, ptr, len) do { } while (0) |
43 | #endif /* VERBOSE_DEBUG */ | 47 | #endif /* VERBOSE_DEBUG */ |
44 | 48 | ||
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index dc5334856afe..a0eb85794fd4 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/usb/ch9.h> | 35 | #include <linux/usb/ch9.h> |
36 | #include <linux/usb/gadget.h> | 36 | #include <linux/usb/gadget.h> |
37 | 37 | ||
38 | #include <mach/usb.h> | 38 | #include <linux/platform_data/usb-imx_udc.h> |
39 | #include <mach/hardware.h> | 39 | #include <mach/hardware.h> |
40 | 40 | ||
41 | #include "imx_udc.h" | 41 | #include "imx_udc.h" |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 644b4305cb99..7a8713cda945 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -2508,7 +2508,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
2508 | IRQF_SHARED, driver_name, udc); | 2508 | IRQF_SHARED, driver_name, udc); |
2509 | if (retval != 0) { | 2509 | if (retval != 0) { |
2510 | dev_err(udc->dev, "%s: can't get irq %i, err %d\n", | 2510 | dev_err(udc->dev, "%s: can't get irq %i, err %d\n", |
2511 | driver_name, IRQ_USB, retval); | 2511 | driver_name, udc->irq, retval); |
2512 | goto err_irq; | 2512 | goto err_irq; |
2513 | } | 2513 | } |
2514 | retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); | 2514 | retval = usb_add_gadget_udc(&pdev->dev, &udc->gadget); |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index b13e0bb5f5b8..0bb617e1dda2 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -3599,6 +3599,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3599 | 3599 | ||
3600 | if (hsotg->num_of_eps == 0) { | 3600 | if (hsotg->num_of_eps == 0) { |
3601 | dev_err(dev, "wrong number of EPs (zero)\n"); | 3601 | dev_err(dev, "wrong number of EPs (zero)\n"); |
3602 | ret = -EINVAL; | ||
3602 | goto err_supplies; | 3603 | goto err_supplies; |
3603 | } | 3604 | } |
3604 | 3605 | ||
@@ -3606,6 +3607,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3606 | GFP_KERNEL); | 3607 | GFP_KERNEL); |
3607 | if (!eps) { | 3608 | if (!eps) { |
3608 | dev_err(dev, "cannot get memory\n"); | 3609 | dev_err(dev, "cannot get memory\n"); |
3610 | ret = -ENOMEM; | ||
3609 | goto err_supplies; | 3611 | goto err_supplies; |
3610 | } | 3612 | } |
3611 | 3613 | ||
@@ -3622,6 +3624,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3622 | GFP_KERNEL); | 3624 | GFP_KERNEL); |
3623 | if (!hsotg->ctrl_req) { | 3625 | if (!hsotg->ctrl_req) { |
3624 | dev_err(dev, "failed to allocate ctrl req\n"); | 3626 | dev_err(dev, "failed to allocate ctrl req\n"); |
3627 | ret = -ENOMEM; | ||
3625 | goto err_ep_mem; | 3628 | goto err_ep_mem; |
3626 | } | 3629 | } |
3627 | 3630 | ||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index f2e51f50e528..f006045fc44c 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <mach/hardware.h> | 43 | #include <mach/hardware.h> |
44 | 44 | ||
45 | #include <plat/regs-udc.h> | 45 | #include <plat/regs-udc.h> |
46 | #include <plat/udc.h> | 46 | #include <linux/platform_data/usb-s3c2410_udc.h> |
47 | 47 | ||
48 | 48 | ||
49 | #include "s3c2410_udc.h" | 49 | #include "s3c2410_udc.h" |
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 5b3f5fffea92..f1739526820f 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -132,11 +132,15 @@ static unsigned n_ports; | |||
132 | 132 | ||
133 | 133 | ||
134 | #ifdef VERBOSE_DEBUG | 134 | #ifdef VERBOSE_DEBUG |
135 | #ifndef pr_vdebug | ||
135 | #define pr_vdebug(fmt, arg...) \ | 136 | #define pr_vdebug(fmt, arg...) \ |
136 | pr_debug(fmt, ##arg) | 137 | pr_debug(fmt, ##arg) |
138 | #endif /* pr_vdebug */ | ||
137 | #else | 139 | #else |
140 | #ifndef pr_vdebig | ||
138 | #define pr_vdebug(fmt, arg...) \ | 141 | #define pr_vdebug(fmt, arg...) \ |
139 | ({ if (0) pr_debug(fmt, ##arg); }) | 142 | ({ if (0) pr_debug(fmt, ##arg); }) |
143 | #endif /* pr_vdebug */ | ||
140 | #endif | 144 | #endif |
141 | 145 | ||
142 | /*-------------------------------------------------------------------------*/ | 146 | /*-------------------------------------------------------------------------*/ |
@@ -1129,7 +1133,8 @@ int gserial_setup(struct usb_gadget *g, unsigned count) | |||
1129 | for (i = 0; i < count; i++) { | 1133 | for (i = 0; i < count; i++) { |
1130 | struct device *tty_dev; | 1134 | struct device *tty_dev; |
1131 | 1135 | ||
1132 | tty_dev = tty_register_device(gs_tty_driver, i, &g->dev); | 1136 | tty_dev = tty_port_register_device(&ports[i].port->port, |
1137 | gs_tty_driver, i, &g->dev); | ||
1133 | if (IS_ERR(tty_dev)) | 1138 | if (IS_ERR(tty_dev)) |
1134 | pr_warning("%s: no classdev for port %d, err %ld\n", | 1139 | pr_warning("%s: no classdev for port %d, err %ld\n", |
1135 | __func__, i, PTR_ERR(tty_dev)); | 1140 | __func__, i, PTR_ERR(tty_dev)); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 075d2eca8108..276add2358a1 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -292,7 +292,7 @@ config USB_OHCI_HCD | |||
292 | depends on USB && USB_ARCH_HAS_OHCI | 292 | depends on USB && USB_ARCH_HAS_OHCI |
293 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 | 293 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 |
294 | select USB_OTG_UTILS if ARCH_OMAP | 294 | select USB_OTG_UTILS if ARCH_OMAP |
295 | select USB_ISP1301 if ARCH_LPC32XX || ARCH_PNX4008 | 295 | select USB_ISP1301 if ARCH_LPC32XX |
296 | ---help--- | 296 | ---help--- |
297 | The Open Host Controller Interface (OHCI) is a standard for accessing | 297 | The Open Host Controller Interface (OHCI) is a standard for accessing |
298 | USB 1.1 host controller hardware. It does more in hardware than Intel's | 298 | USB 1.1 host controller hardware. It does more in hardware than Intel's |
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index 34201372c85f..a6e2ea4ef8fd 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | 26 | ||
27 | #include <mach/hardware.h> | 27 | #include <mach/hardware.h> |
28 | #include <mach/mxc_ehci.h> | 28 | #include <linux/platform_data/usb-ehci-mxc.h> |
29 | 29 | ||
30 | #include <asm/mach-types.h> | 30 | #include <asm/mach-types.h> |
31 | 31 | ||
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c index 8892d3642cef..8e7eca62f169 100644 --- a/drivers/usb/host/ehci-orion.c +++ b/drivers/usb/host/ehci-orion.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/mbus.h> | 14 | #include <linux/mbus.h> |
15 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <plat/ehci-orion.h> | 16 | #include <linux/platform_data/usb-ehci-orion.h> |
17 | 17 | ||
18 | #define rdl(off) __raw_readl(hcd->regs + (off)) | 18 | #define rdl(off) __raw_readl(hcd->regs + (off)) |
19 | #define wrl(off, val) __raw_writel((val), hcd->regs + (off)) | 19 | #define wrl(off, val) __raw_writel((val), hcd->regs + (off)) |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 9bc39ca460c8..4b66374bdc8e 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -128,9 +128,17 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
128 | else { | 128 | else { |
129 | qtd = list_entry (qh->qtd_list.next, | 129 | qtd = list_entry (qh->qtd_list.next, |
130 | struct ehci_qtd, qtd_list); | 130 | struct ehci_qtd, qtd_list); |
131 | /* first qtd may already be partially processed */ | 131 | /* |
132 | if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) | 132 | * first qtd may already be partially processed. |
133 | * If we come here during unlink, the QH overlay region | ||
134 | * might have reference to the just unlinked qtd. The | ||
135 | * qtd is updated in qh_completions(). Update the QH | ||
136 | * overlay here. | ||
137 | */ | ||
138 | if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { | ||
139 | qh->hw->hw_qtd_next = qtd->hw_next; | ||
133 | qtd = NULL; | 140 | qtd = NULL; |
141 | } | ||
134 | } | 142 | } |
135 | 143 | ||
136 | if (qtd) | 144 | if (qtd) |
diff --git a/drivers/usb/host/ehci-s5p.c b/drivers/usb/host/ehci-s5p.c index 9d8f1dd57cb3..dfb14c7a61e2 100644 --- a/drivers/usb/host/ehci-s5p.c +++ b/drivers/usb/host/ehci-s5p.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/of_gpio.h> | 18 | #include <linux/of_gpio.h> |
19 | #include <plat/ehci.h> | 19 | #include <linux/platform_data/usb-ehci-s5p.h> |
20 | #include <plat/usb-phy.h> | 20 | #include <plat/usb-phy.h> |
21 | 21 | ||
22 | #define EHCI_INSNREG00(base) (base + 0x90) | 22 | #define EHCI_INSNREG00(base) (base + 0x90) |
diff --git a/drivers/usb/host/imx21-hcd.h b/drivers/usb/host/imx21-hcd.h index 87b29fd971b4..c005770a73e9 100644 --- a/drivers/usb/host/imx21-hcd.h +++ b/drivers/usb/host/imx21-hcd.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #ifndef __LINUX_IMX21_HCD_H__ | 24 | #ifndef __LINUX_IMX21_HCD_H__ |
25 | #define __LINUX_IMX21_HCD_H__ | 25 | #define __LINUX_IMX21_HCD_H__ |
26 | 26 | ||
27 | #include <mach/mx21-usbhost.h> | 27 | #include <linux/platform_data/usb-mx2.h> |
28 | 28 | ||
29 | #define NUM_ISO_ETDS 2 | 29 | #define NUM_ISO_ETDS 2 |
30 | #define USB_NUM_ETD 32 | 30 | #define USB_NUM_ETD 32 |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index a665b3eaa746..aaa8d2bce217 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -570,6 +570,16 @@ static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev) | |||
570 | 570 | ||
571 | if (pdata) { | 571 | if (pdata) { |
572 | at91_for_each_port(i) { | 572 | at91_for_each_port(i) { |
573 | /* | ||
574 | * do not configure PIO if not in relation with | ||
575 | * real USB port on board | ||
576 | */ | ||
577 | if (i >= pdata->ports) { | ||
578 | pdata->vbus_pin[i] = -EINVAL; | ||
579 | pdata->overcurrent_pin[i] = -EINVAL; | ||
580 | break; | ||
581 | } | ||
582 | |||
573 | if (!gpio_is_valid(pdata->vbus_pin[i])) | 583 | if (!gpio_is_valid(pdata->vbus_pin[i])) |
574 | continue; | 584 | continue; |
575 | gpio = pdata->vbus_pin[i]; | 585 | gpio = pdata->vbus_pin[i]; |
diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c index 269b1e0f7691..0b815a856811 100644 --- a/drivers/usb/host/ohci-da8xx.c +++ b/drivers/usb/host/ohci-da8xx.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | 18 | ||
19 | #include <mach/da8xx.h> | 19 | #include <mach/da8xx.h> |
20 | #include <mach/usb.h> | 20 | #include <linux/platform_data/usb-davinci.h> |
21 | 21 | ||
22 | #ifndef CONFIG_ARCH_DAVINCI_DA8XX | 22 | #ifndef CONFIG_ARCH_DAVINCI_DA8XX |
23 | #error "This file is DA8xx bus glue. Define CONFIG_ARCH_DAVINCI_DA8XX." | 23 | #error "This file is DA8xx bus glue. Define CONFIG_ARCH_DAVINCI_DA8XX." |
diff --git a/drivers/usb/host/ohci-exynos.c b/drivers/usb/host/ohci-exynos.c index fc3091bd2379..20a50081f922 100644 --- a/drivers/usb/host/ohci-exynos.c +++ b/drivers/usb/host/ohci-exynos.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <mach/ohci.h> | 17 | #include <linux/platform_data/usb-exynos.h> |
18 | #include <plat/usb-phy.h> | 18 | #include <plat/usb-phy.h> |
19 | 19 | ||
20 | struct exynos_ohci_hcd { | 20 | struct exynos_ohci_hcd { |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 2b1e8d84c873..6780010e9c3c 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -1049,7 +1049,7 @@ MODULE_LICENSE ("GPL"); | |||
1049 | #define PLATFORM_DRIVER ohci_hcd_at91_driver | 1049 | #define PLATFORM_DRIVER ohci_hcd_at91_driver |
1050 | #endif | 1050 | #endif |
1051 | 1051 | ||
1052 | #if defined(CONFIG_ARCH_PNX4008) || defined(CONFIG_ARCH_LPC32XX) | 1052 | #ifdef CONFIG_ARCH_LPC32XX |
1053 | #include "ohci-nxp.c" | 1053 | #include "ohci-nxp.c" |
1054 | #define PLATFORM_DRIVER usb_hcd_nxp_driver | 1054 | #define PLATFORM_DRIVER usb_hcd_nxp_driver |
1055 | #endif | 1055 | #endif |
diff --git a/drivers/usb/host/ohci-nxp.c b/drivers/usb/host/ohci-nxp.c index a446386bf779..119966603d8d 100644 --- a/drivers/usb/host/ohci-nxp.c +++ b/drivers/usb/host/ohci-nxp.c | |||
@@ -2,7 +2,6 @@ | |||
2 | * driver for NXP USB Host devices | 2 | * driver for NXP USB Host devices |
3 | * | 3 | * |
4 | * Currently supported OHCI host devices: | 4 | * Currently supported OHCI host devices: |
5 | * - Philips PNX4008 | ||
6 | * - NXP LPC32xx | 5 | * - NXP LPC32xx |
7 | * | 6 | * |
8 | * Authors: Dmitry Chigirev <source@mvista.com> | 7 | * Authors: Dmitry Chigirev <source@mvista.com> |
@@ -66,38 +65,6 @@ static struct clk *usb_pll_clk; | |||
66 | static struct clk *usb_dev_clk; | 65 | static struct clk *usb_dev_clk; |
67 | static struct clk *usb_otg_clk; | 66 | static struct clk *usb_otg_clk; |
68 | 67 | ||
69 | static void isp1301_configure_pnx4008(void) | ||
70 | { | ||
71 | /* PNX4008 only supports DAT_SE0 USB mode */ | ||
72 | /* PNX4008 R2A requires setting the MAX603 to output 3.6V */ | ||
73 | /* Power up externel charge-pump */ | ||
74 | |||
75 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
76 | ISP1301_I2C_MODE_CONTROL_1, MC1_DAT_SE0 | MC1_SPEED_REG); | ||
77 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
78 | ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR, | ||
79 | ~(MC1_DAT_SE0 | MC1_SPEED_REG)); | ||
80 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
81 | ISP1301_I2C_MODE_CONTROL_2, | ||
82 | MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL); | ||
83 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
84 | ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR, | ||
85 | ~(MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL)); | ||
86 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
87 | ISP1301_I2C_OTG_CONTROL_1, OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN); | ||
88 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
89 | ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR, | ||
90 | ~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN)); | ||
91 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
92 | ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR, 0xFF); | ||
93 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
94 | ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR, | ||
95 | 0xFF); | ||
96 | i2c_smbus_write_byte_data(isp1301_i2c_client, | ||
97 | ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR, | ||
98 | 0xFF); | ||
99 | } | ||
100 | |||
101 | static void isp1301_configure_lpc32xx(void) | 68 | static void isp1301_configure_lpc32xx(void) |
102 | { | 69 | { |
103 | /* LPC32XX only supports DAT_SE0 USB mode */ | 70 | /* LPC32XX only supports DAT_SE0 USB mode */ |
@@ -149,10 +116,7 @@ static void isp1301_configure_lpc32xx(void) | |||
149 | 116 | ||
150 | static void isp1301_configure(void) | 117 | static void isp1301_configure(void) |
151 | { | 118 | { |
152 | if (machine_is_pnx4008()) | 119 | isp1301_configure_lpc32xx(); |
153 | isp1301_configure_pnx4008(); | ||
154 | else | ||
155 | isp1301_configure_lpc32xx(); | ||
156 | } | 120 | } |
157 | 121 | ||
158 | static inline void isp1301_vbus_on(void) | 122 | static inline void isp1301_vbus_on(void) |
@@ -241,47 +205,6 @@ static const struct hc_driver ohci_nxp_hc_driver = { | |||
241 | .start_port_reset = ohci_start_port_reset, | 205 | .start_port_reset = ohci_start_port_reset, |
242 | }; | 206 | }; |
243 | 207 | ||
244 | static void nxp_set_usb_bits(void) | ||
245 | { | ||
246 | if (machine_is_pnx4008()) { | ||
247 | start_int_set_falling_edge(SE_USB_OTG_ATX_INT_N); | ||
248 | start_int_ack(SE_USB_OTG_ATX_INT_N); | ||
249 | start_int_umask(SE_USB_OTG_ATX_INT_N); | ||
250 | |||
251 | start_int_set_rising_edge(SE_USB_OTG_TIMER_INT); | ||
252 | start_int_ack(SE_USB_OTG_TIMER_INT); | ||
253 | start_int_umask(SE_USB_OTG_TIMER_INT); | ||
254 | |||
255 | start_int_set_rising_edge(SE_USB_I2C_INT); | ||
256 | start_int_ack(SE_USB_I2C_INT); | ||
257 | start_int_umask(SE_USB_I2C_INT); | ||
258 | |||
259 | start_int_set_rising_edge(SE_USB_INT); | ||
260 | start_int_ack(SE_USB_INT); | ||
261 | start_int_umask(SE_USB_INT); | ||
262 | |||
263 | start_int_set_rising_edge(SE_USB_NEED_CLK_INT); | ||
264 | start_int_ack(SE_USB_NEED_CLK_INT); | ||
265 | start_int_umask(SE_USB_NEED_CLK_INT); | ||
266 | |||
267 | start_int_set_rising_edge(SE_USB_AHB_NEED_CLK_INT); | ||
268 | start_int_ack(SE_USB_AHB_NEED_CLK_INT); | ||
269 | start_int_umask(SE_USB_AHB_NEED_CLK_INT); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | static void nxp_unset_usb_bits(void) | ||
274 | { | ||
275 | if (machine_is_pnx4008()) { | ||
276 | start_int_mask(SE_USB_OTG_ATX_INT_N); | ||
277 | start_int_mask(SE_USB_OTG_TIMER_INT); | ||
278 | start_int_mask(SE_USB_I2C_INT); | ||
279 | start_int_mask(SE_USB_INT); | ||
280 | start_int_mask(SE_USB_NEED_CLK_INT); | ||
281 | start_int_mask(SE_USB_AHB_NEED_CLK_INT); | ||
282 | } | ||
283 | } | ||
284 | |||
285 | static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) | 208 | static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) |
286 | { | 209 | { |
287 | struct usb_hcd *hcd = 0; | 210 | struct usb_hcd *hcd = 0; |
@@ -376,9 +299,6 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) | |||
376 | goto out8; | 299 | goto out8; |
377 | } | 300 | } |
378 | 301 | ||
379 | /* Set all USB bits in the Start Enable register */ | ||
380 | nxp_set_usb_bits(); | ||
381 | |||
382 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 302 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
383 | if (!res) { | 303 | if (!res) { |
384 | dev_err(&pdev->dev, "Failed to get MEM resource\n"); | 304 | dev_err(&pdev->dev, "Failed to get MEM resource\n"); |
@@ -413,7 +333,6 @@ static int __devinit usb_hcd_nxp_probe(struct platform_device *pdev) | |||
413 | 333 | ||
414 | nxp_stop_hc(); | 334 | nxp_stop_hc(); |
415 | out8: | 335 | out8: |
416 | nxp_unset_usb_bits(); | ||
417 | usb_put_hcd(hcd); | 336 | usb_put_hcd(hcd); |
418 | out7: | 337 | out7: |
419 | clk_disable(usb_otg_clk); | 338 | clk_disable(usb_otg_clk); |
@@ -441,7 +360,6 @@ static int usb_hcd_nxp_remove(struct platform_device *pdev) | |||
441 | nxp_stop_hc(); | 360 | nxp_stop_hc(); |
442 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 361 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
443 | usb_put_hcd(hcd); | 362 | usb_put_hcd(hcd); |
444 | nxp_unset_usb_bits(); | ||
445 | clk_disable(usb_pll_clk); | 363 | clk_disable(usb_pll_clk); |
446 | clk_put(usb_pll_clk); | 364 | clk_put(usb_pll_clk); |
447 | clk_disable(usb_dev_clk); | 365 | clk_disable(usb_dev_clk); |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index f8b2d91851f7..4531d03503c3 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <asm/io.h> | 24 | #include <asm/io.h> |
25 | #include <asm/mach-types.h> | 25 | #include <asm/mach-types.h> |
26 | 26 | ||
27 | #include <plat/mux.h> | 27 | #include <mach/mux.h> |
28 | #include <plat/fpga.h> | 28 | #include <plat/fpga.h> |
29 | 29 | ||
30 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e1a3cc6d28dc..955c410d59b6 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -24,8 +24,8 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
27 | #include <mach/ohci.h> | 27 | #include <linux/platform_data/usb-ohci-pxa27x.h> |
28 | #include <mach/pxa3xx-u2d.h> | 28 | #include <linux/platform_data/usb-pxa3xx-ulpi.h> |
29 | 29 | ||
30 | /* | 30 | /* |
31 | * UHC: USB Host Controller (OHCI-like) register definitions | 31 | * UHC: USB Host Controller (OHCI-like) register definitions |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 664c869eb096..0d2309ca471e 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
24 | #include <plat/usb-control.h> | 24 | #include <linux/platform_data/usb-ohci-s3c2410.h> |
25 | 25 | ||
26 | #define valid_port(idx) ((idx) == 1 || (idx) == 2) | 26 | #define valid_port(idx) ((idx) == 1 || (idx) == 2) |
27 | 27 | ||
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index c5e9e4a76f14..966d1484ee79 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -75,7 +75,9 @@ | |||
75 | #define NB_PIF0_PWRDOWN_1 0x01100013 | 75 | #define NB_PIF0_PWRDOWN_1 0x01100013 |
76 | 76 | ||
77 | #define USB_INTEL_XUSB2PR 0xD0 | 77 | #define USB_INTEL_XUSB2PR 0xD0 |
78 | #define USB_INTEL_USB2PRM 0xD4 | ||
78 | #define USB_INTEL_USB3_PSSEN 0xD8 | 79 | #define USB_INTEL_USB3_PSSEN 0xD8 |
80 | #define USB_INTEL_USB3PRM 0xDC | ||
79 | 81 | ||
80 | static struct amd_chipset_info { | 82 | static struct amd_chipset_info { |
81 | struct pci_dev *nb_dev; | 83 | struct pci_dev *nb_dev; |
@@ -772,10 +774,18 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
772 | return; | 774 | return; |
773 | } | 775 | } |
774 | 776 | ||
775 | ports_available = 0xffffffff; | 777 | /* Read USB3PRM, the USB 3.0 Port Routing Mask Register |
778 | * Indicate the ports that can be changed from OS. | ||
779 | */ | ||
780 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB3PRM, | ||
781 | &ports_available); | ||
782 | |||
783 | dev_dbg(&xhci_pdev->dev, "Configurable ports to enable SuperSpeed: 0x%x\n", | ||
784 | ports_available); | ||
785 | |||
776 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable | 786 | /* Write USB3_PSSEN, the USB 3.0 Port SuperSpeed Enable |
777 | * Register, to turn on SuperSpeed terminations for all | 787 | * Register, to turn on SuperSpeed terminations for the |
778 | * available ports. | 788 | * switchable ports. |
779 | */ | 789 | */ |
780 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, | 790 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, |
781 | cpu_to_le32(ports_available)); | 791 | cpu_to_le32(ports_available)); |
@@ -785,7 +795,16 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
785 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " | 795 | dev_dbg(&xhci_pdev->dev, "USB 3.0 ports that are now enabled " |
786 | "under xHCI: 0x%x\n", ports_available); | 796 | "under xHCI: 0x%x\n", ports_available); |
787 | 797 | ||
788 | ports_available = 0xffffffff; | 798 | /* Read XUSB2PRM, xHCI USB 2.0 Port Routing Mask Register |
799 | * Indicate the USB 2.0 ports to be controlled by the xHCI host. | ||
800 | */ | ||
801 | |||
802 | pci_read_config_dword(xhci_pdev, USB_INTEL_USB2PRM, | ||
803 | &ports_available); | ||
804 | |||
805 | dev_dbg(&xhci_pdev->dev, "Configurable USB 2.0 ports to hand over to xCHI: 0x%x\n", | ||
806 | ports_available); | ||
807 | |||
789 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to | 808 | /* Write XUSB2PR, the xHC USB 2.0 Port Routing Register, to |
790 | * switch the USB 2.0 power and data lines over to the xHCI | 809 | * switch the USB 2.0 power and data lines over to the xHCI |
791 | * host. | 810 | * host. |
@@ -822,12 +841,12 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
822 | void __iomem *op_reg_base; | 841 | void __iomem *op_reg_base; |
823 | u32 val; | 842 | u32 val; |
824 | int timeout; | 843 | int timeout; |
844 | int len = pci_resource_len(pdev, 0); | ||
825 | 845 | ||
826 | if (!mmio_resource_enabled(pdev, 0)) | 846 | if (!mmio_resource_enabled(pdev, 0)) |
827 | return; | 847 | return; |
828 | 848 | ||
829 | base = ioremap_nocache(pci_resource_start(pdev, 0), | 849 | base = ioremap_nocache(pci_resource_start(pdev, 0), len); |
830 | pci_resource_len(pdev, 0)); | ||
831 | if (base == NULL) | 850 | if (base == NULL) |
832 | return; | 851 | return; |
833 | 852 | ||
@@ -837,9 +856,17 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
837 | */ | 856 | */ |
838 | ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); | 857 | ext_cap_offset = xhci_find_next_cap_offset(base, XHCI_HCC_PARAMS_OFFSET); |
839 | do { | 858 | do { |
859 | if ((ext_cap_offset + sizeof(val)) > len) { | ||
860 | /* We're reading garbage from the controller */ | ||
861 | dev_warn(&pdev->dev, | ||
862 | "xHCI controller failing to respond"); | ||
863 | return; | ||
864 | } | ||
865 | |||
840 | if (!ext_cap_offset) | 866 | if (!ext_cap_offset) |
841 | /* We've reached the end of the extended capabilities */ | 867 | /* We've reached the end of the extended capabilities */ |
842 | goto hc_init; | 868 | goto hc_init; |
869 | |||
843 | val = readl(base + ext_cap_offset); | 870 | val = readl(base + ext_cap_offset); |
844 | if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) | 871 | if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY) |
845 | break; | 872 | break; |
@@ -870,9 +897,10 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
870 | /* Disable any BIOS SMIs and clear all SMI events*/ | 897 | /* Disable any BIOS SMIs and clear all SMI events*/ |
871 | writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); | 898 | writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET); |
872 | 899 | ||
900 | hc_init: | ||
873 | if (usb_is_intel_switchable_xhci(pdev)) | 901 | if (usb_is_intel_switchable_xhci(pdev)) |
874 | usb_enable_xhci_ports(pdev); | 902 | usb_enable_xhci_ports(pdev); |
875 | hc_init: | 903 | |
876 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); | 904 | op_reg_base = base + XHCI_HC_LENGTH(readl(base)); |
877 | 905 | ||
878 | /* Wait for the host controller to be ready before writing any | 906 | /* Wait for the host controller to be ready before writing any |
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index ef004a5de20f..7f69a39163ce 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h | |||
@@ -15,6 +15,7 @@ void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); | |||
15 | static inline void usb_amd_quirk_pll_disable(void) {} | 15 | static inline void usb_amd_quirk_pll_disable(void) {} |
16 | static inline void usb_amd_quirk_pll_enable(void) {} | 16 | static inline void usb_amd_quirk_pll_enable(void) {} |
17 | static inline void usb_amd_dev_put(void) {} | 17 | static inline void usb_amd_dev_put(void) {} |
18 | static inline void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) {} | ||
18 | #endif /* CONFIG_PCI */ | 19 | #endif /* CONFIG_PCI */ |
19 | 20 | ||
20 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ | 21 | #endif /* __LINUX_USB_PCI_QUIRKS_H */ |
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 74bfc868b7ad..d5eb357aa5c4 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c | |||
@@ -493,11 +493,48 @@ static void xhci_hub_report_link_state(u32 *status, u32 status_reg) | |||
493 | * when this bit is set. | 493 | * when this bit is set. |
494 | */ | 494 | */ |
495 | pls |= USB_PORT_STAT_CONNECTION; | 495 | pls |= USB_PORT_STAT_CONNECTION; |
496 | } else { | ||
497 | /* | ||
498 | * If CAS bit isn't set but the Port is already at | ||
499 | * Compliance Mode, fake a connection so the USB core | ||
500 | * notices the Compliance state and resets the port. | ||
501 | * This resolves an issue generated by the SN65LVPE502CP | ||
502 | * in which sometimes the port enters compliance mode | ||
503 | * caused by a delay on the host-device negotiation. | ||
504 | */ | ||
505 | if (pls == USB_SS_PORT_LS_COMP_MOD) | ||
506 | pls |= USB_PORT_STAT_CONNECTION; | ||
496 | } | 507 | } |
508 | |||
497 | /* update status field */ | 509 | /* update status field */ |
498 | *status |= pls; | 510 | *status |= pls; |
499 | } | 511 | } |
500 | 512 | ||
513 | /* | ||
514 | * Function for Compliance Mode Quirk. | ||
515 | * | ||
516 | * This Function verifies if all xhc USB3 ports have entered U0, if so, | ||
517 | * the compliance mode timer is deleted. A port won't enter | ||
518 | * compliance mode if it has previously entered U0. | ||
519 | */ | ||
520 | void xhci_del_comp_mod_timer(struct xhci_hcd *xhci, u32 status, u16 wIndex) | ||
521 | { | ||
522 | u32 all_ports_seen_u0 = ((1 << xhci->num_usb3_ports)-1); | ||
523 | bool port_in_u0 = ((status & PORT_PLS_MASK) == XDEV_U0); | ||
524 | |||
525 | if (!(xhci->quirks & XHCI_COMP_MODE_QUIRK)) | ||
526 | return; | ||
527 | |||
528 | if ((xhci->port_status_u0 != all_ports_seen_u0) && port_in_u0) { | ||
529 | xhci->port_status_u0 |= 1 << wIndex; | ||
530 | if (xhci->port_status_u0 == all_ports_seen_u0) { | ||
531 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
532 | xhci_dbg(xhci, "All USB3 ports have entered U0 already!\n"); | ||
533 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted.\n"); | ||
534 | } | ||
535 | } | ||
536 | } | ||
537 | |||
501 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | 538 | int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, |
502 | u16 wIndex, char *buf, u16 wLength) | 539 | u16 wIndex, char *buf, u16 wLength) |
503 | { | 540 | { |
@@ -651,6 +688,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
651 | /* Update Port Link State for super speed ports*/ | 688 | /* Update Port Link State for super speed ports*/ |
652 | if (hcd->speed == HCD_USB3) { | 689 | if (hcd->speed == HCD_USB3) { |
653 | xhci_hub_report_link_state(&status, temp); | 690 | xhci_hub_report_link_state(&status, temp); |
691 | /* | ||
692 | * Verify if all USB3 Ports Have entered U0 already. | ||
693 | * Delete Compliance Mode Timer if so. | ||
694 | */ | ||
695 | xhci_del_comp_mod_timer(xhci, temp, wIndex); | ||
654 | } | 696 | } |
655 | if (bus_state->port_c_suspend & (1 << wIndex)) | 697 | if (bus_state->port_c_suspend & (1 << wIndex)) |
656 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | 698 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; |
diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index 689bc18b051d..df90fe51b4aa 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c | |||
@@ -118,7 +118,7 @@ static int xhci_plat_probe(struct platform_device *pdev) | |||
118 | goto put_hcd; | 118 | goto put_hcd; |
119 | } | 119 | } |
120 | 120 | ||
121 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 121 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); |
122 | if (!hcd->regs) { | 122 | if (!hcd->regs) { |
123 | dev_dbg(&pdev->dev, "error mapping memory\n"); | 123 | dev_dbg(&pdev->dev, "error mapping memory\n"); |
124 | ret = -EFAULT; | 124 | ret = -EFAULT; |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index c59d5b5b6c7d..6ece0ed288d4 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/moduleparam.h> | 27 | #include <linux/moduleparam.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/dmi.h> | ||
29 | 30 | ||
30 | #include "xhci.h" | 31 | #include "xhci.h" |
31 | 32 | ||
@@ -398,6 +399,95 @@ static void xhci_msix_sync_irqs(struct xhci_hcd *xhci) | |||
398 | 399 | ||
399 | #endif | 400 | #endif |
400 | 401 | ||
402 | static void compliance_mode_recovery(unsigned long arg) | ||
403 | { | ||
404 | struct xhci_hcd *xhci; | ||
405 | struct usb_hcd *hcd; | ||
406 | u32 temp; | ||
407 | int i; | ||
408 | |||
409 | xhci = (struct xhci_hcd *)arg; | ||
410 | |||
411 | for (i = 0; i < xhci->num_usb3_ports; i++) { | ||
412 | temp = xhci_readl(xhci, xhci->usb3_ports[i]); | ||
413 | if ((temp & PORT_PLS_MASK) == USB_SS_PORT_LS_COMP_MOD) { | ||
414 | /* | ||
415 | * Compliance Mode Detected. Letting USB Core | ||
416 | * handle the Warm Reset | ||
417 | */ | ||
418 | xhci_dbg(xhci, "Compliance Mode Detected->Port %d!\n", | ||
419 | i + 1); | ||
420 | xhci_dbg(xhci, "Attempting Recovery routine!\n"); | ||
421 | hcd = xhci->shared_hcd; | ||
422 | |||
423 | if (hcd->state == HC_STATE_SUSPENDED) | ||
424 | usb_hcd_resume_root_hub(hcd); | ||
425 | |||
426 | usb_hcd_poll_rh_status(hcd); | ||
427 | } | ||
428 | } | ||
429 | |||
430 | if (xhci->port_status_u0 != ((1 << xhci->num_usb3_ports)-1)) | ||
431 | mod_timer(&xhci->comp_mode_recovery_timer, | ||
432 | jiffies + msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | * Quirk to work around issue generated by the SN65LVPE502CP USB3.0 re-driver | ||
437 | * that causes ports behind that hardware to enter compliance mode sometimes. | ||
438 | * The quirk creates a timer that polls every 2 seconds the link state of | ||
439 | * each host controller's port and recovers it by issuing a Warm reset | ||
440 | * if Compliance mode is detected, otherwise the port will become "dead" (no | ||
441 | * device connections or disconnections will be detected anymore). Becasue no | ||
442 | * status event is generated when entering compliance mode (per xhci spec), | ||
443 | * this quirk is needed on systems that have the failing hardware installed. | ||
444 | */ | ||
445 | static void compliance_mode_recovery_timer_init(struct xhci_hcd *xhci) | ||
446 | { | ||
447 | xhci->port_status_u0 = 0; | ||
448 | init_timer(&xhci->comp_mode_recovery_timer); | ||
449 | |||
450 | xhci->comp_mode_recovery_timer.data = (unsigned long) xhci; | ||
451 | xhci->comp_mode_recovery_timer.function = compliance_mode_recovery; | ||
452 | xhci->comp_mode_recovery_timer.expires = jiffies + | ||
453 | msecs_to_jiffies(COMP_MODE_RCVRY_MSECS); | ||
454 | |||
455 | set_timer_slack(&xhci->comp_mode_recovery_timer, | ||
456 | msecs_to_jiffies(COMP_MODE_RCVRY_MSECS)); | ||
457 | add_timer(&xhci->comp_mode_recovery_timer); | ||
458 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Initialized.\n"); | ||
459 | } | ||
460 | |||
461 | /* | ||
462 | * This function identifies the systems that have installed the SN65LVPE502CP | ||
463 | * USB3.0 re-driver and that need the Compliance Mode Quirk. | ||
464 | * Systems: | ||
465 | * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820 | ||
466 | */ | ||
467 | static bool compliance_mode_recovery_timer_quirk_check(void) | ||
468 | { | ||
469 | const char *dmi_product_name, *dmi_sys_vendor; | ||
470 | |||
471 | dmi_product_name = dmi_get_system_info(DMI_PRODUCT_NAME); | ||
472 | dmi_sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR); | ||
473 | |||
474 | if (!(strstr(dmi_sys_vendor, "Hewlett-Packard"))) | ||
475 | return false; | ||
476 | |||
477 | if (strstr(dmi_product_name, "Z420") || | ||
478 | strstr(dmi_product_name, "Z620") || | ||
479 | strstr(dmi_product_name, "Z820")) | ||
480 | return true; | ||
481 | |||
482 | return false; | ||
483 | } | ||
484 | |||
485 | static int xhci_all_ports_seen_u0(struct xhci_hcd *xhci) | ||
486 | { | ||
487 | return (xhci->port_status_u0 == ((1 << xhci->num_usb3_ports)-1)); | ||
488 | } | ||
489 | |||
490 | |||
401 | /* | 491 | /* |
402 | * Initialize memory for HCD and xHC (one-time init). | 492 | * Initialize memory for HCD and xHC (one-time init). |
403 | * | 493 | * |
@@ -421,6 +511,12 @@ int xhci_init(struct usb_hcd *hcd) | |||
421 | retval = xhci_mem_init(xhci, GFP_KERNEL); | 511 | retval = xhci_mem_init(xhci, GFP_KERNEL); |
422 | xhci_dbg(xhci, "Finished xhci_init\n"); | 512 | xhci_dbg(xhci, "Finished xhci_init\n"); |
423 | 513 | ||
514 | /* Initializing Compliance Mode Recovery Data If Needed */ | ||
515 | if (compliance_mode_recovery_timer_quirk_check()) { | ||
516 | xhci->quirks |= XHCI_COMP_MODE_QUIRK; | ||
517 | compliance_mode_recovery_timer_init(xhci); | ||
518 | } | ||
519 | |||
424 | return retval; | 520 | return retval; |
425 | } | 521 | } |
426 | 522 | ||
@@ -629,6 +725,11 @@ void xhci_stop(struct usb_hcd *hcd) | |||
629 | del_timer_sync(&xhci->event_ring_timer); | 725 | del_timer_sync(&xhci->event_ring_timer); |
630 | #endif | 726 | #endif |
631 | 727 | ||
728 | /* Deleting Compliance Mode Recovery Timer */ | ||
729 | if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && | ||
730 | (!(xhci_all_ports_seen_u0(xhci)))) | ||
731 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
732 | |||
632 | if (xhci->quirks & XHCI_AMD_PLL_FIX) | 733 | if (xhci->quirks & XHCI_AMD_PLL_FIX) |
633 | usb_amd_dev_put(); | 734 | usb_amd_dev_put(); |
634 | 735 | ||
@@ -659,7 +760,7 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
659 | { | 760 | { |
660 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 761 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
661 | 762 | ||
662 | if (xhci->quirks && XHCI_SPURIOUS_REBOOT) | 763 | if (xhci->quirks & XHCI_SPURIOUS_REBOOT) |
663 | usb_disable_xhci_ports(to_pci_dev(hcd->self.controller)); | 764 | usb_disable_xhci_ports(to_pci_dev(hcd->self.controller)); |
664 | 765 | ||
665 | spin_lock_irq(&xhci->lock); | 766 | spin_lock_irq(&xhci->lock); |
@@ -806,6 +907,16 @@ int xhci_suspend(struct xhci_hcd *xhci) | |||
806 | } | 907 | } |
807 | spin_unlock_irq(&xhci->lock); | 908 | spin_unlock_irq(&xhci->lock); |
808 | 909 | ||
910 | /* | ||
911 | * Deleting Compliance Mode Recovery Timer because the xHCI Host | ||
912 | * is about to be suspended. | ||
913 | */ | ||
914 | if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && | ||
915 | (!(xhci_all_ports_seen_u0(xhci)))) { | ||
916 | del_timer_sync(&xhci->comp_mode_recovery_timer); | ||
917 | xhci_dbg(xhci, "Compliance Mode Recovery Timer Deleted!\n"); | ||
918 | } | ||
919 | |||
809 | /* step 5: remove core well power */ | 920 | /* step 5: remove core well power */ |
810 | /* synchronize irq when using MSI-X */ | 921 | /* synchronize irq when using MSI-X */ |
811 | xhci_msix_sync_irqs(xhci); | 922 | xhci_msix_sync_irqs(xhci); |
@@ -938,6 +1049,16 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) | |||
938 | usb_hcd_resume_root_hub(hcd); | 1049 | usb_hcd_resume_root_hub(hcd); |
939 | usb_hcd_resume_root_hub(xhci->shared_hcd); | 1050 | usb_hcd_resume_root_hub(xhci->shared_hcd); |
940 | } | 1051 | } |
1052 | |||
1053 | /* | ||
1054 | * If system is subject to the Quirk, Compliance Mode Timer needs to | ||
1055 | * be re-initialized Always after a system resume. Ports are subject | ||
1056 | * to suffer the Compliance Mode issue again. It doesn't matter if | ||
1057 | * ports have entered previously to U0 before system's suspension. | ||
1058 | */ | ||
1059 | if (xhci->quirks & XHCI_COMP_MODE_QUIRK) | ||
1060 | compliance_mode_recovery_timer_init(xhci); | ||
1061 | |||
941 | return retval; | 1062 | return retval; |
942 | } | 1063 | } |
943 | #endif /* CONFIG_PM */ | 1064 | #endif /* CONFIG_PM */ |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index c713256297ac..1a05908c6673 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1495,6 +1495,7 @@ struct xhci_hcd { | |||
1495 | #define XHCI_LPM_SUPPORT (1 << 11) | 1495 | #define XHCI_LPM_SUPPORT (1 << 11) |
1496 | #define XHCI_INTEL_HOST (1 << 12) | 1496 | #define XHCI_INTEL_HOST (1 << 12) |
1497 | #define XHCI_SPURIOUS_REBOOT (1 << 13) | 1497 | #define XHCI_SPURIOUS_REBOOT (1 << 13) |
1498 | #define XHCI_COMP_MODE_QUIRK (1 << 14) | ||
1498 | unsigned int num_active_eps; | 1499 | unsigned int num_active_eps; |
1499 | unsigned int limit_active_eps; | 1500 | unsigned int limit_active_eps; |
1500 | /* There are two roothubs to keep track of bus suspend info for */ | 1501 | /* There are two roothubs to keep track of bus suspend info for */ |
@@ -1511,6 +1512,11 @@ struct xhci_hcd { | |||
1511 | unsigned sw_lpm_support:1; | 1512 | unsigned sw_lpm_support:1; |
1512 | /* support xHCI 1.0 spec USB2 hardware LPM */ | 1513 | /* support xHCI 1.0 spec USB2 hardware LPM */ |
1513 | unsigned hw_lpm_support:1; | 1514 | unsigned hw_lpm_support:1; |
1515 | /* Compliance Mode Recovery Data */ | ||
1516 | struct timer_list comp_mode_recovery_timer; | ||
1517 | u32 port_status_u0; | ||
1518 | /* Compliance Mode Timer Triggered every 2 seconds */ | ||
1519 | #define COMP_MODE_RCVRY_MSECS 2000 | ||
1514 | }; | 1520 | }; |
1515 | 1521 | ||
1516 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ | 1522 | /* convert between an HCD pointer and the corresponding EHCI_HCD */ |
diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 0f9fcec4e1d3..15a262754150 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/dma-mapping.h> | 35 | #include <linux/dma-mapping.h> |
36 | 36 | ||
37 | #include <mach/da8xx.h> | 37 | #include <mach/da8xx.h> |
38 | #include <mach/usb.h> | 38 | #include <linux/platform_data/usb-davinci.h> |
39 | 39 | ||
40 | #include "musb_core.h" | 40 | #include "musb_core.h" |
41 | 41 | ||
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 4bb717d0bd41..1ae378d5fc6f 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
@@ -2049,7 +2049,7 @@ static int musb_urb_enqueue( | |||
2049 | * we only have work to do in the former case. | 2049 | * we only have work to do in the former case. |
2050 | */ | 2050 | */ |
2051 | spin_lock_irqsave(&musb->lock, flags); | 2051 | spin_lock_irqsave(&musb->lock, flags); |
2052 | if (hep->hcpriv) { | 2052 | if (hep->hcpriv || !next_urb(qh)) { |
2053 | /* some concurrent activity submitted another urb to hep... | 2053 | /* some concurrent activity submitted another urb to hep... |
2054 | * odd, rare, error prone, but legal. | 2054 | * odd, rare, error prone, but legal. |
2055 | */ | 2055 | */ |
diff --git a/drivers/usb/musb/musbhsdma.c b/drivers/usb/musb/musbhsdma.c index 57a608584e16..c1be687e00ec 100644 --- a/drivers/usb/musb/musbhsdma.c +++ b/drivers/usb/musb/musbhsdma.c | |||
@@ -388,7 +388,7 @@ dma_controller_create(struct musb *musb, void __iomem *base) | |||
388 | struct platform_device *pdev = to_platform_device(dev); | 388 | struct platform_device *pdev = to_platform_device(dev); |
389 | int irq = platform_get_irq_byname(pdev, "dma"); | 389 | int irq = platform_get_irq_byname(pdev, "dma"); |
390 | 390 | ||
391 | if (irq == 0) { | 391 | if (irq <= 0) { |
392 | dev_err(dev, "No DMA interrupt line!\n"); | 392 | dev_err(dev, "No DMA interrupt line!\n"); |
393 | return NULL; | 393 | return NULL; |
394 | } | 394 | } |
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 1a1bd9cf40c5..341625442377 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c | |||
@@ -1215,7 +1215,7 @@ static int __devinit tusb_probe(struct platform_device *pdev) | |||
1215 | ret = platform_device_add(musb); | 1215 | ret = platform_device_add(musb); |
1216 | if (ret) { | 1216 | if (ret) { |
1217 | dev_err(&pdev->dev, "failed to register musb device\n"); | 1217 | dev_err(&pdev->dev, "failed to register musb device\n"); |
1218 | goto err1; | 1218 | goto err2; |
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | return 0; | 1221 | return 0; |
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index b67b4bc596c1..89f0709f8935 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <plat/dma.h> | 19 | #include <plat/dma.h> |
20 | #include <plat/mux.h> | ||
21 | 20 | ||
22 | #include "musb_core.h" | 21 | #include "musb_core.h" |
23 | #include "tusb6010.h" | 22 | #include "tusb6010.h" |
diff --git a/drivers/usb/musb/ux500_dma.c b/drivers/usb/musb/ux500_dma.c index d05c7fbbb703..f82246d2fd16 100644 --- a/drivers/usb/musb/ux500_dma.c +++ b/drivers/usb/musb/ux500_dma.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/dma-mapping.h> | 30 | #include <linux/dma-mapping.h> |
31 | #include <linux/dmaengine.h> | 31 | #include <linux/dmaengine.h> |
32 | #include <linux/pfn.h> | 32 | #include <linux/pfn.h> |
33 | #include <mach/usb.h> | 33 | #include <linux/platform_data/usb-musb-ux500.h> |
34 | #include "musb_core.h" | 34 | #include "musb_core.h" |
35 | 35 | ||
36 | struct ux500_dma_channel { | 36 | struct ux500_dma_channel { |
diff --git a/drivers/usb/otg/isp1301_omap.c b/drivers/usb/otg/isp1301_omap.c index 7a88667742b6..81f1f9a0be8f 100644 --- a/drivers/usb/otg/isp1301_omap.c +++ b/drivers/usb/otg/isp1301_omap.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
37 | #include <asm/mach-types.h> | 37 | #include <asm/mach-types.h> |
38 | 38 | ||
39 | #include <plat/mux.h> | 39 | #include <mach/mux.h> |
40 | 40 | ||
41 | #include <mach/usb.h> | 41 | #include <mach/usb.h> |
42 | 42 | ||
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index ecd173032fd4..143c4e9e1be4 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -818,7 +818,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) | |||
818 | usbhs_pipe_is_dcp(pipe)) | 818 | usbhs_pipe_is_dcp(pipe)) |
819 | goto usbhsf_pio_prepare_push; | 819 | goto usbhsf_pio_prepare_push; |
820 | 820 | ||
821 | if (len % 4) /* 32bit alignment */ | 821 | if (len & 0x7) /* 8byte alignment */ |
822 | goto usbhsf_pio_prepare_push; | 822 | goto usbhsf_pio_prepare_push; |
823 | 823 | ||
824 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ | 824 | if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ |
@@ -905,7 +905,7 @@ static int usbhsf_dma_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
905 | /* use PIO if packet is less than pio_dma_border */ | 905 | /* use PIO if packet is less than pio_dma_border */ |
906 | len = usbhsf_fifo_rcv_len(priv, fifo); | 906 | len = usbhsf_fifo_rcv_len(priv, fifo); |
907 | len = min(pkt->length - pkt->actual, len); | 907 | len = min(pkt->length - pkt->actual, len); |
908 | if (len % 4) /* 32bit alignment */ | 908 | if (len & 0x7) /* 8byte alignment */ |
909 | goto usbhsf_pio_prepare_pop_unselect; | 909 | goto usbhsf_pio_prepare_pop_unselect; |
910 | 910 | ||
911 | if (len < usbhs_get_dparam(priv, pio_dma_border)) | 911 | if (len < usbhs_get_dparam(priv, pio_dma_border)) |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index f8ce97d8b0ad..3b98fb733362 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -215,7 +215,7 @@ static void ark3116_release(struct usb_serial *serial) | |||
215 | 215 | ||
216 | static void ark3116_init_termios(struct tty_struct *tty) | 216 | static void ark3116_init_termios(struct tty_struct *tty) |
217 | { | 217 | { |
218 | struct ktermios *termios = tty->termios; | 218 | struct ktermios *termios = &tty->termios; |
219 | *termios = tty_std_termios; | 219 | *termios = tty_std_termios; |
220 | termios->c_cflag = B9600 | CS8 | 220 | termios->c_cflag = B9600 | CS8 |
221 | | CREAD | HUPCL | CLOCAL; | 221 | | CREAD | HUPCL | CLOCAL; |
@@ -229,7 +229,7 @@ static void ark3116_set_termios(struct tty_struct *tty, | |||
229 | { | 229 | { |
230 | struct usb_serial *serial = port->serial; | 230 | struct usb_serial *serial = port->serial; |
231 | struct ark3116_private *priv = usb_get_serial_port_data(port); | 231 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
232 | struct ktermios *termios = tty->termios; | 232 | struct ktermios *termios = &tty->termios; |
233 | unsigned int cflag = termios->c_cflag; | 233 | unsigned int cflag = termios->c_cflag; |
234 | int bps = tty_get_baud_rate(tty); | 234 | int bps = tty_get_baud_rate(tty); |
235 | int quot; | 235 | int quot; |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 6b7365632951..a46df73ee96e 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -307,7 +307,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty, | |||
307 | unsigned long control_state; | 307 | unsigned long control_state; |
308 | int bad_flow_control; | 308 | int bad_flow_control; |
309 | speed_t baud; | 309 | speed_t baud; |
310 | struct ktermios *termios = tty->termios; | 310 | struct ktermios *termios = &tty->termios; |
311 | 311 | ||
312 | iflag = termios->c_iflag; | 312 | iflag = termios->c_iflag; |
313 | cflag = termios->c_cflag; | 313 | cflag = termios->c_cflag; |
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index b9cca6dcde07..9a564286bfd7 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -165,8 +165,8 @@ static int usb_console_setup(struct console *co, char *options) | |||
165 | } | 165 | } |
166 | 166 | ||
167 | if (serial->type->set_termios) { | 167 | if (serial->type->set_termios) { |
168 | tty->termios->c_cflag = cflag; | 168 | tty->termios.c_cflag = cflag; |
169 | tty_termios_encode_baud_rate(tty->termios, baud, baud); | 169 | tty_termios_encode_baud_rate(&tty->termios, baud, baud); |
170 | memset(&dummy, 0, sizeof(struct ktermios)); | 170 | memset(&dummy, 0, sizeof(struct ktermios)); |
171 | serial->type->set_termios(tty, port, &dummy); | 171 | serial->type->set_termios(tty, port, &dummy); |
172 | 172 | ||
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 1e71079ce33b..ba5e07e188a0 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c | |||
@@ -469,7 +469,7 @@ static void cp210x_get_termios(struct tty_struct *tty, | |||
469 | 469 | ||
470 | if (tty) { | 470 | if (tty) { |
471 | cp210x_get_termios_port(tty->driver_data, | 471 | cp210x_get_termios_port(tty->driver_data, |
472 | &tty->termios->c_cflag, &baud); | 472 | &tty->termios.c_cflag, &baud); |
473 | tty_encode_baud_rate(tty, baud, baud); | 473 | tty_encode_baud_rate(tty, baud, baud); |
474 | } | 474 | } |
475 | 475 | ||
@@ -631,7 +631,7 @@ static void cp210x_change_speed(struct tty_struct *tty, | |||
631 | { | 631 | { |
632 | u32 baud; | 632 | u32 baud; |
633 | 633 | ||
634 | baud = tty->termios->c_ospeed; | 634 | baud = tty->termios.c_ospeed; |
635 | 635 | ||
636 | /* This maps the requested rate to a rate valid on cp2102 or cp2103, | 636 | /* This maps the requested rate to a rate valid on cp2102 or cp2103, |
637 | * or to an arbitrary rate in [1M,2M]. | 637 | * or to an arbitrary rate in [1M,2M]. |
@@ -665,10 +665,10 @@ static void cp210x_set_termios(struct tty_struct *tty, | |||
665 | if (!tty) | 665 | if (!tty) |
666 | return; | 666 | return; |
667 | 667 | ||
668 | cflag = tty->termios->c_cflag; | 668 | cflag = tty->termios.c_cflag; |
669 | old_cflag = old_termios->c_cflag; | 669 | old_cflag = old_termios->c_cflag; |
670 | 670 | ||
671 | if (tty->termios->c_ospeed != old_termios->c_ospeed) | 671 | if (tty->termios.c_ospeed != old_termios->c_ospeed) |
672 | cp210x_change_speed(tty, port, old_termios); | 672 | cp210x_change_speed(tty, port, old_termios); |
673 | 673 | ||
674 | /* If the number of data bits is to be updated */ | 674 | /* If the number of data bits is to be updated */ |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index b78c34eb5d3f..be34f153e566 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -922,38 +922,38 @@ static void cypress_set_termios(struct tty_struct *tty, | |||
922 | early enough */ | 922 | early enough */ |
923 | if (!priv->termios_initialized) { | 923 | if (!priv->termios_initialized) { |
924 | if (priv->chiptype == CT_EARTHMATE) { | 924 | if (priv->chiptype == CT_EARTHMATE) { |
925 | *(tty->termios) = tty_std_termios; | 925 | tty->termios = tty_std_termios; |
926 | tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL | | 926 | tty->termios.c_cflag = B4800 | CS8 | CREAD | HUPCL | |
927 | CLOCAL; | 927 | CLOCAL; |
928 | tty->termios->c_ispeed = 4800; | 928 | tty->termios.c_ispeed = 4800; |
929 | tty->termios->c_ospeed = 4800; | 929 | tty->termios.c_ospeed = 4800; |
930 | } else if (priv->chiptype == CT_CYPHIDCOM) { | 930 | } else if (priv->chiptype == CT_CYPHIDCOM) { |
931 | *(tty->termios) = tty_std_termios; | 931 | tty->termios = tty_std_termios; |
932 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | | 932 | tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | |
933 | CLOCAL; | 933 | CLOCAL; |
934 | tty->termios->c_ispeed = 9600; | 934 | tty->termios.c_ispeed = 9600; |
935 | tty->termios->c_ospeed = 9600; | 935 | tty->termios.c_ospeed = 9600; |
936 | } else if (priv->chiptype == CT_CA42V2) { | 936 | } else if (priv->chiptype == CT_CA42V2) { |
937 | *(tty->termios) = tty_std_termios; | 937 | tty->termios = tty_std_termios; |
938 | tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL | | 938 | tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | |
939 | CLOCAL; | 939 | CLOCAL; |
940 | tty->termios->c_ispeed = 9600; | 940 | tty->termios.c_ispeed = 9600; |
941 | tty->termios->c_ospeed = 9600; | 941 | tty->termios.c_ospeed = 9600; |
942 | } | 942 | } |
943 | priv->termios_initialized = 1; | 943 | priv->termios_initialized = 1; |
944 | } | 944 | } |
945 | spin_unlock_irqrestore(&priv->lock, flags); | 945 | spin_unlock_irqrestore(&priv->lock, flags); |
946 | 946 | ||
947 | /* Unsupported features need clearing */ | 947 | /* Unsupported features need clearing */ |
948 | tty->termios->c_cflag &= ~(CMSPAR|CRTSCTS); | 948 | tty->termios.c_cflag &= ~(CMSPAR|CRTSCTS); |
949 | 949 | ||
950 | cflag = tty->termios->c_cflag; | 950 | cflag = tty->termios.c_cflag; |
951 | iflag = tty->termios->c_iflag; | 951 | iflag = tty->termios.c_iflag; |
952 | 952 | ||
953 | /* check if there are new settings */ | 953 | /* check if there are new settings */ |
954 | if (old_termios) { | 954 | if (old_termios) { |
955 | spin_lock_irqsave(&priv->lock, flags); | 955 | spin_lock_irqsave(&priv->lock, flags); |
956 | priv->tmp_termios = *(tty->termios); | 956 | priv->tmp_termios = tty->termios; |
957 | spin_unlock_irqrestore(&priv->lock, flags); | 957 | spin_unlock_irqrestore(&priv->lock, flags); |
958 | } | 958 | } |
959 | 959 | ||
@@ -1021,7 +1021,7 @@ static void cypress_set_termios(struct tty_struct *tty, | |||
1021 | "4800bps."); | 1021 | "4800bps."); |
1022 | /* define custom termios settings for NMEA protocol */ | 1022 | /* define custom termios settings for NMEA protocol */ |
1023 | 1023 | ||
1024 | tty->termios->c_iflag /* input modes - */ | 1024 | tty->termios.c_iflag /* input modes - */ |
1025 | &= ~(IGNBRK /* disable ignore break */ | 1025 | &= ~(IGNBRK /* disable ignore break */ |
1026 | | BRKINT /* disable break causes interrupt */ | 1026 | | BRKINT /* disable break causes interrupt */ |
1027 | | PARMRK /* disable mark parity errors */ | 1027 | | PARMRK /* disable mark parity errors */ |
@@ -1031,10 +1031,10 @@ static void cypress_set_termios(struct tty_struct *tty, | |||
1031 | | ICRNL /* disable translate CR to NL */ | 1031 | | ICRNL /* disable translate CR to NL */ |
1032 | | IXON); /* disable enable XON/XOFF flow control */ | 1032 | | IXON); /* disable enable XON/XOFF flow control */ |
1033 | 1033 | ||
1034 | tty->termios->c_oflag /* output modes */ | 1034 | tty->termios.c_oflag /* output modes */ |
1035 | &= ~OPOST; /* disable postprocess output char */ | 1035 | &= ~OPOST; /* disable postprocess output char */ |
1036 | 1036 | ||
1037 | tty->termios->c_lflag /* line discipline modes */ | 1037 | tty->termios.c_lflag /* line discipline modes */ |
1038 | &= ~(ECHO /* disable echo input characters */ | 1038 | &= ~(ECHO /* disable echo input characters */ |
1039 | | ECHONL /* disable echo new line */ | 1039 | | ECHONL /* disable echo new line */ |
1040 | | ICANON /* disable erase, kill, werase, and rprnt | 1040 | | ICANON /* disable erase, kill, werase, and rprnt |
@@ -1200,7 +1200,7 @@ static void cypress_read_int_callback(struct urb *urb) | |||
1200 | 1200 | ||
1201 | /* hangup, as defined in acm.c... this might be a bad place for it | 1201 | /* hangup, as defined in acm.c... this might be a bad place for it |
1202 | * though */ | 1202 | * though */ |
1203 | if (tty && !(tty->termios->c_cflag & CLOCAL) && | 1203 | if (tty && !(tty->termios.c_cflag & CLOCAL) && |
1204 | !(priv->current_status & UART_CD)) { | 1204 | !(priv->current_status & UART_CD)) { |
1205 | dbg("%s - calling hangup", __func__); | 1205 | dbg("%s - calling hangup", __func__); |
1206 | tty_hangup(tty); | 1206 | tty_hangup(tty); |
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index b5cd838093ef..afd9d2ec577b 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -687,8 +687,8 @@ static void digi_set_termios(struct tty_struct *tty, | |||
687 | struct usb_serial_port *port, struct ktermios *old_termios) | 687 | struct usb_serial_port *port, struct ktermios *old_termios) |
688 | { | 688 | { |
689 | struct digi_port *priv = usb_get_serial_port_data(port); | 689 | struct digi_port *priv = usb_get_serial_port_data(port); |
690 | unsigned int iflag = tty->termios->c_iflag; | 690 | unsigned int iflag = tty->termios.c_iflag; |
691 | unsigned int cflag = tty->termios->c_cflag; | 691 | unsigned int cflag = tty->termios.c_cflag; |
692 | unsigned int old_iflag = old_termios->c_iflag; | 692 | unsigned int old_iflag = old_termios->c_iflag; |
693 | unsigned int old_cflag = old_termios->c_cflag; | 693 | unsigned int old_cflag = old_termios->c_cflag; |
694 | unsigned char buf[32]; | 694 | unsigned char buf[32]; |
@@ -709,7 +709,7 @@ static void digi_set_termios(struct tty_struct *tty, | |||
709 | /* don't set RTS if using hardware flow control */ | 709 | /* don't set RTS if using hardware flow control */ |
710 | /* and throttling input */ | 710 | /* and throttling input */ |
711 | modem_signals = TIOCM_DTR; | 711 | modem_signals = TIOCM_DTR; |
712 | if (!(tty->termios->c_cflag & CRTSCTS) || | 712 | if (!(tty->termios.c_cflag & CRTSCTS) || |
713 | !test_bit(TTY_THROTTLED, &tty->flags)) | 713 | !test_bit(TTY_THROTTLED, &tty->flags)) |
714 | modem_signals |= TIOCM_RTS; | 714 | modem_signals |= TIOCM_RTS; |
715 | digi_set_modem_signals(port, modem_signals, 1); | 715 | digi_set_modem_signals(port, modem_signals, 1); |
@@ -748,7 +748,7 @@ static void digi_set_termios(struct tty_struct *tty, | |||
748 | } | 748 | } |
749 | } | 749 | } |
750 | /* set parity */ | 750 | /* set parity */ |
751 | tty->termios->c_cflag &= ~CMSPAR; | 751 | tty->termios.c_cflag &= ~CMSPAR; |
752 | 752 | ||
753 | if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { | 753 | if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { |
754 | if (cflag&PARENB) { | 754 | if (cflag&PARENB) { |
@@ -1124,8 +1124,8 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1124 | 1124 | ||
1125 | /* set termios settings */ | 1125 | /* set termios settings */ |
1126 | if (tty) { | 1126 | if (tty) { |
1127 | not_termios.c_cflag = ~tty->termios->c_cflag; | 1127 | not_termios.c_cflag = ~tty->termios.c_cflag; |
1128 | not_termios.c_iflag = ~tty->termios->c_iflag; | 1128 | not_termios.c_iflag = ~tty->termios.c_iflag; |
1129 | digi_set_termios(tty, port, ¬_termios); | 1129 | digi_set_termios(tty, port, ¬_termios); |
1130 | } | 1130 | } |
1131 | return 0; | 1131 | return 0; |
@@ -1500,7 +1500,7 @@ static int digi_read_oob_callback(struct urb *urb) | |||
1500 | 1500 | ||
1501 | rts = 0; | 1501 | rts = 0; |
1502 | if (tty) | 1502 | if (tty) |
1503 | rts = tty->termios->c_cflag & CRTSCTS; | 1503 | rts = tty->termios.c_cflag & CRTSCTS; |
1504 | 1504 | ||
1505 | if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { | 1505 | if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) { |
1506 | spin_lock(&priv->dp_port_lock); | 1506 | spin_lock(&priv->dp_port_lock); |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index cdf61dd07318..34e86383090a 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -87,7 +87,7 @@ static int empeg_startup(struct usb_serial *serial) | |||
87 | 87 | ||
88 | static void empeg_init_termios(struct tty_struct *tty) | 88 | static void empeg_init_termios(struct tty_struct *tty) |
89 | { | 89 | { |
90 | struct ktermios *termios = tty->termios; | 90 | struct ktermios *termios = &tty->termios; |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * The empeg-car player wants these particular tty settings. | 93 | * The empeg-car player wants these particular tty settings. |
diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 499b15fd82f1..79451ee12ca0 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c | |||
@@ -173,10 +173,11 @@ static void f81232_set_termios(struct tty_struct *tty, | |||
173 | /* FIXME - Stubbed out for now */ | 173 | /* FIXME - Stubbed out for now */ |
174 | 174 | ||
175 | /* Don't change anything if nothing has changed */ | 175 | /* Don't change anything if nothing has changed */ |
176 | if (!tty_termios_hw_change(tty->termios, old_termios)) | 176 | if (!tty_termios_hw_change(&tty->termios, old_termios)) |
177 | return; | 177 | return; |
178 | 178 | ||
179 | /* Do the real work here... */ | 179 | /* Do the real work here... */ |
180 | tty_termios_copy_hw(&tty->termios, old_termios); | ||
180 | } | 181 | } |
181 | 182 | ||
182 | static int f81232_tiocmget(struct tty_struct *tty) | 183 | static int f81232_tiocmget(struct tty_struct *tty) |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 5620db6469e5..0c8d1c226273 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -704,6 +704,7 @@ static struct usb_device_id id_table_combined [] = { | |||
704 | { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, | 704 | { USB_DEVICE(FTDI_VID, FTDI_PCDJ_DAC2_PID) }, |
705 | { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, | 705 | { USB_DEVICE(FTDI_VID, FTDI_RRCIRKITS_LOCOBUFFER_PID) }, |
706 | { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, | 706 | { USB_DEVICE(FTDI_VID, FTDI_ASK_RDR400_PID) }, |
707 | { USB_DEVICE(FTDI_VID, FTDI_NZR_SEM_USB_PID) }, | ||
707 | { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, | 708 | { USB_DEVICE(ICOM_VID, ICOM_ID_1_PID) }, |
708 | { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, | 709 | { USB_DEVICE(ICOM_VID, ICOM_OPC_U_UC_PID) }, |
709 | { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, | 710 | { USB_DEVICE(ICOM_VID, ICOM_ID_RP2C1_PID) }, |
@@ -804,13 +805,32 @@ static struct usb_device_id id_table_combined [] = { | |||
804 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 805 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
805 | { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), | 806 | { USB_DEVICE(ADI_VID, ADI_GNICEPLUS_PID), |
806 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 807 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
807 | { USB_DEVICE(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID) }, | 808 | { USB_DEVICE_AND_INTERFACE_INFO(MICROCHIP_VID, MICROCHIP_USB_BOARD_PID, |
809 | USB_CLASS_VENDOR_SPEC, | ||
810 | USB_SUBCLASS_VENDOR_SPEC, 0x00) }, | ||
808 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, | 811 | { USB_DEVICE(JETI_VID, JETI_SPC1201_PID) }, |
809 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), | 812 | { USB_DEVICE(MARVELL_VID, MARVELL_SHEEVAPLUG_PID), |
810 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 813 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
811 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | 814 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, |
812 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, | 815 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, |
816 | { USB_DEVICE(FTDI_VID, PI_C865_PID) }, | ||
817 | { USB_DEVICE(FTDI_VID, PI_C857_PID) }, | ||
818 | { USB_DEVICE(PI_VID, PI_C866_PID) }, | ||
819 | { USB_DEVICE(PI_VID, PI_C663_PID) }, | ||
820 | { USB_DEVICE(PI_VID, PI_C725_PID) }, | ||
821 | { USB_DEVICE(PI_VID, PI_E517_PID) }, | ||
822 | { USB_DEVICE(PI_VID, PI_C863_PID) }, | ||
813 | { USB_DEVICE(PI_VID, PI_E861_PID) }, | 823 | { USB_DEVICE(PI_VID, PI_E861_PID) }, |
824 | { USB_DEVICE(PI_VID, PI_C867_PID) }, | ||
825 | { USB_DEVICE(PI_VID, PI_E609_PID) }, | ||
826 | { USB_DEVICE(PI_VID, PI_E709_PID) }, | ||
827 | { USB_DEVICE(PI_VID, PI_100F_PID) }, | ||
828 | { USB_DEVICE(PI_VID, PI_1011_PID) }, | ||
829 | { USB_DEVICE(PI_VID, PI_1012_PID) }, | ||
830 | { USB_DEVICE(PI_VID, PI_1013_PID) }, | ||
831 | { USB_DEVICE(PI_VID, PI_1014_PID) }, | ||
832 | { USB_DEVICE(PI_VID, PI_1015_PID) }, | ||
833 | { USB_DEVICE(PI_VID, PI_1016_PID) }, | ||
814 | { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, | 834 | { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, |
815 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, | 835 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, |
816 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | 836 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), |
@@ -2082,7 +2102,7 @@ static void ftdi_set_termios(struct tty_struct *tty, | |||
2082 | { | 2102 | { |
2083 | struct usb_device *dev = port->serial->dev; | 2103 | struct usb_device *dev = port->serial->dev; |
2084 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 2104 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2085 | struct ktermios *termios = tty->termios; | 2105 | struct ktermios *termios = &tty->termios; |
2086 | unsigned int cflag = termios->c_cflag; | 2106 | unsigned int cflag = termios->c_cflag; |
2087 | __u16 urb_value; /* will hold the new flags */ | 2107 | __u16 urb_value; /* will hold the new flags */ |
2088 | 2108 | ||
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5dd96ca6c380..41fe5826100c 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -75,6 +75,9 @@ | |||
75 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB | 75 | #define FTDI_OPENDCC_GATEWAY_PID 0xBFDB |
76 | #define FTDI_OPENDCC_GBM_PID 0xBFDC | 76 | #define FTDI_OPENDCC_GBM_PID 0xBFDC |
77 | 77 | ||
78 | /* NZR SEM 16+ USB (http://www.nzr.de) */ | ||
79 | #define FTDI_NZR_SEM_USB_PID 0xC1E0 /* NZR SEM-LOG16+ */ | ||
80 | |||
78 | /* | 81 | /* |
79 | * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) | 82 | * RR-CirKits LocoBuffer USB (http://www.rr-cirkits.com) |
80 | */ | 83 | */ |
@@ -539,7 +542,10 @@ | |||
539 | /* | 542 | /* |
540 | * Microchip Technology, Inc. | 543 | * Microchip Technology, Inc. |
541 | * | 544 | * |
542 | * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are also used by: | 545 | * MICROCHIP_VID (0x04D8) and MICROCHIP_USB_BOARD_PID (0x000A) are |
546 | * used by single function CDC ACM class based firmware demo | ||
547 | * applications. The VID/PID has also been used in firmware | ||
548 | * emulating FTDI serial chips by: | ||
543 | * Hornby Elite - Digital Command Control Console | 549 | * Hornby Elite - Digital Command Control Console |
544 | * http://www.hornby.com/hornby-dcc/controllers/ | 550 | * http://www.hornby.com/hornby-dcc/controllers/ |
545 | */ | 551 | */ |
@@ -791,8 +797,27 @@ | |||
791 | * Physik Instrumente | 797 | * Physik Instrumente |
792 | * http://www.physikinstrumente.com/en/products/ | 798 | * http://www.physikinstrumente.com/en/products/ |
793 | */ | 799 | */ |
800 | /* These two devices use the VID of FTDI */ | ||
801 | #define PI_C865_PID 0xe0a0 /* PI C-865 Piezomotor Controller */ | ||
802 | #define PI_C857_PID 0xe0a1 /* PI Encoder Trigger Box */ | ||
803 | |||
794 | #define PI_VID 0x1a72 /* Vendor ID */ | 804 | #define PI_VID 0x1a72 /* Vendor ID */ |
795 | #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ | 805 | #define PI_C866_PID 0x1000 /* PI C-866 Piezomotor Controller */ |
806 | #define PI_C663_PID 0x1001 /* PI C-663 Mercury-Step */ | ||
807 | #define PI_C725_PID 0x1002 /* PI C-725 Piezomotor Controller */ | ||
808 | #define PI_E517_PID 0x1005 /* PI E-517 Digital Piezo Controller Operation Module */ | ||
809 | #define PI_C863_PID 0x1007 /* PI C-863 */ | ||
810 | #define PI_E861_PID 0x1008 /* PI E-861 Piezomotor Controller */ | ||
811 | #define PI_C867_PID 0x1009 /* PI C-867 Piezomotor Controller */ | ||
812 | #define PI_E609_PID 0x100D /* PI E-609 Digital Piezo Controller */ | ||
813 | #define PI_E709_PID 0x100E /* PI E-709 Digital Piezo Controller */ | ||
814 | #define PI_100F_PID 0x100F /* PI Digital Piezo Controller */ | ||
815 | #define PI_1011_PID 0x1011 /* PI Digital Piezo Controller */ | ||
816 | #define PI_1012_PID 0x1012 /* PI Motion Controller */ | ||
817 | #define PI_1013_PID 0x1013 /* PI Motion Controller */ | ||
818 | #define PI_1014_PID 0x1014 /* PI Device */ | ||
819 | #define PI_1015_PID 0x1015 /* PI Device */ | ||
820 | #define PI_1016_PID 0x1016 /* PI Digital Servo Module */ | ||
796 | 821 | ||
797 | /* | 822 | /* |
798 | * Kondo Kagaku Co.Ltd. | 823 | * Kondo Kagaku Co.Ltd. |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index e1f5ccd1e8f8..f435575c4e6e 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -1458,7 +1458,7 @@ static void edge_throttle(struct tty_struct *tty) | |||
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | /* if we are implementing RTS/CTS, toggle that line */ | 1460 | /* if we are implementing RTS/CTS, toggle that line */ |
1461 | if (tty->termios->c_cflag & CRTSCTS) { | 1461 | if (tty->termios.c_cflag & CRTSCTS) { |
1462 | edge_port->shadowMCR &= ~MCR_RTS; | 1462 | edge_port->shadowMCR &= ~MCR_RTS; |
1463 | status = send_cmd_write_uart_register(edge_port, MCR, | 1463 | status = send_cmd_write_uart_register(edge_port, MCR, |
1464 | edge_port->shadowMCR); | 1464 | edge_port->shadowMCR); |
@@ -1497,7 +1497,7 @@ static void edge_unthrottle(struct tty_struct *tty) | |||
1497 | return; | 1497 | return; |
1498 | } | 1498 | } |
1499 | /* if we are implementing RTS/CTS, toggle that line */ | 1499 | /* if we are implementing RTS/CTS, toggle that line */ |
1500 | if (tty->termios->c_cflag & CRTSCTS) { | 1500 | if (tty->termios.c_cflag & CRTSCTS) { |
1501 | edge_port->shadowMCR |= MCR_RTS; | 1501 | edge_port->shadowMCR |= MCR_RTS; |
1502 | send_cmd_write_uart_register(edge_port, MCR, | 1502 | send_cmd_write_uart_register(edge_port, MCR, |
1503 | edge_port->shadowMCR); | 1503 | edge_port->shadowMCR); |
@@ -1516,9 +1516,9 @@ static void edge_set_termios(struct tty_struct *tty, | |||
1516 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 1516 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
1517 | unsigned int cflag; | 1517 | unsigned int cflag; |
1518 | 1518 | ||
1519 | cflag = tty->termios->c_cflag; | 1519 | cflag = tty->termios.c_cflag; |
1520 | dbg("%s - clfag %08x iflag %08x", __func__, | 1520 | dbg("%s - clfag %08x iflag %08x", __func__, |
1521 | tty->termios->c_cflag, tty->termios->c_iflag); | 1521 | tty->termios.c_cflag, tty->termios.c_iflag); |
1522 | dbg("%s - old clfag %08x old iflag %08x", __func__, | 1522 | dbg("%s - old clfag %08x old iflag %08x", __func__, |
1523 | old_termios->c_cflag, old_termios->c_iflag); | 1523 | old_termios->c_cflag, old_termios->c_iflag); |
1524 | 1524 | ||
@@ -1987,7 +1987,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial, | |||
1987 | tty = tty_port_tty_get(&edge_port->port->port); | 1987 | tty = tty_port_tty_get(&edge_port->port->port); |
1988 | if (tty) { | 1988 | if (tty) { |
1989 | change_port_settings(tty, | 1989 | change_port_settings(tty, |
1990 | edge_port, tty->termios); | 1990 | edge_port, &tty->termios); |
1991 | tty_kref_put(tty); | 1991 | tty_kref_put(tty); |
1992 | } | 1992 | } |
1993 | 1993 | ||
@@ -2570,7 +2570,7 @@ static void change_port_settings(struct tty_struct *tty, | |||
2570 | return; | 2570 | return; |
2571 | } | 2571 | } |
2572 | 2572 | ||
2573 | cflag = tty->termios->c_cflag; | 2573 | cflag = tty->termios.c_cflag; |
2574 | 2574 | ||
2575 | switch (cflag & CSIZE) { | 2575 | switch (cflag & CSIZE) { |
2576 | case CS5: | 2576 | case CS5: |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 3936904c6419..765978ae752e 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -1870,7 +1870,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1870 | 1870 | ||
1871 | /* set up the port settings */ | 1871 | /* set up the port settings */ |
1872 | if (tty) | 1872 | if (tty) |
1873 | edge_set_termios(tty, port, tty->termios); | 1873 | edge_set_termios(tty, port, &tty->termios); |
1874 | 1874 | ||
1875 | /* open up the port */ | 1875 | /* open up the port */ |
1876 | 1876 | ||
@@ -2272,13 +2272,13 @@ static void change_port_settings(struct tty_struct *tty, | |||
2272 | 2272 | ||
2273 | config = kmalloc (sizeof (*config), GFP_KERNEL); | 2273 | config = kmalloc (sizeof (*config), GFP_KERNEL); |
2274 | if (!config) { | 2274 | if (!config) { |
2275 | *tty->termios = *old_termios; | 2275 | tty->termios = *old_termios; |
2276 | dev_err(&edge_port->port->dev, "%s - out of memory\n", | 2276 | dev_err(&edge_port->port->dev, "%s - out of memory\n", |
2277 | __func__); | 2277 | __func__); |
2278 | return; | 2278 | return; |
2279 | } | 2279 | } |
2280 | 2280 | ||
2281 | cflag = tty->termios->c_cflag; | 2281 | cflag = tty->termios.c_cflag; |
2282 | 2282 | ||
2283 | config->wFlags = 0; | 2283 | config->wFlags = 0; |
2284 | 2284 | ||
@@ -2362,7 +2362,7 @@ static void change_port_settings(struct tty_struct *tty, | |||
2362 | } else | 2362 | } else |
2363 | dbg("%s - OUTBOUND XON/XOFF is disabled", __func__); | 2363 | dbg("%s - OUTBOUND XON/XOFF is disabled", __func__); |
2364 | 2364 | ||
2365 | tty->termios->c_cflag &= ~CMSPAR; | 2365 | tty->termios.c_cflag &= ~CMSPAR; |
2366 | 2366 | ||
2367 | /* Round the baud rate */ | 2367 | /* Round the baud rate */ |
2368 | baud = tty_get_baud_rate(tty); | 2368 | baud = tty_get_baud_rate(tty); |
@@ -2408,10 +2408,10 @@ static void edge_set_termios(struct tty_struct *tty, | |||
2408 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 2408 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
2409 | unsigned int cflag; | 2409 | unsigned int cflag; |
2410 | 2410 | ||
2411 | cflag = tty->termios->c_cflag; | 2411 | cflag = tty->termios.c_cflag; |
2412 | 2412 | ||
2413 | dbg("%s - clfag %08x iflag %08x", __func__, | 2413 | dbg("%s - clfag %08x iflag %08x", __func__, |
2414 | tty->termios->c_cflag, tty->termios->c_iflag); | 2414 | tty->termios.c_cflag, tty->termios.c_iflag); |
2415 | dbg("%s - old clfag %08x old iflag %08x", __func__, | 2415 | dbg("%s - old clfag %08x old iflag %08x", __func__, |
2416 | old_termios->c_cflag, old_termios->c_iflag); | 2416 | old_termios->c_cflag, old_termios->c_iflag); |
2417 | dbg("%s - port %d", __func__, port->number); | 2417 | dbg("%s - port %d", __func__, port->number); |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index fc09414c960f..5a96692b12a2 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -381,7 +381,7 @@ static void ir_set_termios(struct tty_struct *tty, | |||
381 | ir_xbof = ir_xbof_change(xbof) ; | 381 | ir_xbof = ir_xbof_change(xbof) ; |
382 | 382 | ||
383 | /* Only speed changes are supported */ | 383 | /* Only speed changes are supported */ |
384 | tty_termios_copy_hw(tty->termios, old_termios); | 384 | tty_termios_copy_hw(&tty->termios, old_termios); |
385 | tty_encode_baud_rate(tty, baud, baud); | 385 | tty_encode_baud_rate(tty, baud, baud); |
386 | 386 | ||
387 | /* | 387 | /* |
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 22b1eb5040b7..bf3864045c18 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c | |||
@@ -921,7 +921,7 @@ static void iuu_set_termios(struct tty_struct *tty, | |||
921 | { | 921 | { |
922 | const u32 supported_mask = CMSPAR|PARENB|PARODD; | 922 | const u32 supported_mask = CMSPAR|PARENB|PARODD; |
923 | struct iuu_private *priv = usb_get_serial_port_data(port); | 923 | struct iuu_private *priv = usb_get_serial_port_data(port); |
924 | unsigned int cflag = tty->termios->c_cflag; | 924 | unsigned int cflag = tty->termios.c_cflag; |
925 | int status; | 925 | int status; |
926 | u32 actual; | 926 | u32 actual; |
927 | u32 parity; | 927 | u32 parity; |
@@ -930,7 +930,7 @@ static void iuu_set_termios(struct tty_struct *tty, | |||
930 | u32 newval = cflag & supported_mask; | 930 | u32 newval = cflag & supported_mask; |
931 | 931 | ||
932 | /* Just use the ospeed. ispeed should be the same. */ | 932 | /* Just use the ospeed. ispeed should be the same. */ |
933 | baud = tty->termios->c_ospeed; | 933 | baud = tty->termios.c_ospeed; |
934 | 934 | ||
935 | dbg("%s - enter c_ospeed or baud=%d", __func__, baud); | 935 | dbg("%s - enter c_ospeed or baud=%d", __func__, baud); |
936 | 936 | ||
@@ -961,13 +961,13 @@ static void iuu_set_termios(struct tty_struct *tty, | |||
961 | * settings back over and then adjust them | 961 | * settings back over and then adjust them |
962 | */ | 962 | */ |
963 | if (old_termios) | 963 | if (old_termios) |
964 | tty_termios_copy_hw(tty->termios, old_termios); | 964 | tty_termios_copy_hw(&tty->termios, old_termios); |
965 | if (status != 0) /* Set failed - return old bits */ | 965 | if (status != 0) /* Set failed - return old bits */ |
966 | return; | 966 | return; |
967 | /* Re-encode speed, parity and csize */ | 967 | /* Re-encode speed, parity and csize */ |
968 | tty_encode_baud_rate(tty, baud, baud); | 968 | tty_encode_baud_rate(tty, baud, baud); |
969 | tty->termios->c_cflag &= ~(supported_mask|CSIZE); | 969 | tty->termios.c_cflag &= ~(supported_mask|CSIZE); |
970 | tty->termios->c_cflag |= newval | csize; | 970 | tty->termios.c_cflag |= newval | csize; |
971 | } | 971 | } |
972 | 972 | ||
973 | static void iuu_close(struct usb_serial_port *port) | 973 | static void iuu_close(struct usb_serial_port *port) |
@@ -993,14 +993,14 @@ static void iuu_close(struct usb_serial_port *port) | |||
993 | 993 | ||
994 | static void iuu_init_termios(struct tty_struct *tty) | 994 | static void iuu_init_termios(struct tty_struct *tty) |
995 | { | 995 | { |
996 | *(tty->termios) = tty_std_termios; | 996 | tty->termios = tty_std_termios; |
997 | tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600 | 997 | tty->termios.c_cflag = CLOCAL | CREAD | CS8 | B9600 |
998 | | TIOCM_CTS | CSTOPB | PARENB; | 998 | | TIOCM_CTS | CSTOPB | PARENB; |
999 | tty->termios->c_ispeed = 9600; | 999 | tty->termios.c_ispeed = 9600; |
1000 | tty->termios->c_ospeed = 9600; | 1000 | tty->termios.c_ospeed = 9600; |
1001 | tty->termios->c_lflag = 0; | 1001 | tty->termios.c_lflag = 0; |
1002 | tty->termios->c_oflag = 0; | 1002 | tty->termios.c_oflag = 0; |
1003 | tty->termios->c_iflag = 0; | 1003 | tty->termios.c_iflag = 0; |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) | 1006 | static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) |
@@ -1012,8 +1012,8 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1012 | u32 actual; | 1012 | u32 actual; |
1013 | struct iuu_private *priv = usb_get_serial_port_data(port); | 1013 | struct iuu_private *priv = usb_get_serial_port_data(port); |
1014 | 1014 | ||
1015 | baud = tty->termios->c_ospeed; | 1015 | baud = tty->termios.c_ospeed; |
1016 | tty->termios->c_ispeed = baud; | 1016 | tty->termios.c_ispeed = baud; |
1017 | /* Re-encode speed */ | 1017 | /* Re-encode speed */ |
1018 | tty_encode_baud_rate(tty, baud, baud); | 1018 | tty_encode_baud_rate(tty, baud, baud); |
1019 | 1019 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index af0b70eaf032..7bcbb47e1449 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -158,7 +158,7 @@ static void keyspan_set_termios(struct tty_struct *tty, | |||
158 | 158 | ||
159 | p_priv = usb_get_serial_port_data(port); | 159 | p_priv = usb_get_serial_port_data(port); |
160 | d_details = p_priv->device_details; | 160 | d_details = p_priv->device_details; |
161 | cflag = tty->termios->c_cflag; | 161 | cflag = tty->termios.c_cflag; |
162 | device_port = port->number - port->serial->minor; | 162 | device_port = port->number - port->serial->minor; |
163 | 163 | ||
164 | /* Baud rate calculation takes baud rate as an integer | 164 | /* Baud rate calculation takes baud rate as an integer |
@@ -179,7 +179,7 @@ static void keyspan_set_termios(struct tty_struct *tty, | |||
179 | p_priv->flow_control = (cflag & CRTSCTS) ? flow_cts : flow_none; | 179 | p_priv->flow_control = (cflag & CRTSCTS) ? flow_cts : flow_none; |
180 | 180 | ||
181 | /* Mark/Space not supported */ | 181 | /* Mark/Space not supported */ |
182 | tty->termios->c_cflag &= ~CMSPAR; | 182 | tty->termios.c_cflag &= ~CMSPAR; |
183 | 183 | ||
184 | keyspan_send_setup(port, 0); | 184 | keyspan_send_setup(port, 0); |
185 | } | 185 | } |
@@ -1086,7 +1086,7 @@ static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
1086 | 1086 | ||
1087 | device_port = port->number - port->serial->minor; | 1087 | device_port = port->number - port->serial->minor; |
1088 | if (tty) { | 1088 | if (tty) { |
1089 | cflag = tty->termios->c_cflag; | 1089 | cflag = tty->termios.c_cflag; |
1090 | /* Baud rate calculation takes baud rate as an integer | 1090 | /* Baud rate calculation takes baud rate as an integer |
1091 | so other rates can be generated if desired. */ | 1091 | so other rates can be generated if desired. */ |
1092 | baud_rate = tty_get_baud_rate(tty); | 1092 | baud_rate = tty_get_baud_rate(tty); |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index a4ac3cfeffc4..dcada8615fcf 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -338,7 +338,7 @@ static void keyspan_pda_set_termios(struct tty_struct *tty, | |||
338 | 7[EOMS]1: 10 bit, b0/b7 is parity | 338 | 7[EOMS]1: 10 bit, b0/b7 is parity |
339 | 7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?) | 339 | 7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?) |
340 | 340 | ||
341 | HW flow control is dictated by the tty->termios->c_cflags & CRTSCTS | 341 | HW flow control is dictated by the tty->termios.c_cflags & CRTSCTS |
342 | bit. | 342 | bit. |
343 | 343 | ||
344 | For now, just do baud. */ | 344 | For now, just do baud. */ |
@@ -353,7 +353,7 @@ static void keyspan_pda_set_termios(struct tty_struct *tty, | |||
353 | } | 353 | } |
354 | /* Only speed can change so copy the old h/w parameters | 354 | /* Only speed can change so copy the old h/w parameters |
355 | then encode the new speed */ | 355 | then encode the new speed */ |
356 | tty_termios_copy_hw(tty->termios, old_termios); | 356 | tty_termios_copy_hw(&tty->termios, old_termios); |
357 | tty_encode_baud_rate(tty, speed, speed); | 357 | tty_encode_baud_rate(tty, speed, speed); |
358 | } | 358 | } |
359 | 359 | ||
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 5bed59cd5776..def9ad258715 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -311,12 +311,12 @@ static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
311 | 311 | ||
312 | /* set up termios structure */ | 312 | /* set up termios structure */ |
313 | spin_lock_irqsave(&priv->lock, flags); | 313 | spin_lock_irqsave(&priv->lock, flags); |
314 | priv->termios.c_iflag = tty->termios->c_iflag; | 314 | priv->termios.c_iflag = tty->termios.c_iflag; |
315 | priv->termios.c_oflag = tty->termios->c_oflag; | 315 | priv->termios.c_oflag = tty->termios.c_oflag; |
316 | priv->termios.c_cflag = tty->termios->c_cflag; | 316 | priv->termios.c_cflag = tty->termios.c_cflag; |
317 | priv->termios.c_lflag = tty->termios->c_lflag; | 317 | priv->termios.c_lflag = tty->termios.c_lflag; |
318 | for (i = 0; i < NCCS; i++) | 318 | for (i = 0; i < NCCS; i++) |
319 | priv->termios.c_cc[i] = tty->termios->c_cc[i]; | 319 | priv->termios.c_cc[i] = tty->termios.c_cc[i]; |
320 | priv->cfg.pktlen = cfg->pktlen; | 320 | priv->cfg.pktlen = cfg->pktlen; |
321 | priv->cfg.baudrate = cfg->baudrate; | 321 | priv->cfg.baudrate = cfg->baudrate; |
322 | priv->cfg.databits = cfg->databits; | 322 | priv->cfg.databits = cfg->databits; |
@@ -445,9 +445,9 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
445 | struct ktermios *old_termios) | 445 | struct ktermios *old_termios) |
446 | { | 446 | { |
447 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | 447 | struct klsi_105_private *priv = usb_get_serial_port_data(port); |
448 | unsigned int iflag = tty->termios->c_iflag; | 448 | unsigned int iflag = tty->termios.c_iflag; |
449 | unsigned int old_iflag = old_termios->c_iflag; | 449 | unsigned int old_iflag = old_termios->c_iflag; |
450 | unsigned int cflag = tty->termios->c_cflag; | 450 | unsigned int cflag = tty->termios.c_cflag; |
451 | unsigned int old_cflag = old_termios->c_cflag; | 451 | unsigned int old_cflag = old_termios->c_cflag; |
452 | struct klsi_105_port_settings *cfg; | 452 | struct klsi_105_port_settings *cfg; |
453 | unsigned long flags; | 453 | unsigned long flags; |
@@ -560,7 +560,7 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
560 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD)) | 560 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD)) |
561 | || (cflag & CSTOPB) != (old_cflag & CSTOPB)) { | 561 | || (cflag & CSTOPB) != (old_cflag & CSTOPB)) { |
562 | /* Not currently supported */ | 562 | /* Not currently supported */ |
563 | tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB); | 563 | tty->termios.c_cflag &= ~(PARENB|PARODD|CSTOPB); |
564 | #if 0 | 564 | #if 0 |
565 | priv->last_lcr = 0; | 565 | priv->last_lcr = 0; |
566 | 566 | ||
@@ -587,7 +587,7 @@ static void klsi_105_set_termios(struct tty_struct *tty, | |||
587 | || (iflag & IXON) != (old_iflag & IXON) | 587 | || (iflag & IXON) != (old_iflag & IXON) |
588 | || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { | 588 | || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { |
589 | /* Not currently supported */ | 589 | /* Not currently supported */ |
590 | tty->termios->c_cflag &= ~CRTSCTS; | 590 | tty->termios.c_cflag &= ~CRTSCTS; |
591 | /* Drop DTR/RTS if no flow control otherwise assert */ | 591 | /* Drop DTR/RTS if no flow control otherwise assert */ |
592 | #if 0 | 592 | #if 0 |
593 | if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) | 593 | if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS)) |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index fafeabb64c55..bf5c74965d34 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -191,11 +191,11 @@ static void kobil_release(struct usb_serial *serial) | |||
191 | static void kobil_init_termios(struct tty_struct *tty) | 191 | static void kobil_init_termios(struct tty_struct *tty) |
192 | { | 192 | { |
193 | /* Default to echo off and other sane device settings */ | 193 | /* Default to echo off and other sane device settings */ |
194 | tty->termios->c_lflag = 0; | 194 | tty->termios.c_lflag = 0; |
195 | tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); | 195 | tty->termios.c_iflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE); |
196 | tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; | 196 | tty->termios.c_iflag |= IGNBRK | IGNPAR | IXOFF; |
197 | /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */ | 197 | /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */ |
198 | tty->termios->c_oflag &= ~ONLCR; | 198 | tty->termios.c_oflag &= ~ONLCR; |
199 | } | 199 | } |
200 | 200 | ||
201 | static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) | 201 | static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port) |
@@ -581,14 +581,14 @@ static void kobil_set_termios(struct tty_struct *tty, | |||
581 | struct kobil_private *priv; | 581 | struct kobil_private *priv; |
582 | int result; | 582 | int result; |
583 | unsigned short urb_val = 0; | 583 | unsigned short urb_val = 0; |
584 | int c_cflag = tty->termios->c_cflag; | 584 | int c_cflag = tty->termios.c_cflag; |
585 | speed_t speed; | 585 | speed_t speed; |
586 | 586 | ||
587 | priv = usb_get_serial_port_data(port); | 587 | priv = usb_get_serial_port_data(port); |
588 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || | 588 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || |
589 | priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { | 589 | priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) { |
590 | /* This device doesn't support ioctl calls */ | 590 | /* This device doesn't support ioctl calls */ |
591 | *tty->termios = *old; | 591 | tty_termios_copy_hw(&tty->termios, old); |
592 | return; | 592 | return; |
593 | } | 593 | } |
594 | 594 | ||
@@ -612,7 +612,7 @@ static void kobil_set_termios(struct tty_struct *tty, | |||
612 | urb_val |= SUSBCR_SPASB_EvenParity; | 612 | urb_val |= SUSBCR_SPASB_EvenParity; |
613 | } else | 613 | } else |
614 | urb_val |= SUSBCR_SPASB_NoParity; | 614 | urb_val |= SUSBCR_SPASB_NoParity; |
615 | tty->termios->c_cflag &= ~CMSPAR; | 615 | tty->termios.c_cflag &= ~CMSPAR; |
616 | tty_encode_baud_rate(tty, speed, speed); | 616 | tty_encode_baud_rate(tty, speed, speed); |
617 | 617 | ||
618 | result = usb_control_msg(port->serial->dev, | 618 | result = usb_control_msg(port->serial->dev, |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index a71fa0aa0406..df98cffdba65 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -454,7 +454,7 @@ static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
454 | * either. | 454 | * either. |
455 | */ | 455 | */ |
456 | spin_lock_irqsave(&priv->lock, flags); | 456 | spin_lock_irqsave(&priv->lock, flags); |
457 | if (tty && (tty->termios->c_cflag & CBAUD)) | 457 | if (tty && (tty->termios.c_cflag & CBAUD)) |
458 | priv->control_state = TIOCM_DTR | TIOCM_RTS; | 458 | priv->control_state = TIOCM_DTR | TIOCM_RTS; |
459 | else | 459 | else |
460 | priv->control_state = 0; | 460 | priv->control_state = 0; |
@@ -634,7 +634,7 @@ static void mct_u232_set_termios(struct tty_struct *tty, | |||
634 | { | 634 | { |
635 | struct usb_serial *serial = port->serial; | 635 | struct usb_serial *serial = port->serial; |
636 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 636 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
637 | struct ktermios *termios = tty->termios; | 637 | struct ktermios *termios = &tty->termios; |
638 | unsigned int cflag = termios->c_cflag; | 638 | unsigned int cflag = termios->c_cflag; |
639 | unsigned int old_cflag = old_termios->c_cflag; | 639 | unsigned int old_cflag = old_termios->c_cflag; |
640 | unsigned long flags; | 640 | unsigned long flags; |
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index d47eb06fe463..2b0627b5fe2c 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c | |||
@@ -130,12 +130,6 @@ static void metrousb_read_int_callback(struct urb *urb) | |||
130 | 130 | ||
131 | /* Set the data read from the usb port into the serial port buffer. */ | 131 | /* Set the data read from the usb port into the serial port buffer. */ |
132 | tty = tty_port_tty_get(&port->port); | 132 | tty = tty_port_tty_get(&port->port); |
133 | if (!tty) { | ||
134 | dev_err(&port->dev, "%s - bad tty pointer - exiting\n", | ||
135 | __func__); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | if (tty && urb->actual_length) { | 133 | if (tty && urb->actual_length) { |
140 | /* Loop through the data copying each byte to the tty layer. */ | 134 | /* Loop through the data copying each byte to the tty layer. */ |
141 | tty_insert_flip_string(tty, data, urb->actual_length); | 135 | tty_insert_flip_string(tty, data, urb->actual_length); |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index a07dd3c8cfef..012f67b2e4cc 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -1349,7 +1349,7 @@ static void mos7720_throttle(struct tty_struct *tty) | |||
1349 | } | 1349 | } |
1350 | 1350 | ||
1351 | /* if we are implementing RTS/CTS, toggle that line */ | 1351 | /* if we are implementing RTS/CTS, toggle that line */ |
1352 | if (tty->termios->c_cflag & CRTSCTS) { | 1352 | if (tty->termios.c_cflag & CRTSCTS) { |
1353 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; | 1353 | mos7720_port->shadowMCR &= ~UART_MCR_RTS; |
1354 | write_mos_reg(port->serial, port->number - port->serial->minor, | 1354 | write_mos_reg(port->serial, port->number - port->serial->minor, |
1355 | MCR, mos7720_port->shadowMCR); | 1355 | MCR, mos7720_port->shadowMCR); |
@@ -1383,7 +1383,7 @@ static void mos7720_unthrottle(struct tty_struct *tty) | |||
1383 | } | 1383 | } |
1384 | 1384 | ||
1385 | /* if we are implementing RTS/CTS, toggle that line */ | 1385 | /* if we are implementing RTS/CTS, toggle that line */ |
1386 | if (tty->termios->c_cflag & CRTSCTS) { | 1386 | if (tty->termios.c_cflag & CRTSCTS) { |
1387 | mos7720_port->shadowMCR |= UART_MCR_RTS; | 1387 | mos7720_port->shadowMCR |= UART_MCR_RTS; |
1388 | write_mos_reg(port->serial, port->number - port->serial->minor, | 1388 | write_mos_reg(port->serial, port->number - port->serial->minor, |
1389 | MCR, mos7720_port->shadowMCR); | 1389 | MCR, mos7720_port->shadowMCR); |
@@ -1604,8 +1604,8 @@ static void change_port_settings(struct tty_struct *tty, | |||
1604 | lStop = 0x00; /* 1 stop bit */ | 1604 | lStop = 0x00; /* 1 stop bit */ |
1605 | lParity = 0x00; /* No parity */ | 1605 | lParity = 0x00; /* No parity */ |
1606 | 1606 | ||
1607 | cflag = tty->termios->c_cflag; | 1607 | cflag = tty->termios.c_cflag; |
1608 | iflag = tty->termios->c_iflag; | 1608 | iflag = tty->termios.c_iflag; |
1609 | 1609 | ||
1610 | /* Change the number of bits */ | 1610 | /* Change the number of bits */ |
1611 | switch (cflag & CSIZE) { | 1611 | switch (cflag & CSIZE) { |
@@ -1753,11 +1753,11 @@ static void mos7720_set_termios(struct tty_struct *tty, | |||
1753 | 1753 | ||
1754 | dbg("%s\n", "setting termios - ASPIRE"); | 1754 | dbg("%s\n", "setting termios - ASPIRE"); |
1755 | 1755 | ||
1756 | cflag = tty->termios->c_cflag; | 1756 | cflag = tty->termios.c_cflag; |
1757 | 1757 | ||
1758 | dbg("%s - cflag %08x iflag %08x", __func__, | 1758 | dbg("%s - cflag %08x iflag %08x", __func__, |
1759 | tty->termios->c_cflag, | 1759 | tty->termios.c_cflag, |
1760 | RELEVANT_IFLAG(tty->termios->c_iflag)); | 1760 | RELEVANT_IFLAG(tty->termios.c_iflag)); |
1761 | 1761 | ||
1762 | dbg("%s - old cflag %08x old iflag %08x", __func__, | 1762 | dbg("%s - old cflag %08x old iflag %08x", __func__, |
1763 | old_termios->c_cflag, | 1763 | old_termios->c_cflag, |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 2f6da1e89bfa..402c32d7accb 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -1651,7 +1651,7 @@ static void mos7840_throttle(struct tty_struct *tty) | |||
1651 | return; | 1651 | return; |
1652 | } | 1652 | } |
1653 | /* if we are implementing RTS/CTS, toggle that line */ | 1653 | /* if we are implementing RTS/CTS, toggle that line */ |
1654 | if (tty->termios->c_cflag & CRTSCTS) { | 1654 | if (tty->termios.c_cflag & CRTSCTS) { |
1655 | mos7840_port->shadowMCR &= ~MCR_RTS; | 1655 | mos7840_port->shadowMCR &= ~MCR_RTS; |
1656 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, | 1656 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, |
1657 | mos7840_port->shadowMCR); | 1657 | mos7840_port->shadowMCR); |
@@ -1694,7 +1694,7 @@ static void mos7840_unthrottle(struct tty_struct *tty) | |||
1694 | } | 1694 | } |
1695 | 1695 | ||
1696 | /* if we are implementing RTS/CTS, toggle that line */ | 1696 | /* if we are implementing RTS/CTS, toggle that line */ |
1697 | if (tty->termios->c_cflag & CRTSCTS) { | 1697 | if (tty->termios.c_cflag & CRTSCTS) { |
1698 | mos7840_port->shadowMCR |= MCR_RTS; | 1698 | mos7840_port->shadowMCR |= MCR_RTS; |
1699 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, | 1699 | status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER, |
1700 | mos7840_port->shadowMCR); | 1700 | mos7840_port->shadowMCR); |
@@ -2000,8 +2000,8 @@ static void mos7840_change_port_settings(struct tty_struct *tty, | |||
2000 | lStop = LCR_STOP_1; | 2000 | lStop = LCR_STOP_1; |
2001 | lParity = LCR_PAR_NONE; | 2001 | lParity = LCR_PAR_NONE; |
2002 | 2002 | ||
2003 | cflag = tty->termios->c_cflag; | 2003 | cflag = tty->termios.c_cflag; |
2004 | iflag = tty->termios->c_iflag; | 2004 | iflag = tty->termios.c_iflag; |
2005 | 2005 | ||
2006 | /* Change the number of bits */ | 2006 | /* Change the number of bits */ |
2007 | if (cflag & CSIZE) { | 2007 | if (cflag & CSIZE) { |
@@ -2161,10 +2161,10 @@ static void mos7840_set_termios(struct tty_struct *tty, | |||
2161 | 2161 | ||
2162 | dbg("%s", "setting termios - "); | 2162 | dbg("%s", "setting termios - "); |
2163 | 2163 | ||
2164 | cflag = tty->termios->c_cflag; | 2164 | cflag = tty->termios.c_cflag; |
2165 | 2165 | ||
2166 | dbg("%s - clfag %08x iflag %08x", __func__, | 2166 | dbg("%s - clfag %08x iflag %08x", __func__, |
2167 | tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); | 2167 | tty->termios.c_cflag, RELEVANT_IFLAG(tty->termios.c_iflag)); |
2168 | dbg("%s - old clfag %08x old iflag %08x", __func__, | 2168 | dbg("%s - old clfag %08x old iflag %08x", __func__, |
2169 | old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); | 2169 | old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); |
2170 | dbg("%s - port %d", __func__, port->number); | 2170 | dbg("%s - port %d", __func__, port->number); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index cc40f47ecea1..5ce88d1bc6f1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -886,8 +886,6 @@ static const struct usb_device_id option_ids[] = { | |||
886 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), | 886 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), |
887 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 887 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
888 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, | 888 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, |
889 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff), | ||
890 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
891 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, | 889 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, |
892 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, | 890 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, |
893 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, | 891 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, |
@@ -1092,6 +1090,10 @@ static const struct usb_device_id option_ids[] = { | |||
1092 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, | 1090 | .driver_info = (kernel_ulong_t)&zte_ad3812_z_blacklist }, |
1093 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), | 1091 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MC2716, 0xff, 0xff, 0xff), |
1094 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, | 1092 | .driver_info = (kernel_ulong_t)&zte_mc2716_z_blacklist }, |
1093 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x01) }, | ||
1094 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x02, 0x05) }, | ||
1095 | { USB_VENDOR_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff, 0x86, 0x10) }, | ||
1096 | |||
1095 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 1097 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
1096 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 1098 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
1097 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ | 1099 | { USB_DEVICE(ALINK_VENDOR_ID, DLINK_PRODUCT_DWM_652_U5) }, /* Yes, ALINK_VENDOR_ID */ |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 5976b65ab6ee..9f555560bfbf 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -404,10 +404,10 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty) | |||
404 | 404 | ||
405 | static void oti6858_init_termios(struct tty_struct *tty) | 405 | static void oti6858_init_termios(struct tty_struct *tty) |
406 | { | 406 | { |
407 | *(tty->termios) = tty_std_termios; | 407 | tty->termios = tty_std_termios; |
408 | tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; | 408 | tty->termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL; |
409 | tty->termios->c_ispeed = 38400; | 409 | tty->termios.c_ispeed = 38400; |
410 | tty->termios->c_ospeed = 38400; | 410 | tty->termios.c_ospeed = 38400; |
411 | } | 411 | } |
412 | 412 | ||
413 | static void oti6858_set_termios(struct tty_struct *tty, | 413 | static void oti6858_set_termios(struct tty_struct *tty, |
@@ -425,7 +425,7 @@ static void oti6858_set_termios(struct tty_struct *tty, | |||
425 | return; | 425 | return; |
426 | } | 426 | } |
427 | 427 | ||
428 | cflag = tty->termios->c_cflag; | 428 | cflag = tty->termios.c_cflag; |
429 | 429 | ||
430 | spin_lock_irqsave(&priv->lock, flags); | 430 | spin_lock_irqsave(&priv->lock, flags); |
431 | divisor = priv->pending_setup.divisor; | 431 | divisor = priv->pending_setup.divisor; |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 13b8dd6481f5..2b9108a8ea64 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -260,16 +260,16 @@ static void pl2303_set_termios(struct tty_struct *tty, | |||
260 | serial settings even to the same values as before. Thus | 260 | serial settings even to the same values as before. Thus |
261 | we actually need to filter in this specific case */ | 261 | we actually need to filter in this specific case */ |
262 | 262 | ||
263 | if (!tty_termios_hw_change(tty->termios, old_termios)) | 263 | if (!tty_termios_hw_change(&tty->termios, old_termios)) |
264 | return; | 264 | return; |
265 | 265 | ||
266 | cflag = tty->termios->c_cflag; | 266 | cflag = tty->termios.c_cflag; |
267 | 267 | ||
268 | buf = kzalloc(7, GFP_KERNEL); | 268 | buf = kzalloc(7, GFP_KERNEL); |
269 | if (!buf) { | 269 | if (!buf) { |
270 | dev_err(&port->dev, "%s - out of memory.\n", __func__); | 270 | dev_err(&port->dev, "%s - out of memory.\n", __func__); |
271 | /* Report back no change occurred */ | 271 | /* Report back no change occurred */ |
272 | *tty->termios = *old_termios; | 272 | tty->termios = *old_termios; |
273 | return; | 273 | return; |
274 | } | 274 | } |
275 | 275 | ||
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 151670b6b72a..7df9cdb053ed 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
@@ -275,7 +275,7 @@ static void qt2_set_termios(struct tty_struct *tty, | |||
275 | { | 275 | { |
276 | struct usb_device *dev = port->serial->dev; | 276 | struct usb_device *dev = port->serial->dev; |
277 | struct qt2_port_private *port_priv; | 277 | struct qt2_port_private *port_priv; |
278 | struct ktermios *termios = tty->termios; | 278 | struct ktermios *termios = &tty->termios; |
279 | u16 baud; | 279 | u16 baud; |
280 | unsigned int cflag = termios->c_cflag; | 280 | unsigned int cflag = termios->c_cflag; |
281 | u16 new_lcr = 0; | 281 | u16 new_lcr = 0; |
@@ -406,7 +406,7 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
406 | port_priv->device_port = (u8) device_port; | 406 | port_priv->device_port = (u8) device_port; |
407 | 407 | ||
408 | if (tty) | 408 | if (tty) |
409 | qt2_set_termios(tty, port, tty->termios); | 409 | qt2_set_termios(tty, port, &tty->termios); |
410 | 410 | ||
411 | return 0; | 411 | return 0; |
412 | 412 | ||
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 0274710cced5..b14ebbd73567 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -382,7 +382,7 @@ static int sierra_send_setup(struct usb_serial_port *port) | |||
382 | static void sierra_set_termios(struct tty_struct *tty, | 382 | static void sierra_set_termios(struct tty_struct *tty, |
383 | struct usb_serial_port *port, struct ktermios *old_termios) | 383 | struct usb_serial_port *port, struct ktermios *old_termios) |
384 | { | 384 | { |
385 | tty_termios_copy_hw(tty->termios, old_termios); | 385 | tty_termios_copy_hw(&tty->termios, old_termios); |
386 | sierra_send_setup(port); | 386 | sierra_send_setup(port); |
387 | } | 387 | } |
388 | 388 | ||
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index cad608984710..ab68a4d74d61 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c | |||
@@ -316,10 +316,10 @@ static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on) | |||
316 | static void spcp8x5_init_termios(struct tty_struct *tty) | 316 | static void spcp8x5_init_termios(struct tty_struct *tty) |
317 | { | 317 | { |
318 | /* for the 1st time call this function */ | 318 | /* for the 1st time call this function */ |
319 | *(tty->termios) = tty_std_termios; | 319 | tty->termios = tty_std_termios; |
320 | tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; | 320 | tty->termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL; |
321 | tty->termios->c_ispeed = 115200; | 321 | tty->termios.c_ispeed = 115200; |
322 | tty->termios->c_ospeed = 115200; | 322 | tty->termios.c_ospeed = 115200; |
323 | } | 323 | } |
324 | 324 | ||
325 | /* set the serial param for transfer. we should check if we really need to | 325 | /* set the serial param for transfer. we should check if we really need to |
@@ -330,7 +330,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty, | |||
330 | struct usb_serial *serial = port->serial; | 330 | struct usb_serial *serial = port->serial; |
331 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); | 331 | struct spcp8x5_private *priv = usb_get_serial_port_data(port); |
332 | unsigned long flags; | 332 | unsigned long flags; |
333 | unsigned int cflag = tty->termios->c_cflag; | 333 | unsigned int cflag = tty->termios.c_cflag; |
334 | unsigned int old_cflag = old_termios->c_cflag; | 334 | unsigned int old_cflag = old_termios->c_cflag; |
335 | unsigned short uartdata; | 335 | unsigned short uartdata; |
336 | unsigned char buf[2] = {0, 0}; | 336 | unsigned char buf[2] = {0, 0}; |
@@ -340,7 +340,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty, | |||
340 | 340 | ||
341 | 341 | ||
342 | /* check that they really want us to change something */ | 342 | /* check that they really want us to change something */ |
343 | if (!tty_termios_hw_change(tty->termios, old_termios)) | 343 | if (!tty_termios_hw_change(&tty->termios, old_termios)) |
344 | return; | 344 | return; |
345 | 345 | ||
346 | /* set DTR/RTS active */ | 346 | /* set DTR/RTS active */ |
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 3fee23bf0c14..cf2d30cf7588 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c | |||
@@ -216,7 +216,7 @@ static void ssu100_set_termios(struct tty_struct *tty, | |||
216 | struct ktermios *old_termios) | 216 | struct ktermios *old_termios) |
217 | { | 217 | { |
218 | struct usb_device *dev = port->serial->dev; | 218 | struct usb_device *dev = port->serial->dev; |
219 | struct ktermios *termios = tty->termios; | 219 | struct ktermios *termios = &tty->termios; |
220 | u16 baud, divisor, remainder; | 220 | u16 baud, divisor, remainder; |
221 | unsigned int cflag = termios->c_cflag; | 221 | unsigned int cflag = termios->c_cflag; |
222 | u16 urb_value = 0; /* will hold the new flags */ | 222 | u16 urb_value = 0; /* will hold the new flags */ |
@@ -322,7 +322,7 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
322 | dbg("%s - set uart failed", __func__); | 322 | dbg("%s - set uart failed", __func__); |
323 | 323 | ||
324 | if (tty) | 324 | if (tty) |
325 | ssu100_set_termios(tty, port, tty->termios); | 325 | ssu100_set_termios(tty, port, &tty->termios); |
326 | 326 | ||
327 | return usb_serial_generic_open(tty, port); | 327 | return usb_serial_generic_open(tty, port); |
328 | } | 328 | } |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index a4404f5ad68e..f502a16aac21 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -520,7 +520,7 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
520 | } | 520 | } |
521 | 521 | ||
522 | if (tty) | 522 | if (tty) |
523 | ti_set_termios(tty, port, tty->termios); | 523 | ti_set_termios(tty, port, &tty->termios); |
524 | 524 | ||
525 | dbg("%s - sending TI_OPEN_PORT", __func__); | 525 | dbg("%s - sending TI_OPEN_PORT", __func__); |
526 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, | 526 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, |
@@ -562,7 +562,7 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) | |||
562 | usb_clear_halt(dev, port->read_urb->pipe); | 562 | usb_clear_halt(dev, port->read_urb->pipe); |
563 | 563 | ||
564 | if (tty) | 564 | if (tty) |
565 | ti_set_termios(tty, port, tty->termios); | 565 | ti_set_termios(tty, port, &tty->termios); |
566 | 566 | ||
567 | dbg("%s - sending TI_OPEN_PORT (2)", __func__); | 567 | dbg("%s - sending TI_OPEN_PORT (2)", __func__); |
568 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, | 568 | status = ti_command_out_sync(tdev, TI_OPEN_PORT, |
@@ -831,8 +831,8 @@ static void ti_set_termios(struct tty_struct *tty, | |||
831 | int port_number = port->number - port->serial->minor; | 831 | int port_number = port->number - port->serial->minor; |
832 | unsigned int mcr; | 832 | unsigned int mcr; |
833 | 833 | ||
834 | cflag = tty->termios->c_cflag; | 834 | cflag = tty->termios.c_cflag; |
835 | iflag = tty->termios->c_iflag; | 835 | iflag = tty->termios.c_iflag; |
836 | 836 | ||
837 | dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag); | 837 | dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag); |
838 | dbg("%s - old clfag %08x, old iflag %08x", __func__, | 838 | dbg("%s - old clfag %08x, old iflag %08x", __func__, |
@@ -871,7 +871,7 @@ static void ti_set_termios(struct tty_struct *tty, | |||
871 | } | 871 | } |
872 | 872 | ||
873 | /* CMSPAR isn't supported by this driver */ | 873 | /* CMSPAR isn't supported by this driver */ |
874 | tty->termios->c_cflag &= ~CMSPAR; | 874 | tty->termios.c_cflag &= ~CMSPAR; |
875 | 875 | ||
876 | if (cflag & PARENB) { | 876 | if (cflag & PARENB) { |
877 | if (cflag & PARODD) { | 877 | if (cflag & PARODD) { |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 27483f91a4a3..aa4b0d775992 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -207,7 +207,7 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) | |||
207 | if (retval) | 207 | if (retval) |
208 | goto error_get_interface; | 208 | goto error_get_interface; |
209 | 209 | ||
210 | retval = tty_standard_install(driver, tty); | 210 | retval = tty_port_install(&port->port, driver, tty); |
211 | if (retval) | 211 | if (retval) |
212 | goto error_init_termios; | 212 | goto error_init_termios; |
213 | 213 | ||
@@ -305,8 +305,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp) | |||
305 | * Do the resource freeing and refcount dropping for the port. | 305 | * Do the resource freeing and refcount dropping for the port. |
306 | * Avoid freeing the console. | 306 | * Avoid freeing the console. |
307 | * | 307 | * |
308 | * Called asynchronously after the last tty kref is dropped, | 308 | * Called asynchronously after the last tty kref is dropped. |
309 | * and the tty layer has already done the tty_shutdown(tty); | ||
310 | */ | 309 | */ |
311 | static void serial_cleanup(struct tty_struct *tty) | 310 | static void serial_cleanup(struct tty_struct *tty) |
312 | { | 311 | { |
@@ -423,7 +422,7 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old) | |||
423 | if (port->serial->type->set_termios) | 422 | if (port->serial->type->set_termios) |
424 | port->serial->type->set_termios(tty, port, old); | 423 | port->serial->type->set_termios(tty, port, old); |
425 | else | 424 | else |
426 | tty_termios_copy_hw(tty->termios, old); | 425 | tty_termios_copy_hw(&tty->termios, old); |
427 | } | 426 | } |
428 | 427 | ||
429 | static int serial_break(struct tty_struct *tty, int break_state) | 428 | static int serial_break(struct tty_struct *tty, int break_state) |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index 6855d5ed0331..72b678d90831 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -67,7 +67,7 @@ void usb_wwan_set_termios(struct tty_struct *tty, | |||
67 | struct usb_wwan_intf_private *intfdata = port->serial->private; | 67 | struct usb_wwan_intf_private *intfdata = port->serial->private; |
68 | 68 | ||
69 | /* Doesn't support option setting */ | 69 | /* Doesn't support option setting */ |
70 | tty_termios_copy_hw(tty->termios, old_termios); | 70 | tty_termios_copy_hw(&tty->termios, old_termios); |
71 | 71 | ||
72 | if (intfdata->send_setup) | 72 | if (intfdata->send_setup) |
73 | intfdata->send_setup(port); | 73 | intfdata->send_setup(port); |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 473635e7f5db..b36077de72b9 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -724,7 +724,7 @@ static void firm_setup_port(struct tty_struct *tty) | |||
724 | { | 724 | { |
725 | struct usb_serial_port *port = tty->driver_data; | 725 | struct usb_serial_port *port = tty->driver_data; |
726 | struct whiteheat_port_settings port_settings; | 726 | struct whiteheat_port_settings port_settings; |
727 | unsigned int cflag = tty->termios->c_cflag; | 727 | unsigned int cflag = tty->termios.c_cflag; |
728 | 728 | ||
729 | port_settings.port = port->number + 1; | 729 | port_settings.port = port->number + 1; |
730 | 730 | ||
diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index bfdc5fbeaa11..9a046a4c98f5 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c | |||
@@ -27,10 +27,10 @@ | |||
27 | #include <linux/fb.h> | 27 | #include <linux/fb.h> |
28 | #include <linux/backlight.h> | 28 | #include <linux/backlight.h> |
29 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
30 | #include <linux/platform_data/omap1_bl.h> | ||
30 | 31 | ||
31 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
32 | #include <plat/board.h> | 33 | #include <mach/mux.h> |
33 | #include <plat/mux.h> | ||
34 | 34 | ||
35 | #define OMAPBL_MAX_INTENSITY 0xff | 35 | #define OMAPBL_MAX_INTENSITY 0xff |
36 | 36 | ||
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 7ae9d53f2bf1..113d43a16f54 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c | |||
@@ -131,7 +131,7 @@ | |||
131 | #define UPPER_MARGIN 32 | 131 | #define UPPER_MARGIN 32 |
132 | #define LOWER_MARGIN 32 | 132 | #define LOWER_MARGIN 32 |
133 | 133 | ||
134 | static resource_size_t da8xx_fb_reg_base; | 134 | static void __iomem *da8xx_fb_reg_base; |
135 | static struct resource *lcdc_regs; | 135 | static struct resource *lcdc_regs; |
136 | static unsigned int lcd_revision; | 136 | static unsigned int lcd_revision; |
137 | static irq_handler_t lcdc_irq_handler; | 137 | static irq_handler_t lcdc_irq_handler; |
@@ -951,7 +951,7 @@ static int __devexit fb_remove(struct platform_device *dev) | |||
951 | clk_disable(par->lcdc_clk); | 951 | clk_disable(par->lcdc_clk); |
952 | clk_put(par->lcdc_clk); | 952 | clk_put(par->lcdc_clk); |
953 | framebuffer_release(info); | 953 | framebuffer_release(info); |
954 | iounmap((void __iomem *)da8xx_fb_reg_base); | 954 | iounmap(da8xx_fb_reg_base); |
955 | release_mem_region(lcdc_regs->start, resource_size(lcdc_regs)); | 955 | release_mem_region(lcdc_regs->start, resource_size(lcdc_regs)); |
956 | 956 | ||
957 | } | 957 | } |
@@ -1171,7 +1171,7 @@ static int __devinit fb_probe(struct platform_device *device) | |||
1171 | if (!lcdc_regs) | 1171 | if (!lcdc_regs) |
1172 | return -EBUSY; | 1172 | return -EBUSY; |
1173 | 1173 | ||
1174 | da8xx_fb_reg_base = (resource_size_t)ioremap(lcdc_regs->start, len); | 1174 | da8xx_fb_reg_base = ioremap(lcdc_regs->start, len); |
1175 | if (!da8xx_fb_reg_base) { | 1175 | if (!da8xx_fb_reg_base) { |
1176 | ret = -EBUSY; | 1176 | ret = -EBUSY; |
1177 | goto err_request_mem; | 1177 | goto err_request_mem; |
@@ -1392,7 +1392,7 @@ err_clk_put: | |||
1392 | clk_put(fb_clk); | 1392 | clk_put(fb_clk); |
1393 | 1393 | ||
1394 | err_ioremap: | 1394 | err_ioremap: |
1395 | iounmap((void __iomem *)da8xx_fb_reg_base); | 1395 | iounmap(da8xx_fb_reg_base); |
1396 | 1396 | ||
1397 | err_request_mem: | 1397 | err_request_mem: |
1398 | release_mem_region(lcdc_regs->start, len); | 1398 | release_mem_region(lcdc_regs->start, len); |
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c index 345d96230978..f2c092da84b0 100644 --- a/drivers/video/ep93xx-fb.c +++ b/drivers/video/ep93xx-fb.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
25 | #include <linux/fb.h> | 25 | #include <linux/fb.h> |
26 | 26 | ||
27 | #include <mach/fb.h> | 27 | #include <linux/platform_data/video-ep93xx.h> |
28 | 28 | ||
29 | /* Vertical Frame Timing Registers */ | 29 | /* Vertical Frame Timing Registers */ |
30 | #define EP93XXFB_VLINES_TOTAL 0x0000 /* SW locked */ | 30 | #define EP93XXFB_VLINES_TOTAL 0x0000 /* SW locked */ |
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index caad3689b4e6..53ffdfc82a75 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/math64.h> | 33 | #include <linux/math64.h> |
34 | 34 | ||
35 | #include <mach/imxfb.h> | 35 | #include <linux/platform_data/video-imxfb.h> |
36 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
37 | 37 | ||
38 | /* | 38 | /* |
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index b061d709bc44..bf73f0480061 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <mach/msm_iomap.h> | 29 | #include <mach/msm_iomap.h> |
30 | #include <mach/irqs.h> | 30 | #include <mach/irqs.h> |
31 | #include <mach/board.h> | 31 | #include <mach/board.h> |
32 | #include <mach/msm_fb.h> | 32 | #include <linux/platform_data/video-msm_fb.h> |
33 | #include "mddi_hw.h" | 33 | #include "mddi_hw.h" |
34 | 34 | ||
35 | #define FLAG_DISABLE_HIBERNATION 0x0001 | 35 | #define FLAG_DISABLE_HIBERNATION 0x0001 |
diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/msm/mddi_client_dummy.c index d2a091cebe2c..f1b0dfcc9717 100644 --- a/drivers/video/msm/mddi_client_dummy.c +++ b/drivers/video/msm/mddi_client_dummy.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | 22 | ||
23 | #include <mach/msm_fb.h> | 23 | #include <linux/platform_data/video-msm_fb.h> |
24 | 24 | ||
25 | struct panel_info { | 25 | struct panel_info { |
26 | struct platform_device pdev; | 26 | struct platform_device pdev; |
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c index 7fcd67e132bf..d7a5bf84fb2a 100644 --- a/drivers/video/msm/mddi_client_nt35399.c +++ b/drivers/video/msm/mddi_client_nt35399.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/sched.h> | 22 | #include <linux/sched.h> |
23 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <mach/msm_fb.h> | 25 | #include <linux/platform_data/video-msm_fb.h> |
26 | 26 | ||
27 | static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait); | 27 | static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait); |
28 | 28 | ||
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c index 053eb6877330..061d7dfebbf3 100644 --- a/drivers/video/msm/mddi_client_toshiba.c +++ b/drivers/video/msm/mddi_client_toshiba.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/sched.h> | 23 | #include <linux/sched.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <mach/msm_fb.h> | 25 | #include <linux/platform_data/video-msm_fb.h> |
26 | 26 | ||
27 | 27 | ||
28 | #define LCD_CONTROL_BLOCK_BASE 0x110000 | 28 | #define LCD_CONTROL_BLOCK_BASE 0x110000 |
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c index cb2ddf164c98..d1f881e8030e 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/msm/mdp.c | |||
@@ -26,7 +26,7 @@ | |||
26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
27 | 27 | ||
28 | #include <mach/msm_iomap.h> | 28 | #include <mach/msm_iomap.h> |
29 | #include <mach/msm_fb.h> | 29 | #include <linux/platform_data/video-msm_fb.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/export.h> | 31 | #include <linux/export.h> |
32 | 32 | ||
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h index d80477415caa..a0bacf581b32 100644 --- a/drivers/video/msm/mdp_hw.h +++ b/drivers/video/msm/mdp_hw.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #define _MDP_HW_H_ | 16 | #define _MDP_HW_H_ |
17 | 17 | ||
18 | #include <mach/msm_iomap.h> | 18 | #include <mach/msm_iomap.h> |
19 | #include <mach/msm_fb.h> | 19 | #include <linux/platform_data/video-msm_fb.h> |
20 | 20 | ||
21 | struct mdp_info { | 21 | struct mdp_info { |
22 | struct mdp_device mdp_dev; | 22 | struct mdp_device mdp_dev; |
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c index 2b6564e8bfea..be6079cdfbb6 100644 --- a/drivers/video/msm/mdp_ppp.c +++ b/drivers/video/msm/mdp_ppp.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <linux/file.h> | 16 | #include <linux/file.h> |
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/msm_mdp.h> | 18 | #include <linux/msm_mdp.h> |
19 | #include <mach/msm_fb.h> | 19 | #include <linux/platform_data/video-msm_fb.h> |
20 | 20 | ||
21 | #include "mdp_hw.h" | 21 | #include "mdp_hw.h" |
22 | #include "mdp_scale_tables.h" | 22 | #include "mdp_scale_tables.h" |
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c index c6e3b4fcdd68..ec08a9ec377d 100644 --- a/drivers/video/msm/msm_fb.c +++ b/drivers/video/msm/msm_fb.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/msm_mdp.h> | 25 | #include <linux/msm_mdp.h> |
26 | #include <linux/io.h> | 26 | #include <linux/io.h> |
27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <mach/msm_fb.h> | 28 | #include <linux/platform_data/video-msm_fb.h> |
29 | #include <mach/board.h> | 29 | #include <mach/board.h> |
30 | #include <linux/workqueue.h> | 30 | #include <linux/workqueue.h> |
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index c89f8a8d36d2..d7381088a180 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c | |||
@@ -27,10 +27,10 @@ | |||
27 | #include <linux/clk.h> | 27 | #include <linux/clk.h> |
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | 29 | ||
30 | #include <mach/dma.h> | 30 | #include <linux/platform_data/dma-imx.h> |
31 | #include <mach/hardware.h> | 31 | #include <mach/hardware.h> |
32 | #include <mach/ipu.h> | 32 | #include <mach/ipu.h> |
33 | #include <mach/mx3fb.h> | 33 | #include <linux/platform_data/video-mx3fb.h> |
34 | 34 | ||
35 | #include <asm/io.h> | 35 | #include <asm/io.h> |
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c index e10f551ade21..93387555337e 100644 --- a/drivers/video/nuc900fb.c +++ b/drivers/video/nuc900fb.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <mach/map.h> | 38 | #include <mach/map.h> |
39 | #include <mach/regs-clock.h> | 39 | #include <mach/regs-clock.h> |
40 | #include <mach/regs-ldm.h> | 40 | #include <mach/regs-ldm.h> |
41 | #include <mach/fb.h> | 41 | #include <linux/platform_data/video-nuc900fb.h> |
42 | 42 | ||
43 | #include "nuc900fb.h" | 43 | #include "nuc900fb.h" |
44 | 44 | ||
diff --git a/drivers/video/nuc900fb.h b/drivers/video/nuc900fb.h index bc7c9300f276..9a1ca6dbb6b2 100644 --- a/drivers/video/nuc900fb.h +++ b/drivers/video/nuc900fb.h | |||
@@ -16,7 +16,7 @@ | |||
16 | #define __NUC900FB_H | 16 | #define __NUC900FB_H |
17 | 17 | ||
18 | #include <mach/map.h> | 18 | #include <mach/map.h> |
19 | #include <mach/fb.h> | 19 | #include <linux/platform_data/video-nuc900fb.h> |
20 | 20 | ||
21 | enum nuc900_lcddrv_type { | 21 | enum nuc900_lcddrv_type { |
22 | LCDDRV_NUC910, | 22 | LCDDRV_NUC910, |
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c index d3a311327227..ed4cad87fbcd 100644 --- a/drivers/video/omap/lcd_ams_delta.c +++ b/drivers/video/omap/lcd_ams_delta.c | |||
@@ -27,8 +27,7 @@ | |||
27 | #include <linux/lcd.h> | 27 | #include <linux/lcd.h> |
28 | #include <linux/gpio.h> | 28 | #include <linux/gpio.h> |
29 | 29 | ||
30 | #include <plat/board-ams-delta.h> | 30 | #include <mach/board-ams-delta.h> |
31 | #include <mach/hardware.h> | ||
32 | 31 | ||
33 | #include "omapfb.h" | 32 | #include "omapfb.h" |
34 | 33 | ||
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c index e3880c4a0bb1..b739600c51ac 100644 --- a/drivers/video/omap/lcd_mipid.c +++ b/drivers/video/omap/lcd_mipid.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/spi/spi.h> | 25 | #include <linux/spi/spi.h> |
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | 27 | ||
28 | #include <plat/lcd_mipid.h> | 28 | #include <linux/platform_data/lcd-mipid.h> |
29 | 29 | ||
30 | #include "omapfb.h" | 30 | #include "omapfb.h" |
31 | 31 | ||
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c index 5914220dfa9c..3aa62da89195 100644 --- a/drivers/video/omap/lcd_osk.c +++ b/drivers/video/omap/lcd_osk.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | 25 | ||
26 | #include <asm/gpio.h> | 26 | #include <asm/gpio.h> |
27 | #include <plat/mux.h> | 27 | #include <mach/mux.h> |
28 | #include "omapfb.h" | 28 | #include "omapfb.h" |
29 | 29 | ||
30 | static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) | 30 | static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) |
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index 5b289c5f695b..ee9e29639dcc 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | #include <linux/pm_runtime.h> | 38 | #include <linux/pm_runtime.h> |
39 | 39 | ||
40 | #include <plat/cpu.h> | ||
40 | #include <plat/clock.h> | 41 | #include <plat/clock.h> |
41 | 42 | ||
42 | #include <video/omapdss.h> | 43 | #include <video/omapdss.h> |
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index fc671d3d8004..3c39aa8de928 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/omapfb.h> | 31 | #include <linux/omapfb.h> |
32 | 32 | ||
33 | #include <video/omapdss.h> | 33 | #include <video/omapdss.h> |
34 | #include <plat/cpu.h> | ||
34 | #include <plat/vram.h> | 35 | #include <plat/vram.h> |
35 | #include <plat/vrfb.h> | 36 | #include <plat/vrfb.h> |
36 | 37 | ||
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 3f902557690e..4fa2ad43fd97 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -61,7 +61,7 @@ | |||
61 | #include <asm/irq.h> | 61 | #include <asm/irq.h> |
62 | #include <asm/div64.h> | 62 | #include <asm/div64.h> |
63 | #include <mach/bitfield.h> | 63 | #include <mach/bitfield.h> |
64 | #include <mach/pxafb.h> | 64 | #include <linux/platform_data/video-pxafb.h> |
65 | 65 | ||
66 | /* | 66 | /* |
67 | * Complain if VAR is out of range. | 67 | * Complain if VAR is out of range. |
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c index 2a5fe6ede845..66a74f9073fb 100644 --- a/drivers/video/vt8500lcdfb.c +++ b/drivers/video/vt8500lcdfb.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/wait.h> | 31 | #include <linux/wait.h> |
32 | 32 | ||
33 | #include <mach/vt8500fb.h> | 33 | #include <linux/platform_data/video-vt8500lcdfb.h> |
34 | 34 | ||
35 | #include "vt8500lcdfb.h" | 35 | #include "vt8500lcdfb.h" |
36 | #include "wmt_ge_rops.h" | 36 | #include "wmt_ge_rops.h" |
diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c index c8703bd61b74..ffeff4838120 100644 --- a/drivers/video/wm8505fb.c +++ b/drivers/video/wm8505fb.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/wait.h> | 30 | #include <linux/wait.h> |
31 | 31 | ||
32 | #include <mach/vt8500fb.h> | 32 | #include <linux/platform_data/video-vt8500lcdfb.h> |
33 | 33 | ||
34 | #include "wm8505fb_regs.h" | 34 | #include "wm8505fb_regs.h" |
35 | #include "wmt_ge_rops.h" | 35 | #include "wmt_ge_rops.h" |
diff --git a/drivers/w1/masters/omap_hdq.c b/drivers/w1/masters/omap_hdq.c index 4b0fcf3c2d03..fee195a76941 100644 --- a/drivers/w1/masters/omap_hdq.c +++ b/drivers/w1/masters/omap_hdq.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/pm_runtime.h> | 19 | #include <linux/pm_runtime.h> |
20 | 20 | ||
21 | #include <asm/irq.h> | 21 | #include <asm/irq.h> |
22 | #include <mach/hardware.h> | ||
23 | 22 | ||
24 | #include "../w1.h" | 23 | #include "../w1.h" |
25 | #include "../w1_int.h" | 24 | #include "../w1_int.h" |
@@ -644,7 +643,7 @@ static int omap_hdq_remove(struct platform_device *pdev) | |||
644 | 643 | ||
645 | /* remove module dependency */ | 644 | /* remove module dependency */ |
646 | pm_runtime_disable(&pdev->dev); | 645 | pm_runtime_disable(&pdev->dev); |
647 | free_irq(INT_24XX_HDQ_IRQ, hdq_data); | 646 | free_irq(platform_get_irq(pdev, 0), hdq_data); |
648 | platform_set_drvdata(pdev, NULL); | 647 | platform_set_drvdata(pdev, NULL); |
649 | iounmap(hdq_data->hdq_base); | 648 | iounmap(hdq_data->hdq_base); |
650 | kfree(hdq_data); | 649 | kfree(hdq_data); |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 53d75719078e..ad1bb9382a96 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -237,12 +237,12 @@ config OMAP_WATCHDOG | |||
237 | here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer. | 237 | here to enable the OMAP1610/OMAP1710/OMAP2420/OMAP3430/OMAP4430 watchdog timer. |
238 | 238 | ||
239 | config PNX4008_WATCHDOG | 239 | config PNX4008_WATCHDOG |
240 | tristate "PNX4008 and LPC32XX Watchdog" | 240 | tristate "LPC32XX Watchdog" |
241 | depends on ARCH_PNX4008 || ARCH_LPC32XX | 241 | depends on ARCH_LPC32XX |
242 | select WATCHDOG_CORE | 242 | select WATCHDOG_CORE |
243 | help | 243 | help |
244 | Say Y here if to include support for the watchdog timer | 244 | Say Y here if to include support for the watchdog timer |
245 | in the PNX4008 or LPC32XX processor. | 245 | in the LPC32XX processor. |
246 | This driver can be built as a module by choosing M. The module | 246 | This driver can be built as a module by choosing M. The module |
247 | will be called pnx4008_wdt. | 247 | will be called pnx4008_wdt. |
248 | 248 | ||
diff --git a/drivers/watchdog/ks8695_wdt.c b/drivers/watchdog/ks8695_wdt.c index 59e75d9a6b7f..c1a4d3bf581d 100644 --- a/drivers/watchdog/ks8695_wdt.c +++ b/drivers/watchdog/ks8695_wdt.c | |||
@@ -24,7 +24,19 @@ | |||
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/uaccess.h> | 25 | #include <linux/uaccess.h> |
26 | #include <mach/hardware.h> | 26 | #include <mach/hardware.h> |
27 | #include <mach/regs-timer.h> | 27 | |
28 | #define KS8695_TMR_OFFSET (0xF0000 + 0xE400) | ||
29 | #define KS8695_TMR_VA (KS8695_IO_VA + KS8695_TMR_OFFSET) | ||
30 | |||
31 | /* | ||
32 | * Timer registers | ||
33 | */ | ||
34 | #define KS8695_TMCON (0x00) /* Timer Control Register */ | ||
35 | #define KS8695_T0TC (0x08) /* Timer 0 Timeout Count Register */ | ||
36 | #define TMCON_T0EN (1 << 0) /* Timer 0 Enable */ | ||
37 | |||
38 | /* Timer0 Timeout Counter Register */ | ||
39 | #define T0TC_WATCHDOG (0xff) /* Enable watchdog mode */ | ||
28 | 40 | ||
29 | #define WDT_DEFAULT_TIME 5 /* seconds */ | 41 | #define WDT_DEFAULT_TIME 5 /* seconds */ |
30 | #define WDT_MAX_TIME 171 /* seconds */ | 42 | #define WDT_MAX_TIME 171 /* seconds */ |
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index fceec4f4eb7e..f5db18dbc0f9 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c | |||
@@ -46,6 +46,7 @@ | |||
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/pm_runtime.h> | 47 | #include <linux/pm_runtime.h> |
48 | #include <mach/hardware.h> | 48 | #include <mach/hardware.h> |
49 | #include <plat/cpu.h> | ||
49 | #include <plat/prcm.h> | 50 | #include <plat/prcm.h> |
50 | 51 | ||
51 | #include "omap_wdt.h" | 52 | #include "omap_wdt.h" |
@@ -218,12 +219,16 @@ static long omap_wdt_ioctl(struct file *file, unsigned int cmd, | |||
218 | case WDIOC_GETSTATUS: | 219 | case WDIOC_GETSTATUS: |
219 | return put_user(0, (int __user *)arg); | 220 | return put_user(0, (int __user *)arg); |
220 | case WDIOC_GETBOOTSTATUS: | 221 | case WDIOC_GETBOOTSTATUS: |
222 | #ifdef CONFIG_ARCH_OMAP1 | ||
221 | if (cpu_is_omap16xx()) | 223 | if (cpu_is_omap16xx()) |
222 | return put_user(__raw_readw(ARM_SYSST), | 224 | return put_user(__raw_readw(ARM_SYSST), |
223 | (int __user *)arg); | 225 | (int __user *)arg); |
226 | #endif | ||
227 | #ifdef CONFIG_ARCH_OMAP2PLUS | ||
224 | if (cpu_is_omap24xx()) | 228 | if (cpu_is_omap24xx()) |
225 | return put_user(omap_prcm_get_reset_sources(), | 229 | return put_user(omap_prcm_get_reset_sources(), |
226 | (int __user *)arg); | 230 | (int __user *)arg); |
231 | #endif | ||
227 | return put_user(0, (int __user *)arg); | 232 | return put_user(0, (int __user *)arg); |
228 | case WDIOC_KEEPALIVE: | 233 | case WDIOC_KEEPALIVE: |
229 | spin_lock(&wdt_lock); | 234 | spin_lock(&wdt_lock); |