diff options
Diffstat (limited to 'drivers')
49 files changed, 900 insertions, 1024 deletions
diff --git a/drivers/acorn/block/fd1772.c b/drivers/acorn/block/fd1772.c index 3cd2e968e96c..c0a37d98b4f3 100644 --- a/drivers/acorn/block/fd1772.c +++ b/drivers/acorn/block/fd1772.c | |||
| @@ -1283,8 +1283,7 @@ static void do_fd_request(request_queue_t* q) | |||
| 1283 | if (fdc_busy) return; | 1283 | if (fdc_busy) return; |
| 1284 | save_flags(flags); | 1284 | save_flags(flags); |
| 1285 | cli(); | 1285 | cli(); |
| 1286 | while (fdc_busy) | 1286 | wait_event(fdc_wait, !fdc_busy); |
| 1287 | sleep_on(&fdc_wait); | ||
| 1288 | fdc_busy = 1; | 1287 | fdc_busy = 1; |
| 1289 | ENABLE_IRQ(); | 1288 | ENABLE_IRQ(); |
| 1290 | restore_flags(flags); | 1289 | restore_flags(flags); |
diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 692a5fced76e..3c818544475e 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c | |||
| @@ -719,7 +719,7 @@ struct request *blk_queue_find_tag(request_queue_t *q, int tag) | |||
| 719 | { | 719 | { |
| 720 | struct blk_queue_tag *bqt = q->queue_tags; | 720 | struct blk_queue_tag *bqt = q->queue_tags; |
| 721 | 721 | ||
| 722 | if (unlikely(bqt == NULL || tag >= bqt->max_depth)) | 722 | if (unlikely(bqt == NULL || tag >= bqt->real_max_depth)) |
| 723 | return NULL; | 723 | return NULL; |
| 724 | 724 | ||
| 725 | return bqt->tag_index[tag]; | 725 | return bqt->tag_index[tag]; |
| @@ -798,6 +798,7 @@ init_tag_map(request_queue_t *q, struct blk_queue_tag *tags, int depth) | |||
| 798 | 798 | ||
| 799 | memset(tag_index, 0, depth * sizeof(struct request *)); | 799 | memset(tag_index, 0, depth * sizeof(struct request *)); |
| 800 | memset(tag_map, 0, nr_ulongs * sizeof(unsigned long)); | 800 | memset(tag_map, 0, nr_ulongs * sizeof(unsigned long)); |
| 801 | tags->real_max_depth = depth; | ||
| 801 | tags->max_depth = depth; | 802 | tags->max_depth = depth; |
| 802 | tags->tag_index = tag_index; | 803 | tags->tag_index = tag_index; |
| 803 | tags->tag_map = tag_map; | 804 | tags->tag_map = tag_map; |
| @@ -872,11 +873,22 @@ int blk_queue_resize_tags(request_queue_t *q, int new_depth) | |||
| 872 | return -ENXIO; | 873 | return -ENXIO; |
| 873 | 874 | ||
| 874 | /* | 875 | /* |
| 876 | * if we already have large enough real_max_depth. just | ||
| 877 | * adjust max_depth. *NOTE* as requests with tag value | ||
| 878 | * between new_depth and real_max_depth can be in-flight, tag | ||
| 879 | * map can not be shrunk blindly here. | ||
| 880 | */ | ||
| 881 | if (new_depth <= bqt->real_max_depth) { | ||
| 882 | bqt->max_depth = new_depth; | ||
| 883 | return 0; | ||
| 884 | } | ||
| 885 | |||
| 886 | /* | ||
| 875 | * save the old state info, so we can copy it back | 887 | * save the old state info, so we can copy it back |
| 876 | */ | 888 | */ |
| 877 | tag_index = bqt->tag_index; | 889 | tag_index = bqt->tag_index; |
| 878 | tag_map = bqt->tag_map; | 890 | tag_map = bqt->tag_map; |
| 879 | max_depth = bqt->max_depth; | 891 | max_depth = bqt->real_max_depth; |
| 880 | 892 | ||
| 881 | if (init_tag_map(q, bqt, new_depth)) | 893 | if (init_tag_map(q, bqt, new_depth)) |
| 882 | return -ENOMEM; | 894 | return -ENOMEM; |
| @@ -913,7 +925,7 @@ void blk_queue_end_tag(request_queue_t *q, struct request *rq) | |||
| 913 | 925 | ||
| 914 | BUG_ON(tag == -1); | 926 | BUG_ON(tag == -1); |
| 915 | 927 | ||
| 916 | if (unlikely(tag >= bqt->max_depth)) | 928 | if (unlikely(tag >= bqt->real_max_depth)) |
| 917 | /* | 929 | /* |
| 918 | * This can happen after tag depth has been reduced. | 930 | * This can happen after tag depth has been reduced. |
| 919 | * FIXME: how about a warning or info message here? | 931 | * FIXME: how about a warning or info message here? |
diff --git a/drivers/bluetooth/bpa10x.c b/drivers/bluetooth/bpa10x.c index 2771c861f185..f696da6f417b 100644 --- a/drivers/bluetooth/bpa10x.c +++ b/drivers/bluetooth/bpa10x.c | |||
| @@ -367,11 +367,8 @@ static inline void bpa10x_free_urb(struct urb *urb) | |||
| 367 | if (!urb) | 367 | if (!urb) |
| 368 | return; | 368 | return; |
| 369 | 369 | ||
| 370 | if (urb->setup_packet) | 370 | kfree(urb->setup_packet); |
| 371 | kfree(urb->setup_packet); | 371 | kfree(urb->transfer_buffer); |
| 372 | |||
| 373 | if (urb->transfer_buffer) | ||
| 374 | kfree(urb->transfer_buffer); | ||
| 375 | 372 | ||
| 376 | usb_free_urb(urb); | 373 | usb_free_urb(urb); |
| 377 | } | 374 | } |
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index c0ed213fc857..858fddb046de 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c | |||
| @@ -58,8 +58,6 @@ | |||
| 58 | #ifndef CONFIG_BT_HCIUART_DEBUG | 58 | #ifndef CONFIG_BT_HCIUART_DEBUG |
| 59 | #undef BT_DBG | 59 | #undef BT_DBG |
| 60 | #define BT_DBG( A... ) | 60 | #define BT_DBG( A... ) |
| 61 | #undef BT_DMP | ||
| 62 | #define BT_DMP( A... ) | ||
| 63 | #endif | 61 | #endif |
| 64 | 62 | ||
| 65 | static int hciextn = 1; | 63 | static int hciextn = 1; |
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index ade94a57bb11..533323b60e63 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c | |||
| @@ -57,8 +57,6 @@ | |||
| 57 | #ifndef CONFIG_BT_HCIUART_DEBUG | 57 | #ifndef CONFIG_BT_HCIUART_DEBUG |
| 58 | #undef BT_DBG | 58 | #undef BT_DBG |
| 59 | #define BT_DBG( A... ) | 59 | #define BT_DBG( A... ) |
| 60 | #undef BT_DMP | ||
| 61 | #define BT_DMP( A... ) | ||
| 62 | #endif | 60 | #endif |
| 63 | 61 | ||
| 64 | /* Initialize protocol */ | 62 | /* Initialize protocol */ |
| @@ -125,7 +123,6 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len) | |||
| 125 | 123 | ||
| 126 | BT_DBG("len %d room %d", len, room); | 124 | BT_DBG("len %d room %d", len, room); |
| 127 | if (!len) { | 125 | if (!len) { |
| 128 | BT_DMP(h4->rx_skb->data, h4->rx_skb->len); | ||
| 129 | hci_recv_frame(h4->rx_skb); | 126 | hci_recv_frame(h4->rx_skb); |
| 130 | } else if (len > room) { | 127 | } else if (len > room) { |
| 131 | BT_ERR("Data length is too large"); | 128 | BT_ERR("Data length is too large"); |
| @@ -169,8 +166,6 @@ static int h4_recv(struct hci_uart *hu, void *data, int count) | |||
| 169 | case H4_W4_DATA: | 166 | case H4_W4_DATA: |
| 170 | BT_DBG("Complete data"); | 167 | BT_DBG("Complete data"); |
| 171 | 168 | ||
| 172 | BT_DMP(h4->rx_skb->data, h4->rx_skb->len); | ||
| 173 | |||
| 174 | hci_recv_frame(h4->rx_skb); | 169 | hci_recv_frame(h4->rx_skb); |
| 175 | 170 | ||
| 176 | h4->rx_state = H4_W4_PACKET_TYPE; | 171 | h4->rx_state = H4_W4_PACKET_TYPE; |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index f766bc22c6bb..90be2eae52e0 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
| @@ -57,8 +57,6 @@ | |||
| 57 | #ifndef CONFIG_BT_HCIUART_DEBUG | 57 | #ifndef CONFIG_BT_HCIUART_DEBUG |
| 58 | #undef BT_DBG | 58 | #undef BT_DBG |
| 59 | #define BT_DBG( A... ) | 59 | #define BT_DBG( A... ) |
| 60 | #undef BT_DMP | ||
| 61 | #define BT_DMP( A... ) | ||
| 62 | #endif | 60 | #endif |
| 63 | 61 | ||
| 64 | static int reset = 0; | 62 | static int reset = 0; |
diff --git a/drivers/bluetooth/hci_usb.c b/drivers/bluetooth/hci_usb.c index b120ecf7b8c9..657719b8254f 100644 --- a/drivers/bluetooth/hci_usb.c +++ b/drivers/bluetooth/hci_usb.c | |||
| @@ -57,8 +57,6 @@ | |||
| 57 | #ifndef CONFIG_BT_HCIUSB_DEBUG | 57 | #ifndef CONFIG_BT_HCIUSB_DEBUG |
| 58 | #undef BT_DBG | 58 | #undef BT_DBG |
| 59 | #define BT_DBG(D...) | 59 | #define BT_DBG(D...) |
| 60 | #undef BT_DMP | ||
| 61 | #define BT_DMP(D...) | ||
| 62 | #endif | 60 | #endif |
| 63 | 61 | ||
| 64 | #ifndef CONFIG_BT_HCIUSB_ZERO_PACKET | 62 | #ifndef CONFIG_BT_HCIUSB_ZERO_PACKET |
| @@ -110,6 +108,9 @@ static struct usb_device_id blacklist_ids[] = { | |||
| 110 | /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ | 108 | /* Microsoft Wireless Transceiver for Bluetooth 2.0 */ |
| 111 | { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, | 109 | { USB_DEVICE(0x045e, 0x009c), .driver_info = HCI_RESET }, |
| 112 | 110 | ||
| 111 | /* Kensington Bluetooth USB adapter */ | ||
| 112 | { USB_DEVICE(0x047d, 0x105d), .driver_info = HCI_RESET }, | ||
| 113 | |||
| 113 | /* ISSC Bluetooth Adapter v3.1 */ | 114 | /* ISSC Bluetooth Adapter v3.1 */ |
| 114 | { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, | 115 | { USB_DEVICE(0x1131, 0x1001), .driver_info = HCI_RESET }, |
| 115 | 116 | ||
| @@ -387,10 +388,8 @@ static void hci_usb_unlink_urbs(struct hci_usb *husb) | |||
| 387 | urb = &_urb->urb; | 388 | urb = &_urb->urb; |
| 388 | BT_DBG("%s freeing _urb %p type %d urb %p", | 389 | BT_DBG("%s freeing _urb %p type %d urb %p", |
| 389 | husb->hdev->name, _urb, _urb->type, urb); | 390 | husb->hdev->name, _urb, _urb->type, urb); |
| 390 | if (urb->setup_packet) | 391 | kfree(urb->setup_packet); |
| 391 | kfree(urb->setup_packet); | 392 | kfree(urb->transfer_buffer); |
| 392 | if (urb->transfer_buffer) | ||
| 393 | kfree(urb->transfer_buffer); | ||
| 394 | _urb_free(_urb); | 393 | _urb_free(_urb); |
| 395 | } | 394 | } |
| 396 | 395 | ||
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index d8f9e94ae475..cd4fe8b1709f 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c | |||
| @@ -1209,6 +1209,7 @@ static int rtc_proc_open(struct inode *inode, struct file *file) | |||
| 1209 | 1209 | ||
| 1210 | void rtc_get_rtc_time(struct rtc_time *rtc_tm) | 1210 | void rtc_get_rtc_time(struct rtc_time *rtc_tm) |
| 1211 | { | 1211 | { |
| 1212 | unsigned long uip_watchdog = jiffies; | ||
| 1212 | unsigned char ctrl; | 1213 | unsigned char ctrl; |
| 1213 | #ifdef CONFIG_MACH_DECSTATION | 1214 | #ifdef CONFIG_MACH_DECSTATION |
| 1214 | unsigned int real_year; | 1215 | unsigned int real_year; |
| @@ -1224,8 +1225,10 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) | |||
| 1224 | * Once the read clears, read the RTC time (again via ioctl). Easy. | 1225 | * Once the read clears, read the RTC time (again via ioctl). Easy. |
| 1225 | */ | 1226 | */ |
| 1226 | 1227 | ||
| 1227 | if (rtc_is_updating() != 0) | 1228 | while (rtc_is_updating() != 0 && jiffies - uip_watchdog < 2*HZ/100) { |
| 1228 | msleep(20); | 1229 | barrier(); |
| 1230 | cpu_relax(); | ||
| 1231 | } | ||
| 1229 | 1232 | ||
| 1230 | /* | 1233 | /* |
| 1231 | * Only the values that we read from the RTC are set. We leave | 1234 | * Only the values that we read from the RTC are set. We leave |
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 94a3b3e20bf9..79e9832ef1f3 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig | |||
| @@ -17,6 +17,8 @@ config TCG_TPM | |||
| 17 | obtained at: <http://sourceforge.net/projects/trousers>. To | 17 | obtained at: <http://sourceforge.net/projects/trousers>. To |
| 18 | compile this driver as a module, choose M here; the module | 18 | compile this driver as a module, choose M here; the module |
| 19 | will be called tpm. If unsure, say N. | 19 | will be called tpm. If unsure, say N. |
| 20 | Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI_BUS | ||
| 21 | and CONFIG_PNPACPI. | ||
| 20 | 22 | ||
| 21 | config TCG_NSC | 23 | config TCG_NSC |
| 22 | tristate "National Semiconductor TPM Interface" | 24 | tristate "National Semiconductor TPM Interface" |
| @@ -36,12 +38,13 @@ config TCG_ATMEL | |||
| 36 | as a module, choose M here; the module will be called tpm_atmel. | 38 | as a module, choose M here; the module will be called tpm_atmel. |
| 37 | 39 | ||
| 38 | config TCG_INFINEON | 40 | config TCG_INFINEON |
| 39 | tristate "Infineon Technologies SLD 9630 TPM Interface" | 41 | tristate "Infineon Technologies TPM Interface" |
| 40 | depends on TCG_TPM | 42 | depends on TCG_TPM && PNPACPI |
| 41 | ---help--- | 43 | ---help--- |
| 42 | If you have a TPM security chip from Infineon Technologies | 44 | If you have a TPM security chip from Infineon Technologies |
| 43 | say Yes and it will be accessible from within Linux. To | 45 | (either SLD 9630 TT 1.1 or SLB 9635 TT 1.2) say Yes and it |
| 44 | compile this driver as a module, choose M here; the module | 46 | will be accessible from within Linux. |
| 47 | To compile this driver as a module, choose M here; the module | ||
| 45 | will be called tpm_infineon. | 48 | will be called tpm_infineon. |
| 46 | Further information on this driver and the supported hardware | 49 | Further information on this driver and the supported hardware |
| 47 | can be found at http://www.prosec.rub.de/tpm | 50 | can be found at http://www.prosec.rub.de/tpm |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 0e3241645c19..dc8c540391fd 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Description: | 2 | * Description: |
| 3 | * Device Driver for the Infineon Technologies | 3 | * Device Driver for the Infineon Technologies |
| 4 | * SLD 9630 TT Trusted Platform Module | 4 | * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module |
| 5 | * Specifications at www.trustedcomputinggroup.org | 5 | * Specifications at www.trustedcomputinggroup.org |
| 6 | * | 6 | * |
| 7 | * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> | 7 | * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> |
| @@ -12,9 +12,10 @@ | |||
| 12 | * modify it under the terms of the GNU General Public License as | 12 | * modify it under the terms of the GNU General Public License as |
| 13 | * published by the Free Software Foundation, version 2 of the | 13 | * published by the Free Software Foundation, version 2 of the |
| 14 | * License. | 14 | * License. |
| 15 | * | ||
| 16 | */ | 15 | */ |
| 17 | 16 | ||
| 17 | #include <acpi/acpi_bus.h> | ||
| 18 | #include <linux/pnp.h> | ||
| 18 | #include "tpm.h" | 19 | #include "tpm.h" |
| 19 | 20 | ||
| 20 | /* Infineon specific definitions */ | 21 | /* Infineon specific definitions */ |
| @@ -26,8 +27,11 @@ | |||
| 26 | #define TPM_MSLEEP_TIME 3 | 27 | #define TPM_MSLEEP_TIME 3 |
| 27 | /* gives number of max. msleep()-calls before throwing timeout */ | 28 | /* gives number of max. msleep()-calls before throwing timeout */ |
| 28 | #define TPM_MAX_TRIES 5000 | 29 | #define TPM_MAX_TRIES 5000 |
| 29 | #define TCPA_INFINEON_DEV_VEN_VALUE 0x15D1 | 30 | #define TPM_INFINEON_DEV_VEN_VALUE 0x15D1 |
| 30 | #define TPM_DATA (TPM_ADDR + 1) & 0xff | 31 | |
| 32 | /* These values will be filled after ACPI-call */ | ||
| 33 | static int TPM_INF_DATA = 0; | ||
| 34 | static int TPM_INF_ADDR = 0; | ||
| 31 | 35 | ||
| 32 | /* TPM header definitions */ | 36 | /* TPM header definitions */ |
| 33 | enum infineon_tpm_header { | 37 | enum infineon_tpm_header { |
| @@ -305,9 +309,10 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
| 305 | 309 | ||
| 306 | static void tpm_inf_cancel(struct tpm_chip *chip) | 310 | static void tpm_inf_cancel(struct tpm_chip *chip) |
| 307 | { | 311 | { |
| 308 | /* Nothing yet! | 312 | /* |
| 309 | This has something to do with the internal functions | 313 | Since we are using the legacy mode to communicate |
| 310 | of the TPM. Abort isn't really necessary... | 314 | with the TPM, we have no cancel functions, but have |
| 315 | a workaround for interrupting the TPM through WTX. | ||
| 311 | */ | 316 | */ |
| 312 | } | 317 | } |
| 313 | 318 | ||
| @@ -345,6 +350,32 @@ static struct tpm_vendor_specific tpm_inf = { | |||
| 345 | .miscdev = {.fops = &inf_ops,}, | 350 | .miscdev = {.fops = &inf_ops,}, |
| 346 | }; | 351 | }; |
| 347 | 352 | ||
| 353 | static const struct pnp_device_id tpm_pnp_tbl[] = { | ||
| 354 | /* Infineon TPMs */ | ||
| 355 | {"IFX0101", 0}, | ||
| 356 | {"IFX0102", 0}, | ||
| 357 | {"", 0} | ||
| 358 | }; | ||
| 359 | |||
| 360 | static int __devinit tpm_inf_acpi_probe(struct pnp_dev *dev, | ||
| 361 | const struct pnp_device_id *dev_id) | ||
| 362 | { | ||
| 363 | TPM_INF_ADDR = (pnp_port_start(dev, 0) & 0xff); | ||
| 364 | TPM_INF_DATA = ((TPM_INF_ADDR + 1) & 0xff); | ||
| 365 | tpm_inf.base = pnp_port_start(dev, 1); | ||
| 366 | dev_info(&dev->dev, "Found %s with ID %s\n", | ||
| 367 | dev->name, dev_id->id); | ||
| 368 | if (!((tpm_inf.base >> 8) & 0xff)) | ||
| 369 | tpm_inf.base = 0; | ||
| 370 | return 0; | ||
| 371 | } | ||
| 372 | |||
| 373 | static struct pnp_driver tpm_inf_pnp = { | ||
| 374 | .name = "tpm_inf_pnp", | ||
| 375 | .id_table = tpm_pnp_tbl, | ||
| 376 | .probe = tpm_inf_acpi_probe, | ||
| 377 | }; | ||
| 378 | |||
| 348 | static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | 379 | static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, |
| 349 | const struct pci_device_id *pci_id) | 380 | const struct pci_device_id *pci_id) |
| 350 | { | 381 | { |
| @@ -353,64 +384,99 @@ static int __devinit tpm_inf_probe(struct pci_dev *pci_dev, | |||
| 353 | int vendorid[2]; | 384 | int vendorid[2]; |
| 354 | int version[2]; | 385 | int version[2]; |
| 355 | int productid[2]; | 386 | int productid[2]; |
| 387 | char chipname[20]; | ||
| 356 | 388 | ||
| 357 | if (pci_enable_device(pci_dev)) | 389 | if (pci_enable_device(pci_dev)) |
| 358 | return -EIO; | 390 | return -EIO; |
| 359 | 391 | ||
| 360 | dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); | 392 | dev_info(&pci_dev->dev, "LPC-bus found at 0x%x\n", pci_id->device); |
| 361 | 393 | ||
| 394 | /* read IO-ports from ACPI */ | ||
| 395 | pnp_register_driver(&tpm_inf_pnp); | ||
| 396 | pnp_unregister_driver(&tpm_inf_pnp); | ||
| 397 | |||
| 398 | /* Make sure, we have received valid config ports */ | ||
| 399 | if (!TPM_INF_ADDR) { | ||
| 400 | pci_disable_device(pci_dev); | ||
| 401 | return -EIO; | ||
| 402 | } | ||
| 403 | |||
| 362 | /* query chip for its vendor, its version number a.s.o. */ | 404 | /* query chip for its vendor, its version number a.s.o. */ |
| 363 | outb(ENABLE_REGISTER_PAIR, TPM_ADDR); | 405 | outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR); |
| 364 | outb(IDVENL, TPM_ADDR); | 406 | outb(IDVENL, TPM_INF_ADDR); |
| 365 | vendorid[1] = inb(TPM_DATA); | 407 | vendorid[1] = inb(TPM_INF_DATA); |
| 366 | outb(IDVENH, TPM_ADDR); | 408 | outb(IDVENH, TPM_INF_ADDR); |
| 367 | vendorid[0] = inb(TPM_DATA); | 409 | vendorid[0] = inb(TPM_INF_DATA); |
| 368 | outb(IDPDL, TPM_ADDR); | 410 | outb(IDPDL, TPM_INF_ADDR); |
| 369 | productid[1] = inb(TPM_DATA); | 411 | productid[1] = inb(TPM_INF_DATA); |
| 370 | outb(IDPDH, TPM_ADDR); | 412 | outb(IDPDH, TPM_INF_ADDR); |
| 371 | productid[0] = inb(TPM_DATA); | 413 | productid[0] = inb(TPM_INF_DATA); |
| 372 | outb(CHIP_ID1, TPM_ADDR); | 414 | outb(CHIP_ID1, TPM_INF_ADDR); |
| 373 | version[1] = inb(TPM_DATA); | 415 | version[1] = inb(TPM_INF_DATA); |
| 374 | outb(CHIP_ID2, TPM_ADDR); | 416 | outb(CHIP_ID2, TPM_INF_ADDR); |
| 375 | version[0] = inb(TPM_DATA); | 417 | version[0] = inb(TPM_INF_DATA); |
| 376 | 418 | ||
| 377 | if ((vendorid[0] << 8 | vendorid[1]) == (TCPA_INFINEON_DEV_VEN_VALUE)) { | 419 | switch ((productid[0] << 8) | productid[1]) { |
| 378 | 420 | case 6: | |
| 379 | /* read IO-ports from TPM */ | 421 | sprintf(chipname, " (SLD 9630 TT 1.1)"); |
| 380 | outb(IOLIMH, TPM_ADDR); | 422 | break; |
| 381 | ioh = inb(TPM_DATA); | 423 | case 11: |
| 382 | outb(IOLIML, TPM_ADDR); | 424 | sprintf(chipname, " (SLB 9635 TT 1.2)"); |
| 383 | iol = inb(TPM_DATA); | 425 | break; |
| 384 | tpm_inf.base = (ioh << 8) | iol; | 426 | default: |
| 427 | sprintf(chipname, " (unknown chip)"); | ||
| 428 | break; | ||
| 429 | } | ||
| 430 | chipname[19] = 0; | ||
| 431 | |||
| 432 | if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) { | ||
| 385 | 433 | ||
| 386 | if (tpm_inf.base == 0) { | 434 | if (tpm_inf.base == 0) { |
| 387 | dev_err(&pci_dev->dev, "No IO-ports set!\n"); | 435 | dev_err(&pci_dev->dev, "No IO-ports found!\n"); |
| 388 | pci_disable_device(pci_dev); | 436 | pci_disable_device(pci_dev); |
| 389 | return -ENODEV; | 437 | return -EIO; |
| 438 | } | ||
| 439 | /* configure TPM with IO-ports */ | ||
| 440 | outb(IOLIMH, TPM_INF_ADDR); | ||
| 441 | outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); | ||
| 442 | outb(IOLIML, TPM_INF_ADDR); | ||
| 443 | outb((tpm_inf.base & 0xff), TPM_INF_DATA); | ||
| 444 | |||
| 445 | /* control if IO-ports are set correctly */ | ||
| 446 | outb(IOLIMH, TPM_INF_ADDR); | ||
| 447 | ioh = inb(TPM_INF_DATA); | ||
| 448 | outb(IOLIML, TPM_INF_ADDR); | ||
| 449 | iol = inb(TPM_INF_DATA); | ||
| 450 | |||
| 451 | if ((ioh << 8 | iol) != tpm_inf.base) { | ||
| 452 | dev_err(&pci_dev->dev, | ||
| 453 | "Could not set IO-ports to %04x\n", | ||
| 454 | tpm_inf.base); | ||
| 455 | pci_disable_device(pci_dev); | ||
| 456 | return -EIO; | ||
| 390 | } | 457 | } |
| 391 | 458 | ||
| 392 | /* activate register */ | 459 | /* activate register */ |
| 393 | outb(TPM_DAR, TPM_ADDR); | 460 | outb(TPM_DAR, TPM_INF_ADDR); |
| 394 | outb(0x01, TPM_DATA); | 461 | outb(0x01, TPM_INF_DATA); |
| 395 | outb(DISABLE_REGISTER_PAIR, TPM_ADDR); | 462 | outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); |
| 396 | 463 | ||
| 397 | /* disable RESET, LP and IRQC */ | 464 | /* disable RESET, LP and IRQC */ |
| 398 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); | 465 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); |
| 399 | 466 | ||
| 400 | /* Finally, we're done, print some infos */ | 467 | /* Finally, we're done, print some infos */ |
| 401 | dev_info(&pci_dev->dev, "TPM found: " | 468 | dev_info(&pci_dev->dev, "TPM found: " |
| 469 | "config base 0x%x, " | ||
| 402 | "io base 0x%x, " | 470 | "io base 0x%x, " |
| 403 | "chip version %02x%02x, " | 471 | "chip version %02x%02x, " |
| 404 | "vendor id %x%x (Infineon), " | 472 | "vendor id %x%x (Infineon), " |
| 405 | "product id %02x%02x" | 473 | "product id %02x%02x" |
| 406 | "%s\n", | 474 | "%s\n", |
| 475 | TPM_INF_ADDR, | ||
| 407 | tpm_inf.base, | 476 | tpm_inf.base, |
| 408 | version[0], version[1], | 477 | version[0], version[1], |
| 409 | vendorid[0], vendorid[1], | 478 | vendorid[0], vendorid[1], |
| 410 | productid[0], productid[1], ((productid[0] == 0) | 479 | productid[0], productid[1], chipname); |
| 411 | && (productid[1] == | ||
| 412 | 6)) ? | ||
| 413 | " (SLD 9630 TT 1.1)" : ""); | ||
| 414 | 480 | ||
| 415 | rc = tpm_register_hardware(pci_dev, &tpm_inf); | 481 | rc = tpm_register_hardware(pci_dev, &tpm_inf); |
| 416 | if (rc < 0) { | 482 | if (rc < 0) { |
| @@ -462,6 +528,6 @@ module_init(init_inf); | |||
| 462 | module_exit(cleanup_inf); | 528 | module_exit(cleanup_inf); |
| 463 | 529 | ||
| 464 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 530 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
| 465 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT"); | 531 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
| 466 | MODULE_VERSION("1.4"); | 532 | MODULE_VERSION("1.5"); |
| 467 | MODULE_LICENSE("GPL"); | 533 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c index f975dab1ddf9..a13395e2c372 100644 --- a/drivers/char/watchdog/i8xx_tco.c +++ b/drivers/char/watchdog/i8xx_tco.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * i8xx_tco 0.07: TCO timer driver for i8xx chipsets | 2 | * i8xx_tco: TCO timer driver for i8xx chipsets |
| 3 | * | 3 | * |
| 4 | * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved. | 4 | * (c) Copyright 2000 kernel concepts <nils@kernelconcepts.de>, All Rights Reserved. |
| 5 | * http://www.kernelconcepts.de | 5 | * http://www.kernelconcepts.de |
| @@ -63,6 +63,9 @@ | |||
| 63 | * 20050128 Wim Van Sebroeck <wim@iguana.be> | 63 | * 20050128 Wim Van Sebroeck <wim@iguana.be> |
| 64 | * 0.07 Added support for the ICH4-M, ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW | 64 | * 0.07 Added support for the ICH4-M, ICH6, ICH6R, ICH6-M, ICH6W and ICH6RW |
| 65 | * chipsets. Also added support for the "undocumented" ICH7 chipset. | 65 | * chipsets. Also added support for the "undocumented" ICH7 chipset. |
| 66 | * 20050807 Wim Van Sebroeck <wim@iguana.be> | ||
| 67 | * 0.08 Make sure that the watchdog is only "armed" when started. | ||
| 68 | * (Kernel Bug 4251) | ||
| 66 | */ | 69 | */ |
| 67 | 70 | ||
| 68 | /* | 71 | /* |
| @@ -87,7 +90,7 @@ | |||
| 87 | #include "i8xx_tco.h" | 90 | #include "i8xx_tco.h" |
| 88 | 91 | ||
| 89 | /* Module and version information */ | 92 | /* Module and version information */ |
| 90 | #define TCO_VERSION "0.07" | 93 | #define TCO_VERSION "0.08" |
| 91 | #define TCO_MODULE_NAME "i8xx TCO timer" | 94 | #define TCO_MODULE_NAME "i8xx TCO timer" |
| 92 | #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION | 95 | #define TCO_DRIVER_NAME TCO_MODULE_NAME ", v" TCO_VERSION |
| 93 | #define PFX TCO_MODULE_NAME ": " | 96 | #define PFX TCO_MODULE_NAME ": " |
| @@ -125,10 +128,18 @@ static int tco_timer_start (void) | |||
| 125 | unsigned char val; | 128 | unsigned char val; |
| 126 | 129 | ||
| 127 | spin_lock(&tco_lock); | 130 | spin_lock(&tco_lock); |
| 131 | |||
| 132 | /* disable chipset's NO_REBOOT bit */ | ||
| 133 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val); | ||
| 134 | val &= 0xfd; | ||
| 135 | pci_write_config_byte (i8xx_tco_pci, 0xd4, val); | ||
| 136 | |||
| 137 | /* Bit 11: TCO Timer Halt -> 0 = The TCO timer is enabled to count */ | ||
| 128 | val = inb (TCO1_CNT + 1); | 138 | val = inb (TCO1_CNT + 1); |
| 129 | val &= 0xf7; | 139 | val &= 0xf7; |
| 130 | outb (val, TCO1_CNT + 1); | 140 | outb (val, TCO1_CNT + 1); |
| 131 | val = inb (TCO1_CNT + 1); | 141 | val = inb (TCO1_CNT + 1); |
| 142 | |||
| 132 | spin_unlock(&tco_lock); | 143 | spin_unlock(&tco_lock); |
| 133 | 144 | ||
| 134 | if (val & 0x08) | 145 | if (val & 0x08) |
| @@ -138,13 +149,20 @@ static int tco_timer_start (void) | |||
| 138 | 149 | ||
| 139 | static int tco_timer_stop (void) | 150 | static int tco_timer_stop (void) |
| 140 | { | 151 | { |
| 141 | unsigned char val; | 152 | unsigned char val, val1; |
| 142 | 153 | ||
| 143 | spin_lock(&tco_lock); | 154 | spin_lock(&tco_lock); |
| 155 | /* Bit 11: TCO Timer Halt -> 1 = The TCO timer is disabled */ | ||
| 144 | val = inb (TCO1_CNT + 1); | 156 | val = inb (TCO1_CNT + 1); |
| 145 | val |= 0x08; | 157 | val |= 0x08; |
| 146 | outb (val, TCO1_CNT + 1); | 158 | outb (val, TCO1_CNT + 1); |
| 147 | val = inb (TCO1_CNT + 1); | 159 | val = inb (TCO1_CNT + 1); |
| 160 | |||
| 161 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | ||
| 162 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1); | ||
| 163 | val1 |= 0x02; | ||
| 164 | pci_write_config_byte (i8xx_tco_pci, 0xd4, val1); | ||
| 165 | |||
| 148 | spin_unlock(&tco_lock); | 166 | spin_unlock(&tco_lock); |
| 149 | 167 | ||
| 150 | if ((val & 0x08) == 0) | 168 | if ((val & 0x08) == 0) |
| @@ -155,6 +173,7 @@ static int tco_timer_stop (void) | |||
| 155 | static int tco_timer_keepalive (void) | 173 | static int tco_timer_keepalive (void) |
| 156 | { | 174 | { |
| 157 | spin_lock(&tco_lock); | 175 | spin_lock(&tco_lock); |
| 176 | /* Reload the timer by writing to the TCO Timer Reload register */ | ||
| 158 | outb (0x01, TCO1_RLD); | 177 | outb (0x01, TCO1_RLD); |
| 159 | spin_unlock(&tco_lock); | 178 | spin_unlock(&tco_lock); |
| 160 | return 0; | 179 | return 0; |
| @@ -417,9 +436,8 @@ static unsigned char __init i8xx_tco_getdevice (void) | |||
| 417 | printk (KERN_ERR PFX "failed to get TCOBASE address\n"); | 436 | printk (KERN_ERR PFX "failed to get TCOBASE address\n"); |
| 418 | return 0; | 437 | return 0; |
| 419 | } | 438 | } |
| 420 | /* | 439 | |
| 421 | * Check chipset's NO_REBOOT bit | 440 | /* Check chipset's NO_REBOOT bit */ |
| 422 | */ | ||
| 423 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1); | 441 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val1); |
| 424 | if (val1 & 0x02) { | 442 | if (val1 & 0x02) { |
| 425 | val1 &= 0xfd; | 443 | val1 &= 0xfd; |
| @@ -430,6 +448,10 @@ static unsigned char __init i8xx_tco_getdevice (void) | |||
| 430 | return 0; /* Cannot reset NO_REBOOT bit */ | 448 | return 0; /* Cannot reset NO_REBOOT bit */ |
| 431 | } | 449 | } |
| 432 | } | 450 | } |
| 451 | /* Disable reboots untill the watchdog starts */ | ||
| 452 | val1 |= 0x02; | ||
| 453 | pci_write_config_byte (i8xx_tco_pci, 0xd4, val1); | ||
| 454 | |||
| 433 | /* Set the TCO_EN bit in SMI_EN register */ | 455 | /* Set the TCO_EN bit in SMI_EN register */ |
| 434 | if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) { | 456 | if (!request_region (SMI_EN + 1, 1, "i8xx TCO")) { |
| 435 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", | 457 | printk (KERN_ERR PFX "I/O address 0x%04x already in use\n", |
| @@ -505,17 +527,10 @@ out: | |||
| 505 | 527 | ||
| 506 | static void __exit watchdog_cleanup (void) | 528 | static void __exit watchdog_cleanup (void) |
| 507 | { | 529 | { |
| 508 | u8 val; | ||
| 509 | |||
| 510 | /* Stop the timer before we leave */ | 530 | /* Stop the timer before we leave */ |
| 511 | if (!nowayout) | 531 | if (!nowayout) |
| 512 | tco_timer_stop (); | 532 | tco_timer_stop (); |
| 513 | 533 | ||
| 514 | /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ | ||
| 515 | pci_read_config_byte (i8xx_tco_pci, 0xd4, &val); | ||
| 516 | val |= 0x02; | ||
| 517 | pci_write_config_byte (i8xx_tco_pci, 0xd4, val); | ||
| 518 | |||
| 519 | /* Deregister */ | 534 | /* Deregister */ |
| 520 | misc_deregister (&i8xx_tco_miscdev); | 535 | misc_deregister (&i8xx_tco_miscdev); |
| 521 | unregister_reboot_notifier(&i8xx_tco_notifier); | 536 | unregister_reboot_notifier(&i8xx_tco_notifier); |
diff --git a/drivers/i2c/busses/i2c-sibyte.c b/drivers/i2c/busses/i2c-sibyte.c index 1c99536b673b..fa503ed9f86d 100644 --- a/drivers/i2c/busses/i2c-sibyte.c +++ b/drivers/i2c/busses/i2c-sibyte.c | |||
| @@ -23,8 +23,8 @@ | |||
| 23 | #include <asm/sibyte/sb1250_smbus.h> | 23 | #include <asm/sibyte/sb1250_smbus.h> |
| 24 | 24 | ||
| 25 | static struct i2c_algo_sibyte_data sibyte_board_data[2] = { | 25 | static struct i2c_algo_sibyte_data sibyte_board_data[2] = { |
| 26 | { NULL, 0, (void *) (KSEG1+A_SMB_BASE(0)) }, | 26 | { NULL, 0, (void *) (CKSEG1+A_SMB_BASE(0)) }, |
| 27 | { NULL, 1, (void *) (KSEG1+A_SMB_BASE(1)) } | 27 | { NULL, 1, (void *) (CKSEG1+A_SMB_BASE(1)) } |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | static struct i2c_adapter sibyte_board_adapter[2] = { | 30 | static struct i2c_adapter sibyte_board_adapter[2] = { |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index f9c1acb4ed6a..c9d3a00a3c0c 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
| @@ -1220,7 +1220,7 @@ static int ide_disk_probe(struct device *dev) | |||
| 1220 | goto failed; | 1220 | goto failed; |
| 1221 | 1221 | ||
| 1222 | g = alloc_disk_node(1 << PARTN_BITS, | 1222 | g = alloc_disk_node(1 << PARTN_BITS, |
| 1223 | pcibus_to_node(drive->hwif->pci_dev->bus)); | 1223 | hwif_to_node(drive->hwif)); |
| 1224 | if (!g) | 1224 | if (!g) |
| 1225 | goto out_free_idkp; | 1225 | goto out_free_idkp; |
| 1226 | 1226 | ||
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 94daf40ae323..c1128ae5cd2f 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -960,15 +960,6 @@ static void save_match(ide_hwif_t *hwif, ide_hwif_t *new, ide_hwif_t **match) | |||
| 960 | } | 960 | } |
| 961 | #endif /* MAX_HWIFS > 1 */ | 961 | #endif /* MAX_HWIFS > 1 */ |
| 962 | 962 | ||
| 963 | static inline int hwif_to_node(ide_hwif_t *hwif) | ||
| 964 | { | ||
| 965 | if (hwif->pci_dev) | ||
| 966 | return pcibus_to_node(hwif->pci_dev->bus); | ||
| 967 | else | ||
| 968 | /* Add ways to determine the node of other busses here */ | ||
| 969 | return -1; | ||
| 970 | } | ||
| 971 | |||
| 972 | /* | 963 | /* |
| 973 | * init request queue | 964 | * init request queue |
| 974 | */ | 965 | */ |
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index e0d1b01cc74c..386df71eee74 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c | |||
| @@ -1650,7 +1650,7 @@ static void __exit icn_exit(void) | |||
| 1650 | { | 1650 | { |
| 1651 | isdn_ctrl cmd; | 1651 | isdn_ctrl cmd; |
| 1652 | icn_card *card = cards; | 1652 | icn_card *card = cards; |
| 1653 | icn_card *last; | 1653 | icn_card *last, *tmpcard; |
| 1654 | int i; | 1654 | int i; |
| 1655 | unsigned long flags; | 1655 | unsigned long flags; |
| 1656 | 1656 | ||
| @@ -1670,8 +1670,9 @@ static void __exit icn_exit(void) | |||
| 1670 | for (i = 0; i < ICN_BCH; i++) | 1670 | for (i = 0; i < ICN_BCH; i++) |
| 1671 | icn_free_queue(card, i); | 1671 | icn_free_queue(card, i); |
| 1672 | } | 1672 | } |
| 1673 | card = card->next; | 1673 | tmpcard = card->next; |
| 1674 | spin_unlock_irqrestore(&card->lock, flags); | 1674 | spin_unlock_irqrestore(&card->lock, flags); |
| 1675 | card = tmpcard; | ||
| 1675 | } | 1676 | } |
| 1676 | card = cards; | 1677 | card = cards; |
| 1677 | cards = NULL; | 1678 | cards = NULL; |
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index e83256d0fd14..a50a41f6f79d 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
| @@ -188,7 +188,7 @@ config DVB_BCM3510 | |||
| 188 | support this frontend. | 188 | support this frontend. |
| 189 | 189 | ||
| 190 | config DVB_LGDT330X | 190 | config DVB_LGDT330X |
| 191 | tristate "LGDT3302 or LGDT3303 based (DViCO FusionHDTV Gold)" | 191 | tristate "LG Electronics LGDT3302/LGDT3303 based" |
| 192 | depends on DVB_CORE | 192 | depends on DVB_CORE |
| 193 | help | 193 | help |
| 194 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 194 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want |
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index 5264310c070e..536c35d969b7 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c | |||
| @@ -225,6 +225,22 @@ struct dvb_pll_desc dvb_pll_tua6034 = { | |||
| 225 | }; | 225 | }; |
| 226 | EXPORT_SYMBOL(dvb_pll_tua6034); | 226 | EXPORT_SYMBOL(dvb_pll_tua6034); |
| 227 | 227 | ||
| 228 | /* Infineon TUA6034 | ||
| 229 | * used in LG Innotek TDVS-H062F | ||
| 230 | */ | ||
| 231 | struct dvb_pll_desc dvb_pll_tdvs_tua6034 = { | ||
| 232 | .name = "LG/Infineon TUA6034", | ||
| 233 | .min = 54000000, | ||
| 234 | .max = 863000000, | ||
| 235 | .count = 3, | ||
| 236 | .entries = { | ||
| 237 | { 160000000, 44000000, 62500, 0xce, 0x01 }, | ||
| 238 | { 455000000, 44000000, 62500, 0xce, 0x02 }, | ||
| 239 | { 999999999, 44000000, 62500, 0xce, 0x04 }, | ||
| 240 | }, | ||
| 241 | }; | ||
| 242 | EXPORT_SYMBOL(dvb_pll_tdvs_tua6034); | ||
| 243 | |||
| 228 | /* Philips FMD1216ME | 244 | /* Philips FMD1216ME |
| 229 | * used in Medion Hybrid PCMCIA card and USB Box | 245 | * used in Medion Hybrid PCMCIA card and USB Box |
| 230 | */ | 246 | */ |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index cb794759d89e..205b2d1a8852 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
| @@ -31,6 +31,7 @@ extern struct dvb_pll_desc dvb_pll_unknown_1; | |||
| 31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; | 31 | extern struct dvb_pll_desc dvb_pll_tua6010xs; |
| 32 | extern struct dvb_pll_desc dvb_pll_env57h1xd5; | 32 | extern struct dvb_pll_desc dvb_pll_env57h1xd5; |
| 33 | extern struct dvb_pll_desc dvb_pll_tua6034; | 33 | extern struct dvb_pll_desc dvb_pll_tua6034; |
| 34 | extern struct dvb_pll_desc dvb_pll_tdvs_tua6034; | ||
| 34 | extern struct dvb_pll_desc dvb_pll_tda665x; | 35 | extern struct dvb_pll_desc dvb_pll_tda665x; |
| 35 | extern struct dvb_pll_desc dvb_pll_fmd1216me; | 36 | extern struct dvb_pll_desc dvb_pll_fmd1216me; |
| 36 | extern struct dvb_pll_desc dvb_pll_tded4; | 37 | extern struct dvb_pll_desc dvb_pll_tded4; |
diff --git a/drivers/media/dvb/frontends/lgdt330x.c b/drivers/media/dvb/frontends/lgdt330x.c index e94dee50eecd..1f1cd7a8d500 100644 --- a/drivers/media/dvb/frontends/lgdt330x.c +++ b/drivers/media/dvb/frontends/lgdt330x.c | |||
| @@ -1,11 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for LGDT3302 & LGDT3303 (DViCO FusionHDTV Gold) - VSB/QAM | 2 | * Support for LGDT3302 and LGDT3303 - VSB/QAM |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> | 4 | * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> |
| 5 | * | 5 | * |
| 6 | * Based on code from Kirk Lapray <kirk_lapray@bigfoot.com> | ||
| 7 | * Copyright (C) 2005 | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 10 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
| 11 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
| @@ -25,11 +22,13 @@ | |||
| 25 | /* | 22 | /* |
| 26 | * NOTES ABOUT THIS DRIVER | 23 | * NOTES ABOUT THIS DRIVER |
| 27 | * | 24 | * |
| 28 | * This driver supports DViCO FusionHDTV Gold under Linux. | 25 | * This Linux driver supports: |
| 26 | * DViCO FusionHDTV 3 Gold-Q | ||
| 27 | * DViCO FusionHDTV 3 Gold-T | ||
| 28 | * DViCO FusionHDTV 5 Gold | ||
| 29 | * | 29 | * |
| 30 | * TODO: | 30 | * TODO: |
| 31 | * BER and signal strength always return 0. | 31 | * signal strength always returns 0. |
| 32 | * Include support for LGDT3303 | ||
| 33 | * | 32 | * |
| 34 | */ | 33 | */ |
| 35 | 34 | ||
| @@ -41,7 +40,6 @@ | |||
| 41 | #include <asm/byteorder.h> | 40 | #include <asm/byteorder.h> |
| 42 | 41 | ||
| 43 | #include "dvb_frontend.h" | 42 | #include "dvb_frontend.h" |
| 44 | #include "dvb-pll.h" | ||
| 45 | #include "lgdt330x_priv.h" | 43 | #include "lgdt330x_priv.h" |
| 46 | #include "lgdt330x.h" | 44 | #include "lgdt330x.h" |
| 47 | 45 | ||
| @@ -70,55 +68,37 @@ struct lgdt330x_state | |||
| 70 | u32 current_frequency; | 68 | u32 current_frequency; |
| 71 | }; | 69 | }; |
| 72 | 70 | ||
| 73 | static int i2c_writebytes (struct lgdt330x_state* state, | 71 | static int i2c_write_demod_bytes (struct lgdt330x_state* state, |
| 74 | u8 addr, /* demod_address or pll_address */ | ||
| 75 | u8 *buf, /* data bytes to send */ | 72 | u8 *buf, /* data bytes to send */ |
| 76 | int len /* number of bytes to send */ ) | 73 | int len /* number of bytes to send */ ) |
| 77 | { | 74 | { |
| 78 | u8 tmp[] = { buf[0], buf[1] }; | ||
| 79 | struct i2c_msg msg = | 75 | struct i2c_msg msg = |
| 80 | { .addr = addr, .flags = 0, .buf = tmp, .len = 2 }; | 76 | { .addr = state->config->demod_address, |
| 81 | int err; | 77 | .flags = 0, |
| 78 | .buf = buf, | ||
| 79 | .len = 2 }; | ||
| 82 | int i; | 80 | int i; |
| 81 | int err; | ||
| 83 | 82 | ||
| 84 | for (i=1; i<len; i++) { | 83 | for (i=0; i<len-1; i+=2){ |
| 85 | tmp[1] = buf[i]; | ||
| 86 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | 84 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { |
| 87 | printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err == %i)\n", __FUNCTION__, addr, buf[0], err); | 85 | printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err); |
| 88 | if (err < 0) | 86 | if (err < 0) |
| 89 | return err; | 87 | return err; |
| 90 | else | 88 | else |
| 91 | return -EREMOTEIO; | 89 | return -EREMOTEIO; |
| 92 | } | 90 | } |
| 93 | tmp[0]++; | 91 | msg.buf += 2; |
| 94 | } | 92 | } |
| 95 | return 0; | 93 | return 0; |
| 96 | } | 94 | } |
| 97 | 95 | ||
| 98 | #if 0 | ||
| 99 | static int i2c_readbytes (struct lgdt330x_state* state, | ||
| 100 | u8 addr, /* demod_address or pll_address */ | ||
| 101 | u8 *buf, /* holds data bytes read */ | ||
| 102 | int len /* number of bytes to read */ ) | ||
| 103 | { | ||
| 104 | struct i2c_msg msg = | ||
| 105 | { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len }; | ||
| 106 | int err; | ||
| 107 | |||
| 108 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
| 109 | printk(KERN_WARNING "lgdt330x: %s error (addr %02x, err == %i)\n", __FUNCTION__, addr, err); | ||
| 110 | return -EREMOTEIO; | ||
| 111 | } | ||
| 112 | return 0; | ||
| 113 | } | ||
| 114 | #endif | ||
| 115 | |||
| 116 | /* | 96 | /* |
| 117 | * This routine writes the register (reg) to the demod bus | 97 | * This routine writes the register (reg) to the demod bus |
| 118 | * then reads the data returned for (len) bytes. | 98 | * then reads the data returned for (len) bytes. |
| 119 | */ | 99 | */ |
| 120 | 100 | ||
| 121 | static u8 i2c_selectreadbytes (struct lgdt330x_state* state, | 101 | static u8 i2c_read_demod_bytes (struct lgdt330x_state* state, |
| 122 | enum I2C_REG reg, u8* buf, int len) | 102 | enum I2C_REG reg, u8* buf, int len) |
| 123 | { | 103 | { |
| 124 | u8 wr [] = { reg }; | 104 | u8 wr [] = { reg }; |
| @@ -139,7 +119,7 @@ static u8 i2c_selectreadbytes (struct lgdt330x_state* state, | |||
| 139 | } | 119 | } |
| 140 | 120 | ||
| 141 | /* Software reset */ | 121 | /* Software reset */ |
| 142 | int lgdt330x_SwReset(struct lgdt330x_state* state) | 122 | static int lgdt3302_SwReset(struct lgdt330x_state* state) |
| 143 | { | 123 | { |
| 144 | u8 ret; | 124 | u8 ret; |
| 145 | u8 reset[] = { | 125 | u8 reset[] = { |
| @@ -148,23 +128,51 @@ int lgdt330x_SwReset(struct lgdt330x_state* state) | |||
| 148 | * bits 5-0 are 1 to mask interrupts */ | 128 | * bits 5-0 are 1 to mask interrupts */ |
| 149 | }; | 129 | }; |
| 150 | 130 | ||
| 151 | ret = i2c_writebytes(state, | 131 | ret = i2c_write_demod_bytes(state, |
| 152 | state->config->demod_address, | 132 | reset, sizeof(reset)); |
| 133 | if (ret == 0) { | ||
| 134 | |||
| 135 | /* force reset high (inactive) and unmask interrupts */ | ||
| 136 | reset[1] = 0x7f; | ||
| 137 | ret = i2c_write_demod_bytes(state, | ||
| 138 | reset, sizeof(reset)); | ||
| 139 | } | ||
| 140 | return ret; | ||
| 141 | } | ||
| 142 | |||
| 143 | static int lgdt3303_SwReset(struct lgdt330x_state* state) | ||
| 144 | { | ||
| 145 | u8 ret; | ||
| 146 | u8 reset[] = { | ||
| 147 | 0x02, | ||
| 148 | 0x00 /* bit 0 is active low software reset */ | ||
| 149 | }; | ||
| 150 | |||
| 151 | ret = i2c_write_demod_bytes(state, | ||
| 153 | reset, sizeof(reset)); | 152 | reset, sizeof(reset)); |
| 154 | if (ret == 0) { | 153 | if (ret == 0) { |
| 155 | /* spec says reset takes 100 ns why wait */ | 154 | |
| 156 | /* mdelay(100); */ /* keep low for 100mS */ | 155 | /* force reset high (inactive) */ |
| 157 | reset[1] = 0x7f; /* force reset high (inactive) | 156 | reset[1] = 0x01; |
| 158 | * and unmask interrupts */ | 157 | ret = i2c_write_demod_bytes(state, |
| 159 | ret = i2c_writebytes(state, | ||
| 160 | state->config->demod_address, | ||
| 161 | reset, sizeof(reset)); | 158 | reset, sizeof(reset)); |
| 162 | } | 159 | } |
| 163 | /* Spec does not indicate a need for this either */ | ||
| 164 | /*mdelay(5); */ /* wait 5 msec before doing more */ | ||
| 165 | return ret; | 160 | return ret; |
| 166 | } | 161 | } |
| 167 | 162 | ||
| 163 | static int lgdt330x_SwReset(struct lgdt330x_state* state) | ||
| 164 | { | ||
| 165 | switch (state->config->demod_chip) { | ||
| 166 | case LGDT3302: | ||
| 167 | return lgdt3302_SwReset(state); | ||
| 168 | case LGDT3303: | ||
| 169 | return lgdt3303_SwReset(state); | ||
| 170 | default: | ||
| 171 | return -ENODEV; | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | |||
| 168 | static int lgdt330x_init(struct dvb_frontend* fe) | 176 | static int lgdt330x_init(struct dvb_frontend* fe) |
| 169 | { | 177 | { |
| 170 | /* Hardware reset is done using gpio[0] of cx23880x chip. | 178 | /* Hardware reset is done using gpio[0] of cx23880x chip. |
| @@ -173,22 +181,98 @@ static int lgdt330x_init(struct dvb_frontend* fe) | |||
| 173 | * Maybe there needs to be a callable function in cx88-core or | 181 | * Maybe there needs to be a callable function in cx88-core or |
| 174 | * the caller of this function needs to do it. */ | 182 | * the caller of this function needs to do it. */ |
| 175 | 183 | ||
| 176 | dprintk("%s entered\n", __FUNCTION__); | 184 | /* |
| 177 | return lgdt330x_SwReset((struct lgdt330x_state*) fe->demodulator_priv); | 185 | * Array of byte pairs <address, value> |
| 186 | * to initialize each different chip | ||
| 187 | */ | ||
| 188 | static u8 lgdt3302_init_data[] = { | ||
| 189 | /* Use 50MHz parameter values from spec sheet since xtal is 50 */ | ||
| 190 | /* Change the value of NCOCTFV[25:0] of carrier | ||
| 191 | recovery center frequency register */ | ||
| 192 | VSB_CARRIER_FREQ0, 0x00, | ||
| 193 | VSB_CARRIER_FREQ1, 0x87, | ||
| 194 | VSB_CARRIER_FREQ2, 0x8e, | ||
| 195 | VSB_CARRIER_FREQ3, 0x01, | ||
| 196 | /* Change the TPCLK pin polarity | ||
| 197 | data is valid on falling clock */ | ||
| 198 | DEMUX_CONTROL, 0xfb, | ||
| 199 | /* Change the value of IFBW[11:0] of | ||
| 200 | AGC IF/RF loop filter bandwidth register */ | ||
| 201 | AGC_RF_BANDWIDTH0, 0x40, | ||
| 202 | AGC_RF_BANDWIDTH1, 0x93, | ||
| 203 | AGC_RF_BANDWIDTH2, 0x00, | ||
| 204 | /* Change the value of bit 6, 'nINAGCBY' and | ||
| 205 | 'NSSEL[1:0] of ACG function control register 2 */ | ||
| 206 | AGC_FUNC_CTRL2, 0xc6, | ||
| 207 | /* Change the value of bit 6 'RFFIX' | ||
| 208 | of AGC function control register 3 */ | ||
| 209 | AGC_FUNC_CTRL3, 0x40, | ||
| 210 | /* Set the value of 'INLVTHD' register 0x2a/0x2c | ||
| 211 | to 0x7fe */ | ||
| 212 | AGC_DELAY0, 0x07, | ||
| 213 | AGC_DELAY2, 0xfe, | ||
| 214 | /* Change the value of IAGCBW[15:8] | ||
| 215 | of inner AGC loop filter bandwith */ | ||
| 216 | AGC_LOOP_BANDWIDTH0, 0x08, | ||
| 217 | AGC_LOOP_BANDWIDTH1, 0x9a | ||
| 218 | }; | ||
| 219 | |||
| 220 | static u8 lgdt3303_init_data[] = { | ||
| 221 | 0x4c, 0x14 | ||
| 222 | }; | ||
| 223 | |||
| 224 | struct lgdt330x_state* state = fe->demodulator_priv; | ||
| 225 | char *chip_name; | ||
| 226 | int err; | ||
| 227 | |||
| 228 | switch (state->config->demod_chip) { | ||
| 229 | case LGDT3302: | ||
| 230 | chip_name = "LGDT3302"; | ||
| 231 | err = i2c_write_demod_bytes(state, lgdt3302_init_data, | ||
| 232 | sizeof(lgdt3302_init_data)); | ||
| 233 | break; | ||
| 234 | case LGDT3303: | ||
| 235 | chip_name = "LGDT3303"; | ||
| 236 | err = i2c_write_demod_bytes(state, lgdt3303_init_data, | ||
| 237 | sizeof(lgdt3303_init_data)); | ||
| 238 | break; | ||
| 239 | default: | ||
| 240 | chip_name = "undefined"; | ||
| 241 | printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n"); | ||
| 242 | err = -ENODEV; | ||
| 243 | } | ||
| 244 | dprintk("%s entered as %s\n", __FUNCTION__, chip_name); | ||
| 245 | if (err < 0) | ||
| 246 | return err; | ||
| 247 | return lgdt330x_SwReset(state); | ||
| 178 | } | 248 | } |
| 179 | 249 | ||
| 180 | static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber) | 250 | static int lgdt330x_read_ber(struct dvb_frontend* fe, u32* ber) |
| 181 | { | 251 | { |
| 182 | *ber = 0; /* Dummy out for now */ | 252 | *ber = 0; /* Not supplied by the demod chips */ |
| 183 | return 0; | 253 | return 0; |
| 184 | } | 254 | } |
| 185 | 255 | ||
| 186 | static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 256 | static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
| 187 | { | 257 | { |
| 188 | struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; | 258 | struct lgdt330x_state* state = fe->demodulator_priv; |
| 259 | int err; | ||
| 189 | u8 buf[2]; | 260 | u8 buf[2]; |
| 190 | 261 | ||
| 191 | i2c_selectreadbytes(state, PACKET_ERR_COUNTER1, buf, sizeof(buf)); | 262 | switch (state->config->demod_chip) { |
| 263 | case LGDT3302: | ||
| 264 | err = i2c_read_demod_bytes(state, LGDT3302_PACKET_ERR_COUNTER1, | ||
| 265 | buf, sizeof(buf)); | ||
| 266 | break; | ||
| 267 | case LGDT3303: | ||
| 268 | err = i2c_read_demod_bytes(state, LGDT3303_PACKET_ERR_COUNTER1, | ||
| 269 | buf, sizeof(buf)); | ||
| 270 | break; | ||
| 271 | default: | ||
| 272 | printk(KERN_WARNING | ||
| 273 | "Only LGDT3302 and LGDT3303 are supported chips.\n"); | ||
| 274 | err = -ENODEV; | ||
| 275 | } | ||
| 192 | 276 | ||
| 193 | *ucblocks = (buf[0] << 8) | buf[1]; | 277 | *ucblocks = (buf[0] << 8) | buf[1]; |
| 194 | return 0; | 278 | return 0; |
| @@ -197,123 +281,113 @@ static int lgdt330x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
| 197 | static int lgdt330x_set_parameters(struct dvb_frontend* fe, | 281 | static int lgdt330x_set_parameters(struct dvb_frontend* fe, |
| 198 | struct dvb_frontend_parameters *param) | 282 | struct dvb_frontend_parameters *param) |
| 199 | { | 283 | { |
| 200 | struct lgdt330x_state* state = | 284 | /* |
| 201 | (struct lgdt330x_state*) fe->demodulator_priv; | 285 | * Array of byte pairs <address, value> |
| 286 | * to initialize 8VSB for lgdt3303 chip 50 MHz IF | ||
| 287 | */ | ||
| 288 | static u8 lgdt3303_8vsb_44_data[] = { | ||
| 289 | 0x04, 0x00, | ||
| 290 | 0x0d, 0x40, | ||
| 291 | 0x0e, 0x87, | ||
| 292 | 0x0f, 0x8e, | ||
| 293 | 0x10, 0x01, | ||
| 294 | 0x47, 0x8b }; | ||
| 295 | |||
| 296 | /* | ||
| 297 | * Array of byte pairs <address, value> | ||
| 298 | * to initialize QAM for lgdt3303 chip | ||
| 299 | */ | ||
| 300 | static u8 lgdt3303_qam_data[] = { | ||
| 301 | 0x04, 0x00, | ||
| 302 | 0x0d, 0x00, | ||
| 303 | 0x0e, 0x00, | ||
| 304 | 0x0f, 0x00, | ||
| 305 | 0x10, 0x00, | ||
| 306 | 0x51, 0x63, | ||
| 307 | 0x47, 0x66, | ||
| 308 | 0x48, 0x66, | ||
| 309 | 0x4d, 0x1a, | ||
| 310 | 0x49, 0x08, | ||
| 311 | 0x4a, 0x9b }; | ||
| 312 | |||
| 313 | struct lgdt330x_state* state = fe->demodulator_priv; | ||
| 202 | 314 | ||
| 203 | /* Use 50MHz parameter values from spec sheet since xtal is 50 */ | ||
| 204 | static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 }; | 315 | static u8 top_ctrl_cfg[] = { TOP_CONTROL, 0x03 }; |
| 205 | static u8 vsb_freq_cfg[] = { VSB_CARRIER_FREQ0, 0x00, 0x87, 0x8e, 0x01 }; | ||
| 206 | static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb }; | ||
| 207 | static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 }; | ||
| 208 | static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 }; | ||
| 209 | static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x07, 0x00, 0xfe }; | ||
| 210 | static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a }; | ||
| 211 | 316 | ||
| 317 | int err; | ||
| 212 | /* Change only if we are actually changing the modulation */ | 318 | /* Change only if we are actually changing the modulation */ |
| 213 | if (state->current_modulation != param->u.vsb.modulation) { | 319 | if (state->current_modulation != param->u.vsb.modulation) { |
| 214 | switch(param->u.vsb.modulation) { | 320 | switch(param->u.vsb.modulation) { |
| 215 | case VSB_8: | 321 | case VSB_8: |
| 216 | dprintk("%s: VSB_8 MODE\n", __FUNCTION__); | 322 | dprintk("%s: VSB_8 MODE\n", __FUNCTION__); |
| 217 | 323 | ||
| 218 | /* Select VSB mode and serial MPEG interface */ | 324 | /* Select VSB mode */ |
| 219 | top_ctrl_cfg[1] = 0x07; | 325 | top_ctrl_cfg[1] = 0x03; |
| 220 | 326 | ||
| 221 | /* Select ANT connector if supported by card */ | 327 | /* Select ANT connector if supported by card */ |
| 222 | if (state->config->pll_rf_set) | 328 | if (state->config->pll_rf_set) |
| 223 | state->config->pll_rf_set(fe, 1); | 329 | state->config->pll_rf_set(fe, 1); |
| 330 | |||
| 331 | if (state->config->demod_chip == LGDT3303) { | ||
| 332 | err = i2c_write_demod_bytes(state, lgdt3303_8vsb_44_data, | ||
| 333 | sizeof(lgdt3303_8vsb_44_data)); | ||
| 334 | } | ||
| 224 | break; | 335 | break; |
| 225 | 336 | ||
| 226 | case QAM_64: | 337 | case QAM_64: |
| 227 | dprintk("%s: QAM_64 MODE\n", __FUNCTION__); | 338 | dprintk("%s: QAM_64 MODE\n", __FUNCTION__); |
| 228 | 339 | ||
| 229 | /* Select QAM_64 mode and serial MPEG interface */ | 340 | /* Select QAM_64 mode */ |
| 230 | top_ctrl_cfg[1] = 0x04; | 341 | top_ctrl_cfg[1] = 0x00; |
| 231 | 342 | ||
| 232 | /* Select CABLE connector if supported by card */ | 343 | /* Select CABLE connector if supported by card */ |
| 233 | if (state->config->pll_rf_set) | 344 | if (state->config->pll_rf_set) |
| 234 | state->config->pll_rf_set(fe, 0); | 345 | state->config->pll_rf_set(fe, 0); |
| 346 | |||
| 347 | if (state->config->demod_chip == LGDT3303) { | ||
| 348 | err = i2c_write_demod_bytes(state, lgdt3303_qam_data, | ||
| 349 | sizeof(lgdt3303_qam_data)); | ||
| 350 | } | ||
| 235 | break; | 351 | break; |
| 236 | 352 | ||
| 237 | case QAM_256: | 353 | case QAM_256: |
| 238 | dprintk("%s: QAM_256 MODE\n", __FUNCTION__); | 354 | dprintk("%s: QAM_256 MODE\n", __FUNCTION__); |
| 239 | 355 | ||
| 240 | /* Select QAM_256 mode and serial MPEG interface */ | 356 | /* Select QAM_256 mode */ |
| 241 | top_ctrl_cfg[1] = 0x05; | 357 | top_ctrl_cfg[1] = 0x01; |
| 242 | 358 | ||
| 243 | /* Select CABLE connector if supported by card */ | 359 | /* Select CABLE connector if supported by card */ |
| 244 | if (state->config->pll_rf_set) | 360 | if (state->config->pll_rf_set) |
| 245 | state->config->pll_rf_set(fe, 0); | 361 | state->config->pll_rf_set(fe, 0); |
| 362 | |||
| 363 | if (state->config->demod_chip == LGDT3303) { | ||
| 364 | err = i2c_write_demod_bytes(state, lgdt3303_qam_data, | ||
| 365 | sizeof(lgdt3303_qam_data)); | ||
| 366 | } | ||
| 246 | break; | 367 | break; |
| 247 | default: | 368 | default: |
| 248 | printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation); | 369 | printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation); |
| 249 | return -1; | 370 | return -1; |
| 250 | } | 371 | } |
| 251 | /* Initializations common to all modes */ | 372 | /* |
| 373 | * select serial or parallel MPEG harware interface | ||
| 374 | * Serial: 0x04 for LGDT3302 or 0x40 for LGDT3303 | ||
| 375 | * Parallel: 0x00 | ||
| 376 | */ | ||
| 377 | top_ctrl_cfg[1] |= state->config->serial_mpeg; | ||
| 252 | 378 | ||
| 253 | /* Select the requested mode */ | 379 | /* Select the requested mode */ |
| 254 | i2c_writebytes(state, state->config->demod_address, | 380 | i2c_write_demod_bytes(state, top_ctrl_cfg, |
| 255 | top_ctrl_cfg, sizeof(top_ctrl_cfg)); | 381 | sizeof(top_ctrl_cfg)); |
| 256 | |||
| 257 | /* Change the value of IFBW[11:0] | ||
| 258 | of AGC IF/RF loop filter bandwidth register */ | ||
| 259 | i2c_writebytes(state, state->config->demod_address, | ||
| 260 | agc_rf_cfg, sizeof(agc_rf_cfg)); | ||
| 261 | |||
| 262 | /* Change the value of bit 6, 'nINAGCBY' and | ||
| 263 | 'NSSEL[1:0] of ACG function control register 2 */ | ||
| 264 | /* Change the value of bit 6 'RFFIX' | ||
| 265 | of AGC function control register 3 */ | ||
| 266 | i2c_writebytes(state, state->config->demod_address, | ||
| 267 | agc_ctrl_cfg, sizeof(agc_ctrl_cfg)); | ||
| 268 | |||
| 269 | /* Change the TPCLK pin polarity | ||
| 270 | data is valid on falling clock */ | ||
| 271 | i2c_writebytes(state, state->config->demod_address, | ||
| 272 | demux_ctrl_cfg, sizeof(demux_ctrl_cfg)); | ||
| 273 | |||
| 274 | /* Change the value of NCOCTFV[25:0] of carrier | ||
| 275 | recovery center frequency register */ | ||
| 276 | i2c_writebytes(state, state->config->demod_address, | ||
| 277 | vsb_freq_cfg, sizeof(vsb_freq_cfg)); | ||
| 278 | |||
| 279 | /* Set the value of 'INLVTHD' register 0x2a/0x2c to 0x7fe */ | ||
| 280 | i2c_writebytes(state, state->config->demod_address, | ||
| 281 | agc_delay_cfg, sizeof(agc_delay_cfg)); | ||
| 282 | |||
| 283 | /* Change the value of IAGCBW[15:8] | ||
| 284 | of inner AGC loop filter bandwith */ | ||
| 285 | i2c_writebytes(state, state->config->demod_address, | ||
| 286 | agc_loop_cfg, sizeof(agc_loop_cfg)); | ||
| 287 | |||
| 288 | state->config->set_ts_params(fe, 0); | 382 | state->config->set_ts_params(fe, 0); |
| 289 | state->current_modulation = param->u.vsb.modulation; | 383 | state->current_modulation = param->u.vsb.modulation; |
| 290 | } | 384 | } |
| 291 | 385 | ||
| 292 | /* Change only if we are actually changing the channel */ | 386 | /* Change only if we are actually changing the channel */ |
| 293 | if (state->current_frequency != param->frequency) { | 387 | if (state->current_frequency != param->frequency) { |
| 294 | u8 buf[5]; | 388 | /* Tune to the new frequency */ |
| 295 | struct i2c_msg msg = { .flags = 0, .buf = &buf[1], .len = 4 }; | 389 | state->config->pll_set(fe, param); |
| 296 | int err; | 390 | /* Keep track of the new frequency */ |
| 297 | |||
| 298 | state->config->pll_set(fe, param, buf); | ||
| 299 | msg.addr = buf[0]; | ||
| 300 | |||
| 301 | dprintk("%s: tuner at 0x%02x bytes: 0x%02x 0x%02x " | ||
| 302 | "0x%02x 0x%02x\n", __FUNCTION__, | ||
| 303 | buf[0],buf[1],buf[2],buf[3],buf[4]); | ||
| 304 | if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) { | ||
| 305 | printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, buf[0], buf[1], err); | ||
| 306 | if (err < 0) | ||
| 307 | return err; | ||
| 308 | else | ||
| 309 | return -EREMOTEIO; | ||
| 310 | } | ||
| 311 | #if 0 | ||
| 312 | /* Check the status of the tuner pll */ | ||
| 313 | i2c_readbytes(state, buf[0], &buf[1], 1); | ||
| 314 | dprintk("%s: tuner status byte = 0x%02x\n", __FUNCTION__, buf[1]); | ||
| 315 | #endif | ||
| 316 | /* Update current frequency */ | ||
| 317 | state->current_frequency = param->frequency; | 391 | state->current_frequency = param->frequency; |
| 318 | } | 392 | } |
| 319 | lgdt330x_SwReset(state); | 393 | lgdt330x_SwReset(state); |
| @@ -328,21 +402,15 @@ static int lgdt330x_get_frontend(struct dvb_frontend* fe, | |||
| 328 | return 0; | 402 | return 0; |
| 329 | } | 403 | } |
| 330 | 404 | ||
| 331 | static int lgdt330x_read_status(struct dvb_frontend* fe, fe_status_t* status) | 405 | static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status) |
| 332 | { | 406 | { |
| 333 | struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; | 407 | struct lgdt330x_state* state = fe->demodulator_priv; |
| 334 | u8 buf[3]; | 408 | u8 buf[3]; |
| 335 | 409 | ||
| 336 | *status = 0; /* Reset status result */ | 410 | *status = 0; /* Reset status result */ |
| 337 | 411 | ||
| 338 | /* | ||
| 339 | * You must set the Mask bits to 1 in the IRQ_MASK in order | ||
| 340 | * to see that status bit in the IRQ_STATUS register. | ||
| 341 | * This is done in SwReset(); | ||
| 342 | */ | ||
| 343 | |||
| 344 | /* AGC status register */ | 412 | /* AGC status register */ |
| 345 | i2c_selectreadbytes(state, AGC_STATUS, buf, 1); | 413 | i2c_read_demod_bytes(state, AGC_STATUS, buf, 1); |
| 346 | dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]); | 414 | dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]); |
| 347 | if ((buf[0] & 0x0c) == 0x8){ | 415 | if ((buf[0] & 0x0c) == 0x8){ |
| 348 | /* Test signal does not exist flag */ | 416 | /* Test signal does not exist flag */ |
| @@ -353,16 +421,15 @@ static int lgdt330x_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
| 353 | return 0; | 421 | return 0; |
| 354 | } | 422 | } |
| 355 | 423 | ||
| 424 | /* | ||
| 425 | * You must set the Mask bits to 1 in the IRQ_MASK in order | ||
| 426 | * to see that status bit in the IRQ_STATUS register. | ||
| 427 | * This is done in SwReset(); | ||
| 428 | */ | ||
| 356 | /* signal status */ | 429 | /* signal status */ |
| 357 | i2c_selectreadbytes(state, TOP_CONTROL, buf, sizeof(buf)); | 430 | i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf)); |
| 358 | dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]); | 431 | dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]); |
| 359 | 432 | ||
| 360 | #if 0 | ||
| 361 | /* Alternative method to check for a signal */ | ||
| 362 | /* using the SNR good/bad interrupts. */ | ||
| 363 | if ((buf[2] & 0x30) == 0x10) | ||
| 364 | *status |= FE_HAS_SIGNAL; | ||
| 365 | #endif | ||
| 366 | 433 | ||
| 367 | /* sync status */ | 434 | /* sync status */ |
| 368 | if ((buf[2] & 0x03) == 0x01) { | 435 | if ((buf[2] & 0x03) == 0x01) { |
| @@ -376,7 +443,7 @@ static int lgdt330x_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
| 376 | } | 443 | } |
| 377 | 444 | ||
| 378 | /* Carrier Recovery Lock Status Register */ | 445 | /* Carrier Recovery Lock Status Register */ |
| 379 | i2c_selectreadbytes(state, CARRIER_LOCK, buf, 1); | 446 | i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); |
| 380 | dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]); | 447 | dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]); |
| 381 | switch (state->current_modulation) { | 448 | switch (state->current_modulation) { |
| 382 | case QAM_256: | 449 | case QAM_256: |
| @@ -396,13 +463,75 @@ static int lgdt330x_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
| 396 | return 0; | 463 | return 0; |
| 397 | } | 464 | } |
| 398 | 465 | ||
| 466 | static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status) | ||
| 467 | { | ||
| 468 | struct lgdt330x_state* state = fe->demodulator_priv; | ||
| 469 | int err; | ||
| 470 | u8 buf[3]; | ||
| 471 | |||
| 472 | *status = 0; /* Reset status result */ | ||
| 473 | |||
| 474 | /* lgdt3303 AGC status register */ | ||
| 475 | err = i2c_read_demod_bytes(state, 0x58, buf, 1); | ||
| 476 | if (err < 0) | ||
| 477 | return err; | ||
| 478 | |||
| 479 | dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]); | ||
| 480 | if ((buf[0] & 0x21) == 0x01){ | ||
| 481 | /* Test input signal does not exist flag */ | ||
| 482 | /* as well as the AGC lock flag. */ | ||
| 483 | *status |= FE_HAS_SIGNAL; | ||
| 484 | } else { | ||
| 485 | /* Without a signal all other status bits are meaningless */ | ||
| 486 | return 0; | ||
| 487 | } | ||
| 488 | |||
| 489 | /* Carrier Recovery Lock Status Register */ | ||
| 490 | i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1); | ||
| 491 | dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]); | ||
| 492 | switch (state->current_modulation) { | ||
| 493 | case QAM_256: | ||
| 494 | case QAM_64: | ||
| 495 | /* Need to undestand why there are 3 lock levels here */ | ||
| 496 | if ((buf[0] & 0x07) == 0x07) | ||
| 497 | *status |= FE_HAS_CARRIER; | ||
| 498 | else | ||
| 499 | break; | ||
| 500 | i2c_read_demod_bytes(state, 0x8a, buf, 1); | ||
| 501 | if ((buf[0] & 0x04) == 0x04) | ||
| 502 | *status |= FE_HAS_SYNC; | ||
| 503 | if ((buf[0] & 0x01) == 0x01) | ||
| 504 | *status |= FE_HAS_LOCK; | ||
| 505 | if ((buf[0] & 0x08) == 0x08) | ||
| 506 | *status |= FE_HAS_VITERBI; | ||
| 507 | break; | ||
| 508 | case VSB_8: | ||
| 509 | if ((buf[0] & 0x80) == 0x80) | ||
| 510 | *status |= FE_HAS_CARRIER; | ||
| 511 | else | ||
| 512 | break; | ||
| 513 | i2c_read_demod_bytes(state, 0x38, buf, 1); | ||
| 514 | if ((buf[0] & 0x02) == 0x00) | ||
| 515 | *status |= FE_HAS_SYNC; | ||
| 516 | if ((buf[0] & 0x01) == 0x01) { | ||
| 517 | *status |= FE_HAS_LOCK; | ||
| 518 | *status |= FE_HAS_VITERBI; | ||
| 519 | } | ||
| 520 | break; | ||
| 521 | default: | ||
| 522 | printk("KERN_WARNING lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__); | ||
| 523 | } | ||
| 524 | return 0; | ||
| 525 | } | ||
| 526 | |||
| 399 | static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 527 | static int lgdt330x_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
| 400 | { | 528 | { |
| 401 | /* not directly available. */ | 529 | /* not directly available. */ |
| 530 | *strength = 0; | ||
| 402 | return 0; | 531 | return 0; |
| 403 | } | 532 | } |
| 404 | 533 | ||
| 405 | static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr) | 534 | static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr) |
| 406 | { | 535 | { |
| 407 | #ifdef SNR_IN_DB | 536 | #ifdef SNR_IN_DB |
| 408 | /* | 537 | /* |
| @@ -451,7 +580,7 @@ static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr) | |||
| 451 | 91, 115, 144, 182, 229, 288, 362, 456, 574, 722, | 580 | 91, 115, 144, 182, 229, 288, 362, 456, 574, 722, |
| 452 | 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216, | 581 | 909, 1144, 1440, 1813, 2282, 2873, 3617, 4553, 5732, 7216, |
| 453 | 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151, | 582 | 9084, 11436, 14396, 18124, 22817, 28724, 36161, 45524, 57312, 72151, |
| 454 | 90833, 114351, 143960, 181235, 228161, 0x040000 | 583 | 90833, 114351, 143960, 181235, 228161, 0x080000 |
| 455 | }; | 584 | }; |
| 456 | 585 | ||
| 457 | static u8 buf[5];/* read data buffer */ | 586 | static u8 buf[5];/* read data buffer */ |
| @@ -459,8 +588,8 @@ static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr) | |||
| 459 | static u32 snr_db; /* index into SNR_EQ[] */ | 588 | static u32 snr_db; /* index into SNR_EQ[] */ |
| 460 | struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; | 589 | struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; |
| 461 | 590 | ||
| 462 | /* read both equalizer and pase tracker noise data */ | 591 | /* read both equalizer and phase tracker noise data */ |
| 463 | i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf)); | 592 | i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf)); |
| 464 | 593 | ||
| 465 | if (state->current_modulation == VSB_8) { | 594 | if (state->current_modulation == VSB_8) { |
| 466 | /* Equalizer Mean-Square Error Register for VSB */ | 595 | /* Equalizer Mean-Square Error Register for VSB */ |
| @@ -496,19 +625,20 @@ static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr) | |||
| 496 | struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; | 625 | struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; |
| 497 | 626 | ||
| 498 | /* read both equalizer and pase tracker noise data */ | 627 | /* read both equalizer and pase tracker noise data */ |
| 499 | i2c_selectreadbytes(state, EQPH_ERR0, buf, sizeof(buf)); | 628 | i2c_read_demod_bytes(state, EQPH_ERR0, buf, sizeof(buf)); |
| 500 | 629 | ||
| 501 | if (state->current_modulation == VSB_8) { | 630 | if (state->current_modulation == VSB_8) { |
| 502 | /* Equalizer Mean-Square Error Register for VSB */ | 631 | /* Phase Tracker Mean-Square Error Register for VSB */ |
| 503 | noise = ((buf[0] & 7) << 16) | (buf[1] << 8) | buf[2]; | ||
| 504 | } else { | ||
| 505 | /* Phase Tracker Mean-Square Error Register for QAM */ | ||
| 506 | noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4]; | 632 | noise = ((buf[0] & 7<<3) << 13) | (buf[3] << 8) | buf[4]; |
| 633 | } else { | ||
| 634 | |||
| 635 | /* Carrier Recovery Mean-Square Error for QAM */ | ||
| 636 | i2c_read_demod_bytes(state, 0x1a, buf, 2); | ||
| 637 | noise = ((buf[0] & 3) << 8) | buf[1]; | ||
| 507 | } | 638 | } |
| 508 | 639 | ||
| 509 | /* Small values for noise mean signal is better so invert noise */ | 640 | /* Small values for noise mean signal is better so invert noise */ |
| 510 | /* Noise is 19 bit value so discard 3 LSB*/ | 641 | *snr = ~noise; |
| 511 | *snr = ~noise>>3; | ||
| 512 | #endif | 642 | #endif |
| 513 | 643 | ||
| 514 | dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr); | 644 | dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr); |
| @@ -516,6 +646,32 @@ static int lgdt330x_read_snr(struct dvb_frontend* fe, u16* snr) | |||
| 516 | return 0; | 646 | return 0; |
| 517 | } | 647 | } |
| 518 | 648 | ||
| 649 | static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr) | ||
| 650 | { | ||
| 651 | /* Return the raw noise value */ | ||
| 652 | static u8 buf[5];/* read data buffer */ | ||
| 653 | static u32 noise; /* noise value */ | ||
| 654 | struct lgdt330x_state* state = (struct lgdt330x_state*) fe->demodulator_priv; | ||
| 655 | |||
| 656 | if (state->current_modulation == VSB_8) { | ||
| 657 | |||
| 658 | /* Phase Tracker Mean-Square Error Register for VSB */ | ||
| 659 | noise = ((buf[0] & 7) << 16) | (buf[3] << 8) | buf[4]; | ||
| 660 | } else { | ||
| 661 | |||
| 662 | /* Carrier Recovery Mean-Square Error for QAM */ | ||
| 663 | i2c_read_demod_bytes(state, 0x1a, buf, 2); | ||
| 664 | noise = (buf[0] << 8) | buf[1]; | ||
| 665 | } | ||
| 666 | |||
| 667 | /* Small values for noise mean signal is better so invert noise */ | ||
| 668 | *snr = ~noise; | ||
| 669 | |||
| 670 | dprintk("%s: noise = 0x%05x, snr = %idb\n",__FUNCTION__, noise, *snr); | ||
| 671 | |||
| 672 | return 0; | ||
| 673 | } | ||
| 674 | |||
| 519 | static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) | 675 | static int lgdt330x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fe_tune_settings) |
| 520 | { | 676 | { |
| 521 | /* I have no idea about this - it may not be needed */ | 677 | /* I have no idea about this - it may not be needed */ |
| @@ -531,7 +687,8 @@ static void lgdt330x_release(struct dvb_frontend* fe) | |||
| 531 | kfree(state); | 687 | kfree(state); |
| 532 | } | 688 | } |
| 533 | 689 | ||
| 534 | static struct dvb_frontend_ops lgdt330x_ops; | 690 | static struct dvb_frontend_ops lgdt3302_ops; |
| 691 | static struct dvb_frontend_ops lgdt3303_ops; | ||
| 535 | 692 | ||
| 536 | struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | 693 | struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, |
| 537 | struct i2c_adapter* i2c) | 694 | struct i2c_adapter* i2c) |
| @@ -548,9 +705,19 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, | |||
| 548 | /* Setup the state */ | 705 | /* Setup the state */ |
| 549 | state->config = config; | 706 | state->config = config; |
| 550 | state->i2c = i2c; | 707 | state->i2c = i2c; |
| 551 | memcpy(&state->ops, &lgdt330x_ops, sizeof(struct dvb_frontend_ops)); | 708 | switch (config->demod_chip) { |
| 709 | case LGDT3302: | ||
| 710 | memcpy(&state->ops, &lgdt3302_ops, sizeof(struct dvb_frontend_ops)); | ||
| 711 | break; | ||
| 712 | case LGDT3303: | ||
| 713 | memcpy(&state->ops, &lgdt3303_ops, sizeof(struct dvb_frontend_ops)); | ||
| 714 | break; | ||
| 715 | default: | ||
| 716 | goto error; | ||
| 717 | } | ||
| 718 | |||
| 552 | /* Verify communication with demod chip */ | 719 | /* Verify communication with demod chip */ |
| 553 | if (i2c_selectreadbytes(state, 2, buf, 1)) | 720 | if (i2c_read_demod_bytes(state, 2, buf, 1)) |
| 554 | goto error; | 721 | goto error; |
| 555 | 722 | ||
| 556 | state->current_frequency = -1; | 723 | state->current_frequency = -1; |
| @@ -568,9 +735,33 @@ error: | |||
| 568 | return NULL; | 735 | return NULL; |
| 569 | } | 736 | } |
| 570 | 737 | ||
| 571 | static struct dvb_frontend_ops lgdt330x_ops = { | 738 | static struct dvb_frontend_ops lgdt3302_ops = { |
| 739 | .info = { | ||
| 740 | .name= "LG Electronics LGDT3302 VSB/QAM Frontend", | ||
| 741 | .type = FE_ATSC, | ||
| 742 | .frequency_min= 54000000, | ||
| 743 | .frequency_max= 858000000, | ||
| 744 | .frequency_stepsize= 62500, | ||
| 745 | /* Symbol rate is for all VSB modes need to check QAM */ | ||
| 746 | .symbol_rate_min = 10762000, | ||
| 747 | .symbol_rate_max = 10762000, | ||
| 748 | .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB | ||
| 749 | }, | ||
| 750 | .init = lgdt330x_init, | ||
| 751 | .set_frontend = lgdt330x_set_parameters, | ||
| 752 | .get_frontend = lgdt330x_get_frontend, | ||
| 753 | .get_tune_settings = lgdt330x_get_tune_settings, | ||
| 754 | .read_status = lgdt3302_read_status, | ||
| 755 | .read_ber = lgdt330x_read_ber, | ||
| 756 | .read_signal_strength = lgdt330x_read_signal_strength, | ||
| 757 | .read_snr = lgdt3302_read_snr, | ||
| 758 | .read_ucblocks = lgdt330x_read_ucblocks, | ||
| 759 | .release = lgdt330x_release, | ||
| 760 | }; | ||
| 761 | |||
| 762 | static struct dvb_frontend_ops lgdt3303_ops = { | ||
| 572 | .info = { | 763 | .info = { |
| 573 | .name= "LG Electronics lgdt330x VSB/QAM Frontend", | 764 | .name= "LG Electronics LGDT3303 VSB/QAM Frontend", |
| 574 | .type = FE_ATSC, | 765 | .type = FE_ATSC, |
| 575 | .frequency_min= 54000000, | 766 | .frequency_min= 54000000, |
| 576 | .frequency_max= 858000000, | 767 | .frequency_max= 858000000, |
| @@ -584,15 +775,15 @@ static struct dvb_frontend_ops lgdt330x_ops = { | |||
| 584 | .set_frontend = lgdt330x_set_parameters, | 775 | .set_frontend = lgdt330x_set_parameters, |
| 585 | .get_frontend = lgdt330x_get_frontend, | 776 | .get_frontend = lgdt330x_get_frontend, |
| 586 | .get_tune_settings = lgdt330x_get_tune_settings, | 777 | .get_tune_settings = lgdt330x_get_tune_settings, |
| 587 | .read_status = lgdt330x_read_status, | 778 | .read_status = lgdt3303_read_status, |
| 588 | .read_ber = lgdt330x_read_ber, | 779 | .read_ber = lgdt330x_read_ber, |
| 589 | .read_signal_strength = lgdt330x_read_signal_strength, | 780 | .read_signal_strength = lgdt330x_read_signal_strength, |
| 590 | .read_snr = lgdt330x_read_snr, | 781 | .read_snr = lgdt3303_read_snr, |
| 591 | .read_ucblocks = lgdt330x_read_ucblocks, | 782 | .read_ucblocks = lgdt330x_read_ucblocks, |
| 592 | .release = lgdt330x_release, | 783 | .release = lgdt330x_release, |
| 593 | }; | 784 | }; |
| 594 | 785 | ||
| 595 | MODULE_DESCRIPTION("lgdt330x [DViCO FusionHDTV 3 Gold] (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); | 786 | MODULE_DESCRIPTION("LGDT330X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver"); |
| 596 | MODULE_AUTHOR("Wilson Michaels"); | 787 | MODULE_AUTHOR("Wilson Michaels"); |
| 597 | MODULE_LICENSE("GPL"); | 788 | MODULE_LICENSE("GPL"); |
| 598 | 789 | ||
| @@ -601,6 +792,5 @@ EXPORT_SYMBOL(lgdt330x_attach); | |||
| 601 | /* | 792 | /* |
| 602 | * Local variables: | 793 | * Local variables: |
| 603 | * c-basic-offset: 8 | 794 | * c-basic-offset: 8 |
| 604 | * compile-command: "make DVB=1" | ||
| 605 | * End: | 795 | * End: |
| 606 | */ | 796 | */ |
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h index 04986f8e7565..e209ba1e47c5 100644 --- a/drivers/media/dvb/frontends/lgdt330x.h +++ b/drivers/media/dvb/frontends/lgdt330x.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for LGDT3302 & LGDT3303 (DViCO FustionHDTV Gold) - VSB/QAM | 2 | * Support for LGDT3302 and LGDT3303 - VSB/QAM |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> | 4 | * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> |
| 5 | * | 5 | * |
| @@ -24,14 +24,26 @@ | |||
| 24 | 24 | ||
| 25 | #include <linux/dvb/frontend.h> | 25 | #include <linux/dvb/frontend.h> |
| 26 | 26 | ||
| 27 | typedef enum lg_chip_t { | ||
| 28 | UNDEFINED, | ||
| 29 | LGDT3302, | ||
| 30 | LGDT3303 | ||
| 31 | }lg_chip_type; | ||
| 32 | |||
| 27 | struct lgdt330x_config | 33 | struct lgdt330x_config |
| 28 | { | 34 | { |
| 29 | /* The demodulator's i2c address */ | 35 | /* The demodulator's i2c address */ |
| 30 | u8 demod_address; | 36 | u8 demod_address; |
| 31 | 37 | ||
| 38 | /* LG demodulator chip LGDT3302 or LGDT3303 */ | ||
| 39 | lg_chip_type demod_chip; | ||
| 40 | |||
| 41 | /* MPEG hardware interface - 0:parallel 1:serial */ | ||
| 42 | int serial_mpeg; | ||
| 43 | |||
| 32 | /* PLL interface */ | 44 | /* PLL interface */ |
| 33 | int (*pll_rf_set) (struct dvb_frontend* fe, int index); | 45 | int (*pll_rf_set) (struct dvb_frontend* fe, int index); |
| 34 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pll_address); | 46 | int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); |
| 35 | 47 | ||
| 36 | /* Need to set device param for start_dma */ | 48 | /* Need to set device param for start_dma */ |
| 37 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); | 49 | int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); |
diff --git a/drivers/media/dvb/frontends/lgdt330x_priv.h b/drivers/media/dvb/frontends/lgdt330x_priv.h index 4143ce8f1a95..59b7c5b9012d 100644 --- a/drivers/media/dvb/frontends/lgdt330x_priv.h +++ b/drivers/media/dvb/frontends/lgdt330x_priv.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Support for LGDT3302 & LGDT3303 (DViCO FustionHDTV Gold) - VSB/QAM | 2 | * Support for LGDT3302 and LGDT3303 - VSB/QAM |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> | 4 | * Copyright (C) 2005 Wilson Michaels <wilsonmichaels@earthlink.net> |
| 5 | * | 5 | * |
| @@ -57,8 +57,10 @@ enum I2C_REG { | |||
| 57 | PH_ERR1= 0x4a, | 57 | PH_ERR1= 0x4a, |
| 58 | PH_ERR2= 0x4b, | 58 | PH_ERR2= 0x4b, |
| 59 | DEMUX_CONTROL= 0x66, | 59 | DEMUX_CONTROL= 0x66, |
| 60 | PACKET_ERR_COUNTER1= 0x6a, | 60 | LGDT3302_PACKET_ERR_COUNTER1= 0x6a, |
| 61 | PACKET_ERR_COUNTER2= 0x6b, | 61 | LGDT3302_PACKET_ERR_COUNTER2= 0x6b, |
| 62 | LGDT3303_PACKET_ERR_COUNTER1= 0x8b, | ||
| 63 | LGDT3303_PACKET_ERR_COUNTER2= 0x8c, | ||
| 62 | }; | 64 | }; |
| 63 | 65 | ||
| 64 | #endif /* _LGDT330X_PRIV_ */ | 66 | #endif /* _LGDT330X_PRIV_ */ |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index ef0e9a85c359..78d223257a68 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * $Id: cx88-dvb.c,v 1.54 2005/07/25 05:13:50 mkrufky Exp $ | 2 | * $Id: cx88-dvb.c,v 1.58 2005/08/07 09:24:08 mkrufky Exp $ |
| 3 | * | 3 | * |
| 4 | * device driver for Conexant 2388x based TV cards | 4 | * device driver for Conexant 2388x based TV cards |
| 5 | * MPEG Transport Stream (DVB) routines | 5 | * MPEG Transport Stream (DVB) routines |
| @@ -208,14 +208,26 @@ static struct or51132_config pchdtv_hd3000 = { | |||
| 208 | 208 | ||
| 209 | #ifdef HAVE_LGDT330X | 209 | #ifdef HAVE_LGDT330X |
| 210 | static int lgdt330x_pll_set(struct dvb_frontend* fe, | 210 | static int lgdt330x_pll_set(struct dvb_frontend* fe, |
| 211 | struct dvb_frontend_parameters* params, | 211 | struct dvb_frontend_parameters* params) |
| 212 | u8* pllbuf) | ||
| 213 | { | 212 | { |
| 214 | struct cx8802_dev *dev= fe->dvb->priv; | 213 | struct cx8802_dev *dev= fe->dvb->priv; |
| 214 | u8 buf[4]; | ||
| 215 | struct i2c_msg msg = | ||
| 216 | { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; | ||
| 217 | int err; | ||
| 215 | 218 | ||
| 216 | pllbuf[0] = dev->core->pll_addr; | 219 | dvb_pll_configure(dev->core->pll_desc, buf, params->frequency, 0); |
| 217 | dvb_pll_configure(dev->core->pll_desc, &pllbuf[1], | 220 | dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", |
| 218 | params->frequency, 0); | 221 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); |
| 222 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
| 223 | printk(KERN_WARNING "cx88-dvb: %s error " | ||
| 224 | "(addr %02x <- %02x, err = %i)\n", | ||
| 225 | __FUNCTION__, buf[0], buf[1], err); | ||
| 226 | if (err < 0) | ||
| 227 | return err; | ||
| 228 | else | ||
| 229 | return -EREMOTEIO; | ||
| 230 | } | ||
| 219 | return 0; | 231 | return 0; |
| 220 | } | 232 | } |
| 221 | 233 | ||
| @@ -244,6 +256,8 @@ static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured) | |||
| 244 | 256 | ||
| 245 | static struct lgdt330x_config fusionhdtv_3_gold = { | 257 | static struct lgdt330x_config fusionhdtv_3_gold = { |
| 246 | .demod_address = 0x0e, | 258 | .demod_address = 0x0e, |
| 259 | .demod_chip = LGDT3302, | ||
| 260 | .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ | ||
| 247 | .pll_set = lgdt330x_pll_set, | 261 | .pll_set = lgdt330x_pll_set, |
| 248 | .set_ts_params = lgdt330x_set_ts_param, | 262 | .set_ts_params = lgdt330x_set_ts_param, |
| 249 | }; | 263 | }; |
diff --git a/drivers/message/i2o/Kconfig b/drivers/message/i2o/Kconfig index 06e8eb19a05c..43a942a29c2e 100644 --- a/drivers/message/i2o/Kconfig +++ b/drivers/message/i2o/Kconfig | |||
| @@ -53,6 +53,9 @@ config I2O_CONFIG | |||
| 53 | To compile this support as a module, choose M here: the | 53 | To compile this support as a module, choose M here: the |
| 54 | module will be called i2o_config. | 54 | module will be called i2o_config. |
| 55 | 55 | ||
| 56 | Note: If you want to use the new API you have to download the | ||
| 57 | i2o_config patch from http://i2o.shadowconnect.com/ | ||
| 58 | |||
| 56 | config I2O_CONFIG_OLD_IOCTL | 59 | config I2O_CONFIG_OLD_IOCTL |
| 57 | bool "Enable ioctls (OBSOLETE)" | 60 | bool "Enable ioctls (OBSOLETE)" |
| 58 | depends on I2O_CONFIG | 61 | depends on I2O_CONFIG |
diff --git a/drivers/message/i2o/config-osm.c b/drivers/message/i2o/config-osm.c index fe2e7afc9eae..af32ab4e90cd 100644 --- a/drivers/message/i2o/config-osm.c +++ b/drivers/message/i2o/config-osm.c | |||
| @@ -30,503 +30,9 @@ | |||
| 30 | 30 | ||
| 31 | static struct i2o_driver i2o_config_driver; | 31 | static struct i2o_driver i2o_config_driver; |
| 32 | 32 | ||
| 33 | /* Special file operations for sysfs */ | ||
| 34 | struct fops_attribute { | ||
| 35 | struct bin_attribute bin; | ||
| 36 | struct file_operations fops; | ||
| 37 | }; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * sysfs_read_dummy | ||
| 41 | */ | ||
| 42 | static ssize_t sysfs_read_dummy(struct kobject *kobj, char *buf, loff_t offset, | ||
| 43 | size_t count) | ||
| 44 | { | ||
| 45 | return 0; | ||
| 46 | }; | ||
| 47 | |||
| 48 | /** | ||
| 49 | * sysfs_write_dummy | ||
| 50 | */ | ||
| 51 | static ssize_t sysfs_write_dummy(struct kobject *kobj, char *buf, loff_t offset, | ||
| 52 | size_t count) | ||
| 53 | { | ||
| 54 | return 0; | ||
| 55 | }; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * sysfs_create_fops_file - Creates attribute with special file operations | ||
| 59 | * @kobj: kobject which should contains the attribute | ||
| 60 | * @attr: attributes which should be used to create file | ||
| 61 | * | ||
| 62 | * First creates attribute @attr in kobject @kobj. If it is the first time | ||
| 63 | * this function is called, merge old fops from sysfs with new one and | ||
| 64 | * write it back. Afterwords the new fops will be set for the created | ||
| 65 | * attribute. | ||
| 66 | * | ||
| 67 | * Returns 0 on success or negative error code on failure. | ||
| 68 | */ | ||
| 69 | static int sysfs_create_fops_file(struct kobject *kobj, | ||
| 70 | struct fops_attribute *attr) | ||
| 71 | { | ||
| 72 | struct file_operations tmp, *fops; | ||
| 73 | struct dentry *d; | ||
| 74 | struct qstr qstr; | ||
| 75 | int rc; | ||
| 76 | |||
| 77 | fops = &attr->fops; | ||
| 78 | |||
| 79 | if (fops->read) | ||
| 80 | attr->bin.read = sysfs_read_dummy; | ||
| 81 | |||
| 82 | if (fops->write) | ||
| 83 | attr->bin.write = sysfs_write_dummy; | ||
| 84 | |||
| 85 | if ((rc = sysfs_create_bin_file(kobj, &attr->bin))) | ||
| 86 | return rc; | ||
| 87 | |||
| 88 | qstr.name = attr->bin.attr.name; | ||
| 89 | qstr.len = strlen(qstr.name); | ||
| 90 | qstr.hash = full_name_hash(qstr.name, qstr.len); | ||
| 91 | |||
| 92 | if ((d = lookup_hash(&qstr, kobj->dentry))) { | ||
| 93 | if (!fops->owner) { | ||
| 94 | memcpy(&tmp, d->d_inode->i_fop, sizeof(tmp)); | ||
| 95 | if (fops->read) | ||
| 96 | tmp.read = fops->read; | ||
| 97 | if (fops->write) | ||
| 98 | tmp.write = fops->write; | ||
| 99 | memcpy(fops, &tmp, sizeof(tmp)); | ||
| 100 | } | ||
| 101 | |||
| 102 | d->d_inode->i_fop = fops; | ||
| 103 | } else | ||
| 104 | sysfs_remove_bin_file(kobj, &attr->bin); | ||
| 105 | |||
| 106 | return -ENOENT; | ||
| 107 | }; | ||
| 108 | |||
| 109 | /** | ||
| 110 | * sysfs_remove_fops_file - Remove attribute with special file operations | ||
| 111 | * @kobj: kobject which contains the attribute | ||
| 112 | * @attr: attributes which are used to create file | ||
| 113 | * | ||
| 114 | * Only wrapper arround sysfs_remove_bin_file() | ||
| 115 | * | ||
| 116 | * Returns 0 on success or negative error code on failure. | ||
| 117 | */ | ||
| 118 | static inline int sysfs_remove_fops_file(struct kobject *kobj, | ||
| 119 | struct fops_attribute *attr) | ||
| 120 | { | ||
| 121 | return sysfs_remove_bin_file(kobj, &attr->bin); | ||
| 122 | }; | ||
| 123 | |||
| 124 | /** | ||
| 125 | * i2o_config_read_hrt - Returns the HRT of the controller | ||
| 126 | * @kob: kernel object handle | ||
| 127 | * @buf: buffer into which the HRT should be copied | ||
| 128 | * @off: file offset | ||
| 129 | * @count: number of bytes to read | ||
| 130 | * | ||
| 131 | * Put @count bytes starting at @off into @buf from the HRT of the I2O | ||
| 132 | * controller corresponding to @kobj. | ||
| 133 | * | ||
| 134 | * Returns number of bytes copied into buffer. | ||
| 135 | */ | ||
| 136 | static ssize_t i2o_config_read_hrt(struct kobject *kobj, char *buf, | ||
| 137 | loff_t offset, size_t count) | ||
| 138 | { | ||
| 139 | struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop; | ||
| 140 | i2o_hrt *hrt = c->hrt.virt; | ||
| 141 | |||
| 142 | u32 size = (hrt->num_entries * hrt->entry_len + 2) * 4; | ||
| 143 | |||
| 144 | if (offset > size) | ||
| 145 | return 0; | ||
| 146 | |||
| 147 | if (offset + count > size) | ||
| 148 | count = size - offset; | ||
| 149 | |||
| 150 | memcpy(buf, (u8 *) hrt + offset, count); | ||
| 151 | |||
| 152 | return count; | ||
| 153 | }; | ||
| 154 | |||
| 155 | /** | ||
| 156 | * i2o_config_read_lct - Returns the LCT of the controller | ||
| 157 | * @kob: kernel object handle | ||
| 158 | * @buf: buffer into which the LCT should be copied | ||
| 159 | * @off: file offset | ||
| 160 | * @count: number of bytes to read | ||
| 161 | * | ||
| 162 | * Put @count bytes starting at @off into @buf from the LCT of the I2O | ||
| 163 | * controller corresponding to @kobj. | ||
| 164 | * | ||
| 165 | * Returns number of bytes copied into buffer. | ||
| 166 | */ | ||
| 167 | static ssize_t i2o_config_read_lct(struct kobject *kobj, char *buf, | ||
| 168 | loff_t offset, size_t count) | ||
| 169 | { | ||
| 170 | struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop; | ||
| 171 | u32 size = c->lct->table_size * 4; | ||
| 172 | |||
| 173 | if (offset > size) | ||
| 174 | return 0; | ||
| 175 | |||
| 176 | if (offset + count > size) | ||
| 177 | count = size - offset; | ||
| 178 | |||
| 179 | memcpy(buf, (u8 *) c->lct + offset, count); | ||
| 180 | |||
| 181 | return count; | ||
| 182 | }; | ||
| 183 | |||
| 184 | #define I2O_CONFIG_SW_ATTR(_name,_mode,_type,_swid) \ | ||
| 185 | static ssize_t i2o_config_##_name##_read(struct file *file, char __user *buf, size_t count, loff_t * offset) { \ | ||
| 186 | return i2o_config_sw_read(file, buf, count, offset, _type, _swid); \ | ||
| 187 | };\ | ||
| 188 | \ | ||
| 189 | static ssize_t i2o_config_##_name##_write(struct file *file, const char __user *buf, size_t count, loff_t * offset) { \ | ||
| 190 | return i2o_config_sw_write(file, buf, count, offset, _type, _swid); \ | ||
| 191 | }; \ | ||
| 192 | \ | ||
| 193 | static struct fops_attribute i2o_config_attr_##_name = { \ | ||
| 194 | .bin = { .attr = { .name = __stringify(_name), .mode = _mode, \ | ||
| 195 | .owner = THIS_MODULE }, \ | ||
| 196 | .size = 0, }, \ | ||
| 197 | .fops = { .write = i2o_config_##_name##_write, \ | ||
| 198 | .read = i2o_config_##_name##_read} \ | ||
| 199 | }; | ||
| 200 | |||
| 201 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
| 202 | |||
| 203 | /** | ||
| 204 | * i2o_config_dpt_reagion - Converts type and id to flash region | ||
| 205 | * @swtype: type of software module reading | ||
| 206 | * @swid: id of software which should be read | ||
| 207 | * | ||
| 208 | * Converts type and id from I2O spec to the matching region for DPT / | ||
| 209 | * Adaptec controllers. | ||
| 210 | * | ||
| 211 | * Returns region which match type and id or -1 on error. | ||
| 212 | */ | ||
| 213 | static u32 i2o_config_dpt_region(u8 swtype, u8 swid) | ||
| 214 | { | ||
| 215 | switch (swtype) { | ||
| 216 | case I2O_SOFTWARE_MODULE_IRTOS: | ||
| 217 | /* | ||
| 218 | * content: operation firmware | ||
| 219 | * region size: | ||
| 220 | * 0xbc000 for 2554, 3754, 2564, 3757 | ||
| 221 | * 0x170000 for 2865 | ||
| 222 | * 0x17c000 for 3966 | ||
| 223 | */ | ||
| 224 | if (!swid) | ||
| 225 | return 0; | ||
| 226 | |||
| 227 | break; | ||
| 228 | |||
| 229 | case I2O_SOFTWARE_MODULE_IOP_PRIVATE: | ||
| 230 | /* | ||
| 231 | * content: BIOS and SMOR | ||
| 232 | * BIOS size: first 0x8000 bytes | ||
| 233 | * region size: | ||
| 234 | * 0x40000 for 2554, 3754, 2564, 3757 | ||
| 235 | * 0x80000 for 2865, 3966 | ||
| 236 | */ | ||
| 237 | if (!swid) | ||
| 238 | return 1; | ||
| 239 | |||
| 240 | break; | ||
| 241 | |||
| 242 | case I2O_SOFTWARE_MODULE_IOP_CONFIG: | ||
| 243 | switch (swid) { | ||
| 244 | case 0: | ||
| 245 | /* | ||
| 246 | * content: NVRAM defaults | ||
| 247 | * region size: 0x2000 bytes | ||
| 248 | */ | ||
| 249 | return 2; | ||
| 250 | case 1: | ||
| 251 | /* | ||
| 252 | * content: serial number | ||
| 253 | * region size: 0x2000 bytes | ||
| 254 | */ | ||
| 255 | return 3; | ||
| 256 | } | ||
| 257 | break; | ||
| 258 | } | ||
| 259 | |||
| 260 | return -1; | ||
| 261 | }; | ||
| 262 | |||
| 263 | #endif | ||
| 264 | |||
| 265 | /** | ||
| 266 | * i2o_config_sw_read - Read a software module from controller | ||
| 267 | * @file: file pointer | ||
| 268 | * @buf: buffer into which the data should be copied | ||
| 269 | * @count: number of bytes to read | ||
| 270 | * @off: file offset | ||
| 271 | * @swtype: type of software module reading | ||
| 272 | * @swid: id of software which should be read | ||
| 273 | * | ||
| 274 | * Transfers @count bytes at offset @offset from IOP into buffer using | ||
| 275 | * type @swtype and id @swid as described in I2O spec. | ||
| 276 | * | ||
| 277 | * Returns number of bytes copied into buffer or error code on failure. | ||
| 278 | */ | ||
| 279 | static ssize_t i2o_config_sw_read(struct file *file, char __user * buf, | ||
| 280 | size_t count, loff_t * offset, u8 swtype, | ||
| 281 | u32 swid) | ||
| 282 | { | ||
| 283 | struct sysfs_dirent *sd = file->f_dentry->d_parent->d_fsdata; | ||
| 284 | struct kobject *kobj = sd->s_element; | ||
| 285 | struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop; | ||
| 286 | u32 m, function = I2O_CMD_SW_UPLOAD; | ||
| 287 | struct i2o_dma buffer; | ||
| 288 | struct i2o_message __iomem *msg; | ||
| 289 | u32 __iomem *mptr; | ||
| 290 | int rc, status; | ||
| 291 | |||
| 292 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | ||
| 293 | if (m == I2O_QUEUE_EMPTY) | ||
| 294 | return -EBUSY; | ||
| 295 | |||
| 296 | mptr = &msg->body[3]; | ||
| 297 | |||
| 298 | if ((rc = i2o_dma_alloc(&c->pdev->dev, &buffer, count, GFP_KERNEL))) { | ||
| 299 | i2o_msg_nop(c, m); | ||
| 300 | return rc; | ||
| 301 | } | ||
| 302 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
| 303 | if (c->adaptec) { | ||
| 304 | mptr = &msg->body[4]; | ||
| 305 | function = I2O_CMD_PRIVATE; | ||
| 306 | |||
| 307 | writel(TEN_WORD_MSG_SIZE | SGL_OFFSET_8, &msg->u.head[0]); | ||
| 308 | |||
| 309 | writel(I2O_VENDOR_DPT << 16 | I2O_DPT_FLASH_READ, | ||
| 310 | &msg->body[0]); | ||
| 311 | writel(i2o_config_dpt_region(swtype, swid), &msg->body[1]); | ||
| 312 | writel(*offset, &msg->body[2]); | ||
| 313 | writel(count, &msg->body[3]); | ||
| 314 | } else | ||
| 315 | #endif | ||
| 316 | writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]); | ||
| 317 | |||
| 318 | writel(0xD0000000 | count, mptr++); | ||
| 319 | writel(buffer.phys, mptr); | ||
| 320 | |||
| 321 | writel(function << 24 | HOST_TID << 12 | ADAPTER_TID, &msg->u.head[1]); | ||
| 322 | writel(i2o_config_driver.context, &msg->u.head[2]); | ||
| 323 | writel(0, &msg->u.head[3]); | ||
| 324 | |||
| 325 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
| 326 | if (!c->adaptec) | ||
| 327 | #endif | ||
| 328 | { | ||
| 329 | writel((u32) swtype << 16 | (u32) 1 << 8, &msg->body[0]); | ||
| 330 | writel(0, &msg->body[1]); | ||
| 331 | writel(swid, &msg->body[2]); | ||
| 332 | } | ||
| 333 | |||
| 334 | status = i2o_msg_post_wait_mem(c, m, 60, &buffer); | ||
| 335 | |||
| 336 | if (status == I2O_POST_WAIT_OK) { | ||
| 337 | if (!(rc = copy_to_user(buf, buffer.virt, count))) { | ||
| 338 | rc = count; | ||
| 339 | *offset += count; | ||
| 340 | } | ||
| 341 | } else | ||
| 342 | rc = -EIO; | ||
| 343 | |||
| 344 | if (status != -ETIMEDOUT) | ||
| 345 | i2o_dma_free(&c->pdev->dev, &buffer); | ||
| 346 | |||
| 347 | return rc; | ||
| 348 | }; | ||
| 349 | |||
| 350 | /** | ||
| 351 | * i2o_config_sw_write - Write a software module to controller | ||
| 352 | * @file: file pointer | ||
| 353 | * @buf: buffer into which the data should be copied | ||
| 354 | * @count: number of bytes to read | ||
| 355 | * @off: file offset | ||
| 356 | * @swtype: type of software module writing | ||
| 357 | * @swid: id of software which should be written | ||
| 358 | * | ||
| 359 | * Transfers @count bytes at offset @offset from buffer to IOP using | ||
| 360 | * type @swtype and id @swid as described in I2O spec. | ||
| 361 | * | ||
| 362 | * Returns number of bytes copied from buffer or error code on failure. | ||
| 363 | */ | ||
| 364 | static ssize_t i2o_config_sw_write(struct file *file, const char __user * buf, | ||
| 365 | size_t count, loff_t * offset, u8 swtype, | ||
| 366 | u32 swid) | ||
| 367 | { | ||
| 368 | struct sysfs_dirent *sd = file->f_dentry->d_parent->d_fsdata; | ||
| 369 | struct kobject *kobj = sd->s_element; | ||
| 370 | struct i2o_controller *c = kobj_to_i2o_device(kobj)->iop; | ||
| 371 | u32 m, function = I2O_CMD_SW_DOWNLOAD; | ||
| 372 | struct i2o_dma buffer; | ||
| 373 | struct i2o_message __iomem *msg; | ||
| 374 | u32 __iomem *mptr; | ||
| 375 | int rc, status; | ||
| 376 | |||
| 377 | m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET); | ||
| 378 | if (m == I2O_QUEUE_EMPTY) | ||
| 379 | return -EBUSY; | ||
| 380 | |||
| 381 | mptr = &msg->body[3]; | ||
| 382 | |||
| 383 | if ((rc = i2o_dma_alloc(&c->pdev->dev, &buffer, count, GFP_KERNEL))) | ||
| 384 | goto nop_msg; | ||
| 385 | |||
| 386 | if ((rc = copy_from_user(buffer.virt, buf, count))) | ||
| 387 | goto free_buffer; | ||
| 388 | |||
| 389 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
| 390 | if (c->adaptec) { | ||
| 391 | mptr = &msg->body[4]; | ||
| 392 | function = I2O_CMD_PRIVATE; | ||
| 393 | |||
| 394 | writel(TEN_WORD_MSG_SIZE | SGL_OFFSET_8, &msg->u.head[0]); | ||
| 395 | |||
| 396 | writel(I2O_VENDOR_DPT << 16 | I2O_DPT_FLASH_WRITE, | ||
| 397 | &msg->body[0]); | ||
| 398 | writel(i2o_config_dpt_region(swtype, swid), &msg->body[1]); | ||
| 399 | writel(*offset, &msg->body[2]); | ||
| 400 | writel(count, &msg->body[3]); | ||
| 401 | } else | ||
| 402 | #endif | ||
| 403 | writel(NINE_WORD_MSG_SIZE | SGL_OFFSET_7, &msg->u.head[0]); | ||
| 404 | |||
| 405 | writel(0xD4000000 | count, mptr++); | ||
| 406 | writel(buffer.phys, mptr); | ||
| 407 | |||
| 408 | writel(function << 24 | HOST_TID << 12 | ADAPTER_TID, &msg->u.head[1]); | ||
| 409 | writel(i2o_config_driver.context, &msg->u.head[2]); | ||
| 410 | writel(0, &msg->u.head[3]); | ||
| 411 | |||
| 412 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
| 413 | if (!c->adaptec) | ||
| 414 | #endif | ||
| 415 | { | ||
| 416 | writel((u32) swtype << 16 | (u32) 1 << 8, &msg->body[0]); | ||
| 417 | writel(0, &msg->body[1]); | ||
| 418 | writel(swid, &msg->body[2]); | ||
| 419 | } | ||
| 420 | |||
| 421 | status = i2o_msg_post_wait_mem(c, m, 60, &buffer); | ||
| 422 | |||
| 423 | if (status != -ETIMEDOUT) | ||
| 424 | i2o_dma_free(&c->pdev->dev, &buffer); | ||
| 425 | |||
| 426 | if (status != I2O_POST_WAIT_OK) | ||
| 427 | return -EIO; | ||
| 428 | |||
| 429 | *offset += count; | ||
| 430 | |||
| 431 | return count; | ||
| 432 | |||
| 433 | free_buffer: | ||
| 434 | i2o_dma_free(&c->pdev->dev, &buffer); | ||
| 435 | |||
| 436 | nop_msg: | ||
| 437 | i2o_msg_nop(c, m); | ||
| 438 | |||
| 439 | return rc; | ||
| 440 | }; | ||
| 441 | |||
| 442 | /* attribute for HRT in sysfs */ | ||
| 443 | static struct bin_attribute i2o_config_hrt_attr = { | ||
| 444 | .attr = { | ||
| 445 | .name = "hrt", | ||
| 446 | .mode = S_IRUGO, | ||
| 447 | .owner = THIS_MODULE}, | ||
| 448 | .size = 0, | ||
| 449 | .read = i2o_config_read_hrt | ||
| 450 | }; | ||
| 451 | |||
| 452 | /* attribute for LCT in sysfs */ | ||
| 453 | static struct bin_attribute i2o_config_lct_attr = { | ||
| 454 | .attr = { | ||
| 455 | .name = "lct", | ||
| 456 | .mode = S_IRUGO, | ||
| 457 | .owner = THIS_MODULE}, | ||
| 458 | .size = 0, | ||
| 459 | .read = i2o_config_read_lct | ||
| 460 | }; | ||
| 461 | |||
| 462 | /* IRTOS firmware access */ | ||
| 463 | I2O_CONFIG_SW_ATTR(irtos, S_IWRSR, I2O_SOFTWARE_MODULE_IRTOS, 0); | ||
| 464 | |||
| 465 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
| 466 | |||
| 467 | /* | ||
| 468 | * attribute for BIOS / SMOR, nvram and serial number access on DPT / Adaptec | ||
| 469 | * controllers | ||
| 470 | */ | ||
| 471 | I2O_CONFIG_SW_ATTR(bios, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_PRIVATE, 0); | ||
| 472 | I2O_CONFIG_SW_ATTR(nvram, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_CONFIG, 0); | ||
| 473 | I2O_CONFIG_SW_ATTR(serial, S_IWRSR, I2O_SOFTWARE_MODULE_IOP_CONFIG, 1); | ||
| 474 | |||
| 475 | #endif | ||
| 476 | |||
| 477 | /** | ||
| 478 | * i2o_config_notify_controller_add - Notify of added controller | ||
| 479 | * @c: the controller which was added | ||
| 480 | * | ||
| 481 | * If a I2O controller is added, we catch the notification to add sysfs | ||
| 482 | * entries. | ||
| 483 | */ | ||
| 484 | static void i2o_config_notify_controller_add(struct i2o_controller *c) | ||
| 485 | { | ||
| 486 | struct kobject *kobj = &c->exec->device.kobj; | ||
| 487 | |||
| 488 | sysfs_create_bin_file(kobj, &i2o_config_hrt_attr); | ||
| 489 | sysfs_create_bin_file(kobj, &i2o_config_lct_attr); | ||
| 490 | |||
| 491 | sysfs_create_fops_file(kobj, &i2o_config_attr_irtos); | ||
| 492 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
| 493 | if (c->adaptec) { | ||
| 494 | sysfs_create_fops_file(kobj, &i2o_config_attr_bios); | ||
| 495 | sysfs_create_fops_file(kobj, &i2o_config_attr_nvram); | ||
| 496 | sysfs_create_fops_file(kobj, &i2o_config_attr_serial); | ||
| 497 | } | ||
| 498 | #endif | ||
| 499 | }; | ||
| 500 | |||
| 501 | /** | ||
| 502 | * i2o_config_notify_controller_remove - Notify of removed controller | ||
| 503 | * @c: the controller which was removed | ||
| 504 | * | ||
| 505 | * If a I2O controller is removed, we catch the notification to remove the | ||
| 506 | * sysfs entries. | ||
| 507 | */ | ||
| 508 | static void i2o_config_notify_controller_remove(struct i2o_controller *c) | ||
| 509 | { | ||
| 510 | struct kobject *kobj = &c->exec->device.kobj; | ||
| 511 | |||
| 512 | #ifdef CONFIG_I2O_EXT_ADAPTEC | ||
| 513 | if (c->adaptec) { | ||
| 514 | sysfs_remove_fops_file(kobj, &i2o_config_attr_serial); | ||
| 515 | sysfs_remove_fops_file(kobj, &i2o_config_attr_nvram); | ||
| 516 | sysfs_remove_fops_file(kobj, &i2o_config_attr_bios); | ||
| 517 | } | ||
| 518 | #endif | ||
| 519 | sysfs_remove_fops_file(kobj, &i2o_config_attr_irtos); | ||
| 520 | |||
| 521 | sysfs_remove_bin_file(kobj, &i2o_config_lct_attr); | ||
| 522 | sysfs_remove_bin_file(kobj, &i2o_config_hrt_attr); | ||
| 523 | }; | ||
| 524 | |||
| 525 | /* Config OSM driver struct */ | 33 | /* Config OSM driver struct */ |
| 526 | static struct i2o_driver i2o_config_driver = { | 34 | static struct i2o_driver i2o_config_driver = { |
| 527 | .name = OSM_NAME, | 35 | .name = OSM_NAME, |
| 528 | .notify_controller_add = i2o_config_notify_controller_add, | ||
| 529 | .notify_controller_remove = i2o_config_notify_controller_remove | ||
| 530 | }; | 36 | }; |
| 531 | 37 | ||
| 532 | #ifdef CONFIG_I2O_CONFIG_OLD_IOCTL | 38 | #ifdef CONFIG_I2O_CONFIG_OLD_IOCTL |
diff --git a/drivers/message/i2o/pci.c b/drivers/message/i2o/pci.c index 7a60fd7be8ad..66c03e882570 100644 --- a/drivers/message/i2o/pci.c +++ b/drivers/message/i2o/pci.c | |||
| @@ -32,6 +32,8 @@ | |||
| 32 | #include <linux/i2o.h> | 32 | #include <linux/i2o.h> |
| 33 | #include "core.h" | 33 | #include "core.h" |
| 34 | 34 | ||
| 35 | #define OSM_DESCRIPTION "I2O-subsystem" | ||
| 36 | |||
| 35 | /* PCI device id table for all I2O controllers */ | 37 | /* PCI device id table for all I2O controllers */ |
| 36 | static struct pci_device_id __devinitdata i2o_pci_ids[] = { | 38 | static struct pci_device_id __devinitdata i2o_pci_ids[] = { |
| 37 | {PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)}, | 39 | {PCI_DEVICE_CLASS(PCI_CLASS_INTELLIGENT_I2O << 8, 0xffff00)}, |
| @@ -66,6 +68,8 @@ static void i2o_pci_free(struct i2o_controller *c) | |||
| 66 | 68 | ||
| 67 | if (c->base.virt) | 69 | if (c->base.virt) |
| 68 | iounmap(c->base.virt); | 70 | iounmap(c->base.virt); |
| 71 | |||
| 72 | pci_release_regions(c->pdev); | ||
| 69 | } | 73 | } |
| 70 | 74 | ||
| 71 | /** | 75 | /** |
| @@ -84,6 +88,11 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) | |||
| 84 | struct device *dev = &pdev->dev; | 88 | struct device *dev = &pdev->dev; |
| 85 | int i; | 89 | int i; |
| 86 | 90 | ||
| 91 | if (pci_request_regions(pdev, OSM_DESCRIPTION)) { | ||
| 92 | printk(KERN_ERR "%s: device already claimed\n", c->name); | ||
| 93 | return -ENODEV; | ||
| 94 | } | ||
| 95 | |||
| 87 | for (i = 0; i < 6; i++) { | 96 | for (i = 0; i < 6; i++) { |
| 88 | /* Skip I/O spaces */ | 97 | /* Skip I/O spaces */ |
| 89 | if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) { | 98 | if (!(pci_resource_flags(pdev, i) & IORESOURCE_IO)) { |
| @@ -138,6 +147,7 @@ static int __devinit i2o_pci_alloc(struct i2o_controller *c) | |||
| 138 | c->base.virt = ioremap_nocache(c->base.phys, c->base.len); | 147 | c->base.virt = ioremap_nocache(c->base.phys, c->base.len); |
| 139 | if (!c->base.virt) { | 148 | if (!c->base.virt) { |
| 140 | printk(KERN_ERR "%s: Unable to map controller.\n", c->name); | 149 | printk(KERN_ERR "%s: Unable to map controller.\n", c->name); |
| 150 | i2o_pci_free(c); | ||
| 141 | return -ENOMEM; | 151 | return -ENOMEM; |
| 142 | } | 152 | } |
| 143 | 153 | ||
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 201a550f0bcc..368b8fb14023 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -66,8 +66,8 @@ | |||
| 66 | 66 | ||
| 67 | #define DRV_MODULE_NAME "tg3" | 67 | #define DRV_MODULE_NAME "tg3" |
| 68 | #define PFX DRV_MODULE_NAME ": " | 68 | #define PFX DRV_MODULE_NAME ": " |
| 69 | #define DRV_MODULE_VERSION "3.34" | 69 | #define DRV_MODULE_VERSION "3.35" |
| 70 | #define DRV_MODULE_RELDATE "July 25, 2005" | 70 | #define DRV_MODULE_RELDATE "August 6, 2005" |
| 71 | 71 | ||
| 72 | #define TG3_DEF_MAC_MODE 0 | 72 | #define TG3_DEF_MAC_MODE 0 |
| 73 | #define TG3_DEF_RX_MODE 0 | 73 | #define TG3_DEF_RX_MODE 0 |
| @@ -10421,6 +10421,12 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
| 10421 | 10421 | ||
| 10422 | tg3_init_coal(tp); | 10422 | tg3_init_coal(tp); |
| 10423 | 10423 | ||
| 10424 | /* Now that we have fully setup the chip, save away a snapshot | ||
| 10425 | * of the PCI config space. We need to restore this after | ||
| 10426 | * GRC_MISC_CFG core clock resets and some resume events. | ||
| 10427 | */ | ||
| 10428 | pci_save_state(tp->pdev); | ||
| 10429 | |||
| 10424 | err = register_netdev(dev); | 10430 | err = register_netdev(dev); |
| 10425 | if (err) { | 10431 | if (err) { |
| 10426 | printk(KERN_ERR PFX "Cannot register net device, " | 10432 | printk(KERN_ERR PFX "Cannot register net device, " |
| @@ -10430,12 +10436,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
| 10430 | 10436 | ||
| 10431 | pci_set_drvdata(pdev, dev); | 10437 | pci_set_drvdata(pdev, dev); |
| 10432 | 10438 | ||
| 10433 | /* Now that we have fully setup the chip, save away a snapshot | ||
| 10434 | * of the PCI config space. We need to restore this after | ||
| 10435 | * GRC_MISC_CFG core clock resets and some resume events. | ||
| 10436 | */ | ||
| 10437 | pci_save_state(tp->pdev); | ||
| 10438 | |||
| 10439 | printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ", | 10439 | printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (PCI%s:%s:%s) %sBaseT Ethernet ", |
| 10440 | dev->name, | 10440 | dev->name, |
| 10441 | tp->board_part_number, | 10441 | tp->board_part_number, |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 8d0968bd527e..a9160ad16581 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -373,6 +373,25 @@ static void __devinit quirk_vt82c686_acpi(struct pci_dev *dev) | |||
| 373 | } | 373 | } |
| 374 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi ); | 374 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_vt82c686_acpi ); |
| 375 | 375 | ||
| 376 | /* | ||
| 377 | * VIA VT8235 ISA Bridge: Two IO regions pointed to by words at | ||
| 378 | * 0x88 (128 bytes of power management registers) | ||
| 379 | * 0xd0 (16 bytes of SMB registers) | ||
| 380 | */ | ||
| 381 | static void __devinit quirk_vt8235_acpi(struct pci_dev *dev) | ||
| 382 | { | ||
| 383 | u16 pm, smb; | ||
| 384 | |||
| 385 | pci_read_config_word(dev, 0x88, &pm); | ||
| 386 | pm &= PCI_BASE_ADDRESS_IO_MASK; | ||
| 387 | quirk_io_region(dev, pm, 128, PCI_BRIDGE_RESOURCES); | ||
| 388 | |||
| 389 | pci_read_config_word(dev, 0xd0, &smb); | ||
| 390 | smb &= PCI_BASE_ADDRESS_IO_MASK; | ||
| 391 | quirk_io_region(dev, smb, 16, PCI_BRIDGE_RESOURCES + 1); | ||
| 392 | } | ||
| 393 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235_acpi); | ||
| 394 | |||
| 376 | 395 | ||
| 377 | #ifdef CONFIG_X86_IO_APIC | 396 | #ifdef CONFIG_X86_IO_APIC |
| 378 | 397 | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 1ca21d2ba11c..84eedc965688 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
| @@ -33,6 +33,11 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
| 33 | u32 new, check, mask; | 33 | u32 new, check, mask; |
| 34 | int reg; | 34 | int reg; |
| 35 | 35 | ||
| 36 | /* Ignore resources for unimplemented BARs and unused resource slots | ||
| 37 | for 64 bit BARs. */ | ||
| 38 | if (!res->flags) | ||
| 39 | return; | ||
| 40 | |||
| 36 | pcibios_resource_to_bus(dev, ®ion, res); | 41 | pcibios_resource_to_bus(dev, ®ion, res); |
| 37 | 42 | ||
| 38 | pr_debug(" got res [%lx:%lx] bus [%lx:%lx] flags %lx for " | 43 | pr_debug(" got res [%lx:%lx] bus [%lx:%lx] flags %lx for " |
| @@ -67,7 +72,7 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
| 67 | 72 | ||
| 68 | if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == | 73 | if ((new & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK)) == |
| 69 | (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) { | 74 | (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64)) { |
| 70 | new = 0; /* currently everyone zeros the high address */ | 75 | new = region.start >> 16 >> 16; |
| 71 | pci_write_config_dword(dev, reg + 4, new); | 76 | pci_write_config_dword(dev, reg + 4, new); |
| 72 | pci_read_config_dword(dev, reg + 4, &check); | 77 | pci_read_config_dword(dev, reg + 4, &check); |
| 73 | if (check != new) { | 78 | if (check != new) { |
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c index 91e7457d5b04..62fd705203fb 100644 --- a/drivers/pcmcia/yenta_socket.c +++ b/drivers/pcmcia/yenta_socket.c | |||
| @@ -605,9 +605,8 @@ static int yenta_search_res(struct yenta_socket *socket, struct resource *res, | |||
| 605 | 605 | ||
| 606 | static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end) | 606 | static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type, int addr_start, int addr_end) |
| 607 | { | 607 | { |
| 608 | struct pci_bus *bus; | ||
| 609 | struct resource *root, *res; | 608 | struct resource *root, *res; |
| 610 | u32 start, end; | 609 | struct pci_bus_region region; |
| 611 | unsigned mask; | 610 | unsigned mask; |
| 612 | 611 | ||
| 613 | res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr; | 612 | res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr; |
| @@ -620,15 +619,13 @@ static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned typ | |||
| 620 | if (type & IORESOURCE_IO) | 619 | if (type & IORESOURCE_IO) |
| 621 | mask = ~3; | 620 | mask = ~3; |
| 622 | 621 | ||
| 623 | bus = socket->dev->subordinate; | 622 | res->name = socket->dev->subordinate->name; |
| 624 | res->name = bus->name; | ||
| 625 | res->flags = type; | 623 | res->flags = type; |
| 626 | 624 | ||
| 627 | start = config_readl(socket, addr_start) & mask; | 625 | region.start = config_readl(socket, addr_start) & mask; |
| 628 | end = config_readl(socket, addr_end) | ~mask; | 626 | region.end = config_readl(socket, addr_end) | ~mask; |
| 629 | if (start && end > start && !override_bios) { | 627 | if (region.start && region.end > region.start && !override_bios) { |
| 630 | res->start = start; | 628 | pcibios_bus_to_resource(socket->dev, res, ®ion); |
| 631 | res->end = end; | ||
| 632 | root = pci_find_parent_resource(socket->dev, res); | 629 | root = pci_find_parent_resource(socket->dev, res); |
| 633 | if (root && (request_resource(root, res) == 0)) | 630 | if (root && (request_resource(root, res) == 0)) |
| 634 | return; | 631 | return; |
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c index 8f4d2999af8e..79c74f3a11f5 100644 --- a/drivers/s390/net/qeth_main.c +++ b/drivers/s390/net/qeth_main.c | |||
| @@ -8120,20 +8120,22 @@ static struct notifier_block qeth_ip6_notifier = { | |||
| 8120 | #endif | 8120 | #endif |
| 8121 | 8121 | ||
| 8122 | static int | 8122 | static int |
| 8123 | qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) | 8123 | __qeth_reboot_event_card(struct device *dev, void *data) |
| 8124 | { | 8124 | { |
| 8125 | |||
| 8126 | struct device *entry; | ||
| 8127 | struct qeth_card *card; | 8125 | struct qeth_card *card; |
| 8128 | 8126 | ||
| 8129 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | 8127 | card = (struct qeth_card *) dev->driver_data; |
| 8130 | list_for_each_entry(entry, &qeth_ccwgroup_driver.driver.devices, | 8128 | qeth_clear_ip_list(card, 0, 0); |
| 8131 | driver_list) { | 8129 | qeth_qdio_clear_card(card, 0); |
| 8132 | card = (struct qeth_card *) entry->driver_data; | 8130 | return 0; |
| 8133 | qeth_clear_ip_list(card, 0, 0); | 8131 | } |
| 8134 | qeth_qdio_clear_card(card, 0); | 8132 | |
| 8135 | } | 8133 | static int |
| 8136 | up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | 8134 | qeth_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) |
| 8135 | { | ||
| 8136 | |||
| 8137 | driver_for_each_device(&qeth_ccwgroup_driver.driver, NULL, NULL, | ||
| 8138 | __qeth_reboot_event_card); | ||
| 8137 | return NOTIFY_DONE; | 8139 | return NOTIFY_DONE; |
| 8138 | } | 8140 | } |
| 8139 | 8141 | ||
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c index 04719196fd20..f2ccfea8fdb8 100644 --- a/drivers/s390/net/qeth_proc.c +++ b/drivers/s390/net/qeth_proc.c | |||
| @@ -27,23 +27,33 @@ const char *VERSION_QETH_PROC_C = "$Revision: 1.13 $"; | |||
| 27 | #define QETH_PROCFILE_NAME "qeth" | 27 | #define QETH_PROCFILE_NAME "qeth" |
| 28 | static struct proc_dir_entry *qeth_procfile; | 28 | static struct proc_dir_entry *qeth_procfile; |
| 29 | 29 | ||
| 30 | static int | ||
| 31 | qeth_procfile_seq_match(struct device *dev, void *data) | ||
| 32 | { | ||
| 33 | return 1; | ||
| 34 | } | ||
| 35 | |||
| 30 | static void * | 36 | static void * |
| 31 | qeth_procfile_seq_start(struct seq_file *s, loff_t *offset) | 37 | qeth_procfile_seq_start(struct seq_file *s, loff_t *offset) |
| 32 | { | 38 | { |
| 33 | struct list_head *next_card = NULL; | 39 | struct device *dev; |
| 34 | int i = 0; | 40 | loff_t nr; |
| 35 | 41 | ||
| 36 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | 42 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); |
| 37 | 43 | ||
| 38 | if (*offset == 0) | 44 | nr = *offset; |
| 45 | if (nr == 0) | ||
| 39 | return SEQ_START_TOKEN; | 46 | return SEQ_START_TOKEN; |
| 40 | 47 | ||
| 41 | /* get card at pos *offset */ | 48 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, |
| 42 | list_for_each(next_card, &qeth_ccwgroup_driver.driver.devices) | 49 | NULL, qeth_procfile_seq_match); |
| 43 | if (++i == *offset) | ||
| 44 | return next_card; | ||
| 45 | 50 | ||
| 46 | return NULL; | 51 | /* get card at pos *offset */ |
| 52 | nr = *offset; | ||
| 53 | while (nr-- > 1 && dev) | ||
| 54 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev, | ||
| 55 | NULL, qeth_procfile_seq_match); | ||
| 56 | return (void *) dev; | ||
| 47 | } | 57 | } |
| 48 | 58 | ||
| 49 | static void | 59 | static void |
| @@ -55,23 +65,21 @@ qeth_procfile_seq_stop(struct seq_file *s, void* it) | |||
| 55 | static void * | 65 | static void * |
| 56 | qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) | 66 | qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) |
| 57 | { | 67 | { |
| 58 | struct list_head *next_card = NULL; | 68 | struct device *prev, *next; |
| 59 | struct list_head *current_card; | ||
| 60 | 69 | ||
| 61 | if (it == SEQ_START_TOKEN) { | 70 | if (it == SEQ_START_TOKEN) { |
| 62 | next_card = qeth_ccwgroup_driver.driver.devices.next; | 71 | next = driver_find_device(&qeth_ccwgroup_driver.driver, |
| 63 | if (next_card->next == next_card) /* list empty */ | 72 | NULL, NULL, qeth_procfile_seq_match); |
| 64 | return NULL; | 73 | if (next) |
| 65 | (*offset)++; | 74 | (*offset)++; |
| 66 | } else { | 75 | return (void *) next; |
| 67 | current_card = (struct list_head *)it; | ||
| 68 | if (current_card->next == &qeth_ccwgroup_driver.driver.devices) | ||
| 69 | return NULL; /* end of list reached */ | ||
| 70 | next_card = current_card->next; | ||
| 71 | (*offset)++; | ||
| 72 | } | 76 | } |
| 73 | 77 | prev = (struct device *) it; | |
| 74 | return next_card; | 78 | next = driver_find_device(&qeth_ccwgroup_driver.driver, |
| 79 | prev, NULL, qeth_procfile_seq_match); | ||
| 80 | if (next) | ||
| 81 | (*offset)++; | ||
| 82 | return (void *) next; | ||
| 75 | } | 83 | } |
| 76 | 84 | ||
| 77 | static inline const char * | 85 | static inline const char * |
| @@ -126,7 +134,7 @@ qeth_procfile_seq_show(struct seq_file *s, void *it) | |||
| 126 | "-------------- ---- ------ ---------- ---- " | 134 | "-------------- ---- ------ ---------- ---- " |
| 127 | "---- ----- -----\n"); | 135 | "---- ----- -----\n"); |
| 128 | } else { | 136 | } else { |
| 129 | device = list_entry(it, struct device, driver_list); | 137 | device = (struct device *) it; |
| 130 | card = device->driver_data; | 138 | card = device->driver_data; |
| 131 | seq_printf(s, "%s/%s/%s x%02X %-10s %-14s %-4i ", | 139 | seq_printf(s, "%s/%s/%s x%02X %-10s %-14s %-4i ", |
| 132 | CARD_RDEV_ID(card), | 140 | CARD_RDEV_ID(card), |
| @@ -180,17 +188,20 @@ static struct proc_dir_entry *qeth_perf_procfile; | |||
| 180 | static void * | 188 | static void * |
| 181 | qeth_perf_procfile_seq_start(struct seq_file *s, loff_t *offset) | 189 | qeth_perf_procfile_seq_start(struct seq_file *s, loff_t *offset) |
| 182 | { | 190 | { |
| 183 | struct list_head *next_card = NULL; | 191 | struct device *dev = NULL; |
| 184 | int i = 0; | 192 | int nr; |
| 185 | 193 | ||
| 186 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | 194 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); |
| 187 | /* get card at pos *offset */ | 195 | /* get card at pos *offset */ |
| 188 | list_for_each(next_card, &qeth_ccwgroup_driver.driver.devices){ | 196 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL, |
| 189 | if (i == *offset) | 197 | qeth_procfile_seq_match); |
| 190 | return next_card; | 198 | |
| 191 | i++; | 199 | /* get card at pos *offset */ |
| 192 | } | 200 | nr = *offset; |
| 193 | return NULL; | 201 | while (nr-- > 1 && dev) |
| 202 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev, | ||
| 203 | NULL, qeth_procfile_seq_match); | ||
| 204 | return (void *) dev; | ||
| 194 | } | 205 | } |
| 195 | 206 | ||
| 196 | static void | 207 | static void |
| @@ -202,12 +213,14 @@ qeth_perf_procfile_seq_stop(struct seq_file *s, void* it) | |||
| 202 | static void * | 213 | static void * |
| 203 | qeth_perf_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) | 214 | qeth_perf_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) |
| 204 | { | 215 | { |
| 205 | struct list_head *current_card = (struct list_head *)it; | 216 | struct device *prev, *next; |
| 206 | 217 | ||
| 207 | if (current_card->next == &qeth_ccwgroup_driver.driver.devices) | 218 | prev = (struct device *) it; |
| 208 | return NULL; /* end of list reached */ | 219 | next = driver_find_device(&qeth_ccwgroup_driver.driver, prev, |
| 209 | (*offset)++; | 220 | NULL, qeth_procfile_seq_match); |
| 210 | return current_card->next; | 221 | if (next) |
| 222 | (*offset)++; | ||
| 223 | return (void *) next; | ||
| 211 | } | 224 | } |
| 212 | 225 | ||
| 213 | static int | 226 | static int |
| @@ -216,7 +229,7 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it) | |||
| 216 | struct device *device; | 229 | struct device *device; |
| 217 | struct qeth_card *card; | 230 | struct qeth_card *card; |
| 218 | 231 | ||
| 219 | device = list_entry(it, struct device, driver_list); | 232 | device = (struct device *) it; |
| 220 | card = device->driver_data; | 233 | card = device->driver_data; |
| 221 | seq_printf(s, "For card with devnos %s/%s/%s (%s):\n", | 234 | seq_printf(s, "For card with devnos %s/%s/%s (%s):\n", |
| 222 | CARD_RDEV_ID(card), | 235 | CARD_RDEV_ID(card), |
| @@ -318,8 +331,8 @@ static struct proc_dir_entry *qeth_ipato_procfile; | |||
| 318 | static void * | 331 | static void * |
| 319 | qeth_ipato_procfile_seq_start(struct seq_file *s, loff_t *offset) | 332 | qeth_ipato_procfile_seq_start(struct seq_file *s, loff_t *offset) |
| 320 | { | 333 | { |
| 321 | struct list_head *next_card = NULL; | 334 | struct device *dev; |
| 322 | int i = 0; | 335 | loff_t nr; |
| 323 | 336 | ||
| 324 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); | 337 | down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem); |
| 325 | /* TODO: finish this */ | 338 | /* TODO: finish this */ |
| @@ -328,13 +341,16 @@ qeth_ipato_procfile_seq_start(struct seq_file *s, loff_t *offset) | |||
| 328 | * output driver settings then; | 341 | * output driver settings then; |
| 329 | * else output setting for respective card | 342 | * else output setting for respective card |
| 330 | */ | 343 | */ |
| 344 | |||
| 345 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL, | ||
| 346 | qeth_procfile_seq_match); | ||
| 347 | |||
| 331 | /* get card at pos *offset */ | 348 | /* get card at pos *offset */ |
| 332 | list_for_each(next_card, &qeth_ccwgroup_driver.driver.devices){ | 349 | nr = *offset; |
| 333 | if (i == *offset) | 350 | while (nr-- > 1 && dev) |
| 334 | return next_card; | 351 | dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev, |
| 335 | i++; | 352 | NULL, qeth_procfile_seq_match); |
| 336 | } | 353 | return (void *) dev; |
| 337 | return NULL; | ||
| 338 | } | 354 | } |
| 339 | 355 | ||
| 340 | static void | 356 | static void |
| @@ -346,18 +362,14 @@ qeth_ipato_procfile_seq_stop(struct seq_file *s, void* it) | |||
| 346 | static void * | 362 | static void * |
| 347 | qeth_ipato_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) | 363 | qeth_ipato_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset) |
| 348 | { | 364 | { |
| 349 | struct list_head *current_card = (struct list_head *)it; | 365 | struct device *prev, *next; |
| 350 | 366 | ||
| 351 | /* TODO: finish this */ | 367 | prev = (struct device *) it; |
| 352 | /* | 368 | next = driver_find_device(&qeth_ccwgroup_driver.driver, prev, |
| 353 | * maybe SEQ_SATRT_TOKEN can be returned for offset 0 | 369 | NULL, qeth_procfile_seq_match); |
| 354 | * output driver settings then; | 370 | if (next) |
| 355 | * else output setting for respective card | 371 | (*offset)++; |
| 356 | */ | 372 | return (void *) next; |
| 357 | if (current_card->next == &qeth_ccwgroup_driver.driver.devices) | ||
| 358 | return NULL; /* end of list reached */ | ||
| 359 | (*offset)++; | ||
| 360 | return current_card->next; | ||
| 361 | } | 373 | } |
| 362 | 374 | ||
| 363 | static int | 375 | static int |
| @@ -372,7 +384,7 @@ qeth_ipato_procfile_seq_show(struct seq_file *s, void *it) | |||
| 372 | * output driver settings then; | 384 | * output driver settings then; |
| 373 | * else output setting for respective card | 385 | * else output setting for respective card |
| 374 | */ | 386 | */ |
| 375 | device = list_entry(it, struct device, driver_list); | 387 | device = (struct device *) it; |
| 376 | card = device->driver_data; | 388 | card = device->driver_data; |
| 377 | 389 | ||
| 378 | return 0; | 390 | return 0; |
diff --git a/drivers/sbus/char/bbc_envctrl.c b/drivers/sbus/char/bbc_envctrl.c index b8a2c7353b0a..d44205d52bf3 100644 --- a/drivers/sbus/char/bbc_envctrl.c +++ b/drivers/sbus/char/bbc_envctrl.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #define __KERNEL_SYSCALLS__ | 7 | #define __KERNEL_SYSCALLS__ |
| 8 | 8 | ||
| 9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| 10 | #include <linux/kthread.h> | ||
| 10 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
| 11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| 12 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
| @@ -459,10 +460,6 @@ static struct task_struct *kenvctrld_task; | |||
| 459 | 460 | ||
| 460 | static int kenvctrld(void *__unused) | 461 | static int kenvctrld(void *__unused) |
| 461 | { | 462 | { |
| 462 | daemonize("kenvctrld"); | ||
| 463 | allow_signal(SIGKILL); | ||
| 464 | kenvctrld_task = current; | ||
| 465 | |||
| 466 | printk(KERN_INFO "bbc_envctrl: kenvctrld starting...\n"); | 463 | printk(KERN_INFO "bbc_envctrl: kenvctrld starting...\n"); |
| 467 | last_warning_jiffies = jiffies - WARN_INTERVAL; | 464 | last_warning_jiffies = jiffies - WARN_INTERVAL; |
| 468 | for (;;) { | 465 | for (;;) { |
| @@ -470,7 +467,7 @@ static int kenvctrld(void *__unused) | |||
| 470 | struct bbc_fan_control *fp; | 467 | struct bbc_fan_control *fp; |
| 471 | 468 | ||
| 472 | msleep_interruptible(POLL_INTERVAL); | 469 | msleep_interruptible(POLL_INTERVAL); |
| 473 | if (signal_pending(current)) | 470 | if (kthread_should_stop()) |
| 474 | break; | 471 | break; |
| 475 | 472 | ||
| 476 | for (tp = all_bbc_temps; tp; tp = tp->next) { | 473 | for (tp = all_bbc_temps; tp; tp = tp->next) { |
| @@ -577,7 +574,6 @@ int bbc_envctrl_init(void) | |||
| 577 | int temp_index = 0; | 574 | int temp_index = 0; |
| 578 | int fan_index = 0; | 575 | int fan_index = 0; |
| 579 | int devidx = 0; | 576 | int devidx = 0; |
| 580 | int err = 0; | ||
| 581 | 577 | ||
| 582 | while ((echild = bbc_i2c_getdev(devidx++)) != NULL) { | 578 | while ((echild = bbc_i2c_getdev(devidx++)) != NULL) { |
| 583 | if (!strcmp(echild->prom_name, "temperature")) | 579 | if (!strcmp(echild->prom_name, "temperature")) |
| @@ -585,9 +581,13 @@ int bbc_envctrl_init(void) | |||
| 585 | if (!strcmp(echild->prom_name, "fan-control")) | 581 | if (!strcmp(echild->prom_name, "fan-control")) |
| 586 | attach_one_fan(echild, fan_index++); | 582 | attach_one_fan(echild, fan_index++); |
| 587 | } | 583 | } |
| 588 | if (temp_index != 0 && fan_index != 0) | 584 | if (temp_index != 0 && fan_index != 0) { |
| 589 | err = kernel_thread(kenvctrld, NULL, CLONE_FS | CLONE_FILES); | 585 | kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); |
| 590 | return err; | 586 | if (IS_ERR(kenvctrld_task)) |
| 587 | return PTR_ERR(kenvctrld_task); | ||
| 588 | } | ||
| 589 | |||
| 590 | return 0; | ||
| 591 | } | 591 | } |
| 592 | 592 | ||
| 593 | static void destroy_one_temp(struct bbc_cpu_temperature *tp) | 593 | static void destroy_one_temp(struct bbc_cpu_temperature *tp) |
| @@ -607,26 +607,7 @@ void bbc_envctrl_cleanup(void) | |||
| 607 | struct bbc_cpu_temperature *tp; | 607 | struct bbc_cpu_temperature *tp; |
| 608 | struct bbc_fan_control *fp; | 608 | struct bbc_fan_control *fp; |
| 609 | 609 | ||
| 610 | if (kenvctrld_task != NULL) { | 610 | kthread_stop(kenvctrld_task); |
| 611 | force_sig(SIGKILL, kenvctrld_task); | ||
| 612 | for (;;) { | ||
| 613 | struct task_struct *p; | ||
| 614 | int found = 0; | ||
| 615 | |||
| 616 | read_lock(&tasklist_lock); | ||
| 617 | for_each_process(p) { | ||
| 618 | if (p == kenvctrld_task) { | ||
| 619 | found = 1; | ||
| 620 | break; | ||
| 621 | } | ||
| 622 | } | ||
| 623 | read_unlock(&tasklist_lock); | ||
| 624 | if (!found) | ||
| 625 | break; | ||
| 626 | msleep(1000); | ||
| 627 | } | ||
| 628 | kenvctrld_task = NULL; | ||
| 629 | } | ||
| 630 | 611 | ||
| 631 | tp = all_bbc_temps; | 612 | tp = all_bbc_temps; |
| 632 | while (tp != NULL) { | 613 | while (tp != NULL) { |
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c index 9a8c572554f5..d765cc1bf060 100644 --- a/drivers/sbus/char/envctrl.c +++ b/drivers/sbus/char/envctrl.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/config.h> | 24 | #include <linux/config.h> |
| 25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 26 | #include <linux/sched.h> | 26 | #include <linux/sched.h> |
| 27 | #include <linux/kthread.h> | ||
| 27 | #include <linux/errno.h> | 28 | #include <linux/errno.h> |
| 28 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
| 29 | #include <linux/ioport.h> | 30 | #include <linux/ioport.h> |
| @@ -1010,16 +1011,13 @@ static int kenvctrld(void *__unused) | |||
| 1010 | 1011 | ||
| 1011 | poll_interval = 5000; /* TODO env_mon_interval */ | 1012 | poll_interval = 5000; /* TODO env_mon_interval */ |
| 1012 | 1013 | ||
| 1013 | daemonize("kenvctrld"); | ||
| 1014 | allow_signal(SIGKILL); | ||
| 1015 | |||
| 1016 | kenvctrld_task = current; | ||
| 1017 | |||
| 1018 | printk(KERN_INFO "envctrl: %s starting...\n", current->comm); | 1014 | printk(KERN_INFO "envctrl: %s starting...\n", current->comm); |
| 1019 | for (;;) { | 1015 | for (;;) { |
| 1020 | if(msleep_interruptible(poll_interval)) | 1016 | msleep_interruptible(poll_interval); |
| 1021 | break; | ||
| 1022 | 1017 | ||
| 1018 | if (kthread_should_stop()) | ||
| 1019 | break; | ||
| 1020 | |||
| 1023 | for (whichcpu = 0; whichcpu < ENVCTRL_MAX_CPU; ++whichcpu) { | 1021 | for (whichcpu = 0; whichcpu < ENVCTRL_MAX_CPU; ++whichcpu) { |
| 1024 | if (0 < envctrl_read_cpu_info(whichcpu, cputemp, | 1022 | if (0 < envctrl_read_cpu_info(whichcpu, cputemp, |
| 1025 | ENVCTRL_CPUTEMP_MON, | 1023 | ENVCTRL_CPUTEMP_MON, |
| @@ -1041,7 +1039,6 @@ static int kenvctrld(void *__unused) | |||
| 1041 | 1039 | ||
| 1042 | static int __init envctrl_init(void) | 1040 | static int __init envctrl_init(void) |
| 1043 | { | 1041 | { |
| 1044 | #ifdef CONFIG_PCI | ||
| 1045 | struct linux_ebus *ebus = NULL; | 1042 | struct linux_ebus *ebus = NULL; |
| 1046 | struct linux_ebus_device *edev = NULL; | 1043 | struct linux_ebus_device *edev = NULL; |
| 1047 | struct linux_ebus_child *edev_child = NULL; | 1044 | struct linux_ebus_child *edev_child = NULL; |
| @@ -1118,9 +1115,11 @@ done: | |||
| 1118 | i2c_childlist[i].addr, (0 == i) ? ("\n") : (" ")); | 1115 | i2c_childlist[i].addr, (0 == i) ? ("\n") : (" ")); |
| 1119 | } | 1116 | } |
| 1120 | 1117 | ||
| 1121 | err = kernel_thread(kenvctrld, NULL, CLONE_FS | CLONE_FILES); | 1118 | kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); |
| 1122 | if (err < 0) | 1119 | if (IS_ERR(kenvctrld_task)) { |
| 1120 | err = PTR_ERR(kenvctrld_task); | ||
| 1123 | goto out_deregister; | 1121 | goto out_deregister; |
| 1122 | } | ||
| 1124 | 1123 | ||
| 1125 | return 0; | 1124 | return 0; |
| 1126 | 1125 | ||
| @@ -1133,37 +1132,13 @@ out_iounmap: | |||
| 1133 | kfree(i2c_childlist[i].tables); | 1132 | kfree(i2c_childlist[i].tables); |
| 1134 | } | 1133 | } |
| 1135 | return err; | 1134 | return err; |
| 1136 | #else | ||
| 1137 | return -ENODEV; | ||
| 1138 | #endif | ||
| 1139 | } | 1135 | } |
| 1140 | 1136 | ||
| 1141 | static void __exit envctrl_cleanup(void) | 1137 | static void __exit envctrl_cleanup(void) |
| 1142 | { | 1138 | { |
| 1143 | int i; | 1139 | int i; |
| 1144 | 1140 | ||
| 1145 | if (NULL != kenvctrld_task) { | 1141 | kthread_stop(kenvctrld_task); |
| 1146 | force_sig(SIGKILL, kenvctrld_task); | ||
| 1147 | for (;;) { | ||
| 1148 | struct task_struct *p; | ||
| 1149 | int found = 0; | ||
| 1150 | |||
| 1151 | read_lock(&tasklist_lock); | ||
| 1152 | for_each_process(p) { | ||
| 1153 | if (p == kenvctrld_task) { | ||
| 1154 | found = 1; | ||
| 1155 | break; | ||
| 1156 | } | ||
| 1157 | } | ||
| 1158 | read_unlock(&tasklist_lock); | ||
| 1159 | |||
| 1160 | if (!found) | ||
| 1161 | break; | ||
| 1162 | |||
| 1163 | msleep(1000); | ||
| 1164 | } | ||
| 1165 | kenvctrld_task = NULL; | ||
| 1166 | } | ||
| 1167 | 1142 | ||
| 1168 | iounmap(i2c); | 1143 | iounmap(i2c); |
| 1169 | misc_deregister(&envctrl_dev); | 1144 | misc_deregister(&envctrl_dev); |
diff --git a/drivers/sbus/char/vfc.h b/drivers/sbus/char/vfc.h index e56a43af0f62..a7782e7da42e 100644 --- a/drivers/sbus/char/vfc.h +++ b/drivers/sbus/char/vfc.h | |||
| @@ -129,8 +129,6 @@ struct vfc_dev { | |||
| 129 | struct vfc_regs *phys_regs; | 129 | struct vfc_regs *phys_regs; |
| 130 | unsigned int control_reg; | 130 | unsigned int control_reg; |
| 131 | struct semaphore device_lock_sem; | 131 | struct semaphore device_lock_sem; |
| 132 | struct timer_list poll_timer; | ||
| 133 | wait_queue_head_t poll_wait; | ||
| 134 | int instance; | 132 | int instance; |
| 135 | int busy; | 133 | int busy; |
| 136 | unsigned long which_io; | 134 | unsigned long which_io; |
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index 86ce54130954..7a103698fa3c 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c | |||
| @@ -137,7 +137,6 @@ int init_vfc_devstruct(struct vfc_dev *dev, int instance) | |||
| 137 | dev->instance=instance; | 137 | dev->instance=instance; |
| 138 | init_MUTEX(&dev->device_lock_sem); | 138 | init_MUTEX(&dev->device_lock_sem); |
| 139 | dev->control_reg=0; | 139 | dev->control_reg=0; |
| 140 | init_waitqueue_head(&dev->poll_wait); | ||
| 141 | dev->busy=0; | 140 | dev->busy=0; |
| 142 | return 0; | 141 | return 0; |
| 143 | } | 142 | } |
diff --git a/drivers/sbus/char/vfc_i2c.c b/drivers/sbus/char/vfc_i2c.c index 1faf1e75f71f..739cad9b19a1 100644 --- a/drivers/sbus/char/vfc_i2c.c +++ b/drivers/sbus/char/vfc_i2c.c | |||
| @@ -79,25 +79,10 @@ int vfc_pcf8584_init(struct vfc_dev *dev) | |||
| 79 | return 0; | 79 | return 0; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | void vfc_i2c_delay_wakeup(struct vfc_dev *dev) | ||
| 83 | { | ||
| 84 | /* Used to profile code and eliminate too many delays */ | ||
| 85 | VFC_I2C_DEBUG_PRINTK(("vfc%d: Delaying\n", dev->instance)); | ||
| 86 | wake_up(&dev->poll_wait); | ||
| 87 | } | ||
| 88 | |||
| 89 | void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs) | 82 | void vfc_i2c_delay_no_busy(struct vfc_dev *dev, unsigned long usecs) |
| 90 | { | 83 | { |
| 91 | DEFINE_WAIT(wait); | 84 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 92 | init_timer(&dev->poll_timer); | 85 | schedule_timeout(usecs_to_jiffies(usecs)); |
| 93 | dev->poll_timer.expires = jiffies + usecs_to_jiffies(usecs); | ||
| 94 | dev->poll_timer.data=(unsigned long)dev; | ||
| 95 | dev->poll_timer.function=(void *)(unsigned long)vfc_i2c_delay_wakeup; | ||
| 96 | add_timer(&dev->poll_timer); | ||
| 97 | prepare_to_wait(&dev->poll_wait, &wait, TASK_UNINTERRUPTIBLE); | ||
| 98 | schedule(); | ||
| 99 | del_timer(&dev->poll_timer); | ||
| 100 | finish_wait(&dev->poll_wait, &wait); | ||
| 101 | } | 86 | } |
| 102 | 87 | ||
| 103 | void inline vfc_i2c_delay(struct vfc_dev *dev) | 88 | void inline vfc_i2c_delay(struct vfc_dev *dev) |
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 5f6187baad86..73c8a088c160 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h | |||
| @@ -40,13 +40,15 @@ | |||
| 40 | #define TX_NUM_FIFO 4 | 40 | #define TX_NUM_FIFO 4 |
| 41 | #define TX_BUF_SIZE 32 | 41 | #define TX_BUF_SIZE 32 |
| 42 | 42 | ||
| 43 | #define SCC_WAIT_CLOSING 100 | ||
| 44 | |||
| 43 | struct uart_cpm_port { | 45 | struct uart_cpm_port { |
| 44 | struct uart_port port; | 46 | struct uart_port port; |
| 45 | u16 rx_nrfifos; | 47 | u16 rx_nrfifos; |
| 46 | u16 rx_fifosize; | 48 | u16 rx_fifosize; |
| 47 | u16 tx_nrfifos; | 49 | u16 tx_nrfifos; |
| 48 | u16 tx_fifosize; | 50 | u16 tx_fifosize; |
| 49 | smc_t *smcp; | 51 | smc_t *smcp; |
| 50 | smc_uart_t *smcup; | 52 | smc_uart_t *smcup; |
| 51 | scc_t *sccp; | 53 | scc_t *sccp; |
| 52 | scc_uart_t *sccup; | 54 | scc_uart_t *sccup; |
| @@ -67,6 +69,8 @@ struct uart_cpm_port { | |||
| 67 | int bits; | 69 | int bits; |
| 68 | /* Keep track of 'odd' SMC2 wirings */ | 70 | /* Keep track of 'odd' SMC2 wirings */ |
| 69 | int is_portb; | 71 | int is_portb; |
| 72 | /* wait on close if needed */ | ||
| 73 | int wait_closing; | ||
| 70 | }; | 74 | }; |
| 71 | 75 | ||
| 72 | extern int cpm_uart_port_map[UART_NR]; | 76 | extern int cpm_uart_port_map[UART_NR]; |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 29db677d4284..d639ac92a117 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
| @@ -9,9 +9,10 @@ | |||
| 9 | * | 9 | * |
| 10 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) | 10 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) |
| 11 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 11 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
| 12 | * | 12 | * |
| 13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
| 14 | * (C) 2004 Intracom, S.A. | 14 | * (C) 2004 Intracom, S.A. |
| 15 | * (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com> | ||
| 15 | * | 16 | * |
| 16 | * This program is free software; you can redistribute it and/or modify | 17 | * This program is free software; you can redistribute it and/or modify |
| 17 | * it under the terms of the GNU General Public License as published by | 18 | * it under the terms of the GNU General Public License as published by |
| @@ -70,8 +71,22 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); | |||
| 70 | 71 | ||
| 71 | /**************************************************************/ | 72 | /**************************************************************/ |
| 72 | 73 | ||
| 74 | static inline unsigned long cpu2cpm_addr(void *addr) | ||
| 75 | { | ||
| 76 | if ((unsigned long)addr >= CPM_ADDR) | ||
| 77 | return (unsigned long)addr; | ||
| 78 | return virt_to_bus(addr); | ||
| 79 | } | ||
| 80 | |||
| 81 | static inline void *cpm2cpu_addr(unsigned long addr) | ||
| 82 | { | ||
| 83 | if (addr >= CPM_ADDR) | ||
| 84 | return (void *)addr; | ||
| 85 | return bus_to_virt(addr); | ||
| 86 | } | ||
| 87 | |||
| 73 | /* | 88 | /* |
| 74 | * Check, if transmit buffers are processed | 89 | * Check, if transmit buffers are processed |
| 75 | */ | 90 | */ |
| 76 | static unsigned int cpm_uart_tx_empty(struct uart_port *port) | 91 | static unsigned int cpm_uart_tx_empty(struct uart_port *port) |
| 77 | { | 92 | { |
| @@ -143,15 +158,18 @@ static void cpm_uart_start_tx(struct uart_port *port, unsigned int tty_start) | |||
| 143 | } | 158 | } |
| 144 | 159 | ||
| 145 | if (cpm_uart_tx_pump(port) != 0) { | 160 | if (cpm_uart_tx_pump(port) != 0) { |
| 146 | if (IS_SMC(pinfo)) | 161 | if (IS_SMC(pinfo)) { |
| 147 | smcp->smc_smcm |= SMCM_TX; | 162 | smcp->smc_smcm |= SMCM_TX; |
| 148 | else | 163 | smcp->smc_smcmr |= SMCMR_TEN; |
| 164 | } else { | ||
| 149 | sccp->scc_sccm |= UART_SCCM_TX; | 165 | sccp->scc_sccm |= UART_SCCM_TX; |
| 166 | pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT; | ||
| 167 | } | ||
| 150 | } | 168 | } |
| 151 | } | 169 | } |
| 152 | 170 | ||
| 153 | /* | 171 | /* |
| 154 | * Stop receiver | 172 | * Stop receiver |
| 155 | */ | 173 | */ |
| 156 | static void cpm_uart_stop_rx(struct uart_port *port) | 174 | static void cpm_uart_stop_rx(struct uart_port *port) |
| 157 | { | 175 | { |
| @@ -176,7 +194,7 @@ static void cpm_uart_enable_ms(struct uart_port *port) | |||
| 176 | } | 194 | } |
| 177 | 195 | ||
| 178 | /* | 196 | /* |
| 179 | * Generate a break. | 197 | * Generate a break. |
| 180 | */ | 198 | */ |
| 181 | static void cpm_uart_break_ctl(struct uart_port *port, int break_state) | 199 | static void cpm_uart_break_ctl(struct uart_port *port, int break_state) |
| 182 | { | 200 | { |
| @@ -231,7 +249,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
| 231 | /* get number of characters, and check spce in flip-buffer */ | 249 | /* get number of characters, and check spce in flip-buffer */ |
| 232 | i = bdp->cbd_datlen; | 250 | i = bdp->cbd_datlen; |
| 233 | 251 | ||
| 234 | /* If we have not enough room in tty flip buffer, then we try | 252 | /* If we have not enough room in tty flip buffer, then we try |
| 235 | * later, which will be the next rx-interrupt or a timeout | 253 | * later, which will be the next rx-interrupt or a timeout |
| 236 | */ | 254 | */ |
| 237 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { | 255 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { |
| @@ -243,7 +261,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
| 243 | } | 261 | } |
| 244 | 262 | ||
| 245 | /* get pointer */ | 263 | /* get pointer */ |
| 246 | cp = (unsigned char *)bus_to_virt(bdp->cbd_bufaddr); | 264 | cp = cpm2cpu_addr(bdp->cbd_bufaddr); |
| 247 | 265 | ||
| 248 | /* loop through the buffer */ | 266 | /* loop through the buffer */ |
| 249 | while (i-- > 0) { | 267 | while (i-- > 0) { |
| @@ -265,13 +283,14 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
| 265 | } /* End while (i--) */ | 283 | } /* End while (i--) */ |
| 266 | 284 | ||
| 267 | /* This BD is ready to be used again. Clear status. get next */ | 285 | /* This BD is ready to be used again. Clear status. get next */ |
| 268 | bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); | 286 | bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID); |
| 269 | bdp->cbd_sc |= BD_SC_EMPTY; | 287 | bdp->cbd_sc |= BD_SC_EMPTY; |
| 270 | 288 | ||
| 271 | if (bdp->cbd_sc & BD_SC_WRAP) | 289 | if (bdp->cbd_sc & BD_SC_WRAP) |
| 272 | bdp = pinfo->rx_bd_base; | 290 | bdp = pinfo->rx_bd_base; |
| 273 | else | 291 | else |
| 274 | bdp++; | 292 | bdp++; |
| 293 | |||
| 275 | } /* End for (;;) */ | 294 | } /* End for (;;) */ |
| 276 | 295 | ||
| 277 | /* Write back buffer pointer */ | 296 | /* Write back buffer pointer */ |
| @@ -336,22 +355,22 @@ static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs) | |||
| 336 | 355 | ||
| 337 | if (IS_SMC(pinfo)) { | 356 | if (IS_SMC(pinfo)) { |
| 338 | events = smcp->smc_smce; | 357 | events = smcp->smc_smce; |
| 358 | smcp->smc_smce = events; | ||
| 339 | if (events & SMCM_BRKE) | 359 | if (events & SMCM_BRKE) |
| 340 | uart_handle_break(port); | 360 | uart_handle_break(port); |
| 341 | if (events & SMCM_RX) | 361 | if (events & SMCM_RX) |
| 342 | cpm_uart_int_rx(port, regs); | 362 | cpm_uart_int_rx(port, regs); |
| 343 | if (events & SMCM_TX) | 363 | if (events & SMCM_TX) |
| 344 | cpm_uart_int_tx(port, regs); | 364 | cpm_uart_int_tx(port, regs); |
| 345 | smcp->smc_smce = events; | ||
| 346 | } else { | 365 | } else { |
| 347 | events = sccp->scc_scce; | 366 | events = sccp->scc_scce; |
| 367 | sccp->scc_scce = events; | ||
| 348 | if (events & UART_SCCM_BRKE) | 368 | if (events & UART_SCCM_BRKE) |
| 349 | uart_handle_break(port); | 369 | uart_handle_break(port); |
| 350 | if (events & UART_SCCM_RX) | 370 | if (events & UART_SCCM_RX) |
| 351 | cpm_uart_int_rx(port, regs); | 371 | cpm_uart_int_rx(port, regs); |
| 352 | if (events & UART_SCCM_TX) | 372 | if (events & UART_SCCM_TX) |
| 353 | cpm_uart_int_tx(port, regs); | 373 | cpm_uart_int_tx(port, regs); |
| 354 | sccp->scc_scce = events; | ||
| 355 | } | 374 | } |
| 356 | return (events) ? IRQ_HANDLED : IRQ_NONE; | 375 | return (events) ? IRQ_HANDLED : IRQ_NONE; |
| 357 | } | 376 | } |
| @@ -360,6 +379,7 @@ static int cpm_uart_startup(struct uart_port *port) | |||
| 360 | { | 379 | { |
| 361 | int retval; | 380 | int retval; |
| 362 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 381 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
| 382 | int line = pinfo - cpm_uart_ports; | ||
| 363 | 383 | ||
| 364 | pr_debug("CPM uart[%d]:startup\n", port->line); | 384 | pr_debug("CPM uart[%d]:startup\n", port->line); |
| 365 | 385 | ||
| @@ -376,9 +396,19 @@ static int cpm_uart_startup(struct uart_port *port) | |||
| 376 | pinfo->sccp->scc_sccm |= UART_SCCM_RX; | 396 | pinfo->sccp->scc_sccm |= UART_SCCM_RX; |
| 377 | } | 397 | } |
| 378 | 398 | ||
| 399 | if (!(pinfo->flags & FLAG_CONSOLE)) | ||
| 400 | cpm_line_cr_cmd(line,CPM_CR_INIT_TRX); | ||
| 379 | return 0; | 401 | return 0; |
| 380 | } | 402 | } |
| 381 | 403 | ||
| 404 | inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo) | ||
| 405 | { | ||
| 406 | unsigned long target_jiffies = jiffies + pinfo->wait_closing; | ||
| 407 | |||
| 408 | while (!time_after(jiffies, target_jiffies)) | ||
| 409 | schedule(); | ||
| 410 | } | ||
| 411 | |||
| 382 | /* | 412 | /* |
| 383 | * Shutdown the uart | 413 | * Shutdown the uart |
| 384 | */ | 414 | */ |
| @@ -394,6 +424,12 @@ static void cpm_uart_shutdown(struct uart_port *port) | |||
| 394 | 424 | ||
| 395 | /* If the port is not the console, disable Rx and Tx. */ | 425 | /* If the port is not the console, disable Rx and Tx. */ |
| 396 | if (!(pinfo->flags & FLAG_CONSOLE)) { | 426 | if (!(pinfo->flags & FLAG_CONSOLE)) { |
| 427 | /* Wait for all the BDs marked sent */ | ||
| 428 | while(!cpm_uart_tx_empty(port)) | ||
| 429 | schedule_timeout(2); | ||
| 430 | if(pinfo->wait_closing) | ||
| 431 | cpm_uart_wait_until_send(pinfo); | ||
| 432 | |||
| 397 | /* Stop uarts */ | 433 | /* Stop uarts */ |
| 398 | if (IS_SMC(pinfo)) { | 434 | if (IS_SMC(pinfo)) { |
| 399 | volatile smc_t *smcp = pinfo->smcp; | 435 | volatile smc_t *smcp = pinfo->smcp; |
| @@ -502,7 +538,7 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
| 502 | */ | 538 | */ |
| 503 | if ((termios->c_cflag & CREAD) == 0) | 539 | if ((termios->c_cflag & CREAD) == 0) |
| 504 | port->read_status_mask &= ~BD_SC_EMPTY; | 540 | port->read_status_mask &= ~BD_SC_EMPTY; |
| 505 | 541 | ||
| 506 | spin_lock_irqsave(&port->lock, flags); | 542 | spin_lock_irqsave(&port->lock, flags); |
| 507 | 543 | ||
| 508 | /* Start bit has not been added (so don't, because we would just | 544 | /* Start bit has not been added (so don't, because we would just |
| @@ -569,7 +605,8 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
| 569 | /* Pick next descriptor and fill from buffer */ | 605 | /* Pick next descriptor and fill from buffer */ |
| 570 | bdp = pinfo->tx_cur; | 606 | bdp = pinfo->tx_cur; |
| 571 | 607 | ||
| 572 | p = bus_to_virt(bdp->cbd_bufaddr); | 608 | p = cpm2cpu_addr(bdp->cbd_bufaddr); |
| 609 | |||
| 573 | *p++ = xmit->buf[xmit->tail]; | 610 | *p++ = xmit->buf[xmit->tail]; |
| 574 | bdp->cbd_datlen = 1; | 611 | bdp->cbd_datlen = 1; |
| 575 | bdp->cbd_sc |= BD_SC_READY; | 612 | bdp->cbd_sc |= BD_SC_READY; |
| @@ -595,7 +632,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
| 595 | 632 | ||
| 596 | while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { | 633 | while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { |
| 597 | count = 0; | 634 | count = 0; |
| 598 | p = bus_to_virt(bdp->cbd_bufaddr); | 635 | p = cpm2cpu_addr(bdp->cbd_bufaddr); |
| 599 | while (count < pinfo->tx_fifosize) { | 636 | while (count < pinfo->tx_fifosize) { |
| 600 | *p++ = xmit->buf[xmit->tail]; | 637 | *p++ = xmit->buf[xmit->tail]; |
| 601 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 638 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
| @@ -606,6 +643,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
| 606 | } | 643 | } |
| 607 | bdp->cbd_datlen = count; | 644 | bdp->cbd_datlen = count; |
| 608 | bdp->cbd_sc |= BD_SC_READY; | 645 | bdp->cbd_sc |= BD_SC_READY; |
| 646 | __asm__("eieio"); | ||
| 609 | /* Get next BD. */ | 647 | /* Get next BD. */ |
| 610 | if (bdp->cbd_sc & BD_SC_WRAP) | 648 | if (bdp->cbd_sc & BD_SC_WRAP) |
| 611 | bdp = pinfo->tx_bd_base; | 649 | bdp = pinfo->tx_bd_base; |
| @@ -643,12 +681,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) | |||
| 643 | mem_addr = pinfo->mem_addr; | 681 | mem_addr = pinfo->mem_addr; |
| 644 | bdp = pinfo->rx_cur = pinfo->rx_bd_base; | 682 | bdp = pinfo->rx_cur = pinfo->rx_bd_base; |
| 645 | for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { | 683 | for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { |
| 646 | bdp->cbd_bufaddr = virt_to_bus(mem_addr); | 684 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); |
| 647 | bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; | 685 | bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; |
| 648 | mem_addr += pinfo->rx_fifosize; | 686 | mem_addr += pinfo->rx_fifosize; |
| 649 | } | 687 | } |
| 650 | 688 | ||
| 651 | bdp->cbd_bufaddr = virt_to_bus(mem_addr); | 689 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); |
| 652 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; | 690 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; |
| 653 | 691 | ||
| 654 | /* Set the physical address of the host memory | 692 | /* Set the physical address of the host memory |
| @@ -658,12 +696,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) | |||
| 658 | mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); | 696 | mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); |
| 659 | bdp = pinfo->tx_cur = pinfo->tx_bd_base; | 697 | bdp = pinfo->tx_cur = pinfo->tx_bd_base; |
| 660 | for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { | 698 | for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { |
| 661 | bdp->cbd_bufaddr = virt_to_bus(mem_addr); | 699 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); |
| 662 | bdp->cbd_sc = BD_SC_INTRPT; | 700 | bdp->cbd_sc = BD_SC_INTRPT; |
| 663 | mem_addr += pinfo->tx_fifosize; | 701 | mem_addr += pinfo->tx_fifosize; |
| 664 | } | 702 | } |
| 665 | 703 | ||
| 666 | bdp->cbd_bufaddr = virt_to_bus(mem_addr); | 704 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); |
| 667 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; | 705 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; |
| 668 | } | 706 | } |
| 669 | 707 | ||
| @@ -763,6 +801,8 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) | |||
| 763 | /* Using idle charater time requires some additional tuning. */ | 801 | /* Using idle charater time requires some additional tuning. */ |
| 764 | up->smc_mrblr = pinfo->rx_fifosize; | 802 | up->smc_mrblr = pinfo->rx_fifosize; |
| 765 | up->smc_maxidl = pinfo->rx_fifosize; | 803 | up->smc_maxidl = pinfo->rx_fifosize; |
| 804 | up->smc_brklen = 0; | ||
| 805 | up->smc_brkec = 0; | ||
| 766 | up->smc_brkcr = 1; | 806 | up->smc_brkcr = 1; |
| 767 | 807 | ||
| 768 | cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); | 808 | cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); |
| @@ -796,7 +836,7 @@ static int cpm_uart_request_port(struct uart_port *port) | |||
| 796 | /* | 836 | /* |
| 797 | * Setup any port IO, connect any baud rate generators, | 837 | * Setup any port IO, connect any baud rate generators, |
| 798 | * etc. This is expected to be handled by board | 838 | * etc. This is expected to be handled by board |
| 799 | * dependant code | 839 | * dependant code |
| 800 | */ | 840 | */ |
| 801 | if (pinfo->set_lineif) | 841 | if (pinfo->set_lineif) |
| 802 | pinfo->set_lineif(pinfo); | 842 | pinfo->set_lineif(pinfo); |
| @@ -815,6 +855,10 @@ static int cpm_uart_request_port(struct uart_port *port) | |||
| 815 | return ret; | 855 | return ret; |
| 816 | 856 | ||
| 817 | cpm_uart_initbd(pinfo); | 857 | cpm_uart_initbd(pinfo); |
| 858 | if (IS_SMC(pinfo)) | ||
| 859 | cpm_uart_init_smc(pinfo); | ||
| 860 | else | ||
| 861 | cpm_uart_init_scc(pinfo); | ||
| 818 | 862 | ||
| 819 | return 0; | 863 | return 0; |
| 820 | } | 864 | } |
| @@ -869,7 +913,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 869 | .flags = FLAG_SMC, | 913 | .flags = FLAG_SMC, |
| 870 | .tx_nrfifos = TX_NUM_FIFO, | 914 | .tx_nrfifos = TX_NUM_FIFO, |
| 871 | .tx_fifosize = TX_BUF_SIZE, | 915 | .tx_fifosize = TX_BUF_SIZE, |
| 872 | .rx_nrfifos = RX_NUM_FIFO, | 916 | .rx_nrfifos = RX_NUM_FIFO, |
| 873 | .rx_fifosize = RX_BUF_SIZE, | 917 | .rx_fifosize = RX_BUF_SIZE, |
| 874 | .set_lineif = smc1_lineif, | 918 | .set_lineif = smc1_lineif, |
| 875 | }, | 919 | }, |
| @@ -883,7 +927,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 883 | .flags = FLAG_SMC, | 927 | .flags = FLAG_SMC, |
| 884 | .tx_nrfifos = TX_NUM_FIFO, | 928 | .tx_nrfifos = TX_NUM_FIFO, |
| 885 | .tx_fifosize = TX_BUF_SIZE, | 929 | .tx_fifosize = TX_BUF_SIZE, |
| 886 | .rx_nrfifos = RX_NUM_FIFO, | 930 | .rx_nrfifos = RX_NUM_FIFO, |
| 887 | .rx_fifosize = RX_BUF_SIZE, | 931 | .rx_fifosize = RX_BUF_SIZE, |
| 888 | .set_lineif = smc2_lineif, | 932 | .set_lineif = smc2_lineif, |
| 889 | #ifdef CONFIG_SERIAL_CPM_ALT_SMC2 | 933 | #ifdef CONFIG_SERIAL_CPM_ALT_SMC2 |
| @@ -899,9 +943,10 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 899 | }, | 943 | }, |
| 900 | .tx_nrfifos = TX_NUM_FIFO, | 944 | .tx_nrfifos = TX_NUM_FIFO, |
| 901 | .tx_fifosize = TX_BUF_SIZE, | 945 | .tx_fifosize = TX_BUF_SIZE, |
| 902 | .rx_nrfifos = RX_NUM_FIFO, | 946 | .rx_nrfifos = RX_NUM_FIFO, |
| 903 | .rx_fifosize = RX_BUF_SIZE, | 947 | .rx_fifosize = RX_BUF_SIZE, |
| 904 | .set_lineif = scc1_lineif, | 948 | .set_lineif = scc1_lineif, |
| 949 | .wait_closing = SCC_WAIT_CLOSING, | ||
| 905 | }, | 950 | }, |
| 906 | [UART_SCC2] = { | 951 | [UART_SCC2] = { |
| 907 | .port = { | 952 | .port = { |
| @@ -912,9 +957,10 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 912 | }, | 957 | }, |
| 913 | .tx_nrfifos = TX_NUM_FIFO, | 958 | .tx_nrfifos = TX_NUM_FIFO, |
| 914 | .tx_fifosize = TX_BUF_SIZE, | 959 | .tx_fifosize = TX_BUF_SIZE, |
| 915 | .rx_nrfifos = RX_NUM_FIFO, | 960 | .rx_nrfifos = RX_NUM_FIFO, |
| 916 | .rx_fifosize = RX_BUF_SIZE, | 961 | .rx_fifosize = RX_BUF_SIZE, |
| 917 | .set_lineif = scc2_lineif, | 962 | .set_lineif = scc2_lineif, |
| 963 | .wait_closing = SCC_WAIT_CLOSING, | ||
| 918 | }, | 964 | }, |
| 919 | [UART_SCC3] = { | 965 | [UART_SCC3] = { |
| 920 | .port = { | 966 | .port = { |
| @@ -925,9 +971,10 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 925 | }, | 971 | }, |
| 926 | .tx_nrfifos = TX_NUM_FIFO, | 972 | .tx_nrfifos = TX_NUM_FIFO, |
| 927 | .tx_fifosize = TX_BUF_SIZE, | 973 | .tx_fifosize = TX_BUF_SIZE, |
| 928 | .rx_nrfifos = RX_NUM_FIFO, | 974 | .rx_nrfifos = RX_NUM_FIFO, |
| 929 | .rx_fifosize = RX_BUF_SIZE, | 975 | .rx_fifosize = RX_BUF_SIZE, |
| 930 | .set_lineif = scc3_lineif, | 976 | .set_lineif = scc3_lineif, |
| 977 | .wait_closing = SCC_WAIT_CLOSING, | ||
| 931 | }, | 978 | }, |
| 932 | [UART_SCC4] = { | 979 | [UART_SCC4] = { |
| 933 | .port = { | 980 | .port = { |
| @@ -938,9 +985,10 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
| 938 | }, | 985 | }, |
| 939 | .tx_nrfifos = TX_NUM_FIFO, | 986 | .tx_nrfifos = TX_NUM_FIFO, |
| 940 | .tx_fifosize = TX_BUF_SIZE, | 987 | .tx_fifosize = TX_BUF_SIZE, |
| 941 | .rx_nrfifos = RX_NUM_FIFO, | 988 | .rx_nrfifos = RX_NUM_FIFO, |
| 942 | .rx_fifosize = RX_BUF_SIZE, | 989 | .rx_fifosize = RX_BUF_SIZE, |
| 943 | .set_lineif = scc4_lineif, | 990 | .set_lineif = scc4_lineif, |
| 991 | .wait_closing = SCC_WAIT_CLOSING, | ||
| 944 | }, | 992 | }, |
| 945 | }; | 993 | }; |
| 946 | 994 | ||
| @@ -983,11 +1031,8 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
| 983 | * If the buffer address is in the CPM DPRAM, don't | 1031 | * If the buffer address is in the CPM DPRAM, don't |
| 984 | * convert it. | 1032 | * convert it. |
| 985 | */ | 1033 | */ |
| 986 | if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR) | 1034 | cp = cpm2cpu_addr(bdp->cbd_bufaddr); |
| 987 | cp = (unsigned char *) (bdp->cbd_bufaddr); | 1035 | |
| 988 | else | ||
| 989 | cp = bus_to_virt(bdp->cbd_bufaddr); | ||
| 990 | |||
| 991 | *cp = *s; | 1036 | *cp = *s; |
| 992 | 1037 | ||
| 993 | bdp->cbd_datlen = 1; | 1038 | bdp->cbd_datlen = 1; |
| @@ -1003,10 +1048,7 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
| 1003 | while ((bdp->cbd_sc & BD_SC_READY) != 0) | 1048 | while ((bdp->cbd_sc & BD_SC_READY) != 0) |
| 1004 | ; | 1049 | ; |
| 1005 | 1050 | ||
| 1006 | if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR) | 1051 | cp = cpm2cpu_addr(bdp->cbd_bufaddr); |
| 1007 | cp = (unsigned char *) (bdp->cbd_bufaddr); | ||
| 1008 | else | ||
| 1009 | cp = bus_to_virt(bdp->cbd_bufaddr); | ||
| 1010 | 1052 | ||
| 1011 | *cp = 13; | 1053 | *cp = 13; |
| 1012 | bdp->cbd_datlen = 1; | 1054 | bdp->cbd_datlen = 1; |
| @@ -1045,7 +1087,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
| 1045 | port = | 1087 | port = |
| 1046 | (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; | 1088 | (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; |
| 1047 | pinfo = (struct uart_cpm_port *)port; | 1089 | pinfo = (struct uart_cpm_port *)port; |
| 1048 | 1090 | ||
| 1049 | pinfo->flags |= FLAG_CONSOLE; | 1091 | pinfo->flags |= FLAG_CONSOLE; |
| 1050 | 1092 | ||
| 1051 | if (options) { | 1093 | if (options) { |
| @@ -1062,7 +1104,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
| 1062 | /* | 1104 | /* |
| 1063 | * Setup any port IO, connect any baud rate generators, | 1105 | * Setup any port IO, connect any baud rate generators, |
| 1064 | * etc. This is expected to be handled by board | 1106 | * etc. This is expected to be handled by board |
| 1065 | * dependant code | 1107 | * dependant code |
| 1066 | */ | 1108 | */ |
| 1067 | if (pinfo->set_lineif) | 1109 | if (pinfo->set_lineif) |
| 1068 | pinfo->set_lineif(pinfo); | 1110 | pinfo->set_lineif(pinfo); |
| @@ -1092,14 +1134,14 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
| 1092 | return 0; | 1134 | return 0; |
| 1093 | } | 1135 | } |
| 1094 | 1136 | ||
| 1095 | extern struct uart_driver cpm_reg; | 1137 | static struct uart_driver cpm_reg; |
| 1096 | static struct console cpm_scc_uart_console = { | 1138 | static struct console cpm_scc_uart_console = { |
| 1097 | .name "ttyCPM", | 1139 | .name = "ttyCPM", |
| 1098 | .write cpm_uart_console_write, | 1140 | .write = cpm_uart_console_write, |
| 1099 | .device uart_console_device, | 1141 | .device = uart_console_device, |
| 1100 | .setup cpm_uart_console_setup, | 1142 | .setup = cpm_uart_console_setup, |
| 1101 | .flags CON_PRINTBUFFER, | 1143 | .flags = CON_PRINTBUFFER, |
| 1102 | .index -1, | 1144 | .index = -1, |
| 1103 | .data = &cpm_reg, | 1145 | .data = &cpm_reg, |
| 1104 | }; | 1146 | }; |
| 1105 | 1147 | ||
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 8efbd6d1d6a4..4b0786e7eb7f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) | 6 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) |
| 7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
| 8 | * | 8 | * |
| 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
| 10 | * (C) 2004 Intracom, S.A. | 10 | * (C) 2004 Intracom, S.A. |
| 11 | * | 11 | * |
| @@ -82,6 +82,17 @@ void cpm_line_cr_cmd(int line, int cmd) | |||
| 82 | void smc1_lineif(struct uart_cpm_port *pinfo) | 82 | void smc1_lineif(struct uart_cpm_port *pinfo) |
| 83 | { | 83 | { |
| 84 | volatile cpm8xx_t *cp = cpmp; | 84 | volatile cpm8xx_t *cp = cpmp; |
| 85 | |||
| 86 | (void)cp; /* fix warning */ | ||
| 87 | #if defined (CONFIG_MPC885ADS) | ||
| 88 | /* Enable SMC1 transceivers */ | ||
| 89 | { | ||
| 90 | cp->cp_pepar |= 0x000000c0; | ||
| 91 | cp->cp_pedir &= ~0x000000c0; | ||
| 92 | cp->cp_peso &= ~0x00000040; | ||
| 93 | cp->cp_peso |= 0x00000080; | ||
| 94 | } | ||
| 95 | #elif defined (CONFIG_MPC86XADS) | ||
| 85 | unsigned int iobits = 0x000000c0; | 96 | unsigned int iobits = 0x000000c0; |
| 86 | 97 | ||
| 87 | if (!pinfo->is_portb) { | 98 | if (!pinfo->is_portb) { |
| @@ -93,41 +104,33 @@ void smc1_lineif(struct uart_cpm_port *pinfo) | |||
| 93 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits; | 104 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits; |
| 94 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; | 105 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; |
| 95 | } | 106 | } |
| 96 | |||
| 97 | #ifdef CONFIG_MPC885ADS | ||
| 98 | /* Enable SMC1 transceivers */ | ||
| 99 | { | ||
| 100 | volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4); | ||
| 101 | uint tmp; | ||
| 102 | |||
| 103 | tmp = in_be32(bcsr1); | ||
| 104 | tmp &= ~BCSR1_RS232EN_1; | ||
| 105 | out_be32(bcsr1, tmp); | ||
| 106 | iounmap(bcsr1); | ||
| 107 | } | ||
| 108 | #endif | 107 | #endif |
| 109 | |||
| 110 | pinfo->brg = 1; | 108 | pinfo->brg = 1; |
| 111 | } | 109 | } |
| 112 | 110 | ||
| 113 | void smc2_lineif(struct uart_cpm_port *pinfo) | 111 | void smc2_lineif(struct uart_cpm_port *pinfo) |
| 114 | { | 112 | { |
| 115 | #ifdef CONFIG_MPC885ADS | ||
| 116 | volatile cpm8xx_t *cp = cpmp; | 113 | volatile cpm8xx_t *cp = cpmp; |
| 117 | volatile uint __iomem *bcsr1; | ||
| 118 | uint tmp; | ||
| 119 | 114 | ||
| 115 | (void)cp; /* fix warning */ | ||
| 116 | #if defined (CONFIG_MPC885ADS) | ||
| 120 | cp->cp_pepar |= 0x00000c00; | 117 | cp->cp_pepar |= 0x00000c00; |
| 121 | cp->cp_pedir &= ~0x00000c00; | 118 | cp->cp_pedir &= ~0x00000c00; |
| 122 | cp->cp_peso &= ~0x00000400; | 119 | cp->cp_peso &= ~0x00000400; |
| 123 | cp->cp_peso |= 0x00000800; | 120 | cp->cp_peso |= 0x00000800; |
| 121 | #elif defined (CONFIG_MPC86XADS) | ||
| 122 | unsigned int iobits = 0x00000c00; | ||
| 123 | |||
| 124 | if (!pinfo->is_portb) { | ||
| 125 | cp->cp_pbpar |= iobits; | ||
| 126 | cp->cp_pbdir &= ~iobits; | ||
| 127 | cp->cp_pbodr &= ~iobits; | ||
| 128 | } else { | ||
| 129 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits; | ||
| 130 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits; | ||
| 131 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; | ||
| 132 | } | ||
| 124 | 133 | ||
| 125 | /* Enable SMC2 transceivers */ | ||
| 126 | bcsr1 = ioremap(BCSR1, 4); | ||
| 127 | tmp = in_be32(bcsr1); | ||
| 128 | tmp &= ~BCSR1_RS232EN_2; | ||
| 129 | out_be32(bcsr1, tmp); | ||
| 130 | iounmap(bcsr1); | ||
| 131 | #endif | 134 | #endif |
| 132 | 135 | ||
| 133 | pinfo->brg = 2; | 136 | pinfo->brg = 2; |
| @@ -158,7 +161,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) | |||
| 158 | } | 161 | } |
| 159 | 162 | ||
| 160 | /* | 163 | /* |
| 161 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and | 164 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and |
| 162 | * receive buffer descriptors from dual port ram, and a character | 165 | * receive buffer descriptors from dual port ram, and a character |
| 163 | * buffer area from host mem. If we are allocating for the console we need | 166 | * buffer area from host mem. If we are allocating for the console we need |
| 164 | * to do it from bootmem | 167 | * to do it from bootmem |
| @@ -185,6 +188,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) | |||
| 185 | memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + | 188 | memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + |
| 186 | L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); | 189 | L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); |
| 187 | if (is_con) { | 190 | if (is_con) { |
| 191 | /* was hostalloc but changed cause it blows away the */ | ||
| 192 | /* large tlb mapping when pinning the kernel area */ | ||
| 188 | mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); | 193 | mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); |
| 189 | dma_addr = 0; | 194 | dma_addr = 0; |
| 190 | } else | 195 | } else |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 50cb01831075..b01efb6b36f6 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
| @@ -527,7 +527,7 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
| 527 | p.qh->period, | 527 | p.qh->period, |
| 528 | le32_to_cpup (&p.qh->hw_info2) | 528 | le32_to_cpup (&p.qh->hw_info2) |
| 529 | /* uframe masks */ | 529 | /* uframe masks */ |
| 530 | & 0xffff, | 530 | & (QH_CMASK | QH_SMASK), |
| 531 | p.qh); | 531 | p.qh); |
| 532 | size -= temp; | 532 | size -= temp; |
| 533 | next += temp; | 533 | next += temp; |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 4f97a4ad1ed3..20df01a79b2e 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
| @@ -222,7 +222,7 @@ __acquires(ehci->lock) | |||
| 222 | struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; | 222 | struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; |
| 223 | 223 | ||
| 224 | /* S-mask in a QH means it's an interrupt urb */ | 224 | /* S-mask in a QH means it's an interrupt urb */ |
| 225 | if ((qh->hw_info2 & __constant_cpu_to_le32 (0x00ff)) != 0) { | 225 | if ((qh->hw_info2 & __constant_cpu_to_le32 (QH_SMASK)) != 0) { |
| 226 | 226 | ||
| 227 | /* ... update hc-wide periodic stats (for usbfs) */ | 227 | /* ... update hc-wide periodic stats (for usbfs) */ |
| 228 | ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; | 228 | ehci_to_hcd(ehci)->self.bandwidth_int_reqs--; |
| @@ -428,7 +428,8 @@ halt: | |||
| 428 | /* should be rare for periodic transfers, | 428 | /* should be rare for periodic transfers, |
| 429 | * except maybe high bandwidth ... | 429 | * except maybe high bandwidth ... |
| 430 | */ | 430 | */ |
| 431 | if (qh->period) { | 431 | if ((__constant_cpu_to_le32 (QH_SMASK) |
| 432 | & qh->hw_info2) != 0) { | ||
| 432 | intr_deschedule (ehci, qh); | 433 | intr_deschedule (ehci, qh); |
| 433 | (void) qh_schedule (ehci, qh); | 434 | (void) qh_schedule (ehci, qh); |
| 434 | } else | 435 | } else |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 9af4f64532a9..b56f25864ed6 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -301,7 +301,7 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 301 | 301 | ||
| 302 | dev_dbg (&qh->dev->dev, | 302 | dev_dbg (&qh->dev->dev, |
| 303 | "link qh%d-%04x/%p start %d [%d/%d us]\n", | 303 | "link qh%d-%04x/%p start %d [%d/%d us]\n", |
| 304 | period, le32_to_cpup (&qh->hw_info2) & 0xffff, | 304 | period, le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK), |
| 305 | qh, qh->start, qh->usecs, qh->c_usecs); | 305 | qh, qh->start, qh->usecs, qh->c_usecs); |
| 306 | 306 | ||
| 307 | /* high bandwidth, or otherwise every microframe */ | 307 | /* high bandwidth, or otherwise every microframe */ |
| @@ -385,7 +385,8 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 385 | 385 | ||
| 386 | dev_dbg (&qh->dev->dev, | 386 | dev_dbg (&qh->dev->dev, |
| 387 | "unlink qh%d-%04x/%p start %d [%d/%d us]\n", | 387 | "unlink qh%d-%04x/%p start %d [%d/%d us]\n", |
| 388 | qh->period, le32_to_cpup (&qh->hw_info2) & 0xffff, | 388 | qh->period, |
| 389 | le32_to_cpup (&qh->hw_info2) & (QH_CMASK | QH_SMASK), | ||
| 389 | qh, qh->start, qh->usecs, qh->c_usecs); | 390 | qh, qh->start, qh->usecs, qh->c_usecs); |
| 390 | 391 | ||
| 391 | /* qh->qh_next still "live" to HC */ | 392 | /* qh->qh_next still "live" to HC */ |
| @@ -411,7 +412,7 @@ static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 411 | * active high speed queues may need bigger delays... | 412 | * active high speed queues may need bigger delays... |
| 412 | */ | 413 | */ |
| 413 | if (list_empty (&qh->qtd_list) | 414 | if (list_empty (&qh->qtd_list) |
| 414 | || (__constant_cpu_to_le32 (0x0ff << 8) | 415 | || (__constant_cpu_to_le32 (QH_CMASK) |
| 415 | & qh->hw_info2) != 0) | 416 | & qh->hw_info2) != 0) |
| 416 | wait = 2; | 417 | wait = 2; |
| 417 | else | 418 | else |
| @@ -533,7 +534,7 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 533 | 534 | ||
| 534 | /* reuse the previous schedule slots, if we can */ | 535 | /* reuse the previous schedule slots, if we can */ |
| 535 | if (frame < qh->period) { | 536 | if (frame < qh->period) { |
| 536 | uframe = ffs (le32_to_cpup (&qh->hw_info2) & 0x00ff); | 537 | uframe = ffs (le32_to_cpup (&qh->hw_info2) & QH_SMASK); |
| 537 | status = check_intr_schedule (ehci, frame, --uframe, | 538 | status = check_intr_schedule (ehci, frame, --uframe, |
| 538 | qh, &c_mask); | 539 | qh, &c_mask); |
| 539 | } else { | 540 | } else { |
| @@ -569,10 +570,10 @@ static int qh_schedule (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 569 | qh->start = frame; | 570 | qh->start = frame; |
| 570 | 571 | ||
| 571 | /* reset S-frame and (maybe) C-frame masks */ | 572 | /* reset S-frame and (maybe) C-frame masks */ |
| 572 | qh->hw_info2 &= __constant_cpu_to_le32 (~0xffff); | 573 | qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK)); |
| 573 | qh->hw_info2 |= qh->period | 574 | qh->hw_info2 |= qh->period |
| 574 | ? cpu_to_le32 (1 << uframe) | 575 | ? cpu_to_le32 (1 << uframe) |
| 575 | : __constant_cpu_to_le32 (0xff); | 576 | : __constant_cpu_to_le32 (QH_SMASK); |
| 576 | qh->hw_info2 |= c_mask; | 577 | qh->hw_info2 |= c_mask; |
| 577 | } else | 578 | } else |
| 578 | ehci_dbg (ehci, "reused qh %p schedule\n", qh); | 579 | ehci_dbg (ehci, "reused qh %p schedule\n", qh); |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 4df498231752..a7542157534c 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
| @@ -385,6 +385,11 @@ struct ehci_qh { | |||
| 385 | __le32 hw_info1; /* see EHCI 3.6.2 */ | 385 | __le32 hw_info1; /* see EHCI 3.6.2 */ |
| 386 | #define QH_HEAD 0x00008000 | 386 | #define QH_HEAD 0x00008000 |
| 387 | __le32 hw_info2; /* see EHCI 3.6.2 */ | 387 | __le32 hw_info2; /* see EHCI 3.6.2 */ |
| 388 | #define QH_SMASK 0x000000ff | ||
| 389 | #define QH_CMASK 0x0000ff00 | ||
| 390 | #define QH_HUBADDR 0x007f0000 | ||
| 391 | #define QH_HUBPORT 0x3f800000 | ||
| 392 | #define QH_MULT 0xc0000000 | ||
| 388 | __le32 hw_current; /* qtd list - see EHCI 3.6.4 */ | 393 | __le32 hw_current; /* qtd list - see EHCI 3.6.4 */ |
| 389 | 394 | ||
| 390 | /* qtd overlay (hardware parts of a struct ehci_qtd) */ | 395 | /* qtd overlay (hardware parts of a struct ehci_qtd) */ |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 50b1970fe6b6..76cb496c5836 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
| @@ -229,9 +229,11 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
| 229 | struct isp116x_ep *ep; | 229 | struct isp116x_ep *ep; |
| 230 | struct urb *urb; | 230 | struct urb *urb; |
| 231 | struct ptd *ptd; | 231 | struct ptd *ptd; |
| 232 | u16 toggle = 0, dir = PTD_DIR_SETUP, len; | 232 | u16 len; |
| 233 | 233 | ||
| 234 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | 234 | for (ep = isp116x->atl_active; ep; ep = ep->active) { |
| 235 | u16 toggle = 0, dir = PTD_DIR_SETUP; | ||
| 236 | |||
| 235 | BUG_ON(list_empty(&ep->hep->urb_list)); | 237 | BUG_ON(list_empty(&ep->hep->urb_list)); |
| 236 | urb = container_of(ep->hep->urb_list.next, | 238 | urb = container_of(ep->hep->urb_list.next, |
| 237 | struct urb, urb_list); | 239 | struct urb, urb_list); |
diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig index 777642e26b9a..deb9ddffa402 100644 --- a/drivers/usb/mon/Kconfig +++ b/drivers/usb/mon/Kconfig | |||
| @@ -9,9 +9,8 @@ config USB_MON | |||
| 9 | help | 9 | help |
| 10 | If you say Y here, a component which captures the USB traffic | 10 | If you say Y here, a component which captures the USB traffic |
| 11 | between peripheral-specific drivers and HC drivers will be built. | 11 | between peripheral-specific drivers and HC drivers will be built. |
| 12 | The USB_MON is similar in spirit and may be compatible with Dave | 12 | For more information, see <file:Documentation/usb/usbmon.txt>. |
| 13 | Harding's USBMon. | ||
| 14 | 13 | ||
| 15 | This is somewhat experimental at this time, but it should be safe, | 14 | This is somewhat experimental at this time, but it should be safe. |
| 16 | as long as you aren't using modular USB and try to remove this | 15 | |
| 17 | module. | 16 | If unsure, say Y. |
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile index f18d10ce91f9..b0015b8a1d1f 100644 --- a/drivers/usb/mon/Makefile +++ b/drivers/usb/mon/Makefile | |||
| @@ -4,4 +4,5 @@ | |||
| 4 | 4 | ||
| 5 | usbmon-objs := mon_main.o mon_stat.o mon_text.o | 5 | usbmon-objs := mon_main.o mon_stat.o mon_text.o |
| 6 | 6 | ||
| 7 | # This does not use CONFIG_USB_MON because we want this to use a tristate. | ||
| 7 | obj-$(CONFIG_USB) += usbmon.o | 8 | obj-$(CONFIG_USB) += usbmon.o |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index fbf659b6dab0..3edc9f49344b 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
| @@ -246,6 +246,11 @@ static const struct fb_videomode modedb[] = { | |||
| 246 | /* 480x300 @ 72 Hz, 48.0 kHz hsync */ | 246 | /* 480x300 @ 72 Hz, 48.0 kHz hsync */ |
| 247 | NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, | 247 | NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3, |
| 248 | 0, FB_VMODE_DOUBLE | 248 | 0, FB_VMODE_DOUBLE |
| 249 | }, { | ||
| 250 | /* 1920x1200 @ 60 Hz, 74.5 Khz hsync */ | ||
| 251 | NULL, 60, 1920, 1200, 5177, 128, 336, 1, 38, 208, 3, | ||
| 252 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
| 253 | FB_VMODE_NONINTERLACED | ||
| 249 | }, | 254 | }, |
| 250 | }; | 255 | }; |
| 251 | 256 | ||
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index b2e6b2407869..52b16850a54e 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
| @@ -1324,6 +1324,13 @@ static int __devinit nvidia_set_fbinfo(struct fb_info *info) | |||
| 1324 | 1324 | ||
| 1325 | fb_videomode_to_var(&nvidiafb_default_var, &modedb); | 1325 | fb_videomode_to_var(&nvidiafb_default_var, &modedb); |
| 1326 | nvidiafb_default_var.bits_per_pixel = 8; | 1326 | nvidiafb_default_var.bits_per_pixel = 8; |
| 1327 | } else if (par->fpWidth && par->fpHeight) { | ||
| 1328 | char buf[16]; | ||
| 1329 | |||
| 1330 | memset(buf, 0, 16); | ||
| 1331 | snprintf(buf, 15, "%dx%d", par->fpWidth, par->fpHeight); | ||
| 1332 | fb_find_mode(&nvidiafb_default_var, info, buf, specs->modedb, | ||
| 1333 | specs->modedb_len, &modedb, 8); | ||
| 1327 | } | 1334 | } |
| 1328 | 1335 | ||
| 1329 | if (mode_option) | 1336 | if (mode_option) |
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c index 2d29db7ef800..beeec7b51425 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/sa1100fb.c | |||
| @@ -598,7 +598,7 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
| 598 | * requests for the LCD controller. If we hit this, it means we're | 598 | * requests for the LCD controller. If we hit this, it means we're |
| 599 | * doing nothing but LCD DMA. | 599 | * doing nothing but LCD DMA. |
| 600 | */ | 600 | */ |
| 601 | static unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var) | 601 | static inline unsigned int sa1100fb_display_dma_period(struct fb_var_screeninfo *var) |
| 602 | { | 602 | { |
| 603 | /* | 603 | /* |
| 604 | * Period = pixclock * bits_per_byte * bytes_per_transfer | 604 | * Period = pixclock * bits_per_byte * bytes_per_transfer |
