diff options
171 files changed, 6253 insertions, 2121 deletions
diff --git a/Documentation/input/input.txt b/Documentation/input/input.txt index 686ee9932dff..b93c08442e3c 100644 --- a/Documentation/input/input.txt +++ b/Documentation/input/input.txt | |||
| @@ -278,7 +278,7 @@ struct input_event { | |||
| 278 | }; | 278 | }; |
| 279 | 279 | ||
| 280 | 'time' is the timestamp, it returns the time at which the event happened. | 280 | 'time' is the timestamp, it returns the time at which the event happened. |
| 281 | Type is for example EV_REL for relative moment, REL_KEY for a keypress or | 281 | Type is for example EV_REL for relative moment, EV_KEY for a keypress or |
| 282 | release. More types are defined in include/linux/input.h. | 282 | release. More types are defined in include/linux/input.h. |
| 283 | 283 | ||
| 284 | 'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete | 284 | 'code' is event code, for example REL_X or KEY_BACKSPACE, again a complete |
diff --git a/Documentation/input/rotary-encoder.txt b/Documentation/input/rotary-encoder.txt index 435102a26d96..3a6aec40c0b0 100644 --- a/Documentation/input/rotary-encoder.txt +++ b/Documentation/input/rotary-encoder.txt | |||
| @@ -67,7 +67,12 @@ data with it. | |||
| 67 | struct rotary_encoder_platform_data is declared in | 67 | struct rotary_encoder_platform_data is declared in |
| 68 | include/linux/rotary-encoder.h and needs to be filled with the number of | 68 | include/linux/rotary-encoder.h and needs to be filled with the number of |
| 69 | steps the encoder has and can carry information about externally inverted | 69 | steps the encoder has and can carry information about externally inverted |
| 70 | signals (because of used invertig buffer or other reasons). | 70 | signals (because of an inverting buffer or other reasons). The encoder |
| 71 | can be set up to deliver input information as either an absolute or relative | ||
| 72 | axes. For relative axes the input event returns +/-1 for each step. For | ||
| 73 | absolute axes the position of the encoder can either roll over between zero | ||
| 74 | and the number of steps or will clamp at the maximum and zero depending on | ||
| 75 | the configuration. | ||
| 71 | 76 | ||
| 72 | Because GPIO to IRQ mapping is platform specific, this information must | 77 | Because GPIO to IRQ mapping is platform specific, this information must |
| 73 | be given in seperately to the driver. See the example below. | 78 | be given in seperately to the driver. See the example below. |
| @@ -85,6 +90,8 @@ be given in seperately to the driver. See the example below. | |||
| 85 | static struct rotary_encoder_platform_data my_rotary_encoder_info = { | 90 | static struct rotary_encoder_platform_data my_rotary_encoder_info = { |
| 86 | .steps = 24, | 91 | .steps = 24, |
| 87 | .axis = ABS_X, | 92 | .axis = ABS_X, |
| 93 | .relative_axis = false, | ||
| 94 | .rollover = false, | ||
| 88 | .gpio_a = GPIO_ROTARY_A, | 95 | .gpio_a = GPIO_ROTARY_A, |
| 89 | .gpio_b = GPIO_ROTARY_B, | 96 | .gpio_b = GPIO_ROTARY_B, |
| 90 | .inverted_a = 0, | 97 | .inverted_a = 0, |
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h new file mode 100644 index 000000000000..83f31cd0a274 --- /dev/null +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | /* | ||
| 2 | * arch/arm/mach-ep93xx/include/mach/ep93xx_keypad.h | ||
| 3 | */ | ||
| 4 | |||
| 5 | #ifndef __ASM_ARCH_EP93XX_KEYPAD_H | ||
| 6 | #define __ASM_ARCH_EP93XX_KEYPAD_H | ||
| 7 | |||
| 8 | #define MAX_MATRIX_KEY_ROWS (8) | ||
| 9 | #define MAX_MATRIX_KEY_COLS (8) | ||
| 10 | |||
| 11 | /* flags for the ep93xx_keypad driver */ | ||
| 12 | #define EP93XX_KEYPAD_DISABLE_3_KEY (1<<0) /* disable 3-key reset */ | ||
| 13 | #define EP93XX_KEYPAD_DIAG_MODE (1<<1) /* diagnostic mode */ | ||
| 14 | #define EP93XX_KEYPAD_BACK_DRIVE (1<<2) /* back driving mode */ | ||
| 15 | #define EP93XX_KEYPAD_TEST_MODE (1<<3) /* scan only column 0 */ | ||
| 16 | #define EP93XX_KEYPAD_KDIV (1<<4) /* 1/4 clock or 1/16 clock */ | ||
| 17 | #define EP93XX_KEYPAD_AUTOREPEAT (1<<5) /* enable key autorepeat */ | ||
| 18 | |||
| 19 | /** | ||
| 20 | * struct ep93xx_keypad_platform_data - platform specific device structure | ||
| 21 | * @matrix_key_rows: number of rows in the keypad matrix | ||
| 22 | * @matrix_key_cols: number of columns in the keypad matrix | ||
| 23 | * @matrix_key_map: array of keycodes defining the keypad matrix | ||
| 24 | * @matrix_key_map_size: ARRAY_SIZE(matrix_key_map) | ||
| 25 | * @debounce: debounce start count; terminal count is 0xff | ||
| 26 | * @prescale: row/column counter pre-scaler load value | ||
| 27 | * @flags: see above | ||
| 28 | */ | ||
| 29 | struct ep93xx_keypad_platform_data { | ||
| 30 | unsigned int matrix_key_rows; | ||
| 31 | unsigned int matrix_key_cols; | ||
| 32 | unsigned int *matrix_key_map; | ||
| 33 | int matrix_key_map_size; | ||
| 34 | unsigned int debounce; | ||
| 35 | unsigned int prescale; | ||
| 36 | unsigned int flags; | ||
| 37 | }; | ||
| 38 | |||
| 39 | /* macro for creating the matrix_key_map table */ | ||
| 40 | #define KEY(row, col, val) (((row) << 28) | ((col) << 24) | (val)) | ||
| 41 | |||
| 42 | #endif /* __ASM_ARCH_EP93XX_KEYPAD_H */ | ||
diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index 6340cef6798a..f97480941269 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c | |||
| @@ -247,10 +247,15 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
| 247 | start &= PAGE_MASK; | 247 | start &= PAGE_MASK; |
| 248 | addr = start; | 248 | addr = start; |
| 249 | len = (unsigned long) nr_pages << PAGE_SHIFT; | 249 | len = (unsigned long) nr_pages << PAGE_SHIFT; |
| 250 | |||
| 250 | end = start + len; | 251 | end = start + len; |
| 251 | if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ, | 252 | if (end < start) |
| 252 | (void __user *)start, len))) | 253 | goto slow_irqon; |
| 254 | |||
| 255 | #ifdef CONFIG_X86_64 | ||
| 256 | if (end >> __VIRTUAL_MASK_SHIFT) | ||
| 253 | goto slow_irqon; | 257 | goto slow_irqon; |
| 258 | #endif | ||
| 254 | 259 | ||
| 255 | /* | 260 | /* |
| 256 | * XXX: batch / limit 'nr', to avoid large irq off latency | 261 | * XXX: batch / limit 'nr', to avoid large irq off latency |
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 46f507531177..178e2e9e9f09 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h | |||
| @@ -107,7 +107,7 @@ struct agp_bridge_driver { | |||
| 107 | void (*agp_enable)(struct agp_bridge_data *, u32); | 107 | void (*agp_enable)(struct agp_bridge_data *, u32); |
| 108 | void (*cleanup)(void); | 108 | void (*cleanup)(void); |
| 109 | void (*tlb_flush)(struct agp_memory *); | 109 | void (*tlb_flush)(struct agp_memory *); |
| 110 | unsigned long (*mask_memory)(struct agp_bridge_data *, unsigned long, int); | 110 | unsigned long (*mask_memory)(struct agp_bridge_data *, struct page *, int); |
| 111 | void (*cache_flush)(void); | 111 | void (*cache_flush)(void); |
| 112 | int (*create_gatt_table)(struct agp_bridge_data *); | 112 | int (*create_gatt_table)(struct agp_bridge_data *); |
| 113 | int (*free_gatt_table)(struct agp_bridge_data *); | 113 | int (*free_gatt_table)(struct agp_bridge_data *); |
| @@ -115,9 +115,9 @@ struct agp_bridge_driver { | |||
| 115 | int (*remove_memory)(struct agp_memory *, off_t, int); | 115 | int (*remove_memory)(struct agp_memory *, off_t, int); |
| 116 | struct agp_memory *(*alloc_by_type) (size_t, int); | 116 | struct agp_memory *(*alloc_by_type) (size_t, int); |
| 117 | void (*free_by_type)(struct agp_memory *); | 117 | void (*free_by_type)(struct agp_memory *); |
| 118 | void *(*agp_alloc_page)(struct agp_bridge_data *); | 118 | struct page *(*agp_alloc_page)(struct agp_bridge_data *); |
| 119 | int (*agp_alloc_pages)(struct agp_bridge_data *, struct agp_memory *, size_t); | 119 | int (*agp_alloc_pages)(struct agp_bridge_data *, struct agp_memory *, size_t); |
| 120 | void (*agp_destroy_page)(void *, int flags); | 120 | void (*agp_destroy_page)(struct page *, int flags); |
| 121 | void (*agp_destroy_pages)(struct agp_memory *); | 121 | void (*agp_destroy_pages)(struct agp_memory *); |
| 122 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); | 122 | int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); |
| 123 | void (*chipset_flush)(struct agp_bridge_data *); | 123 | void (*chipset_flush)(struct agp_bridge_data *); |
| @@ -278,10 +278,10 @@ int agp_generic_insert_memory(struct agp_memory *mem, off_t pg_start, int type); | |||
| 278 | int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type); | 278 | int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type); |
| 279 | struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); | 279 | struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type); |
| 280 | void agp_generic_free_by_type(struct agp_memory *curr); | 280 | void agp_generic_free_by_type(struct agp_memory *curr); |
| 281 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge); | 281 | struct page *agp_generic_alloc_page(struct agp_bridge_data *bridge); |
| 282 | int agp_generic_alloc_pages(struct agp_bridge_data *agp_bridge, | 282 | int agp_generic_alloc_pages(struct agp_bridge_data *agp_bridge, |
| 283 | struct agp_memory *memory, size_t page_count); | 283 | struct agp_memory *memory, size_t page_count); |
| 284 | void agp_generic_destroy_page(void *addr, int flags); | 284 | void agp_generic_destroy_page(struct page *page, int flags); |
| 285 | void agp_generic_destroy_pages(struct agp_memory *memory); | 285 | void agp_generic_destroy_pages(struct agp_memory *memory); |
| 286 | void agp_free_key(int key); | 286 | void agp_free_key(int key); |
| 287 | int agp_num_entries(void); | 287 | int agp_num_entries(void); |
| @@ -291,7 +291,7 @@ int agp_3_5_enable(struct agp_bridge_data *bridge); | |||
| 291 | void global_cache_flush(void); | 291 | void global_cache_flush(void); |
| 292 | void get_agp_version(struct agp_bridge_data *bridge); | 292 | void get_agp_version(struct agp_bridge_data *bridge); |
| 293 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, | 293 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, |
| 294 | unsigned long addr, int type); | 294 | struct page *page, int type); |
| 295 | int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge, | 295 | int agp_generic_type_to_mask_type(struct agp_bridge_data *bridge, |
| 296 | int type); | 296 | int type); |
| 297 | struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev); | 297 | struct agp_bridge_data *agp_generic_find_bridge(struct pci_dev *pdev); |
diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index dc8d1a90971f..201ef3ffd484 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c | |||
| @@ -141,37 +141,37 @@ static void m1541_cache_flush(void) | |||
| 141 | } | 141 | } |
| 142 | } | 142 | } |
| 143 | 143 | ||
| 144 | static void *m1541_alloc_page(struct agp_bridge_data *bridge) | 144 | static struct page *m1541_alloc_page(struct agp_bridge_data *bridge) |
| 145 | { | 145 | { |
| 146 | void *addr = agp_generic_alloc_page(agp_bridge); | 146 | struct page *page = agp_generic_alloc_page(agp_bridge); |
| 147 | u32 temp; | 147 | u32 temp; |
| 148 | 148 | ||
| 149 | if (!addr) | 149 | if (!page) |
| 150 | return NULL; | 150 | return NULL; |
| 151 | 151 | ||
| 152 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); | 152 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); |
| 153 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, | 153 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, |
| 154 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | | 154 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | |
| 155 | virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN )); | 155 | phys_to_gart(page_to_phys(page))) | ALI_CACHE_FLUSH_EN )); |
| 156 | return addr; | 156 | return page; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static void ali_destroy_page(void * addr, int flags) | 159 | static void ali_destroy_page(struct page *page, int flags) |
| 160 | { | 160 | { |
| 161 | if (addr) { | 161 | if (page) { |
| 162 | if (flags & AGP_PAGE_DESTROY_UNMAP) { | 162 | if (flags & AGP_PAGE_DESTROY_UNMAP) { |
| 163 | global_cache_flush(); /* is this really needed? --hch */ | 163 | global_cache_flush(); /* is this really needed? --hch */ |
| 164 | agp_generic_destroy_page(addr, flags); | 164 | agp_generic_destroy_page(page, flags); |
| 165 | } else | 165 | } else |
| 166 | agp_generic_destroy_page(addr, flags); | 166 | agp_generic_destroy_page(page, flags); |
| 167 | } | 167 | } |
| 168 | } | 168 | } |
| 169 | 169 | ||
| 170 | static void m1541_destroy_page(void * addr, int flags) | 170 | static void m1541_destroy_page(struct page *page, int flags) |
| 171 | { | 171 | { |
| 172 | u32 temp; | 172 | u32 temp; |
| 173 | 173 | ||
| 174 | if (addr == NULL) | 174 | if (page == NULL) |
| 175 | return; | 175 | return; |
| 176 | 176 | ||
| 177 | if (flags & AGP_PAGE_DESTROY_UNMAP) { | 177 | if (flags & AGP_PAGE_DESTROY_UNMAP) { |
| @@ -180,9 +180,9 @@ static void m1541_destroy_page(void * addr, int flags) | |||
| 180 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); | 180 | pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp); |
| 181 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, | 181 | pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, |
| 182 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | | 182 | (((temp & ALI_CACHE_FLUSH_ADDR_MASK) | |
| 183 | virt_to_gart(addr)) | ALI_CACHE_FLUSH_EN)); | 183 | phys_to_gart(page_to_phys(page))) | ALI_CACHE_FLUSH_EN)); |
| 184 | } | 184 | } |
| 185 | agp_generic_destroy_page(addr, flags); | 185 | agp_generic_destroy_page(page, flags); |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | 188 | ||
| @@ -346,7 +346,7 @@ found: | |||
| 346 | devs[j].chipset_name = "M1641"; | 346 | devs[j].chipset_name = "M1641"; |
| 347 | break; | 347 | break; |
| 348 | case 0x43: | 348 | case 0x43: |
| 349 | devs[j].chipset_name = "M????"; | 349 | devs[j].chipset_name = "M1621"; |
| 350 | break; | 350 | break; |
| 351 | case 0x47: | 351 | case 0x47: |
| 352 | devs[j].chipset_name = "M1647"; | 352 | devs[j].chipset_name = "M1647"; |
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index 3f98254b911f..ba9bde71eaaf 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c | |||
| @@ -325,7 +325,7 @@ static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
| 325 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; | 325 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; |
| 326 | cur_gatt = GET_GATT(addr); | 326 | cur_gatt = GET_GATT(addr); |
| 327 | writel(agp_generic_mask_memory(agp_bridge, | 327 | writel(agp_generic_mask_memory(agp_bridge, |
| 328 | mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr)); | 328 | mem->pages[i], mem->type), cur_gatt+GET_GATT_OFF(addr)); |
| 329 | readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ | 329 | readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ |
| 330 | } | 330 | } |
| 331 | amd_irongate_tlbflush(mem); | 331 | amd_irongate_tlbflush(mem); |
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index d765afda9c2a..3bf5dda90f4a 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c | |||
| @@ -79,7 +79,7 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
| 79 | 79 | ||
| 80 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 80 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 81 | tmp = agp_bridge->driver->mask_memory(agp_bridge, | 81 | tmp = agp_bridge->driver->mask_memory(agp_bridge, |
| 82 | mem->memory[i], mask_type); | 82 | mem->pages[i], mask_type); |
| 83 | 83 | ||
| 84 | BUG_ON(tmp & 0xffffff0000000ffcULL); | 84 | BUG_ON(tmp & 0xffffff0000000ffcULL); |
| 85 | pte = (tmp & 0x000000ff00000000ULL) >> 28; | 85 | pte = (tmp & 0x000000ff00000000ULL) >> 28; |
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index f1537eece07f..33656e144cc5 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c | |||
| @@ -269,12 +269,17 @@ static int ati_insert_memory(struct agp_memory * mem, | |||
| 269 | int i, j, num_entries; | 269 | int i, j, num_entries; |
| 270 | unsigned long __iomem *cur_gatt; | 270 | unsigned long __iomem *cur_gatt; |
| 271 | unsigned long addr; | 271 | unsigned long addr; |
| 272 | int mask_type; | ||
| 272 | 273 | ||
| 273 | num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; | 274 | num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries; |
| 274 | 275 | ||
| 275 | if (type != 0 || mem->type != 0) | 276 | mask_type = agp_generic_type_to_mask_type(mem->bridge, type); |
| 277 | if (mask_type != 0 || type != mem->type) | ||
| 276 | return -EINVAL; | 278 | return -EINVAL; |
| 277 | 279 | ||
| 280 | if (mem->page_count == 0) | ||
| 281 | return 0; | ||
| 282 | |||
| 278 | if ((pg_start + mem->page_count) > num_entries) | 283 | if ((pg_start + mem->page_count) > num_entries) |
| 279 | return -EINVAL; | 284 | return -EINVAL; |
| 280 | 285 | ||
| @@ -296,10 +301,11 @@ static int ati_insert_memory(struct agp_memory * mem, | |||
| 296 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 301 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 297 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; | 302 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; |
| 298 | cur_gatt = GET_GATT(addr); | 303 | cur_gatt = GET_GATT(addr); |
| 299 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 304 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
| 300 | mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr)); | 305 | mem->pages[i], mem->type), |
| 301 | readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ | 306 | cur_gatt+GET_GATT_OFF(addr)); |
| 302 | } | 307 | } |
| 308 | readl(GET_GATT(agp_bridge->gart_bus_addr)); /* PCI posting */ | ||
| 303 | agp_bridge->driver->tlb_flush(mem); | 309 | agp_bridge->driver->tlb_flush(mem); |
| 304 | return 0; | 310 | return 0; |
| 305 | } | 311 | } |
| @@ -310,17 +316,22 @@ static int ati_remove_memory(struct agp_memory * mem, off_t pg_start, | |||
| 310 | int i; | 316 | int i; |
| 311 | unsigned long __iomem *cur_gatt; | 317 | unsigned long __iomem *cur_gatt; |
| 312 | unsigned long addr; | 318 | unsigned long addr; |
| 319 | int mask_type; | ||
| 313 | 320 | ||
| 314 | if (type != 0 || mem->type != 0) | 321 | mask_type = agp_generic_type_to_mask_type(mem->bridge, type); |
| 322 | if (mask_type != 0 || type != mem->type) | ||
| 315 | return -EINVAL; | 323 | return -EINVAL; |
| 316 | 324 | ||
| 325 | if (mem->page_count == 0) | ||
| 326 | return 0; | ||
| 327 | |||
| 317 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 328 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { |
| 318 | addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; | 329 | addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr; |
| 319 | cur_gatt = GET_GATT(addr); | 330 | cur_gatt = GET_GATT(addr); |
| 320 | writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr)); | 331 | writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr)); |
| 321 | readl(cur_gatt+GET_GATT_OFF(addr)); /* PCI Posting. */ | ||
| 322 | } | 332 | } |
| 323 | 333 | ||
| 334 | readl(GET_GATT(agp_bridge->gart_bus_addr)); /* PCI posting */ | ||
| 324 | agp_bridge->driver->tlb_flush(mem); | 335 | agp_bridge->driver->tlb_flush(mem); |
| 325 | return 0; | 336 | return 0; |
| 326 | } | 337 | } |
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c index 8c617ad7497f..cfa5a649dfe7 100644 --- a/drivers/char/agp/backend.c +++ b/drivers/char/agp/backend.c | |||
| @@ -141,17 +141,17 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge) | |||
| 141 | bridge->version = &agp_current_version; | 141 | bridge->version = &agp_current_version; |
| 142 | 142 | ||
| 143 | if (bridge->driver->needs_scratch_page) { | 143 | if (bridge->driver->needs_scratch_page) { |
| 144 | void *addr = bridge->driver->agp_alloc_page(bridge); | 144 | struct page *page = bridge->driver->agp_alloc_page(bridge); |
| 145 | 145 | ||
| 146 | if (!addr) { | 146 | if (!page) { |
| 147 | dev_err(&bridge->dev->dev, | 147 | dev_err(&bridge->dev->dev, |
| 148 | "can't get memory for scratch page\n"); | 148 | "can't get memory for scratch page\n"); |
| 149 | return -ENOMEM; | 149 | return -ENOMEM; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | bridge->scratch_page_real = virt_to_gart(addr); | 152 | bridge->scratch_page_real = phys_to_gart(page_to_phys(page)); |
| 153 | bridge->scratch_page = | 153 | bridge->scratch_page = |
| 154 | bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); | 154 | bridge->driver->mask_memory(bridge, page, 0); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | size_value = bridge->driver->fetch_size(); | 157 | size_value = bridge->driver->fetch_size(); |
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index 453543a1f293..35d50f2861b6 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c | |||
| @@ -65,8 +65,9 @@ static const struct gatt_mask efficeon_generic_masks[] = | |||
| 65 | }; | 65 | }; |
| 66 | 66 | ||
| 67 | /* This function does the same thing as mask_memory() for this chipset... */ | 67 | /* This function does the same thing as mask_memory() for this chipset... */ |
| 68 | static inline unsigned long efficeon_mask_memory(unsigned long addr) | 68 | static inline unsigned long efficeon_mask_memory(struct page *page) |
| 69 | { | 69 | { |
| 70 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
| 70 | return addr | 0x00000001; | 71 | return addr | 0x00000001; |
| 71 | } | 72 | } |
| 72 | 73 | ||
| @@ -257,7 +258,7 @@ static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int t | |||
| 257 | last_page = NULL; | 258 | last_page = NULL; |
| 258 | for (i = 0; i < count; i++) { | 259 | for (i = 0; i < count; i++) { |
| 259 | int index = pg_start + i; | 260 | int index = pg_start + i; |
| 260 | unsigned long insert = efficeon_mask_memory(mem->memory[i]); | 261 | unsigned long insert = efficeon_mask_memory(mem->pages[i]); |
| 261 | 262 | ||
| 262 | page = (unsigned int *) efficeon_private.l1_table[index >> 10]; | 263 | page = (unsigned int *) efficeon_private.l1_table[index >> 10]; |
| 263 | 264 | ||
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 2224b762b7fb..1e8b461b91f1 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c | |||
| @@ -95,13 +95,13 @@ EXPORT_SYMBOL(agp_flush_chipset); | |||
| 95 | 95 | ||
| 96 | void agp_alloc_page_array(size_t size, struct agp_memory *mem) | 96 | void agp_alloc_page_array(size_t size, struct agp_memory *mem) |
| 97 | { | 97 | { |
| 98 | mem->memory = NULL; | 98 | mem->pages = NULL; |
| 99 | mem->vmalloc_flag = false; | 99 | mem->vmalloc_flag = false; |
| 100 | 100 | ||
| 101 | if (size <= 2*PAGE_SIZE) | 101 | if (size <= 2*PAGE_SIZE) |
| 102 | mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); | 102 | mem->pages = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); |
| 103 | if (mem->memory == NULL) { | 103 | if (mem->pages == NULL) { |
| 104 | mem->memory = vmalloc(size); | 104 | mem->pages = vmalloc(size); |
| 105 | mem->vmalloc_flag = true; | 105 | mem->vmalloc_flag = true; |
| 106 | } | 106 | } |
| 107 | } | 107 | } |
| @@ -110,9 +110,9 @@ EXPORT_SYMBOL(agp_alloc_page_array); | |||
| 110 | void agp_free_page_array(struct agp_memory *mem) | 110 | void agp_free_page_array(struct agp_memory *mem) |
| 111 | { | 111 | { |
| 112 | if (mem->vmalloc_flag) { | 112 | if (mem->vmalloc_flag) { |
| 113 | vfree(mem->memory); | 113 | vfree(mem->pages); |
| 114 | } else { | 114 | } else { |
| 115 | kfree(mem->memory); | 115 | kfree(mem->pages); |
| 116 | } | 116 | } |
| 117 | } | 117 | } |
| 118 | EXPORT_SYMBOL(agp_free_page_array); | 118 | EXPORT_SYMBOL(agp_free_page_array); |
| @@ -136,7 +136,7 @@ static struct agp_memory *agp_create_user_memory(unsigned long num_agp_pages) | |||
| 136 | 136 | ||
| 137 | agp_alloc_page_array(alloc_size, new); | 137 | agp_alloc_page_array(alloc_size, new); |
| 138 | 138 | ||
| 139 | if (new->memory == NULL) { | 139 | if (new->pages == NULL) { |
| 140 | agp_free_key(new->key); | 140 | agp_free_key(new->key); |
| 141 | kfree(new); | 141 | kfree(new); |
| 142 | return NULL; | 142 | return NULL; |
| @@ -162,7 +162,7 @@ struct agp_memory *agp_create_memory(int scratch_pages) | |||
| 162 | 162 | ||
| 163 | agp_alloc_page_array(PAGE_SIZE * scratch_pages, new); | 163 | agp_alloc_page_array(PAGE_SIZE * scratch_pages, new); |
| 164 | 164 | ||
| 165 | if (new->memory == NULL) { | 165 | if (new->pages == NULL) { |
| 166 | agp_free_key(new->key); | 166 | agp_free_key(new->key); |
| 167 | kfree(new); | 167 | kfree(new); |
| 168 | return NULL; | 168 | return NULL; |
| @@ -206,15 +206,13 @@ void agp_free_memory(struct agp_memory *curr) | |||
| 206 | } else { | 206 | } else { |
| 207 | 207 | ||
| 208 | for (i = 0; i < curr->page_count; i++) { | 208 | for (i = 0; i < curr->page_count; i++) { |
| 209 | curr->memory[i] = (unsigned long)gart_to_virt( | ||
| 210 | curr->memory[i]); | ||
| 211 | curr->bridge->driver->agp_destroy_page( | 209 | curr->bridge->driver->agp_destroy_page( |
| 212 | (void *)curr->memory[i], | 210 | curr->pages[i], |
| 213 | AGP_PAGE_DESTROY_UNMAP); | 211 | AGP_PAGE_DESTROY_UNMAP); |
| 214 | } | 212 | } |
| 215 | for (i = 0; i < curr->page_count; i++) { | 213 | for (i = 0; i < curr->page_count; i++) { |
| 216 | curr->bridge->driver->agp_destroy_page( | 214 | curr->bridge->driver->agp_destroy_page( |
| 217 | (void *)curr->memory[i], | 215 | curr->pages[i], |
| 218 | AGP_PAGE_DESTROY_FREE); | 216 | AGP_PAGE_DESTROY_FREE); |
| 219 | } | 217 | } |
| 220 | } | 218 | } |
| @@ -282,13 +280,13 @@ struct agp_memory *agp_allocate_memory(struct agp_bridge_data *bridge, | |||
| 282 | } | 280 | } |
| 283 | 281 | ||
| 284 | for (i = 0; i < page_count; i++) { | 282 | for (i = 0; i < page_count; i++) { |
| 285 | void *addr = bridge->driver->agp_alloc_page(bridge); | 283 | struct page *page = bridge->driver->agp_alloc_page(bridge); |
| 286 | 284 | ||
| 287 | if (addr == NULL) { | 285 | if (page == NULL) { |
| 288 | agp_free_memory(new); | 286 | agp_free_memory(new); |
| 289 | return NULL; | 287 | return NULL; |
| 290 | } | 288 | } |
| 291 | new->memory[i] = virt_to_gart(addr); | 289 | new->pages[i] = page; |
| 292 | new->page_count++; | 290 | new->page_count++; |
| 293 | } | 291 | } |
| 294 | new->bridge = bridge; | 292 | new->bridge = bridge; |
| @@ -1134,7 +1132,7 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type) | |||
| 1134 | } | 1132 | } |
| 1135 | 1133 | ||
| 1136 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1134 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 1137 | writel(bridge->driver->mask_memory(bridge, mem->memory[i], mask_type), | 1135 | writel(bridge->driver->mask_memory(bridge, mem->pages[i], mask_type), |
| 1138 | bridge->gatt_table+j); | 1136 | bridge->gatt_table+j); |
| 1139 | } | 1137 | } |
| 1140 | readl(bridge->gatt_table+j-1); /* PCI Posting. */ | 1138 | readl(bridge->gatt_table+j-1); /* PCI Posting. */ |
| @@ -1204,7 +1202,7 @@ struct agp_memory *agp_generic_alloc_user(size_t page_count, int type) | |||
| 1204 | return NULL; | 1202 | return NULL; |
| 1205 | 1203 | ||
| 1206 | for (i = 0; i < page_count; i++) | 1204 | for (i = 0; i < page_count; i++) |
| 1207 | new->memory[i] = 0; | 1205 | new->pages[i] = 0; |
| 1208 | new->page_count = 0; | 1206 | new->page_count = 0; |
| 1209 | new->type = type; | 1207 | new->type = type; |
| 1210 | new->num_scratch_pages = pages; | 1208 | new->num_scratch_pages = pages; |
| @@ -1237,23 +1235,20 @@ int agp_generic_alloc_pages(struct agp_bridge_data *bridge, struct agp_memory *m | |||
| 1237 | get_page(page); | 1235 | get_page(page); |
| 1238 | atomic_inc(&agp_bridge->current_memory_agp); | 1236 | atomic_inc(&agp_bridge->current_memory_agp); |
| 1239 | 1237 | ||
| 1240 | /* set_memory_array_uc() needs virtual address */ | 1238 | mem->pages[i] = page; |
| 1241 | mem->memory[i] = (unsigned long)page_address(page); | ||
| 1242 | mem->page_count++; | 1239 | mem->page_count++; |
| 1243 | } | 1240 | } |
| 1244 | 1241 | ||
| 1245 | #ifdef CONFIG_X86 | 1242 | #ifdef CONFIG_X86 |
| 1246 | set_memory_array_uc(mem->memory, num_pages); | 1243 | set_pages_array_uc(mem->pages, num_pages); |
| 1247 | #endif | 1244 | #endif |
| 1248 | ret = 0; | 1245 | ret = 0; |
| 1249 | out: | 1246 | out: |
| 1250 | for (i = 0; i < mem->page_count; i++) | ||
| 1251 | mem->memory[i] = virt_to_gart((void *)mem->memory[i]); | ||
| 1252 | return ret; | 1247 | return ret; |
| 1253 | } | 1248 | } |
| 1254 | EXPORT_SYMBOL(agp_generic_alloc_pages); | 1249 | EXPORT_SYMBOL(agp_generic_alloc_pages); |
| 1255 | 1250 | ||
| 1256 | void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | 1251 | struct page *agp_generic_alloc_page(struct agp_bridge_data *bridge) |
| 1257 | { | 1252 | { |
| 1258 | struct page * page; | 1253 | struct page * page; |
| 1259 | 1254 | ||
| @@ -1265,56 +1260,47 @@ void *agp_generic_alloc_page(struct agp_bridge_data *bridge) | |||
| 1265 | 1260 | ||
| 1266 | get_page(page); | 1261 | get_page(page); |
| 1267 | atomic_inc(&agp_bridge->current_memory_agp); | 1262 | atomic_inc(&agp_bridge->current_memory_agp); |
| 1268 | return page_address(page); | 1263 | return page; |
| 1269 | } | 1264 | } |
| 1270 | EXPORT_SYMBOL(agp_generic_alloc_page); | 1265 | EXPORT_SYMBOL(agp_generic_alloc_page); |
| 1271 | 1266 | ||
| 1272 | void agp_generic_destroy_pages(struct agp_memory *mem) | 1267 | void agp_generic_destroy_pages(struct agp_memory *mem) |
| 1273 | { | 1268 | { |
| 1274 | int i; | 1269 | int i; |
| 1275 | void *addr; | ||
| 1276 | struct page *page; | 1270 | struct page *page; |
| 1277 | 1271 | ||
| 1278 | if (!mem) | 1272 | if (!mem) |
| 1279 | return; | 1273 | return; |
| 1280 | 1274 | ||
| 1281 | for (i = 0; i < mem->page_count; i++) | ||
| 1282 | mem->memory[i] = (unsigned long)gart_to_virt(mem->memory[i]); | ||
| 1283 | |||
| 1284 | #ifdef CONFIG_X86 | 1275 | #ifdef CONFIG_X86 |
| 1285 | set_memory_array_wb(mem->memory, mem->page_count); | 1276 | set_pages_array_wb(mem->pages, mem->page_count); |
| 1286 | #endif | 1277 | #endif |
| 1287 | 1278 | ||
| 1288 | for (i = 0; i < mem->page_count; i++) { | 1279 | for (i = 0; i < mem->page_count; i++) { |
| 1289 | addr = (void *)mem->memory[i]; | 1280 | page = mem->pages[i]; |
| 1290 | page = virt_to_page(addr); | ||
| 1291 | 1281 | ||
| 1292 | #ifndef CONFIG_X86 | 1282 | #ifndef CONFIG_X86 |
| 1293 | unmap_page_from_agp(page); | 1283 | unmap_page_from_agp(page); |
| 1294 | #endif | 1284 | #endif |
| 1295 | |||
| 1296 | put_page(page); | 1285 | put_page(page); |
| 1297 | free_page((unsigned long)addr); | 1286 | __free_page(page); |
| 1298 | atomic_dec(&agp_bridge->current_memory_agp); | 1287 | atomic_dec(&agp_bridge->current_memory_agp); |
| 1299 | mem->memory[i] = 0; | 1288 | mem->pages[i] = NULL; |
| 1300 | } | 1289 | } |
| 1301 | } | 1290 | } |
| 1302 | EXPORT_SYMBOL(agp_generic_destroy_pages); | 1291 | EXPORT_SYMBOL(agp_generic_destroy_pages); |
| 1303 | 1292 | ||
| 1304 | void agp_generic_destroy_page(void *addr, int flags) | 1293 | void agp_generic_destroy_page(struct page *page, int flags) |
| 1305 | { | 1294 | { |
| 1306 | struct page *page; | 1295 | if (page == NULL) |
| 1307 | |||
| 1308 | if (addr == NULL) | ||
| 1309 | return; | 1296 | return; |
| 1310 | 1297 | ||
| 1311 | page = virt_to_page(addr); | ||
| 1312 | if (flags & AGP_PAGE_DESTROY_UNMAP) | 1298 | if (flags & AGP_PAGE_DESTROY_UNMAP) |
| 1313 | unmap_page_from_agp(page); | 1299 | unmap_page_from_agp(page); |
| 1314 | 1300 | ||
| 1315 | if (flags & AGP_PAGE_DESTROY_FREE) { | 1301 | if (flags & AGP_PAGE_DESTROY_FREE) { |
| 1316 | put_page(page); | 1302 | put_page(page); |
| 1317 | free_page((unsigned long)addr); | 1303 | __free_page(page); |
| 1318 | atomic_dec(&agp_bridge->current_memory_agp); | 1304 | atomic_dec(&agp_bridge->current_memory_agp); |
| 1319 | } | 1305 | } |
| 1320 | } | 1306 | } |
| @@ -1361,8 +1347,9 @@ void global_cache_flush(void) | |||
| 1361 | EXPORT_SYMBOL(global_cache_flush); | 1347 | EXPORT_SYMBOL(global_cache_flush); |
| 1362 | 1348 | ||
| 1363 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, | 1349 | unsigned long agp_generic_mask_memory(struct agp_bridge_data *bridge, |
| 1364 | unsigned long addr, int type) | 1350 | struct page *page, int type) |
| 1365 | { | 1351 | { |
| 1352 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
| 1366 | /* memory type is ignored in the generic routine */ | 1353 | /* memory type is ignored in the generic routine */ |
| 1367 | if (bridge->driver->masks) | 1354 | if (bridge->driver->masks) |
| 1368 | return addr | bridge->driver->masks[0].mask; | 1355 | return addr | bridge->driver->masks[0].mask; |
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 9c7e2343c399..8f3d4c184914 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c | |||
| @@ -361,13 +361,11 @@ hp_zx1_insert_memory (struct agp_memory *mem, off_t pg_start, int type) | |||
| 361 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { | 361 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { |
| 362 | unsigned long paddr; | 362 | unsigned long paddr; |
| 363 | 363 | ||
| 364 | paddr = mem->memory[i]; | 364 | paddr = page_to_phys(mem->pages[i]); |
| 365 | for (k = 0; | 365 | for (k = 0; |
| 366 | k < hp->io_pages_per_kpage; | 366 | k < hp->io_pages_per_kpage; |
| 367 | k++, j++, paddr += hp->io_page_size) { | 367 | k++, j++, paddr += hp->io_page_size) { |
| 368 | hp->gatt[j] = | 368 | hp->gatt[j] = HP_ZX1_PDIR_VALID_BIT | paddr; |
| 369 | agp_bridge->driver->mask_memory(agp_bridge, | ||
| 370 | paddr, type); | ||
| 371 | } | 369 | } |
| 372 | } | 370 | } |
| 373 | 371 | ||
| @@ -397,8 +395,9 @@ hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type) | |||
| 397 | 395 | ||
| 398 | static unsigned long | 396 | static unsigned long |
| 399 | hp_zx1_mask_memory (struct agp_bridge_data *bridge, | 397 | hp_zx1_mask_memory (struct agp_bridge_data *bridge, |
| 400 | unsigned long addr, int type) | 398 | struct page *page, int type) |
| 401 | { | 399 | { |
| 400 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
| 402 | return HP_ZX1_PDIR_VALID_BIT | addr; | 401 | return HP_ZX1_PDIR_VALID_BIT | addr; |
| 403 | } | 402 | } |
| 404 | 403 | ||
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 10da687d131a..60cc35bb5db7 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c | |||
| @@ -60,6 +60,9 @@ | |||
| 60 | */ | 60 | */ |
| 61 | #define WR_FLUSH_GATT(index) RD_GATT(index) | 61 | #define WR_FLUSH_GATT(index) RD_GATT(index) |
| 62 | 62 | ||
| 63 | static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, | ||
| 64 | unsigned long addr, int type); | ||
| 65 | |||
| 63 | static struct { | 66 | static struct { |
| 64 | void *gatt; /* ioremap'd GATT area */ | 67 | void *gatt; /* ioremap'd GATT area */ |
| 65 | 68 | ||
| @@ -74,6 +77,7 @@ static struct { | |||
| 74 | unsigned long *alloced_map; /* bitmap of kernel-pages in use */ | 77 | unsigned long *alloced_map; /* bitmap of kernel-pages in use */ |
| 75 | int refcount; /* number of kernel pages using the large page */ | 78 | int refcount; /* number of kernel pages using the large page */ |
| 76 | u64 paddr; /* physical address of large page */ | 79 | u64 paddr; /* physical address of large page */ |
| 80 | struct page *page; /* page pointer */ | ||
| 77 | } *lp_desc; | 81 | } *lp_desc; |
| 78 | } i460; | 82 | } i460; |
| 79 | 83 | ||
| @@ -294,7 +298,7 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem, | |||
| 294 | void *temp; | 298 | void *temp; |
| 295 | 299 | ||
| 296 | pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n", | 300 | pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n", |
| 297 | mem, pg_start, type, mem->memory[0]); | 301 | mem, pg_start, type, page_to_phys(mem->pages[0])); |
| 298 | 302 | ||
| 299 | if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES) | 303 | if (type >= AGP_USER_TYPES || mem->type >= AGP_USER_TYPES) |
| 300 | return -EINVAL; | 304 | return -EINVAL; |
| @@ -321,10 +325,9 @@ static int i460_insert_memory_small_io_page (struct agp_memory *mem, | |||
| 321 | 325 | ||
| 322 | io_page_size = 1UL << I460_IO_PAGE_SHIFT; | 326 | io_page_size = 1UL << I460_IO_PAGE_SHIFT; |
| 323 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { | 327 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { |
| 324 | paddr = mem->memory[i]; | 328 | paddr = phys_to_gart(page_to_phys(mem->pages[i])); |
| 325 | for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size) | 329 | for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size) |
| 326 | WR_GATT(j, agp_bridge->driver->mask_memory(agp_bridge, | 330 | WR_GATT(j, i460_mask_memory(agp_bridge, paddr, mem->type)); |
| 327 | paddr, mem->type)); | ||
| 328 | } | 331 | } |
| 329 | WR_FLUSH_GATT(j - 1); | 332 | WR_FLUSH_GATT(j - 1); |
| 330 | return 0; | 333 | return 0; |
| @@ -364,10 +367,9 @@ static int i460_alloc_large_page (struct lp_desc *lp) | |||
| 364 | { | 367 | { |
| 365 | unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT; | 368 | unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT; |
| 366 | size_t map_size; | 369 | size_t map_size; |
| 367 | void *lpage; | ||
| 368 | 370 | ||
| 369 | lpage = (void *) __get_free_pages(GFP_KERNEL, order); | 371 | lp->page = alloc_pages(GFP_KERNEL, order); |
| 370 | if (!lpage) { | 372 | if (!lp->page) { |
| 371 | printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n"); | 373 | printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n"); |
| 372 | return -ENOMEM; | 374 | return -ENOMEM; |
| 373 | } | 375 | } |
| @@ -375,12 +377,12 @@ static int i460_alloc_large_page (struct lp_desc *lp) | |||
| 375 | map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8; | 377 | map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8; |
| 376 | lp->alloced_map = kzalloc(map_size, GFP_KERNEL); | 378 | lp->alloced_map = kzalloc(map_size, GFP_KERNEL); |
| 377 | if (!lp->alloced_map) { | 379 | if (!lp->alloced_map) { |
| 378 | free_pages((unsigned long) lpage, order); | 380 | __free_pages(lp->page, order); |
| 379 | printk(KERN_ERR PFX "Out of memory, we're in trouble...\n"); | 381 | printk(KERN_ERR PFX "Out of memory, we're in trouble...\n"); |
| 380 | return -ENOMEM; | 382 | return -ENOMEM; |
| 381 | } | 383 | } |
| 382 | 384 | ||
| 383 | lp->paddr = virt_to_gart(lpage); | 385 | lp->paddr = phys_to_gart(page_to_phys(lp->page)); |
| 384 | lp->refcount = 0; | 386 | lp->refcount = 0; |
| 385 | atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); | 387 | atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); |
| 386 | return 0; | 388 | return 0; |
| @@ -391,7 +393,7 @@ static void i460_free_large_page (struct lp_desc *lp) | |||
| 391 | kfree(lp->alloced_map); | 393 | kfree(lp->alloced_map); |
| 392 | lp->alloced_map = NULL; | 394 | lp->alloced_map = NULL; |
| 393 | 395 | ||
| 394 | free_pages((unsigned long) gart_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT); | 396 | __free_pages(lp->page, I460_IO_PAGE_SHIFT - PAGE_SHIFT); |
| 395 | atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); | 397 | atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp); |
| 396 | } | 398 | } |
| 397 | 399 | ||
| @@ -439,8 +441,8 @@ static int i460_insert_memory_large_io_page (struct agp_memory *mem, | |||
| 439 | if (i460_alloc_large_page(lp) < 0) | 441 | if (i460_alloc_large_page(lp) < 0) |
| 440 | return -ENOMEM; | 442 | return -ENOMEM; |
| 441 | pg = lp - i460.lp_desc; | 443 | pg = lp - i460.lp_desc; |
| 442 | WR_GATT(pg, agp_bridge->driver->mask_memory(agp_bridge, | 444 | WR_GATT(pg, i460_mask_memory(agp_bridge, |
| 443 | lp->paddr, 0)); | 445 | lp->paddr, 0)); |
| 444 | WR_FLUSH_GATT(pg); | 446 | WR_FLUSH_GATT(pg); |
| 445 | } | 447 | } |
| 446 | 448 | ||
| @@ -448,7 +450,7 @@ static int i460_insert_memory_large_io_page (struct agp_memory *mem, | |||
| 448 | idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); | 450 | idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); |
| 449 | idx++, i++) | 451 | idx++, i++) |
| 450 | { | 452 | { |
| 451 | mem->memory[i] = lp->paddr + idx*PAGE_SIZE; | 453 | mem->pages[i] = lp->page; |
| 452 | __set_bit(idx, lp->alloced_map); | 454 | __set_bit(idx, lp->alloced_map); |
| 453 | ++lp->refcount; | 455 | ++lp->refcount; |
| 454 | } | 456 | } |
| @@ -463,7 +465,7 @@ static int i460_remove_memory_large_io_page (struct agp_memory *mem, | |||
| 463 | struct lp_desc *start, *end, *lp; | 465 | struct lp_desc *start, *end, *lp; |
| 464 | void *temp; | 466 | void *temp; |
| 465 | 467 | ||
| 466 | temp = agp_bridge->driver->current_size; | 468 | temp = agp_bridge->current_size; |
| 467 | num_entries = A_SIZE_8(temp)->num_entries; | 469 | num_entries = A_SIZE_8(temp)->num_entries; |
| 468 | 470 | ||
| 469 | /* Figure out what pg_start means in terms of our large GART pages */ | 471 | /* Figure out what pg_start means in terms of our large GART pages */ |
| @@ -477,7 +479,7 @@ static int i460_remove_memory_large_io_page (struct agp_memory *mem, | |||
| 477 | idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); | 479 | idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE); |
| 478 | idx++, i++) | 480 | idx++, i++) |
| 479 | { | 481 | { |
| 480 | mem->memory[i] = 0; | 482 | mem->pages[i] = NULL; |
| 481 | __clear_bit(idx, lp->alloced_map); | 483 | __clear_bit(idx, lp->alloced_map); |
| 482 | --lp->refcount; | 484 | --lp->refcount; |
| 483 | } | 485 | } |
| @@ -521,7 +523,7 @@ static int i460_remove_memory (struct agp_memory *mem, | |||
| 521 | * Let's just hope nobody counts on the allocated AGP memory being there before bind time | 523 | * Let's just hope nobody counts on the allocated AGP memory being there before bind time |
| 522 | * (I don't think current drivers do)... | 524 | * (I don't think current drivers do)... |
| 523 | */ | 525 | */ |
| 524 | static void *i460_alloc_page (struct agp_bridge_data *bridge) | 526 | static struct page *i460_alloc_page (struct agp_bridge_data *bridge) |
| 525 | { | 527 | { |
| 526 | void *page; | 528 | void *page; |
| 527 | 529 | ||
| @@ -534,7 +536,7 @@ static void *i460_alloc_page (struct agp_bridge_data *bridge) | |||
| 534 | return page; | 536 | return page; |
| 535 | } | 537 | } |
| 536 | 538 | ||
| 537 | static void i460_destroy_page (void *page, int flags) | 539 | static void i460_destroy_page (struct page *page, int flags) |
| 538 | { | 540 | { |
| 539 | if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) { | 541 | if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT) { |
| 540 | agp_generic_destroy_page(page, flags); | 542 | agp_generic_destroy_page(page, flags); |
| @@ -544,13 +546,20 @@ static void i460_destroy_page (void *page, int flags) | |||
| 544 | #endif /* I460_LARGE_IO_PAGES */ | 546 | #endif /* I460_LARGE_IO_PAGES */ |
| 545 | 547 | ||
| 546 | static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, | 548 | static unsigned long i460_mask_memory (struct agp_bridge_data *bridge, |
| 547 | unsigned long addr, int type) | 549 | unsigned long addr, int type) |
| 548 | { | 550 | { |
| 549 | /* Make sure the returned address is a valid GATT entry */ | 551 | /* Make sure the returned address is a valid GATT entry */ |
| 550 | return bridge->driver->masks[0].mask | 552 | return bridge->driver->masks[0].mask |
| 551 | | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12); | 553 | | (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xfffff000) >> 12); |
| 552 | } | 554 | } |
| 553 | 555 | ||
| 556 | static unsigned long i460_page_mask_memory(struct agp_bridge_data *bridge, | ||
| 557 | struct page *page, int type) | ||
| 558 | { | ||
| 559 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
| 560 | return i460_mask_memory(bridge, addr, type); | ||
| 561 | } | ||
| 562 | |||
| 554 | const struct agp_bridge_driver intel_i460_driver = { | 563 | const struct agp_bridge_driver intel_i460_driver = { |
| 555 | .owner = THIS_MODULE, | 564 | .owner = THIS_MODULE, |
| 556 | .aperture_sizes = i460_sizes, | 565 | .aperture_sizes = i460_sizes, |
| @@ -560,7 +569,7 @@ const struct agp_bridge_driver intel_i460_driver = { | |||
| 560 | .fetch_size = i460_fetch_size, | 569 | .fetch_size = i460_fetch_size, |
| 561 | .cleanup = i460_cleanup, | 570 | .cleanup = i460_cleanup, |
| 562 | .tlb_flush = i460_tlb_flush, | 571 | .tlb_flush = i460_tlb_flush, |
| 563 | .mask_memory = i460_mask_memory, | 572 | .mask_memory = i460_page_mask_memory, |
| 564 | .masks = i460_masks, | 573 | .masks = i460_masks, |
| 565 | .agp_enable = agp_generic_enable, | 574 | .agp_enable = agp_generic_enable, |
| 566 | .cache_flush = global_cache_flush, | 575 | .cache_flush = global_cache_flush, |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 7a748fa0dfce..8c9d50db5c3a 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
| @@ -257,7 +257,7 @@ static void intel_i810_agp_enable(struct agp_bridge_data *bridge, u32 mode) | |||
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | /* Exists to support ARGB cursors */ | 259 | /* Exists to support ARGB cursors */ |
| 260 | static void *i8xx_alloc_pages(void) | 260 | static struct page *i8xx_alloc_pages(void) |
| 261 | { | 261 | { |
| 262 | struct page *page; | 262 | struct page *page; |
| 263 | 263 | ||
| @@ -272,17 +272,14 @@ static void *i8xx_alloc_pages(void) | |||
| 272 | } | 272 | } |
| 273 | get_page(page); | 273 | get_page(page); |
| 274 | atomic_inc(&agp_bridge->current_memory_agp); | 274 | atomic_inc(&agp_bridge->current_memory_agp); |
| 275 | return page_address(page); | 275 | return page; |
| 276 | } | 276 | } |
| 277 | 277 | ||
| 278 | static void i8xx_destroy_pages(void *addr) | 278 | static void i8xx_destroy_pages(struct page *page) |
| 279 | { | 279 | { |
| 280 | struct page *page; | 280 | if (page == NULL) |
| 281 | |||
| 282 | if (addr == NULL) | ||
| 283 | return; | 281 | return; |
| 284 | 282 | ||
| 285 | page = virt_to_page(addr); | ||
| 286 | set_pages_wb(page, 4); | 283 | set_pages_wb(page, 4); |
| 287 | put_page(page); | 284 | put_page(page); |
| 288 | __free_pages(page, 2); | 285 | __free_pages(page, 2); |
| @@ -346,7 +343,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
| 346 | global_cache_flush(); | 343 | global_cache_flush(); |
| 347 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 344 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 348 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 345 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
| 349 | mem->memory[i], | 346 | mem->pages[i], |
| 350 | mask_type), | 347 | mask_type), |
| 351 | intel_private.registers+I810_PTE_BASE+(j*4)); | 348 | intel_private.registers+I810_PTE_BASE+(j*4)); |
| 352 | } | 349 | } |
| @@ -389,37 +386,37 @@ static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start, | |||
| 389 | static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) | 386 | static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) |
| 390 | { | 387 | { |
| 391 | struct agp_memory *new; | 388 | struct agp_memory *new; |
| 392 | void *addr; | 389 | struct page *page; |
| 393 | 390 | ||
| 394 | switch (pg_count) { | 391 | switch (pg_count) { |
| 395 | case 1: addr = agp_bridge->driver->agp_alloc_page(agp_bridge); | 392 | case 1: page = agp_bridge->driver->agp_alloc_page(agp_bridge); |
| 396 | break; | 393 | break; |
| 397 | case 4: | 394 | case 4: |
| 398 | /* kludge to get 4 physical pages for ARGB cursor */ | 395 | /* kludge to get 4 physical pages for ARGB cursor */ |
| 399 | addr = i8xx_alloc_pages(); | 396 | page = i8xx_alloc_pages(); |
| 400 | break; | 397 | break; |
| 401 | default: | 398 | default: |
| 402 | return NULL; | 399 | return NULL; |
| 403 | } | 400 | } |
| 404 | 401 | ||
| 405 | if (addr == NULL) | 402 | if (page == NULL) |
| 406 | return NULL; | 403 | return NULL; |
| 407 | 404 | ||
| 408 | new = agp_create_memory(pg_count); | 405 | new = agp_create_memory(pg_count); |
| 409 | if (new == NULL) | 406 | if (new == NULL) |
| 410 | return NULL; | 407 | return NULL; |
| 411 | 408 | ||
| 412 | new->memory[0] = virt_to_gart(addr); | 409 | new->pages[0] = page; |
| 413 | if (pg_count == 4) { | 410 | if (pg_count == 4) { |
| 414 | /* kludge to get 4 physical pages for ARGB cursor */ | 411 | /* kludge to get 4 physical pages for ARGB cursor */ |
| 415 | new->memory[1] = new->memory[0] + PAGE_SIZE; | 412 | new->pages[1] = new->pages[0] + 1; |
| 416 | new->memory[2] = new->memory[1] + PAGE_SIZE; | 413 | new->pages[2] = new->pages[1] + 1; |
| 417 | new->memory[3] = new->memory[2] + PAGE_SIZE; | 414 | new->pages[3] = new->pages[2] + 1; |
| 418 | } | 415 | } |
| 419 | new->page_count = pg_count; | 416 | new->page_count = pg_count; |
| 420 | new->num_scratch_pages = pg_count; | 417 | new->num_scratch_pages = pg_count; |
| 421 | new->type = AGP_PHYS_MEMORY; | 418 | new->type = AGP_PHYS_MEMORY; |
| 422 | new->physical = new->memory[0]; | 419 | new->physical = page_to_phys(new->pages[0]); |
| 423 | return new; | 420 | return new; |
| 424 | } | 421 | } |
| 425 | 422 | ||
| @@ -451,13 +448,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr) | |||
| 451 | agp_free_key(curr->key); | 448 | agp_free_key(curr->key); |
| 452 | if (curr->type == AGP_PHYS_MEMORY) { | 449 | if (curr->type == AGP_PHYS_MEMORY) { |
| 453 | if (curr->page_count == 4) | 450 | if (curr->page_count == 4) |
| 454 | i8xx_destroy_pages(gart_to_virt(curr->memory[0])); | 451 | i8xx_destroy_pages(curr->pages[0]); |
| 455 | else { | 452 | else { |
| 456 | void *va = gart_to_virt(curr->memory[0]); | 453 | agp_bridge->driver->agp_destroy_page(curr->pages[0], |
| 457 | |||
| 458 | agp_bridge->driver->agp_destroy_page(va, | ||
| 459 | AGP_PAGE_DESTROY_UNMAP); | 454 | AGP_PAGE_DESTROY_UNMAP); |
| 460 | agp_bridge->driver->agp_destroy_page(va, | 455 | agp_bridge->driver->agp_destroy_page(curr->pages[0], |
| 461 | AGP_PAGE_DESTROY_FREE); | 456 | AGP_PAGE_DESTROY_FREE); |
| 462 | } | 457 | } |
| 463 | agp_free_page_array(curr); | 458 | agp_free_page_array(curr); |
| @@ -466,8 +461,9 @@ static void intel_i810_free_by_type(struct agp_memory *curr) | |||
| 466 | } | 461 | } |
| 467 | 462 | ||
| 468 | static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, | 463 | static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, |
| 469 | unsigned long addr, int type) | 464 | struct page *page, int type) |
| 470 | { | 465 | { |
| 466 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
| 471 | /* Type checking must be done elsewhere */ | 467 | /* Type checking must be done elsewhere */ |
| 472 | return addr | bridge->driver->masks[type].mask; | 468 | return addr | bridge->driver->masks[type].mask; |
| 473 | } | 469 | } |
| @@ -855,7 +851,7 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
| 855 | 851 | ||
| 856 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 852 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 857 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 853 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
| 858 | mem->memory[i], mask_type), | 854 | mem->pages[i], mask_type), |
| 859 | intel_private.registers+I810_PTE_BASE+(j*4)); | 855 | intel_private.registers+I810_PTE_BASE+(j*4)); |
| 860 | } | 856 | } |
| 861 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); | 857 | readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); |
| @@ -1085,7 +1081,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
| 1085 | 1081 | ||
| 1086 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1082 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 1087 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 1083 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
| 1088 | mem->memory[i], mask_type), intel_private.gtt+j); | 1084 | mem->pages[i], mask_type), intel_private.gtt+j); |
| 1089 | } | 1085 | } |
| 1090 | 1086 | ||
| 1091 | readl(intel_private.gtt+j-1); | 1087 | readl(intel_private.gtt+j-1); |
| @@ -1200,8 +1196,9 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) | |||
| 1200 | * this conditional. | 1196 | * this conditional. |
| 1201 | */ | 1197 | */ |
| 1202 | static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, | 1198 | static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge, |
| 1203 | unsigned long addr, int type) | 1199 | struct page *page, int type) |
| 1204 | { | 1200 | { |
| 1201 | dma_addr_t addr = phys_to_gart(page_to_phys(page)); | ||
| 1205 | /* Shift high bits down */ | 1202 | /* Shift high bits down */ |
| 1206 | addr |= (addr >> 28) & 0xf0; | 1203 | addr |= (addr >> 28) & 0xf0; |
| 1207 | 1204 | ||
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 16acee2de117..263d71dd441c 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c | |||
| @@ -225,7 +225,7 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type | |||
| 225 | } | 225 | } |
| 226 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 226 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 227 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 227 | writel(agp_bridge->driver->mask_memory(agp_bridge, |
| 228 | mem->memory[i], mask_type), | 228 | mem->pages[i], mask_type), |
| 229 | agp_bridge->gatt_table+nvidia_private.pg_offset+j); | 229 | agp_bridge->gatt_table+nvidia_private.pg_offset+j); |
| 230 | } | 230 | } |
| 231 | 231 | ||
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index 699e3422ad93..f4bb43fb8016 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c | |||
| @@ -31,6 +31,10 @@ | |||
| 31 | #define AGP8X_MODE_BIT 3 | 31 | #define AGP8X_MODE_BIT 3 |
| 32 | #define AGP8X_MODE (1 << AGP8X_MODE_BIT) | 32 | #define AGP8X_MODE (1 << AGP8X_MODE_BIT) |
| 33 | 33 | ||
| 34 | static unsigned long | ||
| 35 | parisc_agp_mask_memory(struct agp_bridge_data *bridge, unsigned long addr, | ||
| 36 | int type); | ||
| 37 | |||
| 34 | static struct _parisc_agp_info { | 38 | static struct _parisc_agp_info { |
| 35 | void __iomem *ioc_regs; | 39 | void __iomem *ioc_regs; |
| 36 | void __iomem *lba_regs; | 40 | void __iomem *lba_regs; |
| @@ -149,12 +153,12 @@ parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
| 149 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { | 153 | for (i = 0, j = io_pg_start; i < mem->page_count; i++) { |
| 150 | unsigned long paddr; | 154 | unsigned long paddr; |
| 151 | 155 | ||
| 152 | paddr = mem->memory[i]; | 156 | paddr = page_to_phys(mem->pages[i]); |
| 153 | for (k = 0; | 157 | for (k = 0; |
| 154 | k < info->io_pages_per_kpage; | 158 | k < info->io_pages_per_kpage; |
| 155 | k++, j++, paddr += info->io_page_size) { | 159 | k++, j++, paddr += info->io_page_size) { |
| 156 | info->gatt[j] = | 160 | info->gatt[j] = |
| 157 | agp_bridge->driver->mask_memory(agp_bridge, | 161 | parisc_agp_mask_memory(agp_bridge, |
| 158 | paddr, type); | 162 | paddr, type); |
| 159 | } | 163 | } |
| 160 | } | 164 | } |
| @@ -185,9 +189,17 @@ parisc_agp_remove_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
| 185 | } | 189 | } |
| 186 | 190 | ||
| 187 | static unsigned long | 191 | static unsigned long |
| 188 | parisc_agp_mask_memory(struct agp_bridge_data *bridge, | 192 | parisc_agp_mask_memory(struct agp_bridge_data *bridge, unsigned long addr, |
| 189 | unsigned long addr, int type) | 193 | int type) |
| 194 | { | ||
| 195 | return SBA_PDIR_VALID_BIT | addr; | ||
| 196 | } | ||
| 197 | |||
| 198 | static unsigned long | ||
| 199 | parisc_agp_page_mask_memory(struct agp_bridge_data *bridge, struct page *page, | ||
| 200 | int type) | ||
| 190 | { | 201 | { |
| 202 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
| 191 | return SBA_PDIR_VALID_BIT | addr; | 203 | return SBA_PDIR_VALID_BIT | addr; |
| 192 | } | 204 | } |
| 193 | 205 | ||
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index b972d83bb1b2..d3ea2e4226b5 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c | |||
| @@ -38,7 +38,7 @@ static struct aper_size_info_fixed sgi_tioca_sizes[] = { | |||
| 38 | {0, 0, 0}, | 38 | {0, 0, 0}, |
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | static void *sgi_tioca_alloc_page(struct agp_bridge_data *bridge) | 41 | static struct page *sgi_tioca_alloc_page(struct agp_bridge_data *bridge) |
| 42 | { | 42 | { |
| 43 | struct page *page; | 43 | struct page *page; |
| 44 | int nid; | 44 | int nid; |
| @@ -52,7 +52,7 @@ static void *sgi_tioca_alloc_page(struct agp_bridge_data *bridge) | |||
| 52 | 52 | ||
| 53 | get_page(page); | 53 | get_page(page); |
| 54 | atomic_inc(&agp_bridge->current_memory_agp); | 54 | atomic_inc(&agp_bridge->current_memory_agp); |
| 55 | return page_address(page); | 55 | return page; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | /* | 58 | /* |
| @@ -71,8 +71,9 @@ static void sgi_tioca_tlbflush(struct agp_memory *mem) | |||
| 71 | */ | 71 | */ |
| 72 | static unsigned long | 72 | static unsigned long |
| 73 | sgi_tioca_mask_memory(struct agp_bridge_data *bridge, | 73 | sgi_tioca_mask_memory(struct agp_bridge_data *bridge, |
| 74 | unsigned long addr, int type) | 74 | struct page *page, int type) |
| 75 | { | 75 | { |
| 76 | unsigned long addr = phys_to_gart(page_to_phys(page)); | ||
| 76 | return tioca_physpage_to_gart(addr); | 77 | return tioca_physpage_to_gart(addr); |
| 77 | } | 78 | } |
| 78 | 79 | ||
| @@ -189,7 +190,7 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start, | |||
| 189 | 190 | ||
| 190 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 191 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 191 | table[j] = | 192 | table[j] = |
| 192 | bridge->driver->mask_memory(bridge, mem->memory[i], | 193 | bridge->driver->mask_memory(bridge, mem->pages[i], |
| 193 | mem->type); | 194 | mem->type); |
| 194 | } | 195 | } |
| 195 | 196 | ||
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index 6224df8b7f0a..b964a2199329 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c | |||
| @@ -349,7 +349,7 @@ static int serverworks_insert_memory(struct agp_memory *mem, | |||
| 349 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 349 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 350 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; | 350 | addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr; |
| 351 | cur_gatt = SVRWRKS_GET_GATT(addr); | 351 | cur_gatt = SVRWRKS_GET_GATT(addr); |
| 352 | writel(agp_bridge->driver->mask_memory(agp_bridge, mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr)); | 352 | writel(agp_bridge->driver->mask_memory(agp_bridge, mem->pages[i], mem->type), cur_gatt+GET_GATT_OFF(addr)); |
| 353 | } | 353 | } |
| 354 | serverworks_tlbflush(mem); | 354 | serverworks_tlbflush(mem); |
| 355 | return 0; | 355 | return 0; |
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index 03f95ec08f59..f192c3b9ad41 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c | |||
| @@ -146,13 +146,20 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, | |||
| 146 | { | 146 | { |
| 147 | int i, j, num_entries; | 147 | int i, j, num_entries; |
| 148 | void *temp; | 148 | void *temp; |
| 149 | int mask_type; | ||
| 149 | 150 | ||
| 150 | temp = agp_bridge->current_size; | 151 | temp = agp_bridge->current_size; |
| 151 | num_entries = A_SIZE_32(temp)->num_entries; | 152 | num_entries = A_SIZE_32(temp)->num_entries; |
| 152 | 153 | ||
| 153 | if (type != 0 || mem->type != 0) | 154 | if (type != mem->type) |
| 155 | return -EINVAL; | ||
| 156 | |||
| 157 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | ||
| 158 | if (mask_type != 0) { | ||
| 154 | /* We know nothing of memory types */ | 159 | /* We know nothing of memory types */ |
| 155 | return -EINVAL; | 160 | return -EINVAL; |
| 161 | } | ||
| 162 | |||
| 156 | if ((pg_start + mem->page_count) > num_entries) | 163 | if ((pg_start + mem->page_count) > num_entries) |
| 157 | return -EINVAL; | 164 | return -EINVAL; |
| 158 | 165 | ||
| @@ -166,9 +173,9 @@ static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start, | |||
| 166 | 173 | ||
| 167 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 174 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
| 168 | agp_bridge->gatt_table[j] = | 175 | agp_bridge->gatt_table[j] = |
| 169 | cpu_to_le32((mem->memory[i] & 0xFFFFF000UL) | 0x1UL); | 176 | cpu_to_le32((page_to_phys(mem->pages[i]) & 0xFFFFF000UL) | 0x1UL); |
| 170 | flush_dcache_range((unsigned long)__va(mem->memory[i]), | 177 | flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])), |
| 171 | (unsigned long)__va(mem->memory[i])+0x1000); | 178 | (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000); |
| 172 | } | 179 | } |
| 173 | (void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]); | 180 | (void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]); |
| 174 | mb(); | 181 | mb(); |
| @@ -184,13 +191,20 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
| 184 | int i, num_entries; | 191 | int i, num_entries; |
| 185 | void *temp; | 192 | void *temp; |
| 186 | u32 *gp; | 193 | u32 *gp; |
| 194 | int mask_type; | ||
| 187 | 195 | ||
| 188 | temp = agp_bridge->current_size; | 196 | temp = agp_bridge->current_size; |
| 189 | num_entries = A_SIZE_32(temp)->num_entries; | 197 | num_entries = A_SIZE_32(temp)->num_entries; |
| 190 | 198 | ||
| 191 | if (type != 0 || mem->type != 0) | 199 | if (type != mem->type) |
| 200 | return -EINVAL; | ||
| 201 | |||
| 202 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | ||
| 203 | if (mask_type != 0) { | ||
| 192 | /* We know nothing of memory types */ | 204 | /* We know nothing of memory types */ |
| 193 | return -EINVAL; | 205 | return -EINVAL; |
| 206 | } | ||
| 207 | |||
| 194 | if ((pg_start + mem->page_count) > num_entries) | 208 | if ((pg_start + mem->page_count) > num_entries) |
| 195 | return -EINVAL; | 209 | return -EINVAL; |
| 196 | 210 | ||
| @@ -205,9 +219,9 @@ static int u3_insert_memory(struct agp_memory *mem, off_t pg_start, int type) | |||
| 205 | } | 219 | } |
| 206 | 220 | ||
| 207 | for (i = 0; i < mem->page_count; i++) { | 221 | for (i = 0; i < mem->page_count; i++) { |
| 208 | gp[i] = (mem->memory[i] >> PAGE_SHIFT) | 0x80000000UL; | 222 | gp[i] = (page_to_phys(mem->pages[i]) >> PAGE_SHIFT) | 0x80000000UL; |
| 209 | flush_dcache_range((unsigned long)__va(mem->memory[i]), | 223 | flush_dcache_range((unsigned long)__va(page_to_phys(mem->pages[i])), |
| 210 | (unsigned long)__va(mem->memory[i])+0x1000); | 224 | (unsigned long)__va(page_to_phys(mem->pages[i]))+0x1000); |
| 211 | } | 225 | } |
| 212 | mb(); | 226 | mb(); |
| 213 | flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]); | 227 | flush_dcache_range((unsigned long)gp, (unsigned long) &gp[i]); |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index de26a978fbdd..737be953cc58 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
| @@ -1123,8 +1123,6 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, | |||
| 1123 | 1123 | ||
| 1124 | #define HW_RAW(dev) 0 | 1124 | #define HW_RAW(dev) 0 |
| 1125 | 1125 | ||
| 1126 | #warning "Cannot generate rawmode keyboard for your architecture yet." | ||
| 1127 | |||
| 1128 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag) | 1126 | static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag) |
| 1129 | { | 1127 | { |
| 1130 | if (keycode > 127) | 1128 | if (keycode > 127) |
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index 14796594e5d9..d68888fe3df9 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c | |||
| @@ -203,7 +203,7 @@ int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) | |||
| 203 | 203 | ||
| 204 | if (!dev->agp || !dev->agp->acquired) | 204 | if (!dev->agp || !dev->agp->acquired) |
| 205 | return -EINVAL; | 205 | return -EINVAL; |
| 206 | if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS))) | 206 | if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL))) |
| 207 | return -ENOMEM; | 207 | return -ENOMEM; |
| 208 | 208 | ||
| 209 | memset(entry, 0, sizeof(*entry)); | 209 | memset(entry, 0, sizeof(*entry)); |
| @@ -211,7 +211,7 @@ int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request) | |||
| 211 | pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; | 211 | pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE; |
| 212 | type = (u32) request->type; | 212 | type = (u32) request->type; |
| 213 | if (!(memory = drm_alloc_agp(dev, pages, type))) { | 213 | if (!(memory = drm_alloc_agp(dev, pages, type))) { |
| 214 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 214 | kfree(entry); |
| 215 | return -ENOMEM; | 215 | return -ENOMEM; |
| 216 | } | 216 | } |
| 217 | 217 | ||
| @@ -369,7 +369,7 @@ int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request) | |||
| 369 | list_del(&entry->head); | 369 | list_del(&entry->head); |
| 370 | 370 | ||
| 371 | drm_free_agp(entry->memory, entry->pages); | 371 | drm_free_agp(entry->memory, entry->pages); |
| 372 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 372 | kfree(entry); |
| 373 | return 0; | 373 | return 0; |
| 374 | } | 374 | } |
| 375 | EXPORT_SYMBOL(drm_agp_free); | 375 | EXPORT_SYMBOL(drm_agp_free); |
| @@ -397,13 +397,13 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev) | |||
| 397 | { | 397 | { |
| 398 | struct drm_agp_head *head = NULL; | 398 | struct drm_agp_head *head = NULL; |
| 399 | 399 | ||
| 400 | if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS))) | 400 | if (!(head = kmalloc(sizeof(*head), GFP_KERNEL))) |
| 401 | return NULL; | 401 | return NULL; |
| 402 | memset((void *)head, 0, sizeof(*head)); | 402 | memset((void *)head, 0, sizeof(*head)); |
| 403 | head->bridge = agp_find_bridge(dev->pdev); | 403 | head->bridge = agp_find_bridge(dev->pdev); |
| 404 | if (!head->bridge) { | 404 | if (!head->bridge) { |
| 405 | if (!(head->bridge = agp_backend_acquire(dev->pdev))) { | 405 | if (!(head->bridge = agp_backend_acquire(dev->pdev))) { |
| 406 | drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS); | 406 | kfree(head); |
| 407 | return NULL; | 407 | return NULL; |
| 408 | } | 408 | } |
| 409 | agp_copy_info(head->bridge, &head->agp_info); | 409 | agp_copy_info(head->bridge, &head->agp_info); |
| @@ -412,7 +412,7 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev) | |||
| 412 | agp_copy_info(head->bridge, &head->agp_info); | 412 | agp_copy_info(head->bridge, &head->agp_info); |
| 413 | } | 413 | } |
| 414 | if (head->agp_info.chipset == NOT_SUPPORTED) { | 414 | if (head->agp_info.chipset == NOT_SUPPORTED) { |
| 415 | drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS); | 415 | kfree(head); |
| 416 | return NULL; | 416 | return NULL; |
| 417 | } | 417 | } |
| 418 | INIT_LIST_HEAD(&head->memory); | 418 | INIT_LIST_HEAD(&head->memory); |
| @@ -482,7 +482,7 @@ drm_agp_bind_pages(struct drm_device *dev, | |||
| 482 | } | 482 | } |
| 483 | 483 | ||
| 484 | for (i = 0; i < num_pages; i++) | 484 | for (i = 0; i < num_pages; i++) |
| 485 | mem->memory[i] = phys_to_gart(page_to_phys(pages[i])); | 485 | mem->pages[i] = pages[i]; |
| 486 | mem->page_count = num_pages; | 486 | mem->page_count = num_pages; |
| 487 | 487 | ||
| 488 | mem->is_flushed = true; | 488 | mem->is_flushed = true; |
diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c index ca7a9ef5007b..932b5aa96a67 100644 --- a/drivers/gpu/drm/drm_auth.c +++ b/drivers/gpu/drm/drm_auth.c | |||
| @@ -79,7 +79,7 @@ static int drm_add_magic(struct drm_master *master, struct drm_file *priv, | |||
| 79 | struct drm_device *dev = master->minor->dev; | 79 | struct drm_device *dev = master->minor->dev; |
| 80 | DRM_DEBUG("%d\n", magic); | 80 | DRM_DEBUG("%d\n", magic); |
| 81 | 81 | ||
| 82 | entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); | 82 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
| 83 | if (!entry) | 83 | if (!entry) |
| 84 | return -ENOMEM; | 84 | return -ENOMEM; |
| 85 | memset(entry, 0, sizeof(*entry)); | 85 | memset(entry, 0, sizeof(*entry)); |
| @@ -120,7 +120,7 @@ static int drm_remove_magic(struct drm_master *master, drm_magic_t magic) | |||
| 120 | list_del(&pt->head); | 120 | list_del(&pt->head); |
| 121 | mutex_unlock(&dev->struct_mutex); | 121 | mutex_unlock(&dev->struct_mutex); |
| 122 | 122 | ||
| 123 | drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); | 123 | kfree(pt); |
| 124 | 124 | ||
| 125 | return 0; | 125 | return 0; |
| 126 | } | 126 | } |
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c index 80a257554b30..6246e3f3dad7 100644 --- a/drivers/gpu/drm/drm_bufs.c +++ b/drivers/gpu/drm/drm_bufs.c | |||
| @@ -151,7 +151,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 151 | unsigned long user_token; | 151 | unsigned long user_token; |
| 152 | int ret; | 152 | int ret; |
| 153 | 153 | ||
| 154 | map = drm_alloc(sizeof(*map), DRM_MEM_MAPS); | 154 | map = kmalloc(sizeof(*map), GFP_KERNEL); |
| 155 | if (!map) | 155 | if (!map) |
| 156 | return -ENOMEM; | 156 | return -ENOMEM; |
| 157 | 157 | ||
| @@ -165,7 +165,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 165 | * when processes fork. | 165 | * when processes fork. |
| 166 | */ | 166 | */ |
| 167 | if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) { | 167 | if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) { |
| 168 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 168 | kfree(map); |
| 169 | return -EINVAL; | 169 | return -EINVAL; |
| 170 | } | 170 | } |
| 171 | DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", | 171 | DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n", |
| @@ -179,7 +179,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 179 | map->size = PAGE_ALIGN(map->size); | 179 | map->size = PAGE_ALIGN(map->size); |
| 180 | 180 | ||
| 181 | if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { | 181 | if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) { |
| 182 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 182 | kfree(map); |
| 183 | return -EINVAL; | 183 | return -EINVAL; |
| 184 | } | 184 | } |
| 185 | map->mtrr = -1; | 185 | map->mtrr = -1; |
| @@ -191,7 +191,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 191 | #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) | 191 | #if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) |
| 192 | if (map->offset + (map->size-1) < map->offset || | 192 | if (map->offset + (map->size-1) < map->offset || |
| 193 | map->offset < virt_to_phys(high_memory)) { | 193 | map->offset < virt_to_phys(high_memory)) { |
| 194 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 194 | kfree(map); |
| 195 | return -EINVAL; | 195 | return -EINVAL; |
| 196 | } | 196 | } |
| 197 | #endif | 197 | #endif |
| @@ -212,7 +212,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 212 | list->map->size = map->size; | 212 | list->map->size = map->size; |
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 215 | kfree(map); |
| 216 | *maplist = list; | 216 | *maplist = list; |
| 217 | return 0; | 217 | return 0; |
| 218 | } | 218 | } |
| @@ -227,7 +227,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 227 | if (map->type == _DRM_REGISTERS) { | 227 | if (map->type == _DRM_REGISTERS) { |
| 228 | map->handle = ioremap(map->offset, map->size); | 228 | map->handle = ioremap(map->offset, map->size); |
| 229 | if (!map->handle) { | 229 | if (!map->handle) { |
| 230 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 230 | kfree(map); |
| 231 | return -ENOMEM; | 231 | return -ENOMEM; |
| 232 | } | 232 | } |
| 233 | } | 233 | } |
| @@ -243,7 +243,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 243 | list->map->size = map->size; | 243 | list->map->size = map->size; |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 246 | kfree(map); |
| 247 | *maplist = list; | 247 | *maplist = list; |
| 248 | return 0; | 248 | return 0; |
| 249 | } | 249 | } |
| @@ -251,7 +251,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 251 | DRM_DEBUG("%lu %d %p\n", | 251 | DRM_DEBUG("%lu %d %p\n", |
| 252 | map->size, drm_order(map->size), map->handle); | 252 | map->size, drm_order(map->size), map->handle); |
| 253 | if (!map->handle) { | 253 | if (!map->handle) { |
| 254 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 254 | kfree(map); |
| 255 | return -ENOMEM; | 255 | return -ENOMEM; |
| 256 | } | 256 | } |
| 257 | map->offset = (unsigned long)map->handle; | 257 | map->offset = (unsigned long)map->handle; |
| @@ -259,7 +259,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 259 | /* Prevent a 2nd X Server from creating a 2nd lock */ | 259 | /* Prevent a 2nd X Server from creating a 2nd lock */ |
| 260 | if (dev->primary->master->lock.hw_lock != NULL) { | 260 | if (dev->primary->master->lock.hw_lock != NULL) { |
| 261 | vfree(map->handle); | 261 | vfree(map->handle); |
| 262 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 262 | kfree(map); |
| 263 | return -EBUSY; | 263 | return -EBUSY; |
| 264 | } | 264 | } |
| 265 | dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */ | 265 | dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */ |
| @@ -270,7 +270,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 270 | int valid = 0; | 270 | int valid = 0; |
| 271 | 271 | ||
| 272 | if (!drm_core_has_AGP(dev)) { | 272 | if (!drm_core_has_AGP(dev)) { |
| 273 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 273 | kfree(map); |
| 274 | return -EINVAL; | 274 | return -EINVAL; |
| 275 | } | 275 | } |
| 276 | #ifdef __alpha__ | 276 | #ifdef __alpha__ |
| @@ -303,7 +303,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 303 | } | 303 | } |
| 304 | } | 304 | } |
| 305 | if (!list_empty(&dev->agp->memory) && !valid) { | 305 | if (!list_empty(&dev->agp->memory) && !valid) { |
| 306 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 306 | kfree(map); |
| 307 | return -EPERM; | 307 | return -EPERM; |
| 308 | } | 308 | } |
| 309 | DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n", | 309 | DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n", |
| @@ -316,7 +316,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 316 | } | 316 | } |
| 317 | case _DRM_SCATTER_GATHER: | 317 | case _DRM_SCATTER_GATHER: |
| 318 | if (!dev->sg) { | 318 | if (!dev->sg) { |
| 319 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 319 | kfree(map); |
| 320 | return -EINVAL; | 320 | return -EINVAL; |
| 321 | } | 321 | } |
| 322 | map->offset += (unsigned long)dev->sg->virtual; | 322 | map->offset += (unsigned long)dev->sg->virtual; |
| @@ -328,7 +328,7 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 328 | * need to point to a 64bit variable first. */ | 328 | * need to point to a 64bit variable first. */ |
| 329 | dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL); | 329 | dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL); |
| 330 | if (!dmah) { | 330 | if (!dmah) { |
| 331 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 331 | kfree(map); |
| 332 | return -ENOMEM; | 332 | return -ENOMEM; |
| 333 | } | 333 | } |
| 334 | map->handle = dmah->vaddr; | 334 | map->handle = dmah->vaddr; |
| @@ -336,15 +336,15 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 336 | kfree(dmah); | 336 | kfree(dmah); |
| 337 | break; | 337 | break; |
| 338 | default: | 338 | default: |
| 339 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 339 | kfree(map); |
| 340 | return -EINVAL; | 340 | return -EINVAL; |
| 341 | } | 341 | } |
| 342 | 342 | ||
| 343 | list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); | 343 | list = kmalloc(sizeof(*list), GFP_KERNEL); |
| 344 | if (!list) { | 344 | if (!list) { |
| 345 | if (map->type == _DRM_REGISTERS) | 345 | if (map->type == _DRM_REGISTERS) |
| 346 | iounmap(map->handle); | 346 | iounmap(map->handle); |
| 347 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 347 | kfree(map); |
| 348 | return -EINVAL; | 348 | return -EINVAL; |
| 349 | } | 349 | } |
| 350 | memset(list, 0, sizeof(*list)); | 350 | memset(list, 0, sizeof(*list)); |
| @@ -362,8 +362,8 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset, | |||
| 362 | if (ret) { | 362 | if (ret) { |
| 363 | if (map->type == _DRM_REGISTERS) | 363 | if (map->type == _DRM_REGISTERS) |
| 364 | iounmap(map->handle); | 364 | iounmap(map->handle); |
| 365 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 365 | kfree(map); |
| 366 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); | 366 | kfree(list); |
| 367 | mutex_unlock(&dev->struct_mutex); | 367 | mutex_unlock(&dev->struct_mutex); |
| 368 | return ret; | 368 | return ret; |
| 369 | } | 369 | } |
| @@ -448,7 +448,7 @@ int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) | |||
| 448 | list_del(&r_list->head); | 448 | list_del(&r_list->head); |
| 449 | drm_ht_remove_key(&dev->map_hash, | 449 | drm_ht_remove_key(&dev->map_hash, |
| 450 | r_list->user_token >> PAGE_SHIFT); | 450 | r_list->user_token >> PAGE_SHIFT); |
| 451 | drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS); | 451 | kfree(r_list); |
| 452 | found = 1; | 452 | found = 1; |
| 453 | break; | 453 | break; |
| 454 | } | 454 | } |
| @@ -491,7 +491,7 @@ int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map) | |||
| 491 | DRM_ERROR("tried to rmmap GEM object\n"); | 491 | DRM_ERROR("tried to rmmap GEM object\n"); |
| 492 | break; | 492 | break; |
| 493 | } | 493 | } |
| 494 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 494 | kfree(map); |
| 495 | 495 | ||
| 496 | return 0; | 496 | return 0; |
| 497 | } | 497 | } |
| @@ -582,24 +582,16 @@ static void drm_cleanup_buf_error(struct drm_device * dev, | |||
| 582 | drm_pci_free(dev, entry->seglist[i]); | 582 | drm_pci_free(dev, entry->seglist[i]); |
| 583 | } | 583 | } |
| 584 | } | 584 | } |
| 585 | drm_free(entry->seglist, | 585 | kfree(entry->seglist); |
| 586 | entry->seg_count * | ||
| 587 | sizeof(*entry->seglist), DRM_MEM_SEGS); | ||
| 588 | 586 | ||
| 589 | entry->seg_count = 0; | 587 | entry->seg_count = 0; |
| 590 | } | 588 | } |
| 591 | 589 | ||
| 592 | if (entry->buf_count) { | 590 | if (entry->buf_count) { |
| 593 | for (i = 0; i < entry->buf_count; i++) { | 591 | for (i = 0; i < entry->buf_count; i++) { |
| 594 | if (entry->buflist[i].dev_private) { | 592 | kfree(entry->buflist[i].dev_private); |
| 595 | drm_free(entry->buflist[i].dev_private, | ||
| 596 | entry->buflist[i].dev_priv_size, | ||
| 597 | DRM_MEM_BUFS); | ||
| 598 | } | ||
| 599 | } | 593 | } |
| 600 | drm_free(entry->buflist, | 594 | kfree(entry->buflist); |
| 601 | entry->buf_count * | ||
| 602 | sizeof(*entry->buflist), DRM_MEM_BUFS); | ||
| 603 | 595 | ||
| 604 | entry->buf_count = 0; | 596 | entry->buf_count = 0; |
| 605 | } | 597 | } |
| @@ -698,8 +690,7 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 698 | return -EINVAL; | 690 | return -EINVAL; |
| 699 | } | 691 | } |
| 700 | 692 | ||
| 701 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), | 693 | entry->buflist = kmalloc(count * sizeof(*entry->buflist), GFP_KERNEL); |
| 702 | DRM_MEM_BUFS); | ||
| 703 | if (!entry->buflist) { | 694 | if (!entry->buflist) { |
| 704 | mutex_unlock(&dev->struct_mutex); | 695 | mutex_unlock(&dev->struct_mutex); |
| 705 | atomic_dec(&dev->buf_alloc); | 696 | atomic_dec(&dev->buf_alloc); |
| @@ -729,7 +720,7 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 729 | buf->file_priv = NULL; | 720 | buf->file_priv = NULL; |
| 730 | 721 | ||
| 731 | buf->dev_priv_size = dev->driver->dev_priv_size; | 722 | buf->dev_priv_size = dev->driver->dev_priv_size; |
| 732 | buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS); | 723 | buf->dev_private = kmalloc(buf->dev_priv_size, GFP_KERNEL); |
| 733 | if (!buf->dev_private) { | 724 | if (!buf->dev_private) { |
| 734 | /* Set count correctly so we free the proper amount. */ | 725 | /* Set count correctly so we free the proper amount. */ |
| 735 | entry->buf_count = count; | 726 | entry->buf_count = count; |
| @@ -749,10 +740,9 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 749 | 740 | ||
| 750 | DRM_DEBUG("byte_count: %d\n", byte_count); | 741 | DRM_DEBUG("byte_count: %d\n", byte_count); |
| 751 | 742 | ||
| 752 | temp_buflist = drm_realloc(dma->buflist, | 743 | temp_buflist = krealloc(dma->buflist, |
| 753 | dma->buf_count * sizeof(*dma->buflist), | 744 | (dma->buf_count + entry->buf_count) * |
| 754 | (dma->buf_count + entry->buf_count) | 745 | sizeof(*dma->buflist), GFP_KERNEL); |
| 755 | * sizeof(*dma->buflist), DRM_MEM_BUFS); | ||
| 756 | if (!temp_buflist) { | 746 | if (!temp_buflist) { |
| 757 | /* Free the entry because it isn't valid */ | 747 | /* Free the entry because it isn't valid */ |
| 758 | drm_cleanup_buf_error(dev, entry); | 748 | drm_cleanup_buf_error(dev, entry); |
| @@ -854,8 +844,7 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 854 | return -EINVAL; | 844 | return -EINVAL; |
| 855 | } | 845 | } |
| 856 | 846 | ||
| 857 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), | 847 | entry->buflist = kmalloc(count * sizeof(*entry->buflist), GFP_KERNEL); |
| 858 | DRM_MEM_BUFS); | ||
| 859 | if (!entry->buflist) { | 848 | if (!entry->buflist) { |
| 860 | mutex_unlock(&dev->struct_mutex); | 849 | mutex_unlock(&dev->struct_mutex); |
| 861 | atomic_dec(&dev->buf_alloc); | 850 | atomic_dec(&dev->buf_alloc); |
| @@ -863,11 +852,9 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 863 | } | 852 | } |
| 864 | memset(entry->buflist, 0, count * sizeof(*entry->buflist)); | 853 | memset(entry->buflist, 0, count * sizeof(*entry->buflist)); |
| 865 | 854 | ||
| 866 | entry->seglist = drm_alloc(count * sizeof(*entry->seglist), | 855 | entry->seglist = kmalloc(count * sizeof(*entry->seglist), GFP_KERNEL); |
| 867 | DRM_MEM_SEGS); | ||
| 868 | if (!entry->seglist) { | 856 | if (!entry->seglist) { |
| 869 | drm_free(entry->buflist, | 857 | kfree(entry->buflist); |
| 870 | count * sizeof(*entry->buflist), DRM_MEM_BUFS); | ||
| 871 | mutex_unlock(&dev->struct_mutex); | 858 | mutex_unlock(&dev->struct_mutex); |
| 872 | atomic_dec(&dev->buf_alloc); | 859 | atomic_dec(&dev->buf_alloc); |
| 873 | return -ENOMEM; | 860 | return -ENOMEM; |
| @@ -877,13 +864,11 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 877 | /* Keep the original pagelist until we know all the allocations | 864 | /* Keep the original pagelist until we know all the allocations |
| 878 | * have succeeded | 865 | * have succeeded |
| 879 | */ | 866 | */ |
| 880 | temp_pagelist = drm_alloc((dma->page_count + (count << page_order)) | 867 | temp_pagelist = kmalloc((dma->page_count + (count << page_order)) * |
| 881 | * sizeof(*dma->pagelist), DRM_MEM_PAGES); | 868 | sizeof(*dma->pagelist), GFP_KERNEL); |
| 882 | if (!temp_pagelist) { | 869 | if (!temp_pagelist) { |
| 883 | drm_free(entry->buflist, | 870 | kfree(entry->buflist); |
| 884 | count * sizeof(*entry->buflist), DRM_MEM_BUFS); | 871 | kfree(entry->seglist); |
| 885 | drm_free(entry->seglist, | ||
| 886 | count * sizeof(*entry->seglist), DRM_MEM_SEGS); | ||
| 887 | mutex_unlock(&dev->struct_mutex); | 872 | mutex_unlock(&dev->struct_mutex); |
| 888 | atomic_dec(&dev->buf_alloc); | 873 | atomic_dec(&dev->buf_alloc); |
| 889 | return -ENOMEM; | 874 | return -ENOMEM; |
| @@ -907,9 +892,7 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 907 | entry->buf_count = count; | 892 | entry->buf_count = count; |
| 908 | entry->seg_count = count; | 893 | entry->seg_count = count; |
| 909 | drm_cleanup_buf_error(dev, entry); | 894 | drm_cleanup_buf_error(dev, entry); |
| 910 | drm_free(temp_pagelist, | 895 | kfree(temp_pagelist); |
| 911 | (dma->page_count + (count << page_order)) | ||
| 912 | * sizeof(*dma->pagelist), DRM_MEM_PAGES); | ||
| 913 | mutex_unlock(&dev->struct_mutex); | 896 | mutex_unlock(&dev->struct_mutex); |
| 914 | atomic_dec(&dev->buf_alloc); | 897 | atomic_dec(&dev->buf_alloc); |
| 915 | return -ENOMEM; | 898 | return -ENOMEM; |
| @@ -940,18 +923,14 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 940 | buf->file_priv = NULL; | 923 | buf->file_priv = NULL; |
| 941 | 924 | ||
| 942 | buf->dev_priv_size = dev->driver->dev_priv_size; | 925 | buf->dev_priv_size = dev->driver->dev_priv_size; |
| 943 | buf->dev_private = drm_alloc(buf->dev_priv_size, | 926 | buf->dev_private = kmalloc(buf->dev_priv_size, |
| 944 | DRM_MEM_BUFS); | 927 | GFP_KERNEL); |
| 945 | if (!buf->dev_private) { | 928 | if (!buf->dev_private) { |
| 946 | /* Set count correctly so we free the proper amount. */ | 929 | /* Set count correctly so we free the proper amount. */ |
| 947 | entry->buf_count = count; | 930 | entry->buf_count = count; |
| 948 | entry->seg_count = count; | 931 | entry->seg_count = count; |
| 949 | drm_cleanup_buf_error(dev, entry); | 932 | drm_cleanup_buf_error(dev, entry); |
| 950 | drm_free(temp_pagelist, | 933 | kfree(temp_pagelist); |
| 951 | (dma->page_count + | ||
| 952 | (count << page_order)) | ||
| 953 | * sizeof(*dma->pagelist), | ||
| 954 | DRM_MEM_PAGES); | ||
| 955 | mutex_unlock(&dev->struct_mutex); | 934 | mutex_unlock(&dev->struct_mutex); |
| 956 | atomic_dec(&dev->buf_alloc); | 935 | atomic_dec(&dev->buf_alloc); |
| 957 | return -ENOMEM; | 936 | return -ENOMEM; |
| @@ -964,16 +943,13 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 964 | byte_count += PAGE_SIZE << page_order; | 943 | byte_count += PAGE_SIZE << page_order; |
| 965 | } | 944 | } |
| 966 | 945 | ||
| 967 | temp_buflist = drm_realloc(dma->buflist, | 946 | temp_buflist = krealloc(dma->buflist, |
| 968 | dma->buf_count * sizeof(*dma->buflist), | 947 | (dma->buf_count + entry->buf_count) * |
| 969 | (dma->buf_count + entry->buf_count) | 948 | sizeof(*dma->buflist), GFP_KERNEL); |
| 970 | * sizeof(*dma->buflist), DRM_MEM_BUFS); | ||
| 971 | if (!temp_buflist) { | 949 | if (!temp_buflist) { |
| 972 | /* Free the entry because it isn't valid */ | 950 | /* Free the entry because it isn't valid */ |
| 973 | drm_cleanup_buf_error(dev, entry); | 951 | drm_cleanup_buf_error(dev, entry); |
| 974 | drm_free(temp_pagelist, | 952 | kfree(temp_pagelist); |
| 975 | (dma->page_count + (count << page_order)) | ||
| 976 | * sizeof(*dma->pagelist), DRM_MEM_PAGES); | ||
| 977 | mutex_unlock(&dev->struct_mutex); | 953 | mutex_unlock(&dev->struct_mutex); |
| 978 | atomic_dec(&dev->buf_alloc); | 954 | atomic_dec(&dev->buf_alloc); |
| 979 | return -ENOMEM; | 955 | return -ENOMEM; |
| @@ -988,9 +964,7 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request) | |||
| 988 | * with the new one. | 964 | * with the new one. |
| 989 | */ | 965 | */ |
| 990 | if (dma->page_count) { | 966 | if (dma->page_count) { |
| 991 | drm_free(dma->pagelist, | 967 | kfree(dma->pagelist); |
| 992 | dma->page_count * sizeof(*dma->pagelist), | ||
| 993 | DRM_MEM_PAGES); | ||
| 994 | } | 968 | } |
| 995 | dma->pagelist = temp_pagelist; | 969 | dma->pagelist = temp_pagelist; |
| 996 | 970 | ||
| @@ -1086,8 +1060,8 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request | |||
| 1086 | return -EINVAL; | 1060 | return -EINVAL; |
| 1087 | } | 1061 | } |
| 1088 | 1062 | ||
| 1089 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), | 1063 | entry->buflist = kmalloc(count * sizeof(*entry->buflist), |
| 1090 | DRM_MEM_BUFS); | 1064 | GFP_KERNEL); |
| 1091 | if (!entry->buflist) { | 1065 | if (!entry->buflist) { |
| 1092 | mutex_unlock(&dev->struct_mutex); | 1066 | mutex_unlock(&dev->struct_mutex); |
| 1093 | atomic_dec(&dev->buf_alloc); | 1067 | atomic_dec(&dev->buf_alloc); |
| @@ -1118,7 +1092,7 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request | |||
| 1118 | buf->file_priv = NULL; | 1092 | buf->file_priv = NULL; |
| 1119 | 1093 | ||
| 1120 | buf->dev_priv_size = dev->driver->dev_priv_size; | 1094 | buf->dev_priv_size = dev->driver->dev_priv_size; |
| 1121 | buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS); | 1095 | buf->dev_private = kmalloc(buf->dev_priv_size, GFP_KERNEL); |
| 1122 | if (!buf->dev_private) { | 1096 | if (!buf->dev_private) { |
| 1123 | /* Set count correctly so we free the proper amount. */ | 1097 | /* Set count correctly so we free the proper amount. */ |
| 1124 | entry->buf_count = count; | 1098 | entry->buf_count = count; |
| @@ -1139,10 +1113,9 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request | |||
| 1139 | 1113 | ||
| 1140 | DRM_DEBUG("byte_count: %d\n", byte_count); | 1114 | DRM_DEBUG("byte_count: %d\n", byte_count); |
| 1141 | 1115 | ||
| 1142 | temp_buflist = drm_realloc(dma->buflist, | 1116 | temp_buflist = krealloc(dma->buflist, |
| 1143 | dma->buf_count * sizeof(*dma->buflist), | 1117 | (dma->buf_count + entry->buf_count) * |
| 1144 | (dma->buf_count + entry->buf_count) | 1118 | sizeof(*dma->buflist), GFP_KERNEL); |
| 1145 | * sizeof(*dma->buflist), DRM_MEM_BUFS); | ||
| 1146 | if (!temp_buflist) { | 1119 | if (!temp_buflist) { |
| 1147 | /* Free the entry because it isn't valid */ | 1120 | /* Free the entry because it isn't valid */ |
| 1148 | drm_cleanup_buf_error(dev, entry); | 1121 | drm_cleanup_buf_error(dev, entry); |
| @@ -1248,8 +1221,8 @@ static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request | |||
| 1248 | return -EINVAL; | 1221 | return -EINVAL; |
| 1249 | } | 1222 | } |
| 1250 | 1223 | ||
| 1251 | entry->buflist = drm_alloc(count * sizeof(*entry->buflist), | 1224 | entry->buflist = kmalloc(count * sizeof(*entry->buflist), |
| 1252 | DRM_MEM_BUFS); | 1225 | GFP_KERNEL); |
| 1253 | if (!entry->buflist) { | 1226 | if (!entry->buflist) { |
| 1254 | mutex_unlock(&dev->struct_mutex); | 1227 | mutex_unlock(&dev->struct_mutex); |
| 1255 | atomic_dec(&dev->buf_alloc); | 1228 | atomic_dec(&dev->buf_alloc); |
| @@ -1279,7 +1252,7 @@ static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request | |||
| 1279 | buf->file_priv = NULL; | 1252 | buf->file_priv = NULL; |
| 1280 | 1253 | ||
| 1281 | buf->dev_priv_size = dev->driver->dev_priv_size; | 1254 | buf->dev_priv_size = dev->driver->dev_priv_size; |
| 1282 | buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS); | 1255 | buf->dev_private = kmalloc(buf->dev_priv_size, GFP_KERNEL); |
| 1283 | if (!buf->dev_private) { | 1256 | if (!buf->dev_private) { |
| 1284 | /* Set count correctly so we free the proper amount. */ | 1257 | /* Set count correctly so we free the proper amount. */ |
| 1285 | entry->buf_count = count; | 1258 | entry->buf_count = count; |
| @@ -1299,10 +1272,9 @@ static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request | |||
| 1299 | 1272 | ||
| 1300 | DRM_DEBUG("byte_count: %d\n", byte_count); | 1273 | DRM_DEBUG("byte_count: %d\n", byte_count); |
| 1301 | 1274 | ||
| 1302 | temp_buflist = drm_realloc(dma->buflist, | 1275 | temp_buflist = krealloc(dma->buflist, |
| 1303 | dma->buf_count * sizeof(*dma->buflist), | 1276 | (dma->buf_count + entry->buf_count) * |
| 1304 | (dma->buf_count + entry->buf_count) | 1277 | sizeof(*dma->buflist), GFP_KERNEL); |
| 1305 | * sizeof(*dma->buflist), DRM_MEM_BUFS); | ||
| 1306 | if (!temp_buflist) { | 1278 | if (!temp_buflist) { |
| 1307 | /* Free the entry because it isn't valid */ | 1279 | /* Free the entry because it isn't valid */ |
| 1308 | drm_cleanup_buf_error(dev, entry); | 1280 | drm_cleanup_buf_error(dev, entry); |
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c index 7d1e53c10d4b..2607753a320b 100644 --- a/drivers/gpu/drm/drm_context.c +++ b/drivers/gpu/drm/drm_context.c | |||
| @@ -341,7 +341,7 @@ int drm_addctx(struct drm_device *dev, void *data, | |||
| 341 | } | 341 | } |
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST); | 344 | ctx_entry = kmalloc(sizeof(*ctx_entry), GFP_KERNEL); |
| 345 | if (!ctx_entry) { | 345 | if (!ctx_entry) { |
| 346 | DRM_DEBUG("out of memory\n"); | 346 | DRM_DEBUG("out of memory\n"); |
| 347 | return -ENOMEM; | 347 | return -ENOMEM; |
| @@ -456,7 +456,7 @@ int drm_rmctx(struct drm_device *dev, void *data, | |||
| 456 | list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { | 456 | list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { |
| 457 | if (pos->handle == ctx->handle) { | 457 | if (pos->handle == ctx->handle) { |
| 458 | list_del(&pos->head); | 458 | list_del(&pos->head); |
| 459 | drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST); | 459 | kfree(pos); |
| 460 | --dev->ctx_count; | 460 | --dev->ctx_count; |
| 461 | } | 461 | } |
| 462 | } | 462 | } |
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c index 6ce0e2667a85..2960b6d73456 100644 --- a/drivers/gpu/drm/drm_debugfs.c +++ b/drivers/gpu/drm/drm_debugfs.c | |||
| @@ -100,15 +100,13 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count, | |||
| 100 | (dev->driver->driver_features & features) != features) | 100 | (dev->driver->driver_features & features) != features) |
| 101 | continue; | 101 | continue; |
| 102 | 102 | ||
| 103 | tmp = drm_alloc(sizeof(struct drm_info_node), | 103 | tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); |
| 104 | _DRM_DRIVER); | ||
| 105 | ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, | 104 | ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, |
| 106 | root, tmp, &drm_debugfs_fops); | 105 | root, tmp, &drm_debugfs_fops); |
| 107 | if (!ent) { | 106 | if (!ent) { |
| 108 | DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/%s\n", | 107 | DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/%s\n", |
| 109 | name, files[i].name); | 108 | name, files[i].name); |
| 110 | drm_free(tmp, sizeof(struct drm_info_node), | 109 | kfree(tmp); |
| 111 | _DRM_DRIVER); | ||
| 112 | ret = -1; | 110 | ret = -1; |
| 113 | goto fail; | 111 | goto fail; |
| 114 | } | 112 | } |
| @@ -196,8 +194,7 @@ int drm_debugfs_remove_files(struct drm_info_list *files, int count, | |||
| 196 | if (tmp->info_ent == &files[i]) { | 194 | if (tmp->info_ent == &files[i]) { |
| 197 | debugfs_remove(tmp->dent); | 195 | debugfs_remove(tmp->dent); |
| 198 | list_del(pos); | 196 | list_del(pos); |
| 199 | drm_free(tmp, sizeof(struct drm_info_node), | 197 | kfree(tmp); |
| 200 | _DRM_DRIVER); | ||
| 201 | } | 198 | } |
| 202 | } | 199 | } |
| 203 | } | 200 | } |
diff --git a/drivers/gpu/drm/drm_dma.c b/drivers/gpu/drm/drm_dma.c index 7a8e2fba4678..13f1537413fb 100644 --- a/drivers/gpu/drm/drm_dma.c +++ b/drivers/gpu/drm/drm_dma.c | |||
| @@ -47,7 +47,7 @@ int drm_dma_setup(struct drm_device *dev) | |||
| 47 | { | 47 | { |
| 48 | int i; | 48 | int i; |
| 49 | 49 | ||
| 50 | dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER); | 50 | dev->dma = kmalloc(sizeof(*dev->dma), GFP_KERNEL); |
| 51 | if (!dev->dma) | 51 | if (!dev->dma) |
| 52 | return -ENOMEM; | 52 | return -ENOMEM; |
| 53 | 53 | ||
| @@ -88,36 +88,19 @@ void drm_dma_takedown(struct drm_device *dev) | |||
| 88 | drm_pci_free(dev, dma->bufs[i].seglist[j]); | 88 | drm_pci_free(dev, dma->bufs[i].seglist[j]); |
| 89 | } | 89 | } |
| 90 | } | 90 | } |
| 91 | drm_free(dma->bufs[i].seglist, | 91 | kfree(dma->bufs[i].seglist); |
| 92 | dma->bufs[i].seg_count | ||
| 93 | * sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS); | ||
| 94 | } | 92 | } |
| 95 | if (dma->bufs[i].buf_count) { | 93 | if (dma->bufs[i].buf_count) { |
| 96 | for (j = 0; j < dma->bufs[i].buf_count; j++) { | 94 | for (j = 0; j < dma->bufs[i].buf_count; j++) { |
| 97 | if (dma->bufs[i].buflist[j].dev_private) { | 95 | kfree(dma->bufs[i].buflist[j].dev_private); |
| 98 | drm_free(dma->bufs[i].buflist[j]. | ||
| 99 | dev_private, | ||
| 100 | dma->bufs[i].buflist[j]. | ||
| 101 | dev_priv_size, DRM_MEM_BUFS); | ||
| 102 | } | ||
| 103 | } | 96 | } |
| 104 | drm_free(dma->bufs[i].buflist, | 97 | kfree(dma->bufs[i].buflist); |
| 105 | dma->bufs[i].buf_count * | ||
| 106 | sizeof(*dma->bufs[0].buflist), DRM_MEM_BUFS); | ||
| 107 | } | 98 | } |
| 108 | } | 99 | } |
| 109 | 100 | ||
| 110 | if (dma->buflist) { | 101 | kfree(dma->buflist); |
| 111 | drm_free(dma->buflist, | 102 | kfree(dma->pagelist); |
| 112 | dma->buf_count * sizeof(*dma->buflist), DRM_MEM_BUFS); | 103 | kfree(dev->dma); |
| 113 | } | ||
| 114 | |||
| 115 | if (dma->pagelist) { | ||
| 116 | drm_free(dma->pagelist, | ||
| 117 | dma->page_count * sizeof(*dma->pagelist), | ||
| 118 | DRM_MEM_PAGES); | ||
| 119 | } | ||
| 120 | drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER); | ||
| 121 | dev->dma = NULL; | 104 | dev->dma = NULL; |
| 122 | } | 105 | } |
| 123 | 106 | ||
diff --git a/drivers/gpu/drm/drm_drawable.c b/drivers/gpu/drm/drm_drawable.c index 80be1cab62af..c53c9768cc11 100644 --- a/drivers/gpu/drm/drm_drawable.c +++ b/drivers/gpu/drm/drm_drawable.c | |||
| @@ -85,9 +85,8 @@ int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
| 85 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); | 85 | spin_unlock_irqrestore(&dev->drw_lock, irqflags); |
| 86 | return -EINVAL; | 86 | return -EINVAL; |
| 87 | } | 87 | } |
| 88 | drm_free(info->rects, info->num_rects * sizeof(struct drm_clip_rect), | 88 | kfree(info->rects); |
| 89 | DRM_MEM_BUFS); | 89 | kfree(info); |
| 90 | drm_free(info, sizeof(struct drm_drawable_info), DRM_MEM_BUFS); | ||
| 91 | 90 | ||
| 92 | idr_remove(&dev->drw_idr, draw->handle); | 91 | idr_remove(&dev->drw_idr, draw->handle); |
| 93 | 92 | ||
| @@ -106,12 +105,12 @@ int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file | |||
| 106 | 105 | ||
| 107 | info = idr_find(&dev->drw_idr, update->handle); | 106 | info = idr_find(&dev->drw_idr, update->handle); |
| 108 | if (!info) { | 107 | if (!info) { |
| 109 | info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS); | 108 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
| 110 | if (!info) | 109 | if (!info) |
| 111 | return -ENOMEM; | 110 | return -ENOMEM; |
| 112 | if (IS_ERR(idr_replace(&dev->drw_idr, info, update->handle))) { | 111 | if (IS_ERR(idr_replace(&dev->drw_idr, info, update->handle))) { |
| 113 | DRM_ERROR("No such drawable %d\n", update->handle); | 112 | DRM_ERROR("No such drawable %d\n", update->handle); |
| 114 | drm_free(info, sizeof(*info), DRM_MEM_BUFS); | 113 | kfree(info); |
| 115 | return -EINVAL; | 114 | return -EINVAL; |
| 116 | } | 115 | } |
| 117 | } | 116 | } |
| @@ -121,8 +120,9 @@ int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file | |||
| 121 | if (update->num == 0) | 120 | if (update->num == 0) |
| 122 | rects = NULL; | 121 | rects = NULL; |
| 123 | else if (update->num != info->num_rects) { | 122 | else if (update->num != info->num_rects) { |
| 124 | rects = drm_alloc(update->num * sizeof(struct drm_clip_rect), | 123 | rects = kmalloc(update->num * |
| 125 | DRM_MEM_BUFS); | 124 | sizeof(struct drm_clip_rect), |
| 125 | GFP_KERNEL); | ||
| 126 | } else | 126 | } else |
| 127 | rects = info->rects; | 127 | rects = info->rects; |
| 128 | 128 | ||
| @@ -145,8 +145,7 @@ int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file | |||
| 145 | spin_lock_irqsave(&dev->drw_lock, irqflags); | 145 | spin_lock_irqsave(&dev->drw_lock, irqflags); |
| 146 | 146 | ||
| 147 | if (rects != info->rects) { | 147 | if (rects != info->rects) { |
| 148 | drm_free(info->rects, info->num_rects * | 148 | kfree(info->rects); |
| 149 | sizeof(struct drm_clip_rect), DRM_MEM_BUFS); | ||
| 150 | } | 149 | } |
| 151 | 150 | ||
| 152 | info->rects = rects; | 151 | info->rects = rects; |
| @@ -166,8 +165,7 @@ int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file | |||
| 166 | 165 | ||
| 167 | error: | 166 | error: |
| 168 | if (rects != info->rects) | 167 | if (rects != info->rects) |
| 169 | drm_free(rects, update->num * sizeof(struct drm_clip_rect), | 168 | kfree(rects); |
| 170 | DRM_MEM_BUFS); | ||
| 171 | 169 | ||
| 172 | return err; | 170 | return err; |
| 173 | } | 171 | } |
| @@ -186,9 +184,8 @@ static int drm_drawable_free(int idr, void *p, void *data) | |||
| 186 | struct drm_drawable_info *info = p; | 184 | struct drm_drawable_info *info = p; |
| 187 | 185 | ||
| 188 | if (info) { | 186 | if (info) { |
| 189 | drm_free(info->rects, info->num_rects * | 187 | kfree(info->rects); |
| 190 | sizeof(struct drm_clip_rect), DRM_MEM_BUFS); | 188 | kfree(info); |
| 191 | drm_free(info, sizeof(*info), DRM_MEM_BUFS); | ||
| 192 | } | 189 | } |
| 193 | 190 | ||
| 194 | return 0; | 191 | return 0; |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 1bf7efd8d334..b39d7bfc0c9c 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
| @@ -189,7 +189,7 @@ int drm_lastclose(struct drm_device * dev) | |||
| 189 | if (entry->bound) | 189 | if (entry->bound) |
| 190 | drm_unbind_agp(entry->memory); | 190 | drm_unbind_agp(entry->memory); |
| 191 | drm_free_agp(entry->memory, entry->pages); | 191 | drm_free_agp(entry->memory, entry->pages); |
| 192 | drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); | 192 | kfree(entry); |
| 193 | } | 193 | } |
| 194 | INIT_LIST_HEAD(&dev->agp->memory); | 194 | INIT_LIST_HEAD(&dev->agp->memory); |
| 195 | 195 | ||
| @@ -208,21 +208,15 @@ int drm_lastclose(struct drm_device * dev) | |||
| 208 | /* Clear vma list (only built for debugging) */ | 208 | /* Clear vma list (only built for debugging) */ |
| 209 | list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) { | 209 | list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) { |
| 210 | list_del(&vma->head); | 210 | list_del(&vma->head); |
| 211 | drm_free(vma, sizeof(*vma), DRM_MEM_VMAS); | 211 | kfree(vma); |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { | 214 | if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { |
| 215 | for (i = 0; i < dev->queue_count; i++) { | 215 | for (i = 0; i < dev->queue_count; i++) { |
| 216 | if (dev->queuelist[i]) { | 216 | kfree(dev->queuelist[i]); |
| 217 | drm_free(dev->queuelist[i], | 217 | dev->queuelist[i] = NULL; |
| 218 | sizeof(*dev->queuelist[0]), | ||
| 219 | DRM_MEM_QUEUES); | ||
| 220 | dev->queuelist[i] = NULL; | ||
| 221 | } | ||
| 222 | } | 218 | } |
| 223 | drm_free(dev->queuelist, | 219 | kfree(dev->queuelist); |
| 224 | dev->queue_slots * sizeof(*dev->queuelist), | ||
| 225 | DRM_MEM_QUEUES); | ||
| 226 | dev->queuelist = NULL; | 220 | dev->queuelist = NULL; |
| 227 | } | 221 | } |
| 228 | dev->queue_count = 0; | 222 | dev->queue_count = 0; |
| @@ -344,8 +338,6 @@ static int __init drm_core_init(void) | |||
| 344 | goto err_p3; | 338 | goto err_p3; |
| 345 | } | 339 | } |
| 346 | 340 | ||
| 347 | drm_mem_init(); | ||
| 348 | |||
| 349 | DRM_INFO("Initialized %s %d.%d.%d %s\n", | 341 | DRM_INFO("Initialized %s %d.%d.%d %s\n", |
| 350 | CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); | 342 | CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE); |
| 351 | return 0; | 343 | return 0; |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 801a0d0e0810..7d0835226f6e 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
| @@ -252,16 +252,18 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev, | |||
| 252 | { | 252 | { |
| 253 | struct drm_display_mode *mode; | 253 | struct drm_display_mode *mode; |
| 254 | int hsize = t->hsize * 8 + 248, vsize; | 254 | int hsize = t->hsize * 8 + 248, vsize; |
| 255 | unsigned aspect_ratio = (t->vfreq_aspect & EDID_TIMING_ASPECT_MASK) | ||
| 256 | >> EDID_TIMING_ASPECT_SHIFT; | ||
| 255 | 257 | ||
| 256 | mode = drm_mode_create(dev); | 258 | mode = drm_mode_create(dev); |
| 257 | if (!mode) | 259 | if (!mode) |
| 258 | return NULL; | 260 | return NULL; |
| 259 | 261 | ||
| 260 | if (t->aspect_ratio == 0) | 262 | if (aspect_ratio == 0) |
| 261 | vsize = (hsize * 10) / 16; | 263 | vsize = (hsize * 10) / 16; |
| 262 | else if (t->aspect_ratio == 1) | 264 | else if (aspect_ratio == 1) |
| 263 | vsize = (hsize * 3) / 4; | 265 | vsize = (hsize * 3) / 4; |
| 264 | else if (t->aspect_ratio == 2) | 266 | else if (aspect_ratio == 2) |
| 265 | vsize = (hsize * 4) / 5; | 267 | vsize = (hsize * 4) / 5; |
| 266 | else | 268 | else |
| 267 | vsize = (hsize * 9) / 16; | 269 | vsize = (hsize * 9) / 16; |
| @@ -288,17 +290,24 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
| 288 | { | 290 | { |
| 289 | struct drm_display_mode *mode; | 291 | struct drm_display_mode *mode; |
| 290 | struct detailed_pixel_timing *pt = &timing->data.pixel_data; | 292 | struct detailed_pixel_timing *pt = &timing->data.pixel_data; |
| 293 | unsigned hactive = (pt->hactive_hblank_hi & 0xf0) << 4 | pt->hactive_lo; | ||
| 294 | unsigned vactive = (pt->vactive_vblank_hi & 0xf0) << 4 | pt->vactive_lo; | ||
| 295 | unsigned hblank = (pt->hactive_hblank_hi & 0xf) << 8 | pt->hblank_lo; | ||
| 296 | unsigned vblank = (pt->vactive_vblank_hi & 0xf) << 8 | pt->vblank_lo; | ||
| 297 | unsigned hsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x3) << 8 | pt->hsync_offset_lo; | ||
| 298 | unsigned hsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc) << 6 | pt->hsync_pulse_width_lo; | ||
| 299 | unsigned vsync_offset = (pt->hsync_vsync_offset_pulse_width_hi & 0x30) | (pt->vsync_offset_pulse_width_lo & 0xf); | ||
| 300 | unsigned vsync_pulse_width = (pt->hsync_vsync_offset_pulse_width_hi & 0xc0) >> 2 | pt->vsync_offset_pulse_width_lo >> 4; | ||
| 291 | 301 | ||
| 292 | /* ignore tiny modes */ | 302 | /* ignore tiny modes */ |
| 293 | if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 || | 303 | if (hactive < 64 || vactive < 64) |
| 294 | ((pt->vactive_hi << 8) | pt->hactive_lo) < 64) | ||
| 295 | return NULL; | 304 | return NULL; |
| 296 | 305 | ||
| 297 | if (pt->stereo) { | 306 | if (pt->misc & DRM_EDID_PT_STEREO) { |
| 298 | printk(KERN_WARNING "stereo mode not supported\n"); | 307 | printk(KERN_WARNING "stereo mode not supported\n"); |
| 299 | return NULL; | 308 | return NULL; |
| 300 | } | 309 | } |
| 301 | if (!pt->separate_sync) { | 310 | if (!(pt->misc & DRM_EDID_PT_SEPARATE_SYNC)) { |
| 302 | printk(KERN_WARNING "integrated sync not supported\n"); | 311 | printk(KERN_WARNING "integrated sync not supported\n"); |
| 303 | return NULL; | 312 | return NULL; |
| 304 | } | 313 | } |
| @@ -310,41 +319,36 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
| 310 | mode->type = DRM_MODE_TYPE_DRIVER; | 319 | mode->type = DRM_MODE_TYPE_DRIVER; |
| 311 | 320 | ||
| 312 | if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) | 321 | if (quirks & EDID_QUIRK_135_CLOCK_TOO_HIGH) |
| 313 | timing->pixel_clock = 1088; | 322 | timing->pixel_clock = cpu_to_le16(1088); |
| 314 | 323 | ||
| 315 | mode->clock = timing->pixel_clock * 10; | 324 | mode->clock = le16_to_cpu(timing->pixel_clock) * 10; |
| 316 | 325 | ||
| 317 | mode->hdisplay = (pt->hactive_hi << 8) | pt->hactive_lo; | 326 | mode->hdisplay = hactive; |
| 318 | mode->hsync_start = mode->hdisplay + ((pt->hsync_offset_hi << 8) | | 327 | mode->hsync_start = mode->hdisplay + hsync_offset; |
| 319 | pt->hsync_offset_lo); | 328 | mode->hsync_end = mode->hsync_start + hsync_pulse_width; |
| 320 | mode->hsync_end = mode->hsync_start + | 329 | mode->htotal = mode->hdisplay + hblank; |
| 321 | ((pt->hsync_pulse_width_hi << 8) | | 330 | |
| 322 | pt->hsync_pulse_width_lo); | 331 | mode->vdisplay = vactive; |
| 323 | mode->htotal = mode->hdisplay + ((pt->hblank_hi << 8) | pt->hblank_lo); | 332 | mode->vsync_start = mode->vdisplay + vsync_offset; |
| 324 | 333 | mode->vsync_end = mode->vsync_start + vsync_pulse_width; | |
| 325 | mode->vdisplay = (pt->vactive_hi << 8) | pt->vactive_lo; | 334 | mode->vtotal = mode->vdisplay + vblank; |
| 326 | mode->vsync_start = mode->vdisplay + ((pt->vsync_offset_hi << 4) | | ||
| 327 | pt->vsync_offset_lo); | ||
| 328 | mode->vsync_end = mode->vsync_start + | ||
| 329 | ((pt->vsync_pulse_width_hi << 4) | | ||
| 330 | pt->vsync_pulse_width_lo); | ||
| 331 | mode->vtotal = mode->vdisplay + ((pt->vblank_hi << 8) | pt->vblank_lo); | ||
| 332 | 335 | ||
| 333 | drm_mode_set_name(mode); | 336 | drm_mode_set_name(mode); |
| 334 | 337 | ||
| 335 | if (pt->interlaced) | 338 | if (pt->misc & DRM_EDID_PT_INTERLACED) |
| 336 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | 339 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
| 337 | 340 | ||
| 338 | if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { | 341 | if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { |
| 339 | pt->hsync_positive = 1; | 342 | pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; |
| 340 | pt->vsync_positive = 1; | ||
| 341 | } | 343 | } |
| 342 | 344 | ||
| 343 | mode->flags |= pt->hsync_positive ? DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; | 345 | mode->flags |= (pt->misc & DRM_EDID_PT_HSYNC_POSITIVE) ? |
| 344 | mode->flags |= pt->vsync_positive ? DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; | 346 | DRM_MODE_FLAG_PHSYNC : DRM_MODE_FLAG_NHSYNC; |
| 347 | mode->flags |= (pt->misc & DRM_EDID_PT_VSYNC_POSITIVE) ? | ||
| 348 | DRM_MODE_FLAG_PVSYNC : DRM_MODE_FLAG_NVSYNC; | ||
| 345 | 349 | ||
| 346 | mode->width_mm = pt->width_mm_lo | (pt->width_mm_hi << 8); | 350 | mode->width_mm = pt->width_mm_lo | (pt->width_height_mm_hi & 0xf) << 8; |
| 347 | mode->height_mm = pt->height_mm_lo | (pt->height_mm_hi << 8); | 351 | mode->height_mm = pt->height_mm_lo | (pt->width_height_mm_hi & 0xf0) << 4; |
| 348 | 352 | ||
| 349 | if (quirks & EDID_QUIRK_DETAILED_IN_CM) { | 353 | if (quirks & EDID_QUIRK_DETAILED_IN_CM) { |
| 350 | mode->width_mm *= 10; | 354 | mode->width_mm *= 10; |
| @@ -465,7 +469,7 @@ static int add_standard_modes(struct drm_connector *connector, struct edid *edid | |||
| 465 | struct drm_display_mode *newmode; | 469 | struct drm_display_mode *newmode; |
| 466 | 470 | ||
| 467 | /* If std timings bytes are 1, 1 it's empty */ | 471 | /* If std timings bytes are 1, 1 it's empty */ |
| 468 | if (t->hsize == 1 && (t->aspect_ratio | t->vfreq) == 1) | 472 | if (t->hsize == 1 && t->vfreq_aspect == 1) |
| 469 | continue; | 473 | continue; |
| 470 | 474 | ||
| 471 | newmode = drm_mode_std(dev, &edid->standard_timings[i]); | 475 | newmode = drm_mode_std(dev, &edid->standard_timings[i]); |
| @@ -509,7 +513,7 @@ static int add_detailed_info(struct drm_connector *connector, | |||
| 509 | continue; | 513 | continue; |
| 510 | 514 | ||
| 511 | /* First detailed mode is preferred */ | 515 | /* First detailed mode is preferred */ |
| 512 | if (i == 0 && edid->preferred_timing) | 516 | if (i == 0 && (edid->features & DRM_EDID_FEATURE_PREFERRED_TIMING)) |
| 513 | newmode->type |= DRM_MODE_TYPE_PREFERRED; | 517 | newmode->type |= DRM_MODE_TYPE_PREFERRED; |
| 514 | drm_mode_probed_add(connector, newmode); | 518 | drm_mode_probed_add(connector, newmode); |
| 515 | 519 | ||
| @@ -767,22 +771,22 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid) | |||
| 767 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) | 771 | if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75)) |
| 768 | edid_fixup_preferred(connector, quirks); | 772 | edid_fixup_preferred(connector, quirks); |
| 769 | 773 | ||
| 770 | connector->display_info.serration_vsync = edid->serration_vsync; | 774 | connector->display_info.serration_vsync = (edid->input & DRM_EDID_INPUT_SERRATION_VSYNC) ? 1 : 0; |
| 771 | connector->display_info.sync_on_green = edid->sync_on_green; | 775 | connector->display_info.sync_on_green = (edid->input & DRM_EDID_INPUT_SYNC_ON_GREEN) ? 1 : 0; |
| 772 | connector->display_info.composite_sync = edid->composite_sync; | 776 | connector->display_info.composite_sync = (edid->input & DRM_EDID_INPUT_COMPOSITE_SYNC) ? 1 : 0; |
| 773 | connector->display_info.separate_syncs = edid->separate_syncs; | 777 | connector->display_info.separate_syncs = (edid->input & DRM_EDID_INPUT_SEPARATE_SYNCS) ? 1 : 0; |
| 774 | connector->display_info.blank_to_black = edid->blank_to_black; | 778 | connector->display_info.blank_to_black = (edid->input & DRM_EDID_INPUT_BLANK_TO_BLACK) ? 1 : 0; |
| 775 | connector->display_info.video_level = edid->video_level; | 779 | connector->display_info.video_level = (edid->input & DRM_EDID_INPUT_VIDEO_LEVEL) >> 5; |
| 776 | connector->display_info.digital = edid->digital; | 780 | connector->display_info.digital = (edid->input & DRM_EDID_INPUT_DIGITAL) ? 1 : 0; |
| 777 | connector->display_info.width_mm = edid->width_cm * 10; | 781 | connector->display_info.width_mm = edid->width_cm * 10; |
| 778 | connector->display_info.height_mm = edid->height_cm * 10; | 782 | connector->display_info.height_mm = edid->height_cm * 10; |
| 779 | connector->display_info.gamma = edid->gamma; | 783 | connector->display_info.gamma = edid->gamma; |
| 780 | connector->display_info.gtf_supported = edid->default_gtf; | 784 | connector->display_info.gtf_supported = (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF) ? 1 : 0; |
| 781 | connector->display_info.standard_color = edid->standard_color; | 785 | connector->display_info.standard_color = (edid->features & DRM_EDID_FEATURE_STANDARD_COLOR) ? 1 : 0; |
| 782 | connector->display_info.display_type = edid->display_type; | 786 | connector->display_info.display_type = (edid->features & DRM_EDID_FEATURE_DISPLAY_TYPE) >> 3; |
| 783 | connector->display_info.active_off_supported = edid->pm_active_off; | 787 | connector->display_info.active_off_supported = (edid->features & DRM_EDID_FEATURE_PM_ACTIVE_OFF) ? 1 : 0; |
| 784 | connector->display_info.suspend_supported = edid->pm_suspend; | 788 | connector->display_info.suspend_supported = (edid->features & DRM_EDID_FEATURE_PM_SUSPEND) ? 1 : 0; |
| 785 | connector->display_info.standby_supported = edid->pm_standby; | 789 | connector->display_info.standby_supported = (edid->features & DRM_EDID_FEATURE_PM_STANDBY) ? 1 : 0; |
| 786 | connector->display_info.gamma = edid->gamma; | 790 | connector->display_info.gamma = edid->gamma; |
| 787 | 791 | ||
| 788 | return num_modes; | 792 | return num_modes; |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 09a3571c9908..251bc0e3b5ec 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c | |||
| @@ -240,7 +240,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
| 240 | 240 | ||
| 241 | DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id); | 241 | DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id); |
| 242 | 242 | ||
| 243 | priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES); | 243 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
| 244 | if (!priv) | 244 | if (!priv) |
| 245 | return -ENOMEM; | 245 | return -ENOMEM; |
| 246 | 246 | ||
| @@ -328,7 +328,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, | |||
| 328 | 328 | ||
| 329 | return 0; | 329 | return 0; |
| 330 | out_free: | 330 | out_free: |
| 331 | drm_free(priv, sizeof(*priv), DRM_MEM_FILES); | 331 | kfree(priv); |
| 332 | filp->private_data = NULL; | 332 | filp->private_data = NULL; |
| 333 | return ret; | 333 | return ret; |
| 334 | } | 334 | } |
| @@ -471,7 +471,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 471 | drm_ctxbitmap_free(dev, pos->handle); | 471 | drm_ctxbitmap_free(dev, pos->handle); |
| 472 | 472 | ||
| 473 | list_del(&pos->head); | 473 | list_del(&pos->head); |
| 474 | drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST); | 474 | kfree(pos); |
| 475 | --dev->ctx_count; | 475 | --dev->ctx_count; |
| 476 | } | 476 | } |
| 477 | } | 477 | } |
| @@ -516,7 +516,7 @@ int drm_release(struct inode *inode, struct file *filp) | |||
| 516 | 516 | ||
| 517 | if (dev->driver->postclose) | 517 | if (dev->driver->postclose) |
| 518 | dev->driver->postclose(dev, file_priv); | 518 | dev->driver->postclose(dev, file_priv); |
| 519 | drm_free(file_priv, sizeof(*file_priv), DRM_MEM_FILES); | 519 | kfree(file_priv); |
| 520 | 520 | ||
| 521 | /* ======================================================== | 521 | /* ======================================================== |
| 522 | * End inline drm_release | 522 | * End inline drm_release |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index ec43005100d9..8104ecaea26f 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
| @@ -89,7 +89,7 @@ drm_gem_init(struct drm_device *dev) | |||
| 89 | atomic_set(&dev->gtt_count, 0); | 89 | atomic_set(&dev->gtt_count, 0); |
| 90 | atomic_set(&dev->gtt_memory, 0); | 90 | atomic_set(&dev->gtt_memory, 0); |
| 91 | 91 | ||
| 92 | mm = drm_calloc(1, sizeof(struct drm_gem_mm), DRM_MEM_MM); | 92 | mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL); |
| 93 | if (!mm) { | 93 | if (!mm) { |
| 94 | DRM_ERROR("out of memory\n"); | 94 | DRM_ERROR("out of memory\n"); |
| 95 | return -ENOMEM; | 95 | return -ENOMEM; |
| @@ -98,14 +98,14 @@ drm_gem_init(struct drm_device *dev) | |||
| 98 | dev->mm_private = mm; | 98 | dev->mm_private = mm; |
| 99 | 99 | ||
| 100 | if (drm_ht_create(&mm->offset_hash, 19)) { | 100 | if (drm_ht_create(&mm->offset_hash, 19)) { |
| 101 | drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM); | 101 | kfree(mm); |
| 102 | return -ENOMEM; | 102 | return -ENOMEM; |
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, | 105 | if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, |
| 106 | DRM_FILE_PAGE_OFFSET_SIZE)) { | 106 | DRM_FILE_PAGE_OFFSET_SIZE)) { |
| 107 | drm_ht_remove(&mm->offset_hash); | 107 | drm_ht_remove(&mm->offset_hash); |
| 108 | drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM); | 108 | kfree(mm); |
| 109 | return -ENOMEM; | 109 | return -ENOMEM; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| @@ -119,7 +119,7 @@ drm_gem_destroy(struct drm_device *dev) | |||
| 119 | 119 | ||
| 120 | drm_mm_takedown(&mm->offset_manager); | 120 | drm_mm_takedown(&mm->offset_manager); |
| 121 | drm_ht_remove(&mm->offset_hash); | 121 | drm_ht_remove(&mm->offset_hash); |
| 122 | drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM); | 122 | kfree(mm); |
| 123 | dev->mm_private = NULL; | 123 | dev->mm_private = NULL; |
| 124 | } | 124 | } |
| 125 | 125 | ||
diff --git a/drivers/gpu/drm/drm_hashtab.c b/drivers/gpu/drm/drm_hashtab.c index ac35145c3e20..f36b21c5b2e1 100644 --- a/drivers/gpu/drm/drm_hashtab.c +++ b/drivers/gpu/drm/drm_hashtab.c | |||
| @@ -46,8 +46,7 @@ int drm_ht_create(struct drm_open_hash *ht, unsigned int order) | |||
| 46 | ht->table = NULL; | 46 | ht->table = NULL; |
| 47 | ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE); | 47 | ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE); |
| 48 | if (!ht->use_vmalloc) { | 48 | if (!ht->use_vmalloc) { |
| 49 | ht->table = drm_calloc(ht->size, sizeof(*ht->table), | 49 | ht->table = kcalloc(ht->size, sizeof(*ht->table), GFP_KERNEL); |
| 50 | DRM_MEM_HASHTAB); | ||
| 51 | } | 50 | } |
| 52 | if (!ht->table) { | 51 | if (!ht->table) { |
| 53 | ht->use_vmalloc = 1; | 52 | ht->use_vmalloc = 1; |
| @@ -200,8 +199,7 @@ void drm_ht_remove(struct drm_open_hash *ht) | |||
| 200 | if (ht->use_vmalloc) | 199 | if (ht->use_vmalloc) |
| 201 | vfree(ht->table); | 200 | vfree(ht->table); |
| 202 | else | 201 | else |
| 203 | drm_free(ht->table, ht->size * sizeof(*ht->table), | 202 | kfree(ht->table); |
| 204 | DRM_MEM_HASHTAB); | ||
| 205 | ht->table = NULL; | 203 | ht->table = NULL; |
| 206 | } | 204 | } |
| 207 | } | 205 | } |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 1fad76289e66..9b9ff46c2378 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
| @@ -93,7 +93,7 @@ int drm_setunique(struct drm_device *dev, void *data, | |||
| 93 | 93 | ||
| 94 | master->unique_len = u->unique_len; | 94 | master->unique_len = u->unique_len; |
| 95 | master->unique_size = u->unique_len + 1; | 95 | master->unique_size = u->unique_len + 1; |
| 96 | master->unique = drm_alloc(master->unique_size, DRM_MEM_DRIVER); | 96 | master->unique = kmalloc(master->unique_size, GFP_KERNEL); |
| 97 | if (!master->unique) | 97 | if (!master->unique) |
| 98 | return -ENOMEM; | 98 | return -ENOMEM; |
| 99 | if (copy_from_user(master->unique, u->unique, master->unique_len)) | 99 | if (copy_from_user(master->unique, u->unique, master->unique_len)) |
| @@ -101,9 +101,8 @@ int drm_setunique(struct drm_device *dev, void *data, | |||
| 101 | 101 | ||
| 102 | master->unique[master->unique_len] = '\0'; | 102 | master->unique[master->unique_len] = '\0'; |
| 103 | 103 | ||
| 104 | dev->devname = | 104 | dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) + |
| 105 | drm_alloc(strlen(dev->driver->pci_driver.name) + | 105 | strlen(master->unique) + 2, GFP_KERNEL); |
| 106 | strlen(master->unique) + 2, DRM_MEM_DRIVER); | ||
| 107 | if (!dev->devname) | 106 | if (!dev->devname) |
| 108 | return -ENOMEM; | 107 | return -ENOMEM; |
| 109 | 108 | ||
| @@ -138,7 +137,7 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) | |||
| 138 | 137 | ||
| 139 | master->unique_len = 40; | 138 | master->unique_len = 40; |
| 140 | master->unique_size = master->unique_len; | 139 | master->unique_size = master->unique_len; |
| 141 | master->unique = drm_alloc(master->unique_size, DRM_MEM_DRIVER); | 140 | master->unique = kmalloc(master->unique_size, GFP_KERNEL); |
| 142 | if (master->unique == NULL) | 141 | if (master->unique == NULL) |
| 143 | return -ENOMEM; | 142 | return -ENOMEM; |
| 144 | 143 | ||
| @@ -152,9 +151,8 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv) | |||
| 152 | else | 151 | else |
| 153 | master->unique_len = len; | 152 | master->unique_len = len; |
| 154 | 153 | ||
| 155 | dev->devname = | 154 | dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) + |
| 156 | drm_alloc(strlen(dev->driver->pci_driver.name) + master->unique_len + | 155 | master->unique_len + 2, GFP_KERNEL); |
| 157 | 2, DRM_MEM_DRIVER); | ||
| 158 | if (dev->devname == NULL) | 156 | if (dev->devname == NULL) |
| 159 | return -ENOMEM; | 157 | return -ENOMEM; |
| 160 | 158 | ||
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index fc8e5acd9d9a..b4a3dbcebe9b 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
| @@ -104,21 +104,13 @@ void drm_vblank_cleanup(struct drm_device *dev) | |||
| 104 | 104 | ||
| 105 | vblank_disable_fn((unsigned long)dev); | 105 | vblank_disable_fn((unsigned long)dev); |
| 106 | 106 | ||
| 107 | drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs, | 107 | kfree(dev->vbl_queue); |
| 108 | DRM_MEM_DRIVER); | 108 | kfree(dev->_vblank_count); |
| 109 | drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) * | 109 | kfree(dev->vblank_refcount); |
| 110 | dev->num_crtcs, DRM_MEM_DRIVER); | 110 | kfree(dev->vblank_enabled); |
| 111 | drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) * | 111 | kfree(dev->last_vblank); |
| 112 | dev->num_crtcs, DRM_MEM_DRIVER); | 112 | kfree(dev->last_vblank_wait); |
| 113 | drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) * | 113 | kfree(dev->vblank_inmodeset); |
| 114 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
| 115 | drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs, | ||
| 116 | DRM_MEM_DRIVER); | ||
| 117 | drm_free(dev->last_vblank_wait, | ||
| 118 | sizeof(*dev->last_vblank_wait) * dev->num_crtcs, | ||
| 119 | DRM_MEM_DRIVER); | ||
| 120 | drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) * | ||
| 121 | dev->num_crtcs, DRM_MEM_DRIVER); | ||
| 122 | 114 | ||
| 123 | dev->num_crtcs = 0; | 115 | dev->num_crtcs = 0; |
| 124 | } | 116 | } |
| @@ -132,37 +124,33 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) | |||
| 132 | spin_lock_init(&dev->vbl_lock); | 124 | spin_lock_init(&dev->vbl_lock); |
| 133 | dev->num_crtcs = num_crtcs; | 125 | dev->num_crtcs = num_crtcs; |
| 134 | 126 | ||
| 135 | dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs, | 127 | dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs, |
| 136 | DRM_MEM_DRIVER); | 128 | GFP_KERNEL); |
| 137 | if (!dev->vbl_queue) | 129 | if (!dev->vbl_queue) |
| 138 | goto err; | 130 | goto err; |
| 139 | 131 | ||
| 140 | dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs, | 132 | dev->_vblank_count = kmalloc(sizeof(atomic_t) * num_crtcs, GFP_KERNEL); |
| 141 | DRM_MEM_DRIVER); | ||
| 142 | if (!dev->_vblank_count) | 133 | if (!dev->_vblank_count) |
| 143 | goto err; | 134 | goto err; |
| 144 | 135 | ||
| 145 | dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs, | 136 | dev->vblank_refcount = kmalloc(sizeof(atomic_t) * num_crtcs, |
| 146 | DRM_MEM_DRIVER); | 137 | GFP_KERNEL); |
| 147 | if (!dev->vblank_refcount) | 138 | if (!dev->vblank_refcount) |
| 148 | goto err; | 139 | goto err; |
| 149 | 140 | ||
| 150 | dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int), | 141 | dev->vblank_enabled = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL); |
| 151 | DRM_MEM_DRIVER); | ||
| 152 | if (!dev->vblank_enabled) | 142 | if (!dev->vblank_enabled) |
| 153 | goto err; | 143 | goto err; |
| 154 | 144 | ||
| 155 | dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER); | 145 | dev->last_vblank = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL); |
| 156 | if (!dev->last_vblank) | 146 | if (!dev->last_vblank) |
| 157 | goto err; | 147 | goto err; |
| 158 | 148 | ||
| 159 | dev->last_vblank_wait = drm_calloc(num_crtcs, sizeof(u32), | 149 | dev->last_vblank_wait = kcalloc(num_crtcs, sizeof(u32), GFP_KERNEL); |
| 160 | DRM_MEM_DRIVER); | ||
| 161 | if (!dev->last_vblank_wait) | 150 | if (!dev->last_vblank_wait) |
| 162 | goto err; | 151 | goto err; |
| 163 | 152 | ||
| 164 | dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int), | 153 | dev->vblank_inmodeset = kcalloc(num_crtcs, sizeof(int), GFP_KERNEL); |
| 165 | DRM_MEM_DRIVER); | ||
| 166 | if (!dev->vblank_inmodeset) | 154 | if (!dev->vblank_inmodeset) |
| 167 | goto err; | 155 | goto err; |
| 168 | 156 | ||
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c index 0c707f533eab..e4865f99989c 100644 --- a/drivers/gpu/drm/drm_memory.c +++ b/drivers/gpu/drm/drm_memory.c | |||
| @@ -36,15 +36,6 @@ | |||
| 36 | #include <linux/highmem.h> | 36 | #include <linux/highmem.h> |
| 37 | #include "drmP.h" | 37 | #include "drmP.h" |
| 38 | 38 | ||
| 39 | #ifdef DEBUG_MEMORY | ||
| 40 | #include "drm_memory_debug.h" | ||
| 41 | #else | ||
| 42 | |||
| 43 | /** No-op. */ | ||
| 44 | void drm_mem_init(void) | ||
| 45 | { | ||
| 46 | } | ||
| 47 | |||
| 48 | /** | 39 | /** |
| 49 | * Called when "/proc/dri/%dev%/mem" is read. | 40 | * Called when "/proc/dri/%dev%/mem" is read. |
| 50 | * | 41 | * |
| @@ -64,28 +55,15 @@ int drm_mem_info(char *buf, char **start, off_t offset, | |||
| 64 | return 0; | 55 | return 0; |
| 65 | } | 56 | } |
| 66 | 57 | ||
| 67 | /** Wrapper around kmalloc() and kfree() */ | ||
| 68 | void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) | ||
| 69 | { | ||
| 70 | void *pt; | ||
| 71 | |||
| 72 | if (!(pt = kmalloc(size, GFP_KERNEL))) | ||
| 73 | return NULL; | ||
| 74 | if (oldpt && oldsize) { | ||
| 75 | memcpy(pt, oldpt, oldsize); | ||
| 76 | kfree(oldpt); | ||
| 77 | } | ||
| 78 | return pt; | ||
| 79 | } | ||
| 80 | |||
| 81 | #if __OS_HAS_AGP | 58 | #if __OS_HAS_AGP |
| 82 | static void *agp_remap(unsigned long offset, unsigned long size, | 59 | static void *agp_remap(unsigned long offset, unsigned long size, |
| 83 | struct drm_device * dev) | 60 | struct drm_device * dev) |
| 84 | { | 61 | { |
| 85 | unsigned long *phys_addr_map, i, num_pages = | 62 | unsigned long i, num_pages = |
| 86 | PAGE_ALIGN(size) / PAGE_SIZE; | 63 | PAGE_ALIGN(size) / PAGE_SIZE; |
| 87 | struct drm_agp_mem *agpmem; | 64 | struct drm_agp_mem *agpmem; |
| 88 | struct page **page_map; | 65 | struct page **page_map; |
| 66 | struct page **phys_page_map; | ||
| 89 | void *addr; | 67 | void *addr; |
| 90 | 68 | ||
| 91 | size = PAGE_ALIGN(size); | 69 | size = PAGE_ALIGN(size); |
| @@ -112,10 +90,9 @@ static void *agp_remap(unsigned long offset, unsigned long size, | |||
| 112 | if (!page_map) | 90 | if (!page_map) |
| 113 | return NULL; | 91 | return NULL; |
| 114 | 92 | ||
| 115 | phys_addr_map = | 93 | phys_page_map = (agpmem->memory->pages + (offset - agpmem->bound) / PAGE_SIZE); |
| 116 | agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE; | ||
| 117 | for (i = 0; i < num_pages; ++i) | 94 | for (i = 0; i < num_pages; ++i) |
| 118 | page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT); | 95 | page_map[i] = phys_page_map[i]; |
| 119 | addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP); | 96 | addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP); |
| 120 | vfree(page_map); | 97 | vfree(page_map); |
| 121 | 98 | ||
| @@ -157,8 +134,6 @@ static inline void *agp_remap(unsigned long offset, unsigned long size, | |||
| 157 | 134 | ||
| 158 | #endif /* agp */ | 135 | #endif /* agp */ |
| 159 | 136 | ||
| 160 | #endif /* debug_memory */ | ||
| 161 | |||
| 162 | void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) | 137 | void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev) |
| 163 | { | 138 | { |
| 164 | if (drm_core_has_AGP(dev) && | 139 | if (drm_core_has_AGP(dev) && |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index a912a0ff11cc..3e47869d6dae 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
| @@ -187,9 +187,10 @@ static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent, | |||
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | 189 | ||
| 190 | 190 | struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, | |
| 191 | struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node, | 191 | unsigned long size, |
| 192 | unsigned long size, unsigned alignment) | 192 | unsigned alignment, |
| 193 | int atomic) | ||
| 193 | { | 194 | { |
| 194 | 195 | ||
| 195 | struct drm_mm_node *align_splitoff = NULL; | 196 | struct drm_mm_node *align_splitoff = NULL; |
| @@ -200,7 +201,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node, | |||
| 200 | 201 | ||
| 201 | if (tmp) { | 202 | if (tmp) { |
| 202 | align_splitoff = | 203 | align_splitoff = |
| 203 | drm_mm_split_at_start(node, alignment - tmp, 0); | 204 | drm_mm_split_at_start(node, alignment - tmp, atomic); |
| 204 | if (unlikely(align_splitoff == NULL)) | 205 | if (unlikely(align_splitoff == NULL)) |
| 205 | return NULL; | 206 | return NULL; |
| 206 | } | 207 | } |
| @@ -209,7 +210,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node, | |||
| 209 | list_del_init(&node->fl_entry); | 210 | list_del_init(&node->fl_entry); |
| 210 | node->free = 0; | 211 | node->free = 0; |
| 211 | } else { | 212 | } else { |
| 212 | node = drm_mm_split_at_start(node, size, 0); | 213 | node = drm_mm_split_at_start(node, size, atomic); |
| 213 | } | 214 | } |
| 214 | 215 | ||
| 215 | if (align_splitoff) | 216 | if (align_splitoff) |
| @@ -217,42 +218,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *node, | |||
| 217 | 218 | ||
| 218 | return node; | 219 | return node; |
| 219 | } | 220 | } |
| 220 | 221 | EXPORT_SYMBOL(drm_mm_get_block_generic); | |
| 221 | EXPORT_SYMBOL(drm_mm_get_block); | ||
| 222 | |||
| 223 | struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent, | ||
| 224 | unsigned long size, | ||
| 225 | unsigned alignment) | ||
| 226 | { | ||
| 227 | |||
| 228 | struct drm_mm_node *align_splitoff = NULL; | ||
| 229 | struct drm_mm_node *child; | ||
| 230 | unsigned tmp = 0; | ||
| 231 | |||
| 232 | if (alignment) | ||
| 233 | tmp = parent->start % alignment; | ||
| 234 | |||
| 235 | if (tmp) { | ||
| 236 | align_splitoff = | ||
| 237 | drm_mm_split_at_start(parent, alignment - tmp, 1); | ||
| 238 | if (unlikely(align_splitoff == NULL)) | ||
| 239 | return NULL; | ||
| 240 | } | ||
| 241 | |||
| 242 | if (parent->size == size) { | ||
| 243 | list_del_init(&parent->fl_entry); | ||
| 244 | parent->free = 0; | ||
| 245 | return parent; | ||
| 246 | } else { | ||
| 247 | child = drm_mm_split_at_start(parent, size, 1); | ||
| 248 | } | ||
| 249 | |||
| 250 | if (align_splitoff) | ||
| 251 | drm_mm_put_block(align_splitoff); | ||
| 252 | |||
| 253 | return child; | ||
| 254 | } | ||
| 255 | EXPORT_SYMBOL(drm_mm_get_block_atomic); | ||
| 256 | 222 | ||
| 257 | /* | 223 | /* |
| 258 | * Put a block. Merge with the previous and / or next block if they are free. | 224 | * Put a block. Merge with the previous and / or next block if they are free. |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index b55d5bc6ea61..577094fb1995 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
| @@ -55,17 +55,6 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali | |||
| 55 | unsigned long addr; | 55 | unsigned long addr; |
| 56 | size_t sz; | 56 | size_t sz; |
| 57 | #endif | 57 | #endif |
| 58 | #ifdef DRM_DEBUG_MEMORY | ||
| 59 | int area = DRM_MEM_DMA; | ||
| 60 | |||
| 61 | spin_lock(&drm_mem_lock); | ||
| 62 | if ((drm_ram_used >> PAGE_SHIFT) | ||
| 63 | > (DRM_RAM_PERCENT * drm_ram_available) / 100) { | ||
| 64 | spin_unlock(&drm_mem_lock); | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | spin_unlock(&drm_mem_lock); | ||
| 68 | #endif | ||
| 69 | 58 | ||
| 70 | /* pci_alloc_consistent only guarantees alignment to the smallest | 59 | /* pci_alloc_consistent only guarantees alignment to the smallest |
| 71 | * PAGE_SIZE order which is greater than or equal to the requested size. | 60 | * PAGE_SIZE order which is greater than or equal to the requested size. |
| @@ -86,26 +75,10 @@ drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t ali | |||
| 86 | dmah->size = size; | 75 | dmah->size = size; |
| 87 | dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP); | 76 | dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP); |
| 88 | 77 | ||
| 89 | #ifdef DRM_DEBUG_MEMORY | ||
| 90 | if (dmah->vaddr == NULL) { | ||
| 91 | spin_lock(&drm_mem_lock); | ||
| 92 | ++drm_mem_stats[area].fail_count; | ||
| 93 | spin_unlock(&drm_mem_lock); | ||
| 94 | kfree(dmah); | ||
| 95 | return NULL; | ||
| 96 | } | ||
| 97 | |||
| 98 | spin_lock(&drm_mem_lock); | ||
| 99 | ++drm_mem_stats[area].succeed_count; | ||
| 100 | drm_mem_stats[area].bytes_allocated += size; | ||
| 101 | drm_ram_used += size; | ||
| 102 | spin_unlock(&drm_mem_lock); | ||
| 103 | #else | ||
| 104 | if (dmah->vaddr == NULL) { | 78 | if (dmah->vaddr == NULL) { |
| 105 | kfree(dmah); | 79 | kfree(dmah); |
| 106 | return NULL; | 80 | return NULL; |
| 107 | } | 81 | } |
| 108 | #endif | ||
| 109 | 82 | ||
| 110 | memset(dmah->vaddr, 0, size); | 83 | memset(dmah->vaddr, 0, size); |
| 111 | 84 | ||
| @@ -132,17 +105,8 @@ void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) | |||
| 132 | unsigned long addr; | 105 | unsigned long addr; |
| 133 | size_t sz; | 106 | size_t sz; |
| 134 | #endif | 107 | #endif |
| 135 | #ifdef DRM_DEBUG_MEMORY | ||
| 136 | int area = DRM_MEM_DMA; | ||
| 137 | int alloc_count; | ||
| 138 | int free_count; | ||
| 139 | #endif | ||
| 140 | 108 | ||
| 141 | if (!dmah->vaddr) { | 109 | if (dmah->vaddr) { |
| 142 | #ifdef DRM_DEBUG_MEMORY | ||
| 143 | DRM_MEM_ERROR(area, "Attempt to free address 0\n"); | ||
| 144 | #endif | ||
| 145 | } else { | ||
| 146 | /* XXX - Is virt_to_page() legal for consistent mem? */ | 110 | /* XXX - Is virt_to_page() legal for consistent mem? */ |
| 147 | /* Unreserve */ | 111 | /* Unreserve */ |
| 148 | for (addr = (unsigned long)dmah->vaddr, sz = dmah->size; | 112 | for (addr = (unsigned long)dmah->vaddr, sz = dmah->size; |
| @@ -152,21 +116,6 @@ void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah) | |||
| 152 | dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr, | 116 | dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr, |
| 153 | dmah->busaddr); | 117 | dmah->busaddr); |
| 154 | } | 118 | } |
| 155 | |||
| 156 | #ifdef DRM_DEBUG_MEMORY | ||
| 157 | spin_lock(&drm_mem_lock); | ||
| 158 | free_count = ++drm_mem_stats[area].free_count; | ||
| 159 | alloc_count = drm_mem_stats[area].succeed_count; | ||
| 160 | drm_mem_stats[area].bytes_freed += size; | ||
| 161 | drm_ram_used -= size; | ||
| 162 | spin_unlock(&drm_mem_lock); | ||
| 163 | if (free_count > alloc_count) { | ||
| 164 | DRM_MEM_ERROR(area, | ||
| 165 | "Excess frees: %d frees, %d allocs\n", | ||
| 166 | free_count, alloc_count); | ||
| 167 | } | ||
| 168 | #endif | ||
| 169 | |||
| 170 | } | 119 | } |
| 171 | 120 | ||
| 172 | /** | 121 | /** |
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c index bae5391165ac..bbd4b3d1074a 100644 --- a/drivers/gpu/drm/drm_proc.c +++ b/drivers/gpu/drm/drm_proc.c | |||
| @@ -105,13 +105,12 @@ int drm_proc_create_files(struct drm_info_list *files, int count, | |||
| 105 | (dev->driver->driver_features & features) != features) | 105 | (dev->driver->driver_features & features) != features) |
| 106 | continue; | 106 | continue; |
| 107 | 107 | ||
| 108 | tmp = drm_alloc(sizeof(struct drm_info_node), _DRM_DRIVER); | 108 | tmp = kmalloc(sizeof(struct drm_info_node), GFP_KERNEL); |
| 109 | ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root); | 109 | ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root); |
| 110 | if (!ent) { | 110 | if (!ent) { |
| 111 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", | 111 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", |
| 112 | name, files[i].name); | 112 | name, files[i].name); |
| 113 | drm_free(tmp, sizeof(struct drm_info_node), | 113 | kfree(tmp); |
| 114 | _DRM_DRIVER); | ||
| 115 | ret = -1; | 114 | ret = -1; |
| 116 | goto fail; | 115 | goto fail; |
| 117 | } | 116 | } |
| @@ -192,8 +191,7 @@ int drm_proc_remove_files(struct drm_info_list *files, int count, | |||
| 192 | remove_proc_entry(files[i].name, | 191 | remove_proc_entry(files[i].name, |
| 193 | minor->proc_root); | 192 | minor->proc_root); |
| 194 | list_del(pos); | 193 | list_del(pos); |
| 195 | drm_free(tmp, sizeof(struct drm_info_node), | 194 | kfree(tmp); |
| 196 | _DRM_DRIVER); | ||
| 197 | } | 195 | } |
| 198 | } | 196 | } |
| 199 | } | 197 | } |
diff --git a/drivers/gpu/drm/drm_scatter.c b/drivers/gpu/drm/drm_scatter.c index b2b0f3d41714..c7823c863d4f 100644 --- a/drivers/gpu/drm/drm_scatter.c +++ b/drivers/gpu/drm/drm_scatter.c | |||
| @@ -58,11 +58,9 @@ void drm_sg_cleanup(struct drm_sg_mem * entry) | |||
| 58 | 58 | ||
| 59 | vfree(entry->virtual); | 59 | vfree(entry->virtual); |
| 60 | 60 | ||
| 61 | drm_free(entry->busaddr, | 61 | kfree(entry->busaddr); |
| 62 | entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); | 62 | kfree(entry->pagelist); |
| 63 | drm_free(entry->pagelist, | 63 | kfree(entry); |
| 64 | entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES); | ||
| 65 | drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); | ||
| 66 | } | 64 | } |
| 67 | 65 | ||
| 68 | #ifdef _LP64 | 66 | #ifdef _LP64 |
| @@ -84,7 +82,7 @@ int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request) | |||
| 84 | if (dev->sg) | 82 | if (dev->sg) |
| 85 | return -EINVAL; | 83 | return -EINVAL; |
| 86 | 84 | ||
| 87 | entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS); | 85 | entry = kmalloc(sizeof(*entry), GFP_KERNEL); |
| 88 | if (!entry) | 86 | if (!entry) |
| 89 | return -ENOMEM; | 87 | return -ENOMEM; |
| 90 | 88 | ||
| @@ -93,34 +91,27 @@ int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request) | |||
| 93 | DRM_DEBUG("size=%ld pages=%ld\n", request->size, pages); | 91 | DRM_DEBUG("size=%ld pages=%ld\n", request->size, pages); |
| 94 | 92 | ||
| 95 | entry->pages = pages; | 93 | entry->pages = pages; |
| 96 | entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist), | 94 | entry->pagelist = kmalloc(pages * sizeof(*entry->pagelist), GFP_KERNEL); |
| 97 | DRM_MEM_PAGES); | ||
| 98 | if (!entry->pagelist) { | 95 | if (!entry->pagelist) { |
| 99 | drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); | 96 | kfree(entry); |
| 100 | return -ENOMEM; | 97 | return -ENOMEM; |
| 101 | } | 98 | } |
| 102 | 99 | ||
| 103 | memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist)); | 100 | memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist)); |
| 104 | 101 | ||
| 105 | entry->busaddr = drm_alloc(pages * sizeof(*entry->busaddr), | 102 | entry->busaddr = kmalloc(pages * sizeof(*entry->busaddr), GFP_KERNEL); |
| 106 | DRM_MEM_PAGES); | ||
| 107 | if (!entry->busaddr) { | 103 | if (!entry->busaddr) { |
| 108 | drm_free(entry->pagelist, | 104 | kfree(entry->pagelist); |
| 109 | entry->pages * sizeof(*entry->pagelist), | 105 | kfree(entry); |
| 110 | DRM_MEM_PAGES); | ||
| 111 | drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); | ||
| 112 | return -ENOMEM; | 106 | return -ENOMEM; |
| 113 | } | 107 | } |
| 114 | memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr)); | 108 | memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr)); |
| 115 | 109 | ||
| 116 | entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT); | 110 | entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT); |
| 117 | if (!entry->virtual) { | 111 | if (!entry->virtual) { |
| 118 | drm_free(entry->busaddr, | 112 | kfree(entry->busaddr); |
| 119 | entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES); | 113 | kfree(entry->pagelist); |
| 120 | drm_free(entry->pagelist, | 114 | kfree(entry); |
| 121 | entry->pages * sizeof(*entry->pagelist), | ||
| 122 | DRM_MEM_PAGES); | ||
| 123 | drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS); | ||
| 124 | return -ENOMEM; | 115 | return -ENOMEM; |
| 125 | } | 116 | } |
| 126 | 117 | ||
diff --git a/drivers/gpu/drm/drm_sman.c b/drivers/gpu/drm/drm_sman.c index 926f146390ce..463aed9403db 100644 --- a/drivers/gpu/drm/drm_sman.c +++ b/drivers/gpu/drm/drm_sman.c | |||
| @@ -48,9 +48,7 @@ void drm_sman_takedown(struct drm_sman * sman) | |||
| 48 | { | 48 | { |
| 49 | drm_ht_remove(&sman->user_hash_tab); | 49 | drm_ht_remove(&sman->user_hash_tab); |
| 50 | drm_ht_remove(&sman->owner_hash_tab); | 50 | drm_ht_remove(&sman->owner_hash_tab); |
| 51 | if (sman->mm) | 51 | kfree(sman->mm); |
| 52 | drm_free(sman->mm, sman->num_managers * sizeof(*sman->mm), | ||
| 53 | DRM_MEM_MM); | ||
| 54 | } | 52 | } |
| 55 | 53 | ||
| 56 | EXPORT_SYMBOL(drm_sman_takedown); | 54 | EXPORT_SYMBOL(drm_sman_takedown); |
| @@ -61,8 +59,9 @@ drm_sman_init(struct drm_sman * sman, unsigned int num_managers, | |||
| 61 | { | 59 | { |
| 62 | int ret = 0; | 60 | int ret = 0; |
| 63 | 61 | ||
| 64 | sman->mm = (struct drm_sman_mm *) drm_calloc(num_managers, sizeof(*sman->mm), | 62 | sman->mm = (struct drm_sman_mm *) kcalloc(num_managers, |
| 65 | DRM_MEM_MM); | 63 | sizeof(*sman->mm), |
| 64 | GFP_KERNEL); | ||
| 66 | if (!sman->mm) { | 65 | if (!sman->mm) { |
| 67 | ret = -ENOMEM; | 66 | ret = -ENOMEM; |
| 68 | goto out; | 67 | goto out; |
| @@ -78,7 +77,7 @@ drm_sman_init(struct drm_sman * sman, unsigned int num_managers, | |||
| 78 | 77 | ||
| 79 | drm_ht_remove(&sman->owner_hash_tab); | 78 | drm_ht_remove(&sman->owner_hash_tab); |
| 80 | out1: | 79 | out1: |
| 81 | drm_free(sman->mm, num_managers * sizeof(*sman->mm), DRM_MEM_MM); | 80 | kfree(sman->mm); |
| 82 | out: | 81 | out: |
| 83 | return ret; | 82 | return ret; |
| 84 | } | 83 | } |
| @@ -110,7 +109,7 @@ static void drm_sman_mm_destroy(void *private) | |||
| 110 | { | 109 | { |
| 111 | struct drm_mm *mm = (struct drm_mm *) private; | 110 | struct drm_mm *mm = (struct drm_mm *) private; |
| 112 | drm_mm_takedown(mm); | 111 | drm_mm_takedown(mm); |
| 113 | drm_free(mm, sizeof(*mm), DRM_MEM_MM); | 112 | kfree(mm); |
| 114 | } | 113 | } |
| 115 | 114 | ||
| 116 | static unsigned long drm_sman_mm_offset(void *private, void *ref) | 115 | static unsigned long drm_sman_mm_offset(void *private, void *ref) |
| @@ -130,7 +129,7 @@ drm_sman_set_range(struct drm_sman * sman, unsigned int manager, | |||
| 130 | BUG_ON(manager >= sman->num_managers); | 129 | BUG_ON(manager >= sman->num_managers); |
| 131 | 130 | ||
| 132 | sman_mm = &sman->mm[manager]; | 131 | sman_mm = &sman->mm[manager]; |
| 133 | mm = drm_calloc(1, sizeof(*mm), DRM_MEM_MM); | 132 | mm = kzalloc(sizeof(*mm), GFP_KERNEL); |
| 134 | if (!mm) { | 133 | if (!mm) { |
| 135 | return -ENOMEM; | 134 | return -ENOMEM; |
| 136 | } | 135 | } |
| @@ -138,7 +137,7 @@ drm_sman_set_range(struct drm_sman * sman, unsigned int manager, | |||
| 138 | ret = drm_mm_init(mm, start, size); | 137 | ret = drm_mm_init(mm, start, size); |
| 139 | 138 | ||
| 140 | if (ret) { | 139 | if (ret) { |
| 141 | drm_free(mm, sizeof(*mm), DRM_MEM_MM); | 140 | kfree(mm); |
| 142 | return ret; | 141 | return ret; |
| 143 | } | 142 | } |
| 144 | 143 | ||
| @@ -176,7 +175,7 @@ static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman, | |||
| 176 | owner_hash); | 175 | owner_hash); |
| 177 | } | 176 | } |
| 178 | 177 | ||
| 179 | owner_item = drm_calloc(1, sizeof(*owner_item), DRM_MEM_MM); | 178 | owner_item = kzalloc(sizeof(*owner_item), GFP_KERNEL); |
| 180 | if (!owner_item) | 179 | if (!owner_item) |
| 181 | goto out; | 180 | goto out; |
| 182 | 181 | ||
| @@ -189,7 +188,7 @@ static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman, | |||
| 189 | return owner_item; | 188 | return owner_item; |
| 190 | 189 | ||
| 191 | out1: | 190 | out1: |
| 192 | drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); | 191 | kfree(owner_item); |
| 193 | out: | 192 | out: |
| 194 | return NULL; | 193 | return NULL; |
| 195 | } | 194 | } |
| @@ -212,7 +211,7 @@ struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int man | |||
| 212 | return NULL; | 211 | return NULL; |
| 213 | } | 212 | } |
| 214 | 213 | ||
| 215 | memblock = drm_calloc(1, sizeof(*memblock), DRM_MEM_MM); | 214 | memblock = kzalloc(sizeof(*memblock), GFP_KERNEL); |
| 216 | 215 | ||
| 217 | if (!memblock) | 216 | if (!memblock) |
| 218 | goto out; | 217 | goto out; |
| @@ -237,7 +236,7 @@ struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int man | |||
| 237 | out2: | 236 | out2: |
| 238 | drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash); | 237 | drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash); |
| 239 | out1: | 238 | out1: |
| 240 | drm_free(memblock, sizeof(*memblock), DRM_MEM_MM); | 239 | kfree(memblock); |
| 241 | out: | 240 | out: |
| 242 | sman_mm->free(sman_mm->private, tmp); | 241 | sman_mm->free(sman_mm->private, tmp); |
| 243 | 242 | ||
| @@ -253,7 +252,7 @@ static void drm_sman_free(struct drm_memblock_item *item) | |||
| 253 | list_del(&item->owner_list); | 252 | list_del(&item->owner_list); |
| 254 | drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash); | 253 | drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash); |
| 255 | item->mm->free(item->mm->private, item->mm_info); | 254 | item->mm->free(item->mm->private, item->mm_info); |
| 256 | drm_free(item, sizeof(*item), DRM_MEM_MM); | 255 | kfree(item); |
| 257 | } | 256 | } |
| 258 | 257 | ||
| 259 | int drm_sman_free_key(struct drm_sman *sman, unsigned int key) | 258 | int drm_sman_free_key(struct drm_sman *sman, unsigned int key) |
| @@ -277,7 +276,7 @@ static void drm_sman_remove_owner(struct drm_sman *sman, | |||
| 277 | { | 276 | { |
| 278 | list_del(&owner_item->sman_list); | 277 | list_del(&owner_item->sman_list); |
| 279 | drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash); | 278 | drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash); |
| 280 | drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM); | 279 | kfree(owner_item); |
| 281 | } | 280 | } |
| 282 | 281 | ||
| 283 | int drm_sman_owner_clean(struct drm_sman *sman, unsigned long owner) | 282 | int drm_sman_owner_clean(struct drm_sman *sman, unsigned long owner) |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 387a8de1bc7e..155a5bbce680 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
| @@ -107,7 +107,7 @@ struct drm_master *drm_master_create(struct drm_minor *minor) | |||
| 107 | { | 107 | { |
| 108 | struct drm_master *master; | 108 | struct drm_master *master; |
| 109 | 109 | ||
| 110 | master = drm_calloc(1, sizeof(*master), DRM_MEM_DRIVER); | 110 | master = kzalloc(sizeof(*master), GFP_KERNEL); |
| 111 | if (!master) | 111 | if (!master) |
| 112 | return NULL; | 112 | return NULL; |
| 113 | 113 | ||
| @@ -149,7 +149,7 @@ static void drm_master_destroy(struct kref *kref) | |||
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | if (master->unique) { | 151 | if (master->unique) { |
| 152 | drm_free(master->unique, master->unique_size, DRM_MEM_DRIVER); | 152 | kfree(master->unique); |
| 153 | master->unique = NULL; | 153 | master->unique = NULL; |
| 154 | master->unique_len = 0; | 154 | master->unique_len = 0; |
| 155 | } | 155 | } |
| @@ -157,12 +157,12 @@ static void drm_master_destroy(struct kref *kref) | |||
| 157 | list_for_each_entry_safe(pt, next, &master->magicfree, head) { | 157 | list_for_each_entry_safe(pt, next, &master->magicfree, head) { |
| 158 | list_del(&pt->head); | 158 | list_del(&pt->head); |
| 159 | drm_ht_remove_item(&master->magiclist, &pt->hash_item); | 159 | drm_ht_remove_item(&master->magiclist, &pt->hash_item); |
| 160 | drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); | 160 | kfree(pt); |
| 161 | } | 161 | } |
| 162 | 162 | ||
| 163 | drm_ht_remove(&master->magiclist); | 163 | drm_ht_remove(&master->magiclist); |
| 164 | 164 | ||
| 165 | drm_free(master, sizeof(*master), DRM_MEM_DRIVER); | 165 | kfree(master); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | void drm_master_put(struct drm_master **master) | 168 | void drm_master_put(struct drm_master **master) |
| @@ -390,7 +390,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
| 390 | 390 | ||
| 391 | DRM_DEBUG("\n"); | 391 | DRM_DEBUG("\n"); |
| 392 | 392 | ||
| 393 | dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB); | 393 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
| 394 | if (!dev) | 394 | if (!dev) |
| 395 | return -ENOMEM; | 395 | return -ENOMEM; |
| 396 | 396 | ||
| @@ -443,7 +443,7 @@ err_g3: | |||
| 443 | err_g2: | 443 | err_g2: |
| 444 | pci_disable_device(pdev); | 444 | pci_disable_device(pdev); |
| 445 | err_g1: | 445 | err_g1: |
| 446 | drm_free(dev, sizeof(*dev), DRM_MEM_STUB); | 446 | kfree(dev); |
| 447 | return ret; | 447 | return ret; |
| 448 | } | 448 | } |
| 449 | EXPORT_SYMBOL(drm_get_dev); | 449 | EXPORT_SYMBOL(drm_get_dev); |
| @@ -516,7 +516,7 @@ void drm_put_dev(struct drm_device *dev) | |||
| 516 | dev->driver->unload(dev); | 516 | dev->driver->unload(dev); |
| 517 | 517 | ||
| 518 | if (drm_core_has_AGP(dev) && dev->agp) { | 518 | if (drm_core_has_AGP(dev) && dev->agp) { |
| 519 | drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); | 519 | kfree(dev->agp); |
| 520 | dev->agp = NULL; | 520 | dev->agp = NULL; |
| 521 | } | 521 | } |
| 522 | 522 | ||
| @@ -535,10 +535,9 @@ void drm_put_dev(struct drm_device *dev) | |||
| 535 | drm_put_minor(&dev->primary); | 535 | drm_put_minor(&dev->primary); |
| 536 | 536 | ||
| 537 | if (dev->devname) { | 537 | if (dev->devname) { |
| 538 | drm_free(dev->devname, strlen(dev->devname) + 1, | 538 | kfree(dev->devname); |
| 539 | DRM_MEM_DRIVER); | ||
| 540 | dev->devname = NULL; | 539 | dev->devname = NULL; |
| 541 | } | 540 | } |
| 542 | drm_free(dev, sizeof(*dev), DRM_MEM_STUB); | 541 | kfree(dev); |
| 543 | } | 542 | } |
| 544 | EXPORT_SYMBOL(drm_put_dev); | 543 | EXPORT_SYMBOL(drm_put_dev); |
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 22f76567ac7d..7e1fbe5d4779 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c | |||
| @@ -144,14 +144,14 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 144 | * Get the page, inc the use count, and return it | 144 | * Get the page, inc the use count, and return it |
| 145 | */ | 145 | */ |
| 146 | offset = (baddr - agpmem->bound) >> PAGE_SHIFT; | 146 | offset = (baddr - agpmem->bound) >> PAGE_SHIFT; |
| 147 | page = virt_to_page(__va(agpmem->memory->memory[offset])); | 147 | page = agpmem->memory->pages[offset]; |
| 148 | get_page(page); | 148 | get_page(page); |
| 149 | vmf->page = page; | 149 | vmf->page = page; |
| 150 | 150 | ||
| 151 | DRM_DEBUG | 151 | DRM_DEBUG |
| 152 | ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n", | 152 | ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n", |
| 153 | (unsigned long long)baddr, | 153 | (unsigned long long)baddr, |
| 154 | __va(agpmem->memory->memory[offset]), | 154 | agpmem->memory->pages[offset], |
| 155 | (unsigned long long)offset, | 155 | (unsigned long long)offset, |
| 156 | page_count(page)); | 156 | page_count(page)); |
| 157 | return 0; | 157 | return 0; |
| @@ -227,7 +227,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
| 227 | found_maps++; | 227 | found_maps++; |
| 228 | if (pt->vma == vma) { | 228 | if (pt->vma == vma) { |
| 229 | list_del(&pt->head); | 229 | list_del(&pt->head); |
| 230 | drm_free(pt, sizeof(*pt), DRM_MEM_VMAS); | 230 | kfree(pt); |
| 231 | } | 231 | } |
| 232 | } | 232 | } |
| 233 | 233 | ||
| @@ -273,7 +273,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma) | |||
| 273 | DRM_ERROR("tried to rmmap GEM object\n"); | 273 | DRM_ERROR("tried to rmmap GEM object\n"); |
| 274 | break; | 274 | break; |
| 275 | } | 275 | } |
| 276 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 276 | kfree(map); |
| 277 | } | 277 | } |
| 278 | } | 278 | } |
| 279 | mutex_unlock(&dev->struct_mutex); | 279 | mutex_unlock(&dev->struct_mutex); |
| @@ -414,7 +414,7 @@ void drm_vm_open_locked(struct vm_area_struct *vma) | |||
| 414 | vma->vm_start, vma->vm_end - vma->vm_start); | 414 | vma->vm_start, vma->vm_end - vma->vm_start); |
| 415 | atomic_inc(&dev->vma_count); | 415 | atomic_inc(&dev->vma_count); |
| 416 | 416 | ||
| 417 | vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS); | 417 | vma_entry = kmalloc(sizeof(*vma_entry), GFP_KERNEL); |
| 418 | if (vma_entry) { | 418 | if (vma_entry) { |
| 419 | vma_entry->vma = vma; | 419 | vma_entry->vma = vma; |
| 420 | vma_entry->pid = current->pid; | 420 | vma_entry->pid = current->pid; |
| @@ -454,7 +454,7 @@ static void drm_vm_close(struct vm_area_struct *vma) | |||
| 454 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { | 454 | list_for_each_entry_safe(pt, temp, &dev->vmalist, head) { |
| 455 | if (pt->vma == vma) { | 455 | if (pt->vma == vma) { |
| 456 | list_del(&pt->head); | 456 | list_del(&pt->head); |
| 457 | drm_free(pt, sizeof(*pt), DRM_MEM_VMAS); | 457 | kfree(pt); |
| 458 | break; | 458 | break; |
| 459 | } | 459 | } |
| 460 | } | 460 | } |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index e5de8ea41544..7d1d88cdf2dc 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
| @@ -227,8 +227,7 @@ static int i810_dma_cleanup(struct drm_device * dev) | |||
| 227 | /* Need to rewrite hardware status page */ | 227 | /* Need to rewrite hardware status page */ |
| 228 | I810_WRITE(0x02080, 0x1ffff000); | 228 | I810_WRITE(0x02080, 0x1ffff000); |
| 229 | } | 229 | } |
| 230 | drm_free(dev->dev_private, sizeof(drm_i810_private_t), | 230 | kfree(dev->dev_private); |
| 231 | DRM_MEM_DRIVER); | ||
| 232 | dev->dev_private = NULL; | 231 | dev->dev_private = NULL; |
| 233 | 232 | ||
| 234 | for (i = 0; i < dma->buf_count; i++) { | 233 | for (i = 0; i < dma->buf_count; i++) { |
| @@ -439,8 +438,7 @@ static int i810_dma_init(struct drm_device *dev, void *data, | |||
| 439 | switch (init->func) { | 438 | switch (init->func) { |
| 440 | case I810_INIT_DMA_1_4: | 439 | case I810_INIT_DMA_1_4: |
| 441 | DRM_INFO("Using v1.4 init.\n"); | 440 | DRM_INFO("Using v1.4 init.\n"); |
| 442 | dev_priv = drm_alloc(sizeof(drm_i810_private_t), | 441 | dev_priv = kmalloc(sizeof(drm_i810_private_t), GFP_KERNEL); |
| 443 | DRM_MEM_DRIVER); | ||
| 444 | if (dev_priv == NULL) | 442 | if (dev_priv == NULL) |
| 445 | return -ENOMEM; | 443 | return -ENOMEM; |
| 446 | retcode = i810_dma_initialize(dev, dev_priv, init); | 444 | retcode = i810_dma_initialize(dev, dev_priv, init); |
diff --git a/drivers/gpu/drm/i830/i830_dma.c b/drivers/gpu/drm/i830/i830_dma.c index a86ab30b4620..877bf6cb14a4 100644 --- a/drivers/gpu/drm/i830/i830_dma.c +++ b/drivers/gpu/drm/i830/i830_dma.c | |||
| @@ -232,8 +232,7 @@ static int i830_dma_cleanup(struct drm_device * dev) | |||
| 232 | I830_WRITE(0x02080, 0x1ffff000); | 232 | I830_WRITE(0x02080, 0x1ffff000); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | drm_free(dev->dev_private, sizeof(drm_i830_private_t), | 235 | kfree(dev->dev_private); |
| 236 | DRM_MEM_DRIVER); | ||
| 237 | dev->dev_private = NULL; | 236 | dev->dev_private = NULL; |
| 238 | 237 | ||
| 239 | for (i = 0; i < dma->buf_count; i++) { | 238 | for (i = 0; i < dma->buf_count; i++) { |
| @@ -459,8 +458,7 @@ static int i830_dma_init(struct drm_device *dev, void *data, | |||
| 459 | 458 | ||
| 460 | switch (init->func) { | 459 | switch (init->func) { |
| 461 | case I830_INIT_DMA: | 460 | case I830_INIT_DMA: |
| 462 | dev_priv = drm_alloc(sizeof(drm_i830_private_t), | 461 | dev_priv = kmalloc(sizeof(drm_i830_private_t), GFP_KERNEL); |
| 463 | DRM_MEM_DRIVER); | ||
| 464 | if (dev_priv == NULL) | 462 | if (dev_priv == NULL) |
| 465 | return -ENOMEM; | 463 | return -ENOMEM; |
| 466 | retcode = i830_dma_initialize(dev, dev_priv, init); | 464 | retcode = i830_dma_initialize(dev, dev_priv, init); |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1a60626f6803..f112c769d533 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
| @@ -643,9 +643,9 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
| 643 | return -EINVAL; | 643 | return -EINVAL; |
| 644 | 644 | ||
| 645 | if (batch->num_cliprects) { | 645 | if (batch->num_cliprects) { |
| 646 | cliprects = drm_calloc(batch->num_cliprects, | 646 | cliprects = kcalloc(batch->num_cliprects, |
| 647 | sizeof(struct drm_clip_rect), | 647 | sizeof(struct drm_clip_rect), |
| 648 | DRM_MEM_DRIVER); | 648 | GFP_KERNEL); |
| 649 | if (cliprects == NULL) | 649 | if (cliprects == NULL) |
| 650 | return -ENOMEM; | 650 | return -ENOMEM; |
| 651 | 651 | ||
| @@ -664,9 +664,7 @@ static int i915_batchbuffer(struct drm_device *dev, void *data, | |||
| 664 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 664 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
| 665 | 665 | ||
| 666 | fail_free: | 666 | fail_free: |
| 667 | drm_free(cliprects, | 667 | kfree(cliprects); |
| 668 | batch->num_cliprects * sizeof(struct drm_clip_rect), | ||
| 669 | DRM_MEM_DRIVER); | ||
| 670 | 668 | ||
| 671 | return ret; | 669 | return ret; |
| 672 | } | 670 | } |
| @@ -692,7 +690,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
| 692 | if (cmdbuf->num_cliprects < 0) | 690 | if (cmdbuf->num_cliprects < 0) |
| 693 | return -EINVAL; | 691 | return -EINVAL; |
| 694 | 692 | ||
| 695 | batch_data = drm_alloc(cmdbuf->sz, DRM_MEM_DRIVER); | 693 | batch_data = kmalloc(cmdbuf->sz, GFP_KERNEL); |
| 696 | if (batch_data == NULL) | 694 | if (batch_data == NULL) |
| 697 | return -ENOMEM; | 695 | return -ENOMEM; |
| 698 | 696 | ||
| @@ -701,9 +699,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
| 701 | goto fail_batch_free; | 699 | goto fail_batch_free; |
| 702 | 700 | ||
| 703 | if (cmdbuf->num_cliprects) { | 701 | if (cmdbuf->num_cliprects) { |
| 704 | cliprects = drm_calloc(cmdbuf->num_cliprects, | 702 | cliprects = kcalloc(cmdbuf->num_cliprects, |
| 705 | sizeof(struct drm_clip_rect), | 703 | sizeof(struct drm_clip_rect), GFP_KERNEL); |
| 706 | DRM_MEM_DRIVER); | ||
| 707 | if (cliprects == NULL) | 704 | if (cliprects == NULL) |
| 708 | goto fail_batch_free; | 705 | goto fail_batch_free; |
| 709 | 706 | ||
| @@ -726,11 +723,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data, | |||
| 726 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); | 723 | sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv); |
| 727 | 724 | ||
| 728 | fail_clip_free: | 725 | fail_clip_free: |
| 729 | drm_free(cliprects, | 726 | kfree(cliprects); |
| 730 | cmdbuf->num_cliprects * sizeof(struct drm_clip_rect), | ||
| 731 | DRM_MEM_DRIVER); | ||
| 732 | fail_batch_free: | 727 | fail_batch_free: |
| 733 | drm_free(batch_data, cmdbuf->sz, DRM_MEM_DRIVER); | 728 | kfree(batch_data); |
| 734 | 729 | ||
| 735 | return ret; | 730 | return ret; |
| 736 | } | 731 | } |
| @@ -1067,7 +1062,7 @@ int i915_master_create(struct drm_device *dev, struct drm_master *master) | |||
| 1067 | { | 1062 | { |
| 1068 | struct drm_i915_master_private *master_priv; | 1063 | struct drm_i915_master_private *master_priv; |
| 1069 | 1064 | ||
| 1070 | master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER); | 1065 | master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL); |
| 1071 | if (!master_priv) | 1066 | if (!master_priv) |
| 1072 | return -ENOMEM; | 1067 | return -ENOMEM; |
| 1073 | 1068 | ||
| @@ -1082,7 +1077,7 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) | |||
| 1082 | if (!master_priv) | 1077 | if (!master_priv) |
| 1083 | return; | 1078 | return; |
| 1084 | 1079 | ||
| 1085 | drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); | 1080 | kfree(master_priv); |
| 1086 | 1081 | ||
| 1087 | master->driver_priv = NULL; | 1082 | master->driver_priv = NULL; |
| 1088 | } | 1083 | } |
| @@ -1111,12 +1106,10 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 1111 | dev->types[8] = _DRM_STAT_SECONDARY; | 1106 | dev->types[8] = _DRM_STAT_SECONDARY; |
| 1112 | dev->types[9] = _DRM_STAT_DMA; | 1107 | dev->types[9] = _DRM_STAT_DMA; |
| 1113 | 1108 | ||
| 1114 | dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER); | 1109 | dev_priv = kzalloc(sizeof(drm_i915_private_t), GFP_KERNEL); |
| 1115 | if (dev_priv == NULL) | 1110 | if (dev_priv == NULL) |
| 1116 | return -ENOMEM; | 1111 | return -ENOMEM; |
| 1117 | 1112 | ||
| 1118 | memset(dev_priv, 0, sizeof(drm_i915_private_t)); | ||
| 1119 | |||
| 1120 | dev->dev_private = (void *)dev_priv; | 1113 | dev->dev_private = (void *)dev_priv; |
| 1121 | dev_priv->dev = dev; | 1114 | dev_priv->dev = dev; |
| 1122 | 1115 | ||
| @@ -1153,13 +1146,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 1153 | "performance may suffer.\n"); | 1146 | "performance may suffer.\n"); |
| 1154 | } | 1147 | } |
| 1155 | 1148 | ||
| 1156 | #ifdef CONFIG_HIGHMEM64G | ||
| 1157 | /* don't enable GEM on PAE - needs agp + set_memory_* interface fixes */ | ||
| 1158 | dev_priv->has_gem = 0; | ||
| 1159 | #else | ||
| 1160 | /* enable GEM by default */ | 1149 | /* enable GEM by default */ |
| 1161 | dev_priv->has_gem = 1; | 1150 | dev_priv->has_gem = 1; |
| 1162 | #endif | ||
| 1163 | 1151 | ||
| 1164 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1152 | dev->driver->get_vblank_counter = i915_get_vblank_counter; |
| 1165 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | 1153 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ |
| @@ -1221,7 +1209,7 @@ out_iomapfree: | |||
| 1221 | out_rmmap: | 1209 | out_rmmap: |
| 1222 | iounmap(dev_priv->regs); | 1210 | iounmap(dev_priv->regs); |
| 1223 | free_priv: | 1211 | free_priv: |
| 1224 | drm_free(dev_priv, sizeof(struct drm_i915_private), DRM_MEM_DRIVER); | 1212 | kfree(dev_priv); |
| 1225 | return ret; | 1213 | return ret; |
| 1226 | } | 1214 | } |
| 1227 | 1215 | ||
| @@ -1261,8 +1249,7 @@ int i915_driver_unload(struct drm_device *dev) | |||
| 1261 | i915_gem_lastclose(dev); | 1249 | i915_gem_lastclose(dev); |
| 1262 | } | 1250 | } |
| 1263 | 1251 | ||
| 1264 | drm_free(dev->dev_private, sizeof(drm_i915_private_t), | 1252 | kfree(dev->dev_private); |
| 1265 | DRM_MEM_DRIVER); | ||
| 1266 | 1253 | ||
| 1267 | return 0; | 1254 | return 0; |
| 1268 | } | 1255 | } |
| @@ -1273,7 +1260,7 @@ int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv) | |||
| 1273 | 1260 | ||
| 1274 | DRM_DEBUG_DRIVER(I915_DRV, "\n"); | 1261 | DRM_DEBUG_DRIVER(I915_DRV, "\n"); |
| 1275 | i915_file_priv = (struct drm_i915_file_private *) | 1262 | i915_file_priv = (struct drm_i915_file_private *) |
| 1276 | drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES); | 1263 | kmalloc(sizeof(*i915_file_priv), GFP_KERNEL); |
| 1277 | 1264 | ||
| 1278 | if (!i915_file_priv) | 1265 | if (!i915_file_priv) |
| 1279 | return -ENOMEM; | 1266 | return -ENOMEM; |
| @@ -1326,7 +1313,7 @@ void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
| 1326 | { | 1313 | { |
| 1327 | struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; | 1314 | struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv; |
| 1328 | 1315 | ||
| 1329 | drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES); | 1316 | kfree(i915_file_priv); |
| 1330 | } | 1317 | } |
| 1331 | 1318 | ||
| 1332 | struct drm_ioctl_desc i915_ioctls[] = { | 1319 | struct drm_ioctl_desc i915_ioctls[] = { |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8ef6bcec211b..7a84f04e8439 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
| @@ -646,6 +646,8 @@ void i915_gem_object_unpin(struct drm_gem_object *obj); | |||
| 646 | int i915_gem_object_unbind(struct drm_gem_object *obj); | 646 | int i915_gem_object_unbind(struct drm_gem_object *obj); |
| 647 | void i915_gem_lastclose(struct drm_device *dev); | 647 | void i915_gem_lastclose(struct drm_device *dev); |
| 648 | uint32_t i915_get_gem_seqno(struct drm_device *dev); | 648 | uint32_t i915_get_gem_seqno(struct drm_device *dev); |
| 649 | int i915_gem_object_get_fence_reg(struct drm_gem_object *obj); | ||
| 650 | int i915_gem_object_put_fence_reg(struct drm_gem_object *obj); | ||
| 649 | void i915_gem_retire_requests(struct drm_device *dev); | 651 | void i915_gem_retire_requests(struct drm_device *dev); |
| 650 | void i915_gem_retire_work_handler(struct work_struct *work); | 652 | void i915_gem_retire_work_handler(struct work_struct *work); |
| 651 | void i915_gem_clflush_object(struct drm_gem_object *obj); | 653 | void i915_gem_clflush_object(struct drm_gem_object *obj); |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c0ae6bbbd9b5..fd2b8bdffe3f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
| @@ -46,7 +46,6 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o | |||
| 46 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); | 46 | static int i915_gem_object_wait_rendering(struct drm_gem_object *obj); |
| 47 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, | 47 | static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, |
| 48 | unsigned alignment); | 48 | unsigned alignment); |
| 49 | static int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write); | ||
| 50 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); | 49 | static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); |
| 51 | static int i915_gem_evict_something(struct drm_device *dev); | 50 | static int i915_gem_evict_something(struct drm_device *dev); |
| 52 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, | 51 | static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, |
| @@ -1158,7 +1157,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 1158 | /* Need a new fence register? */ | 1157 | /* Need a new fence register? */ |
| 1159 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && | 1158 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE && |
| 1160 | obj_priv->tiling_mode != I915_TILING_NONE) { | 1159 | obj_priv->tiling_mode != I915_TILING_NONE) { |
| 1161 | ret = i915_gem_object_get_fence_reg(obj, write); | 1160 | ret = i915_gem_object_get_fence_reg(obj); |
| 1162 | if (ret) { | 1161 | if (ret) { |
| 1163 | mutex_unlock(&dev->struct_mutex); | 1162 | mutex_unlock(&dev->struct_mutex); |
| 1164 | return VM_FAULT_SIGBUS; | 1163 | return VM_FAULT_SIGBUS; |
| @@ -1208,8 +1207,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) | |||
| 1208 | 1207 | ||
| 1209 | /* Set the object up for mmap'ing */ | 1208 | /* Set the object up for mmap'ing */ |
| 1210 | list = &obj->map_list; | 1209 | list = &obj->map_list; |
| 1211 | list->map = drm_calloc(1, sizeof(struct drm_map_list), | 1210 | list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); |
| 1212 | DRM_MEM_DRIVER); | ||
| 1213 | if (!list->map) | 1211 | if (!list->map) |
| 1214 | return -ENOMEM; | 1212 | return -ENOMEM; |
| 1215 | 1213 | ||
| @@ -1249,7 +1247,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) | |||
| 1249 | out_free_mm: | 1247 | out_free_mm: |
| 1250 | drm_mm_put_block(list->file_offset_node); | 1248 | drm_mm_put_block(list->file_offset_node); |
| 1251 | out_free_list: | 1249 | out_free_list: |
| 1252 | drm_free(list->map, sizeof(struct drm_map_list), DRM_MEM_DRIVER); | 1250 | kfree(list->map); |
| 1253 | 1251 | ||
| 1254 | return ret; | 1252 | return ret; |
| 1255 | } | 1253 | } |
| @@ -1271,7 +1269,7 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj) | |||
| 1271 | } | 1269 | } |
| 1272 | 1270 | ||
| 1273 | if (list->map) { | 1271 | if (list->map) { |
| 1274 | drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER); | 1272 | kfree(list->map); |
| 1275 | list->map = NULL; | 1273 | list->map = NULL; |
| 1276 | } | 1274 | } |
| 1277 | 1275 | ||
| @@ -1494,7 +1492,7 @@ i915_add_request(struct drm_device *dev, struct drm_file *file_priv, | |||
| 1494 | if (file_priv != NULL) | 1492 | if (file_priv != NULL) |
| 1495 | i915_file_priv = file_priv->driver_priv; | 1493 | i915_file_priv = file_priv->driver_priv; |
| 1496 | 1494 | ||
| 1497 | request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER); | 1495 | request = kzalloc(sizeof(*request), GFP_KERNEL); |
| 1498 | if (request == NULL) | 1496 | if (request == NULL) |
| 1499 | return 0; | 1497 | return 0; |
| 1500 | 1498 | ||
| @@ -1676,7 +1674,7 @@ i915_gem_retire_requests(struct drm_device *dev) | |||
| 1676 | 1674 | ||
| 1677 | list_del(&request->list); | 1675 | list_del(&request->list); |
| 1678 | list_del(&request->client_list); | 1676 | list_del(&request->client_list); |
| 1679 | drm_free(request, sizeof(*request), DRM_MEM_DRIVER); | 1677 | kfree(request); |
| 1680 | } else | 1678 | } else |
| 1681 | break; | 1679 | break; |
| 1682 | } | 1680 | } |
| @@ -2163,13 +2161,11 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
| 2163 | val |= I830_FENCE_REG_VALID; | 2161 | val |= I830_FENCE_REG_VALID; |
| 2164 | 2162 | ||
| 2165 | I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); | 2163 | I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); |
| 2166 | |||
| 2167 | } | 2164 | } |
| 2168 | 2165 | ||
| 2169 | /** | 2166 | /** |
| 2170 | * i915_gem_object_get_fence_reg - set up a fence reg for an object | 2167 | * i915_gem_object_get_fence_reg - set up a fence reg for an object |
| 2171 | * @obj: object to map through a fence reg | 2168 | * @obj: object to map through a fence reg |
| 2172 | * @write: object is about to be written | ||
| 2173 | * | 2169 | * |
| 2174 | * When mapping objects through the GTT, userspace wants to be able to write | 2170 | * When mapping objects through the GTT, userspace wants to be able to write |
| 2175 | * to them without having to worry about swizzling if the object is tiled. | 2171 | * to them without having to worry about swizzling if the object is tiled. |
| @@ -2180,8 +2176,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) | |||
| 2180 | * It then sets up the reg based on the object's properties: address, pitch | 2176 | * It then sets up the reg based on the object's properties: address, pitch |
| 2181 | * and tiling format. | 2177 | * and tiling format. |
| 2182 | */ | 2178 | */ |
| 2183 | static int | 2179 | int |
| 2184 | i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) | 2180 | i915_gem_object_get_fence_reg(struct drm_gem_object *obj) |
| 2185 | { | 2181 | { |
| 2186 | struct drm_device *dev = obj->dev; | 2182 | struct drm_device *dev = obj->dev; |
| 2187 | struct drm_i915_private *dev_priv = dev->dev_private; | 2183 | struct drm_i915_private *dev_priv = dev->dev_private; |
| @@ -2331,6 +2327,42 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) | |||
| 2331 | } | 2327 | } |
| 2332 | 2328 | ||
| 2333 | /** | 2329 | /** |
| 2330 | * i915_gem_object_put_fence_reg - waits on outstanding fenced access | ||
| 2331 | * to the buffer to finish, and then resets the fence register. | ||
| 2332 | * @obj: tiled object holding a fence register. | ||
| 2333 | * | ||
| 2334 | * Zeroes out the fence register itself and clears out the associated | ||
| 2335 | * data structures in dev_priv and obj_priv. | ||
| 2336 | */ | ||
| 2337 | int | ||
| 2338 | i915_gem_object_put_fence_reg(struct drm_gem_object *obj) | ||
| 2339 | { | ||
| 2340 | struct drm_device *dev = obj->dev; | ||
| 2341 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
| 2342 | |||
| 2343 | if (obj_priv->fence_reg == I915_FENCE_REG_NONE) | ||
| 2344 | return 0; | ||
| 2345 | |||
| 2346 | /* On the i915, GPU access to tiled buffers is via a fence, | ||
| 2347 | * therefore we must wait for any outstanding access to complete | ||
| 2348 | * before clearing the fence. | ||
| 2349 | */ | ||
| 2350 | if (!IS_I965G(dev)) { | ||
| 2351 | int ret; | ||
| 2352 | |||
| 2353 | i915_gem_object_flush_gpu_write_domain(obj); | ||
| 2354 | i915_gem_object_flush_gtt_write_domain(obj); | ||
| 2355 | ret = i915_gem_object_wait_rendering(obj); | ||
| 2356 | if (ret != 0) | ||
| 2357 | return ret; | ||
| 2358 | } | ||
| 2359 | |||
| 2360 | i915_gem_clear_fence_reg (obj); | ||
| 2361 | |||
| 2362 | return 0; | ||
| 2363 | } | ||
| 2364 | |||
| 2365 | /** | ||
| 2334 | * Finds free space in the GTT aperture and binds the object there. | 2366 | * Finds free space in the GTT aperture and binds the object there. |
| 2335 | */ | 2367 | */ |
| 2336 | static int | 2368 | static int |
| @@ -2800,8 +2832,7 @@ i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) | |||
| 2800 | /* Free the page_cpu_valid mappings which are now stale, whether | 2832 | /* Free the page_cpu_valid mappings which are now stale, whether |
| 2801 | * or not we've got I915_GEM_DOMAIN_CPU. | 2833 | * or not we've got I915_GEM_DOMAIN_CPU. |
| 2802 | */ | 2834 | */ |
| 2803 | drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE, | 2835 | kfree(obj_priv->page_cpu_valid); |
| 2804 | DRM_MEM_DRIVER); | ||
| 2805 | obj_priv->page_cpu_valid = NULL; | 2836 | obj_priv->page_cpu_valid = NULL; |
| 2806 | } | 2837 | } |
| 2807 | 2838 | ||
| @@ -2843,8 +2874,8 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, | |||
| 2843 | * newly adding I915_GEM_DOMAIN_CPU | 2874 | * newly adding I915_GEM_DOMAIN_CPU |
| 2844 | */ | 2875 | */ |
| 2845 | if (obj_priv->page_cpu_valid == NULL) { | 2876 | if (obj_priv->page_cpu_valid == NULL) { |
| 2846 | obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE, | 2877 | obj_priv->page_cpu_valid = kzalloc(obj->size / PAGE_SIZE, |
| 2847 | DRM_MEM_DRIVER); | 2878 | GFP_KERNEL); |
| 2848 | if (obj_priv->page_cpu_valid == NULL) | 2879 | if (obj_priv->page_cpu_valid == NULL) |
| 2849 | return -ENOMEM; | 2880 | return -ENOMEM; |
| 2850 | } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) | 2881 | } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) |
| @@ -3267,8 +3298,8 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, | |||
| 3267 | } | 3298 | } |
| 3268 | 3299 | ||
| 3269 | if (args->num_cliprects != 0) { | 3300 | if (args->num_cliprects != 0) { |
| 3270 | cliprects = drm_calloc(args->num_cliprects, sizeof(*cliprects), | 3301 | cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), |
| 3271 | DRM_MEM_DRIVER); | 3302 | GFP_KERNEL); |
| 3272 | if (cliprects == NULL) | 3303 | if (cliprects == NULL) |
| 3273 | goto pre_mutex_err; | 3304 | goto pre_mutex_err; |
| 3274 | 3305 | ||
| @@ -3521,8 +3552,7 @@ err: | |||
| 3521 | pre_mutex_err: | 3552 | pre_mutex_err: |
| 3522 | drm_free_large(object_list); | 3553 | drm_free_large(object_list); |
| 3523 | drm_free_large(exec_list); | 3554 | drm_free_large(exec_list); |
| 3524 | drm_free(cliprects, sizeof(*cliprects) * args->num_cliprects, | 3555 | kfree(cliprects); |
| 3525 | DRM_MEM_DRIVER); | ||
| 3526 | 3556 | ||
| 3527 | return ret; | 3557 | return ret; |
| 3528 | } | 3558 | } |
| @@ -3550,7 +3580,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) | |||
| 3550 | if (!IS_I965G(dev) && | 3580 | if (!IS_I965G(dev) && |
| 3551 | obj_priv->fence_reg == I915_FENCE_REG_NONE && | 3581 | obj_priv->fence_reg == I915_FENCE_REG_NONE && |
| 3552 | obj_priv->tiling_mode != I915_TILING_NONE) { | 3582 | obj_priv->tiling_mode != I915_TILING_NONE) { |
| 3553 | ret = i915_gem_object_get_fence_reg(obj, true); | 3583 | ret = i915_gem_object_get_fence_reg(obj); |
| 3554 | if (ret != 0) { | 3584 | if (ret != 0) { |
| 3555 | if (ret != -EBUSY && ret != -ERESTARTSYS) | 3585 | if (ret != -EBUSY && ret != -ERESTARTSYS) |
| 3556 | DRM_ERROR("Failure to install fence: %d\n", | 3586 | DRM_ERROR("Failure to install fence: %d\n", |
| @@ -3739,7 +3769,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
| 3739 | { | 3769 | { |
| 3740 | struct drm_i915_gem_object *obj_priv; | 3770 | struct drm_i915_gem_object *obj_priv; |
| 3741 | 3771 | ||
| 3742 | obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER); | 3772 | obj_priv = kzalloc(sizeof(*obj_priv), GFP_KERNEL); |
| 3743 | if (obj_priv == NULL) | 3773 | if (obj_priv == NULL) |
| 3744 | return -ENOMEM; | 3774 | return -ENOMEM; |
| 3745 | 3775 | ||
| @@ -3777,9 +3807,9 @@ void i915_gem_free_object(struct drm_gem_object *obj) | |||
| 3777 | 3807 | ||
| 3778 | i915_gem_free_mmap_offset(obj); | 3808 | i915_gem_free_mmap_offset(obj); |
| 3779 | 3809 | ||
| 3780 | drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); | 3810 | kfree(obj_priv->page_cpu_valid); |
| 3781 | kfree(obj_priv->bit_17); | 3811 | kfree(obj_priv->bit_17); |
| 3782 | drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); | 3812 | kfree(obj->driver_private); |
| 3783 | } | 3813 | } |
| 3784 | 3814 | ||
| 3785 | /** Unbinds all objects that are on the given buffer list. */ | 3815 | /** Unbinds all objects that are on the given buffer list. */ |
| @@ -4233,7 +4263,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
| 4233 | if (dev_priv->mm.phys_objs[id - 1] || !size) | 4263 | if (dev_priv->mm.phys_objs[id - 1] || !size) |
| 4234 | return 0; | 4264 | return 0; |
| 4235 | 4265 | ||
| 4236 | phys_obj = drm_calloc(1, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); | 4266 | phys_obj = kzalloc(sizeof(struct drm_i915_gem_phys_object), GFP_KERNEL); |
| 4237 | if (!phys_obj) | 4267 | if (!phys_obj) |
| 4238 | return -ENOMEM; | 4268 | return -ENOMEM; |
| 4239 | 4269 | ||
| @@ -4252,7 +4282,7 @@ int i915_gem_init_phys_object(struct drm_device *dev, | |||
| 4252 | 4282 | ||
| 4253 | return 0; | 4283 | return 0; |
| 4254 | kfree_obj: | 4284 | kfree_obj: |
| 4255 | drm_free(phys_obj, sizeof(struct drm_i915_gem_phys_object), DRM_MEM_DRIVER); | 4285 | kfree(phys_obj); |
| 4256 | return ret; | 4286 | return ret; |
| 4257 | } | 4287 | } |
| 4258 | 4288 | ||
| @@ -4312,6 +4342,8 @@ void i915_gem_detach_phys_object(struct drm_device *dev, | |||
| 4312 | } | 4342 | } |
| 4313 | drm_clflush_pages(obj_priv->pages, page_count); | 4343 | drm_clflush_pages(obj_priv->pages, page_count); |
| 4314 | drm_agp_chipset_flush(dev); | 4344 | drm_agp_chipset_flush(dev); |
| 4345 | |||
| 4346 | i915_gem_object_put_pages(obj); | ||
| 4315 | out: | 4347 | out: |
| 4316 | obj_priv->phys_obj->cur_obj = NULL; | 4348 | obj_priv->phys_obj->cur_obj = NULL; |
| 4317 | obj_priv->phys_obj = NULL; | 4349 | obj_priv->phys_obj = NULL; |
| @@ -4369,6 +4401,8 @@ i915_gem_attach_phys_object(struct drm_device *dev, | |||
| 4369 | kunmap_atomic(src, KM_USER0); | 4401 | kunmap_atomic(src, KM_USER0); |
| 4370 | } | 4402 | } |
| 4371 | 4403 | ||
| 4404 | i915_gem_object_put_pages(obj); | ||
| 4405 | |||
| 4372 | return 0; | 4406 | return 0; |
| 4373 | out: | 4407 | out: |
| 4374 | return ret; | 4408 | return ret; |
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c index 986f1082c596..28146e405e87 100644 --- a/drivers/gpu/drm/i915/i915_gem_debugfs.c +++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c | |||
| @@ -104,7 +104,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) | |||
| 104 | if (obj->name) | 104 | if (obj->name) |
| 105 | seq_printf(m, " (name: %d)", obj->name); | 105 | seq_printf(m, " (name: %d)", obj->name); |
| 106 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) | 106 | if (obj_priv->fence_reg != I915_FENCE_REG_NONE) |
| 107 | seq_printf(m, " (fence: %d\n", obj_priv->fence_reg); | 107 | seq_printf(m, " (fence: %d)\n", obj_priv->fence_reg); |
| 108 | seq_printf(m, "\n"); | 108 | seq_printf(m, "\n"); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| @@ -318,7 +318,7 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) | |||
| 318 | seq_printf(m, "RingTail : %08x\n", tail); | 318 | seq_printf(m, "RingTail : %08x\n", tail); |
| 319 | seq_printf(m, "RingMask : %08x\n", mask); | 319 | seq_printf(m, "RingMask : %08x\n", mask); |
| 320 | seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); | 320 | seq_printf(m, "RingSize : %08lx\n", dev_priv->ring.Size); |
| 321 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); | 321 | seq_printf(m, "Acthd : %08x\n", I915_READ(IS_I965G(dev) ? ACTHD_I965 : ACTHD)); |
| 322 | 322 | ||
| 323 | return 0; | 323 | return 0; |
| 324 | } | 324 | } |
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 9a05cadaa4ad..5c1ceec49f5b 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c | |||
| @@ -408,7 +408,7 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | |||
| 408 | if (stride & (stride - 1)) | 408 | if (stride & (stride - 1)) |
| 409 | return false; | 409 | return false; |
| 410 | 410 | ||
| 411 | /* We don't handle the aperture area covered by the fence being bigger | 411 | /* We don't 0handle the aperture area covered by the fence being bigger |
| 412 | * than the object size. | 412 | * than the object size. |
| 413 | */ | 413 | */ |
| 414 | if (i915_get_fence_size(dev, size) != size) | 414 | if (i915_get_fence_size(dev, size) != size) |
| @@ -417,6 +417,33 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) | |||
| 417 | return true; | 417 | return true; |
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | static bool | ||
| 421 | i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) | ||
| 422 | { | ||
| 423 | struct drm_device *dev = obj->dev; | ||
| 424 | struct drm_i915_gem_object *obj_priv = obj->driver_private; | ||
| 425 | |||
| 426 | if (obj_priv->gtt_space == NULL) | ||
| 427 | return true; | ||
| 428 | |||
| 429 | if (tiling_mode == I915_TILING_NONE) | ||
| 430 | return true; | ||
| 431 | |||
| 432 | if (!IS_I965G(dev)) { | ||
| 433 | if (obj_priv->gtt_offset & (obj->size - 1)) | ||
| 434 | return false; | ||
| 435 | if (IS_I9XX(dev)) { | ||
| 436 | if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) | ||
| 437 | return false; | ||
| 438 | } else { | ||
| 439 | if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK) | ||
| 440 | return false; | ||
| 441 | } | ||
| 442 | } | ||
| 443 | |||
| 444 | return true; | ||
| 445 | } | ||
| 446 | |||
| 420 | /** | 447 | /** |
| 421 | * Sets the tiling mode of an object, returning the required swizzling of | 448 | * Sets the tiling mode of an object, returning the required swizzling of |
| 422 | * bit 6 of addresses in the object. | 449 | * bit 6 of addresses in the object. |
| @@ -429,6 +456,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 429 | drm_i915_private_t *dev_priv = dev->dev_private; | 456 | drm_i915_private_t *dev_priv = dev->dev_private; |
| 430 | struct drm_gem_object *obj; | 457 | struct drm_gem_object *obj; |
| 431 | struct drm_i915_gem_object *obj_priv; | 458 | struct drm_i915_gem_object *obj_priv; |
| 459 | int ret = 0; | ||
| 432 | 460 | ||
| 433 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | 461 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); |
| 434 | if (obj == NULL) | 462 | if (obj == NULL) |
| @@ -436,14 +464,15 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 436 | obj_priv = obj->driver_private; | 464 | obj_priv = obj->driver_private; |
| 437 | 465 | ||
| 438 | if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { | 466 | if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { |
| 467 | mutex_lock(&dev->struct_mutex); | ||
| 439 | drm_gem_object_unreference(obj); | 468 | drm_gem_object_unreference(obj); |
| 469 | mutex_unlock(&dev->struct_mutex); | ||
| 440 | return -EINVAL; | 470 | return -EINVAL; |
| 441 | } | 471 | } |
| 442 | 472 | ||
| 443 | mutex_lock(&dev->struct_mutex); | ||
| 444 | |||
| 445 | if (args->tiling_mode == I915_TILING_NONE) { | 473 | if (args->tiling_mode == I915_TILING_NONE) { |
| 446 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; | 474 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; |
| 475 | args->stride = 0; | ||
| 447 | } else { | 476 | } else { |
| 448 | if (args->tiling_mode == I915_TILING_X) | 477 | if (args->tiling_mode == I915_TILING_X) |
| 449 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; | 478 | args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; |
| @@ -466,32 +495,38 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, | |||
| 466 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) { | 495 | if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) { |
| 467 | args->tiling_mode = I915_TILING_NONE; | 496 | args->tiling_mode = I915_TILING_NONE; |
| 468 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; | 497 | args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE; |
| 498 | args->stride = 0; | ||
| 469 | } | 499 | } |
| 470 | } | 500 | } |
| 471 | if (args->tiling_mode != obj_priv->tiling_mode) { | ||
| 472 | int ret; | ||
| 473 | 501 | ||
| 474 | /* Unbind the object, as switching tiling means we're | 502 | mutex_lock(&dev->struct_mutex); |
| 475 | * switching the cache organization due to fencing, probably. | 503 | if (args->tiling_mode != obj_priv->tiling_mode || |
| 504 | args->stride != obj_priv->stride) { | ||
| 505 | /* We need to rebind the object if its current allocation | ||
| 506 | * no longer meets the alignment restrictions for its new | ||
| 507 | * tiling mode. Otherwise we can just leave it alone, but | ||
| 508 | * need to ensure that any fence register is cleared. | ||
| 476 | */ | 509 | */ |
| 477 | ret = i915_gem_object_unbind(obj); | 510 | if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) |
| 511 | ret = i915_gem_object_unbind(obj); | ||
| 512 | else | ||
| 513 | ret = i915_gem_object_put_fence_reg(obj); | ||
| 478 | if (ret != 0) { | 514 | if (ret != 0) { |
| 479 | WARN(ret != -ERESTARTSYS, | 515 | WARN(ret != -ERESTARTSYS, |
| 480 | "failed to unbind object for tiling switch"); | 516 | "failed to reset object for tiling switch"); |
| 481 | args->tiling_mode = obj_priv->tiling_mode; | 517 | args->tiling_mode = obj_priv->tiling_mode; |
| 482 | mutex_unlock(&dev->struct_mutex); | 518 | args->stride = obj_priv->stride; |
| 483 | drm_gem_object_unreference(obj); | 519 | goto err; |
| 484 | |||
| 485 | return ret; | ||
| 486 | } | 520 | } |
| 521 | |||
| 487 | obj_priv->tiling_mode = args->tiling_mode; | 522 | obj_priv->tiling_mode = args->tiling_mode; |
| 523 | obj_priv->stride = args->stride; | ||
| 488 | } | 524 | } |
| 489 | obj_priv->stride = args->stride; | 525 | err: |
| 490 | |||
| 491 | drm_gem_object_unreference(obj); | 526 | drm_gem_object_unreference(obj); |
| 492 | mutex_unlock(&dev->struct_mutex); | 527 | mutex_unlock(&dev->struct_mutex); |
| 493 | 528 | ||
| 494 | return 0; | 529 | return ret; |
| 495 | } | 530 | } |
| 496 | 531 | ||
| 497 | /** | 532 | /** |
diff --git a/drivers/gpu/drm/i915/i915_mem.c b/drivers/gpu/drm/i915/i915_mem.c index 96e271986d2a..83b7b81bb2b8 100644 --- a/drivers/gpu/drm/i915/i915_mem.c +++ b/drivers/gpu/drm/i915/i915_mem.c | |||
| @@ -94,8 +94,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, | |||
| 94 | { | 94 | { |
| 95 | /* Maybe cut off the start of an existing block */ | 95 | /* Maybe cut off the start of an existing block */ |
| 96 | if (start > p->start) { | 96 | if (start > p->start) { |
| 97 | struct mem_block *newblock = | 97 | struct mem_block *newblock = kmalloc(sizeof(*newblock), |
| 98 | drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS); | 98 | GFP_KERNEL); |
| 99 | if (!newblock) | 99 | if (!newblock) |
| 100 | goto out; | 100 | goto out; |
| 101 | newblock->start = start; | 101 | newblock->start = start; |
| @@ -111,8 +111,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, | |||
| 111 | 111 | ||
| 112 | /* Maybe cut off the end of an existing block */ | 112 | /* Maybe cut off the end of an existing block */ |
| 113 | if (size < p->size) { | 113 | if (size < p->size) { |
| 114 | struct mem_block *newblock = | 114 | struct mem_block *newblock = kmalloc(sizeof(*newblock), |
| 115 | drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS); | 115 | GFP_KERNEL); |
| 116 | if (!newblock) | 116 | if (!newblock) |
| 117 | goto out; | 117 | goto out; |
| 118 | newblock->start = start + size; | 118 | newblock->start = start + size; |
| @@ -169,7 +169,7 @@ static void free_block(struct mem_block *p) | |||
| 169 | p->size += q->size; | 169 | p->size += q->size; |
| 170 | p->next = q->next; | 170 | p->next = q->next; |
| 171 | p->next->prev = p; | 171 | p->next->prev = p; |
| 172 | drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); | 172 | kfree(q); |
| 173 | } | 173 | } |
| 174 | 174 | ||
| 175 | if (p->prev->file_priv == NULL) { | 175 | if (p->prev->file_priv == NULL) { |
| @@ -177,7 +177,7 @@ static void free_block(struct mem_block *p) | |||
| 177 | q->size += p->size; | 177 | q->size += p->size; |
| 178 | q->next = p->next; | 178 | q->next = p->next; |
| 179 | q->next->prev = q; | 179 | q->next->prev = q; |
| 180 | drm_free(p, sizeof(*q), DRM_MEM_BUFLISTS); | 180 | kfree(p); |
| 181 | } | 181 | } |
| 182 | } | 182 | } |
| 183 | 183 | ||
| @@ -185,14 +185,14 @@ static void free_block(struct mem_block *p) | |||
| 185 | */ | 185 | */ |
| 186 | static int init_heap(struct mem_block **heap, int start, int size) | 186 | static int init_heap(struct mem_block **heap, int start, int size) |
| 187 | { | 187 | { |
| 188 | struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFLISTS); | 188 | struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); |
| 189 | 189 | ||
| 190 | if (!blocks) | 190 | if (!blocks) |
| 191 | return -ENOMEM; | 191 | return -ENOMEM; |
| 192 | 192 | ||
| 193 | *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFLISTS); | 193 | *heap = kmalloc(sizeof(**heap), GFP_KERNEL); |
| 194 | if (!*heap) { | 194 | if (!*heap) { |
| 195 | drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFLISTS); | 195 | kfree(blocks); |
| 196 | return -ENOMEM; | 196 | return -ENOMEM; |
| 197 | } | 197 | } |
| 198 | 198 | ||
| @@ -233,7 +233,7 @@ void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv, | |||
| 233 | p->size += q->size; | 233 | p->size += q->size; |
| 234 | p->next = q->next; | 234 | p->next = q->next; |
| 235 | p->next->prev = p; | 235 | p->next->prev = p; |
| 236 | drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); | 236 | kfree(q); |
| 237 | } | 237 | } |
| 238 | } | 238 | } |
| 239 | } | 239 | } |
| @@ -250,10 +250,10 @@ void i915_mem_takedown(struct mem_block **heap) | |||
| 250 | for (p = (*heap)->next; p != *heap;) { | 250 | for (p = (*heap)->next; p != *heap;) { |
| 251 | struct mem_block *q = p; | 251 | struct mem_block *q = p; |
| 252 | p = p->next; | 252 | p = p->next; |
| 253 | drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS); | 253 | kfree(q); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | drm_free(*heap, sizeof(**heap), DRM_MEM_BUFLISTS); | 256 | kfree(*heap); |
| 257 | *heap = NULL; | 257 | *heap = NULL; |
| 258 | } | 258 | } |
| 259 | 259 | ||
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 754dd22fdd77..cdd126d068a7 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c | |||
| @@ -124,8 +124,7 @@ parse_lfp_panel_data(struct drm_i915_private *dev_priv, | |||
| 124 | entry = &lvds_lfp_data->data[lvds_options->panel_type]; | 124 | entry = &lvds_lfp_data->data[lvds_options->panel_type]; |
| 125 | dvo_timing = &entry->dvo_timing; | 125 | dvo_timing = &entry->dvo_timing; |
| 126 | 126 | ||
| 127 | panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode), | 127 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
| 128 | DRM_MEM_DRIVER); | ||
| 129 | 128 | ||
| 130 | fill_detail_timing_data(panel_fixed_mode, dvo_timing); | 129 | fill_detail_timing_data(panel_fixed_mode, dvo_timing); |
| 131 | 130 | ||
| @@ -156,8 +155,7 @@ parse_sdvo_panel_data(struct drm_i915_private *dev_priv, | |||
| 156 | if (!dvo_timing) | 155 | if (!dvo_timing) |
| 157 | return; | 156 | return; |
| 158 | 157 | ||
| 159 | panel_fixed_mode = drm_calloc(1, sizeof(*panel_fixed_mode), | 158 | panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL); |
| 160 | DRM_MEM_DRIVER); | ||
| 161 | 159 | ||
| 162 | if (!panel_fixed_mode) | 160 | if (!panel_fixed_mode) |
| 163 | return; | 161 | return; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 028f5b66e3d8..3e1c78162119 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -828,19 +828,31 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 828 | } | 828 | } |
| 829 | 829 | ||
| 830 | mutex_lock(&dev->struct_mutex); | 830 | mutex_lock(&dev->struct_mutex); |
| 831 | ret = i915_gem_object_pin(intel_fb->obj, alignment); | 831 | ret = i915_gem_object_pin(obj, alignment); |
| 832 | if (ret != 0) { | 832 | if (ret != 0) { |
| 833 | mutex_unlock(&dev->struct_mutex); | 833 | mutex_unlock(&dev->struct_mutex); |
| 834 | return ret; | 834 | return ret; |
| 835 | } | 835 | } |
| 836 | 836 | ||
| 837 | ret = i915_gem_object_set_to_gtt_domain(intel_fb->obj, 1); | 837 | ret = i915_gem_object_set_to_gtt_domain(obj, 1); |
| 838 | if (ret != 0) { | 838 | if (ret != 0) { |
| 839 | i915_gem_object_unpin(intel_fb->obj); | 839 | i915_gem_object_unpin(obj); |
| 840 | mutex_unlock(&dev->struct_mutex); | 840 | mutex_unlock(&dev->struct_mutex); |
| 841 | return ret; | 841 | return ret; |
| 842 | } | 842 | } |
| 843 | 843 | ||
| 844 | /* Pre-i965 needs to install a fence for tiled scan-out */ | ||
| 845 | if (!IS_I965G(dev) && | ||
| 846 | obj_priv->fence_reg == I915_FENCE_REG_NONE && | ||
| 847 | obj_priv->tiling_mode != I915_TILING_NONE) { | ||
| 848 | ret = i915_gem_object_get_fence_reg(obj); | ||
| 849 | if (ret != 0) { | ||
| 850 | i915_gem_object_unpin(obj); | ||
| 851 | mutex_unlock(&dev->struct_mutex); | ||
| 852 | return ret; | ||
| 853 | } | ||
| 854 | } | ||
| 855 | |||
| 844 | dspcntr = I915_READ(dspcntr_reg); | 856 | dspcntr = I915_READ(dspcntr_reg); |
| 845 | /* Mask out pixel format bits in case we change it */ | 857 | /* Mask out pixel format bits in case we change it */ |
| 846 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; | 858 | dspcntr &= ~DISPPLANE_PIXFORMAT_MASK; |
| @@ -860,7 +872,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, | |||
| 860 | break; | 872 | break; |
| 861 | default: | 873 | default: |
| 862 | DRM_ERROR("Unknown color depth\n"); | 874 | DRM_ERROR("Unknown color depth\n"); |
| 863 | i915_gem_object_unpin(intel_fb->obj); | 875 | i915_gem_object_unpin(obj); |
| 864 | mutex_unlock(&dev->struct_mutex); | 876 | mutex_unlock(&dev->struct_mutex); |
| 865 | return -EINVAL; | 877 | return -EINVAL; |
| 866 | } | 878 | } |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 8e28e5993df5..1af7d68e3807 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
| @@ -870,7 +870,11 @@ static int intelfb_single_fb_probe(struct drm_device *dev) | |||
| 870 | */ | 870 | */ |
| 871 | void intelfb_restore(void) | 871 | void intelfb_restore(void) |
| 872 | { | 872 | { |
| 873 | drm_crtc_helper_set_config(&kernelfb_mode); | 873 | int ret; |
| 874 | if ((ret = drm_crtc_helper_set_config(&kernelfb_mode)) != 0) { | ||
| 875 | printk(KERN_ERR "Failed to restore crtc configuration: %d\n", | ||
| 876 | ret); | ||
| 877 | } | ||
| 874 | } | 878 | } |
| 875 | 879 | ||
| 876 | static void intelfb_restore_work_fn(struct work_struct *ignored) | 880 | static void intelfb_restore_work_fn(struct work_struct *ignored) |
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 50d7ed70b338..ea68992e4416 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c | |||
| @@ -1561,8 +1561,7 @@ intel_tv_destroy (struct drm_connector *connector) | |||
| 1561 | 1561 | ||
| 1562 | drm_sysfs_connector_remove(connector); | 1562 | drm_sysfs_connector_remove(connector); |
| 1563 | drm_connector_cleanup(connector); | 1563 | drm_connector_cleanup(connector); |
| 1564 | drm_free(intel_output, sizeof(struct intel_output) + sizeof(struct intel_tv_priv), | 1564 | kfree(intel_output); |
| 1565 | DRM_MEM_DRIVER); | ||
| 1566 | } | 1565 | } |
| 1567 | 1566 | ||
| 1568 | 1567 | ||
| @@ -1695,8 +1694,8 @@ intel_tv_init(struct drm_device *dev) | |||
| 1695 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) | 1694 | (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) |
| 1696 | return; | 1695 | return; |
| 1697 | 1696 | ||
| 1698 | intel_output = drm_calloc(1, sizeof(struct intel_output) + | 1697 | intel_output = kzalloc(sizeof(struct intel_output) + |
| 1699 | sizeof(struct intel_tv_priv), DRM_MEM_DRIVER); | 1698 | sizeof(struct intel_tv_priv), GFP_KERNEL); |
| 1700 | if (!intel_output) { | 1699 | if (!intel_output) { |
| 1701 | return; | 1700 | return; |
| 1702 | } | 1701 | } |
| @@ -1730,8 +1729,8 @@ intel_tv_init(struct drm_device *dev) | |||
| 1730 | connector->doublescan_allowed = false; | 1729 | connector->doublescan_allowed = false; |
| 1731 | 1730 | ||
| 1732 | /* Create TV properties then attach current values */ | 1731 | /* Create TV properties then attach current values */ |
| 1733 | tv_format_names = drm_alloc(sizeof(char *) * NUM_TV_MODES, | 1732 | tv_format_names = kmalloc(sizeof(char *) * NUM_TV_MODES, |
| 1734 | DRM_MEM_DRIVER); | 1733 | GFP_KERNEL); |
| 1735 | if (!tv_format_names) | 1734 | if (!tv_format_names) |
| 1736 | goto out; | 1735 | goto out; |
| 1737 | for (i = 0; i < NUM_TV_MODES; i++) | 1736 | for (i = 0; i < NUM_TV_MODES; i++) |
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index 7a6bf9ffc5a3..6c67a02910c8 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c | |||
| @@ -254,23 +254,20 @@ static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_pr | |||
| 254 | int i; | 254 | int i; |
| 255 | DRM_DEBUG("count=%d\n", dma->buf_count); | 255 | DRM_DEBUG("count=%d\n", dma->buf_count); |
| 256 | 256 | ||
| 257 | dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); | 257 | dev_priv->head = kzalloc(sizeof(drm_mga_freelist_t), GFP_KERNEL); |
| 258 | if (dev_priv->head == NULL) | 258 | if (dev_priv->head == NULL) |
| 259 | return -ENOMEM; | 259 | return -ENOMEM; |
| 260 | 260 | ||
| 261 | memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t)); | ||
| 262 | SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0); | 261 | SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0); |
| 263 | 262 | ||
| 264 | for (i = 0; i < dma->buf_count; i++) { | 263 | for (i = 0; i < dma->buf_count; i++) { |
| 265 | buf = dma->buflist[i]; | 264 | buf = dma->buflist[i]; |
| 266 | buf_priv = buf->dev_private; | 265 | buf_priv = buf->dev_private; |
| 267 | 266 | ||
| 268 | entry = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); | 267 | entry = kzalloc(sizeof(drm_mga_freelist_t), GFP_KERNEL); |
| 269 | if (entry == NULL) | 268 | if (entry == NULL) |
| 270 | return -ENOMEM; | 269 | return -ENOMEM; |
| 271 | 270 | ||
| 272 | memset(entry, 0, sizeof(drm_mga_freelist_t)); | ||
| 273 | |||
| 274 | entry->next = dev_priv->head->next; | 271 | entry->next = dev_priv->head->next; |
| 275 | entry->prev = dev_priv->head; | 272 | entry->prev = dev_priv->head; |
| 276 | SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); | 273 | SET_AGE(&entry->age, MGA_BUFFER_FREE, 0); |
| @@ -301,7 +298,7 @@ static void mga_freelist_cleanup(struct drm_device * dev) | |||
| 301 | entry = dev_priv->head; | 298 | entry = dev_priv->head; |
| 302 | while (entry) { | 299 | while (entry) { |
| 303 | next = entry->next; | 300 | next = entry->next; |
| 304 | drm_free(entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER); | 301 | kfree(entry); |
| 305 | entry = next; | 302 | entry = next; |
| 306 | } | 303 | } |
| 307 | 304 | ||
| @@ -399,12 +396,11 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags) | |||
| 399 | drm_mga_private_t *dev_priv; | 396 | drm_mga_private_t *dev_priv; |
| 400 | int ret; | 397 | int ret; |
| 401 | 398 | ||
| 402 | dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER); | 399 | dev_priv = kzalloc(sizeof(drm_mga_private_t), GFP_KERNEL); |
| 403 | if (!dev_priv) | 400 | if (!dev_priv) |
| 404 | return -ENOMEM; | 401 | return -ENOMEM; |
| 405 | 402 | ||
| 406 | dev->dev_private = (void *)dev_priv; | 403 | dev->dev_private = (void *)dev_priv; |
| 407 | memset(dev_priv, 0, sizeof(drm_mga_private_t)); | ||
| 408 | 404 | ||
| 409 | dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; | 405 | dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; |
| 410 | dev_priv->chipset = flags; | 406 | dev_priv->chipset = flags; |
| @@ -1150,7 +1146,7 @@ int mga_dma_buffers(struct drm_device *dev, void *data, | |||
| 1150 | */ | 1146 | */ |
| 1151 | int mga_driver_unload(struct drm_device * dev) | 1147 | int mga_driver_unload(struct drm_device * dev) |
| 1152 | { | 1148 | { |
| 1153 | drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER); | 1149 | kfree(dev->dev_private); |
| 1154 | dev->dev_private = NULL; | 1150 | dev->dev_private = NULL; |
| 1155 | 1151 | ||
| 1156 | return 0; | 1152 | return 0; |
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c index 077c0455a6b9..c75fd3564040 100644 --- a/drivers/gpu/drm/r128/r128_cce.c +++ b/drivers/gpu/drm/r128/r128_cce.c | |||
| @@ -353,12 +353,10 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init) | |||
| 353 | 353 | ||
| 354 | DRM_DEBUG("\n"); | 354 | DRM_DEBUG("\n"); |
| 355 | 355 | ||
| 356 | dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER); | 356 | dev_priv = kzalloc(sizeof(drm_r128_private_t), GFP_KERNEL); |
| 357 | if (dev_priv == NULL) | 357 | if (dev_priv == NULL) |
| 358 | return -ENOMEM; | 358 | return -ENOMEM; |
| 359 | 359 | ||
| 360 | memset(dev_priv, 0, sizeof(drm_r128_private_t)); | ||
| 361 | |||
| 362 | dev_priv->is_pci = init->is_pci; | 360 | dev_priv->is_pci = init->is_pci; |
| 363 | 361 | ||
| 364 | if (dev_priv->is_pci && !dev->sg) { | 362 | if (dev_priv->is_pci && !dev->sg) { |
| @@ -619,8 +617,7 @@ int r128_do_cleanup_cce(struct drm_device * dev) | |||
| 619 | ("failed to cleanup PCI GART!\n"); | 617 | ("failed to cleanup PCI GART!\n"); |
| 620 | } | 618 | } |
| 621 | 619 | ||
| 622 | drm_free(dev->dev_private, sizeof(drm_r128_private_t), | 620 | kfree(dev->dev_private); |
| 623 | DRM_MEM_DRIVER); | ||
| 624 | dev->dev_private = NULL; | 621 | dev->dev_private = NULL; |
| 625 | } | 622 | } |
| 626 | 623 | ||
| @@ -768,18 +765,17 @@ static int r128_freelist_init(struct drm_device * dev) | |||
| 768 | drm_r128_freelist_t *entry; | 765 | drm_r128_freelist_t *entry; |
| 769 | int i; | 766 | int i; |
| 770 | 767 | ||
| 771 | dev_priv->head = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER); | 768 | dev_priv->head = kzalloc(sizeof(drm_r128_freelist_t), GFP_KERNEL); |
| 772 | if (dev_priv->head == NULL) | 769 | if (dev_priv->head == NULL) |
| 773 | return -ENOMEM; | 770 | return -ENOMEM; |
| 774 | 771 | ||
| 775 | memset(dev_priv->head, 0, sizeof(drm_r128_freelist_t)); | ||
| 776 | dev_priv->head->age = R128_BUFFER_USED; | 772 | dev_priv->head->age = R128_BUFFER_USED; |
| 777 | 773 | ||
| 778 | for (i = 0; i < dma->buf_count; i++) { | 774 | for (i = 0; i < dma->buf_count; i++) { |
| 779 | buf = dma->buflist[i]; | 775 | buf = dma->buflist[i]; |
| 780 | buf_priv = buf->dev_private; | 776 | buf_priv = buf->dev_private; |
| 781 | 777 | ||
| 782 | entry = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER); | 778 | entry = kmalloc(sizeof(drm_r128_freelist_t), GFP_KERNEL); |
| 783 | if (!entry) | 779 | if (!entry) |
| 784 | return -ENOMEM; | 780 | return -ENOMEM; |
| 785 | 781 | ||
diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c index f7a5b5740764..026a48c95c8f 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c | |||
| @@ -910,24 +910,24 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, | |||
| 910 | } | 910 | } |
| 911 | 911 | ||
| 912 | buffer_size = depth->n * sizeof(u32); | 912 | buffer_size = depth->n * sizeof(u32); |
| 913 | buffer = drm_alloc(buffer_size, DRM_MEM_BUFS); | 913 | buffer = kmalloc(buffer_size, GFP_KERNEL); |
| 914 | if (buffer == NULL) | 914 | if (buffer == NULL) |
| 915 | return -ENOMEM; | 915 | return -ENOMEM; |
| 916 | if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { | 916 | if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { |
| 917 | drm_free(buffer, buffer_size, DRM_MEM_BUFS); | 917 | kfree(buffer); |
| 918 | return -EFAULT; | 918 | return -EFAULT; |
| 919 | } | 919 | } |
| 920 | 920 | ||
| 921 | mask_size = depth->n * sizeof(u8); | 921 | mask_size = depth->n * sizeof(u8); |
| 922 | if (depth->mask) { | 922 | if (depth->mask) { |
| 923 | mask = drm_alloc(mask_size, DRM_MEM_BUFS); | 923 | mask = kmalloc(mask_size, GFP_KERNEL); |
| 924 | if (mask == NULL) { | 924 | if (mask == NULL) { |
| 925 | drm_free(buffer, buffer_size, DRM_MEM_BUFS); | 925 | kfree(buffer); |
| 926 | return -ENOMEM; | 926 | return -ENOMEM; |
| 927 | } | 927 | } |
| 928 | if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { | 928 | if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { |
| 929 | drm_free(buffer, buffer_size, DRM_MEM_BUFS); | 929 | kfree(buffer); |
| 930 | drm_free(mask, mask_size, DRM_MEM_BUFS); | 930 | kfree(mask); |
| 931 | return -EFAULT; | 931 | return -EFAULT; |
| 932 | } | 932 | } |
| 933 | 933 | ||
| @@ -954,7 +954,7 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, | |||
| 954 | } | 954 | } |
| 955 | } | 955 | } |
| 956 | 956 | ||
| 957 | drm_free(mask, mask_size, DRM_MEM_BUFS); | 957 | kfree(mask); |
| 958 | } else { | 958 | } else { |
| 959 | for (i = 0; i < count; i++, x++) { | 959 | for (i = 0; i < count; i++, x++) { |
| 960 | BEGIN_RING(6); | 960 | BEGIN_RING(6); |
| @@ -978,7 +978,7 @@ static int r128_cce_dispatch_write_span(struct drm_device * dev, | |||
| 978 | } | 978 | } |
| 979 | } | 979 | } |
| 980 | 980 | ||
| 981 | drm_free(buffer, buffer_size, DRM_MEM_BUFS); | 981 | kfree(buffer); |
| 982 | 982 | ||
| 983 | return 0; | 983 | return 0; |
| 984 | } | 984 | } |
| @@ -1000,54 +1000,54 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, | |||
| 1000 | 1000 | ||
| 1001 | xbuf_size = count * sizeof(*x); | 1001 | xbuf_size = count * sizeof(*x); |
| 1002 | ybuf_size = count * sizeof(*y); | 1002 | ybuf_size = count * sizeof(*y); |
| 1003 | x = drm_alloc(xbuf_size, DRM_MEM_BUFS); | 1003 | x = kmalloc(xbuf_size, GFP_KERNEL); |
| 1004 | if (x == NULL) { | 1004 | if (x == NULL) { |
| 1005 | return -ENOMEM; | 1005 | return -ENOMEM; |
| 1006 | } | 1006 | } |
| 1007 | y = drm_alloc(ybuf_size, DRM_MEM_BUFS); | 1007 | y = kmalloc(ybuf_size, GFP_KERNEL); |
| 1008 | if (y == NULL) { | 1008 | if (y == NULL) { |
| 1009 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1009 | kfree(x); |
| 1010 | return -ENOMEM; | 1010 | return -ENOMEM; |
| 1011 | } | 1011 | } |
| 1012 | if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { | 1012 | if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { |
| 1013 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1013 | kfree(x); |
| 1014 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1014 | kfree(y); |
| 1015 | return -EFAULT; | 1015 | return -EFAULT; |
| 1016 | } | 1016 | } |
| 1017 | if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) { | 1017 | if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) { |
| 1018 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1018 | kfree(x); |
| 1019 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1019 | kfree(y); |
| 1020 | return -EFAULT; | 1020 | return -EFAULT; |
| 1021 | } | 1021 | } |
| 1022 | 1022 | ||
| 1023 | buffer_size = depth->n * sizeof(u32); | 1023 | buffer_size = depth->n * sizeof(u32); |
| 1024 | buffer = drm_alloc(buffer_size, DRM_MEM_BUFS); | 1024 | buffer = kmalloc(buffer_size, GFP_KERNEL); |
| 1025 | if (buffer == NULL) { | 1025 | if (buffer == NULL) { |
| 1026 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1026 | kfree(x); |
| 1027 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1027 | kfree(y); |
| 1028 | return -ENOMEM; | 1028 | return -ENOMEM; |
| 1029 | } | 1029 | } |
| 1030 | if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { | 1030 | if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) { |
| 1031 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1031 | kfree(x); |
| 1032 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1032 | kfree(y); |
| 1033 | drm_free(buffer, buffer_size, DRM_MEM_BUFS); | 1033 | kfree(buffer); |
| 1034 | return -EFAULT; | 1034 | return -EFAULT; |
| 1035 | } | 1035 | } |
| 1036 | 1036 | ||
| 1037 | if (depth->mask) { | 1037 | if (depth->mask) { |
| 1038 | mask_size = depth->n * sizeof(u8); | 1038 | mask_size = depth->n * sizeof(u8); |
| 1039 | mask = drm_alloc(mask_size, DRM_MEM_BUFS); | 1039 | mask = kmalloc(mask_size, GFP_KERNEL); |
| 1040 | if (mask == NULL) { | 1040 | if (mask == NULL) { |
| 1041 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1041 | kfree(x); |
| 1042 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1042 | kfree(y); |
| 1043 | drm_free(buffer, buffer_size, DRM_MEM_BUFS); | 1043 | kfree(buffer); |
| 1044 | return -ENOMEM; | 1044 | return -ENOMEM; |
| 1045 | } | 1045 | } |
| 1046 | if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { | 1046 | if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) { |
| 1047 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1047 | kfree(x); |
| 1048 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1048 | kfree(y); |
| 1049 | drm_free(buffer, buffer_size, DRM_MEM_BUFS); | 1049 | kfree(buffer); |
| 1050 | drm_free(mask, mask_size, DRM_MEM_BUFS); | 1050 | kfree(mask); |
| 1051 | return -EFAULT; | 1051 | return -EFAULT; |
| 1052 | } | 1052 | } |
| 1053 | 1053 | ||
| @@ -1074,7 +1074,7 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, | |||
| 1074 | } | 1074 | } |
| 1075 | } | 1075 | } |
| 1076 | 1076 | ||
| 1077 | drm_free(mask, mask_size, DRM_MEM_BUFS); | 1077 | kfree(mask); |
| 1078 | } else { | 1078 | } else { |
| 1079 | for (i = 0; i < count; i++) { | 1079 | for (i = 0; i < count; i++) { |
| 1080 | BEGIN_RING(6); | 1080 | BEGIN_RING(6); |
| @@ -1098,9 +1098,9 @@ static int r128_cce_dispatch_write_pixels(struct drm_device * dev, | |||
| 1098 | } | 1098 | } |
| 1099 | } | 1099 | } |
| 1100 | 1100 | ||
| 1101 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1101 | kfree(x); |
| 1102 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1102 | kfree(y); |
| 1103 | drm_free(buffer, buffer_size, DRM_MEM_BUFS); | 1103 | kfree(buffer); |
| 1104 | 1104 | ||
| 1105 | return 0; | 1105 | return 0; |
| 1106 | } | 1106 | } |
| @@ -1167,23 +1167,23 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev, | |||
| 1167 | 1167 | ||
| 1168 | xbuf_size = count * sizeof(*x); | 1168 | xbuf_size = count * sizeof(*x); |
| 1169 | ybuf_size = count * sizeof(*y); | 1169 | ybuf_size = count * sizeof(*y); |
| 1170 | x = drm_alloc(xbuf_size, DRM_MEM_BUFS); | 1170 | x = kmalloc(xbuf_size, GFP_KERNEL); |
| 1171 | if (x == NULL) { | 1171 | if (x == NULL) { |
| 1172 | return -ENOMEM; | 1172 | return -ENOMEM; |
| 1173 | } | 1173 | } |
| 1174 | y = drm_alloc(ybuf_size, DRM_MEM_BUFS); | 1174 | y = kmalloc(ybuf_size, GFP_KERNEL); |
| 1175 | if (y == NULL) { | 1175 | if (y == NULL) { |
| 1176 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1176 | kfree(x); |
| 1177 | return -ENOMEM; | 1177 | return -ENOMEM; |
| 1178 | } | 1178 | } |
| 1179 | if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { | 1179 | if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) { |
| 1180 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1180 | kfree(x); |
| 1181 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1181 | kfree(y); |
| 1182 | return -EFAULT; | 1182 | return -EFAULT; |
| 1183 | } | 1183 | } |
| 1184 | if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) { | 1184 | if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) { |
| 1185 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1185 | kfree(x); |
| 1186 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1186 | kfree(y); |
| 1187 | return -EFAULT; | 1187 | return -EFAULT; |
| 1188 | } | 1188 | } |
| 1189 | 1189 | ||
| @@ -1210,8 +1210,8 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev, | |||
| 1210 | ADVANCE_RING(); | 1210 | ADVANCE_RING(); |
| 1211 | } | 1211 | } |
| 1212 | 1212 | ||
| 1213 | drm_free(x, xbuf_size, DRM_MEM_BUFS); | 1213 | kfree(x); |
| 1214 | drm_free(y, ybuf_size, DRM_MEM_BUFS); | 1214 | kfree(y); |
| 1215 | 1215 | ||
| 1216 | return 0; | 1216 | return 0; |
| 1217 | } | 1217 | } |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 5225f5be7ea7..c550932a108f 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
| @@ -551,6 +551,9 @@ int r100_cp_init(struct radeon_device *rdev, unsigned ring_size) | |||
| 551 | /* cp setup */ | 551 | /* cp setup */ |
| 552 | WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); | 552 | WREG32(0x718, pre_write_timer | (pre_write_limit << 28)); |
| 553 | WREG32(RADEON_CP_RB_CNTL, | 553 | WREG32(RADEON_CP_RB_CNTL, |
| 554 | #ifdef __BIG_ENDIAN | ||
| 555 | RADEON_BUF_SWAP_32BIT | | ||
| 556 | #endif | ||
| 554 | REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | | 557 | REG_SET(RADEON_RB_BUFSZ, rb_bufsz) | |
| 555 | REG_SET(RADEON_RB_BLKSZ, rb_blksz) | | 558 | REG_SET(RADEON_RB_BLKSZ, rb_blksz) | |
| 556 | REG_SET(RADEON_MAX_FETCH, max_fetch) | | 559 | REG_SET(RADEON_MAX_FETCH, max_fetch) | |
| @@ -644,7 +647,7 @@ int r100_cp_reset(struct radeon_device *rdev) | |||
| 644 | */ | 647 | */ |
| 645 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, | 648 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, |
| 646 | struct radeon_cs_packet *pkt, | 649 | struct radeon_cs_packet *pkt, |
| 647 | unsigned *auth, unsigned n, | 650 | const unsigned *auth, unsigned n, |
| 648 | radeon_packet0_check_t check) | 651 | radeon_packet0_check_t check) |
| 649 | { | 652 | { |
| 650 | unsigned reg; | 653 | unsigned reg; |
| @@ -654,6 +657,10 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p, | |||
| 654 | 657 | ||
| 655 | idx = pkt->idx + 1; | 658 | idx = pkt->idx + 1; |
| 656 | reg = pkt->reg; | 659 | reg = pkt->reg; |
| 660 | /* Check that register fall into register range | ||
| 661 | * determined by the number of entry (n) in the | ||
| 662 | * safe register bitmap. | ||
| 663 | */ | ||
| 657 | if (pkt->one_reg_wr) { | 664 | if (pkt->one_reg_wr) { |
| 658 | if ((reg >> 7) > n) { | 665 | if ((reg >> 7) > n) { |
| 659 | return -EINVAL; | 666 | return -EINVAL; |
| @@ -683,24 +690,6 @@ int r100_cs_parse_packet0(struct radeon_cs_parser *p, | |||
| 683 | return 0; | 690 | return 0; |
| 684 | } | 691 | } |
| 685 | 692 | ||
| 686 | int r100_cs_parse_packet3(struct radeon_cs_parser *p, | ||
| 687 | struct radeon_cs_packet *pkt, | ||
| 688 | unsigned *auth, unsigned n, | ||
| 689 | radeon_packet3_check_t check) | ||
| 690 | { | ||
| 691 | unsigned i, m; | ||
| 692 | |||
| 693 | if ((pkt->opcode >> 5) > n) { | ||
| 694 | return -EINVAL; | ||
| 695 | } | ||
| 696 | i = pkt->opcode >> 5; | ||
| 697 | m = 1 << (pkt->opcode & 31); | ||
| 698 | if (auth[i] & m) { | ||
| 699 | return check(p, pkt); | ||
| 700 | } | ||
| 701 | return 0; | ||
| 702 | } | ||
| 703 | |||
| 704 | void r100_cs_dump_packet(struct radeon_cs_parser *p, | 693 | void r100_cs_dump_packet(struct radeon_cs_parser *p, |
| 705 | struct radeon_cs_packet *pkt) | 694 | struct radeon_cs_packet *pkt) |
| 706 | { | 695 | { |
| @@ -901,6 +890,25 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
| 901 | return 0; | 890 | return 0; |
| 902 | } | 891 | } |
| 903 | 892 | ||
| 893 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | ||
| 894 | struct radeon_cs_packet *pkt, | ||
| 895 | struct radeon_object *robj) | ||
| 896 | { | ||
| 897 | struct radeon_cs_chunk *ib_chunk; | ||
| 898 | unsigned idx; | ||
| 899 | |||
| 900 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | ||
| 901 | idx = pkt->idx + 1; | ||
| 902 | if ((ib_chunk->kdata[idx+2] + 1) > radeon_object_size(robj)) { | ||
| 903 | DRM_ERROR("[drm] Buffer too small for PACKET3 INDX_BUFFER " | ||
| 904 | "(need %u have %lu) !\n", | ||
| 905 | ib_chunk->kdata[idx+2] + 1, | ||
| 906 | radeon_object_size(robj)); | ||
| 907 | return -EINVAL; | ||
| 908 | } | ||
| 909 | return 0; | ||
| 910 | } | ||
| 911 | |||
| 904 | static int r100_packet3_check(struct radeon_cs_parser *p, | 912 | static int r100_packet3_check(struct radeon_cs_parser *p, |
| 905 | struct radeon_cs_packet *pkt) | 913 | struct radeon_cs_packet *pkt) |
| 906 | { | 914 | { |
| @@ -954,6 +962,10 @@ static int r100_packet3_check(struct radeon_cs_parser *p, | |||
| 954 | return r; | 962 | return r; |
| 955 | } | 963 | } |
| 956 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | 964 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
| 965 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); | ||
| 966 | if (r) { | ||
| 967 | return r; | ||
| 968 | } | ||
| 957 | break; | 969 | break; |
| 958 | case 0x23: | 970 | case 0x23: |
| 959 | /* FIXME: cleanup */ | 971 | /* FIXME: cleanup */ |
| @@ -999,18 +1011,18 @@ int r100_cs_parse(struct radeon_cs_parser *p) | |||
| 999 | } | 1011 | } |
| 1000 | p->idx += pkt.count + 2; | 1012 | p->idx += pkt.count + 2; |
| 1001 | switch (pkt.type) { | 1013 | switch (pkt.type) { |
| 1002 | case PACKET_TYPE0: | 1014 | case PACKET_TYPE0: |
| 1003 | r = r100_packet0_check(p, &pkt); | 1015 | r = r100_packet0_check(p, &pkt); |
| 1004 | break; | 1016 | break; |
| 1005 | case PACKET_TYPE2: | 1017 | case PACKET_TYPE2: |
| 1006 | break; | 1018 | break; |
| 1007 | case PACKET_TYPE3: | 1019 | case PACKET_TYPE3: |
| 1008 | r = r100_packet3_check(p, &pkt); | 1020 | r = r100_packet3_check(p, &pkt); |
| 1009 | break; | 1021 | break; |
| 1010 | default: | 1022 | default: |
| 1011 | DRM_ERROR("Unknown packet type %d !\n", | 1023 | DRM_ERROR("Unknown packet type %d !\n", |
| 1012 | pkt.type); | 1024 | pkt.type); |
| 1013 | return -EINVAL; | 1025 | return -EINVAL; |
| 1014 | } | 1026 | } |
| 1015 | if (r) { | 1027 | if (r) { |
| 1016 | return r; | 1028 | return r; |
| @@ -1267,12 +1279,6 @@ void r100_vram_info(struct radeon_device *rdev) | |||
| 1267 | 1279 | ||
| 1268 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); | 1280 | rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0); |
| 1269 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); | 1281 | rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0); |
| 1270 | if (rdev->mc.aper_size > rdev->mc.vram_size) { | ||
| 1271 | /* Why does some hw doesn't have CONFIG_MEMSIZE properly | ||
| 1272 | * setup ? */ | ||
| 1273 | rdev->mc.vram_size = rdev->mc.aper_size; | ||
| 1274 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.vram_size); | ||
| 1275 | } | ||
| 1276 | } | 1282 | } |
| 1277 | 1283 | ||
| 1278 | 1284 | ||
| @@ -1352,6 +1358,11 @@ void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
| 1352 | } | 1358 | } |
| 1353 | } | 1359 | } |
| 1354 | 1360 | ||
| 1361 | int r100_init(struct radeon_device *rdev) | ||
| 1362 | { | ||
| 1363 | return 0; | ||
| 1364 | } | ||
| 1365 | |||
| 1355 | /* | 1366 | /* |
| 1356 | * Debugfs info | 1367 | * Debugfs info |
| 1357 | */ | 1368 | */ |
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index f5870a099d4f..e2ed5bc08170 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c | |||
| @@ -48,14 +48,13 @@ int r100_cs_packet_next_reloc(struct radeon_cs_parser *p, | |||
| 48 | struct radeon_cs_reloc **cs_reloc); | 48 | struct radeon_cs_reloc **cs_reloc); |
| 49 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, | 49 | int r100_cs_parse_packet0(struct radeon_cs_parser *p, |
| 50 | struct radeon_cs_packet *pkt, | 50 | struct radeon_cs_packet *pkt, |
| 51 | unsigned *auth, unsigned n, | 51 | const unsigned *auth, unsigned n, |
| 52 | radeon_packet0_check_t check); | 52 | radeon_packet0_check_t check); |
| 53 | int r100_cs_parse_packet3(struct radeon_cs_parser *p, | ||
| 54 | struct radeon_cs_packet *pkt, | ||
| 55 | unsigned *auth, unsigned n, | ||
| 56 | radeon_packet3_check_t check); | ||
| 57 | void r100_cs_dump_packet(struct radeon_cs_parser *p, | 53 | void r100_cs_dump_packet(struct radeon_cs_parser *p, |
| 58 | struct radeon_cs_packet *pkt); | 54 | struct radeon_cs_packet *pkt); |
| 55 | int r100_cs_track_check_pkt3_indx_buffer(struct radeon_cs_parser *p, | ||
| 56 | struct radeon_cs_packet *pkt, | ||
| 57 | struct radeon_object *robj); | ||
| 59 | 58 | ||
| 60 | /* This files gather functions specifics to: | 59 | /* This files gather functions specifics to: |
| 61 | * r300,r350,rv350,rv370,rv380 | 60 | * r300,r350,rv350,rv370,rv380 |
| @@ -288,7 +287,7 @@ int r300_copy_dma(struct radeon_device *rdev, | |||
| 288 | return r; | 287 | return r; |
| 289 | } | 288 | } |
| 290 | /* Must wait for 2D idle & clean before DMA or hangs might happen */ | 289 | /* Must wait for 2D idle & clean before DMA or hangs might happen */ |
| 291 | radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0)); | 290 | radeon_ring_write(rdev, PACKET0(RADEON_WAIT_UNTIL, 0 )); |
| 292 | radeon_ring_write(rdev, (1 << 16)); | 291 | radeon_ring_write(rdev, (1 << 16)); |
| 293 | for (i = 0; i < num_loops; i++) { | 292 | for (i = 0; i < num_loops; i++) { |
| 294 | cur_size = size; | 293 | cur_size = size; |
| @@ -319,7 +318,7 @@ void r300_ring_start(struct radeon_device *rdev) | |||
| 319 | 318 | ||
| 320 | /* Sub pixel 1/12 so we can have 4K rendering according to doc */ | 319 | /* Sub pixel 1/12 so we can have 4K rendering according to doc */ |
| 321 | gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); | 320 | gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16); |
| 322 | switch (rdev->num_gb_pipes) { | 321 | switch(rdev->num_gb_pipes) { |
| 323 | case 2: | 322 | case 2: |
| 324 | gb_tile_config |= R300_PIPE_COUNT_R300; | 323 | gb_tile_config |= R300_PIPE_COUNT_R300; |
| 325 | break; | 324 | break; |
| @@ -452,8 +451,8 @@ void r300_gpu_init(struct radeon_device *rdev) | |||
| 452 | case 4: | 451 | case 4: |
| 453 | gb_tile_config |= R300_PIPE_COUNT_R420; | 452 | gb_tile_config |= R300_PIPE_COUNT_R420; |
| 454 | break; | 453 | break; |
| 455 | case 1: | ||
| 456 | default: | 454 | default: |
| 455 | case 1: | ||
| 457 | gb_tile_config |= R300_PIPE_COUNT_RV350; | 456 | gb_tile_config |= R300_PIPE_COUNT_RV350; |
| 458 | break; | 457 | break; |
| 459 | } | 458 | } |
| @@ -725,18 +724,120 @@ struct r300_cs_track_cb { | |||
| 725 | unsigned offset; | 724 | unsigned offset; |
| 726 | }; | 725 | }; |
| 727 | 726 | ||
| 727 | struct r300_cs_track_array { | ||
| 728 | struct radeon_object *robj; | ||
| 729 | unsigned esize; | ||
| 730 | }; | ||
| 731 | |||
| 732 | struct r300_cs_track_texture { | ||
| 733 | struct radeon_object *robj; | ||
| 734 | unsigned pitch; | ||
| 735 | unsigned width; | ||
| 736 | unsigned height; | ||
| 737 | unsigned num_levels; | ||
| 738 | unsigned cpp; | ||
| 739 | unsigned tex_coord_type; | ||
| 740 | unsigned txdepth; | ||
| 741 | unsigned width_11; | ||
| 742 | unsigned height_11; | ||
| 743 | bool use_pitch; | ||
| 744 | bool enabled; | ||
| 745 | bool roundup_w; | ||
| 746 | bool roundup_h; | ||
| 747 | }; | ||
| 748 | |||
| 728 | struct r300_cs_track { | 749 | struct r300_cs_track { |
| 729 | unsigned num_cb; | 750 | unsigned num_cb; |
| 730 | unsigned maxy; | 751 | unsigned maxy; |
| 731 | struct r300_cs_track_cb cb[4]; | 752 | unsigned vtx_size; |
| 732 | struct r300_cs_track_cb zb; | 753 | unsigned vap_vf_cntl; |
| 733 | bool z_enabled; | 754 | unsigned immd_dwords; |
| 755 | unsigned num_arrays; | ||
| 756 | unsigned max_indx; | ||
| 757 | struct r300_cs_track_array arrays[11]; | ||
| 758 | struct r300_cs_track_cb cb[4]; | ||
| 759 | struct r300_cs_track_cb zb; | ||
| 760 | struct r300_cs_track_texture textures[16]; | ||
| 761 | bool z_enabled; | ||
| 734 | }; | 762 | }; |
| 735 | 763 | ||
| 764 | static inline void r300_cs_track_texture_print(struct r300_cs_track_texture *t) | ||
| 765 | { | ||
| 766 | DRM_ERROR("pitch %d\n", t->pitch); | ||
| 767 | DRM_ERROR("width %d\n", t->width); | ||
| 768 | DRM_ERROR("height %d\n", t->height); | ||
| 769 | DRM_ERROR("num levels %d\n", t->num_levels); | ||
| 770 | DRM_ERROR("depth %d\n", t->txdepth); | ||
| 771 | DRM_ERROR("bpp %d\n", t->cpp); | ||
| 772 | DRM_ERROR("coordinate type %d\n", t->tex_coord_type); | ||
| 773 | DRM_ERROR("width round to power of 2 %d\n", t->roundup_w); | ||
| 774 | DRM_ERROR("height round to power of 2 %d\n", t->roundup_h); | ||
| 775 | } | ||
| 776 | |||
| 777 | static inline int r300_cs_track_texture_check(struct radeon_device *rdev, | ||
| 778 | struct r300_cs_track *track) | ||
| 779 | { | ||
| 780 | struct radeon_object *robj; | ||
| 781 | unsigned long size; | ||
| 782 | unsigned u, i, w, h; | ||
| 783 | |||
| 784 | for (u = 0; u < 16; u++) { | ||
| 785 | if (!track->textures[u].enabled) | ||
| 786 | continue; | ||
| 787 | robj = track->textures[u].robj; | ||
| 788 | if (robj == NULL) { | ||
| 789 | DRM_ERROR("No texture bound to unit %u\n", u); | ||
| 790 | return -EINVAL; | ||
| 791 | } | ||
| 792 | size = 0; | ||
| 793 | for (i = 0; i <= track->textures[u].num_levels; i++) { | ||
| 794 | if (track->textures[u].use_pitch) { | ||
| 795 | w = track->textures[u].pitch / (1 << i); | ||
| 796 | } else { | ||
| 797 | w = track->textures[u].width / (1 << i); | ||
| 798 | if (rdev->family >= CHIP_RV515) | ||
| 799 | w |= track->textures[u].width_11; | ||
| 800 | if (track->textures[u].roundup_w) | ||
| 801 | w = roundup_pow_of_two(w); | ||
| 802 | } | ||
| 803 | h = track->textures[u].height / (1 << i); | ||
| 804 | if (rdev->family >= CHIP_RV515) | ||
| 805 | h |= track->textures[u].height_11; | ||
| 806 | if (track->textures[u].roundup_h) | ||
| 807 | h = roundup_pow_of_two(h); | ||
| 808 | size += w * h; | ||
| 809 | } | ||
| 810 | size *= track->textures[u].cpp; | ||
| 811 | switch (track->textures[u].tex_coord_type) { | ||
| 812 | case 0: | ||
| 813 | break; | ||
| 814 | case 1: | ||
| 815 | size *= (1 << track->textures[u].txdepth); | ||
| 816 | break; | ||
| 817 | case 2: | ||
| 818 | size *= 6; | ||
| 819 | break; | ||
| 820 | default: | ||
| 821 | DRM_ERROR("Invalid texture coordinate type %u for unit " | ||
| 822 | "%u\n", track->textures[u].tex_coord_type, u); | ||
| 823 | return -EINVAL; | ||
| 824 | } | ||
| 825 | if (size > radeon_object_size(robj)) { | ||
| 826 | DRM_ERROR("Texture of unit %u needs %lu bytes but is " | ||
| 827 | "%lu\n", u, size, radeon_object_size(robj)); | ||
| 828 | r300_cs_track_texture_print(&track->textures[u]); | ||
| 829 | return -EINVAL; | ||
| 830 | } | ||
| 831 | } | ||
| 832 | return 0; | ||
| 833 | } | ||
| 834 | |||
| 736 | int r300_cs_track_check(struct radeon_device *rdev, struct r300_cs_track *track) | 835 | int r300_cs_track_check(struct radeon_device *rdev, struct r300_cs_track *track) |
| 737 | { | 836 | { |
| 738 | unsigned i; | 837 | unsigned i; |
| 739 | unsigned long size; | 838 | unsigned long size; |
| 839 | unsigned prim_walk; | ||
| 840 | unsigned nverts; | ||
| 740 | 841 | ||
| 741 | for (i = 0; i < track->num_cb; i++) { | 842 | for (i = 0; i < track->num_cb; i++) { |
| 742 | if (track->cb[i].robj == NULL) { | 843 | if (track->cb[i].robj == NULL) { |
| @@ -769,7 +870,59 @@ int r300_cs_track_check(struct radeon_device *rdev, struct r300_cs_track *track) | |||
| 769 | return -EINVAL; | 870 | return -EINVAL; |
| 770 | } | 871 | } |
| 771 | } | 872 | } |
| 772 | return 0; | 873 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; |
| 874 | nverts = (track->vap_vf_cntl >> 16) & 0xFFFF; | ||
| 875 | switch (prim_walk) { | ||
| 876 | case 1: | ||
| 877 | for (i = 0; i < track->num_arrays; i++) { | ||
| 878 | size = track->arrays[i].esize * track->max_indx * 4; | ||
| 879 | if (track->arrays[i].robj == NULL) { | ||
| 880 | DRM_ERROR("(PW %u) Vertex array %u no buffer " | ||
| 881 | "bound\n", prim_walk, i); | ||
| 882 | return -EINVAL; | ||
| 883 | } | ||
| 884 | if (size > radeon_object_size(track->arrays[i].robj)) { | ||
| 885 | DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " | ||
| 886 | "have %lu dwords\n", prim_walk, i, | ||
| 887 | size >> 2, | ||
| 888 | radeon_object_size(track->arrays[i].robj) >> 2); | ||
| 889 | DRM_ERROR("Max indices %u\n", track->max_indx); | ||
| 890 | return -EINVAL; | ||
| 891 | } | ||
| 892 | } | ||
| 893 | break; | ||
| 894 | case 2: | ||
| 895 | for (i = 0; i < track->num_arrays; i++) { | ||
| 896 | size = track->arrays[i].esize * (nverts - 1) * 4; | ||
| 897 | if (track->arrays[i].robj == NULL) { | ||
| 898 | DRM_ERROR("(PW %u) Vertex array %u no buffer " | ||
| 899 | "bound\n", prim_walk, i); | ||
| 900 | return -EINVAL; | ||
| 901 | } | ||
| 902 | if (size > radeon_object_size(track->arrays[i].robj)) { | ||
| 903 | DRM_ERROR("(PW %u) Vertex array %u need %lu dwords " | ||
| 904 | "have %lu dwords\n", prim_walk, i, size >> 2, | ||
| 905 | radeon_object_size(track->arrays[i].robj) >> 2); | ||
| 906 | return -EINVAL; | ||
| 907 | } | ||
| 908 | } | ||
| 909 | break; | ||
| 910 | case 3: | ||
| 911 | size = track->vtx_size * nverts; | ||
| 912 | if (size != track->immd_dwords) { | ||
| 913 | DRM_ERROR("IMMD draw %u dwors but needs %lu dwords\n", | ||
| 914 | track->immd_dwords, size); | ||
| 915 | DRM_ERROR("VAP_VF_CNTL.NUM_VERTICES %u, VTX_SIZE %u\n", | ||
| 916 | nverts, track->vtx_size); | ||
| 917 | return -EINVAL; | ||
| 918 | } | ||
| 919 | break; | ||
| 920 | default: | ||
| 921 | DRM_ERROR("[drm] Invalid primitive walk %d for VAP_VF_CNTL\n", | ||
| 922 | prim_walk); | ||
| 923 | return -EINVAL; | ||
| 924 | } | ||
| 925 | return r300_cs_track_texture_check(rdev, track); | ||
| 773 | } | 926 | } |
| 774 | 927 | ||
| 775 | static inline void r300_cs_track_clear(struct r300_cs_track *track) | 928 | static inline void r300_cs_track_clear(struct r300_cs_track *track) |
| @@ -789,9 +942,33 @@ static inline void r300_cs_track_clear(struct r300_cs_track *track) | |||
| 789 | track->zb.pitch = 8192; | 942 | track->zb.pitch = 8192; |
| 790 | track->zb.cpp = 4; | 943 | track->zb.cpp = 4; |
| 791 | track->zb.offset = 0; | 944 | track->zb.offset = 0; |
| 945 | track->vtx_size = 0x7F; | ||
| 946 | track->immd_dwords = 0xFFFFFFFFUL; | ||
| 947 | track->num_arrays = 11; | ||
| 948 | track->max_indx = 0x00FFFFFFUL; | ||
| 949 | for (i = 0; i < track->num_arrays; i++) { | ||
| 950 | track->arrays[i].robj = NULL; | ||
| 951 | track->arrays[i].esize = 0x7F; | ||
| 952 | } | ||
| 953 | for (i = 0; i < 16; i++) { | ||
| 954 | track->textures[i].pitch = 16536; | ||
| 955 | track->textures[i].width = 16536; | ||
| 956 | track->textures[i].height = 16536; | ||
| 957 | track->textures[i].width_11 = 1 << 11; | ||
| 958 | track->textures[i].height_11 = 1 << 11; | ||
| 959 | track->textures[i].num_levels = 12; | ||
| 960 | track->textures[i].txdepth = 16; | ||
| 961 | track->textures[i].cpp = 64; | ||
| 962 | track->textures[i].tex_coord_type = 1; | ||
| 963 | track->textures[i].robj = NULL; | ||
| 964 | /* CS IB emission code makes sure texture unit are disabled */ | ||
| 965 | track->textures[i].enabled = false; | ||
| 966 | track->textures[i].roundup_w = true; | ||
| 967 | track->textures[i].roundup_h = true; | ||
| 968 | } | ||
| 792 | } | 969 | } |
| 793 | 970 | ||
| 794 | static unsigned r300_auth_reg[] = { | 971 | static const unsigned r300_reg_safe_bm[159] = { |
| 795 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 972 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| 796 | 0xFFFFFFBF, 0xFFFFFFFF, 0xFFFFFFBF, 0xFFFFFFFF, | 973 | 0xFFFFFFBF, 0xFFFFFFFF, 0xFFFFFFBF, 0xFFFFFFFF, |
| 797 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 974 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| @@ -808,7 +985,7 @@ static unsigned r300_auth_reg[] = { | |||
| 808 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 985 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| 809 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F, | 986 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F, |
| 810 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 987 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| 811 | 0xFFFFFFFF, 0xFFFFCFCC, 0xF00E9FFF, 0x007C0000, | 988 | 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000, |
| 812 | 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF, | 989 | 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF, |
| 813 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 990 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| 814 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 991 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| @@ -824,9 +1001,9 @@ static unsigned r300_auth_reg[] = { | |||
| 824 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 1001 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| 825 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 1002 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| 826 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | 1003 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, |
| 827 | 0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, | 1004 | 0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, |
| 828 | 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF, | 1005 | 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF, |
| 829 | 0x00000000, 0x00000000, 0xFFFF0000, 0x00000000, | 1006 | 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, |
| 830 | 0x00000000, 0x0000C100, 0x00000000, 0x00000000, | 1007 | 0x00000000, 0x0000C100, 0x00000000, 0x00000000, |
| 831 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 1008 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, |
| 832 | 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF, | 1009 | 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF, |
| @@ -848,8 +1025,8 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 848 | 1025 | ||
| 849 | ib = p->ib->ptr; | 1026 | ib = p->ib->ptr; |
| 850 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | 1027 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
| 851 | track = (struct r300_cs_track *)p->track; | 1028 | track = (struct r300_cs_track*)p->track; |
| 852 | switch (reg) { | 1029 | switch(reg) { |
| 853 | case RADEON_DST_PITCH_OFFSET: | 1030 | case RADEON_DST_PITCH_OFFSET: |
| 854 | case RADEON_SRC_PITCH_OFFSET: | 1031 | case RADEON_SRC_PITCH_OFFSET: |
| 855 | r = r100_cs_packet_next_reloc(p, &reloc); | 1032 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -907,6 +1084,7 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 907 | case R300_TX_OFFSET_0+52: | 1084 | case R300_TX_OFFSET_0+52: |
| 908 | case R300_TX_OFFSET_0+56: | 1085 | case R300_TX_OFFSET_0+56: |
| 909 | case R300_TX_OFFSET_0+60: | 1086 | case R300_TX_OFFSET_0+60: |
| 1087 | i = (reg - R300_TX_OFFSET_0) >> 2; | ||
| 910 | r = r100_cs_packet_next_reloc(p, &reloc); | 1088 | r = r100_cs_packet_next_reloc(p, &reloc); |
| 911 | if (r) { | 1089 | if (r) { |
| 912 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", | 1090 | DRM_ERROR("No reloc for ib[%d]=0x%04X\n", |
| @@ -915,11 +1093,23 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 915 | return r; | 1093 | return r; |
| 916 | } | 1094 | } |
| 917 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); | 1095 | ib[idx] = ib_chunk->kdata[idx] + ((u32)reloc->lobj.gpu_offset); |
| 1096 | track->textures[i].robj = reloc->robj; | ||
| 918 | break; | 1097 | break; |
| 919 | /* Tracked registers */ | 1098 | /* Tracked registers */ |
| 1099 | case 0x2084: | ||
| 1100 | /* VAP_VF_CNTL */ | ||
| 1101 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | ||
| 1102 | break; | ||
| 1103 | case 0x20B4: | ||
| 1104 | /* VAP_VTX_SIZE */ | ||
| 1105 | track->vtx_size = ib_chunk->kdata[idx] & 0x7F; | ||
| 1106 | break; | ||
| 1107 | case 0x2134: | ||
| 1108 | /* VAP_VF_MAX_VTX_INDX */ | ||
| 1109 | track->max_indx = ib_chunk->kdata[idx] & 0x00FFFFFFUL; | ||
| 1110 | break; | ||
| 920 | case 0x43E4: | 1111 | case 0x43E4: |
| 921 | /* SC_SCISSOR1 */ | 1112 | /* SC_SCISSOR1 */ |
| 922 | |||
| 923 | track->maxy = ((ib_chunk->kdata[idx] >> 13) & 0x1FFF) + 1; | 1113 | track->maxy = ((ib_chunk->kdata[idx] >> 13) & 0x1FFF) + 1; |
| 924 | if (p->rdev->family < CHIP_RV515) { | 1114 | if (p->rdev->family < CHIP_RV515) { |
| 925 | track->maxy -= 1440; | 1115 | track->maxy -= 1440; |
| @@ -994,8 +1184,166 @@ static int r300_packet0_check(struct radeon_cs_parser *p, | |||
| 994 | /* ZB_DEPTHPITCH */ | 1184 | /* ZB_DEPTHPITCH */ |
| 995 | track->zb.pitch = ib_chunk->kdata[idx] & 0x3FFC; | 1185 | track->zb.pitch = ib_chunk->kdata[idx] & 0x3FFC; |
| 996 | break; | 1186 | break; |
| 1187 | case 0x4104: | ||
| 1188 | for (i = 0; i < 16; i++) { | ||
| 1189 | bool enabled; | ||
| 1190 | |||
| 1191 | enabled = !!(ib_chunk->kdata[idx] & (1 << i)); | ||
| 1192 | track->textures[i].enabled = enabled; | ||
| 1193 | } | ||
| 1194 | break; | ||
| 1195 | case 0x44C0: | ||
| 1196 | case 0x44C4: | ||
| 1197 | case 0x44C8: | ||
| 1198 | case 0x44CC: | ||
| 1199 | case 0x44D0: | ||
| 1200 | case 0x44D4: | ||
| 1201 | case 0x44D8: | ||
| 1202 | case 0x44DC: | ||
| 1203 | case 0x44E0: | ||
| 1204 | case 0x44E4: | ||
| 1205 | case 0x44E8: | ||
| 1206 | case 0x44EC: | ||
| 1207 | case 0x44F0: | ||
| 1208 | case 0x44F4: | ||
| 1209 | case 0x44F8: | ||
| 1210 | case 0x44FC: | ||
| 1211 | /* TX_FORMAT1_[0-15] */ | ||
| 1212 | i = (reg - 0x44C0) >> 2; | ||
| 1213 | tmp = (ib_chunk->kdata[idx] >> 25) & 0x3; | ||
| 1214 | track->textures[i].tex_coord_type = tmp; | ||
| 1215 | switch ((ib_chunk->kdata[idx] & 0x1F)) { | ||
| 1216 | case 0: | ||
| 1217 | case 2: | ||
| 1218 | case 5: | ||
| 1219 | case 18: | ||
| 1220 | case 20: | ||
| 1221 | case 21: | ||
| 1222 | track->textures[i].cpp = 1; | ||
| 1223 | break; | ||
| 1224 | case 1: | ||
| 1225 | case 3: | ||
| 1226 | case 6: | ||
| 1227 | case 7: | ||
| 1228 | case 10: | ||
| 1229 | case 11: | ||
| 1230 | case 19: | ||
| 1231 | case 22: | ||
| 1232 | case 24: | ||
| 1233 | track->textures[i].cpp = 2; | ||
| 1234 | break; | ||
| 1235 | case 4: | ||
| 1236 | case 8: | ||
| 1237 | case 9: | ||
| 1238 | case 12: | ||
| 1239 | case 13: | ||
| 1240 | case 23: | ||
| 1241 | case 25: | ||
| 1242 | case 27: | ||
| 1243 | case 30: | ||
| 1244 | track->textures[i].cpp = 4; | ||
| 1245 | break; | ||
| 1246 | case 14: | ||
| 1247 | case 26: | ||
| 1248 | case 28: | ||
| 1249 | track->textures[i].cpp = 8; | ||
| 1250 | break; | ||
| 1251 | case 29: | ||
| 1252 | track->textures[i].cpp = 16; | ||
| 1253 | break; | ||
| 1254 | default: | ||
| 1255 | DRM_ERROR("Invalid texture format %u\n", | ||
| 1256 | (ib_chunk->kdata[idx] & 0x1F)); | ||
| 1257 | return -EINVAL; | ||
| 1258 | break; | ||
| 1259 | } | ||
| 1260 | break; | ||
| 1261 | case 0x4400: | ||
| 1262 | case 0x4404: | ||
| 1263 | case 0x4408: | ||
| 1264 | case 0x440C: | ||
| 1265 | case 0x4410: | ||
| 1266 | case 0x4414: | ||
| 1267 | case 0x4418: | ||
| 1268 | case 0x441C: | ||
| 1269 | case 0x4420: | ||
| 1270 | case 0x4424: | ||
| 1271 | case 0x4428: | ||
| 1272 | case 0x442C: | ||
| 1273 | case 0x4430: | ||
| 1274 | case 0x4434: | ||
| 1275 | case 0x4438: | ||
| 1276 | case 0x443C: | ||
| 1277 | /* TX_FILTER0_[0-15] */ | ||
| 1278 | i = (reg - 0x4400) >> 2; | ||
| 1279 | tmp = ib_chunk->kdata[idx] & 0x7;; | ||
| 1280 | if (tmp == 2 || tmp == 4 || tmp == 6) { | ||
| 1281 | track->textures[i].roundup_w = false; | ||
| 1282 | } | ||
| 1283 | tmp = (ib_chunk->kdata[idx] >> 3) & 0x7;; | ||
| 1284 | if (tmp == 2 || tmp == 4 || tmp == 6) { | ||
| 1285 | track->textures[i].roundup_h = false; | ||
| 1286 | } | ||
| 1287 | break; | ||
| 1288 | case 0x4500: | ||
| 1289 | case 0x4504: | ||
| 1290 | case 0x4508: | ||
| 1291 | case 0x450C: | ||
| 1292 | case 0x4510: | ||
| 1293 | case 0x4514: | ||
| 1294 | case 0x4518: | ||
| 1295 | case 0x451C: | ||
| 1296 | case 0x4520: | ||
| 1297 | case 0x4524: | ||
| 1298 | case 0x4528: | ||
| 1299 | case 0x452C: | ||
| 1300 | case 0x4530: | ||
| 1301 | case 0x4534: | ||
| 1302 | case 0x4538: | ||
| 1303 | case 0x453C: | ||
| 1304 | /* TX_FORMAT2_[0-15] */ | ||
| 1305 | i = (reg - 0x4500) >> 2; | ||
| 1306 | tmp = ib_chunk->kdata[idx] & 0x3FFF; | ||
| 1307 | track->textures[i].pitch = tmp + 1; | ||
| 1308 | if (p->rdev->family >= CHIP_RV515) { | ||
| 1309 | tmp = ((ib_chunk->kdata[idx] >> 15) & 1) << 11; | ||
| 1310 | track->textures[i].width_11 = tmp; | ||
| 1311 | tmp = ((ib_chunk->kdata[idx] >> 16) & 1) << 11; | ||
| 1312 | track->textures[i].height_11 = tmp; | ||
| 1313 | } | ||
| 1314 | break; | ||
| 1315 | case 0x4480: | ||
| 1316 | case 0x4484: | ||
| 1317 | case 0x4488: | ||
| 1318 | case 0x448C: | ||
| 1319 | case 0x4490: | ||
| 1320 | case 0x4494: | ||
| 1321 | case 0x4498: | ||
| 1322 | case 0x449C: | ||
| 1323 | case 0x44A0: | ||
| 1324 | case 0x44A4: | ||
| 1325 | case 0x44A8: | ||
| 1326 | case 0x44AC: | ||
| 1327 | case 0x44B0: | ||
| 1328 | case 0x44B4: | ||
| 1329 | case 0x44B8: | ||
| 1330 | case 0x44BC: | ||
| 1331 | /* TX_FORMAT0_[0-15] */ | ||
| 1332 | i = (reg - 0x4480) >> 2; | ||
| 1333 | tmp = ib_chunk->kdata[idx] & 0x7FF; | ||
| 1334 | track->textures[i].width = tmp + 1; | ||
| 1335 | tmp = (ib_chunk->kdata[idx] >> 11) & 0x7FF; | ||
| 1336 | track->textures[i].height = tmp + 1; | ||
| 1337 | tmp = (ib_chunk->kdata[idx] >> 26) & 0xF; | ||
| 1338 | track->textures[i].num_levels = tmp; | ||
| 1339 | tmp = ib_chunk->kdata[idx] & (1 << 31); | ||
| 1340 | track->textures[i].use_pitch = !!tmp; | ||
| 1341 | tmp = (ib_chunk->kdata[idx] >> 22) & 0xF; | ||
| 1342 | track->textures[i].txdepth = tmp; | ||
| 1343 | break; | ||
| 997 | default: | 1344 | default: |
| 998 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", reg, idx); | 1345 | printk(KERN_ERR "Forbidden register 0x%04X in cs at %d\n", |
| 1346 | reg, idx); | ||
| 999 | return -EINVAL; | 1347 | return -EINVAL; |
| 1000 | } | 1348 | } |
| 1001 | return 0; | 1349 | return 0; |
| @@ -1015,11 +1363,12 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1015 | ib = p->ib->ptr; | 1363 | ib = p->ib->ptr; |
| 1016 | ib_chunk = &p->chunks[p->chunk_ib_idx]; | 1364 | ib_chunk = &p->chunks[p->chunk_ib_idx]; |
| 1017 | idx = pkt->idx + 1; | 1365 | idx = pkt->idx + 1; |
| 1018 | track = (struct r300_cs_track *)p->track; | 1366 | track = (struct r300_cs_track*)p->track; |
| 1019 | switch (pkt->opcode) { | 1367 | switch(pkt->opcode) { |
| 1020 | case PACKET3_3D_LOAD_VBPNTR: | 1368 | case PACKET3_3D_LOAD_VBPNTR: |
| 1021 | c = ib_chunk->kdata[idx++]; | 1369 | c = ib_chunk->kdata[idx++] & 0x1F; |
| 1022 | for (i = 0; i < (c - 1); i += 2, idx += 3) { | 1370 | track->num_arrays = c; |
| 1371 | for (i = 0; i < (c - 1); i+=2, idx+=3) { | ||
| 1023 | r = r100_cs_packet_next_reloc(p, &reloc); | 1372 | r = r100_cs_packet_next_reloc(p, &reloc); |
| 1024 | if (r) { | 1373 | if (r) { |
| 1025 | DRM_ERROR("No reloc for packet3 %d\n", | 1374 | DRM_ERROR("No reloc for packet3 %d\n", |
| @@ -1028,6 +1377,9 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1028 | return r; | 1377 | return r; |
| 1029 | } | 1378 | } |
| 1030 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | 1379 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
| 1380 | track->arrays[i + 0].robj = reloc->robj; | ||
| 1381 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; | ||
| 1382 | track->arrays[i + 0].esize &= 0x7F; | ||
| 1031 | r = r100_cs_packet_next_reloc(p, &reloc); | 1383 | r = r100_cs_packet_next_reloc(p, &reloc); |
| 1032 | if (r) { | 1384 | if (r) { |
| 1033 | DRM_ERROR("No reloc for packet3 %d\n", | 1385 | DRM_ERROR("No reloc for packet3 %d\n", |
| @@ -1036,6 +1388,9 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1036 | return r; | 1388 | return r; |
| 1037 | } | 1389 | } |
| 1038 | ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); | 1390 | ib[idx+2] = ib_chunk->kdata[idx+2] + ((u32)reloc->lobj.gpu_offset); |
| 1391 | track->arrays[i + 1].robj = reloc->robj; | ||
| 1392 | track->arrays[i + 1].esize = ib_chunk->kdata[idx] >> 24; | ||
| 1393 | track->arrays[i + 1].esize &= 0x7F; | ||
| 1039 | } | 1394 | } |
| 1040 | if (c & 1) { | 1395 | if (c & 1) { |
| 1041 | r = r100_cs_packet_next_reloc(p, &reloc); | 1396 | r = r100_cs_packet_next_reloc(p, &reloc); |
| @@ -1046,6 +1401,9 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1046 | return r; | 1401 | return r; |
| 1047 | } | 1402 | } |
| 1048 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | 1403 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
| 1404 | track->arrays[i + 0].robj = reloc->robj; | ||
| 1405 | track->arrays[i + 0].esize = ib_chunk->kdata[idx] >> 8; | ||
| 1406 | track->arrays[i + 0].esize &= 0x7F; | ||
| 1049 | } | 1407 | } |
| 1050 | break; | 1408 | break; |
| 1051 | case PACKET3_INDX_BUFFER: | 1409 | case PACKET3_INDX_BUFFER: |
| @@ -1056,14 +1414,65 @@ static int r300_packet3_check(struct radeon_cs_parser *p, | |||
| 1056 | return r; | 1414 | return r; |
| 1057 | } | 1415 | } |
| 1058 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); | 1416 | ib[idx+1] = ib_chunk->kdata[idx+1] + ((u32)reloc->lobj.gpu_offset); |
| 1417 | r = r100_cs_track_check_pkt3_indx_buffer(p, pkt, reloc->robj); | ||
| 1418 | if (r) { | ||
| 1419 | return r; | ||
| 1420 | } | ||
| 1059 | break; | 1421 | break; |
| 1060 | /* Draw packet */ | 1422 | /* Draw packet */ |
| 1061 | case PACKET3_3D_DRAW_VBUF: | ||
| 1062 | case PACKET3_3D_DRAW_IMMD: | 1423 | case PACKET3_3D_DRAW_IMMD: |
| 1063 | case PACKET3_3D_DRAW_INDX: | 1424 | /* Number of dwords is vtx_size * (num_vertices - 1) |
| 1064 | case PACKET3_3D_DRAW_VBUF_2: | 1425 | * PRIM_WALK must be equal to 3 vertex data in embedded |
| 1426 | * in cmd stream */ | ||
| 1427 | if (((ib_chunk->kdata[idx+1] >> 4) & 0x3) != 3) { | ||
| 1428 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); | ||
| 1429 | return -EINVAL; | ||
| 1430 | } | ||
| 1431 | track->vap_vf_cntl = ib_chunk->kdata[idx+1]; | ||
| 1432 | track->immd_dwords = pkt->count - 1; | ||
| 1433 | r = r300_cs_track_check(p->rdev, track); | ||
| 1434 | if (r) { | ||
| 1435 | return r; | ||
| 1436 | } | ||
| 1437 | break; | ||
| 1065 | case PACKET3_3D_DRAW_IMMD_2: | 1438 | case PACKET3_3D_DRAW_IMMD_2: |
| 1439 | /* Number of dwords is vtx_size * (num_vertices - 1) | ||
| 1440 | * PRIM_WALK must be equal to 3 vertex data in embedded | ||
| 1441 | * in cmd stream */ | ||
| 1442 | if (((ib_chunk->kdata[idx] >> 4) & 0x3) != 3) { | ||
| 1443 | DRM_ERROR("PRIM_WALK must be 3 for IMMD draw\n"); | ||
| 1444 | return -EINVAL; | ||
| 1445 | } | ||
| 1446 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | ||
| 1447 | track->immd_dwords = pkt->count; | ||
| 1448 | r = r300_cs_track_check(p->rdev, track); | ||
| 1449 | if (r) { | ||
| 1450 | return r; | ||
| 1451 | } | ||
| 1452 | break; | ||
| 1453 | case PACKET3_3D_DRAW_VBUF: | ||
| 1454 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; | ||
| 1455 | r = r300_cs_track_check(p->rdev, track); | ||
| 1456 | if (r) { | ||
| 1457 | return r; | ||
| 1458 | } | ||
| 1459 | break; | ||
| 1460 | case PACKET3_3D_DRAW_VBUF_2: | ||
| 1461 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | ||
| 1462 | r = r300_cs_track_check(p->rdev, track); | ||
| 1463 | if (r) { | ||
| 1464 | return r; | ||
| 1465 | } | ||
| 1466 | break; | ||
| 1467 | case PACKET3_3D_DRAW_INDX: | ||
| 1468 | track->vap_vf_cntl = ib_chunk->kdata[idx + 1]; | ||
| 1469 | r = r300_cs_track_check(p->rdev, track); | ||
| 1470 | if (r) { | ||
| 1471 | return r; | ||
| 1472 | } | ||
| 1473 | break; | ||
| 1066 | case PACKET3_3D_DRAW_INDX_2: | 1474 | case PACKET3_3D_DRAW_INDX_2: |
| 1475 | track->vap_vf_cntl = ib_chunk->kdata[idx]; | ||
| 1067 | r = r300_cs_track_check(p->rdev, track); | 1476 | r = r300_cs_track_check(p->rdev, track); |
| 1068 | if (r) { | 1477 | if (r) { |
| 1069 | return r; | 1478 | return r; |
| @@ -1095,8 +1504,8 @@ int r300_cs_parse(struct radeon_cs_parser *p) | |||
| 1095 | switch (pkt.type) { | 1504 | switch (pkt.type) { |
| 1096 | case PACKET_TYPE0: | 1505 | case PACKET_TYPE0: |
| 1097 | r = r100_cs_parse_packet0(p, &pkt, | 1506 | r = r100_cs_parse_packet0(p, &pkt, |
| 1098 | r300_auth_reg, | 1507 | p->rdev->config.r300.reg_safe_bm, |
| 1099 | ARRAY_SIZE(r300_auth_reg), | 1508 | p->rdev->config.r300.reg_safe_bm_size, |
| 1100 | &r300_packet0_check); | 1509 | &r300_packet0_check); |
| 1101 | break; | 1510 | break; |
| 1102 | case PACKET_TYPE2: | 1511 | case PACKET_TYPE2: |
| @@ -1114,3 +1523,10 @@ int r300_cs_parse(struct radeon_cs_parser *p) | |||
| 1114 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); | 1523 | } while (p->idx < p->chunks[p->chunk_ib_idx].length_dw); |
| 1115 | return 0; | 1524 | return 0; |
| 1116 | } | 1525 | } |
| 1526 | |||
| 1527 | int r300_init(struct radeon_device *rdev) | ||
| 1528 | { | ||
| 1529 | rdev->config.r300.reg_safe_bm = r300_reg_safe_bm; | ||
| 1530 | rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r300_reg_safe_bm); | ||
| 1531 | return 0; | ||
| 1532 | } | ||
diff --git a/drivers/gpu/drm/radeon/r300.h b/drivers/gpu/drm/radeon/r300.h new file mode 100644 index 000000000000..8486b4da9d69 --- /dev/null +++ b/drivers/gpu/drm/radeon/r300.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2008 Advanced Micro Devices, Inc. | ||
| 3 | * Copyright 2008 Red Hat Inc. | ||
| 4 | * Copyright 2009 Jerome Glisse. | ||
| 5 | * | ||
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 7 | * copy of this software and associated documentation files (the "Software"), | ||
| 8 | * to deal in the Software without restriction, including without limitation | ||
| 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 11 | * Software is furnished to do so, subject to the following conditions: | ||
| 12 | * | ||
| 13 | * The above copyright notice and this permission notice shall be included in | ||
| 14 | * all copies or substantial portions of the Software. | ||
| 15 | * | ||
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 19 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 20 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 21 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 22 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 23 | * | ||
| 24 | * Authors: Dave Airlie | ||
| 25 | * Alex Deucher | ||
| 26 | * Jerome Glisse | ||
| 27 | */ | ||
| 28 | #ifndef R300_H | ||
| 29 | #define R300_H | ||
| 30 | |||
| 31 | struct r300_asic { | ||
| 32 | const unsigned *reg_safe_bm; | ||
| 33 | unsigned reg_safe_bm_size; | ||
| 34 | }; | ||
| 35 | |||
| 36 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index c3f24cc56009..d61f2fc61df5 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | 51 | ||
| 52 | #include "radeon_mode.h" | 52 | #include "radeon_mode.h" |
| 53 | #include "radeon_reg.h" | 53 | #include "radeon_reg.h" |
| 54 | 54 | #include "r300.h" | |
| 55 | 55 | ||
| 56 | /* | 56 | /* |
| 57 | * Modules parameters. | 57 | * Modules parameters. |
| @@ -496,6 +496,7 @@ int r100_debugfs_cp_init(struct radeon_device *rdev); | |||
| 496 | * ASIC specific functions. | 496 | * ASIC specific functions. |
| 497 | */ | 497 | */ |
| 498 | struct radeon_asic { | 498 | struct radeon_asic { |
| 499 | int (*init)(struct radeon_device *rdev); | ||
| 499 | void (*errata)(struct radeon_device *rdev); | 500 | void (*errata)(struct radeon_device *rdev); |
| 500 | void (*vram_info)(struct radeon_device *rdev); | 501 | void (*vram_info)(struct radeon_device *rdev); |
| 501 | int (*gpu_reset)(struct radeon_device *rdev); | 502 | int (*gpu_reset)(struct radeon_device *rdev); |
| @@ -536,6 +537,10 @@ struct radeon_asic { | |||
| 536 | void (*set_clock_gating)(struct radeon_device *rdev, int enable); | 537 | void (*set_clock_gating)(struct radeon_device *rdev, int enable); |
| 537 | }; | 538 | }; |
| 538 | 539 | ||
| 540 | union radeon_asic_config { | ||
| 541 | struct r300_asic r300; | ||
| 542 | }; | ||
| 543 | |||
| 539 | 544 | ||
| 540 | /* | 545 | /* |
| 541 | * IOCTL. | 546 | * IOCTL. |
| @@ -573,6 +578,7 @@ struct radeon_device { | |||
| 573 | struct drm_device *ddev; | 578 | struct drm_device *ddev; |
| 574 | struct pci_dev *pdev; | 579 | struct pci_dev *pdev; |
| 575 | /* ASIC */ | 580 | /* ASIC */ |
| 581 | union radeon_asic_config config; | ||
| 576 | enum radeon_family family; | 582 | enum radeon_family family; |
| 577 | unsigned long flags; | 583 | unsigned long flags; |
| 578 | int usec_timeout; | 584 | int usec_timeout; |
| @@ -763,6 +769,7 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) | |||
| 763 | /* | 769 | /* |
| 764 | * ASICs macro. | 770 | * ASICs macro. |
| 765 | */ | 771 | */ |
| 772 | #define radeon_init(rdev) (rdev)->asic->init((rdev)) | ||
| 766 | #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) | 773 | #define radeon_cs_parse(p) rdev->asic->cs_parse((p)) |
| 767 | #define radeon_errata(rdev) (rdev)->asic->errata((rdev)) | 774 | #define radeon_errata(rdev) (rdev)->asic->errata((rdev)) |
| 768 | #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev)) | 775 | #define radeon_vram_info(rdev) (rdev)->asic->vram_info((rdev)) |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index e57d8a784e9f..e2e567395df8 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
| @@ -41,6 +41,7 @@ void radeon_atom_set_clock_gating(struct radeon_device *rdev, int enable); | |||
| 41 | /* | 41 | /* |
| 42 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | 42 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
| 43 | */ | 43 | */ |
| 44 | int r100_init(struct radeon_device *rdev); | ||
| 44 | uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); | 45 | uint32_t r100_mm_rreg(struct radeon_device *rdev, uint32_t reg); |
| 45 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 46 | void r100_mm_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 46 | void r100_errata(struct radeon_device *rdev); | 47 | void r100_errata(struct radeon_device *rdev); |
| @@ -72,6 +73,7 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
| 72 | struct radeon_fence *fence); | 73 | struct radeon_fence *fence); |
| 73 | 74 | ||
| 74 | static struct radeon_asic r100_asic = { | 75 | static struct radeon_asic r100_asic = { |
| 76 | .init = &r100_init, | ||
| 75 | .errata = &r100_errata, | 77 | .errata = &r100_errata, |
| 76 | .vram_info = &r100_vram_info, | 78 | .vram_info = &r100_vram_info, |
| 77 | .gpu_reset = &r100_gpu_reset, | 79 | .gpu_reset = &r100_gpu_reset, |
| @@ -104,6 +106,7 @@ static struct radeon_asic r100_asic = { | |||
| 104 | /* | 106 | /* |
| 105 | * r300,r350,rv350,rv380 | 107 | * r300,r350,rv350,rv380 |
| 106 | */ | 108 | */ |
| 109 | int r300_init(struct radeon_device *rdev); | ||
| 107 | void r300_errata(struct radeon_device *rdev); | 110 | void r300_errata(struct radeon_device *rdev); |
| 108 | void r300_vram_info(struct radeon_device *rdev); | 111 | void r300_vram_info(struct radeon_device *rdev); |
| 109 | int r300_gpu_reset(struct radeon_device *rdev); | 112 | int r300_gpu_reset(struct radeon_device *rdev); |
| @@ -126,6 +129,7 @@ int r300_copy_dma(struct radeon_device *rdev, | |||
| 126 | unsigned num_pages, | 129 | unsigned num_pages, |
| 127 | struct radeon_fence *fence); | 130 | struct radeon_fence *fence); |
| 128 | static struct radeon_asic r300_asic = { | 131 | static struct radeon_asic r300_asic = { |
| 132 | .init = &r300_init, | ||
| 129 | .errata = &r300_errata, | 133 | .errata = &r300_errata, |
| 130 | .vram_info = &r300_vram_info, | 134 | .vram_info = &r300_vram_info, |
| 131 | .gpu_reset = &r300_gpu_reset, | 135 | .gpu_reset = &r300_gpu_reset, |
| @@ -162,6 +166,7 @@ void r420_vram_info(struct radeon_device *rdev); | |||
| 162 | int r420_mc_init(struct radeon_device *rdev); | 166 | int r420_mc_init(struct radeon_device *rdev); |
| 163 | void r420_mc_fini(struct radeon_device *rdev); | 167 | void r420_mc_fini(struct radeon_device *rdev); |
| 164 | static struct radeon_asic r420_asic = { | 168 | static struct radeon_asic r420_asic = { |
| 169 | .init = &r300_init, | ||
| 165 | .errata = &r420_errata, | 170 | .errata = &r420_errata, |
| 166 | .vram_info = &r420_vram_info, | 171 | .vram_info = &r420_vram_info, |
| 167 | .gpu_reset = &r300_gpu_reset, | 172 | .gpu_reset = &r300_gpu_reset, |
| @@ -205,6 +210,7 @@ int rs400_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | |||
| 205 | uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 210 | uint32_t rs400_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 206 | void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 211 | void rs400_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 207 | static struct radeon_asic rs400_asic = { | 212 | static struct radeon_asic rs400_asic = { |
| 213 | .init = &r300_init, | ||
| 208 | .errata = &rs400_errata, | 214 | .errata = &rs400_errata, |
| 209 | .vram_info = &rs400_vram_info, | 215 | .vram_info = &rs400_vram_info, |
| 210 | .gpu_reset = &r300_gpu_reset, | 216 | .gpu_reset = &r300_gpu_reset, |
| @@ -249,6 +255,7 @@ int rs600_gart_set_page(struct radeon_device *rdev, int i, uint64_t addr); | |||
| 249 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 255 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 250 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 256 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 251 | static struct radeon_asic rs600_asic = { | 257 | static struct radeon_asic rs600_asic = { |
| 258 | .init = &r300_init, | ||
| 252 | .errata = &rs600_errata, | 259 | .errata = &rs600_errata, |
| 253 | .vram_info = &rs600_vram_info, | 260 | .vram_info = &rs600_vram_info, |
| 254 | .gpu_reset = &r300_gpu_reset, | 261 | .gpu_reset = &r300_gpu_reset, |
| @@ -288,6 +295,7 @@ void rs690_mc_fini(struct radeon_device *rdev); | |||
| 288 | uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 295 | uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
| 289 | void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 296 | void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 290 | static struct radeon_asic rs690_asic = { | 297 | static struct radeon_asic rs690_asic = { |
| 298 | .init = &r300_init, | ||
| 291 | .errata = &rs690_errata, | 299 | .errata = &rs690_errata, |
| 292 | .vram_info = &rs690_vram_info, | 300 | .vram_info = &rs690_vram_info, |
| 293 | .gpu_reset = &r300_gpu_reset, | 301 | .gpu_reset = &r300_gpu_reset, |
| @@ -320,6 +328,7 @@ static struct radeon_asic rs690_asic = { | |||
| 320 | /* | 328 | /* |
| 321 | * rv515 | 329 | * rv515 |
| 322 | */ | 330 | */ |
| 331 | int rv515_init(struct radeon_device *rdev); | ||
| 323 | void rv515_errata(struct radeon_device *rdev); | 332 | void rv515_errata(struct radeon_device *rdev); |
| 324 | void rv515_vram_info(struct radeon_device *rdev); | 333 | void rv515_vram_info(struct radeon_device *rdev); |
| 325 | int rv515_gpu_reset(struct radeon_device *rdev); | 334 | int rv515_gpu_reset(struct radeon_device *rdev); |
| @@ -331,6 +340,7 @@ void rv515_ring_start(struct radeon_device *rdev); | |||
| 331 | uint32_t rv515_pcie_rreg(struct radeon_device *rdev, uint32_t reg); | 340 | uint32_t rv515_pcie_rreg(struct radeon_device *rdev, uint32_t reg); |
| 332 | void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | 341 | void rv515_pcie_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); |
| 333 | static struct radeon_asic rv515_asic = { | 342 | static struct radeon_asic rv515_asic = { |
| 343 | .init = &rv515_init, | ||
| 334 | .errata = &rv515_errata, | 344 | .errata = &rv515_errata, |
| 335 | .vram_info = &rv515_vram_info, | 345 | .vram_info = &rv515_vram_info, |
| 336 | .gpu_reset = &rv515_gpu_reset, | 346 | .gpu_reset = &rv515_gpu_reset, |
| @@ -349,7 +359,7 @@ static struct radeon_asic rv515_asic = { | |||
| 349 | .irq_set = &r100_irq_set, | 359 | .irq_set = &r100_irq_set, |
| 350 | .irq_process = &r100_irq_process, | 360 | .irq_process = &r100_irq_process, |
| 351 | .fence_ring_emit = &r300_fence_ring_emit, | 361 | .fence_ring_emit = &r300_fence_ring_emit, |
| 352 | .cs_parse = &r100_cs_parse, | 362 | .cs_parse = &r300_cs_parse, |
| 353 | .copy_blit = &r100_copy_blit, | 363 | .copy_blit = &r100_copy_blit, |
| 354 | .copy_dma = &r300_copy_dma, | 364 | .copy_dma = &r300_copy_dma, |
| 355 | .copy = &r100_copy_blit, | 365 | .copy = &r100_copy_blit, |
| @@ -368,6 +378,7 @@ void r520_vram_info(struct radeon_device *rdev); | |||
| 368 | int r520_mc_init(struct radeon_device *rdev); | 378 | int r520_mc_init(struct radeon_device *rdev); |
| 369 | void r520_mc_fini(struct radeon_device *rdev); | 379 | void r520_mc_fini(struct radeon_device *rdev); |
| 370 | static struct radeon_asic r520_asic = { | 380 | static struct radeon_asic r520_asic = { |
| 381 | .init = &rv515_init, | ||
| 371 | .errata = &r520_errata, | 382 | .errata = &r520_errata, |
| 372 | .vram_info = &r520_vram_info, | 383 | .vram_info = &r520_vram_info, |
| 373 | .gpu_reset = &rv515_gpu_reset, | 384 | .gpu_reset = &rv515_gpu_reset, |
| @@ -386,7 +397,7 @@ static struct radeon_asic r520_asic = { | |||
| 386 | .irq_set = &r100_irq_set, | 397 | .irq_set = &r100_irq_set, |
| 387 | .irq_process = &r100_irq_process, | 398 | .irq_process = &r100_irq_process, |
| 388 | .fence_ring_emit = &r300_fence_ring_emit, | 399 | .fence_ring_emit = &r300_fence_ring_emit, |
| 389 | .cs_parse = &r100_cs_parse, | 400 | .cs_parse = &r300_cs_parse, |
| 390 | .copy_blit = &r100_copy_blit, | 401 | .copy_blit = &r100_copy_blit, |
| 391 | .copy_dma = &r300_copy_dma, | 402 | .copy_dma = &r300_copy_dma, |
| 392 | .copy = &r100_copy_blit, | 403 | .copy = &r100_copy_blit, |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 786632d3e378..1f5a1a490984 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
| @@ -835,7 +835,6 @@ radeon_atombios_get_primary_dac_info(struct radeon_encoder *encoder) | |||
| 835 | struct _COMPASSIONATE_DATA *dac_info; | 835 | struct _COMPASSIONATE_DATA *dac_info; |
| 836 | uint8_t frev, crev; | 836 | uint8_t frev, crev; |
| 837 | uint8_t bg, dac; | 837 | uint8_t bg, dac; |
| 838 | int i; | ||
| 839 | struct radeon_encoder_primary_dac *p_dac = NULL; | 838 | struct radeon_encoder_primary_dac *p_dac = NULL; |
| 840 | 839 | ||
| 841 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | 840 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); |
| @@ -867,7 +866,6 @@ radeon_atombios_get_tv_dac_info(struct radeon_encoder *encoder) | |||
| 867 | struct _COMPASSIONATE_DATA *dac_info; | 866 | struct _COMPASSIONATE_DATA *dac_info; |
| 868 | uint8_t frev, crev; | 867 | uint8_t frev, crev; |
| 869 | uint8_t bg, dac; | 868 | uint8_t bg, dac; |
| 870 | int i; | ||
| 871 | struct radeon_encoder_tv_dac *tv_dac = NULL; | 869 | struct radeon_encoder_tv_dac *tv_dac = NULL; |
| 872 | 870 | ||
| 873 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); | 871 | atom_parse_data_header(mode_info->atom_context, index, NULL, &frev, &crev, &data_offset); |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 06e8038bc4ac..afc4db280b94 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
| @@ -799,6 +799,7 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct | |||
| 799 | struct radeon_encoder_lvds *lvds = NULL; | 799 | struct radeon_encoder_lvds *lvds = NULL; |
| 800 | uint32_t fp_vert_stretch, fp_horz_stretch; | 800 | uint32_t fp_vert_stretch, fp_horz_stretch; |
| 801 | uint32_t ppll_div_sel, ppll_val; | 801 | uint32_t ppll_div_sel, ppll_val; |
| 802 | uint32_t lvds_ss_gen_cntl = RREG32(RADEON_LVDS_SS_GEN_CNTL); | ||
| 802 | 803 | ||
| 803 | lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL); | 804 | lvds = kzalloc(sizeof(struct radeon_encoder_lvds), GFP_KERNEL); |
| 804 | 805 | ||
| @@ -808,6 +809,14 @@ static struct radeon_encoder_lvds *radeon_legacy_get_lvds_info_from_regs(struct | |||
| 808 | fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH); | 809 | fp_vert_stretch = RREG32(RADEON_FP_VERT_STRETCH); |
| 809 | fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH); | 810 | fp_horz_stretch = RREG32(RADEON_FP_HORZ_STRETCH); |
| 810 | 811 | ||
| 812 | /* These should be fail-safe defaults, fingers crossed */ | ||
| 813 | lvds->panel_pwr_delay = 200; | ||
| 814 | lvds->panel_vcc_delay = 2000; | ||
| 815 | |||
| 816 | lvds->lvds_gen_cntl = RREG32(RADEON_LVDS_GEN_CNTL); | ||
| 817 | lvds->panel_digon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY1_SHIFT) & 0xf; | ||
| 818 | lvds->panel_blon_delay = (lvds_ss_gen_cntl >> RADEON_LVDS_PWRSEQ_DELAY2_SHIFT) & 0xf; | ||
| 819 | |||
| 811 | if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) | 820 | if (fp_vert_stretch & RADEON_VERT_STRETCH_ENABLE) |
| 812 | lvds->native_mode.panel_yres = | 821 | lvds->native_mode.panel_yres = |
| 813 | ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> | 822 | ((fp_vert_stretch & RADEON_VERT_PANEL_SIZE) >> |
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 89c4c44169f7..d8356827ef17 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
| @@ -2045,11 +2045,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) | |||
| 2045 | drm_radeon_private_t *dev_priv; | 2045 | drm_radeon_private_t *dev_priv; |
| 2046 | int ret = 0; | 2046 | int ret = 0; |
| 2047 | 2047 | ||
| 2048 | dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER); | 2048 | dev_priv = kzalloc(sizeof(drm_radeon_private_t), GFP_KERNEL); |
| 2049 | if (dev_priv == NULL) | 2049 | if (dev_priv == NULL) |
| 2050 | return -ENOMEM; | 2050 | return -ENOMEM; |
| 2051 | 2051 | ||
| 2052 | memset(dev_priv, 0, sizeof(drm_radeon_private_t)); | ||
| 2053 | dev->dev_private = (void *)dev_priv; | 2052 | dev->dev_private = (void *)dev_priv; |
| 2054 | dev_priv->flags = flags; | 2053 | dev_priv->flags = flags; |
| 2055 | 2054 | ||
| @@ -2103,7 +2102,7 @@ int radeon_master_create(struct drm_device *dev, struct drm_master *master) | |||
| 2103 | unsigned long sareapage; | 2102 | unsigned long sareapage; |
| 2104 | int ret; | 2103 | int ret; |
| 2105 | 2104 | ||
| 2106 | master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER); | 2105 | master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL); |
| 2107 | if (!master_priv) | 2106 | if (!master_priv) |
| 2108 | return -ENOMEM; | 2107 | return -ENOMEM; |
| 2109 | 2108 | ||
| @@ -2137,7 +2136,7 @@ void radeon_master_destroy(struct drm_device *dev, struct drm_master *master) | |||
| 2137 | if (master_priv->sarea) | 2136 | if (master_priv->sarea) |
| 2138 | drm_rmmap_locked(dev, master_priv->sarea); | 2137 | drm_rmmap_locked(dev, master_priv->sarea); |
| 2139 | 2138 | ||
| 2140 | drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); | 2139 | kfree(master_priv); |
| 2141 | 2140 | ||
| 2142 | master->driver_priv = NULL; | 2141 | master->driver_priv = NULL; |
| 2143 | } | 2142 | } |
| @@ -2171,7 +2170,7 @@ int radeon_driver_unload(struct drm_device *dev) | |||
| 2171 | 2170 | ||
| 2172 | drm_rmmap(dev, dev_priv->mmio); | 2171 | drm_rmmap(dev, dev_priv->mmio); |
| 2173 | 2172 | ||
| 2174 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); | 2173 | kfree(dev_priv); |
| 2175 | 2174 | ||
| 2176 | dev->dev_private = NULL; | 2175 | dev->dev_private = NULL; |
| 2177 | return 0; | 2176 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 5fd2b639bf66..f30aa7274a54 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -470,6 +470,10 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 470 | if (r) { | 470 | if (r) { |
| 471 | return r; | 471 | return r; |
| 472 | } | 472 | } |
| 473 | r = radeon_init(rdev); | ||
| 474 | if (r) { | ||
| 475 | return r; | ||
| 476 | } | ||
| 473 | 477 | ||
| 474 | /* Report DMA addressing limitation */ | 478 | /* Report DMA addressing limitation */ |
| 475 | r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(32)); | 479 | r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(32)); |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 5452bb9d925e..3efcf1a526be 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
| @@ -351,7 +351,7 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) | |||
| 351 | radeon_i2c_do_lock(radeon_connector, 0); | 351 | radeon_i2c_do_lock(radeon_connector, 0); |
| 352 | if (edid) { | 352 | if (edid) { |
| 353 | /* update digital bits here */ | 353 | /* update digital bits here */ |
| 354 | if (edid->digital) | 354 | if (edid->input & DRM_EDID_INPUT_DIGITAL) |
| 355 | radeon_connector->use_digital = 1; | 355 | radeon_connector->use_digital = 1; |
| 356 | else | 356 | else |
| 357 | radeon_connector->use_digital = 0; | 357 | radeon_connector->use_digital = 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index c815a2cbf7b3..09c9fb9f6210 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
| @@ -313,7 +313,7 @@ static int __init radeon_init(void) | |||
| 313 | { | 313 | { |
| 314 | driver = &driver_old; | 314 | driver = &driver_old; |
| 315 | driver->num_ioctls = radeon_max_ioctl; | 315 | driver->num_ioctls = radeon_max_ioctl; |
| 316 | #if defined(CONFIG_DRM_RADEON_KMS) && defined(CONFIG_X86) | 316 | #if defined(CONFIG_DRM_RADEON_KMS) |
| 317 | /* if enabled by default */ | 317 | /* if enabled by default */ |
| 318 | if (radeon_modeset == -1) { | 318 | if (radeon_modeset == -1) { |
| 319 | DRM_INFO("radeon default to kernel modesetting.\n"); | 319 | DRM_INFO("radeon default to kernel modesetting.\n"); |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 71465ed2688a..dd438d32e5c0 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
| @@ -162,7 +162,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
| 162 | struct radeon_i2c_chan *i2c; | 162 | struct radeon_i2c_chan *i2c; |
| 163 | int ret; | 163 | int ret; |
| 164 | 164 | ||
| 165 | i2c = drm_calloc(1, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER); | 165 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); |
| 166 | if (i2c == NULL) | 166 | if (i2c == NULL) |
| 167 | return NULL; | 167 | return NULL; |
| 168 | 168 | ||
| @@ -189,7 +189,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
| 189 | 189 | ||
| 190 | return i2c; | 190 | return i2c; |
| 191 | out_free: | 191 | out_free: |
| 192 | drm_free(i2c, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER); | 192 | kfree(i2c); |
| 193 | return NULL; | 193 | return NULL; |
| 194 | 194 | ||
| 195 | } | 195 | } |
| @@ -200,7 +200,7 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) | |||
| 200 | return; | 200 | return; |
| 201 | 201 | ||
| 202 | i2c_del_adapter(&i2c->adapter); | 202 | i2c_del_adapter(&i2c->adapter); |
| 203 | drm_free(i2c, sizeof(struct radeon_i2c_chan), DRM_MEM_DRIVER); | 203 | kfree(i2c); |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) | 206 | struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 64f42b19cbfa..4612a7c146d1 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
| @@ -169,7 +169,7 @@ int radeon_master_create_kms(struct drm_device *dev, struct drm_master *master) | |||
| 169 | unsigned long sareapage; | 169 | unsigned long sareapage; |
| 170 | int ret; | 170 | int ret; |
| 171 | 171 | ||
| 172 | master_priv = drm_calloc(1, sizeof(*master_priv), DRM_MEM_DRIVER); | 172 | master_priv = kzalloc(sizeof(*master_priv), GFP_KERNEL); |
| 173 | if (master_priv == NULL) { | 173 | if (master_priv == NULL) { |
| 174 | return -ENOMEM; | 174 | return -ENOMEM; |
| 175 | } | 175 | } |
| @@ -199,7 +199,7 @@ void radeon_master_destroy_kms(struct drm_device *dev, | |||
| 199 | if (master_priv->sarea) { | 199 | if (master_priv->sarea) { |
| 200 | drm_rmmap_locked(dev, master_priv->sarea); | 200 | drm_rmmap_locked(dev, master_priv->sarea); |
| 201 | } | 201 | } |
| 202 | drm_free(master_priv, sizeof(*master_priv), DRM_MEM_DRIVER); | 202 | kfree(master_priv); |
| 203 | master->driver_priv = NULL; | 203 | master->driver_priv = NULL; |
| 204 | } | 204 | } |
| 205 | 205 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_mem.c b/drivers/gpu/drm/radeon/radeon_mem.c index 4af5286a36fb..ed95155c4b1d 100644 --- a/drivers/gpu/drm/radeon/radeon_mem.c +++ b/drivers/gpu/drm/radeon/radeon_mem.c | |||
| @@ -43,8 +43,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, | |||
| 43 | { | 43 | { |
| 44 | /* Maybe cut off the start of an existing block */ | 44 | /* Maybe cut off the start of an existing block */ |
| 45 | if (start > p->start) { | 45 | if (start > p->start) { |
| 46 | struct mem_block *newblock = | 46 | struct mem_block *newblock = kmalloc(sizeof(*newblock), |
| 47 | drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); | 47 | GFP_KERNEL); |
| 48 | if (!newblock) | 48 | if (!newblock) |
| 49 | goto out; | 49 | goto out; |
| 50 | newblock->start = start; | 50 | newblock->start = start; |
| @@ -60,8 +60,8 @@ static struct mem_block *split_block(struct mem_block *p, int start, int size, | |||
| 60 | 60 | ||
| 61 | /* Maybe cut off the end of an existing block */ | 61 | /* Maybe cut off the end of an existing block */ |
| 62 | if (size < p->size) { | 62 | if (size < p->size) { |
| 63 | struct mem_block *newblock = | 63 | struct mem_block *newblock = kmalloc(sizeof(*newblock), |
| 64 | drm_alloc(sizeof(*newblock), DRM_MEM_BUFS); | 64 | GFP_KERNEL); |
| 65 | if (!newblock) | 65 | if (!newblock) |
| 66 | goto out; | 66 | goto out; |
| 67 | newblock->start = start + size; | 67 | newblock->start = start + size; |
| @@ -118,7 +118,7 @@ static void free_block(struct mem_block *p) | |||
| 118 | p->size += q->size; | 118 | p->size += q->size; |
| 119 | p->next = q->next; | 119 | p->next = q->next; |
| 120 | p->next->prev = p; | 120 | p->next->prev = p; |
| 121 | drm_free(q, sizeof(*q), DRM_MEM_BUFS); | 121 | kfree(q); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | if (p->prev->file_priv == NULL) { | 124 | if (p->prev->file_priv == NULL) { |
| @@ -126,7 +126,7 @@ static void free_block(struct mem_block *p) | |||
| 126 | q->size += p->size; | 126 | q->size += p->size; |
| 127 | q->next = p->next; | 127 | q->next = p->next; |
| 128 | q->next->prev = q; | 128 | q->next->prev = q; |
| 129 | drm_free(p, sizeof(*q), DRM_MEM_BUFS); | 129 | kfree(p); |
| 130 | } | 130 | } |
| 131 | } | 131 | } |
| 132 | 132 | ||
| @@ -134,14 +134,14 @@ static void free_block(struct mem_block *p) | |||
| 134 | */ | 134 | */ |
| 135 | static int init_heap(struct mem_block **heap, int start, int size) | 135 | static int init_heap(struct mem_block **heap, int start, int size) |
| 136 | { | 136 | { |
| 137 | struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS); | 137 | struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); |
| 138 | 138 | ||
| 139 | if (!blocks) | 139 | if (!blocks) |
| 140 | return -ENOMEM; | 140 | return -ENOMEM; |
| 141 | 141 | ||
| 142 | *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS); | 142 | *heap = kmalloc(sizeof(**heap), GFP_KERNEL); |
| 143 | if (!*heap) { | 143 | if (!*heap) { |
| 144 | drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS); | 144 | kfree(blocks); |
| 145 | return -ENOMEM; | 145 | return -ENOMEM; |
| 146 | } | 146 | } |
| 147 | 147 | ||
| @@ -179,7 +179,7 @@ void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap) | |||
| 179 | p->size += q->size; | 179 | p->size += q->size; |
| 180 | p->next = q->next; | 180 | p->next = q->next; |
| 181 | p->next->prev = p; | 181 | p->next->prev = p; |
| 182 | drm_free(q, sizeof(*q), DRM_MEM_DRIVER); | 182 | kfree(q); |
| 183 | } | 183 | } |
| 184 | } | 184 | } |
| 185 | } | 185 | } |
| @@ -196,10 +196,10 @@ void radeon_mem_takedown(struct mem_block **heap) | |||
| 196 | for (p = (*heap)->next; p != *heap;) { | 196 | for (p = (*heap)->next; p != *heap;) { |
| 197 | struct mem_block *q = p; | 197 | struct mem_block *q = p; |
| 198 | p = p->next; | 198 | p = p->next; |
| 199 | drm_free(q, sizeof(*q), DRM_MEM_DRIVER); | 199 | kfree(q); |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER); | 202 | kfree(*heap); |
| 203 | *heap = NULL; | 203 | *heap = NULL; |
| 204 | } | 204 | } |
| 205 | 205 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 6d3d90406a24..e1b618574461 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
| @@ -3184,6 +3184,7 @@ | |||
| 3184 | # define RADEON_RB_BUFSZ_MASK (0x3f << 0) | 3184 | # define RADEON_RB_BUFSZ_MASK (0x3f << 0) |
| 3185 | # define RADEON_RB_BLKSZ_SHIFT 8 | 3185 | # define RADEON_RB_BLKSZ_SHIFT 8 |
| 3186 | # define RADEON_RB_BLKSZ_MASK (0x3f << 8) | 3186 | # define RADEON_RB_BLKSZ_MASK (0x3f << 8) |
| 3187 | # define RADEON_BUF_SWAP_32BIT (1 << 17) | ||
| 3187 | # define RADEON_MAX_FETCH_SHIFT 18 | 3188 | # define RADEON_MAX_FETCH_SHIFT 18 |
| 3188 | # define RADEON_MAX_FETCH_MASK (0x3 << 18) | 3189 | # define RADEON_MAX_FETCH_MASK (0x3 << 18) |
| 3189 | # define RADEON_RB_NO_UPDATE (1 << 27) | 3190 | # define RADEON_RB_NO_UPDATE (1 << 27) |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index fa728ec6ed34..46645f3e0328 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
| @@ -2866,12 +2866,12 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file | |||
| 2866 | */ | 2866 | */ |
| 2867 | orig_bufsz = cmdbuf->bufsz; | 2867 | orig_bufsz = cmdbuf->bufsz; |
| 2868 | if (orig_bufsz != 0) { | 2868 | if (orig_bufsz != 0) { |
| 2869 | kbuf = drm_alloc(cmdbuf->bufsz, DRM_MEM_DRIVER); | 2869 | kbuf = kmalloc(cmdbuf->bufsz, GFP_KERNEL); |
| 2870 | if (kbuf == NULL) | 2870 | if (kbuf == NULL) |
| 2871 | return -ENOMEM; | 2871 | return -ENOMEM; |
| 2872 | if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf, | 2872 | if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf, |
| 2873 | cmdbuf->bufsz)) { | 2873 | cmdbuf->bufsz)) { |
| 2874 | drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); | 2874 | kfree(kbuf); |
| 2875 | return -EFAULT; | 2875 | return -EFAULT; |
| 2876 | } | 2876 | } |
| 2877 | cmdbuf->buf = kbuf; | 2877 | cmdbuf->buf = kbuf; |
| @@ -2884,7 +2884,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file | |||
| 2884 | temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); | 2884 | temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf); |
| 2885 | 2885 | ||
| 2886 | if (orig_bufsz != 0) | 2886 | if (orig_bufsz != 0) |
| 2887 | drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); | 2887 | kfree(kbuf); |
| 2888 | 2888 | ||
| 2889 | return temp; | 2889 | return temp; |
| 2890 | } | 2890 | } |
| @@ -2991,7 +2991,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file | |||
| 2991 | } | 2991 | } |
| 2992 | 2992 | ||
| 2993 | if (orig_bufsz != 0) | 2993 | if (orig_bufsz != 0) |
| 2994 | drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); | 2994 | kfree(kbuf); |
| 2995 | 2995 | ||
| 2996 | DRM_DEBUG("DONE\n"); | 2996 | DRM_DEBUG("DONE\n"); |
| 2997 | COMMIT_RING(); | 2997 | COMMIT_RING(); |
| @@ -2999,7 +2999,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file | |||
| 2999 | 2999 | ||
| 3000 | err: | 3000 | err: |
| 3001 | if (orig_bufsz != 0) | 3001 | if (orig_bufsz != 0) |
| 3002 | drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER); | 3002 | kfree(kbuf); |
| 3003 | return -EINVAL; | 3003 | return -EINVAL; |
| 3004 | } | 3004 | } |
| 3005 | 3005 | ||
| @@ -3175,9 +3175,7 @@ int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv) | |||
| 3175 | struct drm_radeon_driver_file_fields *radeon_priv; | 3175 | struct drm_radeon_driver_file_fields *radeon_priv; |
| 3176 | 3176 | ||
| 3177 | DRM_DEBUG("\n"); | 3177 | DRM_DEBUG("\n"); |
| 3178 | radeon_priv = | 3178 | radeon_priv = kmalloc(sizeof(*radeon_priv), GFP_KERNEL); |
| 3179 | (struct drm_radeon_driver_file_fields *) | ||
| 3180 | drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES); | ||
| 3181 | 3179 | ||
| 3182 | if (!radeon_priv) | 3180 | if (!radeon_priv) |
| 3183 | return -ENOMEM; | 3181 | return -ENOMEM; |
| @@ -3196,7 +3194,7 @@ void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv) | |||
| 3196 | struct drm_radeon_driver_file_fields *radeon_priv = | 3194 | struct drm_radeon_driver_file_fields *radeon_priv = |
| 3197 | file_priv->driver_priv; | 3195 | file_priv->driver_priv; |
| 3198 | 3196 | ||
| 3199 | drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES); | 3197 | kfree(radeon_priv); |
| 3200 | } | 3198 | } |
| 3201 | 3199 | ||
| 3202 | struct drm_ioctl_desc radeon_ioctls[] = { | 3200 | struct drm_ioctl_desc radeon_ioctls[] = { |
diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 4c087c1510d7..1227a97f5169 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c | |||
| @@ -133,6 +133,7 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
| 133 | man->gpu_offset = 0; | 133 | man->gpu_offset = 0; |
| 134 | man->available_caching = TTM_PL_MASK_CACHING; | 134 | man->available_caching = TTM_PL_MASK_CACHING; |
| 135 | man->default_caching = TTM_PL_FLAG_CACHED; | 135 | man->default_caching = TTM_PL_FLAG_CACHED; |
| 136 | man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | TTM_MEMTYPE_FLAG_CMA; | ||
| 136 | #if __OS_HAS_AGP | 137 | #if __OS_HAS_AGP |
| 137 | if (rdev->flags & RADEON_IS_AGP) { | 138 | if (rdev->flags & RADEON_IS_AGP) { |
| 138 | if (!(drm_core_has_AGP(rdev->ddev) && rdev->ddev->agp)) { | 139 | if (!(drm_core_has_AGP(rdev->ddev) && rdev->ddev->agp)) { |
| @@ -143,8 +144,9 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
| 143 | man->io_offset = rdev->mc.agp_base; | 144 | man->io_offset = rdev->mc.agp_base; |
| 144 | man->io_size = rdev->mc.gtt_size; | 145 | man->io_size = rdev->mc.gtt_size; |
| 145 | man->io_addr = NULL; | 146 | man->io_addr = NULL; |
| 146 | man->flags = TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | | 147 | if (!rdev->ddev->agp->cant_use_aperture) |
| 147 | TTM_MEMTYPE_FLAG_MAPPABLE; | 148 | man->flags = TTM_MEMTYPE_FLAG_NEEDS_IOREMAP | |
| 149 | TTM_MEMTYPE_FLAG_MAPPABLE; | ||
| 148 | man->available_caching = TTM_PL_FLAG_UNCACHED | | 150 | man->available_caching = TTM_PL_FLAG_UNCACHED | |
| 149 | TTM_PL_FLAG_WC; | 151 | TTM_PL_FLAG_WC; |
| 150 | man->default_caching = TTM_PL_FLAG_WC; | 152 | man->default_caching = TTM_PL_FLAG_WC; |
| @@ -154,8 +156,6 @@ static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, | |||
| 154 | man->io_offset = 0; | 156 | man->io_offset = 0; |
| 155 | man->io_size = 0; | 157 | man->io_size = 0; |
| 156 | man->io_addr = NULL; | 158 | man->io_addr = NULL; |
| 157 | man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | | ||
| 158 | TTM_MEMTYPE_FLAG_CMA; | ||
| 159 | } | 159 | } |
| 160 | break; | 160 | break; |
| 161 | case TTM_PL_VRAM: | 161 | case TTM_PL_VRAM: |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 7eab95db58ac..ffea37b1b3e2 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
| @@ -225,6 +225,8 @@ void rv515_ring_start(struct radeon_device *rdev) | |||
| 225 | radeon_ring_write(rdev, | 225 | radeon_ring_write(rdev, |
| 226 | R300_GEOMETRY_ROUND_NEAREST | | 226 | R300_GEOMETRY_ROUND_NEAREST | |
| 227 | R300_COLOR_ROUND_NEAREST); | 227 | R300_COLOR_ROUND_NEAREST); |
| 228 | radeon_ring_write(rdev, PACKET0(0x20C8, 0)); | ||
| 229 | radeon_ring_write(rdev, 0); | ||
| 228 | radeon_ring_unlock_commit(rdev); | 230 | radeon_ring_unlock_commit(rdev); |
| 229 | } | 231 | } |
| 230 | 232 | ||
| @@ -502,3 +504,59 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
| 502 | return 0; | 504 | return 0; |
| 503 | #endif | 505 | #endif |
| 504 | } | 506 | } |
| 507 | |||
| 508 | |||
| 509 | /* | ||
| 510 | * Asic initialization | ||
| 511 | */ | ||
| 512 | static const unsigned r500_reg_safe_bm[159] = { | ||
| 513 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 514 | 0xFFFFFFBF, 0xFFFFFFFF, 0xFFFFFFBF, 0xFFFFFFFF, | ||
| 515 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 516 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 517 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 518 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 519 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 520 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 521 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 522 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 523 | 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF, | ||
| 524 | 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF, | ||
| 525 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 526 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 527 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F, | ||
| 528 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 529 | 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000, | ||
| 530 | 0xF0000038, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 531 | 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF, | ||
| 532 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 533 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 534 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 535 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 536 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 537 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 538 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 539 | 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 540 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 541 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 542 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 543 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 544 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 545 | 0x1FFFFC78, 0xFFFFE000, 0xFFFFFFFE, 0xFFFFFFFF, | ||
| 546 | 0x38CF8F50, 0xFFF88082, 0xFF0000FC, 0xFAE009FF, | ||
| 547 | 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, | ||
| 548 | 0xFFFF8CFC, 0xFFFFC1FF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 549 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, | ||
| 550 | 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF, | ||
| 551 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | ||
| 552 | 0x0003FC01, 0x3FFFFCF8, 0xFE800B19, | ||
| 553 | }; | ||
| 554 | |||
| 555 | |||
| 556 | |||
| 557 | int rv515_init(struct radeon_device *rdev) | ||
| 558 | { | ||
| 559 | rdev->config.r300.reg_safe_bm = r500_reg_safe_bm; | ||
| 560 | rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(r500_reg_safe_bm); | ||
| 561 | return 0; | ||
| 562 | } | ||
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c index 456cd040f31a..bff6fc2524c8 100644 --- a/drivers/gpu/drm/savage/savage_bci.c +++ b/drivers/gpu/drm/savage/savage_bci.c | |||
| @@ -298,8 +298,8 @@ static int savage_dma_init(drm_savage_private_t * dev_priv) | |||
| 298 | 298 | ||
| 299 | dev_priv->nr_dma_pages = dev_priv->cmd_dma->size / | 299 | dev_priv->nr_dma_pages = dev_priv->cmd_dma->size / |
| 300 | (SAVAGE_DMA_PAGE_SIZE * 4); | 300 | (SAVAGE_DMA_PAGE_SIZE * 4); |
| 301 | dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) * | 301 | dev_priv->dma_pages = kmalloc(sizeof(drm_savage_dma_page_t) * |
| 302 | dev_priv->nr_dma_pages, DRM_MEM_DRIVER); | 302 | dev_priv->nr_dma_pages, GFP_KERNEL); |
| 303 | if (dev_priv->dma_pages == NULL) | 303 | if (dev_priv->dma_pages == NULL) |
| 304 | return -ENOMEM; | 304 | return -ENOMEM; |
| 305 | 305 | ||
| @@ -539,7 +539,7 @@ int savage_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 539 | { | 539 | { |
| 540 | drm_savage_private_t *dev_priv; | 540 | drm_savage_private_t *dev_priv; |
| 541 | 541 | ||
| 542 | dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER); | 542 | dev_priv = kmalloc(sizeof(drm_savage_private_t), GFP_KERNEL); |
| 543 | if (dev_priv == NULL) | 543 | if (dev_priv == NULL) |
| 544 | return -ENOMEM; | 544 | return -ENOMEM; |
| 545 | 545 | ||
| @@ -671,7 +671,7 @@ int savage_driver_unload(struct drm_device *dev) | |||
| 671 | { | 671 | { |
| 672 | drm_savage_private_t *dev_priv = dev->dev_private; | 672 | drm_savage_private_t *dev_priv = dev->dev_private; |
| 673 | 673 | ||
| 674 | drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER); | 674 | kfree(dev_priv); |
| 675 | 675 | ||
| 676 | return 0; | 676 | return 0; |
| 677 | } | 677 | } |
| @@ -804,8 +804,8 @@ static int savage_do_init_bci(struct drm_device * dev, drm_savage_init_t * init) | |||
| 804 | dev_priv->fake_dma.offset = 0; | 804 | dev_priv->fake_dma.offset = 0; |
| 805 | dev_priv->fake_dma.size = SAVAGE_FAKE_DMA_SIZE; | 805 | dev_priv->fake_dma.size = SAVAGE_FAKE_DMA_SIZE; |
| 806 | dev_priv->fake_dma.type = _DRM_SHM; | 806 | dev_priv->fake_dma.type = _DRM_SHM; |
| 807 | dev_priv->fake_dma.handle = drm_alloc(SAVAGE_FAKE_DMA_SIZE, | 807 | dev_priv->fake_dma.handle = kmalloc(SAVAGE_FAKE_DMA_SIZE, |
| 808 | DRM_MEM_DRIVER); | 808 | GFP_KERNEL); |
| 809 | if (!dev_priv->fake_dma.handle) { | 809 | if (!dev_priv->fake_dma.handle) { |
| 810 | DRM_ERROR("could not allocate faked DMA buffer!\n"); | 810 | DRM_ERROR("could not allocate faked DMA buffer!\n"); |
| 811 | savage_do_cleanup_bci(dev); | 811 | savage_do_cleanup_bci(dev); |
| @@ -903,9 +903,7 @@ static int savage_do_cleanup_bci(struct drm_device * dev) | |||
| 903 | drm_savage_private_t *dev_priv = dev->dev_private; | 903 | drm_savage_private_t *dev_priv = dev->dev_private; |
| 904 | 904 | ||
| 905 | if (dev_priv->cmd_dma == &dev_priv->fake_dma) { | 905 | if (dev_priv->cmd_dma == &dev_priv->fake_dma) { |
| 906 | if (dev_priv->fake_dma.handle) | 906 | kfree(dev_priv->fake_dma.handle); |
| 907 | drm_free(dev_priv->fake_dma.handle, | ||
| 908 | SAVAGE_FAKE_DMA_SIZE, DRM_MEM_DRIVER); | ||
| 909 | } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->handle && | 907 | } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->handle && |
| 910 | dev_priv->cmd_dma->type == _DRM_AGP && | 908 | dev_priv->cmd_dma->type == _DRM_AGP && |
| 911 | dev_priv->dma_type == SAVAGE_DMA_AGP) | 909 | dev_priv->dma_type == SAVAGE_DMA_AGP) |
| @@ -920,10 +918,7 @@ static int savage_do_cleanup_bci(struct drm_device * dev) | |||
| 920 | dev->agp_buffer_map = NULL; | 918 | dev->agp_buffer_map = NULL; |
| 921 | } | 919 | } |
| 922 | 920 | ||
| 923 | if (dev_priv->dma_pages) | 921 | kfree(dev_priv->dma_pages); |
| 924 | drm_free(dev_priv->dma_pages, | ||
| 925 | sizeof(drm_savage_dma_page_t) * dev_priv->nr_dma_pages, | ||
| 926 | DRM_MEM_DRIVER); | ||
| 927 | 922 | ||
| 928 | return 0; | 923 | return 0; |
| 929 | } | 924 | } |
diff --git a/drivers/gpu/drm/savage/savage_state.c b/drivers/gpu/drm/savage/savage_state.c index 5f6238fdf1fa..8a3e31599c94 100644 --- a/drivers/gpu/drm/savage/savage_state.c +++ b/drivers/gpu/drm/savage/savage_state.c | |||
| @@ -988,20 +988,20 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ | |||
| 988 | * for locking on FreeBSD. | 988 | * for locking on FreeBSD. |
| 989 | */ | 989 | */ |
| 990 | if (cmdbuf->size) { | 990 | if (cmdbuf->size) { |
| 991 | kcmd_addr = drm_alloc(cmdbuf->size * 8, DRM_MEM_DRIVER); | 991 | kcmd_addr = kmalloc(cmdbuf->size * 8, GFP_KERNEL); |
| 992 | if (kcmd_addr == NULL) | 992 | if (kcmd_addr == NULL) |
| 993 | return -ENOMEM; | 993 | return -ENOMEM; |
| 994 | 994 | ||
| 995 | if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf->cmd_addr, | 995 | if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf->cmd_addr, |
| 996 | cmdbuf->size * 8)) | 996 | cmdbuf->size * 8)) |
| 997 | { | 997 | { |
| 998 | drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER); | 998 | kfree(kcmd_addr); |
| 999 | return -EFAULT; | 999 | return -EFAULT; |
| 1000 | } | 1000 | } |
| 1001 | cmdbuf->cmd_addr = kcmd_addr; | 1001 | cmdbuf->cmd_addr = kcmd_addr; |
| 1002 | } | 1002 | } |
| 1003 | if (cmdbuf->vb_size) { | 1003 | if (cmdbuf->vb_size) { |
| 1004 | kvb_addr = drm_alloc(cmdbuf->vb_size, DRM_MEM_DRIVER); | 1004 | kvb_addr = kmalloc(cmdbuf->vb_size, GFP_KERNEL); |
| 1005 | if (kvb_addr == NULL) { | 1005 | if (kvb_addr == NULL) { |
| 1006 | ret = -ENOMEM; | 1006 | ret = -ENOMEM; |
| 1007 | goto done; | 1007 | goto done; |
| @@ -1015,8 +1015,8 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ | |||
| 1015 | cmdbuf->vb_addr = kvb_addr; | 1015 | cmdbuf->vb_addr = kvb_addr; |
| 1016 | } | 1016 | } |
| 1017 | if (cmdbuf->nbox) { | 1017 | if (cmdbuf->nbox) { |
| 1018 | kbox_addr = drm_alloc(cmdbuf->nbox * sizeof(struct drm_clip_rect), | 1018 | kbox_addr = kmalloc(cmdbuf->nbox * sizeof(struct drm_clip_rect), |
| 1019 | DRM_MEM_DRIVER); | 1019 | GFP_KERNEL); |
| 1020 | if (kbox_addr == NULL) { | 1020 | if (kbox_addr == NULL) { |
| 1021 | ret = -ENOMEM; | 1021 | ret = -ENOMEM; |
| 1022 | goto done; | 1022 | goto done; |
| @@ -1154,10 +1154,9 @@ int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_ | |||
| 1154 | 1154 | ||
| 1155 | done: | 1155 | done: |
| 1156 | /* If we didn't need to allocate them, these'll be NULL */ | 1156 | /* If we didn't need to allocate them, these'll be NULL */ |
| 1157 | drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER); | 1157 | kfree(kcmd_addr); |
| 1158 | drm_free(kvb_addr, cmdbuf->vb_size, DRM_MEM_DRIVER); | 1158 | kfree(kvb_addr); |
| 1159 | drm_free(kbox_addr, cmdbuf->nbox * sizeof(struct drm_clip_rect), | 1159 | kfree(kbox_addr); |
| 1160 | DRM_MEM_DRIVER); | ||
| 1161 | 1160 | ||
| 1162 | return ret; | 1161 | return ret; |
| 1163 | } | 1162 | } |
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 7dacc64e9b56..e725cc0b1155 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
| @@ -40,7 +40,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 40 | drm_sis_private_t *dev_priv; | 40 | drm_sis_private_t *dev_priv; |
| 41 | int ret; | 41 | int ret; |
| 42 | 42 | ||
| 43 | dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER); | 43 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); |
| 44 | if (dev_priv == NULL) | 44 | if (dev_priv == NULL) |
| 45 | return -ENOMEM; | 45 | return -ENOMEM; |
| 46 | 46 | ||
| @@ -48,7 +48,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 48 | dev_priv->chipset = chipset; | 48 | dev_priv->chipset = chipset; |
| 49 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); | 49 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); |
| 50 | if (ret) { | 50 | if (ret) { |
| 51 | drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER); | 51 | kfree(dev_priv); |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | return ret; | 54 | return ret; |
| @@ -59,7 +59,7 @@ static int sis_driver_unload(struct drm_device *dev) | |||
| 59 | drm_sis_private_t *dev_priv = dev->dev_private; | 59 | drm_sis_private_t *dev_priv = dev->dev_private; |
| 60 | 60 | ||
| 61 | drm_sman_takedown(&dev_priv->sman); | 61 | drm_sman_takedown(&dev_priv->sman); |
| 62 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); | 62 | kfree(dev_priv); |
| 63 | 63 | ||
| 64 | return 0; | 64 | return 0; |
| 65 | } | 65 | } |
diff --git a/drivers/gpu/drm/ttm/ttm_agp_backend.c b/drivers/gpu/drm/ttm/ttm_agp_backend.c index e8f6d2229d8c..4648ed2f0143 100644 --- a/drivers/gpu/drm/ttm/ttm_agp_backend.c +++ b/drivers/gpu/drm/ttm/ttm_agp_backend.c | |||
| @@ -63,8 +63,7 @@ static int ttm_agp_populate(struct ttm_backend *backend, | |||
| 63 | if (!page) | 63 | if (!page) |
| 64 | page = dummy_read_page; | 64 | page = dummy_read_page; |
| 65 | 65 | ||
| 66 | mem->memory[mem->page_count++] = | 66 | mem->pages[mem->page_count++] = page; |
| 67 | phys_to_gart(page_to_phys(page)); | ||
| 68 | } | 67 | } |
| 69 | agp_be->mem = mem; | 68 | agp_be->mem = mem; |
| 70 | return 0; | 69 | return 0; |
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 1587aeca7bea..c1c407f7cca3 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c | |||
| @@ -282,7 +282,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, | |||
| 282 | 282 | ||
| 283 | ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement); | 283 | ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement); |
| 284 | if (ret) | 284 | if (ret) |
| 285 | return ret; | 285 | goto out_err; |
| 286 | 286 | ||
| 287 | if (mem->mem_type != TTM_PL_SYSTEM) { | 287 | if (mem->mem_type != TTM_PL_SYSTEM) { |
| 288 | ret = ttm_tt_bind(bo->ttm, mem); | 288 | ret = ttm_tt_bind(bo->ttm, mem); |
| @@ -527,9 +527,12 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, unsigned mem_type, | |||
| 527 | ret = ttm_bo_wait(bo, false, interruptible, no_wait); | 527 | ret = ttm_bo_wait(bo, false, interruptible, no_wait); |
| 528 | spin_unlock(&bo->lock); | 528 | spin_unlock(&bo->lock); |
| 529 | 529 | ||
| 530 | if (ret && ret != -ERESTART) { | 530 | if (unlikely(ret != 0)) { |
| 531 | printk(KERN_ERR TTM_PFX "Failed to expire sync object before " | 531 | if (ret != -ERESTART) { |
| 532 | "buffer eviction.\n"); | 532 | printk(KERN_ERR TTM_PFX |
| 533 | "Failed to expire sync object before " | ||
| 534 | "buffer eviction.\n"); | ||
| 535 | } | ||
| 533 | goto out; | 536 | goto out; |
| 534 | } | 537 | } |
| 535 | 538 | ||
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c index c27ab3a877ad..0331fa74cd3f 100644 --- a/drivers/gpu/drm/ttm/ttm_tt.c +++ b/drivers/gpu/drm/ttm/ttm_tt.c | |||
| @@ -68,7 +68,7 @@ static void ttm_tt_cache_flush_clflush(struct page *pages[], | |||
| 68 | ttm_tt_clflush_page(*pages++); | 68 | ttm_tt_clflush_page(*pages++); |
| 69 | mb(); | 69 | mb(); |
| 70 | } | 70 | } |
| 71 | #else | 71 | #elif !defined(__powerpc__) |
| 72 | static void ttm_tt_ipi_handler(void *null) | 72 | static void ttm_tt_ipi_handler(void *null) |
| 73 | { | 73 | { |
| 74 | ; | 74 | ; |
| @@ -83,6 +83,15 @@ void ttm_tt_cache_flush(struct page *pages[], unsigned long num_pages) | |||
| 83 | ttm_tt_cache_flush_clflush(pages, num_pages); | 83 | ttm_tt_cache_flush_clflush(pages, num_pages); |
| 84 | return; | 84 | return; |
| 85 | } | 85 | } |
| 86 | #elif defined(__powerpc__) | ||
| 87 | unsigned long i; | ||
| 88 | |||
| 89 | for (i = 0; i < num_pages; ++i) { | ||
| 90 | if (pages[i]) { | ||
| 91 | unsigned long start = (unsigned long)page_address(pages[i]); | ||
| 92 | flush_dcache_range(start, start + PAGE_SIZE); | ||
| 93 | } | ||
| 94 | } | ||
| 86 | #else | 95 | #else |
| 87 | if (on_each_cpu(ttm_tt_ipi_handler, NULL, 1) != 0) | 96 | if (on_each_cpu(ttm_tt_ipi_handler, NULL, 1) != 0) |
| 88 | printk(KERN_ERR TTM_PFX | 97 | printk(KERN_ERR TTM_PFX |
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index 2c4f0b485792..6e6f91591639 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c | |||
| @@ -96,7 +96,7 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 96 | drm_via_private_t *dev_priv; | 96 | drm_via_private_t *dev_priv; |
| 97 | int ret = 0; | 97 | int ret = 0; |
| 98 | 98 | ||
| 99 | dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER); | 99 | dev_priv = kzalloc(sizeof(drm_via_private_t), GFP_KERNEL); |
| 100 | if (dev_priv == NULL) | 100 | if (dev_priv == NULL) |
| 101 | return -ENOMEM; | 101 | return -ENOMEM; |
| 102 | 102 | ||
| @@ -106,14 +106,14 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) | |||
| 106 | 106 | ||
| 107 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); | 107 | ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); |
| 108 | if (ret) { | 108 | if (ret) { |
| 109 | drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER); | 109 | kfree(dev_priv); |
| 110 | return ret; | 110 | return ret; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | ret = drm_vblank_init(dev, 1); | 113 | ret = drm_vblank_init(dev, 1); |
| 114 | if (ret) { | 114 | if (ret) { |
| 115 | drm_sman_takedown(&dev_priv->sman); | 115 | drm_sman_takedown(&dev_priv->sman); |
| 116 | drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER); | 116 | kfree(dev_priv); |
| 117 | return ret; | 117 | return ret; |
| 118 | } | 118 | } |
| 119 | 119 | ||
| @@ -126,7 +126,7 @@ int via_driver_unload(struct drm_device *dev) | |||
| 126 | 126 | ||
| 127 | drm_sman_takedown(&dev_priv->sman); | 127 | drm_sman_takedown(&dev_priv->sman); |
| 128 | 128 | ||
| 129 | drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER); | 129 | kfree(dev_priv); |
| 130 | 130 | ||
| 131 | return 0; | 131 | return 0; |
| 132 | } | 132 | } |
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c index fc0949a8cfde..dbfeda42b940 100644 --- a/drivers/ide/at91_ide.c +++ b/drivers/ide/at91_ide.c | |||
| @@ -185,8 +185,7 @@ static void at91_ide_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 185 | timing = ide_timing_find_mode(XFER_PIO_0 + pio); | 185 | timing = ide_timing_find_mode(XFER_PIO_0 + pio); |
| 186 | BUG_ON(!timing); | 186 | BUG_ON(!timing); |
| 187 | 187 | ||
| 188 | if ((pio > 2 || ata_id_has_iordy(drive->id)) && | 188 | if (ide_pio_need_iordy(drive, pio)) |
| 189 | !(ata_id_is_cfa(drive->id) && pio > 4)) | ||
| 190 | use_iordy = 1; | 189 | use_iordy = 1; |
| 191 | 190 | ||
| 192 | apply_timings(chipselect, pio, timing, use_iordy); | 191 | apply_timings(chipselect, pio, timing, use_iordy); |
diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c index e3c6a5913305..ab4f169d0837 100644 --- a/drivers/ide/buddha.c +++ b/drivers/ide/buddha.c | |||
| @@ -99,7 +99,7 @@ static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" }; | |||
| 99 | * Check and acknowledge the interrupt status | 99 | * Check and acknowledge the interrupt status |
| 100 | */ | 100 | */ |
| 101 | 101 | ||
| 102 | static int buddha_ack_intr(ide_hwif_t *hwif) | 102 | static int buddha_test_irq(ide_hwif_t *hwif) |
| 103 | { | 103 | { |
| 104 | unsigned char ch; | 104 | unsigned char ch; |
| 105 | 105 | ||
| @@ -109,21 +109,16 @@ static int buddha_ack_intr(ide_hwif_t *hwif) | |||
| 109 | return 1; | 109 | return 1; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static int xsurf_ack_intr(ide_hwif_t *hwif) | 112 | static void xsurf_clear_irq(ide_drive_t *drive) |
| 113 | { | 113 | { |
| 114 | unsigned char ch; | 114 | /* |
| 115 | 115 | * X-Surf needs 0 written to IRQ register to ensure ISA bit A11 stays at 0 | |
| 116 | ch = z_readb(hwif->io_ports.irq_addr); | 116 | */ |
| 117 | /* X-Surf needs a 0 written to IRQ register to ensure ISA bit A11 stays at 0 */ | 117 | z_writeb(0, drive->hwif->io_ports.irq_addr); |
| 118 | z_writeb(0, hwif->io_ports.irq_addr); | ||
| 119 | if (!(ch & 0x80)) | ||
| 120 | return 0; | ||
| 121 | return 1; | ||
| 122 | } | 118 | } |
| 123 | 119 | ||
| 124 | static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base, | 120 | static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base, |
| 125 | unsigned long ctl, unsigned long irq_port, | 121 | unsigned long ctl, unsigned long irq_port) |
| 126 | ide_ack_intr_t *ack_intr) | ||
| 127 | { | 122 | { |
| 128 | int i; | 123 | int i; |
| 129 | 124 | ||
| @@ -138,10 +133,19 @@ static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base, | |||
| 138 | hw->io_ports.irq_addr = irq_port; | 133 | hw->io_ports.irq_addr = irq_port; |
| 139 | 134 | ||
| 140 | hw->irq = IRQ_AMIGA_PORTS; | 135 | hw->irq = IRQ_AMIGA_PORTS; |
| 141 | hw->ack_intr = ack_intr; | ||
| 142 | } | 136 | } |
| 143 | 137 | ||
| 138 | static const struct ide_port_ops buddha_port_ops = { | ||
| 139 | .test_irq = buddha_test_irq, | ||
| 140 | }; | ||
| 141 | |||
| 142 | static const struct ide_port_ops xsurf_port_ops = { | ||
| 143 | .clear_irq = xsurf_clear_irq, | ||
| 144 | .test_irq = buddha_test_irq, | ||
| 145 | }; | ||
| 146 | |||
| 144 | static const struct ide_port_info buddha_port_info = { | 147 | static const struct ide_port_info buddha_port_info = { |
| 148 | .port_ops = &buddha_port_ops, | ||
| 145 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, | 149 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, |
| 146 | .irq_flags = IRQF_SHARED, | 150 | .irq_flags = IRQF_SHARED, |
| 147 | .chipset = ide_generic, | 151 | .chipset = ide_generic, |
| @@ -161,6 +165,7 @@ static int __init buddha_init(void) | |||
| 161 | while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { | 165 | while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { |
| 162 | unsigned long board; | 166 | unsigned long board; |
| 163 | struct ide_hw hw[MAX_NUM_HWIFS], *hws[MAX_NUM_HWIFS]; | 167 | struct ide_hw hw[MAX_NUM_HWIFS], *hws[MAX_NUM_HWIFS]; |
| 168 | struct ide_port_info d = buddha_port_info; | ||
| 164 | 169 | ||
| 165 | if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { | 170 | if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { |
| 166 | buddha_num_hwifs = BUDDHA_NUM_HWIFS; | 171 | buddha_num_hwifs = BUDDHA_NUM_HWIFS; |
| @@ -171,6 +176,7 @@ static int __init buddha_init(void) | |||
| 171 | } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) { | 176 | } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) { |
| 172 | buddha_num_hwifs = XSURF_NUM_HWIFS; | 177 | buddha_num_hwifs = XSURF_NUM_HWIFS; |
| 173 | type=BOARD_XSURF; | 178 | type=BOARD_XSURF; |
| 179 | d.port_ops = &xsurf_port_ops; | ||
| 174 | } else | 180 | } else |
| 175 | continue; | 181 | continue; |
| 176 | 182 | ||
| @@ -203,28 +209,24 @@ fail_base2: | |||
| 203 | 209 | ||
| 204 | for (i = 0; i < buddha_num_hwifs; i++) { | 210 | for (i = 0; i < buddha_num_hwifs; i++) { |
| 205 | unsigned long base, ctl, irq_port; | 211 | unsigned long base, ctl, irq_port; |
| 206 | ide_ack_intr_t *ack_intr; | ||
| 207 | 212 | ||
| 208 | if (type != BOARD_XSURF) { | 213 | if (type != BOARD_XSURF) { |
| 209 | base = buddha_board + buddha_bases[i]; | 214 | base = buddha_board + buddha_bases[i]; |
| 210 | ctl = base + BUDDHA_CONTROL; | 215 | ctl = base + BUDDHA_CONTROL; |
| 211 | irq_port = buddha_board + buddha_irqports[i]; | 216 | irq_port = buddha_board + buddha_irqports[i]; |
| 212 | ack_intr = buddha_ack_intr; | ||
| 213 | } else { | 217 | } else { |
| 214 | base = buddha_board + xsurf_bases[i]; | 218 | base = buddha_board + xsurf_bases[i]; |
| 215 | /* X-Surf has no CS1* (Control/AltStat) */ | 219 | /* X-Surf has no CS1* (Control/AltStat) */ |
| 216 | ctl = 0; | 220 | ctl = 0; |
| 217 | irq_port = buddha_board + xsurf_irqports[i]; | 221 | irq_port = buddha_board + xsurf_irqports[i]; |
| 218 | ack_intr = xsurf_ack_intr; | ||
| 219 | } | 222 | } |
| 220 | 223 | ||
| 221 | buddha_setup_ports(&hw[i], base, ctl, irq_port, | 224 | buddha_setup_ports(&hw[i], base, ctl, irq_port); |
| 222 | ack_intr); | ||
| 223 | 225 | ||
| 224 | hws[i] = &hw[i]; | 226 | hws[i] = &hw[i]; |
| 225 | } | 227 | } |
| 226 | 228 | ||
| 227 | ide_host_add(&buddha_port_info, hws, i, NULL); | 229 | ide_host_add(&d, hws, i, NULL); |
| 228 | } | 230 | } |
| 229 | 231 | ||
| 230 | return 0; | 232 | return 0; |
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c index 1683ed5c7329..1a32d62ed86b 100644 --- a/drivers/ide/cmd640.c +++ b/drivers/ide/cmd640.c | |||
| @@ -153,6 +153,7 @@ static int cmd640_vlb; | |||
| 153 | #define ARTTIM23 0x57 | 153 | #define ARTTIM23 0x57 |
| 154 | #define ARTTIM23_DIS_RA2 0x04 | 154 | #define ARTTIM23_DIS_RA2 0x04 |
| 155 | #define ARTTIM23_DIS_RA3 0x08 | 155 | #define ARTTIM23_DIS_RA3 0x08 |
| 156 | #define ARTTIM23_IDE23INTR 0x10 | ||
| 156 | #define DRWTIM23 0x58 | 157 | #define DRWTIM23 0x58 |
| 157 | #define BRST 0x59 | 158 | #define BRST 0x59 |
| 158 | 159 | ||
| @@ -629,12 +630,24 @@ static void cmd640_init_dev(ide_drive_t *drive) | |||
| 629 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ | 630 | #endif /* CONFIG_BLK_DEV_CMD640_ENHANCED */ |
| 630 | } | 631 | } |
| 631 | 632 | ||
| 633 | static int cmd640_test_irq(ide_hwif_t *hwif) | ||
| 634 | { | ||
| 635 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
| 636 | int irq_reg = hwif->channel ? ARTTIM23 : CFR; | ||
| 637 | u8 irq_stat, irq_mask = hwif->channel ? ARTTIM23_IDE23INTR : | ||
| 638 | CFR_IDE01INTR; | ||
| 639 | |||
| 640 | pci_read_config_byte(dev, irq_reg, &irq_stat); | ||
| 641 | |||
| 642 | return (irq_stat & irq_mask) ? 1 : 0; | ||
| 643 | } | ||
| 632 | 644 | ||
| 633 | static const struct ide_port_ops cmd640_port_ops = { | 645 | static const struct ide_port_ops cmd640_port_ops = { |
| 634 | .init_dev = cmd640_init_dev, | 646 | .init_dev = cmd640_init_dev, |
| 635 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED | 647 | #ifdef CONFIG_BLK_DEV_CMD640_ENHANCED |
| 636 | .set_pio_mode = cmd640_set_pio_mode, | 648 | .set_pio_mode = cmd640_set_pio_mode, |
| 637 | #endif | 649 | #endif |
| 650 | .test_irq = cmd640_test_irq, | ||
| 638 | }; | 651 | }; |
| 639 | 652 | ||
| 640 | static int pci_conf1(void) | 653 | static int pci_conf1(void) |
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c index 80b777e4247b..03c86209446f 100644 --- a/drivers/ide/cmd64x.c +++ b/drivers/ide/cmd64x.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Copyright (C) 1998 David S. Miller (davem@redhat.com) | 7 | * Copyright (C) 1998 David S. Miller (davem@redhat.com) |
| 8 | * | 8 | * |
| 9 | * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> | 9 | * Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org> |
| 10 | * Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com> | 10 | * Copyright (C) 2007,2009 MontaVista Software, Inc. <source@mvista.com> |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| @@ -118,8 +118,9 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) | |||
| 118 | ide_hwif_t *hwif = drive->hwif; | 118 | ide_hwif_t *hwif = drive->hwif; |
| 119 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 119 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| 120 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); | 120 | struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); |
| 121 | unsigned long setup_count; | ||
| 121 | unsigned int cycle_time; | 122 | unsigned int cycle_time; |
| 122 | u8 setup_count, arttim = 0; | 123 | u8 arttim = 0; |
| 123 | 124 | ||
| 124 | static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; | 125 | static const u8 setup_values[] = {0x40, 0x40, 0x40, 0x80, 0, 0xc0}; |
| 125 | static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; | 126 | static const u8 arttim_regs[4] = {ARTTIM0, ARTTIM1, ARTTIM23, ARTTIM23}; |
| @@ -140,10 +141,11 @@ static void cmd64x_tune_pio(ide_drive_t *drive, const u8 pio) | |||
| 140 | if (hwif->channel) { | 141 | if (hwif->channel) { |
| 141 | ide_drive_t *pair = ide_get_pair_dev(drive); | 142 | ide_drive_t *pair = ide_get_pair_dev(drive); |
| 142 | 143 | ||
| 143 | drive->drive_data = setup_count; | 144 | ide_set_drivedata(drive, (void *)setup_count); |
| 144 | 145 | ||
| 145 | if (pair) | 146 | if (pair) |
| 146 | setup_count = max_t(u8, setup_count, pair->drive_data); | 147 | setup_count = max_t(u8, setup_count, |
| 148 | (unsigned long)ide_get_drivedata(pair)); | ||
| 147 | } | 149 | } |
| 148 | 150 | ||
| 149 | if (setup_count > 5) /* shouldn't actually happen... */ | 151 | if (setup_count > 5) /* shouldn't actually happen... */ |
| @@ -226,11 +228,11 @@ static void cmd64x_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 226 | (void) pci_write_config_byte(dev, pciU, regU); | 228 | (void) pci_write_config_byte(dev, pciU, regU); |
| 227 | } | 229 | } |
| 228 | 230 | ||
| 229 | static int cmd648_dma_end(ide_drive_t *drive) | 231 | static void cmd648_clear_irq(ide_drive_t *drive) |
| 230 | { | 232 | { |
| 231 | ide_hwif_t *hwif = drive->hwif; | 233 | ide_hwif_t *hwif = drive->hwif; |
| 232 | unsigned long base = hwif->dma_base - (hwif->channel * 8); | 234 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| 233 | int err = ide_dma_end(drive); | 235 | unsigned long base = pci_resource_start(dev, 4); |
| 234 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : | 236 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : |
| 235 | MRDMODE_INTR_CH0; | 237 | MRDMODE_INTR_CH0; |
| 236 | u8 mrdmode = inb(base + 1); | 238 | u8 mrdmode = inb(base + 1); |
| @@ -238,11 +240,9 @@ static int cmd648_dma_end(ide_drive_t *drive) | |||
| 238 | /* clear the interrupt bit */ | 240 | /* clear the interrupt bit */ |
| 239 | outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask, | 241 | outb((mrdmode & ~(MRDMODE_INTR_CH0 | MRDMODE_INTR_CH1)) | irq_mask, |
| 240 | base + 1); | 242 | base + 1); |
| 241 | |||
| 242 | return err; | ||
| 243 | } | 243 | } |
| 244 | 244 | ||
| 245 | static int cmd64x_dma_end(ide_drive_t *drive) | 245 | static void cmd64x_clear_irq(ide_drive_t *drive) |
| 246 | { | 246 | { |
| 247 | ide_hwif_t *hwif = drive->hwif; | 247 | ide_hwif_t *hwif = drive->hwif; |
| 248 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 248 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| @@ -250,62 +250,40 @@ static int cmd64x_dma_end(ide_drive_t *drive) | |||
| 250 | u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : | 250 | u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : |
| 251 | CFR_INTR_CH0; | 251 | CFR_INTR_CH0; |
| 252 | u8 irq_stat = 0; | 252 | u8 irq_stat = 0; |
| 253 | int err = ide_dma_end(drive); | ||
| 254 | 253 | ||
| 255 | (void) pci_read_config_byte(dev, irq_reg, &irq_stat); | 254 | (void) pci_read_config_byte(dev, irq_reg, &irq_stat); |
| 256 | /* clear the interrupt bit */ | 255 | /* clear the interrupt bit */ |
| 257 | (void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask); | 256 | (void) pci_write_config_byte(dev, irq_reg, irq_stat | irq_mask); |
| 258 | |||
| 259 | return err; | ||
| 260 | } | 257 | } |
| 261 | 258 | ||
| 262 | static int cmd648_dma_test_irq(ide_drive_t *drive) | 259 | static int cmd648_test_irq(ide_hwif_t *hwif) |
| 263 | { | 260 | { |
| 264 | ide_hwif_t *hwif = drive->hwif; | 261 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| 265 | unsigned long base = hwif->dma_base - (hwif->channel * 8); | 262 | unsigned long base = pci_resource_start(dev, 4); |
| 266 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : | 263 | u8 irq_mask = hwif->channel ? MRDMODE_INTR_CH1 : |
| 267 | MRDMODE_INTR_CH0; | 264 | MRDMODE_INTR_CH0; |
| 268 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | ||
| 269 | u8 mrdmode = inb(base + 1); | 265 | u8 mrdmode = inb(base + 1); |
| 270 | 266 | ||
| 271 | #ifdef DEBUG | 267 | pr_debug("%s: mrdmode: 0x%02x irq_mask: 0x%02x\n", |
| 272 | printk("%s: dma_stat: 0x%02x mrdmode: 0x%02x irq_mask: 0x%02x\n", | 268 | hwif->name, mrdmode, irq_mask); |
| 273 | drive->name, dma_stat, mrdmode, irq_mask); | ||
| 274 | #endif | ||
| 275 | if (!(mrdmode & irq_mask)) | ||
| 276 | return 0; | ||
| 277 | |||
| 278 | /* return 1 if INTR asserted */ | ||
| 279 | if (dma_stat & 4) | ||
| 280 | return 1; | ||
| 281 | 269 | ||
| 282 | return 0; | 270 | return (mrdmode & irq_mask) ? 1 : 0; |
| 283 | } | 271 | } |
| 284 | 272 | ||
| 285 | static int cmd64x_dma_test_irq(ide_drive_t *drive) | 273 | static int cmd64x_test_irq(ide_hwif_t *hwif) |
| 286 | { | 274 | { |
| 287 | ide_hwif_t *hwif = drive->hwif; | ||
| 288 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 275 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| 289 | int irq_reg = hwif->channel ? ARTTIM23 : CFR; | 276 | int irq_reg = hwif->channel ? ARTTIM23 : CFR; |
| 290 | u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : | 277 | u8 irq_mask = hwif->channel ? ARTTIM23_INTR_CH1 : |
| 291 | CFR_INTR_CH0; | 278 | CFR_INTR_CH0; |
| 292 | u8 dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS); | ||
| 293 | u8 irq_stat = 0; | 279 | u8 irq_stat = 0; |
| 294 | 280 | ||
| 295 | (void) pci_read_config_byte(dev, irq_reg, &irq_stat); | 281 | (void) pci_read_config_byte(dev, irq_reg, &irq_stat); |
| 296 | 282 | ||
| 297 | #ifdef DEBUG | 283 | pr_debug("%s: irq_stat: 0x%02x irq_mask: 0x%02x\n", |
| 298 | printk("%s: dma_stat: 0x%02x irq_stat: 0x%02x irq_mask: 0x%02x\n", | 284 | hwif->name, irq_stat, irq_mask); |
| 299 | drive->name, dma_stat, irq_stat, irq_mask); | ||
| 300 | #endif | ||
| 301 | if (!(irq_stat & irq_mask)) | ||
| 302 | return 0; | ||
| 303 | |||
| 304 | /* return 1 if INTR asserted */ | ||
| 305 | if (dma_stat & 4) | ||
| 306 | return 1; | ||
| 307 | 285 | ||
| 308 | return 0; | 286 | return (irq_stat & irq_mask) ? 1 : 0; |
| 309 | } | 287 | } |
| 310 | 288 | ||
| 311 | /* | 289 | /* |
| @@ -370,18 +348,17 @@ static u8 cmd64x_cable_detect(ide_hwif_t *hwif) | |||
| 370 | static const struct ide_port_ops cmd64x_port_ops = { | 348 | static const struct ide_port_ops cmd64x_port_ops = { |
| 371 | .set_pio_mode = cmd64x_set_pio_mode, | 349 | .set_pio_mode = cmd64x_set_pio_mode, |
| 372 | .set_dma_mode = cmd64x_set_dma_mode, | 350 | .set_dma_mode = cmd64x_set_dma_mode, |
| 351 | .clear_irq = cmd64x_clear_irq, | ||
| 352 | .test_irq = cmd64x_test_irq, | ||
| 373 | .cable_detect = cmd64x_cable_detect, | 353 | .cable_detect = cmd64x_cable_detect, |
| 374 | }; | 354 | }; |
| 375 | 355 | ||
| 376 | static const struct ide_dma_ops cmd64x_dma_ops = { | 356 | static const struct ide_port_ops cmd648_port_ops = { |
| 377 | .dma_host_set = ide_dma_host_set, | 357 | .set_pio_mode = cmd64x_set_pio_mode, |
| 378 | .dma_setup = ide_dma_setup, | 358 | .set_dma_mode = cmd64x_set_dma_mode, |
| 379 | .dma_start = ide_dma_start, | 359 | .clear_irq = cmd648_clear_irq, |
| 380 | .dma_end = cmd64x_dma_end, | 360 | .test_irq = cmd648_test_irq, |
| 381 | .dma_test_irq = cmd64x_dma_test_irq, | 361 | .cable_detect = cmd64x_cable_detect, |
| 382 | .dma_lost_irq = ide_dma_lost_irq, | ||
| 383 | .dma_timer_expiry = ide_dma_sff_timer_expiry, | ||
| 384 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
| 385 | }; | 362 | }; |
| 386 | 363 | ||
| 387 | static const struct ide_dma_ops cmd646_rev1_dma_ops = { | 364 | static const struct ide_dma_ops cmd646_rev1_dma_ops = { |
| @@ -395,24 +372,12 @@ static const struct ide_dma_ops cmd646_rev1_dma_ops = { | |||
| 395 | .dma_sff_read_status = ide_dma_sff_read_status, | 372 | .dma_sff_read_status = ide_dma_sff_read_status, |
| 396 | }; | 373 | }; |
| 397 | 374 | ||
| 398 | static const struct ide_dma_ops cmd648_dma_ops = { | ||
| 399 | .dma_host_set = ide_dma_host_set, | ||
| 400 | .dma_setup = ide_dma_setup, | ||
| 401 | .dma_start = ide_dma_start, | ||
| 402 | .dma_end = cmd648_dma_end, | ||
| 403 | .dma_test_irq = cmd648_dma_test_irq, | ||
| 404 | .dma_lost_irq = ide_dma_lost_irq, | ||
| 405 | .dma_timer_expiry = ide_dma_sff_timer_expiry, | ||
| 406 | .dma_sff_read_status = ide_dma_sff_read_status, | ||
| 407 | }; | ||
| 408 | |||
| 409 | static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | 375 | static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { |
| 410 | { /* 0: CMD643 */ | 376 | { /* 0: CMD643 */ |
| 411 | .name = DRV_NAME, | 377 | .name = DRV_NAME, |
| 412 | .init_chipset = init_chipset_cmd64x, | 378 | .init_chipset = init_chipset_cmd64x, |
| 413 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, | 379 | .enablebits = {{0x00,0x00,0x00}, {0x51,0x08,0x08}}, |
| 414 | .port_ops = &cmd64x_port_ops, | 380 | .port_ops = &cmd64x_port_ops, |
| 415 | .dma_ops = &cmd64x_dma_ops, | ||
| 416 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | | 381 | .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | |
| 417 | IDE_HFLAG_ABUSE_PREFETCH, | 382 | IDE_HFLAG_ABUSE_PREFETCH, |
| 418 | .pio_mask = ATA_PIO5, | 383 | .pio_mask = ATA_PIO5, |
| @@ -423,8 +388,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
| 423 | .name = DRV_NAME, | 388 | .name = DRV_NAME, |
| 424 | .init_chipset = init_chipset_cmd64x, | 389 | .init_chipset = init_chipset_cmd64x, |
| 425 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 390 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
| 426 | .port_ops = &cmd64x_port_ops, | 391 | .port_ops = &cmd648_port_ops, |
| 427 | .dma_ops = &cmd648_dma_ops, | ||
| 428 | .host_flags = IDE_HFLAG_SERIALIZE | | 392 | .host_flags = IDE_HFLAG_SERIALIZE | |
| 429 | IDE_HFLAG_ABUSE_PREFETCH, | 393 | IDE_HFLAG_ABUSE_PREFETCH, |
| 430 | .pio_mask = ATA_PIO5, | 394 | .pio_mask = ATA_PIO5, |
| @@ -435,8 +399,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
| 435 | .name = DRV_NAME, | 399 | .name = DRV_NAME, |
| 436 | .init_chipset = init_chipset_cmd64x, | 400 | .init_chipset = init_chipset_cmd64x, |
| 437 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 401 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
| 438 | .port_ops = &cmd64x_port_ops, | 402 | .port_ops = &cmd648_port_ops, |
| 439 | .dma_ops = &cmd648_dma_ops, | ||
| 440 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, | 403 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, |
| 441 | .pio_mask = ATA_PIO5, | 404 | .pio_mask = ATA_PIO5, |
| 442 | .mwdma_mask = ATA_MWDMA2, | 405 | .mwdma_mask = ATA_MWDMA2, |
| @@ -446,8 +409,7 @@ static const struct ide_port_info cmd64x_chipsets[] __devinitdata = { | |||
| 446 | .name = DRV_NAME, | 409 | .name = DRV_NAME, |
| 447 | .init_chipset = init_chipset_cmd64x, | 410 | .init_chipset = init_chipset_cmd64x, |
| 448 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, | 411 | .enablebits = {{0x51,0x04,0x04}, {0x51,0x08,0x08}}, |
| 449 | .port_ops = &cmd64x_port_ops, | 412 | .port_ops = &cmd648_port_ops, |
| 450 | .dma_ops = &cmd648_dma_ops, | ||
| 451 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, | 413 | .host_flags = IDE_HFLAG_ABUSE_PREFETCH, |
| 452 | .pio_mask = ATA_PIO5, | 414 | .pio_mask = ATA_PIO5, |
| 453 | .mwdma_mask = ATA_MWDMA2, | 415 | .mwdma_mask = ATA_MWDMA2, |
| @@ -484,10 +446,9 @@ static int __devinit cmd64x_init_one(struct pci_dev *dev, const struct pci_devic | |||
| 484 | */ | 446 | */ |
| 485 | if (dev->revision < 3) { | 447 | if (dev->revision < 3) { |
| 486 | d.enablebits[0].reg = 0; | 448 | d.enablebits[0].reg = 0; |
| 449 | d.port_ops = &cmd64x_port_ops; | ||
| 487 | if (dev->revision == 1) | 450 | if (dev->revision == 1) |
| 488 | d.dma_ops = &cmd646_rev1_dma_ops; | 451 | d.dma_ops = &cmd646_rev1_dma_ops; |
| 489 | else | ||
| 490 | d.dma_ops = &cmd64x_dma_ops; | ||
| 491 | } | 452 | } |
| 492 | } | 453 | } |
| 493 | } | 454 | } |
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c index 0332a95eefd4..9623b852c616 100644 --- a/drivers/ide/cs5536.c +++ b/drivers/ide/cs5536.c | |||
| @@ -146,14 +146,16 @@ static void cs5536_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 146 | struct pci_dev *pdev = to_pci_dev(drive->hwif->dev); | 146 | struct pci_dev *pdev = to_pci_dev(drive->hwif->dev); |
| 147 | ide_drive_t *pair = ide_get_pair_dev(drive); | 147 | ide_drive_t *pair = ide_get_pair_dev(drive); |
| 148 | int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT; | 148 | int cshift = (drive->dn & 1) ? IDE_CAST_D1_SHIFT : IDE_CAST_D0_SHIFT; |
| 149 | unsigned long timings = (unsigned long)ide_get_drivedata(drive); | ||
| 149 | u32 cast; | 150 | u32 cast; |
| 150 | u8 cmd_pio = pio; | 151 | u8 cmd_pio = pio; |
| 151 | 152 | ||
| 152 | if (pair) | 153 | if (pair) |
| 153 | cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4)); | 154 | cmd_pio = min(pio, ide_get_best_pio_mode(pair, 255, 4)); |
| 154 | 155 | ||
| 155 | drive->drive_data &= (IDE_DRV_MASK << 8); | 156 | timings &= (IDE_DRV_MASK << 8); |
| 156 | drive->drive_data |= drv_timings[pio]; | 157 | timings |= drv_timings[pio]; |
| 158 | ide_set_drivedata(drive, (void *)timings); | ||
| 157 | 159 | ||
| 158 | cs5536_program_dtc(drive, drv_timings[pio]); | 160 | cs5536_program_dtc(drive, drv_timings[pio]); |
| 159 | 161 | ||
| @@ -186,6 +188,7 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
| 186 | 188 | ||
| 187 | struct pci_dev *pdev = to_pci_dev(drive->hwif->dev); | 189 | struct pci_dev *pdev = to_pci_dev(drive->hwif->dev); |
| 188 | int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT; | 190 | int dshift = (drive->dn & 1) ? IDE_D1_SHIFT : IDE_D0_SHIFT; |
| 191 | unsigned long timings = (unsigned long)ide_get_drivedata(drive); | ||
| 189 | u32 etc; | 192 | u32 etc; |
| 190 | 193 | ||
| 191 | cs5536_read(pdev, ETC, &etc); | 194 | cs5536_read(pdev, ETC, &etc); |
| @@ -195,8 +198,9 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
| 195 | etc |= udma_timings[mode - XFER_UDMA_0] << dshift; | 198 | etc |= udma_timings[mode - XFER_UDMA_0] << dshift; |
| 196 | } else { /* MWDMA */ | 199 | } else { /* MWDMA */ |
| 197 | etc &= ~(IDE_ETC_UDMA_MASK << dshift); | 200 | etc &= ~(IDE_ETC_UDMA_MASK << dshift); |
| 198 | drive->drive_data &= IDE_DRV_MASK; | 201 | timings &= IDE_DRV_MASK; |
| 199 | drive->drive_data |= mwdma_timings[mode - XFER_MW_DMA_0] << 8; | 202 | timings |= mwdma_timings[mode - XFER_MW_DMA_0] << 8; |
| 203 | ide_set_drivedata(drive, (void *)timings); | ||
| 200 | } | 204 | } |
| 201 | 205 | ||
| 202 | cs5536_write(pdev, ETC, etc); | 206 | cs5536_write(pdev, ETC, etc); |
| @@ -204,9 +208,11 @@ static void cs5536_set_dma_mode(ide_drive_t *drive, const u8 mode) | |||
| 204 | 208 | ||
| 205 | static void cs5536_dma_start(ide_drive_t *drive) | 209 | static void cs5536_dma_start(ide_drive_t *drive) |
| 206 | { | 210 | { |
| 211 | unsigned long timings = (unsigned long)ide_get_drivedata(drive); | ||
| 212 | |||
| 207 | if (drive->current_speed < XFER_UDMA_0 && | 213 | if (drive->current_speed < XFER_UDMA_0 && |
| 208 | (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK)) | 214 | (timings >> 8) != (timings & IDE_DRV_MASK)) |
| 209 | cs5536_program_dtc(drive, drive->drive_data >> 8); | 215 | cs5536_program_dtc(drive, timings >> 8); |
| 210 | 216 | ||
| 211 | ide_dma_start(drive); | 217 | ide_dma_start(drive); |
| 212 | } | 218 | } |
| @@ -214,10 +220,11 @@ static void cs5536_dma_start(ide_drive_t *drive) | |||
| 214 | static int cs5536_dma_end(ide_drive_t *drive) | 220 | static int cs5536_dma_end(ide_drive_t *drive) |
| 215 | { | 221 | { |
| 216 | int ret = ide_dma_end(drive); | 222 | int ret = ide_dma_end(drive); |
| 223 | unsigned long timings = (unsigned long)ide_get_drivedata(drive); | ||
| 217 | 224 | ||
| 218 | if (drive->current_speed < XFER_UDMA_0 && | 225 | if (drive->current_speed < XFER_UDMA_0 && |
| 219 | (drive->drive_data >> 8) != (drive->drive_data & IDE_DRV_MASK)) | 226 | (timings >> 8) != (timings & IDE_DRV_MASK)) |
| 220 | cs5536_program_dtc(drive, drive->drive_data & IDE_DRV_MASK); | 227 | cs5536_program_dtc(drive, timings & IDE_DRV_MASK); |
| 221 | 228 | ||
| 222 | return ret; | 229 | return ret; |
| 223 | } | 230 | } |
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c index 22fa27389c3b..a5a07ccb81a7 100644 --- a/drivers/ide/falconide.c +++ b/drivers/ide/falconide.c | |||
| @@ -128,7 +128,6 @@ static void __init falconide_setup_ports(struct ide_hw *hw) | |||
| 128 | hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL; | 128 | hw->io_ports.ctl_addr = ATA_HD_BASE + ATA_HD_CONTROL; |
| 129 | 129 | ||
| 130 | hw->irq = IRQ_MFP_IDE; | 130 | hw->irq = IRQ_MFP_IDE; |
| 131 | hw->ack_intr = NULL; | ||
| 132 | } | 131 | } |
| 133 | 132 | ||
| 134 | /* | 133 | /* |
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c index 4451a6a5dfe0..b9e517de6a82 100644 --- a/drivers/ide/gayle.c +++ b/drivers/ide/gayle.c | |||
| @@ -66,7 +66,7 @@ MODULE_PARM_DESC(doubler, "enable support for IDE doublers"); | |||
| 66 | * Check and acknowledge the interrupt status | 66 | * Check and acknowledge the interrupt status |
| 67 | */ | 67 | */ |
| 68 | 68 | ||
| 69 | static int gayle_ack_intr_a4000(ide_hwif_t *hwif) | 69 | static int gayle_test_irq(ide_hwif_t *hwif) |
| 70 | { | 70 | { |
| 71 | unsigned char ch; | 71 | unsigned char ch; |
| 72 | 72 | ||
| @@ -76,21 +76,16 @@ static int gayle_ack_intr_a4000(ide_hwif_t *hwif) | |||
| 76 | return 1; | 76 | return 1; |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static int gayle_ack_intr_a1200(ide_hwif_t *hwif) | 79 | static void gayle_a1200_clear_irq(ide_drive_t *drive) |
| 80 | { | 80 | { |
| 81 | unsigned char ch; | 81 | ide_hwif_t *hwif = drive->hwif; |
| 82 | 82 | ||
| 83 | ch = z_readb(hwif->io_ports.irq_addr); | ||
| 84 | if (!(ch & GAYLE_IRQ_IDE)) | ||
| 85 | return 0; | ||
| 86 | (void)z_readb(hwif->io_ports.status_addr); | 83 | (void)z_readb(hwif->io_ports.status_addr); |
| 87 | z_writeb(0x7c, hwif->io_ports.irq_addr); | 84 | z_writeb(0x7c, hwif->io_ports.irq_addr); |
| 88 | return 1; | ||
| 89 | } | 85 | } |
| 90 | 86 | ||
| 91 | static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base, | 87 | static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base, |
| 92 | unsigned long ctl, unsigned long irq_port, | 88 | unsigned long ctl, unsigned long irq_port) |
| 93 | ide_ack_intr_t *ack_intr) | ||
| 94 | { | 89 | { |
| 95 | int i; | 90 | int i; |
| 96 | 91 | ||
| @@ -105,9 +100,17 @@ static void __init gayle_setup_ports(struct ide_hw *hw, unsigned long base, | |||
| 105 | hw->io_ports.irq_addr = irq_port; | 100 | hw->io_ports.irq_addr = irq_port; |
| 106 | 101 | ||
| 107 | hw->irq = IRQ_AMIGA_PORTS; | 102 | hw->irq = IRQ_AMIGA_PORTS; |
| 108 | hw->ack_intr = ack_intr; | ||
| 109 | } | 103 | } |
| 110 | 104 | ||
| 105 | static const struct ide_port_ops gayle_a4000_port_ops = { | ||
| 106 | .test_irq = gayle_test_irq, | ||
| 107 | }; | ||
| 108 | |||
| 109 | static const struct ide_port_ops gayle_a1200_port_ops = { | ||
| 110 | .clear_irq = gayle_a1200_clear_irq, | ||
| 111 | .test_irq = gayle_test_irq, | ||
| 112 | }; | ||
| 113 | |||
| 111 | static const struct ide_port_info gayle_port_info = { | 114 | static const struct ide_port_info gayle_port_info = { |
| 112 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE | | 115 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE | |
| 113 | IDE_HFLAG_NO_DMA, | 116 | IDE_HFLAG_NO_DMA, |
| @@ -123,9 +126,9 @@ static int __init gayle_init(void) | |||
| 123 | { | 126 | { |
| 124 | unsigned long phys_base, res_start, res_n; | 127 | unsigned long phys_base, res_start, res_n; |
| 125 | unsigned long base, ctrlport, irqport; | 128 | unsigned long base, ctrlport, irqport; |
| 126 | ide_ack_intr_t *ack_intr; | ||
| 127 | int a4000, i, rc; | 129 | int a4000, i, rc; |
| 128 | struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS]; | 130 | struct ide_hw hw[GAYLE_NUM_HWIFS], *hws[GAYLE_NUM_HWIFS]; |
| 131 | struct ide_port_info d = gayle_port_info; | ||
| 129 | 132 | ||
| 130 | if (!MACH_IS_AMIGA) | 133 | if (!MACH_IS_AMIGA) |
| 131 | return -ENODEV; | 134 | return -ENODEV; |
| @@ -148,11 +151,11 @@ found: | |||
| 148 | if (a4000) { | 151 | if (a4000) { |
| 149 | phys_base = GAYLE_BASE_4000; | 152 | phys_base = GAYLE_BASE_4000; |
| 150 | irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000); | 153 | irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000); |
| 151 | ack_intr = gayle_ack_intr_a4000; | 154 | d.port_ops = &gayle_a4000_port_ops; |
| 152 | } else { | 155 | } else { |
| 153 | phys_base = GAYLE_BASE_1200; | 156 | phys_base = GAYLE_BASE_1200; |
| 154 | irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); | 157 | irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); |
| 155 | ack_intr = gayle_ack_intr_a1200; | 158 | d.port_ops = &gayle_a1200_port_ops; |
| 156 | } | 159 | } |
| 157 | 160 | ||
| 158 | res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); | 161 | res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); |
| @@ -165,12 +168,12 @@ found: | |||
| 165 | base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT); | 168 | base = (unsigned long)ZTWO_VADDR(phys_base + i * GAYLE_NEXT_PORT); |
| 166 | ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; | 169 | ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; |
| 167 | 170 | ||
| 168 | gayle_setup_ports(&hw[i], base, ctrlport, irqport, ack_intr); | 171 | gayle_setup_ports(&hw[i], base, ctrlport, irqport); |
| 169 | 172 | ||
| 170 | hws[i] = &hw[i]; | 173 | hws[i] = &hw[i]; |
| 171 | } | 174 | } |
| 172 | 175 | ||
| 173 | rc = ide_host_add(&gayle_port_info, hws, i, NULL); | 176 | rc = ide_host_add(&d, hws, i, NULL); |
| 174 | if (rc) | 177 | if (rc) |
| 175 | release_mem_region(res_start, res_n); | 178 | release_mem_region(res_start, res_n); |
| 176 | 179 | ||
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c index 2fb0f2965009..aafed8060e17 100644 --- a/drivers/ide/ht6560b.c +++ b/drivers/ide/ht6560b.c | |||
| @@ -44,7 +44,12 @@ | |||
| 44 | * bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time (?) | 44 | * bit3 (0x08): "1" 3 cycle time, "0" 2 cycle time (?) |
| 45 | */ | 45 | */ |
| 46 | #define HT_CONFIG_PORT 0x3e6 | 46 | #define HT_CONFIG_PORT 0x3e6 |
| 47 | #define HT_CONFIG(drivea) (u8)(((drivea)->drive_data & 0xff00) >> 8) | 47 | |
| 48 | static inline u8 HT_CONFIG(ide_drive_t *drive) | ||
| 49 | { | ||
| 50 | return ((unsigned long)ide_get_drivedata(drive) & 0xff00) >> 8; | ||
| 51 | } | ||
| 52 | |||
| 48 | /* | 53 | /* |
| 49 | * FIFO + PREFETCH (both a/b-model) | 54 | * FIFO + PREFETCH (both a/b-model) |
| 50 | */ | 55 | */ |
| @@ -90,7 +95,11 @@ | |||
| 90 | * Active Time for each drive. Smaller value gives higher speed. | 95 | * Active Time for each drive. Smaller value gives higher speed. |
| 91 | * In case of failures you should probably fall back to a higher value. | 96 | * In case of failures you should probably fall back to a higher value. |
| 92 | */ | 97 | */ |
| 93 | #define HT_TIMING(drivea) (u8)((drivea)->drive_data & 0x00ff) | 98 | static inline u8 HT_TIMING(ide_drive_t *drive) |
| 99 | { | ||
| 100 | return (unsigned long)ide_get_drivedata(drive) & 0x00ff; | ||
| 101 | } | ||
| 102 | |||
| 94 | #define HT_TIMING_DEFAULT 0xff | 103 | #define HT_TIMING_DEFAULT 0xff |
| 95 | 104 | ||
| 96 | /* | 105 | /* |
| @@ -242,23 +251,27 @@ static DEFINE_SPINLOCK(ht6560b_lock); | |||
| 242 | */ | 251 | */ |
| 243 | static void ht_set_prefetch(ide_drive_t *drive, u8 state) | 252 | static void ht_set_prefetch(ide_drive_t *drive, u8 state) |
| 244 | { | 253 | { |
| 245 | unsigned long flags; | 254 | unsigned long flags, config; |
| 246 | int t = HT_PREFETCH_MODE << 8; | 255 | int t = HT_PREFETCH_MODE << 8; |
| 247 | 256 | ||
| 248 | spin_lock_irqsave(&ht6560b_lock, flags); | 257 | spin_lock_irqsave(&ht6560b_lock, flags); |
| 249 | 258 | ||
| 259 | config = (unsigned long)ide_get_drivedata(drive); | ||
| 260 | |||
| 250 | /* | 261 | /* |
| 251 | * Prefetch mode and unmask irq seems to conflict | 262 | * Prefetch mode and unmask irq seems to conflict |
| 252 | */ | 263 | */ |
| 253 | if (state) { | 264 | if (state) { |
| 254 | drive->drive_data |= t; /* enable prefetch mode */ | 265 | config |= t; /* enable prefetch mode */ |
| 255 | drive->dev_flags |= IDE_DFLAG_NO_UNMASK; | 266 | drive->dev_flags |= IDE_DFLAG_NO_UNMASK; |
| 256 | drive->dev_flags &= ~IDE_DFLAG_UNMASK; | 267 | drive->dev_flags &= ~IDE_DFLAG_UNMASK; |
| 257 | } else { | 268 | } else { |
| 258 | drive->drive_data &= ~t; /* disable prefetch mode */ | 269 | config &= ~t; /* disable prefetch mode */ |
| 259 | drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK; | 270 | drive->dev_flags &= ~IDE_DFLAG_NO_UNMASK; |
| 260 | } | 271 | } |
| 261 | 272 | ||
| 273 | ide_set_drivedata(drive, (void *)config); | ||
| 274 | |||
| 262 | spin_unlock_irqrestore(&ht6560b_lock, flags); | 275 | spin_unlock_irqrestore(&ht6560b_lock, flags); |
| 263 | 276 | ||
| 264 | #ifdef DEBUG | 277 | #ifdef DEBUG |
| @@ -268,7 +281,7 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state) | |||
| 268 | 281 | ||
| 269 | static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio) | 282 | static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio) |
| 270 | { | 283 | { |
| 271 | unsigned long flags; | 284 | unsigned long flags, config; |
| 272 | u8 timing; | 285 | u8 timing; |
| 273 | 286 | ||
| 274 | switch (pio) { | 287 | switch (pio) { |
| @@ -281,8 +294,10 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 281 | timing = ht_pio2timings(drive, pio); | 294 | timing = ht_pio2timings(drive, pio); |
| 282 | 295 | ||
| 283 | spin_lock_irqsave(&ht6560b_lock, flags); | 296 | spin_lock_irqsave(&ht6560b_lock, flags); |
| 284 | drive->drive_data &= 0xff00; | 297 | config = (unsigned long)ide_get_drivedata(drive); |
| 285 | drive->drive_data |= timing; | 298 | config &= 0xff00; |
| 299 | config |= timing; | ||
| 300 | ide_set_drivedata(drive, (void *)config); | ||
| 286 | spin_unlock_irqrestore(&ht6560b_lock, flags); | 301 | spin_unlock_irqrestore(&ht6560b_lock, flags); |
| 287 | 302 | ||
| 288 | #ifdef DEBUG | 303 | #ifdef DEBUG |
| @@ -299,7 +314,7 @@ static void __init ht6560b_init_dev(ide_drive_t *drive) | |||
| 299 | if (hwif->channel) | 314 | if (hwif->channel) |
| 300 | t |= (HT_SECONDARY_IF << 8); | 315 | t |= (HT_SECONDARY_IF << 8); |
| 301 | 316 | ||
| 302 | drive->drive_data = t; | 317 | ide_set_drivedata(drive, (void *)t); |
| 303 | } | 318 | } |
| 304 | 319 | ||
| 305 | static int probe_ht6560b; | 320 | static int probe_ht6560b; |
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c index 5af3d0ffaf0a..0f67f1abbbd3 100644 --- a/drivers/ide/icside.c +++ b/drivers/ide/icside.c | |||
| @@ -187,7 +187,8 @@ static const expansioncard_ops_t icside_ops_arcin_v6 = { | |||
| 187 | */ | 187 | */ |
| 188 | static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) | 188 | static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) |
| 189 | { | 189 | { |
| 190 | int cycle_time, use_dma_info = 0; | 190 | unsigned long cycle_time; |
| 191 | int use_dma_info = 0; | ||
| 191 | 192 | ||
| 192 | switch (xfer_mode) { | 193 | switch (xfer_mode) { |
| 193 | case XFER_MW_DMA_2: | 194 | case XFER_MW_DMA_2: |
| @@ -218,10 +219,11 @@ static void icside_set_dma_mode(ide_drive_t *drive, const u8 xfer_mode) | |||
| 218 | if (use_dma_info && drive->id[ATA_ID_EIDE_DMA_TIME] > cycle_time) | 219 | if (use_dma_info && drive->id[ATA_ID_EIDE_DMA_TIME] > cycle_time) |
| 219 | cycle_time = drive->id[ATA_ID_EIDE_DMA_TIME]; | 220 | cycle_time = drive->id[ATA_ID_EIDE_DMA_TIME]; |
| 220 | 221 | ||
| 221 | drive->drive_data = cycle_time; | 222 | ide_set_drivedata(drive, (void *)cycle_time); |
| 222 | 223 | ||
| 223 | printk("%s: %s selected (peak %dMB/s)\n", drive->name, | 224 | printk("%s: %s selected (peak %dMB/s)\n", drive->name, |
| 224 | ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data); | 225 | ide_xfer_verbose(xfer_mode), |
| 226 | 2000 / (unsigned long)ide_get_drivedata(drive)); | ||
| 225 | } | 227 | } |
| 226 | 228 | ||
| 227 | static const struct ide_port_ops icside_v6_port_ops = { | 229 | static const struct ide_port_ops icside_v6_port_ops = { |
| @@ -277,7 +279,7 @@ static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 277 | /* | 279 | /* |
| 278 | * Select the correct timing for this drive. | 280 | * Select the correct timing for this drive. |
| 279 | */ | 281 | */ |
| 280 | set_dma_speed(ec->dma, drive->drive_data); | 282 | set_dma_speed(ec->dma, (unsigned long)ide_get_drivedata(drive)); |
| 281 | 283 | ||
| 282 | /* | 284 | /* |
| 283 | * Tell the DMA engine about the SG table and | 285 | * Tell the DMA engine about the SG table and |
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c index 702ef64a0f12..eb2181a6a11c 100644 --- a/drivers/ide/ide-atapi.c +++ b/drivers/ide/ide-atapi.c | |||
| @@ -10,6 +10,9 @@ | |||
| 10 | 10 | ||
| 11 | #include <scsi/scsi.h> | 11 | #include <scsi/scsi.h> |
| 12 | 12 | ||
| 13 | #define DRV_NAME "ide-atapi" | ||
| 14 | #define PFX DRV_NAME ": " | ||
| 15 | |||
| 13 | #ifdef DEBUG | 16 | #ifdef DEBUG |
| 14 | #define debug_log(fmt, args...) \ | 17 | #define debug_log(fmt, args...) \ |
| 15 | printk(KERN_INFO "ide: " fmt, ## args) | 18 | printk(KERN_INFO "ide: " fmt, ## args) |
| @@ -74,8 +77,6 @@ EXPORT_SYMBOL_GPL(ide_check_atapi_device); | |||
| 74 | void ide_init_pc(struct ide_atapi_pc *pc) | 77 | void ide_init_pc(struct ide_atapi_pc *pc) |
| 75 | { | 78 | { |
| 76 | memset(pc, 0, sizeof(*pc)); | 79 | memset(pc, 0, sizeof(*pc)); |
| 77 | pc->buf = pc->pc_buf; | ||
| 78 | pc->buf_size = IDE_PC_BUFFER_SIZE; | ||
| 79 | } | 80 | } |
| 80 | EXPORT_SYMBOL_GPL(ide_init_pc); | 81 | EXPORT_SYMBOL_GPL(ide_init_pc); |
| 81 | 82 | ||
| @@ -84,7 +85,7 @@ EXPORT_SYMBOL_GPL(ide_init_pc); | |||
| 84 | * and wait for it to be serviced. | 85 | * and wait for it to be serviced. |
| 85 | */ | 86 | */ |
| 86 | int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, | 87 | int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, |
| 87 | struct ide_atapi_pc *pc) | 88 | struct ide_atapi_pc *pc, void *buf, unsigned int bufflen) |
| 88 | { | 89 | { |
| 89 | struct request *rq; | 90 | struct request *rq; |
| 90 | int error; | 91 | int error; |
| @@ -93,8 +94,8 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk, | |||
| 93 | rq->cmd_type = REQ_TYPE_SPECIAL; | 94 | rq->cmd_type = REQ_TYPE_SPECIAL; |
| 94 | rq->special = (char *)pc; | 95 | rq->special = (char *)pc; |
| 95 | 96 | ||
| 96 | if (pc->req_xfer) { | 97 | if (buf && bufflen) { |
| 97 | error = blk_rq_map_kern(drive->queue, rq, pc->buf, pc->req_xfer, | 98 | error = blk_rq_map_kern(drive->queue, rq, buf, bufflen, |
| 98 | GFP_NOIO); | 99 | GFP_NOIO); |
| 99 | if (error) | 100 | if (error) |
| 100 | goto put_req; | 101 | goto put_req; |
| @@ -117,7 +118,7 @@ int ide_do_test_unit_ready(ide_drive_t *drive, struct gendisk *disk) | |||
| 117 | ide_init_pc(&pc); | 118 | ide_init_pc(&pc); |
| 118 | pc.c[0] = TEST_UNIT_READY; | 119 | pc.c[0] = TEST_UNIT_READY; |
| 119 | 120 | ||
| 120 | return ide_queue_pc_tail(drive, disk, &pc); | 121 | return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
| 121 | } | 122 | } |
| 122 | EXPORT_SYMBOL_GPL(ide_do_test_unit_ready); | 123 | EXPORT_SYMBOL_GPL(ide_do_test_unit_ready); |
| 123 | 124 | ||
| @@ -132,7 +133,7 @@ int ide_do_start_stop(ide_drive_t *drive, struct gendisk *disk, int start) | |||
| 132 | if (drive->media == ide_tape) | 133 | if (drive->media == ide_tape) |
| 133 | pc.flags |= PC_FLAG_WAIT_FOR_DSC; | 134 | pc.flags |= PC_FLAG_WAIT_FOR_DSC; |
| 134 | 135 | ||
| 135 | return ide_queue_pc_tail(drive, disk, &pc); | 136 | return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
| 136 | } | 137 | } |
| 137 | EXPORT_SYMBOL_GPL(ide_do_start_stop); | 138 | EXPORT_SYMBOL_GPL(ide_do_start_stop); |
| 138 | 139 | ||
| @@ -147,7 +148,7 @@ int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on) | |||
| 147 | pc.c[0] = ALLOW_MEDIUM_REMOVAL; | 148 | pc.c[0] = ALLOW_MEDIUM_REMOVAL; |
| 148 | pc.c[4] = on; | 149 | pc.c[4] = on; |
| 149 | 150 | ||
| 150 | return ide_queue_pc_tail(drive, disk, &pc); | 151 | return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
| 151 | } | 152 | } |
| 152 | EXPORT_SYMBOL_GPL(ide_set_media_lock); | 153 | EXPORT_SYMBOL_GPL(ide_set_media_lock); |
| 153 | 154 | ||
| @@ -172,8 +173,6 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) | |||
| 172 | unsigned int cmd_len, sense_len; | 173 | unsigned int cmd_len, sense_len; |
| 173 | int err; | 174 | int err; |
| 174 | 175 | ||
| 175 | debug_log("%s: enter\n", __func__); | ||
| 176 | |||
| 177 | switch (drive->media) { | 176 | switch (drive->media) { |
| 178 | case ide_floppy: | 177 | case ide_floppy: |
| 179 | cmd_len = 255; | 178 | cmd_len = 255; |
| @@ -201,8 +200,8 @@ void ide_prep_sense(ide_drive_t *drive, struct request *rq) | |||
| 201 | GFP_NOIO); | 200 | GFP_NOIO); |
| 202 | if (unlikely(err)) { | 201 | if (unlikely(err)) { |
| 203 | if (printk_ratelimit()) | 202 | if (printk_ratelimit()) |
| 204 | printk(KERN_WARNING "%s: failed to map sense buffer\n", | 203 | printk(KERN_WARNING PFX "%s: failed to map sense " |
| 205 | drive->name); | 204 | "buffer\n", drive->name); |
| 206 | return; | 205 | return; |
| 207 | } | 206 | } |
| 208 | 207 | ||
| @@ -223,7 +222,7 @@ int ide_queue_sense_rq(ide_drive_t *drive, void *special) | |||
| 223 | { | 222 | { |
| 224 | /* deferred failure from ide_prep_sense() */ | 223 | /* deferred failure from ide_prep_sense() */ |
| 225 | if (!drive->sense_rq_armed) { | 224 | if (!drive->sense_rq_armed) { |
| 226 | printk(KERN_WARNING "%s: failed queue sense request\n", | 225 | printk(KERN_WARNING PFX "%s: error queuing a sense request\n", |
| 227 | drive->name); | 226 | drive->name); |
| 228 | return -ENOMEM; | 227 | return -ENOMEM; |
| 229 | } | 228 | } |
| @@ -255,8 +254,6 @@ void ide_retry_pc(ide_drive_t *drive) | |||
| 255 | /* init pc from sense_rq */ | 254 | /* init pc from sense_rq */ |
| 256 | ide_init_pc(pc); | 255 | ide_init_pc(pc); |
| 257 | memcpy(pc->c, sense_rq->cmd, 12); | 256 | memcpy(pc->c, sense_rq->cmd, 12); |
| 258 | pc->buf = bio_data(sense_rq->bio); /* pointer to mapped address */ | ||
| 259 | pc->req_xfer = blk_rq_bytes(sense_rq); | ||
| 260 | 257 | ||
| 261 | if (drive->media == ide_tape) | 258 | if (drive->media == ide_tape) |
| 262 | drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; | 259 | drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; |
| @@ -298,7 +295,7 @@ int ide_cd_expiry(ide_drive_t *drive) | |||
| 298 | break; | 295 | break; |
| 299 | default: | 296 | default: |
| 300 | if (!(rq->cmd_flags & REQ_QUIET)) | 297 | if (!(rq->cmd_flags & REQ_QUIET)) |
| 301 | printk(KERN_INFO "cmd 0x%x timed out\n", | 298 | printk(KERN_INFO PFX "cmd 0x%x timed out\n", |
| 302 | rq->cmd[0]); | 299 | rq->cmd[0]); |
| 303 | wait = 0; | 300 | wait = 0; |
| 304 | break; | 301 | break; |
| @@ -332,6 +329,55 @@ void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason) | |||
| 332 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); | 329 | EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason); |
| 333 | 330 | ||
| 334 | /* | 331 | /* |
| 332 | * Check the contents of the interrupt reason register and attempt to recover if | ||
| 333 | * there are problems. | ||
| 334 | * | ||
| 335 | * Returns: | ||
| 336 | * - 0 if everything's ok | ||
| 337 | * - 1 if the request has to be terminated. | ||
| 338 | */ | ||
| 339 | int ide_check_ireason(ide_drive_t *drive, struct request *rq, int len, | ||
| 340 | int ireason, int rw) | ||
| 341 | { | ||
| 342 | ide_hwif_t *hwif = drive->hwif; | ||
| 343 | |||
| 344 | debug_log("ireason: 0x%x, rw: 0x%x\n", ireason, rw); | ||
| 345 | |||
| 346 | if (ireason == (!rw << 1)) | ||
| 347 | return 0; | ||
| 348 | else if (ireason == (rw << 1)) { | ||
| 349 | printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n", | ||
| 350 | drive->name, __func__); | ||
| 351 | |||
| 352 | if (dev_is_idecd(drive)) | ||
| 353 | ide_pad_transfer(drive, rw, len); | ||
| 354 | } else if (!rw && ireason == ATAPI_COD) { | ||
| 355 | if (dev_is_idecd(drive)) { | ||
| 356 | /* | ||
| 357 | * Some drives (ASUS) seem to tell us that status info | ||
| 358 | * is available. Just get it and ignore. | ||
| 359 | */ | ||
| 360 | (void)hwif->tp_ops->read_status(hwif); | ||
| 361 | return 0; | ||
| 362 | } | ||
| 363 | } else { | ||
| 364 | if (ireason & ATAPI_COD) | ||
| 365 | printk(KERN_ERR PFX "%s: CoD != 0 in %s\n", drive->name, | ||
| 366 | __func__); | ||
| 367 | |||
| 368 | /* drive wants a command packet, or invalid ireason... */ | ||
| 369 | printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n", | ||
| 370 | drive->name, __func__, ireason); | ||
| 371 | } | ||
| 372 | |||
| 373 | if (dev_is_idecd(drive) && rq->cmd_type == REQ_TYPE_ATA_PC) | ||
| 374 | rq->cmd_flags |= REQ_FAILED; | ||
| 375 | |||
| 376 | return 1; | ||
| 377 | } | ||
| 378 | EXPORT_SYMBOL_GPL(ide_check_ireason); | ||
| 379 | |||
| 380 | /* | ||
| 335 | * This is the usual interrupt handler which will be called during a packet | 381 | * This is the usual interrupt handler which will be called during a packet |
| 336 | * command. We will transfer some of the data (as requested by the drive) | 382 | * command. We will transfer some of the data (as requested by the drive) |
| 337 | * and will re-point interrupt handler to us. | 383 | * and will re-point interrupt handler to us. |
| @@ -365,12 +411,12 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 365 | 411 | ||
| 366 | if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { | 412 | if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) { |
| 367 | if (drive->media == ide_floppy) | 413 | if (drive->media == ide_floppy) |
| 368 | printk(KERN_ERR "%s: DMA %s error\n", | 414 | printk(KERN_ERR PFX "%s: DMA %s error\n", |
| 369 | drive->name, rq_data_dir(pc->rq) | 415 | drive->name, rq_data_dir(pc->rq) |
| 370 | ? "write" : "read"); | 416 | ? "write" : "read"); |
| 371 | pc->flags |= PC_FLAG_DMA_ERROR; | 417 | pc->flags |= PC_FLAG_DMA_ERROR; |
| 372 | } else | 418 | } else |
| 373 | pc->xferred = pc->req_xfer; | 419 | rq->resid_len = 0; |
| 374 | debug_log("%s: DMA finished\n", drive->name); | 420 | debug_log("%s: DMA finished\n", drive->name); |
| 375 | } | 421 | } |
| 376 | 422 | ||
| @@ -379,7 +425,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 379 | int uptodate, error; | 425 | int uptodate, error; |
| 380 | 426 | ||
| 381 | debug_log("Packet command completed, %d bytes transferred\n", | 427 | debug_log("Packet command completed, %d bytes transferred\n", |
| 382 | pc->xferred); | 428 | blk_rq_bytes(rq)); |
| 383 | 429 | ||
| 384 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | 430 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; |
| 385 | 431 | ||
| @@ -397,8 +443,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 397 | pc->rq->errors++; | 443 | pc->rq->errors++; |
| 398 | 444 | ||
| 399 | if (rq->cmd[0] == REQUEST_SENSE) { | 445 | if (rq->cmd[0] == REQUEST_SENSE) { |
| 400 | printk(KERN_ERR "%s: I/O error in request sense" | 446 | printk(KERN_ERR PFX "%s: I/O error in request " |
| 401 | " command\n", drive->name); | 447 | "sense command\n", drive->name); |
| 402 | return ide_do_reset(drive); | 448 | return ide_do_reset(drive); |
| 403 | } | 449 | } |
| 404 | 450 | ||
| @@ -446,8 +492,8 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 446 | 492 | ||
| 447 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { | 493 | if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) { |
| 448 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; | 494 | pc->flags &= ~PC_FLAG_DMA_IN_PROGRESS; |
| 449 | printk(KERN_ERR "%s: The device wants to issue more interrupts " | 495 | printk(KERN_ERR PFX "%s: The device wants to issue more " |
| 450 | "in DMA mode\n", drive->name); | 496 | "interrupts in DMA mode\n", drive->name); |
| 451 | ide_dma_off(drive); | 497 | ide_dma_off(drive); |
| 452 | return ide_do_reset(drive); | 498 | return ide_do_reset(drive); |
| 453 | } | 499 | } |
| @@ -455,33 +501,22 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive) | |||
| 455 | /* Get the number of bytes to transfer on this interrupt. */ | 501 | /* Get the number of bytes to transfer on this interrupt. */ |
| 456 | ide_read_bcount_and_ireason(drive, &bcount, &ireason); | 502 | ide_read_bcount_and_ireason(drive, &bcount, &ireason); |
| 457 | 503 | ||
| 458 | if (ireason & ATAPI_COD) { | 504 | if (ide_check_ireason(drive, rq, bcount, ireason, write)) |
| 459 | printk(KERN_ERR "%s: CoD != 0 in %s\n", drive->name, __func__); | ||
| 460 | return ide_do_reset(drive); | 505 | return ide_do_reset(drive); |
| 461 | } | ||
| 462 | |||
| 463 | if (((ireason & ATAPI_IO) == ATAPI_IO) == write) { | ||
| 464 | /* Hopefully, we will never get here */ | ||
| 465 | printk(KERN_ERR "%s: We wanted to %s, but the device wants us " | ||
| 466 | "to %s!\n", drive->name, | ||
| 467 | (ireason & ATAPI_IO) ? "Write" : "Read", | ||
| 468 | (ireason & ATAPI_IO) ? "Read" : "Write"); | ||
| 469 | return ide_do_reset(drive); | ||
| 470 | } | ||
| 471 | 506 | ||
| 472 | done = min_t(unsigned int, bcount, cmd->nleft); | 507 | done = min_t(unsigned int, bcount, cmd->nleft); |
| 473 | ide_pio_bytes(drive, cmd, write, done); | 508 | ide_pio_bytes(drive, cmd, write, done); |
| 474 | 509 | ||
| 475 | /* Update transferred byte count */ | 510 | /* Update transferred byte count */ |
| 476 | pc->xferred += done; | 511 | rq->resid_len -= done; |
| 477 | 512 | ||
| 478 | bcount -= done; | 513 | bcount -= done; |
| 479 | 514 | ||
| 480 | if (bcount) | 515 | if (bcount) |
| 481 | ide_pad_transfer(drive, write, bcount); | 516 | ide_pad_transfer(drive, write, bcount); |
| 482 | 517 | ||
| 483 | debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n", | 518 | debug_log("[cmd %x] transferred %d bytes, padded %d bytes, resid: %u\n", |
| 484 | rq->cmd[0], done, bcount); | 519 | rq->cmd[0], done, bcount, rq->resid_len); |
| 485 | 520 | ||
| 486 | /* And set the interrupt handler again */ | 521 | /* And set the interrupt handler again */ |
| 487 | ide_set_handler(drive, ide_pc_intr, timeout); | 522 | ide_set_handler(drive, ide_pc_intr, timeout); |
| @@ -515,13 +550,13 @@ static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason) | |||
| 515 | 550 | ||
| 516 | while (retries-- && ((ireason & ATAPI_COD) == 0 || | 551 | while (retries-- && ((ireason & ATAPI_COD) == 0 || |
| 517 | (ireason & ATAPI_IO))) { | 552 | (ireason & ATAPI_IO))) { |
| 518 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " | 553 | printk(KERN_ERR PFX "%s: (IO,CoD != (0,1) while issuing " |
| 519 | "a packet command, retrying\n", drive->name); | 554 | "a packet command, retrying\n", drive->name); |
| 520 | udelay(100); | 555 | udelay(100); |
| 521 | ireason = ide_read_ireason(drive); | 556 | ireason = ide_read_ireason(drive); |
| 522 | if (retries == 0) { | 557 | if (retries == 0) { |
| 523 | printk(KERN_ERR "%s: (IO,CoD != (0,1) while issuing " | 558 | printk(KERN_ERR PFX "%s: (IO,CoD != (0,1) while issuing" |
| 524 | "a packet command, ignoring\n", | 559 | " a packet command, ignoring\n", |
| 525 | drive->name); | 560 | drive->name); |
| 526 | ireason |= ATAPI_COD; | 561 | ireason |= ATAPI_COD; |
| 527 | ireason &= ~ATAPI_IO; | 562 | ireason &= ~ATAPI_IO; |
| @@ -552,7 +587,7 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) | |||
| 552 | u8 ireason; | 587 | u8 ireason; |
| 553 | 588 | ||
| 554 | if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) { | 589 | if (ide_wait_stat(&startstop, drive, ATA_DRQ, ATA_BUSY, WAIT_READY)) { |
| 555 | printk(KERN_ERR "%s: Strange, packet command initiated yet " | 590 | printk(KERN_ERR PFX "%s: Strange, packet command initiated yet " |
| 556 | "DRQ isn't asserted\n", drive->name); | 591 | "DRQ isn't asserted\n", drive->name); |
| 557 | return startstop; | 592 | return startstop; |
| 558 | } | 593 | } |
| @@ -594,8 +629,8 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive) | |||
| 594 | ireason = ide_wait_ireason(drive, ireason); | 629 | ireason = ide_wait_ireason(drive, ireason); |
| 595 | 630 | ||
| 596 | if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { | 631 | if ((ireason & ATAPI_COD) == 0 || (ireason & ATAPI_IO)) { |
| 597 | printk(KERN_ERR "%s: (IO,CoD) != (0,1) while issuing " | 632 | printk(KERN_ERR PFX "%s: (IO,CoD) != (0,1) while " |
| 598 | "a packet command\n", drive->name); | 633 | "issuing a packet command\n", drive->name); |
| 599 | 634 | ||
| 600 | return ide_do_reset(drive); | 635 | return ide_do_reset(drive); |
| 601 | } | 636 | } |
| @@ -633,7 +668,7 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 633 | ide_hwif_t *hwif = drive->hwif; | 668 | ide_hwif_t *hwif = drive->hwif; |
| 634 | ide_expiry_t *expiry = NULL; | 669 | ide_expiry_t *expiry = NULL; |
| 635 | struct request *rq = hwif->rq; | 670 | struct request *rq = hwif->rq; |
| 636 | unsigned int timeout; | 671 | unsigned int timeout, bytes; |
| 637 | u16 bcount; | 672 | u16 bcount; |
| 638 | u8 valid_tf; | 673 | u8 valid_tf; |
| 639 | u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); | 674 | u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT); |
| @@ -649,13 +684,14 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 649 | } else { | 684 | } else { |
| 650 | pc = drive->pc; | 685 | pc = drive->pc; |
| 651 | 686 | ||
| 652 | /* We haven't transferred any data yet */ | ||
| 653 | pc->xferred = 0; | ||
| 654 | |||
| 655 | valid_tf = IDE_VALID_DEVICE; | 687 | valid_tf = IDE_VALID_DEVICE; |
| 656 | bcount = ((drive->media == ide_tape) ? | 688 | bytes = blk_rq_bytes(rq); |
| 657 | pc->req_xfer : | 689 | bcount = ((drive->media == ide_tape) ? bytes |
| 658 | min(pc->req_xfer, 63 * 1024)); | 690 | : min_t(unsigned int, |
| 691 | bytes, 63 * 1024)); | ||
| 692 | |||
| 693 | /* We haven't transferred any data yet */ | ||
| 694 | rq->resid_len = bcount; | ||
| 659 | 695 | ||
| 660 | if (pc->flags & PC_FLAG_DMA_ERROR) { | 696 | if (pc->flags & PC_FLAG_DMA_ERROR) { |
| 661 | pc->flags &= ~PC_FLAG_DMA_ERROR; | 697 | pc->flags &= ~PC_FLAG_DMA_ERROR; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 424140c6c400..4a19686fcfe9 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
| @@ -92,16 +92,16 @@ static void cdrom_saw_media_change(ide_drive_t *drive) | |||
| 92 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; | 92 | drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID; |
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, | 95 | static int cdrom_log_sense(ide_drive_t *drive, struct request *rq) |
| 96 | struct request_sense *sense) | ||
| 97 | { | 96 | { |
| 97 | struct request_sense *sense = &drive->sense_data; | ||
| 98 | int log = 0; | 98 | int log = 0; |
| 99 | 99 | ||
| 100 | ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); | ||
| 101 | |||
| 102 | if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) | 100 | if (!sense || !rq || (rq->cmd_flags & REQ_QUIET)) |
| 103 | return 0; | 101 | return 0; |
| 104 | 102 | ||
| 103 | ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key); | ||
| 104 | |||
| 105 | switch (sense->sense_key) { | 105 | switch (sense->sense_key) { |
| 106 | case NO_SENSE: | 106 | case NO_SENSE: |
| 107 | case RECOVERED_ERROR: | 107 | case RECOVERED_ERROR: |
| @@ -140,12 +140,12 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq, | |||
| 140 | } | 140 | } |
| 141 | 141 | ||
| 142 | static void cdrom_analyze_sense_data(ide_drive_t *drive, | 142 | static void cdrom_analyze_sense_data(ide_drive_t *drive, |
| 143 | struct request *failed_command, | 143 | struct request *failed_command) |
| 144 | struct request_sense *sense) | ||
| 145 | { | 144 | { |
| 145 | struct request_sense *sense = &drive->sense_data; | ||
| 146 | struct cdrom_info *info = drive->driver_data; | ||
| 146 | unsigned long sector; | 147 | unsigned long sector; |
| 147 | unsigned long bio_sectors; | 148 | unsigned long bio_sectors; |
| 148 | struct cdrom_info *info = drive->driver_data; | ||
| 149 | 149 | ||
| 150 | ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", | 150 | ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x", |
| 151 | sense->error_code, sense->sense_key); | 151 | sense->error_code, sense->sense_key); |
| @@ -154,7 +154,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, | |||
| 154 | ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", | 154 | ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x", |
| 155 | failed_command->cmd[0]); | 155 | failed_command->cmd[0]); |
| 156 | 156 | ||
| 157 | if (!cdrom_log_sense(drive, failed_command, sense)) | 157 | if (!cdrom_log_sense(drive, failed_command)) |
| 158 | return; | 158 | return; |
| 159 | 159 | ||
| 160 | /* | 160 | /* |
| @@ -225,15 +225,14 @@ static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq) | |||
| 225 | * sense pointer set. | 225 | * sense pointer set. |
| 226 | */ | 226 | */ |
| 227 | memcpy(failed->sense, sense, 18); | 227 | memcpy(failed->sense, sense, 18); |
| 228 | sense = failed->sense; | ||
| 229 | failed->sense_len = rq->sense_len; | 228 | failed->sense_len = rq->sense_len; |
| 230 | } | 229 | } |
| 231 | cdrom_analyze_sense_data(drive, failed, sense); | 230 | cdrom_analyze_sense_data(drive, failed); |
| 232 | 231 | ||
| 233 | if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) | 232 | if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed))) |
| 234 | BUG(); | 233 | BUG(); |
| 235 | } else | 234 | } else |
| 236 | cdrom_analyze_sense_data(drive, NULL, sense); | 235 | cdrom_analyze_sense_data(drive, NULL); |
| 237 | } | 236 | } |
| 238 | 237 | ||
| 239 | 238 | ||
| @@ -410,50 +409,6 @@ end_request: | |||
| 410 | return 2; | 409 | return 2; |
| 411 | } | 410 | } |
| 412 | 411 | ||
| 413 | /* | ||
| 414 | * Check the contents of the interrupt reason register from the cdrom | ||
| 415 | * and attempt to recover if there are problems. Returns 0 if everything's | ||
| 416 | * ok; nonzero if the request has been terminated. | ||
| 417 | */ | ||
| 418 | static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq, | ||
| 419 | int len, int ireason, int rw) | ||
| 420 | { | ||
| 421 | ide_hwif_t *hwif = drive->hwif; | ||
| 422 | |||
| 423 | ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw); | ||
| 424 | |||
| 425 | /* | ||
| 426 | * ireason == 0: the drive wants to receive data from us | ||
| 427 | * ireason == 2: the drive is expecting to transfer data to us | ||
| 428 | */ | ||
| 429 | if (ireason == (!rw << 1)) | ||
| 430 | return 0; | ||
| 431 | else if (ireason == (rw << 1)) { | ||
| 432 | |||
| 433 | /* whoops... */ | ||
| 434 | printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n", | ||
| 435 | drive->name, __func__); | ||
| 436 | |||
| 437 | ide_pad_transfer(drive, rw, len); | ||
| 438 | } else if (rw == 0 && ireason == 1) { | ||
| 439 | /* | ||
| 440 | * Some drives (ASUS) seem to tell us that status info is | ||
| 441 | * available. Just get it and ignore. | ||
| 442 | */ | ||
| 443 | (void)hwif->tp_ops->read_status(hwif); | ||
| 444 | return 0; | ||
| 445 | } else { | ||
| 446 | /* drive wants a command packet, or invalid ireason... */ | ||
| 447 | printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n", | ||
| 448 | drive->name, __func__, ireason); | ||
| 449 | } | ||
| 450 | |||
| 451 | if (rq->cmd_type == REQ_TYPE_ATA_PC) | ||
| 452 | rq->cmd_flags |= REQ_FAILED; | ||
| 453 | |||
| 454 | return -1; | ||
| 455 | } | ||
| 456 | |||
| 457 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) | 412 | static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd) |
| 458 | { | 413 | { |
| 459 | struct request *rq = cmd->rq; | 414 | struct request *rq = cmd->rq; |
| @@ -645,8 +600,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
| 645 | goto out_end; | 600 | goto out_end; |
| 646 | } | 601 | } |
| 647 | 602 | ||
| 648 | /* check which way to transfer data */ | 603 | rc = ide_check_ireason(drive, rq, len, ireason, write); |
| 649 | rc = ide_cd_check_ireason(drive, rq, len, ireason, write); | ||
| 650 | if (rc) | 604 | if (rc) |
| 651 | goto out_end; | 605 | goto out_end; |
| 652 | 606 | ||
| @@ -713,7 +667,7 @@ out_end: | |||
| 713 | rq->errors = -EIO; | 667 | rq->errors = -EIO; |
| 714 | } | 668 | } |
| 715 | 669 | ||
| 716 | if (uptodate == 0) | 670 | if (uptodate == 0 && rq->bio) |
| 717 | ide_cd_error_cmd(drive, cmd); | 671 | ide_cd_error_cmd(drive, cmd); |
| 718 | 672 | ||
| 719 | /* make sure it's fully ended */ | 673 | /* make sure it's fully ended */ |
| @@ -831,12 +785,8 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
| 831 | /* right now this can only be a reset... */ | 785 | /* right now this can only be a reset... */ |
| 832 | uptodate = 1; | 786 | uptodate = 1; |
| 833 | goto out_end; | 787 | goto out_end; |
| 834 | } else { | 788 | } else |
| 835 | blk_dump_rq_flags(rq, DRV_NAME " bad flags"); | 789 | BUG(); |
| 836 | if (rq->errors == 0) | ||
| 837 | rq->errors = -EIO; | ||
| 838 | goto out_end; | ||
| 839 | } | ||
| 840 | 790 | ||
| 841 | /* prepare sense request for this command */ | 791 | /* prepare sense request for this command */ |
| 842 | ide_prep_sense(drive, rq); | 792 | ide_prep_sense(drive, rq); |
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 6a1de2169709..695181120cdb 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
| @@ -184,14 +184,7 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
| 184 | ide_hwif_t *hwif = drive->hwif; | 184 | ide_hwif_t *hwif = drive->hwif; |
| 185 | 185 | ||
| 186 | BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED); | 186 | BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED); |
| 187 | 187 | BUG_ON(!blk_fs_request(rq)); | |
| 188 | if (!blk_fs_request(rq)) { | ||
| 189 | blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command"); | ||
| 190 | if (rq->errors == 0) | ||
| 191 | rq->errors = -EIO; | ||
| 192 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); | ||
| 193 | return ide_stopped; | ||
| 194 | } | ||
| 195 | 188 | ||
| 196 | ledtrig_ide_activity(); | 189 | ledtrig_ide_activity(); |
| 197 | 190 | ||
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 650981758f15..8b3f204f7d73 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
| @@ -77,7 +77,8 @@ static int ide_floppy_callback(ide_drive_t *drive, int dsc) | |||
| 77 | (rq && blk_pc_request(rq))) | 77 | (rq && blk_pc_request(rq))) |
| 78 | uptodate = 1; /* FIXME */ | 78 | uptodate = 1; /* FIXME */ |
| 79 | else if (pc->c[0] == GPCMD_REQUEST_SENSE) { | 79 | else if (pc->c[0] == GPCMD_REQUEST_SENSE) { |
| 80 | u8 *buf = pc->buf; | 80 | |
| 81 | u8 *buf = bio_data(rq->bio); | ||
| 81 | 82 | ||
| 82 | if (!pc->error) { | 83 | if (!pc->error) { |
| 83 | floppy->sense_key = buf[2] & 0x0F; | 84 | floppy->sense_key = buf[2] & 0x0F; |
| @@ -209,8 +210,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive, | |||
| 209 | pc->rq = rq; | 210 | pc->rq = rq; |
| 210 | if (rq->cmd_flags & REQ_RW) | 211 | if (rq->cmd_flags & REQ_RW) |
| 211 | pc->flags |= PC_FLAG_WRITING; | 212 | pc->flags |= PC_FLAG_WRITING; |
| 212 | pc->buf = NULL; | 213 | |
| 213 | pc->req_xfer = pc->buf_size = blocks * floppy->block_size; | ||
| 214 | pc->flags |= PC_FLAG_DMA_OK; | 214 | pc->flags |= PC_FLAG_DMA_OK; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| @@ -225,9 +225,6 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy, | |||
| 225 | if (rq_data_dir(rq) == WRITE) | 225 | if (rq_data_dir(rq) == WRITE) |
| 226 | pc->flags |= PC_FLAG_WRITING; | 226 | pc->flags |= PC_FLAG_WRITING; |
| 227 | } | 227 | } |
| 228 | /* pio will be performed by ide_pio_bytes() which handles sg fine */ | ||
| 229 | pc->buf = NULL; | ||
| 230 | pc->req_xfer = pc->buf_size = blk_rq_bytes(rq); | ||
| 231 | } | 228 | } |
| 232 | 229 | ||
| 233 | static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, | 230 | static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, |
| @@ -272,10 +269,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, | |||
| 272 | } else if (blk_pc_request(rq)) { | 269 | } else if (blk_pc_request(rq)) { |
| 273 | pc = &floppy->queued_pc; | 270 | pc = &floppy->queued_pc; |
| 274 | idefloppy_blockpc_cmd(floppy, pc, rq); | 271 | idefloppy_blockpc_cmd(floppy, pc, rq); |
| 275 | } else { | 272 | } else |
| 276 | blk_dump_rq_flags(rq, PFX "unsupported command in queue"); | 273 | BUG(); |
| 277 | goto out_end; | ||
| 278 | } | ||
| 279 | 274 | ||
| 280 | ide_prep_sense(drive, rq); | 275 | ide_prep_sense(drive, rq); |
| 281 | 276 | ||
| @@ -286,8 +281,8 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive, | |||
| 286 | 281 | ||
| 287 | cmd.rq = rq; | 282 | cmd.rq = rq; |
| 288 | 283 | ||
| 289 | if (blk_fs_request(rq) || pc->req_xfer) { | 284 | if (blk_fs_request(rq) || blk_rq_bytes(rq)) { |
| 290 | ide_init_sg_cmd(&cmd, pc->req_xfer); | 285 | ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); |
| 291 | ide_map_sg(drive, &cmd); | 286 | ide_map_sg(drive, &cmd); |
| 292 | } | 287 | } |
| 293 | 288 | ||
| @@ -311,33 +306,33 @@ static int ide_floppy_get_flexible_disk_page(ide_drive_t *drive, | |||
| 311 | { | 306 | { |
| 312 | struct ide_disk_obj *floppy = drive->driver_data; | 307 | struct ide_disk_obj *floppy = drive->driver_data; |
| 313 | struct gendisk *disk = floppy->disk; | 308 | struct gendisk *disk = floppy->disk; |
| 314 | u8 *page; | 309 | u8 *page, buf[40]; |
| 315 | int capacity, lba_capacity; | 310 | int capacity, lba_capacity; |
| 316 | u16 transfer_rate, sector_size, cyls, rpm; | 311 | u16 transfer_rate, sector_size, cyls, rpm; |
| 317 | u8 heads, sectors; | 312 | u8 heads, sectors; |
| 318 | 313 | ||
| 319 | ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); | 314 | ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_FLEXIBLE_DISK_PAGE); |
| 320 | 315 | ||
| 321 | if (ide_queue_pc_tail(drive, disk, pc)) { | 316 | if (ide_queue_pc_tail(drive, disk, pc, buf, pc->req_xfer)) { |
| 322 | printk(KERN_ERR PFX "Can't get flexible disk page params\n"); | 317 | printk(KERN_ERR PFX "Can't get flexible disk page params\n"); |
| 323 | return 1; | 318 | return 1; |
| 324 | } | 319 | } |
| 325 | 320 | ||
| 326 | if (pc->buf[3] & 0x80) | 321 | if (buf[3] & 0x80) |
| 327 | drive->dev_flags |= IDE_DFLAG_WP; | 322 | drive->dev_flags |= IDE_DFLAG_WP; |
| 328 | else | 323 | else |
| 329 | drive->dev_flags &= ~IDE_DFLAG_WP; | 324 | drive->dev_flags &= ~IDE_DFLAG_WP; |
| 330 | 325 | ||
| 331 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); | 326 | set_disk_ro(disk, !!(drive->dev_flags & IDE_DFLAG_WP)); |
| 332 | 327 | ||
| 333 | page = &pc->buf[8]; | 328 | page = &buf[8]; |
| 334 | 329 | ||
| 335 | transfer_rate = be16_to_cpup((__be16 *)&pc->buf[8 + 2]); | 330 | transfer_rate = be16_to_cpup((__be16 *)&buf[8 + 2]); |
| 336 | sector_size = be16_to_cpup((__be16 *)&pc->buf[8 + 6]); | 331 | sector_size = be16_to_cpup((__be16 *)&buf[8 + 6]); |
| 337 | cyls = be16_to_cpup((__be16 *)&pc->buf[8 + 8]); | 332 | cyls = be16_to_cpup((__be16 *)&buf[8 + 8]); |
| 338 | rpm = be16_to_cpup((__be16 *)&pc->buf[8 + 28]); | 333 | rpm = be16_to_cpup((__be16 *)&buf[8 + 28]); |
| 339 | heads = pc->buf[8 + 4]; | 334 | heads = buf[8 + 4]; |
| 340 | sectors = pc->buf[8 + 5]; | 335 | sectors = buf[8 + 5]; |
| 341 | 336 | ||
| 342 | capacity = cyls * heads * sectors * sector_size; | 337 | capacity = cyls * heads * sectors * sector_size; |
| 343 | 338 | ||
| @@ -387,22 +382,19 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
| 387 | drive->capacity64 = 0; | 382 | drive->capacity64 = 0; |
| 388 | 383 | ||
| 389 | ide_floppy_create_read_capacity_cmd(&pc); | 384 | ide_floppy_create_read_capacity_cmd(&pc); |
| 390 | pc.buf = &pc_buf[0]; | 385 | if (ide_queue_pc_tail(drive, disk, &pc, pc_buf, pc.req_xfer)) { |
| 391 | pc.buf_size = sizeof(pc_buf); | ||
| 392 | |||
| 393 | if (ide_queue_pc_tail(drive, disk, &pc)) { | ||
| 394 | printk(KERN_ERR PFX "Can't get floppy parameters\n"); | 386 | printk(KERN_ERR PFX "Can't get floppy parameters\n"); |
| 395 | return 1; | 387 | return 1; |
| 396 | } | 388 | } |
| 397 | header_len = pc.buf[3]; | 389 | header_len = pc_buf[3]; |
| 398 | cap_desc = &pc.buf[4]; | 390 | cap_desc = &pc_buf[4]; |
| 399 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ | 391 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ |
| 400 | 392 | ||
| 401 | for (i = 0; i < desc_cnt; i++) { | 393 | for (i = 0; i < desc_cnt; i++) { |
| 402 | unsigned int desc_start = 4 + i*8; | 394 | unsigned int desc_start = 4 + i*8; |
| 403 | 395 | ||
| 404 | blocks = be32_to_cpup((__be32 *)&pc.buf[desc_start]); | 396 | blocks = be32_to_cpup((__be32 *)&pc_buf[desc_start]); |
| 405 | length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]); | 397 | length = be16_to_cpup((__be16 *)&pc_buf[desc_start + 6]); |
| 406 | 398 | ||
| 407 | ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " | 399 | ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, " |
| 408 | "%d sector size", | 400 | "%d sector size", |
| @@ -415,7 +407,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
| 415 | * the code below is valid only for the 1st descriptor, ie i=0 | 407 | * the code below is valid only for the 1st descriptor, ie i=0 |
| 416 | */ | 408 | */ |
| 417 | 409 | ||
| 418 | switch (pc.buf[desc_start + 4] & 0x03) { | 410 | switch (pc_buf[desc_start + 4] & 0x03) { |
| 419 | /* Clik! drive returns this instead of CAPACITY_CURRENT */ | 411 | /* Clik! drive returns this instead of CAPACITY_CURRENT */ |
| 420 | case CAPACITY_UNFORMATTED: | 412 | case CAPACITY_UNFORMATTED: |
| 421 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) | 413 | if (!(drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE)) |
| @@ -464,7 +456,7 @@ static int ide_floppy_get_capacity(ide_drive_t *drive) | |||
| 464 | break; | 456 | break; |
| 465 | } | 457 | } |
| 466 | ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d", | 458 | ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d", |
| 467 | pc.buf[desc_start + 4] & 0x03); | 459 | pc_buf[desc_start + 4] & 0x03); |
| 468 | } | 460 | } |
| 469 | 461 | ||
| 470 | /* Clik! disk does not support get_flexible_disk_page */ | 462 | /* Clik! disk does not support get_flexible_disk_page */ |
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c index cd8a42027ede..9c2288234dea 100644 --- a/drivers/ide/ide-floppy_ioctl.c +++ b/drivers/ide/ide-floppy_ioctl.c | |||
| @@ -47,15 +47,13 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, | |||
| 47 | return -EINVAL; | 47 | return -EINVAL; |
| 48 | 48 | ||
| 49 | ide_floppy_create_read_capacity_cmd(pc); | 49 | ide_floppy_create_read_capacity_cmd(pc); |
| 50 | pc->buf = &pc_buf[0]; | ||
| 51 | pc->buf_size = sizeof(pc_buf); | ||
| 52 | 50 | ||
| 53 | if (ide_queue_pc_tail(drive, floppy->disk, pc)) { | 51 | if (ide_queue_pc_tail(drive, floppy->disk, pc, pc_buf, pc->req_xfer)) { |
| 54 | printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); | 52 | printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n"); |
| 55 | return -EIO; | 53 | return -EIO; |
| 56 | } | 54 | } |
| 57 | 55 | ||
| 58 | header_len = pc->buf[3]; | 56 | header_len = pc_buf[3]; |
| 59 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ | 57 | desc_cnt = header_len / 8; /* capacity descriptor of 8 bytes */ |
| 60 | 58 | ||
| 61 | u_index = 0; | 59 | u_index = 0; |
| @@ -72,8 +70,8 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, | |||
| 72 | if (u_index >= u_array_size) | 70 | if (u_index >= u_array_size) |
| 73 | break; /* User-supplied buffer too small */ | 71 | break; /* User-supplied buffer too small */ |
| 74 | 72 | ||
| 75 | blocks = be32_to_cpup((__be32 *)&pc->buf[desc_start]); | 73 | blocks = be32_to_cpup((__be32 *)&pc_buf[desc_start]); |
| 76 | length = be16_to_cpup((__be16 *)&pc->buf[desc_start + 6]); | 74 | length = be16_to_cpup((__be16 *)&pc_buf[desc_start + 6]); |
| 77 | 75 | ||
| 78 | if (put_user(blocks, argp)) | 76 | if (put_user(blocks, argp)) |
| 79 | return -EFAULT; | 77 | return -EFAULT; |
| @@ -94,40 +92,42 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive, | |||
| 94 | return 0; | 92 | return 0; |
| 95 | } | 93 | } |
| 96 | 94 | ||
| 97 | static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, int b, | 95 | static void ide_floppy_create_format_unit_cmd(struct ide_atapi_pc *pc, |
| 98 | int l, int flags) | 96 | u8 *buf, int b, int l, |
| 97 | int flags) | ||
| 99 | { | 98 | { |
| 100 | ide_init_pc(pc); | 99 | ide_init_pc(pc); |
| 101 | pc->c[0] = GPCMD_FORMAT_UNIT; | 100 | pc->c[0] = GPCMD_FORMAT_UNIT; |
| 102 | pc->c[1] = 0x17; | 101 | pc->c[1] = 0x17; |
| 103 | 102 | ||
| 104 | memset(pc->buf, 0, 12); | 103 | memset(buf, 0, 12); |
| 105 | pc->buf[1] = 0xA2; | 104 | buf[1] = 0xA2; |
| 106 | /* Default format list header, u8 1: FOV/DCRT/IMM bits set */ | 105 | /* Default format list header, u8 1: FOV/DCRT/IMM bits set */ |
| 107 | 106 | ||
| 108 | if (flags & 1) /* Verify bit on... */ | 107 | if (flags & 1) /* Verify bit on... */ |
| 109 | pc->buf[1] ^= 0x20; /* ... turn off DCRT bit */ | 108 | buf[1] ^= 0x20; /* ... turn off DCRT bit */ |
| 110 | pc->buf[3] = 8; | 109 | buf[3] = 8; |
| 111 | 110 | ||
| 112 | put_unaligned(cpu_to_be32(b), (unsigned int *)(&pc->buf[4])); | 111 | put_unaligned(cpu_to_be32(b), (unsigned int *)(&buf[4])); |
| 113 | put_unaligned(cpu_to_be32(l), (unsigned int *)(&pc->buf[8])); | 112 | put_unaligned(cpu_to_be32(l), (unsigned int *)(&buf[8])); |
| 114 | pc->buf_size = 12; | 113 | pc->req_xfer = 12; |
| 115 | pc->flags |= PC_FLAG_WRITING; | 114 | pc->flags |= PC_FLAG_WRITING; |
| 116 | } | 115 | } |
| 117 | 116 | ||
| 118 | static int ide_floppy_get_sfrp_bit(ide_drive_t *drive, struct ide_atapi_pc *pc) | 117 | static int ide_floppy_get_sfrp_bit(ide_drive_t *drive, struct ide_atapi_pc *pc) |
| 119 | { | 118 | { |
| 120 | struct ide_disk_obj *floppy = drive->driver_data; | 119 | struct ide_disk_obj *floppy = drive->driver_data; |
| 120 | u8 buf[20]; | ||
| 121 | 121 | ||
| 122 | drive->atapi_flags &= ~IDE_AFLAG_SRFP; | 122 | drive->atapi_flags &= ~IDE_AFLAG_SRFP; |
| 123 | 123 | ||
| 124 | ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE); | 124 | ide_floppy_create_mode_sense_cmd(pc, IDEFLOPPY_CAPABILITIES_PAGE); |
| 125 | pc->flags |= PC_FLAG_SUPPRESS_ERROR; | 125 | pc->flags |= PC_FLAG_SUPPRESS_ERROR; |
| 126 | 126 | ||
| 127 | if (ide_queue_pc_tail(drive, floppy->disk, pc)) | 127 | if (ide_queue_pc_tail(drive, floppy->disk, pc, buf, pc->req_xfer)) |
| 128 | return 1; | 128 | return 1; |
| 129 | 129 | ||
| 130 | if (pc->buf[8 + 2] & 0x40) | 130 | if (buf[8 + 2] & 0x40) |
| 131 | drive->atapi_flags |= IDE_AFLAG_SRFP; | 131 | drive->atapi_flags |= IDE_AFLAG_SRFP; |
| 132 | 132 | ||
| 133 | return 0; | 133 | return 0; |
| @@ -137,6 +137,7 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
| 137 | int __user *arg) | 137 | int __user *arg) |
| 138 | { | 138 | { |
| 139 | struct ide_disk_obj *floppy = drive->driver_data; | 139 | struct ide_disk_obj *floppy = drive->driver_data; |
| 140 | u8 buf[12]; | ||
| 140 | int blocks, length, flags, err = 0; | 141 | int blocks, length, flags, err = 0; |
| 141 | 142 | ||
| 142 | if (floppy->openers > 1) { | 143 | if (floppy->openers > 1) { |
| @@ -170,9 +171,9 @@ static int ide_floppy_format_unit(ide_drive_t *drive, struct ide_atapi_pc *pc, | |||
| 170 | } | 171 | } |
| 171 | 172 | ||
| 172 | ide_floppy_get_sfrp_bit(drive, pc); | 173 | ide_floppy_get_sfrp_bit(drive, pc); |
| 173 | ide_floppy_create_format_unit_cmd(pc, blocks, length, flags); | 174 | ide_floppy_create_format_unit_cmd(pc, buf, blocks, length, flags); |
| 174 | 175 | ||
| 175 | if (ide_queue_pc_tail(drive, floppy->disk, pc)) | 176 | if (ide_queue_pc_tail(drive, floppy->disk, pc, buf, pc->req_xfer)) |
| 176 | err = -EIO; | 177 | err = -EIO; |
| 177 | 178 | ||
| 178 | out: | 179 | out: |
| @@ -196,11 +197,13 @@ static int ide_floppy_get_format_progress(ide_drive_t *drive, | |||
| 196 | int __user *arg) | 197 | int __user *arg) |
| 197 | { | 198 | { |
| 198 | struct ide_disk_obj *floppy = drive->driver_data; | 199 | struct ide_disk_obj *floppy = drive->driver_data; |
| 200 | u8 sense_buf[18]; | ||
| 199 | int progress_indication = 0x10000; | 201 | int progress_indication = 0x10000; |
| 200 | 202 | ||
| 201 | if (drive->atapi_flags & IDE_AFLAG_SRFP) { | 203 | if (drive->atapi_flags & IDE_AFLAG_SRFP) { |
| 202 | ide_create_request_sense_cmd(drive, pc); | 204 | ide_create_request_sense_cmd(drive, pc); |
| 203 | if (ide_queue_pc_tail(drive, floppy->disk, pc)) | 205 | if (ide_queue_pc_tail(drive, floppy->disk, pc, sense_buf, |
| 206 | pc->req_xfer)) | ||
| 204 | return -EIO; | 207 | return -EIO; |
| 205 | 208 | ||
| 206 | if (floppy->sense_key == 2 && | 209 | if (floppy->sense_key == 2 && |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 272cc38f6dbe..1059f809b809 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
| @@ -683,8 +683,9 @@ void ide_timer_expiry (unsigned long data) | |||
| 683 | } else if (drive_is_ready(drive)) { | 683 | } else if (drive_is_ready(drive)) { |
| 684 | if (drive->waiting_for_dma) | 684 | if (drive->waiting_for_dma) |
| 685 | hwif->dma_ops->dma_lost_irq(drive); | 685 | hwif->dma_ops->dma_lost_irq(drive); |
| 686 | if (hwif->ack_intr) | 686 | if (hwif->port_ops && hwif->port_ops->clear_irq) |
| 687 | hwif->ack_intr(hwif); | 687 | hwif->port_ops->clear_irq(drive); |
| 688 | |||
| 688 | printk(KERN_WARNING "%s: lost interrupt\n", | 689 | printk(KERN_WARNING "%s: lost interrupt\n", |
| 689 | drive->name); | 690 | drive->name); |
| 690 | startstop = handler(drive); | 691 | startstop = handler(drive); |
| @@ -803,7 +804,8 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
| 803 | 804 | ||
| 804 | spin_lock_irqsave(&hwif->lock, flags); | 805 | spin_lock_irqsave(&hwif->lock, flags); |
| 805 | 806 | ||
| 806 | if (hwif->ack_intr && hwif->ack_intr(hwif) == 0) | 807 | if (hwif->port_ops && hwif->port_ops->test_irq && |
| 808 | hwif->port_ops->test_irq(hwif) == 0) | ||
| 807 | goto out; | 809 | goto out; |
| 808 | 810 | ||
| 809 | handler = hwif->handler; | 811 | handler = hwif->handler; |
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index 5991b23793f2..82f252c3ee6e 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c | |||
| @@ -118,7 +118,6 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 118 | u8 args[4], xfer_rate = 0; | 118 | u8 args[4], xfer_rate = 0; |
| 119 | struct ide_cmd cmd; | 119 | struct ide_cmd cmd; |
| 120 | struct ide_taskfile *tf = &cmd.tf; | 120 | struct ide_taskfile *tf = &cmd.tf; |
| 121 | u16 *id = drive->id; | ||
| 122 | 121 | ||
| 123 | if (NULL == (void *) arg) { | 122 | if (NULL == (void *) arg) { |
| 124 | struct request *rq; | 123 | struct request *rq; |
| @@ -161,14 +160,10 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) | |||
| 161 | 160 | ||
| 162 | if (tf->command == ATA_CMD_SET_FEATURES && | 161 | if (tf->command == ATA_CMD_SET_FEATURES && |
| 163 | tf->feature == SETFEATURES_XFER && | 162 | tf->feature == SETFEATURES_XFER && |
| 164 | tf->nsect >= XFER_SW_DMA_0 && | 163 | tf->nsect >= XFER_SW_DMA_0) { |
| 165 | (id[ATA_ID_UDMA_MODES] || | 164 | xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6); |
| 166 | id[ATA_ID_MWDMA_MODES] || | 165 | if (xfer_rate != tf->nsect) { |
| 167 | id[ATA_ID_SWDMA_MODES])) { | 166 | err = -EINVAL; |
| 168 | xfer_rate = args[1]; | ||
| 169 | if (tf->nsect > XFER_UDMA_2 && !eighty_ninty_three(drive)) { | ||
| 170 | printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " | ||
| 171 | "be set\n", drive->name); | ||
| 172 | goto abort; | 167 | goto abort; |
| 173 | } | 168 | } |
| 174 | } | 169 | } |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 79e0af3fd158..51af4eea0d36 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
| @@ -1170,7 +1170,6 @@ static void ide_init_port_hw(ide_hwif_t *hwif, struct ide_hw *hw) | |||
| 1170 | hwif->irq = hw->irq; | 1170 | hwif->irq = hw->irq; |
| 1171 | hwif->dev = hw->dev; | 1171 | hwif->dev = hw->dev; |
| 1172 | hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; | 1172 | hwif->gendev.parent = hw->parent ? hw->parent : hw->dev; |
| 1173 | hwif->ack_intr = hw->ack_intr; | ||
| 1174 | hwif->config_data = hw->config; | 1173 | hwif->config_data = hw->config; |
| 1175 | } | 1174 | } |
| 1176 | 1175 | ||
| @@ -1378,6 +1377,9 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
| 1378 | 1377 | ||
| 1379 | ide_init_port(hwif, i & 1, d); | 1378 | ide_init_port(hwif, i & 1, d); |
| 1380 | ide_port_cable_detect(hwif); | 1379 | ide_port_cable_detect(hwif); |
| 1380 | |||
| 1381 | hwif->port_flags |= IDE_PFLAG_PROBING; | ||
| 1382 | |||
| 1381 | ide_port_init_devices(hwif); | 1383 | ide_port_init_devices(hwif); |
| 1382 | } | 1384 | } |
| 1383 | 1385 | ||
| @@ -1388,6 +1390,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d, | |||
| 1388 | if (ide_probe_port(hwif) == 0) | 1390 | if (ide_probe_port(hwif) == 0) |
| 1389 | hwif->present = 1; | 1391 | hwif->present = 1; |
| 1390 | 1392 | ||
| 1393 | hwif->port_flags &= ~IDE_PFLAG_PROBING; | ||
| 1394 | |||
| 1391 | if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 || | 1395 | if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 || |
| 1392 | hwif->mate == NULL || hwif->mate->present == 0) { | 1396 | hwif->mate == NULL || hwif->mate->present == 0) { |
| 1393 | if (ide_register_port(hwif)) { | 1397 | if (ide_register_port(hwif)) { |
| @@ -1569,11 +1573,20 @@ EXPORT_SYMBOL_GPL(ide_host_remove); | |||
| 1569 | 1573 | ||
| 1570 | void ide_port_scan(ide_hwif_t *hwif) | 1574 | void ide_port_scan(ide_hwif_t *hwif) |
| 1571 | { | 1575 | { |
| 1576 | int rc; | ||
| 1577 | |||
| 1572 | ide_port_apply_params(hwif); | 1578 | ide_port_apply_params(hwif); |
| 1573 | ide_port_cable_detect(hwif); | 1579 | ide_port_cable_detect(hwif); |
| 1580 | |||
| 1581 | hwif->port_flags |= IDE_PFLAG_PROBING; | ||
| 1582 | |||
| 1574 | ide_port_init_devices(hwif); | 1583 | ide_port_init_devices(hwif); |
| 1575 | 1584 | ||
| 1576 | if (ide_probe_port(hwif) < 0) | 1585 | rc = ide_probe_port(hwif); |
| 1586 | |||
| 1587 | hwif->port_flags &= ~IDE_PFLAG_PROBING; | ||
| 1588 | |||
| 1589 | if (rc < 0) | ||
| 1577 | return; | 1590 | return; |
| 1578 | 1591 | ||
| 1579 | hwif->present = 1; | 1592 | hwif->present = 1; |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 4b447a8a49d4..013dc595fab6 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
| @@ -279,10 +279,12 @@ static void ide_tape_put(struct ide_tape_obj *tape) | |||
| 279 | * called on each failed packet command retry to analyze the request sense. We | 279 | * called on each failed packet command retry to analyze the request sense. We |
| 280 | * currently do not utilize this information. | 280 | * currently do not utilize this information. |
| 281 | */ | 281 | */ |
| 282 | static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | 282 | static void idetape_analyze_error(ide_drive_t *drive) |
| 283 | { | 283 | { |
| 284 | idetape_tape_t *tape = drive->driver_data; | 284 | idetape_tape_t *tape = drive->driver_data; |
| 285 | struct ide_atapi_pc *pc = drive->failed_pc; | 285 | struct ide_atapi_pc *pc = drive->failed_pc; |
| 286 | struct request *rq = drive->hwif->rq; | ||
| 287 | u8 *sense = bio_data(rq->bio); | ||
| 286 | 288 | ||
| 287 | tape->sense_key = sense[2] & 0xF; | 289 | tape->sense_key = sense[2] & 0xF; |
| 288 | tape->asc = sense[12]; | 290 | tape->asc = sense[12]; |
| @@ -291,11 +293,9 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | |||
| 291 | debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n", | 293 | debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n", |
| 292 | pc->c[0], tape->sense_key, tape->asc, tape->ascq); | 294 | pc->c[0], tape->sense_key, tape->asc, tape->ascq); |
| 293 | 295 | ||
| 294 | /* Correct pc->xferred by asking the tape. */ | 296 | /* correct remaining bytes to transfer */ |
| 295 | if (pc->flags & PC_FLAG_DMA_ERROR) | 297 | if (pc->flags & PC_FLAG_DMA_ERROR) |
| 296 | pc->xferred = pc->req_xfer - | 298 | rq->resid_len = tape->blk_size * get_unaligned_be32(&sense[3]); |
| 297 | tape->blk_size * | ||
| 298 | get_unaligned_be32(&sense[3]); | ||
| 299 | 299 | ||
| 300 | /* | 300 | /* |
| 301 | * If error was the result of a zero-length read or write command, | 301 | * If error was the result of a zero-length read or write command, |
| @@ -329,7 +329,7 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | |||
| 329 | pc->flags |= PC_FLAG_ABORT; | 329 | pc->flags |= PC_FLAG_ABORT; |
| 330 | } | 330 | } |
| 331 | if (!(pc->flags & PC_FLAG_ABORT) && | 331 | if (!(pc->flags & PC_FLAG_ABORT) && |
| 332 | pc->xferred) | 332 | (blk_rq_bytes(rq) - rq->resid_len)) |
| 333 | pc->retries = IDETAPE_MAX_PC_RETRIES + 1; | 333 | pc->retries = IDETAPE_MAX_PC_RETRIES + 1; |
| 334 | } | 334 | } |
| 335 | } | 335 | } |
| @@ -354,12 +354,13 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) | |||
| 354 | 354 | ||
| 355 | if (pc->c[0] == REQUEST_SENSE) { | 355 | if (pc->c[0] == REQUEST_SENSE) { |
| 356 | if (uptodate) | 356 | if (uptodate) |
| 357 | idetape_analyze_error(drive, pc->buf); | 357 | idetape_analyze_error(drive); |
| 358 | else | 358 | else |
| 359 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " | 359 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE " |
| 360 | "itself - Aborting request!\n"); | 360 | "itself - Aborting request!\n"); |
| 361 | } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { | 361 | } else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) { |
| 362 | int blocks = pc->xferred / tape->blk_size; | 362 | unsigned int blocks = |
| 363 | (blk_rq_bytes(rq) - rq->resid_len) / tape->blk_size; | ||
| 363 | 364 | ||
| 364 | tape->avg_size += blocks * tape->blk_size; | 365 | tape->avg_size += blocks * tape->blk_size; |
| 365 | 366 | ||
| @@ -371,38 +372,12 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) | |||
| 371 | } | 372 | } |
| 372 | 373 | ||
| 373 | tape->first_frame += blocks; | 374 | tape->first_frame += blocks; |
| 374 | rq->resid_len -= blocks * tape->blk_size; | ||
| 375 | 375 | ||
| 376 | if (pc->error) { | 376 | if (pc->error) { |
| 377 | uptodate = 0; | 377 | uptodate = 0; |
| 378 | err = pc->error; | 378 | err = pc->error; |
| 379 | } | 379 | } |
| 380 | } else if (pc->c[0] == READ_POSITION && uptodate) { | ||
| 381 | u8 *readpos = pc->buf; | ||
| 382 | |||
| 383 | debug_log(DBG_SENSE, "BOP - %s\n", | ||
| 384 | (readpos[0] & 0x80) ? "Yes" : "No"); | ||
| 385 | debug_log(DBG_SENSE, "EOP - %s\n", | ||
| 386 | (readpos[0] & 0x40) ? "Yes" : "No"); | ||
| 387 | |||
| 388 | if (readpos[0] & 0x4) { | ||
| 389 | printk(KERN_INFO "ide-tape: Block location is unknown" | ||
| 390 | "to the tape\n"); | ||
| 391 | clear_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), | ||
| 392 | &drive->atapi_flags); | ||
| 393 | uptodate = 0; | ||
| 394 | err = IDE_DRV_ERROR_GENERAL; | ||
| 395 | } else { | ||
| 396 | debug_log(DBG_SENSE, "Block Location - %u\n", | ||
| 397 | be32_to_cpup((__be32 *)&readpos[4])); | ||
| 398 | |||
| 399 | tape->partition = readpos[1]; | ||
| 400 | tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); | ||
| 401 | set_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), | ||
| 402 | &drive->atapi_flags); | ||
| 403 | } | ||
| 404 | } | 380 | } |
| 405 | |||
| 406 | rq->errors = err; | 381 | rq->errors = err; |
| 407 | 382 | ||
| 408 | return uptodate; | 383 | return uptodate; |
| @@ -477,6 +452,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, | |||
| 477 | struct ide_atapi_pc *pc) | 452 | struct ide_atapi_pc *pc) |
| 478 | { | 453 | { |
| 479 | idetape_tape_t *tape = drive->driver_data; | 454 | idetape_tape_t *tape = drive->driver_data; |
| 455 | struct request *rq = drive->hwif->rq; | ||
| 480 | 456 | ||
| 481 | if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) | 457 | if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE) |
| 482 | drive->failed_pc = pc; | 458 | drive->failed_pc = pc; |
| @@ -486,7 +462,6 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, | |||
| 486 | 462 | ||
| 487 | if (pc->retries > IDETAPE_MAX_PC_RETRIES || | 463 | if (pc->retries > IDETAPE_MAX_PC_RETRIES || |
| 488 | (pc->flags & PC_FLAG_ABORT)) { | 464 | (pc->flags & PC_FLAG_ABORT)) { |
| 489 | unsigned int done = blk_rq_bytes(drive->hwif->rq); | ||
| 490 | 465 | ||
| 491 | /* | 466 | /* |
| 492 | * We will "abort" retrying a packet command in case legitimate | 467 | * We will "abort" retrying a packet command in case legitimate |
| @@ -510,7 +485,7 @@ static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive, | |||
| 510 | 485 | ||
| 511 | drive->failed_pc = NULL; | 486 | drive->failed_pc = NULL; |
| 512 | drive->pc_callback(drive, 0); | 487 | drive->pc_callback(drive, 0); |
| 513 | ide_complete_rq(drive, -EIO, done); | 488 | ide_complete_rq(drive, -EIO, blk_rq_bytes(rq)); |
| 514 | return ide_stopped; | 489 | return ide_stopped; |
| 515 | } | 490 | } |
| 516 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); | 491 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); |
| @@ -579,15 +554,13 @@ static void ide_tape_create_rw_cmd(idetape_tape_t *tape, | |||
| 579 | struct ide_atapi_pc *pc, struct request *rq, | 554 | struct ide_atapi_pc *pc, struct request *rq, |
| 580 | u8 opcode) | 555 | u8 opcode) |
| 581 | { | 556 | { |
| 582 | unsigned int length = blk_rq_sectors(rq); | 557 | unsigned int length = blk_rq_sectors(rq) / (tape->blk_size >> 9); |
| 583 | 558 | ||
| 584 | ide_init_pc(pc); | 559 | ide_init_pc(pc); |
| 585 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); | 560 | put_unaligned(cpu_to_be32(length), (unsigned int *) &pc->c[1]); |
| 586 | pc->c[1] = 1; | 561 | pc->c[1] = 1; |
| 587 | pc->buf = NULL; | 562 | |
| 588 | pc->buf_size = length * tape->blk_size; | 563 | if (blk_rq_bytes(rq) == tape->buffer_size) |
| 589 | pc->req_xfer = pc->buf_size; | ||
| 590 | if (pc->req_xfer == tape->buffer_size) | ||
| 591 | pc->flags |= PC_FLAG_DMA_OK; | 564 | pc->flags |= PC_FLAG_DMA_OK; |
| 592 | 565 | ||
| 593 | if (opcode == READ_6) | 566 | if (opcode == READ_6) |
| @@ -613,15 +586,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
| 613 | debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n" | 586 | debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %u\n" |
| 614 | (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); | 587 | (unsigned long long)blk_rq_pos(rq), blk_rq_sectors(rq)); |
| 615 | 588 | ||
| 616 | if (!(blk_special_request(rq) || blk_sense_request(rq))) { | 589 | BUG_ON(!(blk_special_request(rq) || blk_sense_request(rq))); |
| 617 | /* We do not support buffer cache originated requests. */ | ||
| 618 | printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " | ||
| 619 | "request queue (%d)\n", drive->name, rq->cmd_type); | ||
| 620 | if (blk_fs_request(rq) == 0 && rq->errors == 0) | ||
| 621 | rq->errors = -EIO; | ||
| 622 | ide_complete_rq(drive, -EIO, ide_rq_bytes(rq)); | ||
| 623 | return ide_stopped; | ||
| 624 | } | ||
| 625 | 590 | ||
| 626 | /* Retry a failed packet command */ | 591 | /* Retry a failed packet command */ |
| 627 | if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { | 592 | if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) { |
| @@ -713,7 +678,7 @@ out: | |||
| 713 | 678 | ||
| 714 | cmd.rq = rq; | 679 | cmd.rq = rq; |
| 715 | 680 | ||
| 716 | ide_init_sg_cmd(&cmd, pc->req_xfer); | 681 | ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); |
| 717 | ide_map_sg(drive, &cmd); | 682 | ide_map_sg(drive, &cmd); |
| 718 | 683 | ||
| 719 | return ide_tape_issue_pc(drive, &cmd, pc); | 684 | return ide_tape_issue_pc(drive, &cmd, pc); |
| @@ -767,33 +732,53 @@ static int idetape_flush_tape_buffers(ide_drive_t *drive) | |||
| 767 | int rc; | 732 | int rc; |
| 768 | 733 | ||
| 769 | idetape_create_write_filemark_cmd(drive, &pc, 0); | 734 | idetape_create_write_filemark_cmd(drive, &pc, 0); |
| 770 | rc = ide_queue_pc_tail(drive, tape->disk, &pc); | 735 | rc = ide_queue_pc_tail(drive, tape->disk, &pc, NULL, 0); |
| 771 | if (rc) | 736 | if (rc) |
| 772 | return rc; | 737 | return rc; |
| 773 | idetape_wait_ready(drive, 60 * 5 * HZ); | 738 | idetape_wait_ready(drive, 60 * 5 * HZ); |
| 774 | return 0; | 739 | return 0; |
| 775 | } | 740 | } |
| 776 | 741 | ||
| 777 | static void idetape_create_read_position_cmd(struct ide_atapi_pc *pc) | 742 | static int ide_tape_read_position(ide_drive_t *drive) |
| 778 | { | ||
| 779 | ide_init_pc(pc); | ||
| 780 | pc->c[0] = READ_POSITION; | ||
| 781 | pc->req_xfer = 20; | ||
| 782 | } | ||
| 783 | |||
| 784 | static int idetape_read_position(ide_drive_t *drive) | ||
| 785 | { | 743 | { |
| 786 | idetape_tape_t *tape = drive->driver_data; | 744 | idetape_tape_t *tape = drive->driver_data; |
| 787 | struct ide_atapi_pc pc; | 745 | struct ide_atapi_pc pc; |
| 788 | int position; | 746 | u8 buf[20]; |
| 789 | 747 | ||
| 790 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | 748 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
| 791 | 749 | ||
| 792 | idetape_create_read_position_cmd(&pc); | 750 | /* prep cmd */ |
| 793 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) | 751 | ide_init_pc(&pc); |
| 752 | pc.c[0] = READ_POSITION; | ||
| 753 | pc.req_xfer = 20; | ||
| 754 | |||
| 755 | if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) | ||
| 794 | return -1; | 756 | return -1; |
| 795 | position = tape->first_frame; | 757 | |
| 796 | return position; | 758 | if (!pc.error) { |
| 759 | debug_log(DBG_SENSE, "BOP - %s\n", | ||
| 760 | (buf[0] & 0x80) ? "Yes" : "No"); | ||
| 761 | debug_log(DBG_SENSE, "EOP - %s\n", | ||
| 762 | (buf[0] & 0x40) ? "Yes" : "No"); | ||
| 763 | |||
| 764 | if (buf[0] & 0x4) { | ||
| 765 | printk(KERN_INFO "ide-tape: Block location is unknown" | ||
| 766 | "to the tape\n"); | ||
| 767 | clear_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), | ||
| 768 | &drive->atapi_flags); | ||
| 769 | return -1; | ||
| 770 | } else { | ||
| 771 | debug_log(DBG_SENSE, "Block Location - %u\n", | ||
| 772 | be32_to_cpup((__be32 *)&buf[4])); | ||
| 773 | |||
| 774 | tape->partition = buf[1]; | ||
| 775 | tape->first_frame = be32_to_cpup((__be32 *)&buf[4]); | ||
| 776 | set_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), | ||
| 777 | &drive->atapi_flags); | ||
| 778 | } | ||
| 779 | } | ||
| 780 | |||
| 781 | return tape->first_frame; | ||
| 797 | } | 782 | } |
| 798 | 783 | ||
| 799 | static void idetape_create_locate_cmd(ide_drive_t *drive, | 784 | static void idetape_create_locate_cmd(ide_drive_t *drive, |
| @@ -836,19 +821,21 @@ static int idetape_position_tape(ide_drive_t *drive, unsigned int block, | |||
| 836 | { | 821 | { |
| 837 | idetape_tape_t *tape = drive->driver_data; | 822 | idetape_tape_t *tape = drive->driver_data; |
| 838 | struct gendisk *disk = tape->disk; | 823 | struct gendisk *disk = tape->disk; |
| 839 | int retval; | 824 | int ret; |
| 840 | struct ide_atapi_pc pc; | 825 | struct ide_atapi_pc pc; |
| 841 | 826 | ||
| 842 | if (tape->chrdev_dir == IDETAPE_DIR_READ) | 827 | if (tape->chrdev_dir == IDETAPE_DIR_READ) |
| 843 | __ide_tape_discard_merge_buffer(drive); | 828 | __ide_tape_discard_merge_buffer(drive); |
| 844 | idetape_wait_ready(drive, 60 * 5 * HZ); | 829 | idetape_wait_ready(drive, 60 * 5 * HZ); |
| 845 | idetape_create_locate_cmd(drive, &pc, block, partition, skip); | 830 | idetape_create_locate_cmd(drive, &pc, block, partition, skip); |
| 846 | retval = ide_queue_pc_tail(drive, disk, &pc); | 831 | ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
| 847 | if (retval) | 832 | if (ret) |
| 848 | return (retval); | 833 | return ret; |
| 849 | 834 | ||
| 850 | idetape_create_read_position_cmd(&pc); | 835 | ret = ide_tape_read_position(drive); |
| 851 | return ide_queue_pc_tail(drive, disk, &pc); | 836 | if (ret < 0) |
| 837 | return ret; | ||
| 838 | return 0; | ||
| 852 | } | 839 | } |
| 853 | 840 | ||
| 854 | static void ide_tape_discard_merge_buffer(ide_drive_t *drive, | 841 | static void ide_tape_discard_merge_buffer(ide_drive_t *drive, |
| @@ -859,7 +846,7 @@ static void ide_tape_discard_merge_buffer(ide_drive_t *drive, | |||
| 859 | 846 | ||
| 860 | __ide_tape_discard_merge_buffer(drive); | 847 | __ide_tape_discard_merge_buffer(drive); |
| 861 | if (restore_position) { | 848 | if (restore_position) { |
| 862 | position = idetape_read_position(drive); | 849 | position = ide_tape_read_position(drive); |
| 863 | seek = position > 0 ? position : 0; | 850 | seek = position > 0 ? position : 0; |
| 864 | if (idetape_position_tape(drive, seek, 0, 0)) { | 851 | if (idetape_position_tape(drive, seek, 0, 0)) { |
| 865 | printk(KERN_INFO "ide-tape: %s: position_tape failed in" | 852 | printk(KERN_INFO "ide-tape: %s: position_tape failed in" |
| @@ -1039,20 +1026,19 @@ static int idetape_rewind_tape(ide_drive_t *drive) | |||
| 1039 | { | 1026 | { |
| 1040 | struct ide_tape_obj *tape = drive->driver_data; | 1027 | struct ide_tape_obj *tape = drive->driver_data; |
| 1041 | struct gendisk *disk = tape->disk; | 1028 | struct gendisk *disk = tape->disk; |
| 1042 | int retval; | ||
| 1043 | struct ide_atapi_pc pc; | 1029 | struct ide_atapi_pc pc; |
| 1030 | int ret; | ||
| 1044 | 1031 | ||
| 1045 | debug_log(DBG_SENSE, "Enter %s\n", __func__); | 1032 | debug_log(DBG_SENSE, "Enter %s\n", __func__); |
| 1046 | 1033 | ||
| 1047 | idetape_create_rewind_cmd(drive, &pc); | 1034 | idetape_create_rewind_cmd(drive, &pc); |
| 1048 | retval = ide_queue_pc_tail(drive, disk, &pc); | 1035 | ret = ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
| 1049 | if (retval) | 1036 | if (ret) |
| 1050 | return retval; | 1037 | return ret; |
| 1051 | 1038 | ||
| 1052 | idetape_create_read_position_cmd(&pc); | 1039 | ret = ide_tape_read_position(drive); |
| 1053 | retval = ide_queue_pc_tail(drive, disk, &pc); | 1040 | if (ret < 0) |
| 1054 | if (retval) | 1041 | return ret; |
| 1055 | return retval; | ||
| 1056 | return 0; | 1042 | return 0; |
| 1057 | } | 1043 | } |
| 1058 | 1044 | ||
| @@ -1119,7 +1105,7 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, | |||
| 1119 | case MTBSF: | 1105 | case MTBSF: |
| 1120 | idetape_create_space_cmd(&pc, mt_count - count, | 1106 | idetape_create_space_cmd(&pc, mt_count - count, |
| 1121 | IDETAPE_SPACE_OVER_FILEMARK); | 1107 | IDETAPE_SPACE_OVER_FILEMARK); |
| 1122 | return ide_queue_pc_tail(drive, disk, &pc); | 1108 | return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
| 1123 | case MTFSFM: | 1109 | case MTFSFM: |
| 1124 | case MTBSFM: | 1110 | case MTBSFM: |
| 1125 | if (!sprev) | 1111 | if (!sprev) |
| @@ -1259,7 +1245,7 @@ static int idetape_write_filemark(ide_drive_t *drive) | |||
| 1259 | 1245 | ||
| 1260 | /* Write a filemark */ | 1246 | /* Write a filemark */ |
| 1261 | idetape_create_write_filemark_cmd(drive, &pc, 1); | 1247 | idetape_create_write_filemark_cmd(drive, &pc, 1); |
| 1262 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { | 1248 | if (ide_queue_pc_tail(drive, tape->disk, &pc, NULL, 0)) { |
| 1263 | printk(KERN_ERR "ide-tape: Couldn't write a filemark\n"); | 1249 | printk(KERN_ERR "ide-tape: Couldn't write a filemark\n"); |
| 1264 | return -EIO; | 1250 | return -EIO; |
| 1265 | } | 1251 | } |
| @@ -1345,11 +1331,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) | |||
| 1345 | IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK); | 1331 | IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK); |
| 1346 | case MTEOM: | 1332 | case MTEOM: |
| 1347 | idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD); | 1333 | idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD); |
| 1348 | return ide_queue_pc_tail(drive, disk, &pc); | 1334 | return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
| 1349 | case MTERASE: | 1335 | case MTERASE: |
| 1350 | (void)idetape_rewind_tape(drive); | 1336 | (void)idetape_rewind_tape(drive); |
| 1351 | idetape_create_erase_cmd(&pc); | 1337 | idetape_create_erase_cmd(&pc); |
| 1352 | return ide_queue_pc_tail(drive, disk, &pc); | 1338 | return ide_queue_pc_tail(drive, disk, &pc, NULL, 0); |
| 1353 | case MTSETBLK: | 1339 | case MTSETBLK: |
| 1354 | if (mt_count) { | 1340 | if (mt_count) { |
| 1355 | if (mt_count < tape->blk_size || | 1341 | if (mt_count < tape->blk_size || |
| @@ -1415,7 +1401,7 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, | |||
| 1415 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { | 1401 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { |
| 1416 | block_offset = tape->valid / | 1402 | block_offset = tape->valid / |
| 1417 | (tape->blk_size * tape->user_bs_factor); | 1403 | (tape->blk_size * tape->user_bs_factor); |
| 1418 | position = idetape_read_position(drive); | 1404 | position = ide_tape_read_position(drive); |
| 1419 | if (position < 0) | 1405 | if (position < 0) |
| 1420 | return -EIO; | 1406 | return -EIO; |
| 1421 | } | 1407 | } |
| @@ -1458,9 +1444,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) | |||
| 1458 | { | 1444 | { |
| 1459 | idetape_tape_t *tape = drive->driver_data; | 1445 | idetape_tape_t *tape = drive->driver_data; |
| 1460 | struct ide_atapi_pc pc; | 1446 | struct ide_atapi_pc pc; |
| 1447 | u8 buf[12]; | ||
| 1461 | 1448 | ||
| 1462 | idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); | 1449 | idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); |
| 1463 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { | 1450 | if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) { |
| 1464 | printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); | 1451 | printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); |
| 1465 | if (tape->blk_size == 0) { | 1452 | if (tape->blk_size == 0) { |
| 1466 | printk(KERN_WARNING "ide-tape: Cannot deal with zero " | 1453 | printk(KERN_WARNING "ide-tape: Cannot deal with zero " |
| @@ -1469,10 +1456,10 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) | |||
| 1469 | } | 1456 | } |
| 1470 | return; | 1457 | return; |
| 1471 | } | 1458 | } |
| 1472 | tape->blk_size = (pc.buf[4 + 5] << 16) + | 1459 | tape->blk_size = (buf[4 + 5] << 16) + |
| 1473 | (pc.buf[4 + 6] << 8) + | 1460 | (buf[4 + 6] << 8) + |
| 1474 | pc.buf[4 + 7]; | 1461 | buf[4 + 7]; |
| 1475 | tape->drv_write_prot = (pc.buf[2] & 0x80) >> 7; | 1462 | tape->drv_write_prot = (buf[2] & 0x80) >> 7; |
| 1476 | } | 1463 | } |
| 1477 | 1464 | ||
| 1478 | static int idetape_chrdev_open(struct inode *inode, struct file *filp) | 1465 | static int idetape_chrdev_open(struct inode *inode, struct file *filp) |
| @@ -1517,7 +1504,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) | |||
| 1517 | goto out_put_tape; | 1504 | goto out_put_tape; |
| 1518 | } | 1505 | } |
| 1519 | 1506 | ||
| 1520 | idetape_read_position(drive); | 1507 | ide_tape_read_position(drive); |
| 1521 | if (!test_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), &drive->atapi_flags)) | 1508 | if (!test_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), &drive->atapi_flags)) |
| 1522 | (void)idetape_rewind_tape(drive); | 1509 | (void)idetape_rewind_tape(drive); |
| 1523 | 1510 | ||
| @@ -1615,17 +1602,14 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) | |||
| 1615 | char fw_rev[4], vendor_id[8], product_id[16]; | 1602 | char fw_rev[4], vendor_id[8], product_id[16]; |
| 1616 | 1603 | ||
| 1617 | idetape_create_inquiry_cmd(&pc); | 1604 | idetape_create_inquiry_cmd(&pc); |
| 1618 | pc.buf = &pc_buf[0]; | 1605 | if (ide_queue_pc_tail(drive, tape->disk, &pc, pc_buf, pc.req_xfer)) { |
| 1619 | pc.buf_size = sizeof(pc_buf); | ||
| 1620 | |||
| 1621 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { | ||
| 1622 | printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", | 1606 | printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n", |
| 1623 | tape->name); | 1607 | tape->name); |
| 1624 | return; | 1608 | return; |
| 1625 | } | 1609 | } |
| 1626 | memcpy(vendor_id, &pc.buf[8], 8); | 1610 | memcpy(vendor_id, &pc_buf[8], 8); |
| 1627 | memcpy(product_id, &pc.buf[16], 16); | 1611 | memcpy(product_id, &pc_buf[16], 16); |
| 1628 | memcpy(fw_rev, &pc.buf[32], 4); | 1612 | memcpy(fw_rev, &pc_buf[32], 4); |
| 1629 | 1613 | ||
| 1630 | ide_fixstring(vendor_id, 8, 0); | 1614 | ide_fixstring(vendor_id, 8, 0); |
| 1631 | ide_fixstring(product_id, 16, 0); | 1615 | ide_fixstring(product_id, 16, 0); |
| @@ -1643,11 +1627,11 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) | |||
| 1643 | { | 1627 | { |
| 1644 | idetape_tape_t *tape = drive->driver_data; | 1628 | idetape_tape_t *tape = drive->driver_data; |
| 1645 | struct ide_atapi_pc pc; | 1629 | struct ide_atapi_pc pc; |
| 1646 | u8 *caps; | 1630 | u8 buf[24], *caps; |
| 1647 | u8 speed, max_speed; | 1631 | u8 speed, max_speed; |
| 1648 | 1632 | ||
| 1649 | idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE); | 1633 | idetape_create_mode_sense_cmd(&pc, IDETAPE_CAPABILITIES_PAGE); |
| 1650 | if (ide_queue_pc_tail(drive, tape->disk, &pc)) { | 1634 | if (ide_queue_pc_tail(drive, tape->disk, &pc, buf, pc.req_xfer)) { |
| 1651 | printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming" | 1635 | printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming" |
| 1652 | " some default values\n"); | 1636 | " some default values\n"); |
| 1653 | tape->blk_size = 512; | 1637 | tape->blk_size = 512; |
| @@ -1656,7 +1640,7 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive) | |||
| 1656 | put_unaligned(6*52, (u16 *)&tape->caps[16]); | 1640 | put_unaligned(6*52, (u16 *)&tape->caps[16]); |
| 1657 | return; | 1641 | return; |
| 1658 | } | 1642 | } |
| 1659 | caps = pc.buf + 4 + pc.buf[3]; | 1643 | caps = buf + 4 + buf[3]; |
| 1660 | 1644 | ||
| 1661 | /* convert to host order and save for later use */ | 1645 | /* convert to host order and save for later use */ |
| 1662 | speed = be16_to_cpup((__be16 *)&caps[14]); | 1646 | speed = be16_to_cpup((__be16 *)&caps[14]); |
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c index af44be9d546c..46d203ce60cc 100644 --- a/drivers/ide/ide-xfer-mode.c +++ b/drivers/ide/ide-xfer-mode.c | |||
| @@ -107,6 +107,18 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode) | |||
| 107 | } | 107 | } |
| 108 | EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); | 108 | EXPORT_SYMBOL_GPL(ide_get_best_pio_mode); |
| 109 | 109 | ||
| 110 | int ide_pio_need_iordy(ide_drive_t *drive, const u8 pio) | ||
| 111 | { | ||
| 112 | /* | ||
| 113 | * IORDY may lead to controller lock up on certain controllers | ||
| 114 | * if the port is not occupied. | ||
| 115 | */ | ||
| 116 | if (pio == 0 && (drive->hwif->port_flags & IDE_PFLAG_PROBING)) | ||
| 117 | return 0; | ||
| 118 | return ata_id_pio_need_iordy(drive->id, pio); | ||
| 119 | } | ||
| 120 | EXPORT_SYMBOL_GPL(ide_pio_need_iordy); | ||
| 121 | |||
| 110 | int ide_set_pio_mode(ide_drive_t *drive, const u8 mode) | 122 | int ide_set_pio_mode(ide_drive_t *drive, const u8 mode) |
| 111 | { | 123 | { |
| 112 | ide_hwif_t *hwif = drive->hwif; | 124 | ide_hwif_t *hwif = drive->hwif; |
diff --git a/drivers/ide/it8172.c b/drivers/ide/it8172.c index e021078cd06b..0d266a5b524d 100644 --- a/drivers/ide/it8172.c +++ b/drivers/ide/it8172.c | |||
| @@ -66,7 +66,7 @@ static void it8172_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 66 | if (drive->media == ide_disk) | 66 | if (drive->media == ide_disk) |
| 67 | /* enable prefetch */ | 67 | /* enable prefetch */ |
| 68 | drive_enables |= 0x0004 << (drive->dn * 4); | 68 | drive_enables |= 0x0004 << (drive->dn * 4); |
| 69 | if (ata_id_has_iordy(drive->id)) | 69 | if (ide_pio_need_iordy(drive, pio)) |
| 70 | /* enable IORDY sample-point */ | 70 | /* enable IORDY sample-point */ |
| 71 | drive_enables |= 0x0002 << (drive->dn * 4); | 71 | drive_enables |= 0x0002 << (drive->dn * 4); |
| 72 | 72 | ||
diff --git a/drivers/ide/it8213.c b/drivers/ide/it8213.c index d7969b6d139e..47976167796a 100644 --- a/drivers/ide/it8213.c +++ b/drivers/ide/it8213.c | |||
| @@ -50,7 +50,7 @@ static void it8213_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 50 | control |= 1; /* Programmable timing on */ | 50 | control |= 1; /* Programmable timing on */ |
| 51 | if (drive->media != ide_disk) | 51 | if (drive->media != ide_disk) |
| 52 | control |= 4; /* ATAPI */ | 52 | control |= 4; /* ATAPI */ |
| 53 | if (pio > 2) | 53 | if (ide_pio_need_iordy(drive, pio)) |
| 54 | control |= 2; /* IORDY */ | 54 | control |= 2; /* IORDY */ |
| 55 | if (is_slave) { | 55 | if (is_slave) { |
| 56 | master_data |= 0x4000; | 56 | master_data |= 0x4000; |
diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c index 1447c8c90565..505ec43e5606 100644 --- a/drivers/ide/macide.c +++ b/drivers/ide/macide.c | |||
| @@ -53,17 +53,20 @@ | |||
| 53 | 53 | ||
| 54 | volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR); | 54 | volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR); |
| 55 | 55 | ||
| 56 | int macide_ack_intr(ide_hwif_t* hwif) | 56 | int macide_test_irq(ide_hwif_t *hwif) |
| 57 | { | 57 | { |
| 58 | if (*ide_ifr & 0x20) { | 58 | if (*ide_ifr & 0x20) |
| 59 | *ide_ifr &= ~0x20; | ||
| 60 | return 1; | 59 | return 1; |
| 61 | } | ||
| 62 | return 0; | 60 | return 0; |
| 63 | } | 61 | } |
| 64 | 62 | ||
| 63 | static void macide_clear_irq(ide_drive_t *drive) | ||
| 64 | { | ||
| 65 | *ide_ifr &= ~0x20; | ||
| 66 | } | ||
| 67 | |||
| 65 | static void __init macide_setup_ports(struct ide_hw *hw, unsigned long base, | 68 | static void __init macide_setup_ports(struct ide_hw *hw, unsigned long base, |
| 66 | int irq, ide_ack_intr_t *ack_intr) | 69 | int irq) |
| 67 | { | 70 | { |
| 68 | int i; | 71 | int i; |
| 69 | 72 | ||
| @@ -75,10 +78,15 @@ static void __init macide_setup_ports(struct ide_hw *hw, unsigned long base, | |||
| 75 | hw->io_ports.ctl_addr = base + IDE_CONTROL; | 78 | hw->io_ports.ctl_addr = base + IDE_CONTROL; |
| 76 | 79 | ||
| 77 | hw->irq = irq; | 80 | hw->irq = irq; |
| 78 | hw->ack_intr = ack_intr; | ||
| 79 | } | 81 | } |
| 80 | 82 | ||
| 83 | static const struct ide_port_ops macide_port_ops = { | ||
| 84 | .clear_irq = macide_clear_irq, | ||
| 85 | .test_irq = macide_test_irq, | ||
| 86 | }; | ||
| 87 | |||
| 81 | static const struct ide_port_info macide_port_info = { | 88 | static const struct ide_port_info macide_port_info = { |
| 89 | .port_ops = &macide_port_ops, | ||
| 82 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, | 90 | .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA, |
| 83 | .irq_flags = IRQF_SHARED, | 91 | .irq_flags = IRQF_SHARED, |
| 84 | .chipset = ide_generic, | 92 | .chipset = ide_generic, |
| @@ -93,10 +101,10 @@ static const char *mac_ide_name[] = | |||
| 93 | 101 | ||
| 94 | static int __init macide_init(void) | 102 | static int __init macide_init(void) |
| 95 | { | 103 | { |
| 96 | ide_ack_intr_t *ack_intr; | ||
| 97 | unsigned long base; | 104 | unsigned long base; |
| 98 | int irq; | 105 | int irq; |
| 99 | struct ide_hw hw, *hws[] = { &hw }; | 106 | struct ide_hw hw, *hws[] = { &hw }; |
| 107 | struct ide_port_info d = macide_port_info; | ||
| 100 | 108 | ||
| 101 | if (!MACH_IS_MAC) | 109 | if (!MACH_IS_MAC) |
| 102 | return -ENODEV; | 110 | return -ENODEV; |
| @@ -104,17 +112,15 @@ static int __init macide_init(void) | |||
| 104 | switch (macintosh_config->ide_type) { | 112 | switch (macintosh_config->ide_type) { |
| 105 | case MAC_IDE_QUADRA: | 113 | case MAC_IDE_QUADRA: |
| 106 | base = IDE_BASE; | 114 | base = IDE_BASE; |
| 107 | ack_intr = macide_ack_intr; | ||
| 108 | irq = IRQ_NUBUS_F; | 115 | irq = IRQ_NUBUS_F; |
| 109 | break; | 116 | break; |
| 110 | case MAC_IDE_PB: | 117 | case MAC_IDE_PB: |
| 111 | base = IDE_BASE; | 118 | base = IDE_BASE; |
| 112 | ack_intr = macide_ack_intr; | ||
| 113 | irq = IRQ_NUBUS_C; | 119 | irq = IRQ_NUBUS_C; |
| 114 | break; | 120 | break; |
| 115 | case MAC_IDE_BABOON: | 121 | case MAC_IDE_BABOON: |
| 116 | base = BABOON_BASE; | 122 | base = BABOON_BASE; |
| 117 | ack_intr = NULL; | 123 | d.port_ops = NULL; |
| 118 | irq = IRQ_BABOON_1; | 124 | irq = IRQ_BABOON_1; |
| 119 | break; | 125 | break; |
| 120 | default: | 126 | default: |
| @@ -124,9 +130,9 @@ static int __init macide_init(void) | |||
| 124 | printk(KERN_INFO "ide: Macintosh %s IDE controller\n", | 130 | printk(KERN_INFO "ide: Macintosh %s IDE controller\n", |
| 125 | mac_ide_name[macintosh_config->ide_type - 1]); | 131 | mac_ide_name[macintosh_config->ide_type - 1]); |
| 126 | 132 | ||
| 127 | macide_setup_ports(&hw, base, irq, ack_intr); | 133 | macide_setup_ports(&hw, base, irq); |
| 128 | 134 | ||
| 129 | return ide_host_add(&macide_port_info, hws, 1, NULL); | 135 | return ide_host_add(&d, hws, 1, NULL); |
| 130 | } | 136 | } |
| 131 | 137 | ||
| 132 | module_init(macide_init); | 138 | module_init(macide_init); |
diff --git a/drivers/ide/opti621.c b/drivers/ide/opti621.c index 6048eda3cd61..f1d70d6630fe 100644 --- a/drivers/ide/opti621.c +++ b/drivers/ide/opti621.c | |||
| @@ -138,6 +138,7 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 138 | ide_hwif_t *hwif = drive->hwif; | 138 | ide_hwif_t *hwif = drive->hwif; |
| 139 | ide_drive_t *pair = ide_get_pair_dev(drive); | 139 | ide_drive_t *pair = ide_get_pair_dev(drive); |
| 140 | unsigned long flags; | 140 | unsigned long flags; |
| 141 | unsigned long mode = XFER_PIO_0 + pio, pair_mode; | ||
| 141 | u8 tim, misc, addr_pio = pio, clk; | 142 | u8 tim, misc, addr_pio = pio, clk; |
| 142 | 143 | ||
| 143 | /* DRDY is default 2 (by OPTi Databook) */ | 144 | /* DRDY is default 2 (by OPTi Databook) */ |
| @@ -150,11 +151,12 @@ static void opti621_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 150 | { 0x48, 0x34, 0x21, 0x10, 0x10 } /* 25 MHz */ | 151 | { 0x48, 0x34, 0x21, 0x10, 0x10 } /* 25 MHz */ |
| 151 | }; | 152 | }; |
| 152 | 153 | ||
| 153 | drive->drive_data = XFER_PIO_0 + pio; | 154 | ide_set_drivedata(drive, (void *)mode); |
| 154 | 155 | ||
| 155 | if (pair) { | 156 | if (pair) { |
| 156 | if (pair->drive_data && pair->drive_data < drive->drive_data) | 157 | pair_mode = (unsigned long)ide_get_drivedata(pair); |
| 157 | addr_pio = pair->drive_data - XFER_PIO_0; | 158 | if (pair_mode && pair_mode < mode) |
| 159 | addr_pio = pair_mode - XFER_PIO_0; | ||
| 158 | } | 160 | } |
| 159 | 161 | ||
| 160 | spin_lock_irqsave(&opti621_lock, flags); | 162 | spin_lock_irqsave(&opti621_lock, flags); |
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c index b6abf7e52cac..cb812f3700e8 100644 --- a/drivers/ide/pdc202xx_old.c +++ b/drivers/ide/pdc202xx_old.c | |||
| @@ -73,7 +73,7 @@ static void pdc202xx_set_mode(ide_drive_t *drive, const u8 speed) | |||
| 73 | * Prefetch_EN / IORDY_EN / PA[3:0] bits of register A | 73 | * Prefetch_EN / IORDY_EN / PA[3:0] bits of register A |
| 74 | */ | 74 | */ |
| 75 | AP &= ~0x3f; | 75 | AP &= ~0x3f; |
| 76 | if (ata_id_iordy_disable(drive->id)) | 76 | if (ide_pio_need_iordy(drive, speed - XFER_PIO_0)) |
| 77 | AP |= 0x20; /* set IORDY_EN bit */ | 77 | AP |= 0x20; /* set IORDY_EN bit */ |
| 78 | if (drive->media == ide_disk) | 78 | if (drive->media == ide_disk) |
| 79 | AP |= 0x10; /* set Prefetch_EN bit */ | 79 | AP |= 0x10; /* set Prefetch_EN bit */ |
| @@ -104,6 +104,27 @@ static void pdc202xx_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 104 | pdc202xx_set_mode(drive, XFER_PIO_0 + pio); | 104 | pdc202xx_set_mode(drive, XFER_PIO_0 + pio); |
| 105 | } | 105 | } |
| 106 | 106 | ||
| 107 | static int pdc202xx_test_irq(ide_hwif_t *hwif) | ||
| 108 | { | ||
| 109 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
| 110 | unsigned long high_16 = pci_resource_start(dev, 4); | ||
| 111 | u8 sc1d = inb(high_16 + 0x1d); | ||
| 112 | |||
| 113 | if (hwif->channel) { | ||
| 114 | /* | ||
| 115 | * bit 7: error, bit 6: interrupting, | ||
| 116 | * bit 5: FIFO full, bit 4: FIFO empty | ||
| 117 | */ | ||
| 118 | return ((sc1d & 0x50) == 0x40) ? 1 : 0; | ||
| 119 | } else { | ||
| 120 | /* | ||
| 121 | * bit 3: error, bit 2: interrupting, | ||
| 122 | * bit 1: FIFO full, bit 0: FIFO empty | ||
| 123 | */ | ||
| 124 | return ((sc1d & 0x05) == 0x04) ? 1 : 0; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 107 | static u8 pdc2026x_cable_detect(ide_hwif_t *hwif) | 128 | static u8 pdc2026x_cable_detect(ide_hwif_t *hwif) |
| 108 | { | 129 | { |
| 109 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 130 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| @@ -231,6 +252,7 @@ static void __devinit pdc202ata4_fixup_irq(struct pci_dev *dev, | |||
| 231 | static const struct ide_port_ops pdc20246_port_ops = { | 252 | static const struct ide_port_ops pdc20246_port_ops = { |
| 232 | .set_pio_mode = pdc202xx_set_pio_mode, | 253 | .set_pio_mode = pdc202xx_set_pio_mode, |
| 233 | .set_dma_mode = pdc202xx_set_mode, | 254 | .set_dma_mode = pdc202xx_set_mode, |
| 255 | .test_irq = pdc202xx_test_irq, | ||
| 234 | }; | 256 | }; |
| 235 | 257 | ||
| 236 | static const struct ide_port_ops pdc2026x_port_ops = { | 258 | static const struct ide_port_ops pdc2026x_port_ops = { |
diff --git a/drivers/ide/piix.c b/drivers/ide/piix.c index 69860dea3820..bf14f39bd3a7 100644 --- a/drivers/ide/piix.c +++ b/drivers/ide/piix.c | |||
| @@ -98,7 +98,7 @@ static void piix_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 98 | control |= 1; /* Programmable timing on */ | 98 | control |= 1; /* Programmable timing on */ |
| 99 | if (drive->media == ide_disk) | 99 | if (drive->media == ide_disk) |
| 100 | control |= 4; /* Prefetch, post write */ | 100 | control |= 4; /* Prefetch, post write */ |
| 101 | if (pio > 2) | 101 | if (ide_pio_need_iordy(drive, pio)) |
| 102 | control |= 2; /* IORDY */ | 102 | control |= 2; /* IORDY */ |
| 103 | if (is_slave) { | 103 | if (is_slave) { |
| 104 | master_data |= 0x4000; | 104 | master_data |= 0x4000; |
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c index ab49a97023d9..90786083b439 100644 --- a/drivers/ide/q40ide.c +++ b/drivers/ide/q40ide.c | |||
| @@ -51,9 +51,7 @@ static int q40ide_default_irq(unsigned long base) | |||
| 51 | /* | 51 | /* |
| 52 | * Addresses are pretranslated for Q40 ISA access. | 52 | * Addresses are pretranslated for Q40 ISA access. |
| 53 | */ | 53 | */ |
| 54 | static void q40_ide_setup_ports(struct ide_hw *hw, unsigned long base, | 54 | static void q40_ide_setup_ports(struct ide_hw *hw, unsigned long base, int irq) |
| 55 | ide_ack_intr_t *ack_intr, | ||
| 56 | int irq) | ||
| 57 | { | 55 | { |
| 58 | memset(hw, 0, sizeof(*hw)); | 56 | memset(hw, 0, sizeof(*hw)); |
| 59 | /* BIG FAT WARNING: | 57 | /* BIG FAT WARNING: |
| @@ -69,7 +67,6 @@ static void q40_ide_setup_ports(struct ide_hw *hw, unsigned long base, | |||
| 69 | hw->io_ports.ctl_addr = Q40_ISA_IO_B(base + 0x206); | 67 | hw->io_ports.ctl_addr = Q40_ISA_IO_B(base + 0x206); |
| 70 | 68 | ||
| 71 | hw->irq = irq; | 69 | hw->irq = irq; |
| 72 | hw->ack_intr = ack_intr; | ||
| 73 | } | 70 | } |
| 74 | 71 | ||
| 75 | static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, | 72 | static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, |
| @@ -156,7 +153,7 @@ static int __init q40ide_init(void) | |||
| 156 | release_region(pcide_bases[i], 8); | 153 | release_region(pcide_bases[i], 8); |
| 157 | continue; | 154 | continue; |
| 158 | } | 155 | } |
| 159 | q40_ide_setup_ports(&hw[i], pcide_bases[i], NULL, | 156 | q40_ide_setup_ports(&hw[i], pcide_bases[i], |
| 160 | q40ide_default_irq(pcide_bases[i])); | 157 | q40ide_default_irq(pcide_bases[i])); |
| 161 | 158 | ||
| 162 | hws[i] = &hw[i]; | 159 | hws[i] = &hw[i]; |
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c index c9a134986891..74696edc8d1d 100644 --- a/drivers/ide/qd65xx.c +++ b/drivers/ide/qd65xx.c | |||
| @@ -180,8 +180,11 @@ static int qd_find_disk_type (ide_drive_t *drive, | |||
| 180 | 180 | ||
| 181 | static void qd_set_timing (ide_drive_t *drive, u8 timing) | 181 | static void qd_set_timing (ide_drive_t *drive, u8 timing) |
| 182 | { | 182 | { |
| 183 | drive->drive_data &= 0xff00; | 183 | unsigned long data = (unsigned long)ide_get_drivedata(drive); |
| 184 | drive->drive_data |= timing; | 184 | |
| 185 | data &= 0xff00; | ||
| 186 | data |= timing; | ||
| 187 | ide_set_drivedata(drive, (void *)data); | ||
| 185 | 188 | ||
| 186 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); | 189 | printk(KERN_DEBUG "%s: %#x\n", drive->name, timing); |
| 187 | } | 190 | } |
| @@ -292,7 +295,7 @@ static void __init qd6500_init_dev(ide_drive_t *drive) | |||
| 292 | u8 base = (hwif->config_data & 0xff00) >> 8; | 295 | u8 base = (hwif->config_data & 0xff00) >> 8; |
| 293 | u8 config = QD_CONFIG(hwif); | 296 | u8 config = QD_CONFIG(hwif); |
| 294 | 297 | ||
| 295 | drive->drive_data = QD6500_DEF_DATA; | 298 | ide_set_drivedata(drive, (void *)QD6500_DEF_DATA); |
| 296 | } | 299 | } |
| 297 | 300 | ||
| 298 | static void __init qd6580_init_dev(ide_drive_t *drive) | 301 | static void __init qd6580_init_dev(ide_drive_t *drive) |
| @@ -308,7 +311,7 @@ static void __init qd6580_init_dev(ide_drive_t *drive) | |||
| 308 | } else | 311 | } else |
| 309 | t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA; | 312 | t2 = t1 = hwif->channel ? QD6580_DEF_DATA2 : QD6580_DEF_DATA; |
| 310 | 313 | ||
| 311 | drive->drive_data = (drive->dn & 1) ? t2 : t1; | 314 | ide_set_drivedata(drive, (void *)((drive->dn & 1) ? t2 : t1)); |
| 312 | } | 315 | } |
| 313 | 316 | ||
| 314 | static const struct ide_tp_ops qd65xx_tp_ops = { | 317 | static const struct ide_tp_ops qd65xx_tp_ops = { |
diff --git a/drivers/ide/qd65xx.h b/drivers/ide/qd65xx.h index d7e67a1a1dcc..1fba2a5f281c 100644 --- a/drivers/ide/qd65xx.h +++ b/drivers/ide/qd65xx.h | |||
| @@ -31,8 +31,15 @@ | |||
| 31 | 31 | ||
| 32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) | 32 | #define QD_CONFIG(hwif) ((hwif)->config_data & 0x00ff) |
| 33 | 33 | ||
| 34 | #define QD_TIMING(drive) (u8)(((drive)->drive_data) & 0x00ff) | 34 | static inline u8 QD_TIMING(ide_drive_t *drive) |
| 35 | #define QD_TIMREG(drive) (u8)((((drive)->drive_data) & 0xff00) >> 8) | 35 | { |
| 36 | return (unsigned long)ide_get_drivedata(drive) & 0x00ff; | ||
| 37 | } | ||
| 38 | |||
| 39 | static inline u8 QD_TIMREG(ide_drive_t *drive) | ||
| 40 | { | ||
| 41 | return ((unsigned long)ide_get_drivedata(drive) & 0xff00) >> 8; | ||
| 42 | } | ||
| 36 | 43 | ||
| 37 | #define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08)) | 44 | #define QD6500_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0c : 0x08)) |
| 38 | #define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) | 45 | #define QD6580_DEF_DATA ((QD_TIM1_PORT<<8) | (QD_ID3 ? 0x0a : 0x00)) |
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c index 5f37f168f944..b7d61dc64096 100644 --- a/drivers/ide/sgiioc4.c +++ b/drivers/ide/sgiioc4.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. | 2 | * Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. |
| 3 | * Copyright (C) 2008 MontaVista Software, Inc. | 3 | * Copyright (C) 2008-2009 MontaVista Software, Inc. |
| 4 | * | 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or modify it |
| 6 | * under the terms of version 2 of the GNU General Public License | 6 | * under the terms of version 2 of the GNU General Public License |
| @@ -29,8 +29,7 @@ | |||
| 29 | #include <linux/blkdev.h> | 29 | #include <linux/blkdev.h> |
| 30 | #include <linux/scatterlist.h> | 30 | #include <linux/scatterlist.h> |
| 31 | #include <linux/ioc4.h> | 31 | #include <linux/ioc4.h> |
| 32 | #include <asm/io.h> | 32 | #include <linux/io.h> |
| 33 | |||
| 34 | #include <linux/ide.h> | 33 | #include <linux/ide.h> |
| 35 | 34 | ||
| 36 | #define DRV_NAME "SGIIOC4" | 35 | #define DRV_NAME "SGIIOC4" |
| @@ -72,7 +71,7 @@ | |||
| 72 | #define IOC4_CMD_CTL_BLK_SIZE 0x20 | 71 | #define IOC4_CMD_CTL_BLK_SIZE 0x20 |
| 73 | #define IOC4_SUPPORTED_FIRMWARE_REV 46 | 72 | #define IOC4_SUPPORTED_FIRMWARE_REV 46 |
| 74 | 73 | ||
| 75 | typedef struct { | 74 | struct ioc4_dma_regs { |
| 76 | u32 timing_reg0; | 75 | u32 timing_reg0; |
| 77 | u32 timing_reg1; | 76 | u32 timing_reg1; |
| 78 | u32 low_mem_ptr; | 77 | u32 low_mem_ptr; |
| @@ -82,17 +81,18 @@ typedef struct { | |||
| 82 | u32 dev_byte_count; | 81 | u32 dev_byte_count; |
| 83 | u32 mem_byte_count; | 82 | u32 mem_byte_count; |
| 84 | u32 status; | 83 | u32 status; |
| 85 | } ioc4_dma_regs_t; | 84 | }; |
| 86 | 85 | ||
| 87 | /* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */ | 86 | /* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */ |
| 88 | /* IOC4 has only 1 IDE channel */ | 87 | /* IOC4 has only 1 IDE channel */ |
| 89 | #define IOC4_PRD_BYTES 16 | 88 | #define IOC4_PRD_BYTES 16 |
| 90 | #define IOC4_PRD_ENTRIES (PAGE_SIZE /(4*IOC4_PRD_BYTES)) | 89 | #define IOC4_PRD_ENTRIES (PAGE_SIZE / (4 * IOC4_PRD_BYTES)) |
| 91 | 90 | ||
| 92 | 91 | ||
| 93 | static void | 92 | static void sgiioc4_init_hwif_ports(struct ide_hw *hw, |
| 94 | sgiioc4_init_hwif_ports(struct ide_hw *hw, unsigned long data_port, | 93 | unsigned long data_port, |
| 95 | unsigned long ctrl_port, unsigned long irq_port) | 94 | unsigned long ctrl_port, |
| 95 | unsigned long irq_port) | ||
| 96 | { | 96 | { |
| 97 | unsigned long reg = data_port; | 97 | unsigned long reg = data_port; |
| 98 | int i; | 98 | int i; |
| @@ -105,13 +105,11 @@ sgiioc4_init_hwif_ports(struct ide_hw *hw, unsigned long data_port, | |||
| 105 | hw->io_ports.irq_addr = irq_port; | 105 | hw->io_ports.irq_addr = irq_port; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static int | 108 | static int sgiioc4_checkirq(ide_hwif_t *hwif) |
| 109 | sgiioc4_checkirq(ide_hwif_t * hwif) | ||
| 110 | { | 109 | { |
| 111 | unsigned long intr_addr = | 110 | unsigned long intr_addr = hwif->io_ports.irq_addr + IOC4_INTR_REG * 4; |
| 112 | hwif->io_ports.irq_addr + IOC4_INTR_REG * 4; | ||
| 113 | 111 | ||
| 114 | if ((u8)readl((void __iomem *)intr_addr) & 0x03) | 112 | if (readl((void __iomem *)intr_addr) & 0x03) |
| 115 | return 1; | 113 | return 1; |
| 116 | 114 | ||
| 117 | return 0; | 115 | return 0; |
| @@ -119,8 +117,7 @@ sgiioc4_checkirq(ide_hwif_t * hwif) | |||
| 119 | 117 | ||
| 120 | static u8 sgiioc4_read_status(ide_hwif_t *); | 118 | static u8 sgiioc4_read_status(ide_hwif_t *); |
| 121 | 119 | ||
| 122 | static int | 120 | static int sgiioc4_clearirq(ide_drive_t *drive) |
| 123 | sgiioc4_clearirq(ide_drive_t * drive) | ||
| 124 | { | 121 | { |
| 125 | u32 intr_reg; | 122 | u32 intr_reg; |
| 126 | ide_hwif_t *hwif = drive->hwif; | 123 | ide_hwif_t *hwif = drive->hwif; |
| @@ -158,12 +155,10 @@ sgiioc4_clearirq(ide_drive_t * drive) | |||
| 158 | readl((void __iomem *)(io_ports->irq_addr + 4)); | 155 | readl((void __iomem *)(io_ports->irq_addr + 4)); |
| 159 | pci_read_config_dword(dev, PCI_COMMAND, | 156 | pci_read_config_dword(dev, PCI_COMMAND, |
| 160 | &pci_stat_cmd_reg); | 157 | &pci_stat_cmd_reg); |
| 161 | printk(KERN_ERR | 158 | printk(KERN_ERR "%s(%s): PCI Bus Error when doing DMA: " |
| 162 | "%s(%s) : PCI Bus Error when doing DMA:" | 159 | "status-cmd reg is 0x%x\n", |
| 163 | " status-cmd reg is 0x%x\n", | ||
| 164 | __func__, drive->name, pci_stat_cmd_reg); | 160 | __func__, drive->name, pci_stat_cmd_reg); |
| 165 | printk(KERN_ERR | 161 | printk(KERN_ERR "%s(%s): PCI Error Address is 0x%x%x\n", |
| 166 | "%s(%s) : PCI Error Address is 0x%x%x\n", | ||
| 167 | __func__, drive->name, | 162 | __func__, drive->name, |
| 168 | pci_err_addr_high, pci_err_addr_low); | 163 | pci_err_addr_high, pci_err_addr_low); |
| 169 | /* Clear the PCI Error indicator */ | 164 | /* Clear the PCI Error indicator */ |
| @@ -189,8 +184,7 @@ static void sgiioc4_dma_start(ide_drive_t *drive) | |||
| 189 | writel(temp_reg, (void __iomem *)ioc4_dma_addr); | 184 | writel(temp_reg, (void __iomem *)ioc4_dma_addr); |
| 190 | } | 185 | } |
| 191 | 186 | ||
| 192 | static u32 | 187 | static u32 sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base) |
| 193 | sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base) | ||
| 194 | { | 188 | { |
| 195 | unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4; | 189 | unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4; |
| 196 | u32 ioc4_dma; | 190 | u32 ioc4_dma; |
| @@ -227,7 +221,7 @@ static int sgiioc4_dma_end(ide_drive_t *drive) | |||
| 227 | } | 221 | } |
| 228 | 222 | ||
| 229 | /* | 223 | /* |
| 230 | * The IOC4 will DMA 1's to the ending dma area to indicate that | 224 | * The IOC4 will DMA 1's to the ending DMA area to indicate that |
| 231 | * previous data DMA is complete. This is necessary because of relaxed | 225 | * previous data DMA is complete. This is necessary because of relaxed |
| 232 | * ordering between register reads and DMA writes on the Altix. | 226 | * ordering between register reads and DMA writes on the Altix. |
| 233 | */ | 227 | */ |
| @@ -265,7 +259,7 @@ static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 265 | { | 259 | { |
| 266 | } | 260 | } |
| 267 | 261 | ||
| 268 | /* returns 1 if dma irq issued, 0 otherwise */ | 262 | /* Returns 1 if DMA IRQ issued, 0 otherwise */ |
| 269 | static int sgiioc4_dma_test_irq(ide_drive_t *drive) | 263 | static int sgiioc4_dma_test_irq(ide_drive_t *drive) |
| 270 | { | 264 | { |
| 271 | return sgiioc4_checkirq(drive->hwif); | 265 | return sgiioc4_checkirq(drive->hwif); |
| @@ -286,8 +280,7 @@ static void sgiioc4_resetproc(ide_drive_t *drive) | |||
| 286 | sgiioc4_clearirq(drive); | 280 | sgiioc4_clearirq(drive); |
| 287 | } | 281 | } |
| 288 | 282 | ||
| 289 | static void | 283 | static void sgiioc4_dma_lost_irq(ide_drive_t *drive) |
| 290 | sgiioc4_dma_lost_irq(ide_drive_t * drive) | ||
| 291 | { | 284 | { |
| 292 | sgiioc4_resetproc(drive); | 285 | sgiioc4_resetproc(drive); |
| 293 | 286 | ||
| @@ -313,13 +306,13 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif) | |||
| 313 | return reg; | 306 | return reg; |
| 314 | } | 307 | } |
| 315 | 308 | ||
| 316 | /* Creates a dma map for the scatter-gather list entries */ | 309 | /* Creates a DMA map for the scatter-gather list entries */ |
| 317 | static int __devinit | 310 | static int __devinit ide_dma_sgiioc4(ide_hwif_t *hwif, |
| 318 | ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) | 311 | const struct ide_port_info *d) |
| 319 | { | 312 | { |
| 320 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 313 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| 321 | unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; | 314 | unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; |
| 322 | int num_ports = sizeof (ioc4_dma_regs_t); | 315 | int num_ports = sizeof(struct ioc4_dma_regs); |
| 323 | void *pad; | 316 | void *pad; |
| 324 | 317 | ||
| 325 | printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); | 318 | printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); |
| @@ -362,8 +355,7 @@ dma_pci_alloc_failure: | |||
| 362 | } | 355 | } |
| 363 | 356 | ||
| 364 | /* Initializes the IOC4 DMA Engine */ | 357 | /* Initializes the IOC4 DMA Engine */ |
| 365 | static void | 358 | static void sgiioc4_configure_for_dma(int dma_direction, ide_drive_t *drive) |
| 366 | sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) | ||
| 367 | { | 359 | { |
| 368 | u32 ioc4_dma; | 360 | u32 ioc4_dma; |
| 369 | ide_hwif_t *hwif = drive->hwif; | 361 | ide_hwif_t *hwif = drive->hwif; |
| @@ -374,31 +366,27 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) | |||
| 374 | ioc4_dma = readl((void __iomem *)ioc4_dma_addr); | 366 | ioc4_dma = readl((void __iomem *)ioc4_dma_addr); |
| 375 | 367 | ||
| 376 | if (ioc4_dma & IOC4_S_DMA_ACTIVE) { | 368 | if (ioc4_dma & IOC4_S_DMA_ACTIVE) { |
| 377 | printk(KERN_WARNING | 369 | printk(KERN_WARNING "%s(%s): Warning!! DMA from previous " |
| 378 | "%s(%s):Warning!! DMA from previous transfer was still active\n", | 370 | "transfer was still active\n", __func__, drive->name); |
| 379 | __func__, drive->name); | ||
| 380 | writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr); | 371 | writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr); |
| 381 | ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); | 372 | ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); |
| 382 | 373 | ||
| 383 | if (ioc4_dma & IOC4_S_DMA_STOP) | 374 | if (ioc4_dma & IOC4_S_DMA_STOP) |
| 384 | printk(KERN_ERR | 375 | printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is " |
| 385 | "%s(%s) : IOC4 Dma STOP bit is still 1\n", | 376 | "still 1\n", __func__, drive->name); |
| 386 | __func__, drive->name); | ||
| 387 | } | 377 | } |
| 388 | 378 | ||
| 389 | ioc4_dma = readl((void __iomem *)ioc4_dma_addr); | 379 | ioc4_dma = readl((void __iomem *)ioc4_dma_addr); |
| 390 | if (ioc4_dma & IOC4_S_DMA_ERROR) { | 380 | if (ioc4_dma & IOC4_S_DMA_ERROR) { |
| 391 | printk(KERN_WARNING | 381 | printk(KERN_WARNING "%s(%s): Warning!! DMA Error during " |
| 392 | "%s(%s) : Warning!! - DMA Error during Previous" | 382 | "previous transfer, status 0x%x\n", |
| 393 | " transfer | status 0x%x\n", | ||
| 394 | __func__, drive->name, ioc4_dma); | 383 | __func__, drive->name, ioc4_dma); |
| 395 | writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr); | 384 | writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr); |
| 396 | ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); | 385 | ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); |
| 397 | 386 | ||
| 398 | if (ioc4_dma & IOC4_S_DMA_STOP) | 387 | if (ioc4_dma & IOC4_S_DMA_STOP) |
| 399 | printk(KERN_ERR | 388 | printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is " |
| 400 | "%s(%s) : IOC4 DMA STOP bit is still 1\n", | 389 | "still 1\n", __func__, drive->name); |
| 401 | __func__, drive->name); | ||
| 402 | } | 390 | } |
| 403 | 391 | ||
| 404 | /* Address of the Scatter Gather List */ | 392 | /* Address of the Scatter Gather List */ |
| @@ -408,20 +396,22 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive) | |||
| 408 | /* Address of the Ending DMA */ | 396 | /* Address of the Ending DMA */ |
| 409 | memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); | 397 | memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); |
| 410 | ending_dma_addr = cpu_to_le32(hwif->extra_base); | 398 | ending_dma_addr = cpu_to_le32(hwif->extra_base); |
| 411 | writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4)); | 399 | writel(ending_dma_addr, (void __iomem *)(dma_base + |
| 400 | IOC4_DMA_END_ADDR * 4)); | ||
| 412 | 401 | ||
| 413 | writel(dma_direction, (void __iomem *)ioc4_dma_addr); | 402 | writel(dma_direction, (void __iomem *)ioc4_dma_addr); |
| 414 | } | 403 | } |
| 415 | 404 | ||
| 416 | /* IOC4 Scatter Gather list Format */ | 405 | /* IOC4 Scatter Gather list Format */ |
| 417 | /* 128 Bit entries to support 64 bit addresses in the future */ | 406 | /* 128 Bit entries to support 64 bit addresses in the future */ |
| 418 | /* The Scatter Gather list Entry should be in the BIG-ENDIAN Format */ | 407 | /* The Scatter Gather list Entry should be in the BIG-ENDIAN Format */ |
| 419 | /* --------------------------------------------------------------------- */ | 408 | /* --------------------------------------------------------------------- */ |
| 420 | /* | Upper 32 bits - Zero | Lower 32 bits- address | */ | 409 | /* | Upper 32 bits - Zero | Lower 32 bits- address | */ |
| 421 | /* --------------------------------------------------------------------- */ | 410 | /* --------------------------------------------------------------------- */ |
| 422 | /* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */ | 411 | /* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */ |
| 423 | /* --------------------------------------------------------------------- */ | 412 | /* --------------------------------------------------------------------- */ |
| 424 | /* Creates the scatter gather list, DMA Table */ | 413 | /* Creates the scatter gather list, DMA Table */ |
| 414 | |||
| 425 | static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) | 415 | static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) |
| 426 | { | 416 | { |
| 427 | ide_hwif_t *hwif = drive->hwif; | 417 | ide_hwif_t *hwif = drive->hwif; |
| @@ -448,8 +438,10 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) | |||
| 448 | if (bcount > cur_len) | 438 | if (bcount > cur_len) |
| 449 | bcount = cur_len; | 439 | bcount = cur_len; |
| 450 | 440 | ||
| 451 | /* put the addr, length in | 441 | /* |
| 452 | * the IOC4 dma-table format */ | 442 | * Put the address, length in |
| 443 | * the IOC4 dma-table format | ||
| 444 | */ | ||
| 453 | *table = 0x0; | 445 | *table = 0x0; |
| 454 | table++; | 446 | table++; |
| 455 | *table = cpu_to_be32(cur_addr); | 447 | *table = cpu_to_be32(cur_addr); |
| @@ -540,8 +532,7 @@ static const struct ide_port_info sgiioc4_port_info __devinitconst = { | |||
| 540 | .mwdma_mask = ATA_MWDMA2_ONLY, | 532 | .mwdma_mask = ATA_MWDMA2_ONLY, |
| 541 | }; | 533 | }; |
| 542 | 534 | ||
| 543 | static int __devinit | 535 | static int __devinit sgiioc4_ide_setup_pci_device(struct pci_dev *dev) |
| 544 | sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | ||
| 545 | { | 536 | { |
| 546 | unsigned long cmd_base, irqport; | 537 | unsigned long cmd_base, irqport; |
| 547 | unsigned long bar0, cmd_phys_base, ctl; | 538 | unsigned long bar0, cmd_phys_base, ctl; |
| @@ -549,7 +540,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | |||
| 549 | struct ide_hw hw, *hws[] = { &hw }; | 540 | struct ide_hw hw, *hws[] = { &hw }; |
| 550 | int rc; | 541 | int rc; |
| 551 | 542 | ||
| 552 | /* Get the CmdBlk and CtrlBlk Base Registers */ | 543 | /* Get the CmdBlk and CtrlBlk base registers */ |
| 553 | bar0 = pci_resource_start(dev, 0); | 544 | bar0 = pci_resource_start(dev, 0); |
| 554 | virt_base = pci_ioremap_bar(dev, 0); | 545 | virt_base = pci_ioremap_bar(dev, 0); |
| 555 | if (virt_base == NULL) { | 546 | if (virt_base == NULL) { |
| @@ -557,9 +548,9 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | |||
| 557 | DRV_NAME, bar0); | 548 | DRV_NAME, bar0); |
| 558 | return -ENOMEM; | 549 | return -ENOMEM; |
| 559 | } | 550 | } |
| 560 | cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; | 551 | cmd_base = (unsigned long)virt_base + IOC4_CMD_OFFSET; |
| 561 | ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET; | 552 | ctl = (unsigned long)virt_base + IOC4_CTRL_OFFSET; |
| 562 | irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET; | 553 | irqport = (unsigned long)virt_base + IOC4_INTR_OFFSET; |
| 563 | 554 | ||
| 564 | cmd_phys_base = bar0 + IOC4_CMD_OFFSET; | 555 | cmd_phys_base = bar0 + IOC4_CMD_OFFSET; |
| 565 | if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, | 556 | if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, |
| @@ -577,7 +568,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev) | |||
| 577 | hw.irq = dev->irq; | 568 | hw.irq = dev->irq; |
| 578 | hw.dev = &dev->dev; | 569 | hw.dev = &dev->dev; |
| 579 | 570 | ||
| 580 | /* Initializing chipset IRQ Registers */ | 571 | /* Initialize chipset IRQ registers */ |
| 581 | writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); | 572 | writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); |
| 582 | 573 | ||
| 583 | rc = ide_host_add(&sgiioc4_port_info, hws, 1, NULL); | 574 | rc = ide_host_add(&sgiioc4_port_info, hws, 1, NULL); |
| @@ -590,8 +581,7 @@ req_mem_rgn_err: | |||
| 590 | return rc; | 581 | return rc; |
| 591 | } | 582 | } |
| 592 | 583 | ||
| 593 | static unsigned int __devinit | 584 | static unsigned int __devinit pci_init_sgiioc4(struct pci_dev *dev) |
| 594 | pci_init_sgiioc4(struct pci_dev *dev) | ||
| 595 | { | 585 | { |
| 596 | int ret; | 586 | int ret; |
| 597 | 587 | ||
| @@ -611,10 +601,10 @@ out: | |||
| 611 | return ret; | 601 | return ret; |
| 612 | } | 602 | } |
| 613 | 603 | ||
| 614 | int __devinit | 604 | int __devinit ioc4_ide_attach_one(struct ioc4_driver_data *idd) |
| 615 | ioc4_ide_attach_one(struct ioc4_driver_data *idd) | ||
| 616 | { | 605 | { |
| 617 | /* PCI-RT does not bring out IDE connection. | 606 | /* |
| 607 | * PCI-RT does not bring out IDE connection. | ||
| 618 | * Do not attach to this particular IOC4. | 608 | * Do not attach to this particular IOC4. |
| 619 | */ | 609 | */ |
| 620 | if (idd->idd_variant == IOC4_VARIANT_PCI_RT) | 610 | if (idd->idd_variant == IOC4_VARIANT_PCI_RT) |
| @@ -627,7 +617,6 @@ static struct ioc4_submodule __devinitdata ioc4_ide_submodule = { | |||
| 627 | .is_name = "IOC4_ide", | 617 | .is_name = "IOC4_ide", |
| 628 | .is_owner = THIS_MODULE, | 618 | .is_owner = THIS_MODULE, |
| 629 | .is_probe = ioc4_ide_attach_one, | 619 | .is_probe = ioc4_ide_attach_one, |
| 630 | /* .is_remove = ioc4_ide_remove_one, */ | ||
| 631 | }; | 620 | }; |
| 632 | 621 | ||
| 633 | static int __init ioc4_ide_init(void) | 622 | static int __init ioc4_ide_init(void) |
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c index bd82d228608c..d95df528562f 100644 --- a/drivers/ide/siimage.c +++ b/drivers/ide/siimage.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | * smarter code in libata. | 32 | * smarter code in libata. |
| 33 | * | 33 | * |
| 34 | * TODO: | 34 | * TODO: |
| 35 | * - IORDY fixes | ||
| 36 | * - VDMA support | 35 | * - VDMA support |
| 37 | */ | 36 | */ |
| 38 | 37 | ||
| @@ -234,8 +233,7 @@ static u8 sil_sata_udma_filter(ide_drive_t *drive) | |||
| 234 | * @pio: PIO mode number | 233 | * @pio: PIO mode number |
| 235 | * | 234 | * |
| 236 | * Load the timing settings for this device mode into the | 235 | * Load the timing settings for this device mode into the |
| 237 | * controller. If we are in PIO mode 3 or 4 turn on IORDY | 236 | * controller. |
| 238 | * monitoring (bit 9). The TF timing is bits 31:16 | ||
| 239 | */ | 237 | */ |
| 240 | 238 | ||
| 241 | static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) | 239 | static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) |
| @@ -276,13 +274,16 @@ static void sil_set_pio_mode(ide_drive_t *drive, u8 pio) | |||
| 276 | /* now set up IORDY */ | 274 | /* now set up IORDY */ |
| 277 | speedp = sil_ioread16(dev, tfaddr - 2); | 275 | speedp = sil_ioread16(dev, tfaddr - 2); |
| 278 | speedp &= ~0x200; | 276 | speedp &= ~0x200; |
| 279 | if (pio > 2) | ||
| 280 | speedp |= 0x200; | ||
| 281 | sil_iowrite16(dev, speedp, tfaddr - 2); | ||
| 282 | 277 | ||
| 283 | mode = sil_ioread8(dev, base + addr_mask); | 278 | mode = sil_ioread8(dev, base + addr_mask); |
| 284 | mode &= ~(unit ? 0x30 : 0x03); | 279 | mode &= ~(unit ? 0x30 : 0x03); |
| 285 | mode |= unit ? 0x10 : 0x01; | 280 | |
| 281 | if (ide_pio_need_iordy(drive, pio)) { | ||
| 282 | speedp |= 0x200; | ||
| 283 | mode |= unit ? 0x10 : 0x01; | ||
| 284 | } | ||
| 285 | |||
| 286 | sil_iowrite16(dev, speedp, tfaddr - 2); | ||
| 286 | sil_iowrite8(dev, mode, base + addr_mask); | 287 | sil_iowrite8(dev, mode, base + addr_mask); |
| 287 | } | 288 | } |
| 288 | 289 | ||
| @@ -337,24 +338,14 @@ static void sil_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 337 | sil_iowrite16(dev, ultra, ua); | 338 | sil_iowrite16(dev, ultra, ua); |
| 338 | } | 339 | } |
| 339 | 340 | ||
| 340 | /* returns 1 if dma irq issued, 0 otherwise */ | 341 | static int sil_test_irq(ide_hwif_t *hwif) |
| 341 | static int siimage_io_dma_test_irq(ide_drive_t *drive) | ||
| 342 | { | 342 | { |
| 343 | ide_hwif_t *hwif = drive->hwif; | ||
| 344 | struct pci_dev *dev = to_pci_dev(hwif->dev); | 343 | struct pci_dev *dev = to_pci_dev(hwif->dev); |
| 345 | u8 dma_altstat = 0; | ||
| 346 | unsigned long addr = siimage_selreg(hwif, 1); | 344 | unsigned long addr = siimage_selreg(hwif, 1); |
| 345 | u8 val = sil_ioread8(dev, addr); | ||
| 347 | 346 | ||
| 348 | /* return 1 if INTR asserted */ | 347 | /* Return 1 if INTRQ asserted */ |
| 349 | if (inb(hwif->dma_base + ATA_DMA_STATUS) & 4) | 348 | return (val & 8) ? 1 : 0; |
| 350 | return 1; | ||
| 351 | |||
| 352 | /* return 1 if Device INTR asserted */ | ||
| 353 | pci_read_config_byte(dev, addr, &dma_altstat); | ||
| 354 | if (dma_altstat & 8) | ||
| 355 | return 0; /* return 1; */ | ||
| 356 | |||
| 357 | return 0; | ||
| 358 | } | 349 | } |
| 359 | 350 | ||
| 360 | /** | 351 | /** |
| @@ -368,7 +359,6 @@ static int siimage_io_dma_test_irq(ide_drive_t *drive) | |||
| 368 | static int siimage_mmio_dma_test_irq(ide_drive_t *drive) | 359 | static int siimage_mmio_dma_test_irq(ide_drive_t *drive) |
| 369 | { | 360 | { |
| 370 | ide_hwif_t *hwif = drive->hwif; | 361 | ide_hwif_t *hwif = drive->hwif; |
| 371 | unsigned long addr = siimage_selreg(hwif, 0x1); | ||
| 372 | void __iomem *sata_error_addr | 362 | void __iomem *sata_error_addr |
| 373 | = (void __iomem *)hwif->sata_scr[SATA_ERROR_OFFSET]; | 363 | = (void __iomem *)hwif->sata_scr[SATA_ERROR_OFFSET]; |
| 374 | 364 | ||
| @@ -397,10 +387,6 @@ static int siimage_mmio_dma_test_irq(ide_drive_t *drive) | |||
| 397 | if (readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)) & 4) | 387 | if (readb((void __iomem *)(hwif->dma_base + ATA_DMA_STATUS)) & 4) |
| 398 | return 1; | 388 | return 1; |
| 399 | 389 | ||
| 400 | /* return 1 if Device INTR asserted */ | ||
| 401 | if (readb((void __iomem *)addr) & 8) | ||
| 402 | return 0; /* return 1; */ | ||
| 403 | |||
| 404 | return 0; | 390 | return 0; |
| 405 | } | 391 | } |
| 406 | 392 | ||
| @@ -409,7 +395,7 @@ static int siimage_dma_test_irq(ide_drive_t *drive) | |||
| 409 | if (drive->hwif->host_flags & IDE_HFLAG_MMIO) | 395 | if (drive->hwif->host_flags & IDE_HFLAG_MMIO) |
| 410 | return siimage_mmio_dma_test_irq(drive); | 396 | return siimage_mmio_dma_test_irq(drive); |
| 411 | else | 397 | else |
| 412 | return siimage_io_dma_test_irq(drive); | 398 | return ide_dma_test_irq(drive); |
| 413 | } | 399 | } |
| 414 | 400 | ||
| 415 | /** | 401 | /** |
| @@ -694,6 +680,7 @@ static const struct ide_port_ops sil_pata_port_ops = { | |||
| 694 | .set_pio_mode = sil_set_pio_mode, | 680 | .set_pio_mode = sil_set_pio_mode, |
| 695 | .set_dma_mode = sil_set_dma_mode, | 681 | .set_dma_mode = sil_set_dma_mode, |
| 696 | .quirkproc = sil_quirkproc, | 682 | .quirkproc = sil_quirkproc, |
| 683 | .test_irq = sil_test_irq, | ||
| 697 | .udma_filter = sil_pata_udma_filter, | 684 | .udma_filter = sil_pata_udma_filter, |
| 698 | .cable_detect = sil_cable_detect, | 685 | .cable_detect = sil_cable_detect, |
| 699 | }; | 686 | }; |
| @@ -704,6 +691,7 @@ static const struct ide_port_ops sil_sata_port_ops = { | |||
| 704 | .reset_poll = sil_sata_reset_poll, | 691 | .reset_poll = sil_sata_reset_poll, |
| 705 | .pre_reset = sil_sata_pre_reset, | 692 | .pre_reset = sil_sata_pre_reset, |
| 706 | .quirkproc = sil_quirkproc, | 693 | .quirkproc = sil_quirkproc, |
| 694 | .test_irq = sil_test_irq, | ||
| 707 | .udma_filter = sil_sata_udma_filter, | 695 | .udma_filter = sil_sata_udma_filter, |
| 708 | .cable_detect = sil_cable_detect, | 696 | .cable_detect = sil_cable_detect, |
| 709 | }; | 697 | }; |
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c index 0924abff52ff..d698da470d6f 100644 --- a/drivers/ide/sl82c105.c +++ b/drivers/ide/sl82c105.c | |||
| @@ -61,8 +61,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio) | |||
| 61 | if (cmd_off == 0) | 61 | if (cmd_off == 0) |
| 62 | cmd_off = 1; | 62 | cmd_off = 1; |
| 63 | 63 | ||
| 64 | if ((pio > 2 || ata_id_has_iordy(drive->id)) && | 64 | if (ide_pio_need_iordy(drive, pio)) |
| 65 | !(pio > 4 && ata_id_is_cfa(drive->id))) | ||
| 66 | iordy = 0x40; | 65 | iordy = 0x40; |
| 67 | 66 | ||
| 68 | return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy; | 67 | return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy; |
| @@ -74,6 +73,7 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio) | |||
| 74 | static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) | 73 | static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) |
| 75 | { | 74 | { |
| 76 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); | 75 | struct pci_dev *dev = to_pci_dev(drive->hwif->dev); |
| 76 | unsigned long timings = (unsigned long)ide_get_drivedata(drive); | ||
| 77 | int reg = 0x44 + drive->dn * 4; | 77 | int reg = 0x44 + drive->dn * 4; |
| 78 | u16 drv_ctrl; | 78 | u16 drv_ctrl; |
| 79 | 79 | ||
| @@ -83,8 +83,9 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 83 | * Store the PIO timings so that we can restore them | 83 | * Store the PIO timings so that we can restore them |
| 84 | * in case DMA will be turned off... | 84 | * in case DMA will be turned off... |
| 85 | */ | 85 | */ |
| 86 | drive->drive_data &= 0xffff0000; | 86 | timings &= 0xffff0000; |
| 87 | drive->drive_data |= drv_ctrl; | 87 | timings |= drv_ctrl; |
| 88 | ide_set_drivedata(drive, (void *)timings); | ||
| 88 | 89 | ||
| 89 | pci_write_config_word(dev, reg, drv_ctrl); | 90 | pci_write_config_word(dev, reg, drv_ctrl); |
| 90 | pci_read_config_word (dev, reg, &drv_ctrl); | 91 | pci_read_config_word (dev, reg, &drv_ctrl); |
| @@ -100,6 +101,7 @@ static void sl82c105_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 100 | static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed) | 101 | static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed) |
| 101 | { | 102 | { |
| 102 | static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200}; | 103 | static u16 mwdma_timings[] = {0x0707, 0x0201, 0x0200}; |
| 104 | unsigned long timings = (unsigned long)ide_get_drivedata(drive); | ||
| 103 | u16 drv_ctrl; | 105 | u16 drv_ctrl; |
| 104 | 106 | ||
| 105 | DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n", | 107 | DBG(("sl82c105_tune_chipset(drive:%s, speed:%s)\n", |
| @@ -111,8 +113,19 @@ static void sl82c105_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
| 111 | * Store the DMA timings so that we can actually program | 113 | * Store the DMA timings so that we can actually program |
| 112 | * them when DMA will be turned on... | 114 | * them when DMA will be turned on... |
| 113 | */ | 115 | */ |
| 114 | drive->drive_data &= 0x0000ffff; | 116 | timings &= 0x0000ffff; |
| 115 | drive->drive_data |= (unsigned long)drv_ctrl << 16; | 117 | timings |= (unsigned long)drv_ctrl << 16; |
| 118 | ide_set_drivedata(drive, (void *)timings); | ||
| 119 | } | ||
| 120 | |||
| 121 | static int sl82c105_test_irq(ide_hwif_t *hwif) | ||
| 122 | { | ||
| 123 | struct pci_dev *dev = to_pci_dev(hwif->dev); | ||
| 124 | u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA; | ||
| 125 | |||
| 126 | pci_read_config_dword(dev, 0x40, &val); | ||
| 127 | |||
| 128 | return (val & mask) ? 1 : 0; | ||
| 116 | } | 129 | } |
| 117 | 130 | ||
| 118 | /* | 131 | /* |
| @@ -185,7 +198,8 @@ static void sl82c105_dma_start(ide_drive_t *drive) | |||
| 185 | 198 | ||
| 186 | DBG(("%s(drive:%s)\n", __func__, drive->name)); | 199 | DBG(("%s(drive:%s)\n", __func__, drive->name)); |
| 187 | 200 | ||
| 188 | pci_write_config_word(dev, reg, drive->drive_data >> 16); | 201 | pci_write_config_word(dev, reg, |
| 202 | (unsigned long)ide_get_drivedata(drive) >> 16); | ||
| 189 | 203 | ||
| 190 | sl82c105_reset_host(dev); | 204 | sl82c105_reset_host(dev); |
| 191 | ide_dma_start(drive); | 205 | ide_dma_start(drive); |
| @@ -210,7 +224,8 @@ static int sl82c105_dma_end(ide_drive_t *drive) | |||
| 210 | 224 | ||
| 211 | ret = ide_dma_end(drive); | 225 | ret = ide_dma_end(drive); |
| 212 | 226 | ||
| 213 | pci_write_config_word(dev, reg, drive->drive_data); | 227 | pci_write_config_word(dev, reg, |
| 228 | (unsigned long)ide_get_drivedata(drive)); | ||
| 214 | 229 | ||
| 215 | return ret; | 230 | return ret; |
| 216 | } | 231 | } |
| @@ -289,6 +304,7 @@ static const struct ide_port_ops sl82c105_port_ops = { | |||
| 289 | .set_pio_mode = sl82c105_set_pio_mode, | 304 | .set_pio_mode = sl82c105_set_pio_mode, |
| 290 | .set_dma_mode = sl82c105_set_dma_mode, | 305 | .set_dma_mode = sl82c105_set_dma_mode, |
| 291 | .resetproc = sl82c105_resetproc, | 306 | .resetproc = sl82c105_resetproc, |
| 307 | .test_irq = sl82c105_test_irq, | ||
| 292 | }; | 308 | }; |
| 293 | 309 | ||
| 294 | static const struct ide_dma_ops sl82c105_dma_ops = { | 310 | static const struct ide_dma_ops sl82c105_dma_ops = { |
diff --git a/drivers/ide/slc90e66.c b/drivers/ide/slc90e66.c index f55d7d6313e8..9aec78d3bcff 100644 --- a/drivers/ide/slc90e66.c +++ b/drivers/ide/slc90e66.c | |||
| @@ -44,7 +44,7 @@ static void slc90e66_set_pio_mode(ide_drive_t *drive, const u8 pio) | |||
| 44 | control |= 1; /* Programmable timing on */ | 44 | control |= 1; /* Programmable timing on */ |
| 45 | if (drive->media == ide_disk) | 45 | if (drive->media == ide_disk) |
| 46 | control |= 4; /* Prefetch, post write */ | 46 | control |= 4; /* Prefetch, post write */ |
| 47 | if (pio > 2) | 47 | if (ide_pio_need_iordy(drive, pio)) |
| 48 | control |= 2; /* IORDY */ | 48 | control |= 2; /* IORDY */ |
| 49 | if (is_slave) { | 49 | if (is_slave) { |
| 50 | master_data |= 0x4000; | 50 | master_data |= 0x4000; |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 7a7a026ba712..114efd8dc8f5 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
| @@ -25,7 +25,6 @@ struct evdev { | |||
| 25 | int exist; | 25 | int exist; |
| 26 | int open; | 26 | int open; |
| 27 | int minor; | 27 | int minor; |
| 28 | char name[16]; | ||
| 29 | struct input_handle handle; | 28 | struct input_handle handle; |
| 30 | wait_queue_head_t wait; | 29 | wait_queue_head_t wait; |
| 31 | struct evdev_client *grab; | 30 | struct evdev_client *grab; |
| @@ -609,7 +608,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 609 | p, compat_mode); | 608 | p, compat_mode); |
| 610 | 609 | ||
| 611 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) | 610 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGNAME(0))) |
| 612 | return str_to_user(dev->name, _IOC_SIZE(cmd), p); | 611 | return str_to_user(dev_name(&evdev->dev), |
| 612 | _IOC_SIZE(cmd), p); | ||
| 613 | 613 | ||
| 614 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) | 614 | if (_IOC_NR(cmd) == _IOC_NR(EVIOCGPHYS(0))) |
| 615 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); | 615 | return str_to_user(dev->phys, _IOC_SIZE(cmd), p); |
| @@ -626,8 +626,11 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 626 | abs.maximum = dev->absmax[t]; | 626 | abs.maximum = dev->absmax[t]; |
| 627 | abs.fuzz = dev->absfuzz[t]; | 627 | abs.fuzz = dev->absfuzz[t]; |
| 628 | abs.flat = dev->absflat[t]; | 628 | abs.flat = dev->absflat[t]; |
| 629 | abs.resolution = dev->absres[t]; | ||
| 629 | 630 | ||
| 630 | if (copy_to_user(p, &abs, sizeof(struct input_absinfo))) | 631 | if (copy_to_user(p, &abs, min_t(size_t, |
| 632 | _IOC_SIZE(cmd), | ||
| 633 | sizeof(struct input_absinfo)))) | ||
| 631 | return -EFAULT; | 634 | return -EFAULT; |
| 632 | 635 | ||
| 633 | return 0; | 636 | return 0; |
| @@ -654,8 +657,9 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 654 | 657 | ||
| 655 | t = _IOC_NR(cmd) & ABS_MAX; | 658 | t = _IOC_NR(cmd) & ABS_MAX; |
| 656 | 659 | ||
| 657 | if (copy_from_user(&abs, p, | 660 | if (copy_from_user(&abs, p, min_t(size_t, |
| 658 | sizeof(struct input_absinfo))) | 661 | _IOC_SIZE(cmd), |
| 662 | sizeof(struct input_absinfo)))) | ||
| 659 | return -EFAULT; | 663 | return -EFAULT; |
| 660 | 664 | ||
| 661 | /* | 665 | /* |
| @@ -670,6 +674,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
| 670 | dev->absmax[t] = abs.maximum; | 674 | dev->absmax[t] = abs.maximum; |
| 671 | dev->absfuzz[t] = abs.fuzz; | 675 | dev->absfuzz[t] = abs.fuzz; |
| 672 | dev->absflat[t] = abs.flat; | 676 | dev->absflat[t] = abs.flat; |
| 677 | dev->absres[t] = _IOC_SIZE(cmd) < sizeof(struct input_absinfo) ? | ||
| 678 | 0 : abs.resolution; | ||
| 673 | 679 | ||
| 674 | spin_unlock_irq(&dev->event_lock); | 680 | spin_unlock_irq(&dev->event_lock); |
| 675 | 681 | ||
| @@ -807,16 +813,15 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 807 | mutex_init(&evdev->mutex); | 813 | mutex_init(&evdev->mutex); |
| 808 | init_waitqueue_head(&evdev->wait); | 814 | init_waitqueue_head(&evdev->wait); |
| 809 | 815 | ||
| 810 | snprintf(evdev->name, sizeof(evdev->name), "event%d", minor); | 816 | dev_set_name(&evdev->dev, "event%d", minor); |
| 811 | evdev->exist = 1; | 817 | evdev->exist = 1; |
| 812 | evdev->minor = minor; | 818 | evdev->minor = minor; |
| 813 | 819 | ||
| 814 | evdev->handle.dev = input_get_device(dev); | 820 | evdev->handle.dev = input_get_device(dev); |
| 815 | evdev->handle.name = evdev->name; | 821 | evdev->handle.name = dev_name(&evdev->dev); |
| 816 | evdev->handle.handler = handler; | 822 | evdev->handle.handler = handler; |
| 817 | evdev->handle.private = evdev; | 823 | evdev->handle.private = evdev; |
| 818 | 824 | ||
| 819 | dev_set_name(&evdev->dev, evdev->name); | ||
| 820 | evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); | 825 | evdev->dev.devt = MKDEV(INPUT_MAJOR, EVDEV_MINOR_BASE + minor); |
| 821 | evdev->dev.class = &input_class; | 826 | evdev->dev.class = &input_class; |
| 822 | evdev->dev.parent = &dev->dev; | 827 | evdev->dev.parent = &dev->dev; |
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c index 1dec00e20dbc..8a1810f88b9e 100644 --- a/drivers/input/gameport/fm801-gp.c +++ b/drivers/input/gameport/fm801-gp.c | |||
| @@ -167,5 +167,6 @@ module_exit(fm801_gp_exit); | |||
| 167 | 167 | ||
| 168 | MODULE_DEVICE_TABLE(pci, fm801_gp_id_table); | 168 | MODULE_DEVICE_TABLE(pci, fm801_gp_id_table); |
| 169 | 169 | ||
| 170 | MODULE_DESCRIPTION("FM801 gameport driver"); | ||
| 170 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | 171 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
| 171 | MODULE_LICENSE("GPL"); | 172 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 2d175b5928ff..ac11be08585e 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
| @@ -30,16 +30,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | |||
| 30 | MODULE_DESCRIPTION("Generic gameport layer"); | 30 | MODULE_DESCRIPTION("Generic gameport layer"); |
| 31 | MODULE_LICENSE("GPL"); | 31 | MODULE_LICENSE("GPL"); |
| 32 | 32 | ||
| 33 | EXPORT_SYMBOL(__gameport_register_port); | ||
| 34 | EXPORT_SYMBOL(gameport_unregister_port); | ||
| 35 | EXPORT_SYMBOL(__gameport_register_driver); | ||
| 36 | EXPORT_SYMBOL(gameport_unregister_driver); | ||
| 37 | EXPORT_SYMBOL(gameport_open); | ||
| 38 | EXPORT_SYMBOL(gameport_close); | ||
| 39 | EXPORT_SYMBOL(gameport_set_phys); | ||
| 40 | EXPORT_SYMBOL(gameport_start_polling); | ||
| 41 | EXPORT_SYMBOL(gameport_stop_polling); | ||
| 42 | |||
| 43 | /* | 33 | /* |
| 44 | * gameport_mutex protects entire gameport subsystem and is taken | 34 | * gameport_mutex protects entire gameport subsystem and is taken |
| 45 | * every time gameport port or driver registrered or unregistered. | 35 | * every time gameport port or driver registrered or unregistered. |
| @@ -162,6 +152,7 @@ void gameport_start_polling(struct gameport *gameport) | |||
| 162 | 152 | ||
| 163 | spin_unlock(&gameport->timer_lock); | 153 | spin_unlock(&gameport->timer_lock); |
| 164 | } | 154 | } |
| 155 | EXPORT_SYMBOL(gameport_start_polling); | ||
| 165 | 156 | ||
| 166 | void gameport_stop_polling(struct gameport *gameport) | 157 | void gameport_stop_polling(struct gameport *gameport) |
| 167 | { | 158 | { |
| @@ -172,6 +163,7 @@ void gameport_stop_polling(struct gameport *gameport) | |||
| 172 | 163 | ||
| 173 | spin_unlock(&gameport->timer_lock); | 164 | spin_unlock(&gameport->timer_lock); |
| 174 | } | 165 | } |
| 166 | EXPORT_SYMBOL(gameport_stop_polling); | ||
| 175 | 167 | ||
| 176 | static void gameport_run_poll_handler(unsigned long d) | 168 | static void gameport_run_poll_handler(unsigned long d) |
| 177 | { | 169 | { |
| @@ -516,6 +508,7 @@ void gameport_set_phys(struct gameport *gameport, const char *fmt, ...) | |||
| 516 | vsnprintf(gameport->phys, sizeof(gameport->phys), fmt, args); | 508 | vsnprintf(gameport->phys, sizeof(gameport->phys), fmt, args); |
| 517 | va_end(args); | 509 | va_end(args); |
| 518 | } | 510 | } |
| 511 | EXPORT_SYMBOL(gameport_set_phys); | ||
| 519 | 512 | ||
| 520 | /* | 513 | /* |
| 521 | * Prepare gameport port for registration. | 514 | * Prepare gameport port for registration. |
| @@ -658,6 +651,7 @@ void __gameport_register_port(struct gameport *gameport, struct module *owner) | |||
| 658 | gameport_init_port(gameport); | 651 | gameport_init_port(gameport); |
| 659 | gameport_queue_event(gameport, owner, GAMEPORT_REGISTER_PORT); | 652 | gameport_queue_event(gameport, owner, GAMEPORT_REGISTER_PORT); |
| 660 | } | 653 | } |
| 654 | EXPORT_SYMBOL(__gameport_register_port); | ||
| 661 | 655 | ||
| 662 | /* | 656 | /* |
| 663 | * Synchronously unregisters gameport port. | 657 | * Synchronously unregisters gameport port. |
| @@ -669,6 +663,7 @@ void gameport_unregister_port(struct gameport *gameport) | |||
| 669 | gameport_destroy_port(gameport); | 663 | gameport_destroy_port(gameport); |
| 670 | mutex_unlock(&gameport_mutex); | 664 | mutex_unlock(&gameport_mutex); |
| 671 | } | 665 | } |
| 666 | EXPORT_SYMBOL(gameport_unregister_port); | ||
| 672 | 667 | ||
| 673 | 668 | ||
| 674 | /* | 669 | /* |
| @@ -728,7 +723,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner | |||
| 728 | * Temporarily disable automatic binding because probing | 723 | * Temporarily disable automatic binding because probing |
| 729 | * takes long time and we are better off doing it in kgameportd | 724 | * takes long time and we are better off doing it in kgameportd |
| 730 | */ | 725 | */ |
| 731 | drv->ignore = 1; | 726 | drv->ignore = true; |
| 732 | 727 | ||
| 733 | error = driver_register(&drv->driver); | 728 | error = driver_register(&drv->driver); |
| 734 | if (error) { | 729 | if (error) { |
| @@ -741,7 +736,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner | |||
| 741 | /* | 736 | /* |
| 742 | * Reset ignore flag and let kgameportd bind the driver to free ports | 737 | * Reset ignore flag and let kgameportd bind the driver to free ports |
| 743 | */ | 738 | */ |
| 744 | drv->ignore = 0; | 739 | drv->ignore = false; |
| 745 | error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER); | 740 | error = gameport_queue_event(drv, NULL, GAMEPORT_ATTACH_DRIVER); |
| 746 | if (error) { | 741 | if (error) { |
| 747 | driver_unregister(&drv->driver); | 742 | driver_unregister(&drv->driver); |
| @@ -750,6 +745,7 @@ int __gameport_register_driver(struct gameport_driver *drv, struct module *owner | |||
| 750 | 745 | ||
| 751 | return 0; | 746 | return 0; |
| 752 | } | 747 | } |
| 748 | EXPORT_SYMBOL(__gameport_register_driver); | ||
| 753 | 749 | ||
| 754 | void gameport_unregister_driver(struct gameport_driver *drv) | 750 | void gameport_unregister_driver(struct gameport_driver *drv) |
| 755 | { | 751 | { |
| @@ -757,7 +753,7 @@ void gameport_unregister_driver(struct gameport_driver *drv) | |||
| 757 | 753 | ||
| 758 | mutex_lock(&gameport_mutex); | 754 | mutex_lock(&gameport_mutex); |
| 759 | 755 | ||
| 760 | drv->ignore = 1; /* so gameport_find_driver ignores it */ | 756 | drv->ignore = true; /* so gameport_find_driver ignores it */ |
| 761 | gameport_remove_pending_events(drv); | 757 | gameport_remove_pending_events(drv); |
| 762 | 758 | ||
| 763 | start_over: | 759 | start_over: |
| @@ -774,6 +770,7 @@ start_over: | |||
| 774 | 770 | ||
| 775 | mutex_unlock(&gameport_mutex); | 771 | mutex_unlock(&gameport_mutex); |
| 776 | } | 772 | } |
| 773 | EXPORT_SYMBOL(gameport_unregister_driver); | ||
| 777 | 774 | ||
| 778 | static int gameport_bus_match(struct device *dev, struct device_driver *drv) | 775 | static int gameport_bus_match(struct device *dev, struct device_driver *drv) |
| 779 | { | 776 | { |
| @@ -812,6 +809,7 @@ int gameport_open(struct gameport *gameport, struct gameport_driver *drv, int mo | |||
| 812 | gameport_set_drv(gameport, drv); | 809 | gameport_set_drv(gameport, drv); |
| 813 | return 0; | 810 | return 0; |
| 814 | } | 811 | } |
| 812 | EXPORT_SYMBOL(gameport_open); | ||
| 815 | 813 | ||
| 816 | void gameport_close(struct gameport *gameport) | 814 | void gameport_close(struct gameport *gameport) |
| 817 | { | 815 | { |
| @@ -822,6 +820,7 @@ void gameport_close(struct gameport *gameport) | |||
| 822 | if (gameport->close) | 820 | if (gameport->close) |
| 823 | gameport->close(gameport); | 821 | gameport->close(gameport); |
| 824 | } | 822 | } |
| 823 | EXPORT_SYMBOL(gameport_close); | ||
| 825 | 824 | ||
| 826 | static int __init gameport_init(void) | 825 | static int __init gameport_init(void) |
| 827 | { | 826 | { |
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 012a5e753991..0e12f89276a3 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c | |||
| @@ -39,7 +39,6 @@ struct joydev { | |||
| 39 | int exist; | 39 | int exist; |
| 40 | int open; | 40 | int open; |
| 41 | int minor; | 41 | int minor; |
| 42 | char name[16]; | ||
| 43 | struct input_handle handle; | 42 | struct input_handle handle; |
| 44 | wait_queue_head_t wait; | 43 | wait_queue_head_t wait; |
| 45 | struct list_head client_list; | 44 | struct list_head client_list; |
| @@ -537,12 +536,14 @@ static int joydev_ioctl_common(struct joydev *joydev, | |||
| 537 | default: | 536 | default: |
| 538 | if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) { | 537 | if ((cmd & ~IOCSIZE_MASK) == JSIOCGNAME(0)) { |
| 539 | int len; | 538 | int len; |
| 540 | if (!dev->name) | 539 | const char *name = dev_name(&dev->dev); |
| 540 | |||
| 541 | if (!name) | ||
| 541 | return 0; | 542 | return 0; |
| 542 | len = strlen(dev->name) + 1; | 543 | len = strlen(name) + 1; |
| 543 | if (len > _IOC_SIZE(cmd)) | 544 | if (len > _IOC_SIZE(cmd)) |
| 544 | len = _IOC_SIZE(cmd); | 545 | len = _IOC_SIZE(cmd); |
| 545 | if (copy_to_user(argp, dev->name, len)) | 546 | if (copy_to_user(argp, name, len)) |
| 546 | return -EFAULT; | 547 | return -EFAULT; |
| 547 | return len; | 548 | return len; |
| 548 | } | 549 | } |
| @@ -742,13 +743,13 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 742 | mutex_init(&joydev->mutex); | 743 | mutex_init(&joydev->mutex); |
| 743 | init_waitqueue_head(&joydev->wait); | 744 | init_waitqueue_head(&joydev->wait); |
| 744 | 745 | ||
| 745 | snprintf(joydev->name, sizeof(joydev->name), "js%d", minor); | 746 | dev_set_name(&joydev->dev, "js%d", minor); |
| 746 | joydev->exist = 1; | 747 | joydev->exist = 1; |
| 747 | joydev->minor = minor; | 748 | joydev->minor = minor; |
| 748 | 749 | ||
| 749 | joydev->exist = 1; | 750 | joydev->exist = 1; |
| 750 | joydev->handle.dev = input_get_device(dev); | 751 | joydev->handle.dev = input_get_device(dev); |
| 751 | joydev->handle.name = joydev->name; | 752 | joydev->handle.name = dev_name(&joydev->dev); |
| 752 | joydev->handle.handler = handler; | 753 | joydev->handle.handler = handler; |
| 753 | joydev->handle.private = joydev; | 754 | joydev->handle.private = joydev; |
| 754 | 755 | ||
| @@ -797,7 +798,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev, | |||
| 797 | } | 798 | } |
| 798 | } | 799 | } |
| 799 | 800 | ||
| 800 | dev_set_name(&joydev->dev, joydev->name); | ||
| 801 | joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor); | 801 | joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor); |
| 802 | joydev->dev.class = &input_class; | 802 | joydev->dev.class = &input_class; |
| 803 | joydev->dev.parent = &dev->dev; | 803 | joydev->dev.parent = &dev->dev; |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index ea2638b41982..9d8f796c6745 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
| @@ -250,6 +250,17 @@ config KEYBOARD_HP7XX | |||
| 250 | To compile this driver as a module, choose M here: the | 250 | To compile this driver as a module, choose M here: the |
| 251 | module will be called jornada720_kbd. | 251 | module will be called jornada720_kbd. |
| 252 | 252 | ||
| 253 | config KEYBOARD_LM8323 | ||
| 254 | tristate "LM8323 keypad chip" | ||
| 255 | depends on I2C | ||
| 256 | depends on LEDS_CLASS | ||
| 257 | help | ||
| 258 | If you say yes here you get support for the National Semiconductor | ||
| 259 | LM8323 keypad controller. | ||
| 260 | |||
| 261 | To compile this driver as a module, choose M here: the | ||
| 262 | module will be called lm8323. | ||
| 263 | |||
| 253 | config KEYBOARD_OMAP | 264 | config KEYBOARD_OMAP |
| 254 | tristate "TI OMAP keypad support" | 265 | tristate "TI OMAP keypad support" |
| 255 | depends on (ARCH_OMAP1 || ARCH_OMAP2) | 266 | depends on (ARCH_OMAP1 || ARCH_OMAP2) |
| @@ -332,4 +343,14 @@ config KEYBOARD_SH_KEYSC | |||
| 332 | 343 | ||
| 333 | To compile this driver as a module, choose M here: the | 344 | To compile this driver as a module, choose M here: the |
| 334 | module will be called sh_keysc. | 345 | module will be called sh_keysc. |
| 346 | |||
| 347 | config KEYBOARD_EP93XX | ||
| 348 | tristate "EP93xx Matrix Keypad support" | ||
| 349 | depends on ARCH_EP93XX | ||
| 350 | help | ||
| 351 | Say Y here to enable the matrix keypad on the Cirrus EP93XX. | ||
| 352 | |||
| 353 | To compile this driver as a module, choose M here: the | ||
| 354 | module will be called ep93xx_keypad. | ||
| 355 | |||
| 335 | endif | 356 | endif |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index 36351e1190f9..156b647a259b 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
| @@ -18,6 +18,7 @@ obj-$(CONFIG_KEYBOARD_SPITZ) += spitzkbd.o | |||
| 18 | obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o | 18 | obj-$(CONFIG_KEYBOARD_TOSA) += tosakbd.o |
| 19 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
| 20 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 20 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
| 21 | obj-$(CONFIG_KEYBOARD_LM8323) += lm8323.o | ||
| 21 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o | 22 | obj-$(CONFIG_KEYBOARD_OMAP) += omap-keypad.o |
| 22 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o | 23 | obj-$(CONFIG_KEYBOARD_PXA27x) += pxa27x_keypad.o |
| 23 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o | 24 | obj-$(CONFIG_KEYBOARD_PXA930_ROTARY) += pxa930_rotary.o |
| @@ -28,3 +29,4 @@ obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o | |||
| 28 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o | 29 | obj-$(CONFIG_KEYBOARD_MAPLE) += maple_keyb.o |
| 29 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | 30 | obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o |
| 30 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o | 31 | obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o |
| 32 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | ||
diff --git a/drivers/input/keyboard/ep93xx_keypad.c b/drivers/input/keyboard/ep93xx_keypad.c new file mode 100644 index 000000000000..181d30e3018e --- /dev/null +++ b/drivers/input/keyboard/ep93xx_keypad.c | |||
| @@ -0,0 +1,470 @@ | |||
| 1 | /* | ||
| 2 | * Driver for the Cirrus EP93xx matrix keypad controller. | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 H Hartley Sweeten <hsweeten@visionengravers.com> | ||
| 5 | * | ||
| 6 | * Based on the pxa27x matrix keypad controller by Rodolfo Giometti. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License version 2 as | ||
| 10 | * published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | * NOTE: | ||
| 13 | * | ||
| 14 | * The 3-key reset is triggered by pressing the 3 keys in | ||
| 15 | * Row 0, Columns 2, 4, and 7 at the same time. This action can | ||
| 16 | * be disabled by setting the EP93XX_KEYPAD_DISABLE_3_KEY flag. | ||
| 17 | * | ||
| 18 | * Normal operation for the matrix does not autorepeat the key press. | ||
| 19 | * This action can be enabled by setting the EP93XX_KEYPAD_AUTOREPEAT | ||
| 20 | * flag. | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/platform_device.h> | ||
| 24 | #include <linux/interrupt.h> | ||
| 25 | #include <linux/input.h> | ||
| 26 | #include <linux/clk.h> | ||
| 27 | |||
| 28 | #include <mach/hardware.h> | ||
| 29 | #include <mach/gpio.h> | ||
| 30 | #include <mach/ep93xx_keypad.h> | ||
| 31 | |||
| 32 | /* | ||
| 33 | * Keypad Interface Register offsets | ||
| 34 | */ | ||
| 35 | #define KEY_INIT 0x00 /* Key Scan Initialization register */ | ||
| 36 | #define KEY_DIAG 0x04 /* Key Scan Diagnostic register */ | ||
| 37 | #define KEY_REG 0x08 /* Key Value Capture register */ | ||
| 38 | |||
| 39 | /* Key Scan Initialization Register bit defines */ | ||
| 40 | #define KEY_INIT_DBNC_MASK (0x00ff0000) | ||
| 41 | #define KEY_INIT_DBNC_SHIFT (16) | ||
| 42 | #define KEY_INIT_DIS3KY (1<<15) | ||
| 43 | #define KEY_INIT_DIAG (1<<14) | ||
| 44 | #define KEY_INIT_BACK (1<<13) | ||
| 45 | #define KEY_INIT_T2 (1<<12) | ||
| 46 | #define KEY_INIT_PRSCL_MASK (0x000003ff) | ||
| 47 | #define KEY_INIT_PRSCL_SHIFT (0) | ||
| 48 | |||
| 49 | /* Key Scan Diagnostic Register bit defines */ | ||
| 50 | #define KEY_DIAG_MASK (0x0000003f) | ||
| 51 | #define KEY_DIAG_SHIFT (0) | ||
| 52 | |||
| 53 | /* Key Value Capture Register bit defines */ | ||
| 54 | #define KEY_REG_K (1<<15) | ||
| 55 | #define KEY_REG_INT (1<<14) | ||
| 56 | #define KEY_REG_2KEYS (1<<13) | ||
| 57 | #define KEY_REG_1KEY (1<<12) | ||
| 58 | #define KEY_REG_KEY2_MASK (0x00000fc0) | ||
| 59 | #define KEY_REG_KEY2_SHIFT (6) | ||
| 60 | #define KEY_REG_KEY1_MASK (0x0000003f) | ||
| 61 | #define KEY_REG_KEY1_SHIFT (0) | ||
| 62 | |||
| 63 | #define keypad_readl(off) __raw_readl(keypad->mmio_base + (off)) | ||
| 64 | #define keypad_writel(v, off) __raw_writel((v), keypad->mmio_base + (off)) | ||
| 65 | |||
| 66 | #define MAX_MATRIX_KEY_NUM (MAX_MATRIX_KEY_ROWS * MAX_MATRIX_KEY_COLS) | ||
| 67 | |||
| 68 | struct ep93xx_keypad { | ||
| 69 | struct ep93xx_keypad_platform_data *pdata; | ||
| 70 | |||
| 71 | struct clk *clk; | ||
| 72 | struct input_dev *input_dev; | ||
| 73 | void __iomem *mmio_base; | ||
| 74 | |||
| 75 | int irq; | ||
| 76 | int enabled; | ||
| 77 | |||
| 78 | int key1; | ||
| 79 | int key2; | ||
| 80 | |||
| 81 | unsigned int matrix_keycodes[MAX_MATRIX_KEY_NUM]; | ||
| 82 | }; | ||
| 83 | |||
| 84 | static void ep93xx_keypad_build_keycode(struct ep93xx_keypad *keypad) | ||
| 85 | { | ||
| 86 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; | ||
| 87 | struct input_dev *input_dev = keypad->input_dev; | ||
| 88 | int i; | ||
| 89 | |||
| 90 | for (i = 0; i < pdata->matrix_key_map_size; i++) { | ||
| 91 | unsigned int key = pdata->matrix_key_map[i]; | ||
| 92 | int row = (key >> 28) & 0xf; | ||
| 93 | int col = (key >> 24) & 0xf; | ||
| 94 | int code = key & 0xffffff; | ||
| 95 | |||
| 96 | keypad->matrix_keycodes[(row << 3) + col] = code; | ||
| 97 | __set_bit(code, input_dev->keybit); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | static irqreturn_t ep93xx_keypad_irq_handler(int irq, void *dev_id) | ||
| 102 | { | ||
| 103 | struct ep93xx_keypad *keypad = dev_id; | ||
| 104 | struct input_dev *input_dev = keypad->input_dev; | ||
| 105 | unsigned int status = keypad_readl(KEY_REG); | ||
| 106 | int keycode, key1, key2; | ||
| 107 | |||
| 108 | keycode = (status & KEY_REG_KEY1_MASK) >> KEY_REG_KEY1_SHIFT; | ||
| 109 | key1 = keypad->matrix_keycodes[keycode]; | ||
| 110 | |||
| 111 | keycode = (status & KEY_REG_KEY2_MASK) >> KEY_REG_KEY2_SHIFT; | ||
| 112 | key2 = keypad->matrix_keycodes[keycode]; | ||
| 113 | |||
| 114 | if (status & KEY_REG_2KEYS) { | ||
| 115 | if (keypad->key1 && key1 != keypad->key1 && key2 != keypad->key1) | ||
| 116 | input_report_key(input_dev, keypad->key1, 0); | ||
| 117 | |||
| 118 | if (keypad->key2 && key1 != keypad->key2 && key2 != keypad->key2) | ||
| 119 | input_report_key(input_dev, keypad->key2, 0); | ||
| 120 | |||
| 121 | input_report_key(input_dev, key1, 1); | ||
| 122 | input_report_key(input_dev, key2, 1); | ||
| 123 | |||
| 124 | keypad->key1 = key1; | ||
| 125 | keypad->key2 = key2; | ||
| 126 | |||
| 127 | } else if (status & KEY_REG_1KEY) { | ||
| 128 | if (keypad->key1 && key1 != keypad->key1) | ||
| 129 | input_report_key(input_dev, keypad->key1, 0); | ||
| 130 | |||
| 131 | if (keypad->key2 && key1 != keypad->key2) | ||
| 132 | input_report_key(input_dev, keypad->key2, 0); | ||
| 133 | |||
| 134 | input_report_key(input_dev, key1, 1); | ||
| 135 | |||
| 136 | keypad->key1 = key1; | ||
| 137 | keypad->key2 = 0; | ||
| 138 | |||
| 139 | } else { | ||
| 140 | input_report_key(input_dev, keypad->key1, 0); | ||
| 141 | input_report_key(input_dev, keypad->key2, 0); | ||
| 142 | |||
| 143 | keypad->key1 = keypad->key2 = 0; | ||
| 144 | } | ||
| 145 | input_sync(input_dev); | ||
| 146 | |||
| 147 | return IRQ_HANDLED; | ||
| 148 | } | ||
| 149 | |||
| 150 | static void ep93xx_keypad_config(struct ep93xx_keypad *keypad) | ||
| 151 | { | ||
| 152 | struct ep93xx_keypad_platform_data *pdata = keypad->pdata; | ||
| 153 | unsigned int val = 0; | ||
| 154 | |||
| 155 | clk_set_rate(keypad->clk, pdata->flags & EP93XX_KEYPAD_KDIV); | ||
| 156 | |||
| 157 | if (pdata->flags & EP93XX_KEYPAD_DISABLE_3_KEY) | ||
| 158 | val |= KEY_INIT_DIS3KY; | ||
| 159 | if (pdata->flags & EP93XX_KEYPAD_DIAG_MODE) | ||
| 160 | val |= KEY_INIT_DIAG; | ||
| 161 | if (pdata->flags & EP93XX_KEYPAD_BACK_DRIVE) | ||
| 162 | val |= KEY_INIT_BACK; | ||
| 163 | if (pdata->flags & EP93XX_KEYPAD_TEST_MODE) | ||
| 164 | val |= KEY_INIT_T2; | ||
| 165 | |||
| 166 | val |= ((pdata->debounce << KEY_INIT_DBNC_SHIFT) & KEY_INIT_DBNC_MASK); | ||
| 167 | |||
| 168 | val |= ((pdata->prescale << KEY_INIT_PRSCL_SHIFT) & KEY_INIT_PRSCL_MASK); | ||
| 169 | |||
| 170 | keypad_writel(val, KEY_INIT); | ||
| 171 | } | ||
| 172 | |||
| 173 | static int ep93xx_keypad_open(struct input_dev *pdev) | ||
| 174 | { | ||
| 175 | struct ep93xx_keypad *keypad = input_get_drvdata(pdev); | ||
| 176 | |||
| 177 | if (!keypad->enabled) { | ||
| 178 | ep93xx_keypad_config(keypad); | ||
| 179 | clk_enable(keypad->clk); | ||
| 180 | keypad->enabled = 1; | ||
| 181 | } | ||
| 182 | |||
| 183 | return 0; | ||
| 184 | } | ||
| 185 | |||
| 186 | static void ep93xx_keypad_close(struct input_dev *pdev) | ||
| 187 | { | ||
| 188 | struct ep93xx_keypad *keypad = input_get_drvdata(pdev); | ||
| 189 | |||
| 190 | if (keypad->enabled) { | ||
| 191 | clk_disable(keypad->clk); | ||
| 192 | keypad->enabled = 0; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | |||
| 197 | #ifdef CONFIG_PM | ||
| 198 | /* | ||
| 199 | * NOTE: I don't know if this is correct, or will work on the ep93xx. | ||
| 200 | * | ||
| 201 | * None of the existing ep93xx drivers have power management support. | ||
| 202 | * But, this is basically what the pxa27x_keypad driver does. | ||
| 203 | */ | ||
| 204 | static int ep93xx_keypad_suspend(struct platform_device *pdev, | ||
| 205 | pm_message_t state) | ||
| 206 | { | ||
| 207 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | ||
| 208 | struct input_dev *input_dev = keypad->input_dev; | ||
| 209 | |||
| 210 | mutex_lock(&input_dev->mutex); | ||
| 211 | |||
| 212 | if (keypad->enabled) { | ||
| 213 | clk_disable(keypad->clk); | ||
| 214 | keypad->enabled = 0; | ||
| 215 | } | ||
| 216 | |||
| 217 | mutex_unlock(&input_dev->mutex); | ||
| 218 | |||
| 219 | if (device_may_wakeup(&pdev->dev)) | ||
| 220 | enable_irq_wake(keypad->irq); | ||
| 221 | |||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | static int ep93xx_keypad_resume(struct platform_device *pdev) | ||
| 226 | { | ||
| 227 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | ||
| 228 | struct input_dev *input_dev = keypad->input_dev; | ||
| 229 | |||
| 230 | if (device_may_wakeup(&pdev->dev)) | ||
| 231 | disable_irq_wake(keypad->irq); | ||
| 232 | |||
| 233 | mutex_lock(&input_dev->mutex); | ||
| 234 | |||
| 235 | if (input_dev->users) { | ||
| 236 | if (!keypad->enabled) { | ||
| 237 | ep93xx_keypad_config(keypad); | ||
| 238 | clk_enable(keypad->clk); | ||
| 239 | keypad->enabled = 1; | ||
| 240 | } | ||
| 241 | } | ||
| 242 | |||
| 243 | mutex_unlock(&input_dev->mutex); | ||
| 244 | |||
| 245 | return 0; | ||
| 246 | } | ||
| 247 | #else /* !CONFIG_PM */ | ||
| 248 | #define ep93xx_keypad_suspend NULL | ||
| 249 | #define ep93xx_keypad_resume NULL | ||
| 250 | #endif /* !CONFIG_PM */ | ||
| 251 | |||
| 252 | static int __devinit ep93xx_keypad_probe(struct platform_device *pdev) | ||
| 253 | { | ||
| 254 | struct ep93xx_keypad *keypad; | ||
| 255 | struct ep93xx_keypad_platform_data *pdata = pdev->dev.platform_data; | ||
| 256 | struct input_dev *input_dev; | ||
| 257 | struct resource *res; | ||
| 258 | int irq, err, i, gpio; | ||
| 259 | |||
| 260 | if (!pdata || | ||
| 261 | !pdata->matrix_key_rows || | ||
| 262 | pdata->matrix_key_rows > MAX_MATRIX_KEY_ROWS || | ||
| 263 | !pdata->matrix_key_cols || | ||
| 264 | pdata->matrix_key_cols > MAX_MATRIX_KEY_COLS) { | ||
| 265 | dev_err(&pdev->dev, "invalid or missing platform data\n"); | ||
| 266 | return -EINVAL; | ||
| 267 | } | ||
| 268 | |||
| 269 | keypad = kzalloc(sizeof(struct ep93xx_keypad), GFP_KERNEL); | ||
| 270 | if (!keypad) { | ||
| 271 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
| 272 | return -ENOMEM; | ||
| 273 | } | ||
| 274 | |||
| 275 | keypad->pdata = pdata; | ||
| 276 | |||
| 277 | irq = platform_get_irq(pdev, 0); | ||
| 278 | if (irq < 0) { | ||
| 279 | dev_err(&pdev->dev, "failed to get keypad irq\n"); | ||
| 280 | err = -ENXIO; | ||
| 281 | goto failed_free; | ||
| 282 | } | ||
| 283 | |||
| 284 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 285 | if (!res) { | ||
| 286 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
| 287 | err = -ENXIO; | ||
| 288 | goto failed_free; | ||
| 289 | } | ||
| 290 | |||
| 291 | res = request_mem_region(res->start, resource_size(res), pdev->name); | ||
| 292 | if (!res) { | ||
| 293 | dev_err(&pdev->dev, "failed to request I/O memory\n"); | ||
| 294 | err = -EBUSY; | ||
| 295 | goto failed_free; | ||
| 296 | } | ||
| 297 | |||
| 298 | keypad->mmio_base = ioremap(res->start, resource_size(res)); | ||
| 299 | if (keypad->mmio_base == NULL) { | ||
| 300 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
| 301 | err = -ENXIO; | ||
| 302 | goto failed_free_mem; | ||
| 303 | } | ||
| 304 | |||
| 305 | /* Request the needed GPIO's */ | ||
| 306 | gpio = EP93XX_GPIO_LINE_ROW0; | ||
| 307 | for (i = 0; i < keypad->pdata->matrix_key_rows; i++, gpio++) { | ||
| 308 | err = gpio_request(gpio, pdev->name); | ||
| 309 | if (err) { | ||
| 310 | dev_err(&pdev->dev, "failed to request gpio-%d\n", | ||
| 311 | gpio); | ||
| 312 | goto failed_free_rows; | ||
| 313 | } | ||
| 314 | } | ||
| 315 | |||
| 316 | gpio = EP93XX_GPIO_LINE_COL0; | ||
| 317 | for (i = 0; i < keypad->pdata->matrix_key_cols; i++, gpio++) { | ||
| 318 | err = gpio_request(gpio, pdev->name); | ||
| 319 | if (err) { | ||
| 320 | dev_err(&pdev->dev, "failed to request gpio-%d\n", | ||
| 321 | gpio); | ||
| 322 | goto failed_free_cols; | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | keypad->clk = clk_get(&pdev->dev, "key_clk"); | ||
| 327 | if (IS_ERR(keypad->clk)) { | ||
| 328 | dev_err(&pdev->dev, "failed to get keypad clock\n"); | ||
| 329 | err = PTR_ERR(keypad->clk); | ||
| 330 | goto failed_free_io; | ||
| 331 | } | ||
| 332 | |||
| 333 | /* Create and register the input driver */ | ||
| 334 | input_dev = input_allocate_device(); | ||
| 335 | if (!input_dev) { | ||
| 336 | dev_err(&pdev->dev, "failed to allocate input device\n"); | ||
| 337 | err = -ENOMEM; | ||
| 338 | goto failed_put_clk; | ||
| 339 | } | ||
| 340 | |||
| 341 | keypad->input_dev = input_dev; | ||
| 342 | |||
| 343 | input_dev->name = pdev->name; | ||
| 344 | input_dev->id.bustype = BUS_HOST; | ||
| 345 | input_dev->open = ep93xx_keypad_open; | ||
| 346 | input_dev->close = ep93xx_keypad_close; | ||
| 347 | input_dev->dev.parent = &pdev->dev; | ||
| 348 | input_dev->keycode = keypad->matrix_keycodes; | ||
| 349 | input_dev->keycodesize = sizeof(keypad->matrix_keycodes[0]); | ||
| 350 | input_dev->keycodemax = ARRAY_SIZE(keypad->matrix_keycodes); | ||
| 351 | |||
| 352 | input_set_drvdata(input_dev, keypad); | ||
| 353 | |||
| 354 | input_dev->evbit[0] = BIT_MASK(EV_KEY); | ||
| 355 | if (keypad->pdata->flags & EP93XX_KEYPAD_AUTOREPEAT) | ||
| 356 | input_dev->evbit[0] |= BIT_MASK(EV_REP); | ||
| 357 | |||
| 358 | ep93xx_keypad_build_keycode(keypad); | ||
| 359 | platform_set_drvdata(pdev, keypad); | ||
| 360 | |||
| 361 | err = request_irq(irq, ep93xx_keypad_irq_handler, IRQF_DISABLED, | ||
| 362 | pdev->name, keypad); | ||
| 363 | if (err) { | ||
| 364 | dev_err(&pdev->dev, "failed to request IRQ\n"); | ||
| 365 | goto failed_free_dev; | ||
| 366 | } | ||
| 367 | |||
| 368 | keypad->irq = irq; | ||
| 369 | |||
| 370 | /* Register the input device */ | ||
| 371 | err = input_register_device(input_dev); | ||
| 372 | if (err) { | ||
| 373 | dev_err(&pdev->dev, "failed to register input device\n"); | ||
| 374 | goto failed_free_irq; | ||
| 375 | } | ||
| 376 | |||
| 377 | device_init_wakeup(&pdev->dev, 1); | ||
| 378 | |||
| 379 | return 0; | ||
| 380 | |||
| 381 | failed_free_irq: | ||
| 382 | free_irq(irq, pdev); | ||
| 383 | platform_set_drvdata(pdev, NULL); | ||
| 384 | failed_free_dev: | ||
| 385 | input_free_device(input_dev); | ||
| 386 | failed_put_clk: | ||
| 387 | clk_put(keypad->clk); | ||
| 388 | failed_free_io: | ||
| 389 | i = keypad->pdata->matrix_key_cols - 1; | ||
| 390 | gpio = EP93XX_GPIO_LINE_COL0 + i; | ||
| 391 | failed_free_cols: | ||
| 392 | for ( ; i >= 0; i--, gpio--) | ||
| 393 | gpio_free(gpio); | ||
| 394 | i = keypad->pdata->matrix_key_rows - 1; | ||
| 395 | gpio = EP93XX_GPIO_LINE_ROW0 + i; | ||
| 396 | failed_free_rows: | ||
| 397 | for ( ; i >= 0; i--, gpio--) | ||
| 398 | gpio_free(gpio); | ||
| 399 | iounmap(keypad->mmio_base); | ||
| 400 | failed_free_mem: | ||
| 401 | release_mem_region(res->start, resource_size(res)); | ||
| 402 | failed_free: | ||
| 403 | kfree(keypad); | ||
| 404 | return err; | ||
| 405 | } | ||
| 406 | |||
| 407 | static int __devexit ep93xx_keypad_remove(struct platform_device *pdev) | ||
| 408 | { | ||
| 409 | struct ep93xx_keypad *keypad = platform_get_drvdata(pdev); | ||
| 410 | struct resource *res; | ||
| 411 | int i, gpio; | ||
| 412 | |||
| 413 | free_irq(keypad->irq, pdev); | ||
| 414 | |||
| 415 | platform_set_drvdata(pdev, NULL); | ||
| 416 | |||
| 417 | if (keypad->enabled) | ||
| 418 | clk_disable(keypad->clk); | ||
| 419 | clk_put(keypad->clk); | ||
| 420 | |||
| 421 | input_unregister_device(keypad->input_dev); | ||
| 422 | |||
| 423 | i = keypad->pdata->matrix_key_cols - 1; | ||
| 424 | gpio = EP93XX_GPIO_LINE_COL0 + i; | ||
| 425 | for ( ; i >= 0; i--, gpio--) | ||
| 426 | gpio_free(gpio); | ||
| 427 | |||
| 428 | i = keypad->pdata->matrix_key_rows - 1; | ||
| 429 | gpio = EP93XX_GPIO_LINE_ROW0 + i; | ||
| 430 | for ( ; i >= 0; i--, gpio--) | ||
| 431 | gpio_free(gpio); | ||
| 432 | |||
| 433 | iounmap(keypad->mmio_base); | ||
| 434 | |||
| 435 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 436 | release_mem_region(res->start, resource_size(res)); | ||
| 437 | |||
| 438 | kfree(keypad); | ||
| 439 | |||
| 440 | return 0; | ||
| 441 | } | ||
| 442 | |||
| 443 | static struct platform_driver ep93xx_keypad_driver = { | ||
| 444 | .driver = { | ||
| 445 | .name = "ep93xx-keypad", | ||
| 446 | .owner = THIS_MODULE, | ||
| 447 | }, | ||
| 448 | .probe = ep93xx_keypad_probe, | ||
| 449 | .remove = __devexit_p(ep93xx_keypad_remove), | ||
| 450 | .suspend = ep93xx_keypad_suspend, | ||
| 451 | .resume = ep93xx_keypad_resume, | ||
| 452 | }; | ||
| 453 | |||
| 454 | static int __init ep93xx_keypad_init(void) | ||
| 455 | { | ||
| 456 | return platform_driver_register(&ep93xx_keypad_driver); | ||
| 457 | } | ||
| 458 | |||
| 459 | static void __exit ep93xx_keypad_exit(void) | ||
| 460 | { | ||
| 461 | platform_driver_unregister(&ep93xx_keypad_driver); | ||
| 462 | } | ||
| 463 | |||
| 464 | module_init(ep93xx_keypad_init); | ||
| 465 | module_exit(ep93xx_keypad_exit); | ||
| 466 | |||
| 467 | MODULE_LICENSE("GPL"); | ||
| 468 | MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>"); | ||
| 469 | MODULE_DESCRIPTION("EP93xx Matrix Keypad Controller"); | ||
| 470 | MODULE_ALIAS("platform:ep93xx-keypad"); | ||
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index ad67d763fdbd..2157cd7de00c 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c | |||
| @@ -22,13 +22,14 @@ | |||
| 22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 23 | #include <linux/input.h> | 23 | #include <linux/input.h> |
| 24 | #include <linux/gpio_keys.h> | 24 | #include <linux/gpio_keys.h> |
| 25 | #include <linux/workqueue.h> | ||
| 25 | 26 | ||
| 26 | #include <asm/gpio.h> | 27 | #include <asm/gpio.h> |
| 27 | 28 | ||
| 28 | struct gpio_button_data { | 29 | struct gpio_button_data { |
| 29 | struct gpio_keys_button *button; | 30 | struct gpio_keys_button *button; |
| 30 | struct input_dev *input; | 31 | struct input_dev *input; |
| 31 | struct timer_list timer; | 32 | struct delayed_work work; |
| 32 | }; | 33 | }; |
| 33 | 34 | ||
| 34 | struct gpio_keys_drvdata { | 35 | struct gpio_keys_drvdata { |
| @@ -36,8 +37,10 @@ struct gpio_keys_drvdata { | |||
| 36 | struct gpio_button_data data[0]; | 37 | struct gpio_button_data data[0]; |
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | static void gpio_keys_report_event(struct gpio_button_data *bdata) | 40 | static void gpio_keys_report_event(struct work_struct *work) |
| 40 | { | 41 | { |
| 42 | struct gpio_button_data *bdata = | ||
| 43 | container_of(work, struct gpio_button_data, work.work); | ||
| 41 | struct gpio_keys_button *button = bdata->button; | 44 | struct gpio_keys_button *button = bdata->button; |
| 42 | struct input_dev *input = bdata->input; | 45 | struct input_dev *input = bdata->input; |
| 43 | unsigned int type = button->type ?: EV_KEY; | 46 | unsigned int type = button->type ?: EV_KEY; |
| @@ -47,25 +50,17 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata) | |||
| 47 | input_sync(input); | 50 | input_sync(input); |
| 48 | } | 51 | } |
| 49 | 52 | ||
| 50 | static void gpio_check_button(unsigned long _data) | ||
| 51 | { | ||
| 52 | struct gpio_button_data *data = (struct gpio_button_data *)_data; | ||
| 53 | |||
| 54 | gpio_keys_report_event(data); | ||
| 55 | } | ||
| 56 | |||
| 57 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) | 53 | static irqreturn_t gpio_keys_isr(int irq, void *dev_id) |
| 58 | { | 54 | { |
| 59 | struct gpio_button_data *bdata = dev_id; | 55 | struct gpio_button_data *bdata = dev_id; |
| 60 | struct gpio_keys_button *button = bdata->button; | 56 | struct gpio_keys_button *button = bdata->button; |
| 57 | unsigned long delay; | ||
| 61 | 58 | ||
| 62 | BUG_ON(irq != gpio_to_irq(button->gpio)); | 59 | BUG_ON(irq != gpio_to_irq(button->gpio)); |
| 63 | 60 | ||
| 64 | if (button->debounce_interval) | 61 | delay = button->debounce_interval ? |
| 65 | mod_timer(&bdata->timer, | 62 | msecs_to_jiffies(button->debounce_interval) : 0; |
| 66 | jiffies + msecs_to_jiffies(button->debounce_interval)); | 63 | schedule_delayed_work(&bdata->work, delay); |
| 67 | else | ||
| 68 | gpio_keys_report_event(bdata); | ||
| 69 | 64 | ||
| 70 | return IRQ_HANDLED; | 65 | return IRQ_HANDLED; |
| 71 | } | 66 | } |
| @@ -112,8 +107,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
| 112 | 107 | ||
| 113 | bdata->input = input; | 108 | bdata->input = input; |
| 114 | bdata->button = button; | 109 | bdata->button = button; |
| 115 | setup_timer(&bdata->timer, | 110 | INIT_DELAYED_WORK(&bdata->work, gpio_keys_report_event); |
| 116 | gpio_check_button, (unsigned long)bdata); | ||
| 117 | 111 | ||
| 118 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); | 112 | error = gpio_request(button->gpio, button->desc ?: "gpio_keys"); |
| 119 | if (error < 0) { | 113 | if (error < 0) { |
| @@ -142,8 +136,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
| 142 | } | 136 | } |
| 143 | 137 | ||
| 144 | error = request_irq(irq, gpio_keys_isr, | 138 | error = request_irq(irq, gpio_keys_isr, |
| 145 | IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_RISING | | 139 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
| 146 | IRQF_TRIGGER_FALLING, | ||
| 147 | button->desc ? button->desc : "gpio_keys", | 140 | button->desc ? button->desc : "gpio_keys", |
| 148 | bdata); | 141 | bdata); |
| 149 | if (error) { | 142 | if (error) { |
| @@ -173,8 +166,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev) | |||
| 173 | fail2: | 166 | fail2: |
| 174 | while (--i >= 0) { | 167 | while (--i >= 0) { |
| 175 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); | 168 | free_irq(gpio_to_irq(pdata->buttons[i].gpio), &ddata->data[i]); |
| 176 | if (pdata->buttons[i].debounce_interval) | 169 | cancel_delayed_work_sync(&ddata->data[i].work); |
| 177 | del_timer_sync(&ddata->data[i].timer); | ||
| 178 | gpio_free(pdata->buttons[i].gpio); | 170 | gpio_free(pdata->buttons[i].gpio); |
| 179 | } | 171 | } |
| 180 | 172 | ||
| @@ -198,8 +190,7 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev) | |||
| 198 | for (i = 0; i < pdata->nbuttons; i++) { | 190 | for (i = 0; i < pdata->nbuttons; i++) { |
| 199 | int irq = gpio_to_irq(pdata->buttons[i].gpio); | 191 | int irq = gpio_to_irq(pdata->buttons[i].gpio); |
| 200 | free_irq(irq, &ddata->data[i]); | 192 | free_irq(irq, &ddata->data[i]); |
| 201 | if (pdata->buttons[i].debounce_interval) | 193 | cancel_delayed_work_sync(&ddata->data[i].work); |
| 202 | del_timer_sync(&ddata->data[i].timer); | ||
| 203 | gpio_free(pdata->buttons[i].gpio); | 194 | gpio_free(pdata->buttons[i].gpio); |
| 204 | } | 195 | } |
| 205 | 196 | ||
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c new file mode 100644 index 000000000000..574eda2a4957 --- /dev/null +++ b/drivers/input/keyboard/lm8323.c | |||
| @@ -0,0 +1,878 @@ | |||
| 1 | /* | ||
| 2 | * drivers/i2c/chips/lm8323.c | ||
| 3 | * | ||
| 4 | * Copyright (C) 2007-2009 Nokia Corporation | ||
| 5 | * | ||
| 6 | * Written by Daniel Stone <daniel.stone@nokia.com> | ||
| 7 | * Timo O. Karjalainen <timo.o.karjalainen@nokia.com> | ||
| 8 | * | ||
| 9 | * Updated by Felipe Balbi <felipe.balbi@nokia.com> | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License as published by | ||
| 13 | * the Free Software Foundation (version 2 of the License only). | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 23 | */ | ||
| 24 | |||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/i2c.h> | ||
| 27 | #include <linux/interrupt.h> | ||
| 28 | #include <linux/sched.h> | ||
| 29 | #include <linux/mutex.h> | ||
| 30 | #include <linux/delay.h> | ||
| 31 | #include <linux/input.h> | ||
| 32 | #include <linux/leds.h> | ||
| 33 | #include <linux/i2c/lm8323.h> | ||
| 34 | |||
| 35 | /* Commands to send to the chip. */ | ||
| 36 | #define LM8323_CMD_READ_ID 0x80 /* Read chip ID. */ | ||
| 37 | #define LM8323_CMD_WRITE_CFG 0x81 /* Set configuration item. */ | ||
| 38 | #define LM8323_CMD_READ_INT 0x82 /* Get interrupt status. */ | ||
| 39 | #define LM8323_CMD_RESET 0x83 /* Reset, same as external one */ | ||
| 40 | #define LM8323_CMD_WRITE_PORT_SEL 0x85 /* Set GPIO in/out. */ | ||
| 41 | #define LM8323_CMD_WRITE_PORT_STATE 0x86 /* Set GPIO pullup. */ | ||
| 42 | #define LM8323_CMD_READ_PORT_SEL 0x87 /* Get GPIO in/out. */ | ||
| 43 | #define LM8323_CMD_READ_PORT_STATE 0x88 /* Get GPIO pullup. */ | ||
| 44 | #define LM8323_CMD_READ_FIFO 0x89 /* Read byte from FIFO. */ | ||
| 45 | #define LM8323_CMD_RPT_READ_FIFO 0x8a /* Read FIFO (no increment). */ | ||
| 46 | #define LM8323_CMD_SET_ACTIVE 0x8b /* Set active time. */ | ||
| 47 | #define LM8323_CMD_READ_ERR 0x8c /* Get error status. */ | ||
| 48 | #define LM8323_CMD_READ_ROTATOR 0x8e /* Read rotator status. */ | ||
| 49 | #define LM8323_CMD_SET_DEBOUNCE 0x8f /* Set debouncing time. */ | ||
| 50 | #define LM8323_CMD_SET_KEY_SIZE 0x90 /* Set keypad size. */ | ||
| 51 | #define LM8323_CMD_READ_KEY_SIZE 0x91 /* Get keypad size. */ | ||
| 52 | #define LM8323_CMD_READ_CFG 0x92 /* Get configuration item. */ | ||
| 53 | #define LM8323_CMD_WRITE_CLOCK 0x93 /* Set clock config. */ | ||
| 54 | #define LM8323_CMD_READ_CLOCK 0x94 /* Get clock config. */ | ||
| 55 | #define LM8323_CMD_PWM_WRITE 0x95 /* Write PWM script. */ | ||
| 56 | #define LM8323_CMD_START_PWM 0x96 /* Start PWM engine. */ | ||
| 57 | #define LM8323_CMD_STOP_PWM 0x97 /* Stop PWM engine. */ | ||
| 58 | |||
| 59 | /* Interrupt status. */ | ||
| 60 | #define INT_KEYPAD 0x01 /* Key event. */ | ||
| 61 | #define INT_ROTATOR 0x02 /* Rotator event. */ | ||
| 62 | #define INT_ERROR 0x08 /* Error: use CMD_READ_ERR. */ | ||
| 63 | #define INT_NOINIT 0x10 /* Lost configuration. */ | ||
| 64 | #define INT_PWM1 0x20 /* PWM1 stopped. */ | ||
| 65 | #define INT_PWM2 0x40 /* PWM2 stopped. */ | ||
| 66 | #define INT_PWM3 0x80 /* PWM3 stopped. */ | ||
| 67 | |||
| 68 | /* Errors (signalled by INT_ERROR, read with CMD_READ_ERR). */ | ||
| 69 | #define ERR_BADPAR 0x01 /* Bad parameter. */ | ||
| 70 | #define ERR_CMDUNK 0x02 /* Unknown command. */ | ||
| 71 | #define ERR_KEYOVR 0x04 /* Too many keys pressed. */ | ||
| 72 | #define ERR_FIFOOVER 0x40 /* FIFO overflow. */ | ||
| 73 | |||
| 74 | /* Configuration keys (CMD_{WRITE,READ}_CFG). */ | ||
| 75 | #define CFG_MUX1SEL 0x01 /* Select MUX1_OUT input. */ | ||
| 76 | #define CFG_MUX1EN 0x02 /* Enable MUX1_OUT. */ | ||
| 77 | #define CFG_MUX2SEL 0x04 /* Select MUX2_OUT input. */ | ||
| 78 | #define CFG_MUX2EN 0x08 /* Enable MUX2_OUT. */ | ||
| 79 | #define CFG_PSIZE 0x20 /* Package size (must be 0). */ | ||
| 80 | #define CFG_ROTEN 0x40 /* Enable rotator. */ | ||
| 81 | |||
| 82 | /* Clock settings (CMD_{WRITE,READ}_CLOCK). */ | ||
| 83 | #define CLK_RCPWM_INTERNAL 0x00 | ||
| 84 | #define CLK_RCPWM_EXTERNAL 0x03 | ||
| 85 | #define CLK_SLOWCLKEN 0x08 /* Enable 32.768kHz clock. */ | ||
| 86 | #define CLK_SLOWCLKOUT 0x40 /* Enable slow pulse output. */ | ||
| 87 | |||
| 88 | /* The possible addresses corresponding to CONFIG1 and CONFIG2 pin wirings. */ | ||
| 89 | #define LM8323_I2C_ADDR00 (0x84 >> 1) /* 1000 010x */ | ||
| 90 | #define LM8323_I2C_ADDR01 (0x86 >> 1) /* 1000 011x */ | ||
| 91 | #define LM8323_I2C_ADDR10 (0x88 >> 1) /* 1000 100x */ | ||
| 92 | #define LM8323_I2C_ADDR11 (0x8A >> 1) /* 1000 101x */ | ||
| 93 | |||
| 94 | /* Key event fifo length */ | ||
| 95 | #define LM8323_FIFO_LEN 15 | ||
| 96 | |||
| 97 | /* Commands for PWM engine; feed in with PWM_WRITE. */ | ||
| 98 | /* Load ramp counter from duty cycle field (range 0 - 0xff). */ | ||
| 99 | #define PWM_SET(v) (0x4000 | ((v) & 0xff)) | ||
| 100 | /* Go to start of script. */ | ||
| 101 | #define PWM_GOTOSTART 0x0000 | ||
| 102 | /* | ||
| 103 | * Stop engine (generates interrupt). If reset is 1, clear the program | ||
| 104 | * counter, else leave it. | ||
| 105 | */ | ||
| 106 | #define PWM_END(reset) (0xc000 | (!!(reset) << 11)) | ||
| 107 | /* | ||
| 108 | * Ramp. If s is 1, divide clock by 512, else divide clock by 16. | ||
| 109 | * Take t clock scales (up to 63) per step, for n steps (up to 126). | ||
| 110 | * If u is set, ramp up, else ramp down. | ||
| 111 | */ | ||
| 112 | #define PWM_RAMP(s, t, n, u) ((!!(s) << 14) | ((t) & 0x3f) << 8 | \ | ||
| 113 | ((n) & 0x7f) | ((u) ? 0 : 0x80)) | ||
| 114 | /* | ||
| 115 | * Loop (i.e. jump back to pos) for a given number of iterations (up to 63). | ||
| 116 | * If cnt is zero, execute until PWM_END is encountered. | ||
| 117 | */ | ||
| 118 | #define PWM_LOOP(cnt, pos) (0xa000 | (((cnt) & 0x3f) << 7) | \ | ||
| 119 | ((pos) & 0x3f)) | ||
| 120 | /* | ||
| 121 | * Wait for trigger. Argument is a mask of channels, shifted by the channel | ||
| 122 | * number, e.g. 0xa for channels 3 and 1. Note that channels are numbered | ||
| 123 | * from 1, not 0. | ||
| 124 | */ | ||
| 125 | #define PWM_WAIT_TRIG(chans) (0xe000 | (((chans) & 0x7) << 6)) | ||
| 126 | /* Send trigger. Argument is same as PWM_WAIT_TRIG. */ | ||
| 127 | #define PWM_SEND_TRIG(chans) (0xe000 | ((chans) & 0x7)) | ||
| 128 | |||
| 129 | struct lm8323_pwm { | ||
| 130 | int id; | ||
| 131 | int fade_time; | ||
| 132 | int brightness; | ||
| 133 | int desired_brightness; | ||
| 134 | bool enabled; | ||
| 135 | bool running; | ||
| 136 | /* pwm lock */ | ||
| 137 | struct mutex lock; | ||
| 138 | struct work_struct work; | ||
| 139 | struct led_classdev cdev; | ||
| 140 | struct lm8323_chip *chip; | ||
| 141 | }; | ||
| 142 | |||
| 143 | struct lm8323_chip { | ||
| 144 | /* device lock */ | ||
| 145 | struct mutex lock; | ||
| 146 | struct i2c_client *client; | ||
| 147 | struct work_struct work; | ||
| 148 | struct input_dev *idev; | ||
| 149 | bool kp_enabled; | ||
| 150 | bool pm_suspend; | ||
| 151 | unsigned keys_down; | ||
| 152 | char phys[32]; | ||
| 153 | unsigned short keymap[LM8323_KEYMAP_SIZE]; | ||
| 154 | int size_x; | ||
| 155 | int size_y; | ||
| 156 | int debounce_time; | ||
| 157 | int active_time; | ||
| 158 | struct lm8323_pwm pwm[LM8323_NUM_PWMS]; | ||
| 159 | }; | ||
| 160 | |||
| 161 | #define client_to_lm8323(c) container_of(c, struct lm8323_chip, client) | ||
| 162 | #define dev_to_lm8323(d) container_of(d, struct lm8323_chip, client->dev) | ||
| 163 | #define work_to_lm8323(w) container_of(w, struct lm8323_chip, work) | ||
| 164 | #define cdev_to_pwm(c) container_of(c, struct lm8323_pwm, cdev) | ||
| 165 | #define work_to_pwm(w) container_of(w, struct lm8323_pwm, work) | ||
| 166 | |||
| 167 | #define LM8323_MAX_DATA 8 | ||
| 168 | |||
| 169 | /* | ||
| 170 | * To write, we just access the chip's address in write mode, and dump the | ||
| 171 | * command and data out on the bus. The command byte and data are taken as | ||
| 172 | * sequential u8s out of varargs, to a maximum of LM8323_MAX_DATA. | ||
| 173 | */ | ||
| 174 | static int lm8323_write(struct lm8323_chip *lm, int len, ...) | ||
| 175 | { | ||
| 176 | int ret, i; | ||
| 177 | va_list ap; | ||
| 178 | u8 data[LM8323_MAX_DATA]; | ||
| 179 | |||
| 180 | va_start(ap, len); | ||
| 181 | |||
| 182 | if (unlikely(len > LM8323_MAX_DATA)) { | ||
| 183 | dev_err(&lm->client->dev, "tried to send %d bytes\n", len); | ||
| 184 | va_end(ap); | ||
| 185 | return 0; | ||
| 186 | } | ||
| 187 | |||
| 188 | for (i = 0; i < len; i++) | ||
| 189 | data[i] = va_arg(ap, int); | ||
| 190 | |||
| 191 | va_end(ap); | ||
| 192 | |||
| 193 | /* | ||
| 194 | * If the host is asleep while we send the data, we can get a NACK | ||
| 195 | * back while it wakes up, so try again, once. | ||
| 196 | */ | ||
| 197 | ret = i2c_master_send(lm->client, data, len); | ||
| 198 | if (unlikely(ret == -EREMOTEIO)) | ||
| 199 | ret = i2c_master_send(lm->client, data, len); | ||
| 200 | if (unlikely(ret != len)) | ||
| 201 | dev_err(&lm->client->dev, "sent %d bytes of %d total\n", | ||
| 202 | len, ret); | ||
| 203 | |||
| 204 | return ret; | ||
| 205 | } | ||
| 206 | |||
| 207 | /* | ||
| 208 | * To read, we first send the command byte to the chip and end the transaction, | ||
| 209 | * then access the chip in read mode, at which point it will send the data. | ||
| 210 | */ | ||
| 211 | static int lm8323_read(struct lm8323_chip *lm, u8 cmd, u8 *buf, int len) | ||
| 212 | { | ||
| 213 | int ret; | ||
| 214 | |||
| 215 | /* | ||
| 216 | * If the host is asleep while we send the byte, we can get a NACK | ||
| 217 | * back while it wakes up, so try again, once. | ||
| 218 | */ | ||
| 219 | ret = i2c_master_send(lm->client, &cmd, 1); | ||
| 220 | if (unlikely(ret == -EREMOTEIO)) | ||
| 221 | ret = i2c_master_send(lm->client, &cmd, 1); | ||
| 222 | if (unlikely(ret != 1)) { | ||
| 223 | dev_err(&lm->client->dev, "sending read cmd 0x%02x failed\n", | ||
| 224 | cmd); | ||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 228 | ret = i2c_master_recv(lm->client, buf, len); | ||
| 229 | if (unlikely(ret != len)) | ||
| 230 | dev_err(&lm->client->dev, "wanted %d bytes, got %d\n", | ||
| 231 | len, ret); | ||
| 232 | |||
| 233 | return ret; | ||
| 234 | } | ||
| 235 | |||
| 236 | /* | ||
| 237 | * Set the chip active time (idle time before it enters halt). | ||
| 238 | */ | ||
| 239 | static void lm8323_set_active_time(struct lm8323_chip *lm, int time) | ||
| 240 | { | ||
| 241 | lm8323_write(lm, 2, LM8323_CMD_SET_ACTIVE, time >> 2); | ||
| 242 | } | ||
| 243 | |||
| 244 | /* | ||
| 245 | * The signals are AT-style: the low 7 bits are the keycode, and the top | ||
| 246 | * bit indicates the state (1 for down, 0 for up). | ||
| 247 | */ | ||
| 248 | static inline u8 lm8323_whichkey(u8 event) | ||
| 249 | { | ||
| 250 | return event & 0x7f; | ||
| 251 | } | ||
| 252 | |||
| 253 | static inline int lm8323_ispress(u8 event) | ||
| 254 | { | ||
| 255 | return (event & 0x80) ? 1 : 0; | ||
| 256 | } | ||
| 257 | |||
| 258 | static void process_keys(struct lm8323_chip *lm) | ||
| 259 | { | ||
| 260 | u8 event; | ||
| 261 | u8 key_fifo[LM8323_FIFO_LEN + 1]; | ||
| 262 | int old_keys_down = lm->keys_down; | ||
| 263 | int ret; | ||
| 264 | int i = 0; | ||
| 265 | |||
| 266 | /* | ||
| 267 | * Read all key events from the FIFO at once. Next READ_FIFO clears the | ||
| 268 | * FIFO even if we didn't read all events previously. | ||
| 269 | */ | ||
| 270 | ret = lm8323_read(lm, LM8323_CMD_READ_FIFO, key_fifo, LM8323_FIFO_LEN); | ||
| 271 | |||
| 272 | if (ret < 0) { | ||
| 273 | dev_err(&lm->client->dev, "Failed reading fifo \n"); | ||
| 274 | return; | ||
| 275 | } | ||
| 276 | key_fifo[ret] = 0; | ||
| 277 | |||
| 278 | while ((event = key_fifo[i++])) { | ||
| 279 | u8 key = lm8323_whichkey(event); | ||
| 280 | int isdown = lm8323_ispress(event); | ||
| 281 | unsigned short keycode = lm->keymap[key]; | ||
| 282 | |||
| 283 | dev_vdbg(&lm->client->dev, "key 0x%02x %s\n", | ||
| 284 | key, isdown ? "down" : "up"); | ||
| 285 | |||
| 286 | if (lm->kp_enabled) { | ||
| 287 | input_event(lm->idev, EV_MSC, MSC_SCAN, key); | ||
| 288 | input_report_key(lm->idev, keycode, isdown); | ||
| 289 | input_sync(lm->idev); | ||
| 290 | } | ||
| 291 | |||
| 292 | if (isdown) | ||
| 293 | lm->keys_down++; | ||
| 294 | else | ||
| 295 | lm->keys_down--; | ||
| 296 | } | ||
| 297 | |||
| 298 | /* | ||
| 299 | * Errata: We need to ensure that the chip never enters halt mode | ||
| 300 | * during a keypress, so set active time to 0. When it's released, | ||
| 301 | * we can enter halt again, so set the active time back to normal. | ||
| 302 | */ | ||
| 303 | if (!old_keys_down && lm->keys_down) | ||
| 304 | lm8323_set_active_time(lm, 0); | ||
| 305 | if (old_keys_down && !lm->keys_down) | ||
| 306 | lm8323_set_active_time(lm, lm->active_time); | ||
| 307 | } | ||
| 308 | |||
| 309 | static void lm8323_process_error(struct lm8323_chip *lm) | ||
| 310 | { | ||
| 311 | u8 error; | ||
| 312 | |||
| 313 | if (lm8323_read(lm, LM8323_CMD_READ_ERR, &error, 1) == 1) { | ||
| 314 | if (error & ERR_FIFOOVER) | ||
| 315 | dev_vdbg(&lm->client->dev, "fifo overflow!\n"); | ||
| 316 | if (error & ERR_KEYOVR) | ||
| 317 | dev_vdbg(&lm->client->dev, | ||
| 318 | "more than two keys pressed\n"); | ||
| 319 | if (error & ERR_CMDUNK) | ||
| 320 | dev_vdbg(&lm->client->dev, | ||
| 321 | "unknown command submitted\n"); | ||
| 322 | if (error & ERR_BADPAR) | ||
| 323 | dev_vdbg(&lm->client->dev, "bad command parameter\n"); | ||
| 324 | } | ||
| 325 | } | ||
| 326 | |||
| 327 | static void lm8323_reset(struct lm8323_chip *lm) | ||
| 328 | { | ||
| 329 | /* The docs say we must pass 0xAA as the data byte. */ | ||
| 330 | lm8323_write(lm, 2, LM8323_CMD_RESET, 0xAA); | ||
| 331 | } | ||
| 332 | |||
| 333 | static int lm8323_configure(struct lm8323_chip *lm) | ||
| 334 | { | ||
| 335 | int keysize = (lm->size_x << 4) | lm->size_y; | ||
| 336 | int clock = (CLK_SLOWCLKEN | CLK_RCPWM_EXTERNAL); | ||
| 337 | int debounce = lm->debounce_time >> 2; | ||
| 338 | int active = lm->active_time >> 2; | ||
| 339 | |||
| 340 | /* | ||
| 341 | * Active time must be greater than the debounce time: if it's | ||
| 342 | * a close-run thing, give ourselves a 12ms buffer. | ||
| 343 | */ | ||
| 344 | if (debounce >= active) | ||
| 345 | active = debounce + 3; | ||
| 346 | |||
| 347 | lm8323_write(lm, 2, LM8323_CMD_WRITE_CFG, 0); | ||
| 348 | lm8323_write(lm, 2, LM8323_CMD_WRITE_CLOCK, clock); | ||
| 349 | lm8323_write(lm, 2, LM8323_CMD_SET_KEY_SIZE, keysize); | ||
| 350 | lm8323_set_active_time(lm, lm->active_time); | ||
| 351 | lm8323_write(lm, 2, LM8323_CMD_SET_DEBOUNCE, debounce); | ||
| 352 | lm8323_write(lm, 3, LM8323_CMD_WRITE_PORT_STATE, 0xff, 0xff); | ||
| 353 | lm8323_write(lm, 3, LM8323_CMD_WRITE_PORT_SEL, 0, 0); | ||
| 354 | |||
| 355 | /* | ||
| 356 | * Not much we can do about errors at this point, so just hope | ||
| 357 | * for the best. | ||
| 358 | */ | ||
| 359 | |||
| 360 | return 0; | ||
| 361 | } | ||
| 362 | |||
| 363 | static void pwm_done(struct lm8323_pwm *pwm) | ||
| 364 | { | ||
| 365 | mutex_lock(&pwm->lock); | ||
| 366 | pwm->running = false; | ||
| 367 | if (pwm->desired_brightness != pwm->brightness) | ||
| 368 | schedule_work(&pwm->work); | ||
| 369 | mutex_unlock(&pwm->lock); | ||
| 370 | } | ||
| 371 | |||
| 372 | /* | ||
| 373 | * Bottom half: handle the interrupt by posting key events, or dealing with | ||
| 374 | * errors appropriately. | ||
| 375 | */ | ||
| 376 | static void lm8323_work(struct work_struct *work) | ||
| 377 | { | ||
| 378 | struct lm8323_chip *lm = work_to_lm8323(work); | ||
| 379 | u8 ints; | ||
| 380 | int i; | ||
| 381 | |||
| 382 | mutex_lock(&lm->lock); | ||
| 383 | |||
| 384 | while ((lm8323_read(lm, LM8323_CMD_READ_INT, &ints, 1) == 1) && ints) { | ||
| 385 | if (likely(ints & INT_KEYPAD)) | ||
| 386 | process_keys(lm); | ||
| 387 | if (ints & INT_ROTATOR) { | ||
| 388 | /* We don't currently support the rotator. */ | ||
| 389 | dev_vdbg(&lm->client->dev, "rotator fired\n"); | ||
| 390 | } | ||
| 391 | if (ints & INT_ERROR) { | ||
| 392 | dev_vdbg(&lm->client->dev, "error!\n"); | ||
| 393 | lm8323_process_error(lm); | ||
| 394 | } | ||
| 395 | if (ints & INT_NOINIT) { | ||
| 396 | dev_err(&lm->client->dev, "chip lost config; " | ||
| 397 | "reinitialising\n"); | ||
| 398 | lm8323_configure(lm); | ||
| 399 | } | ||
| 400 | for (i = 0; i < LM8323_NUM_PWMS; i++) { | ||
| 401 | if (ints & (1 << (INT_PWM1 + i))) { | ||
| 402 | dev_vdbg(&lm->client->dev, | ||
| 403 | "pwm%d engine completed\n", i); | ||
| 404 | pwm_done(&lm->pwm[i]); | ||
| 405 | } | ||
| 406 | } | ||
| 407 | } | ||
| 408 | |||
| 409 | mutex_unlock(&lm->lock); | ||
| 410 | } | ||
| 411 | |||
| 412 | /* | ||
| 413 | * We cannot use I2C in interrupt context, so we just schedule work. | ||
| 414 | */ | ||
| 415 | static irqreturn_t lm8323_irq(int irq, void *data) | ||
| 416 | { | ||
| 417 | struct lm8323_chip *lm = data; | ||
| 418 | |||
| 419 | schedule_work(&lm->work); | ||
| 420 | |||
| 421 | return IRQ_HANDLED; | ||
| 422 | } | ||
| 423 | |||
| 424 | /* | ||
| 425 | * Read the chip ID. | ||
| 426 | */ | ||
| 427 | static int lm8323_read_id(struct lm8323_chip *lm, u8 *buf) | ||
| 428 | { | ||
| 429 | int bytes; | ||
| 430 | |||
| 431 | bytes = lm8323_read(lm, LM8323_CMD_READ_ID, buf, 2); | ||
| 432 | if (unlikely(bytes != 2)) | ||
| 433 | return -EIO; | ||
| 434 | |||
| 435 | return 0; | ||
| 436 | } | ||
| 437 | |||
| 438 | static void lm8323_write_pwm_one(struct lm8323_pwm *pwm, int pos, u16 cmd) | ||
| 439 | { | ||
| 440 | lm8323_write(pwm->chip, 4, LM8323_CMD_PWM_WRITE, (pos << 2) | pwm->id, | ||
| 441 | (cmd & 0xff00) >> 8, cmd & 0x00ff); | ||
| 442 | } | ||
| 443 | |||
| 444 | /* | ||
| 445 | * Write a script into a given PWM engine, concluding with PWM_END. | ||
| 446 | * If 'kill' is nonzero, the engine will be shut down at the end | ||
| 447 | * of the script, producing a zero output. Otherwise the engine | ||
| 448 | * will be kept running at the final PWM level indefinitely. | ||
| 449 | */ | ||
| 450 | static void lm8323_write_pwm(struct lm8323_pwm *pwm, int kill, | ||
| 451 | int len, const u16 *cmds) | ||
| 452 | { | ||
| 453 | int i; | ||
| 454 | |||
| 455 | for (i = 0; i < len; i++) | ||
| 456 | lm8323_write_pwm_one(pwm, i, cmds[i]); | ||
| 457 | |||
| 458 | lm8323_write_pwm_one(pwm, i++, PWM_END(kill)); | ||
| 459 | lm8323_write(pwm->chip, 2, LM8323_CMD_START_PWM, pwm->id); | ||
| 460 | pwm->running = true; | ||
| 461 | } | ||
| 462 | |||
| 463 | static void lm8323_pwm_work(struct work_struct *work) | ||
| 464 | { | ||
| 465 | struct lm8323_pwm *pwm = work_to_pwm(work); | ||
| 466 | int div512, perstep, steps, hz, up, kill; | ||
| 467 | u16 pwm_cmds[3]; | ||
| 468 | int num_cmds = 0; | ||
| 469 | |||
| 470 | mutex_lock(&pwm->lock); | ||
| 471 | |||
| 472 | /* | ||
| 473 | * Do nothing if we're already at the requested level, | ||
| 474 | * or previous setting is not yet complete. In the latter | ||
| 475 | * case we will be called again when the previous PWM script | ||
| 476 | * finishes. | ||
| 477 | */ | ||
| 478 | if (pwm->running || pwm->desired_brightness == pwm->brightness) | ||
| 479 | goto out; | ||
| 480 | |||
| 481 | kill = (pwm->desired_brightness == 0); | ||
| 482 | up = (pwm->desired_brightness > pwm->brightness); | ||
| 483 | steps = abs(pwm->desired_brightness - pwm->brightness); | ||
| 484 | |||
| 485 | /* | ||
| 486 | * Convert time (in ms) into a divisor (512 or 16 on a refclk of | ||
| 487 | * 32768Hz), and number of ticks per step. | ||
| 488 | */ | ||
| 489 | if ((pwm->fade_time / steps) > (32768 / 512)) { | ||
| 490 | div512 = 1; | ||
| 491 | hz = 32768 / 512; | ||
| 492 | } else { | ||
| 493 | div512 = 0; | ||
| 494 | hz = 32768 / 16; | ||
| 495 | } | ||
| 496 | |||
| 497 | perstep = (hz * pwm->fade_time) / (steps * 1000); | ||
| 498 | |||
| 499 | if (perstep == 0) | ||
| 500 | perstep = 1; | ||
| 501 | else if (perstep > 63) | ||
| 502 | perstep = 63; | ||
| 503 | |||
| 504 | while (steps) { | ||
| 505 | int s; | ||
| 506 | |||
| 507 | s = min(126, steps); | ||
| 508 | pwm_cmds[num_cmds++] = PWM_RAMP(div512, perstep, s, up); | ||
| 509 | steps -= s; | ||
| 510 | } | ||
| 511 | |||
| 512 | lm8323_write_pwm(pwm, kill, num_cmds, pwm_cmds); | ||
| 513 | pwm->brightness = pwm->desired_brightness; | ||
| 514 | |||
| 515 | out: | ||
| 516 | mutex_unlock(&pwm->lock); | ||
| 517 | } | ||
| 518 | |||
| 519 | static void lm8323_pwm_set_brightness(struct led_classdev *led_cdev, | ||
| 520 | enum led_brightness brightness) | ||
| 521 | { | ||
| 522 | struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev); | ||
| 523 | struct lm8323_chip *lm = pwm->chip; | ||
| 524 | |||
| 525 | mutex_lock(&pwm->lock); | ||
| 526 | pwm->desired_brightness = brightness; | ||
| 527 | mutex_unlock(&pwm->lock); | ||
| 528 | |||
| 529 | if (in_interrupt()) { | ||
| 530 | schedule_work(&pwm->work); | ||
| 531 | } else { | ||
| 532 | /* | ||
| 533 | * Schedule PWM work as usual unless we are going into suspend | ||
| 534 | */ | ||
| 535 | mutex_lock(&lm->lock); | ||
| 536 | if (likely(!lm->pm_suspend)) | ||
| 537 | schedule_work(&pwm->work); | ||
| 538 | else | ||
| 539 | lm8323_pwm_work(&pwm->work); | ||
| 540 | mutex_unlock(&lm->lock); | ||
| 541 | } | ||
| 542 | } | ||
| 543 | |||
| 544 | static ssize_t lm8323_pwm_show_time(struct device *dev, | ||
| 545 | struct device_attribute *attr, char *buf) | ||
| 546 | { | ||
| 547 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
| 548 | struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev); | ||
| 549 | |||
| 550 | return sprintf(buf, "%d\n", pwm->fade_time); | ||
| 551 | } | ||
| 552 | |||
| 553 | static ssize_t lm8323_pwm_store_time(struct device *dev, | ||
| 554 | struct device_attribute *attr, const char *buf, size_t len) | ||
| 555 | { | ||
| 556 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
| 557 | struct lm8323_pwm *pwm = cdev_to_pwm(led_cdev); | ||
| 558 | int ret; | ||
| 559 | unsigned long time; | ||
| 560 | |||
| 561 | ret = strict_strtoul(buf, 10, &time); | ||
| 562 | /* Numbers only, please. */ | ||
| 563 | if (ret) | ||
| 564 | return -EINVAL; | ||
| 565 | |||
| 566 | pwm->fade_time = time; | ||
| 567 | |||
| 568 | return strlen(buf); | ||
| 569 | } | ||
| 570 | static DEVICE_ATTR(time, 0644, lm8323_pwm_show_time, lm8323_pwm_store_time); | ||
| 571 | |||
| 572 | static int init_pwm(struct lm8323_chip *lm, int id, struct device *dev, | ||
| 573 | const char *name) | ||
| 574 | { | ||
| 575 | struct lm8323_pwm *pwm; | ||
| 576 | |||
| 577 | BUG_ON(id > 3); | ||
| 578 | |||
| 579 | pwm = &lm->pwm[id - 1]; | ||
| 580 | |||
| 581 | pwm->id = id; | ||
| 582 | pwm->fade_time = 0; | ||
| 583 | pwm->brightness = 0; | ||
| 584 | pwm->desired_brightness = 0; | ||
| 585 | pwm->running = false; | ||
| 586 | pwm->enabled = false; | ||
| 587 | INIT_WORK(&pwm->work, lm8323_pwm_work); | ||
| 588 | mutex_init(&pwm->lock); | ||
| 589 | pwm->chip = lm; | ||
| 590 | |||
| 591 | if (name) { | ||
| 592 | pwm->cdev.name = name; | ||
| 593 | pwm->cdev.brightness_set = lm8323_pwm_set_brightness; | ||
| 594 | if (led_classdev_register(dev, &pwm->cdev) < 0) { | ||
| 595 | dev_err(dev, "couldn't register PWM %d\n", id); | ||
| 596 | return -1; | ||
| 597 | } | ||
| 598 | if (device_create_file(pwm->cdev.dev, | ||
| 599 | &dev_attr_time) < 0) { | ||
| 600 | dev_err(dev, "couldn't register time attribute\n"); | ||
| 601 | led_classdev_unregister(&pwm->cdev); | ||
| 602 | return -1; | ||
| 603 | } | ||
| 604 | pwm->enabled = true; | ||
| 605 | } | ||
| 606 | |||
| 607 | return 0; | ||
| 608 | } | ||
| 609 | |||
| 610 | static struct i2c_driver lm8323_i2c_driver; | ||
| 611 | |||
| 612 | static ssize_t lm8323_show_disable(struct device *dev, | ||
| 613 | struct device_attribute *attr, char *buf) | ||
| 614 | { | ||
| 615 | struct lm8323_chip *lm = dev_get_drvdata(dev); | ||
| 616 | |||
| 617 | return sprintf(buf, "%u\n", !lm->kp_enabled); | ||
| 618 | } | ||
| 619 | |||
| 620 | static ssize_t lm8323_set_disable(struct device *dev, | ||
| 621 | struct device_attribute *attr, | ||
| 622 | const char *buf, size_t count) | ||
| 623 | { | ||
| 624 | struct lm8323_chip *lm = dev_get_drvdata(dev); | ||
| 625 | int ret; | ||
| 626 | unsigned long i; | ||
| 627 | |||
| 628 | ret = strict_strtoul(buf, 10, &i); | ||
| 629 | |||
| 630 | mutex_lock(&lm->lock); | ||
| 631 | lm->kp_enabled = !i; | ||
| 632 | mutex_unlock(&lm->lock); | ||
| 633 | |||
| 634 | return count; | ||
| 635 | } | ||
| 636 | static DEVICE_ATTR(disable_kp, 0644, lm8323_show_disable, lm8323_set_disable); | ||
| 637 | |||
| 638 | static int __devinit lm8323_probe(struct i2c_client *client, | ||
| 639 | const struct i2c_device_id *id) | ||
| 640 | { | ||
| 641 | struct lm8323_platform_data *pdata = client->dev.platform_data; | ||
| 642 | struct input_dev *idev; | ||
| 643 | struct lm8323_chip *lm; | ||
| 644 | int i, err; | ||
| 645 | unsigned long tmo; | ||
| 646 | u8 data[2]; | ||
| 647 | |||
| 648 | if (!pdata || !pdata->size_x || !pdata->size_y) { | ||
| 649 | dev_err(&client->dev, "missing platform_data\n"); | ||
| 650 | return -EINVAL; | ||
| 651 | } | ||
| 652 | |||
| 653 | if (pdata->size_x > 8) { | ||
| 654 | dev_err(&client->dev, "invalid x size %d specified\n", | ||
| 655 | pdata->size_x); | ||
| 656 | return -EINVAL; | ||
| 657 | } | ||
| 658 | |||
| 659 | if (pdata->size_y > 12) { | ||
| 660 | dev_err(&client->dev, "invalid y size %d specified\n", | ||
| 661 | pdata->size_y); | ||
| 662 | return -EINVAL; | ||
| 663 | } | ||
| 664 | |||
| 665 | lm = kzalloc(sizeof *lm, GFP_KERNEL); | ||
| 666 | idev = input_allocate_device(); | ||
| 667 | if (!lm || !idev) { | ||
| 668 | err = -ENOMEM; | ||
| 669 | goto fail1; | ||
| 670 | } | ||
| 671 | |||
| 672 | i2c_set_clientdata(client, lm); | ||
| 673 | |||
| 674 | lm->client = client; | ||
| 675 | lm->idev = idev; | ||
| 676 | mutex_init(&lm->lock); | ||
| 677 | INIT_WORK(&lm->work, lm8323_work); | ||
| 678 | |||
| 679 | lm->size_x = pdata->size_x; | ||
| 680 | lm->size_y = pdata->size_y; | ||
| 681 | dev_vdbg(&client->dev, "Keypad size: %d x %d\n", | ||
| 682 | lm->size_x, lm->size_y); | ||
| 683 | |||
| 684 | lm->debounce_time = pdata->debounce_time; | ||
| 685 | lm->active_time = pdata->active_time; | ||
| 686 | |||
| 687 | lm8323_reset(lm); | ||
| 688 | |||
| 689 | /* Nothing's set up to service the IRQ yet, so just spin for max. | ||
| 690 | * 100ms until we can configure. */ | ||
| 691 | tmo = jiffies + msecs_to_jiffies(100); | ||
| 692 | while (lm8323_read(lm, LM8323_CMD_READ_INT, data, 1) == 1) { | ||
| 693 | if (data[0] & INT_NOINIT) | ||
| 694 | break; | ||
| 695 | |||
| 696 | if (time_after(jiffies, tmo)) { | ||
| 697 | dev_err(&client->dev, | ||
| 698 | "timeout waiting for initialisation\n"); | ||
| 699 | break; | ||
| 700 | } | ||
| 701 | |||
| 702 | msleep(1); | ||
| 703 | } | ||
| 704 | |||
| 705 | lm8323_configure(lm); | ||
| 706 | |||
| 707 | /* If a true probe check the device */ | ||
| 708 | if (lm8323_read_id(lm, data) != 0) { | ||
| 709 | dev_err(&client->dev, "device not found\n"); | ||
| 710 | err = -ENODEV; | ||
| 711 | goto fail1; | ||
| 712 | } | ||
| 713 | |||
| 714 | for (i = 0; i < LM8323_NUM_PWMS; i++) { | ||
| 715 | err = init_pwm(lm, i + 1, &client->dev, pdata->pwm_names[i]); | ||
| 716 | if (err < 0) | ||
| 717 | goto fail2; | ||
| 718 | } | ||
| 719 | |||
| 720 | lm->kp_enabled = true; | ||
| 721 | err = device_create_file(&client->dev, &dev_attr_disable_kp); | ||
| 722 | if (err < 0) | ||
| 723 | goto fail2; | ||
| 724 | |||
| 725 | idev->name = pdata->name ? : "LM8323 keypad"; | ||
| 726 | snprintf(lm->phys, sizeof(lm->phys), | ||
| 727 | "%s/input-kp", dev_name(&client->dev)); | ||
| 728 | idev->phys = lm->phys; | ||
| 729 | |||
| 730 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_MSC); | ||
| 731 | __set_bit(MSC_SCAN, idev->mscbit); | ||
| 732 | for (i = 0; i < LM8323_KEYMAP_SIZE; i++) { | ||
| 733 | __set_bit(pdata->keymap[i], idev->keybit); | ||
| 734 | lm->keymap[i] = pdata->keymap[i]; | ||
| 735 | } | ||
| 736 | __clear_bit(KEY_RESERVED, idev->keybit); | ||
| 737 | |||
| 738 | if (pdata->repeat) | ||
| 739 | __set_bit(EV_REP, idev->evbit); | ||
| 740 | |||
| 741 | err = input_register_device(idev); | ||
| 742 | if (err) { | ||
| 743 | dev_dbg(&client->dev, "error registering input device\n"); | ||
| 744 | goto fail3; | ||
| 745 | } | ||
| 746 | |||
| 747 | err = request_irq(client->irq, lm8323_irq, | ||
| 748 | IRQF_TRIGGER_FALLING | IRQF_DISABLED, | ||
| 749 | "lm8323", lm); | ||
| 750 | if (err) { | ||
| 751 | dev_err(&client->dev, "could not get IRQ %d\n", client->irq); | ||
| 752 | goto fail4; | ||
| 753 | } | ||
| 754 | |||
| 755 | device_init_wakeup(&client->dev, 1); | ||
| 756 | enable_irq_wake(client->irq); | ||
| 757 | |||
| 758 | return 0; | ||
| 759 | |||
| 760 | fail4: | ||
| 761 | input_unregister_device(idev); | ||
| 762 | idev = NULL; | ||
| 763 | fail3: | ||
| 764 | device_remove_file(&client->dev, &dev_attr_disable_kp); | ||
| 765 | fail2: | ||
| 766 | while (--i >= 0) | ||
| 767 | if (lm->pwm[i].enabled) | ||
| 768 | led_classdev_unregister(&lm->pwm[i].cdev); | ||
| 769 | fail1: | ||
| 770 | input_free_device(idev); | ||
| 771 | kfree(lm); | ||
| 772 | return err; | ||
| 773 | } | ||
| 774 | |||
| 775 | static int __devexit lm8323_remove(struct i2c_client *client) | ||
| 776 | { | ||
| 777 | struct lm8323_chip *lm = i2c_get_clientdata(client); | ||
| 778 | int i; | ||
| 779 | |||
| 780 | disable_irq_wake(client->irq); | ||
| 781 | free_irq(client->irq, lm); | ||
| 782 | cancel_work_sync(&lm->work); | ||
| 783 | |||
| 784 | input_unregister_device(lm->idev); | ||
| 785 | |||
| 786 | device_remove_file(&lm->client->dev, &dev_attr_disable_kp); | ||
| 787 | |||
| 788 | for (i = 0; i < 3; i++) | ||
| 789 | if (lm->pwm[i].enabled) | ||
| 790 | led_classdev_unregister(&lm->pwm[i].cdev); | ||
| 791 | |||
| 792 | kfree(lm); | ||
| 793 | |||
| 794 | return 0; | ||
| 795 | } | ||
| 796 | |||
| 797 | #ifdef CONFIG_PM | ||
| 798 | /* | ||
| 799 | * We don't need to explicitly suspend the chip, as it already switches off | ||
| 800 | * when there's no activity. | ||
| 801 | */ | ||
| 802 | static int lm8323_suspend(struct i2c_client *client, pm_message_t mesg) | ||
| 803 | { | ||
| 804 | struct lm8323_chip *lm = i2c_get_clientdata(client); | ||
| 805 | int i; | ||
| 806 | |||
| 807 | set_irq_wake(client->irq, 0); | ||
| 808 | disable_irq(client->irq); | ||
| 809 | |||
| 810 | mutex_lock(&lm->lock); | ||
| 811 | lm->pm_suspend = true; | ||
| 812 | mutex_unlock(&lm->lock); | ||
| 813 | |||
| 814 | for (i = 0; i < 3; i++) | ||
| 815 | if (lm->pwm[i].enabled) | ||
| 816 | led_classdev_suspend(&lm->pwm[i].cdev); | ||
| 817 | |||
| 818 | return 0; | ||
| 819 | } | ||
| 820 | |||
| 821 | static int lm8323_resume(struct i2c_client *client) | ||
| 822 | { | ||
| 823 | struct lm8323_chip *lm = i2c_get_clientdata(client); | ||
| 824 | int i; | ||
| 825 | |||
| 826 | mutex_lock(&lm->lock); | ||
| 827 | lm->pm_suspend = false; | ||
| 828 | mutex_unlock(&lm->lock); | ||
| 829 | |||
| 830 | for (i = 0; i < 3; i++) | ||
| 831 | if (lm->pwm[i].enabled) | ||
| 832 | led_classdev_resume(&lm->pwm[i].cdev); | ||
| 833 | |||
| 834 | enable_irq(client->irq); | ||
| 835 | set_irq_wake(client->irq, 1); | ||
| 836 | |||
| 837 | return 0; | ||
| 838 | } | ||
| 839 | #else | ||
| 840 | #define lm8323_suspend NULL | ||
| 841 | #define lm8323_resume NULL | ||
| 842 | #endif | ||
| 843 | |||
| 844 | static const struct i2c_device_id lm8323_id[] = { | ||
| 845 | { "lm8323", 0 }, | ||
| 846 | { } | ||
| 847 | }; | ||
| 848 | |||
| 849 | static struct i2c_driver lm8323_i2c_driver = { | ||
| 850 | .driver = { | ||
| 851 | .name = "lm8323", | ||
| 852 | }, | ||
| 853 | .probe = lm8323_probe, | ||
| 854 | .remove = __devexit_p(lm8323_remove), | ||
| 855 | .suspend = lm8323_suspend, | ||
| 856 | .resume = lm8323_resume, | ||
| 857 | .id_table = lm8323_id, | ||
| 858 | }; | ||
| 859 | MODULE_DEVICE_TABLE(i2c, lm8323_id); | ||
| 860 | |||
| 861 | static int __init lm8323_init(void) | ||
| 862 | { | ||
| 863 | return i2c_add_driver(&lm8323_i2c_driver); | ||
| 864 | } | ||
| 865 | module_init(lm8323_init); | ||
| 866 | |||
| 867 | static void __exit lm8323_exit(void) | ||
| 868 | { | ||
| 869 | i2c_del_driver(&lm8323_i2c_driver); | ||
| 870 | } | ||
| 871 | module_exit(lm8323_exit); | ||
| 872 | |||
| 873 | MODULE_AUTHOR("Timo O. Karjalainen <timo.o.karjalainen@nokia.com>"); | ||
| 874 | MODULE_AUTHOR("Daniel Stone"); | ||
| 875 | MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>"); | ||
| 876 | MODULE_DESCRIPTION("LM8323 keypad driver"); | ||
| 877 | MODULE_LICENSE("GPL"); | ||
| 878 | |||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 06f46fcc0772..1acfa3a05aad 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
| @@ -193,6 +193,16 @@ config INPUT_CM109 | |||
| 193 | To compile this driver as a module, choose M here: the module will be | 193 | To compile this driver as a module, choose M here: the module will be |
| 194 | called cm109. | 194 | called cm109. |
| 195 | 195 | ||
| 196 | config INPUT_TWL4030_PWRBUTTON | ||
| 197 | tristate "TWL4030 Power button Driver" | ||
| 198 | depends on TWL4030_CORE | ||
| 199 | help | ||
| 200 | Say Y here if you want to enable power key reporting via the | ||
| 201 | TWL4030 family of chips. | ||
| 202 | |||
| 203 | To compile this driver as a module, choose M here. The module will | ||
| 204 | be called twl4030_pwrbutton. | ||
| 205 | |||
| 196 | config INPUT_UINPUT | 206 | config INPUT_UINPUT |
| 197 | tristate "User level driver support" | 207 | tristate "User level driver support" |
| 198 | help | 208 | help |
| @@ -250,4 +260,13 @@ config INPUT_RB532_BUTTON | |||
| 250 | To compile this driver as a module, choose M here: the | 260 | To compile this driver as a module, choose M here: the |
| 251 | module will be called rb532_button. | 261 | module will be called rb532_button. |
| 252 | 262 | ||
| 263 | config INPUT_DM355EVM | ||
| 264 | tristate "TI DaVinci DM355 EVM Keypad and IR Remote" | ||
| 265 | depends on MFD_DM355EVM_MSP | ||
| 266 | help | ||
| 267 | Supports the pushbuttons and IR remote used with | ||
| 268 | the DM355 EVM board. | ||
| 269 | |||
| 270 | To compile this driver as a module, choose M here: the | ||
| 271 | module will be called dm355evm_keys. | ||
| 253 | endif | 272 | endif |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index eb3f407baedf..0d979fd4cd57 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
| @@ -10,6 +10,7 @@ obj-$(CONFIG_INPUT_ATI_REMOTE2) += ati_remote2.o | |||
| 10 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o | 10 | obj-$(CONFIG_INPUT_ATLAS_BTNS) += atlas_btns.o |
| 11 | obj-$(CONFIG_INPUT_CM109) += cm109.o | 11 | obj-$(CONFIG_INPUT_CM109) += cm109.o |
| 12 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o | 12 | obj-$(CONFIG_INPUT_COBALT_BTNS) += cobalt_btns.o |
| 13 | obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o | ||
| 13 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 14 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
| 14 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o | 15 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o |
| 15 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o | 16 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o |
| @@ -21,6 +22,7 @@ obj-$(CONFIG_INPUT_RB532_BUTTON) += rb532_button.o | |||
| 21 | obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o | 22 | obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER) += rotary_encoder.o |
| 22 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | 23 | obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o |
| 23 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | 24 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o |
| 25 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o | ||
| 24 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o | 26 | obj-$(CONFIG_INPUT_UINPUT) += uinput.o |
| 25 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o | 27 | obj-$(CONFIG_INPUT_WISTRON_BTNS) += wistron_btns.o |
| 26 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o | 28 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o |
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 922c05141585..0501f0e65157 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
| @@ -509,7 +509,7 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc | |||
| 509 | 509 | ||
| 510 | old_keycode = ar2->keycode[mode][index]; | 510 | old_keycode = ar2->keycode[mode][index]; |
| 511 | ar2->keycode[mode][index] = keycode; | 511 | ar2->keycode[mode][index] = keycode; |
| 512 | set_bit(keycode, idev->keybit); | 512 | __set_bit(keycode, idev->keybit); |
| 513 | 513 | ||
| 514 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { | 514 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { |
| 515 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { | 515 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { |
| @@ -518,7 +518,7 @@ static int ati_remote2_setkeycode(struct input_dev *idev, int scancode, int keyc | |||
| 518 | } | 518 | } |
| 519 | } | 519 | } |
| 520 | 520 | ||
| 521 | clear_bit(old_keycode, idev->keybit); | 521 | __clear_bit(old_keycode, idev->keybit); |
| 522 | 522 | ||
| 523 | return 0; | 523 | return 0; |
| 524 | } | 524 | } |
| @@ -543,7 +543,7 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) | |||
| 543 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { | 543 | for (mode = 0; mode < ATI_REMOTE2_MODES; mode++) { |
| 544 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { | 544 | for (index = 0; index < ARRAY_SIZE(ati_remote2_key_table); index++) { |
| 545 | ar2->keycode[mode][index] = ati_remote2_key_table[index].keycode; | 545 | ar2->keycode[mode][index] = ati_remote2_key_table[index].keycode; |
| 546 | set_bit(ar2->keycode[mode][index], idev->keybit); | 546 | __set_bit(ar2->keycode[mode][index], idev->keybit); |
| 547 | } | 547 | } |
| 548 | } | 548 | } |
| 549 | 549 | ||
| @@ -554,11 +554,11 @@ static int ati_remote2_input_init(struct ati_remote2 *ar2) | |||
| 554 | ar2->keycode[ATI_REMOTE2_AUX3][index] = KEY_PROG3; | 554 | ar2->keycode[ATI_REMOTE2_AUX3][index] = KEY_PROG3; |
| 555 | ar2->keycode[ATI_REMOTE2_AUX4][index] = KEY_PROG4; | 555 | ar2->keycode[ATI_REMOTE2_AUX4][index] = KEY_PROG4; |
| 556 | ar2->keycode[ATI_REMOTE2_PC][index] = KEY_PC; | 556 | ar2->keycode[ATI_REMOTE2_PC][index] = KEY_PC; |
| 557 | set_bit(KEY_PROG1, idev->keybit); | 557 | __set_bit(KEY_PROG1, idev->keybit); |
| 558 | set_bit(KEY_PROG2, idev->keybit); | 558 | __set_bit(KEY_PROG2, idev->keybit); |
| 559 | set_bit(KEY_PROG3, idev->keybit); | 559 | __set_bit(KEY_PROG3, idev->keybit); |
| 560 | set_bit(KEY_PROG4, idev->keybit); | 560 | __set_bit(KEY_PROG4, idev->keybit); |
| 561 | set_bit(KEY_PC, idev->keybit); | 561 | __set_bit(KEY_PC, idev->keybit); |
| 562 | 562 | ||
| 563 | idev->rep[REP_DELAY] = 250; | 563 | idev->rep[REP_DELAY] = 250; |
| 564 | idev->rep[REP_PERIOD] = 33; | 564 | idev->rep[REP_PERIOD] = 33; |
diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c new file mode 100644 index 000000000000..a63315ce4a6c --- /dev/null +++ b/drivers/input/misc/dm355evm_keys.c | |||
| @@ -0,0 +1,329 @@ | |||
| 1 | /* | ||
| 2 | * dm355evm_keys.c - support buttons and IR remote on DM355 EVM board | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 by David Brownell | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | #include <linux/kernel.h> | ||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/input.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/interrupt.h> | ||
| 16 | |||
| 17 | #include <linux/i2c/dm355evm_msp.h> | ||
| 18 | |||
| 19 | |||
| 20 | /* | ||
| 21 | * The MSP430 firmware on the DM355 EVM monitors on-board pushbuttons | ||
| 22 | * and an IR receptor used for the remote control. When any key is | ||
| 23 | * pressed, or its autorepeat kicks in, an event is sent. This driver | ||
| 24 | * read those events from the small (32 event) queue and reports them. | ||
| 25 | * | ||
| 26 | * Because we communicate with the MSP430 using I2C, and all I2C calls | ||
| 27 | * in Linux sleep, we need to cons up a kind of threaded IRQ handler | ||
| 28 | * using a work_struct. The IRQ is active low, but we use it through | ||
| 29 | * the GPIO controller so we can trigger on falling edges. | ||
| 30 | * | ||
| 31 | * Note that physically there can only be one of these devices. | ||
| 32 | * | ||
| 33 | * This driver was tested with firmware revision A4. | ||
| 34 | */ | ||
| 35 | struct dm355evm_keys { | ||
| 36 | struct work_struct work; | ||
| 37 | struct input_dev *input; | ||
| 38 | struct device *dev; | ||
| 39 | int irq; | ||
| 40 | }; | ||
| 41 | |||
| 42 | static irqreturn_t dm355evm_keys_irq(int irq, void *_keys) | ||
| 43 | { | ||
| 44 | struct dm355evm_keys *keys = _keys; | ||
| 45 | |||
| 46 | schedule_work(&keys->work); | ||
| 47 | return IRQ_HANDLED; | ||
| 48 | } | ||
| 49 | |||
| 50 | /* These initial keycodes can be remapped by dm355evm_setkeycode(). */ | ||
| 51 | static struct { | ||
| 52 | u16 event; | ||
| 53 | u16 keycode; | ||
| 54 | } dm355evm_keys[] = { | ||
| 55 | |||
| 56 | /* | ||
| 57 | * Pushbuttons on the EVM board ... note that the labels for these | ||
| 58 | * are SW10/SW11/etc on the PC board. The left/right orientation | ||
| 59 | * comes only from the firmware's documentation, and presumes the | ||
| 60 | * power connector is immediately in front of you and the IR sensor | ||
| 61 | * is to the right. (That is, rotate the board counter-clockwise | ||
| 62 | * by 90 degrees from the SW10/etc and "DM355 EVM" labels.) | ||
| 63 | */ | ||
| 64 | { 0x00d8, KEY_OK, }, /* SW12 */ | ||
| 65 | { 0x00b8, KEY_UP, }, /* SW13 */ | ||
| 66 | { 0x00e8, KEY_DOWN, }, /* SW11 */ | ||
| 67 | { 0x0078, KEY_LEFT, }, /* SW14 */ | ||
| 68 | { 0x00f0, KEY_RIGHT, }, /* SW10 */ | ||
| 69 | |||
| 70 | /* | ||
| 71 | * IR buttons ... codes assigned to match the universal remote | ||
| 72 | * provided with the EVM (Philips PM4S) using DVD code 0020. | ||
| 73 | * | ||
| 74 | * These event codes match firmware documentation, but other | ||
| 75 | * remote controls could easily send more RC5-encoded events. | ||
| 76 | * The PM4S manual was used in several cases to help select | ||
| 77 | * a keycode reflecting the intended usage. | ||
| 78 | * | ||
| 79 | * RC5 codes are 14 bits, with two start bits (0x3 prefix) | ||
| 80 | * and a toggle bit (masked out below). | ||
| 81 | */ | ||
| 82 | { 0x300c, KEY_POWER, }, /* NOTE: docs omit this */ | ||
| 83 | { 0x3000, KEY_NUMERIC_0, }, | ||
| 84 | { 0x3001, KEY_NUMERIC_1, }, | ||
| 85 | { 0x3002, KEY_NUMERIC_2, }, | ||
| 86 | { 0x3003, KEY_NUMERIC_3, }, | ||
| 87 | { 0x3004, KEY_NUMERIC_4, }, | ||
| 88 | { 0x3005, KEY_NUMERIC_5, }, | ||
| 89 | { 0x3006, KEY_NUMERIC_6, }, | ||
| 90 | { 0x3007, KEY_NUMERIC_7, }, | ||
| 91 | { 0x3008, KEY_NUMERIC_8, }, | ||
| 92 | { 0x3009, KEY_NUMERIC_9, }, | ||
| 93 | { 0x3022, KEY_ENTER, }, | ||
| 94 | { 0x30ec, KEY_MODE, }, /* "tv/vcr/..." */ | ||
| 95 | { 0x300f, KEY_SELECT, }, /* "info" */ | ||
| 96 | { 0x3020, KEY_CHANNELUP, }, /* "up" */ | ||
| 97 | { 0x302e, KEY_MENU, }, /* "in/out" */ | ||
| 98 | { 0x3011, KEY_VOLUMEDOWN, }, /* "left" */ | ||
| 99 | { 0x300d, KEY_MUTE, }, /* "ok" */ | ||
| 100 | { 0x3010, KEY_VOLUMEUP, }, /* "right" */ | ||
| 101 | { 0x301e, KEY_SUBTITLE, }, /* "cc" */ | ||
| 102 | { 0x3021, KEY_CHANNELDOWN, }, /* "down" */ | ||
| 103 | { 0x3022, KEY_PREVIOUS, }, | ||
| 104 | { 0x3026, KEY_SLEEP, }, | ||
| 105 | { 0x3172, KEY_REWIND, }, /* NOTE: docs wrongly say 0x30ca */ | ||
| 106 | { 0x3175, KEY_PLAY, }, | ||
| 107 | { 0x3174, KEY_FASTFORWARD, }, | ||
| 108 | { 0x3177, KEY_RECORD, }, | ||
| 109 | { 0x3176, KEY_STOP, }, | ||
| 110 | { 0x3169, KEY_PAUSE, }, | ||
| 111 | }; | ||
| 112 | |||
| 113 | static void dm355evm_keys_work(struct work_struct *work) | ||
| 114 | { | ||
| 115 | struct dm355evm_keys *keys; | ||
| 116 | int status; | ||
| 117 | |||
| 118 | keys = container_of(work, struct dm355evm_keys, work); | ||
| 119 | |||
| 120 | /* For simplicity we ignore INPUT_COUNT and just read | ||
| 121 | * events until we get the "queue empty" indicator. | ||
| 122 | * Reading INPUT_LOW decrements the count. | ||
| 123 | */ | ||
| 124 | for (;;) { | ||
| 125 | static u16 last_event; | ||
| 126 | u16 event; | ||
| 127 | int keycode; | ||
| 128 | int i; | ||
| 129 | |||
| 130 | status = dm355evm_msp_read(DM355EVM_MSP_INPUT_HIGH); | ||
| 131 | if (status < 0) { | ||
| 132 | dev_dbg(keys->dev, "input high err %d\n", | ||
| 133 | status); | ||
| 134 | break; | ||
| 135 | } | ||
| 136 | event = status << 8; | ||
| 137 | |||
| 138 | status = dm355evm_msp_read(DM355EVM_MSP_INPUT_LOW); | ||
| 139 | if (status < 0) { | ||
| 140 | dev_dbg(keys->dev, "input low err %d\n", | ||
| 141 | status); | ||
| 142 | break; | ||
| 143 | } | ||
| 144 | event |= status; | ||
| 145 | if (event == 0xdead) | ||
| 146 | break; | ||
| 147 | |||
| 148 | /* Press and release a button: two events, same code. | ||
| 149 | * Press and hold (autorepeat), then release: N events | ||
| 150 | * (N > 2), same code. For RC5 buttons the toggle bits | ||
| 151 | * distinguish (for example) "1-autorepeat" from "1 1"; | ||
| 152 | * but PCB buttons don't support that bit. | ||
| 153 | * | ||
| 154 | * So we must synthesize release events. We do that by | ||
| 155 | * mapping events to a press/release event pair; then | ||
| 156 | * to avoid adding extra events, skip the second event | ||
| 157 | * of each pair. | ||
| 158 | */ | ||
| 159 | if (event == last_event) { | ||
| 160 | last_event = 0; | ||
| 161 | continue; | ||
| 162 | } | ||
| 163 | last_event = event; | ||
| 164 | |||
| 165 | /* ignore the RC5 toggle bit */ | ||
| 166 | event &= ~0x0800; | ||
| 167 | |||
| 168 | /* find the key, or leave it as unknown */ | ||
| 169 | keycode = KEY_UNKNOWN; | ||
| 170 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) { | ||
| 171 | if (dm355evm_keys[i].event != event) | ||
| 172 | continue; | ||
| 173 | keycode = dm355evm_keys[i].keycode; | ||
| 174 | break; | ||
| 175 | } | ||
| 176 | dev_dbg(keys->dev, | ||
| 177 | "input event 0x%04x--> keycode %d\n", | ||
| 178 | event, keycode); | ||
| 179 | |||
| 180 | /* report press + release */ | ||
| 181 | input_report_key(keys->input, keycode, 1); | ||
| 182 | input_sync(keys->input); | ||
| 183 | input_report_key(keys->input, keycode, 0); | ||
| 184 | input_sync(keys->input); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | static int dm355evm_setkeycode(struct input_dev *dev, int index, int keycode) | ||
| 189 | { | ||
| 190 | u16 old_keycode; | ||
| 191 | unsigned i; | ||
| 192 | |||
| 193 | if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys)) | ||
| 194 | return -EINVAL; | ||
| 195 | |||
| 196 | old_keycode = dm355evm_keys[index].keycode; | ||
| 197 | dm355evm_keys[index].keycode = keycode; | ||
| 198 | set_bit(keycode, dev->keybit); | ||
| 199 | |||
| 200 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) { | ||
| 201 | if (dm355evm_keys[index].keycode == old_keycode) | ||
| 202 | goto done; | ||
| 203 | } | ||
| 204 | clear_bit(old_keycode, dev->keybit); | ||
| 205 | done: | ||
| 206 | return 0; | ||
| 207 | } | ||
| 208 | |||
| 209 | static int dm355evm_getkeycode(struct input_dev *dev, int index, int *keycode) | ||
| 210 | { | ||
| 211 | if (((unsigned)index) >= ARRAY_SIZE(dm355evm_keys)) | ||
| 212 | return -EINVAL; | ||
| 213 | |||
| 214 | return dm355evm_keys[index].keycode; | ||
| 215 | } | ||
| 216 | |||
| 217 | /*----------------------------------------------------------------------*/ | ||
| 218 | |||
| 219 | static int __devinit dm355evm_keys_probe(struct platform_device *pdev) | ||
| 220 | { | ||
| 221 | struct dm355evm_keys *keys; | ||
| 222 | struct input_dev *input; | ||
| 223 | int status; | ||
| 224 | int i; | ||
| 225 | |||
| 226 | /* allocate instance struct and input dev */ | ||
| 227 | keys = kzalloc(sizeof *keys, GFP_KERNEL); | ||
| 228 | input = input_allocate_device(); | ||
| 229 | if (!keys || !input) { | ||
| 230 | status = -ENOMEM; | ||
| 231 | goto fail1; | ||
| 232 | } | ||
| 233 | |||
| 234 | keys->dev = &pdev->dev; | ||
| 235 | keys->input = input; | ||
| 236 | INIT_WORK(&keys->work, dm355evm_keys_work); | ||
| 237 | |||
| 238 | /* set up "threaded IRQ handler" */ | ||
| 239 | status = platform_get_irq(pdev, 0); | ||
| 240 | if (status < 0) | ||
| 241 | goto fail1; | ||
| 242 | keys->irq = status; | ||
| 243 | |||
| 244 | input_set_drvdata(input, keys); | ||
| 245 | |||
| 246 | input->name = "DM355 EVM Controls"; | ||
| 247 | input->phys = "dm355evm/input0"; | ||
| 248 | input->dev.parent = &pdev->dev; | ||
| 249 | |||
| 250 | input->id.bustype = BUS_I2C; | ||
| 251 | input->id.product = 0x0355; | ||
| 252 | input->id.version = dm355evm_msp_read(DM355EVM_MSP_FIRMREV); | ||
| 253 | |||
| 254 | input->evbit[0] = BIT(EV_KEY); | ||
| 255 | for (i = 0; i < ARRAY_SIZE(dm355evm_keys); i++) | ||
| 256 | __set_bit(dm355evm_keys[i].keycode, input->keybit); | ||
| 257 | |||
| 258 | input->setkeycode = dm355evm_setkeycode; | ||
| 259 | input->getkeycode = dm355evm_getkeycode; | ||
| 260 | |||
| 261 | /* REVISIT: flush the event queue? */ | ||
| 262 | |||
| 263 | status = request_irq(keys->irq, dm355evm_keys_irq, | ||
| 264 | IRQF_TRIGGER_FALLING, | ||
| 265 | dev_name(&pdev->dev), keys); | ||
| 266 | if (status < 0) | ||
| 267 | goto fail1; | ||
| 268 | |||
| 269 | /* register */ | ||
| 270 | status = input_register_device(input); | ||
| 271 | if (status < 0) | ||
| 272 | goto fail2; | ||
| 273 | |||
| 274 | platform_set_drvdata(pdev, keys); | ||
| 275 | |||
| 276 | return 0; | ||
| 277 | |||
| 278 | fail2: | ||
| 279 | free_irq(keys->irq, keys); | ||
| 280 | fail1: | ||
| 281 | input_free_device(input); | ||
| 282 | kfree(keys); | ||
| 283 | dev_err(&pdev->dev, "can't register, err %d\n", status); | ||
| 284 | |||
| 285 | return status; | ||
| 286 | } | ||
| 287 | |||
| 288 | static int __devexit dm355evm_keys_remove(struct platform_device *pdev) | ||
| 289 | { | ||
| 290 | struct dm355evm_keys *keys = platform_get_drvdata(pdev); | ||
| 291 | |||
| 292 | free_irq(keys->irq, keys); | ||
| 293 | input_unregister_device(keys->input); | ||
| 294 | kfree(keys); | ||
| 295 | |||
| 296 | return 0; | ||
| 297 | } | ||
| 298 | |||
| 299 | /* REVISIT: add suspend/resume when DaVinci supports it. The IRQ should | ||
| 300 | * be able to wake up the system. When device_may_wakeup(&pdev->dev), call | ||
| 301 | * enable_irq_wake() on suspend, and disable_irq_wake() on resume. | ||
| 302 | */ | ||
| 303 | |||
| 304 | /* | ||
| 305 | * I2C is used to talk to the MSP430, but this platform device is | ||
| 306 | * exposed by an MFD driver that manages I2C communications. | ||
| 307 | */ | ||
| 308 | static struct platform_driver dm355evm_keys_driver = { | ||
| 309 | .probe = dm355evm_keys_probe, | ||
| 310 | .remove = __devexit_p(dm355evm_keys_remove), | ||
| 311 | .driver = { | ||
| 312 | .owner = THIS_MODULE, | ||
| 313 | .name = "dm355evm_keys", | ||
| 314 | }, | ||
| 315 | }; | ||
| 316 | |||
| 317 | static int __init dm355evm_keys_init(void) | ||
| 318 | { | ||
| 319 | return platform_driver_register(&dm355evm_keys_driver); | ||
| 320 | } | ||
| 321 | module_init(dm355evm_keys_init); | ||
| 322 | |||
| 323 | static void __exit dm355evm_keys_exit(void) | ||
| 324 | { | ||
| 325 | platform_driver_unregister(&dm355evm_keys_driver); | ||
| 326 | } | ||
| 327 | module_exit(dm355evm_keys_exit); | ||
| 328 | |||
| 329 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 5bb3ab51b8c6..c806fbf1e174 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
| @@ -26,13 +26,17 @@ | |||
| 26 | #define DRV_NAME "rotary-encoder" | 26 | #define DRV_NAME "rotary-encoder" |
| 27 | 27 | ||
| 28 | struct rotary_encoder { | 28 | struct rotary_encoder { |
| 29 | unsigned int irq_a; | ||
| 30 | unsigned int irq_b; | ||
| 31 | unsigned int pos; | ||
| 32 | unsigned int armed; | ||
| 33 | unsigned int dir; | ||
| 34 | struct input_dev *input; | 29 | struct input_dev *input; |
| 35 | struct rotary_encoder_platform_data *pdata; | 30 | struct rotary_encoder_platform_data *pdata; |
| 31 | |||
| 32 | unsigned int axis; | ||
| 33 | unsigned int pos; | ||
| 34 | |||
| 35 | unsigned int irq_a; | ||
| 36 | unsigned int irq_b; | ||
| 37 | |||
| 38 | bool armed; | ||
| 39 | unsigned char dir; /* 0 - clockwise, 1 - CCW */ | ||
| 36 | }; | 40 | }; |
| 37 | 41 | ||
| 38 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | 42 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) |
| @@ -53,21 +57,32 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | |||
| 53 | if (!encoder->armed) | 57 | if (!encoder->armed) |
| 54 | break; | 58 | break; |
| 55 | 59 | ||
| 56 | if (encoder->dir) { | 60 | if (pdata->relative_axis) { |
| 57 | /* turning counter-clockwise */ | 61 | input_report_rel(encoder->input, pdata->axis, |
| 58 | encoder->pos += pdata->steps; | 62 | encoder->dir ? -1 : 1); |
| 59 | encoder->pos--; | ||
| 60 | encoder->pos %= pdata->steps; | ||
| 61 | } else { | 63 | } else { |
| 62 | /* turning clockwise */ | 64 | unsigned int pos = encoder->pos; |
| 63 | encoder->pos++; | 65 | |
| 64 | encoder->pos %= pdata->steps; | 66 | if (encoder->dir) { |
| 67 | /* turning counter-clockwise */ | ||
| 68 | if (pdata->rollover) | ||
| 69 | pos += pdata->steps; | ||
| 70 | if (pos) | ||
| 71 | pos--; | ||
| 72 | } else { | ||
| 73 | /* turning clockwise */ | ||
| 74 | if (pdata->rollover || pos < pdata->steps) | ||
| 75 | pos++; | ||
| 76 | } | ||
| 77 | if (pdata->rollover) | ||
| 78 | pos %= pdata->steps; | ||
| 79 | encoder->pos = pos; | ||
| 80 | input_report_abs(encoder->input, pdata->axis, | ||
| 81 | encoder->pos); | ||
| 65 | } | 82 | } |
| 66 | |||
| 67 | input_report_abs(encoder->input, pdata->axis, encoder->pos); | ||
| 68 | input_sync(encoder->input); | 83 | input_sync(encoder->input); |
| 69 | 84 | ||
| 70 | encoder->armed = 0; | 85 | encoder->armed = false; |
| 71 | break; | 86 | break; |
| 72 | 87 | ||
| 73 | case 0x1: | 88 | case 0x1: |
| @@ -77,7 +92,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | |||
| 77 | break; | 92 | break; |
| 78 | 93 | ||
| 79 | case 0x3: | 94 | case 0x3: |
| 80 | encoder->armed = 1; | 95 | encoder->armed = true; |
| 81 | break; | 96 | break; |
| 82 | } | 97 | } |
| 83 | 98 | ||
| @@ -113,9 +128,15 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
| 113 | input->name = pdev->name; | 128 | input->name = pdev->name; |
| 114 | input->id.bustype = BUS_HOST; | 129 | input->id.bustype = BUS_HOST; |
| 115 | input->dev.parent = &pdev->dev; | 130 | input->dev.parent = &pdev->dev; |
| 116 | input->evbit[0] = BIT_MASK(EV_ABS); | 131 | |
| 117 | input_set_abs_params(encoder->input, | 132 | if (pdata->relative_axis) { |
| 118 | pdata->axis, 0, pdata->steps, 0, 1); | 133 | input->evbit[0] = BIT_MASK(EV_REL); |
| 134 | input->relbit[0] = BIT_MASK(pdata->axis); | ||
| 135 | } else { | ||
| 136 | input->evbit[0] = BIT_MASK(EV_ABS); | ||
| 137 | input_set_abs_params(encoder->input, | ||
| 138 | pdata->axis, 0, pdata->steps, 0, 1); | ||
| 139 | } | ||
| 119 | 140 | ||
| 120 | err = input_register_device(input); | 141 | err = input_register_device(input); |
| 121 | if (err) { | 142 | if (err) { |
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c new file mode 100644 index 000000000000..f5fc9974a111 --- /dev/null +++ b/drivers/input/misc/twl4030-pwrbutton.c | |||
| @@ -0,0 +1,145 @@ | |||
| 1 | /** | ||
| 2 | * twl4030-pwrbutton.c - TWL4030 Power Button Input Driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008-2009 Nokia Corporation | ||
| 5 | * | ||
| 6 | * Written by Peter De Schrijver <peter.de-schrijver@nokia.com> | ||
| 7 | * Several fixes by Felipe Balbi <felipe.balbi@nokia.com> | ||
| 8 | * | ||
| 9 | * This file is subject to the terms and conditions of the GNU General | ||
| 10 | * Public License. See the file "COPYING" in the main directory of this | ||
| 11 | * archive for more details. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, | ||
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 16 | * GNU General Public License for more details. | ||
| 17 | * | ||
| 18 | * You should have received a copy of the GNU General Public License | ||
| 19 | * along with this program; if not, write to the Free Software | ||
| 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/errno.h> | ||
| 27 | #include <linux/input.h> | ||
| 28 | #include <linux/interrupt.h> | ||
| 29 | #include <linux/platform_device.h> | ||
| 30 | #include <linux/i2c/twl4030.h> | ||
| 31 | |||
| 32 | #define PWR_PWRON_IRQ (1 << 0) | ||
| 33 | |||
| 34 | #define STS_HW_CONDITIONS 0xf | ||
| 35 | |||
| 36 | static irqreturn_t powerbutton_irq(int irq, void *_pwr) | ||
| 37 | { | ||
| 38 | struct input_dev *pwr = _pwr; | ||
| 39 | int err; | ||
| 40 | u8 value; | ||
| 41 | |||
| 42 | #ifdef CONFIG_LOCKDEP | ||
| 43 | /* WORKAROUND for lockdep forcing IRQF_DISABLED on us, which | ||
| 44 | * we don't want and can't tolerate since this is a threaded | ||
| 45 | * IRQ and can sleep due to the i2c reads it has to issue. | ||
| 46 | * Although it might be friendlier not to borrow this thread | ||
| 47 | * context... | ||
| 48 | */ | ||
| 49 | local_irq_enable(); | ||
| 50 | #endif | ||
| 51 | |||
| 52 | err = twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &value, | ||
| 53 | STS_HW_CONDITIONS); | ||
| 54 | if (!err) { | ||
| 55 | input_report_key(pwr, KEY_POWER, value & PWR_PWRON_IRQ); | ||
| 56 | input_sync(pwr); | ||
| 57 | } else { | ||
| 58 | dev_err(pwr->dev.parent, "twl4030: i2c error %d while reading" | ||
| 59 | " TWL4030 PM_MASTER STS_HW_CONDITIONS register\n", err); | ||
| 60 | } | ||
| 61 | |||
| 62 | return IRQ_HANDLED; | ||
| 63 | } | ||
| 64 | |||
| 65 | static int __devinit twl4030_pwrbutton_probe(struct platform_device *pdev) | ||
| 66 | { | ||
| 67 | struct input_dev *pwr; | ||
| 68 | int irq = platform_get_irq(pdev, 0); | ||
| 69 | int err; | ||
| 70 | |||
| 71 | pwr = input_allocate_device(); | ||
| 72 | if (!pwr) { | ||
| 73 | dev_dbg(&pdev->dev, "Can't allocate power button\n"); | ||
| 74 | return -ENOMEM; | ||
| 75 | } | ||
| 76 | |||
| 77 | pwr->evbit[0] = BIT_MASK(EV_KEY); | ||
| 78 | pwr->keybit[BIT_WORD(KEY_POWER)] = BIT_MASK(KEY_POWER); | ||
| 79 | pwr->name = "twl4030_pwrbutton"; | ||
| 80 | pwr->phys = "twl4030_pwrbutton/input0"; | ||
| 81 | pwr->dev.parent = &pdev->dev; | ||
| 82 | |||
| 83 | err = request_irq(irq, powerbutton_irq, | ||
| 84 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | ||
| 85 | "twl4030_pwrbutton", pwr); | ||
| 86 | if (err < 0) { | ||
| 87 | dev_dbg(&pdev->dev, "Can't get IRQ for pwrbutton: %d\n", err); | ||
| 88 | goto free_input_dev; | ||
| 89 | } | ||
| 90 | |||
| 91 | err = input_register_device(pwr); | ||
| 92 | if (err) { | ||
| 93 | dev_dbg(&pdev->dev, "Can't register power button: %d\n", err); | ||
| 94 | goto free_irq; | ||
| 95 | } | ||
| 96 | |||
| 97 | platform_set_drvdata(pdev, pwr); | ||
| 98 | |||
| 99 | return 0; | ||
| 100 | |||
| 101 | free_irq: | ||
| 102 | free_irq(irq, NULL); | ||
| 103 | free_input_dev: | ||
| 104 | input_free_device(pwr); | ||
| 105 | return err; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int __devexit twl4030_pwrbutton_remove(struct platform_device *pdev) | ||
| 109 | { | ||
| 110 | struct input_dev *pwr = platform_get_drvdata(pdev); | ||
| 111 | int irq = platform_get_irq(pdev, 0); | ||
| 112 | |||
| 113 | free_irq(irq, pwr); | ||
| 114 | input_unregister_device(pwr); | ||
| 115 | |||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 119 | struct platform_driver twl4030_pwrbutton_driver = { | ||
| 120 | .probe = twl4030_pwrbutton_probe, | ||
| 121 | .remove = __devexit_p(twl4030_pwrbutton_remove), | ||
| 122 | .driver = { | ||
| 123 | .name = "twl4030_pwrbutton", | ||
| 124 | .owner = THIS_MODULE, | ||
| 125 | }, | ||
| 126 | }; | ||
| 127 | |||
| 128 | static int __init twl4030_pwrbutton_init(void) | ||
| 129 | { | ||
| 130 | return platform_driver_register(&twl4030_pwrbutton_driver); | ||
| 131 | } | ||
| 132 | module_init(twl4030_pwrbutton_init); | ||
| 133 | |||
| 134 | static void __exit twl4030_pwrbutton_exit(void) | ||
| 135 | { | ||
| 136 | platform_driver_unregister(&twl4030_pwrbutton_driver); | ||
| 137 | } | ||
| 138 | module_exit(twl4030_pwrbutton_exit); | ||
| 139 | |||
| 140 | MODULE_ALIAS("platform:twl4030_pwrbutton"); | ||
| 141 | MODULE_DESCRIPTION("Triton2 Power Button"); | ||
| 142 | MODULE_LICENSE("GPL"); | ||
| 143 | MODULE_AUTHOR("Peter De Schrijver <peter.de-schrijver@nokia.com>"); | ||
| 144 | MODULE_AUTHOR("Felipe Balbi <felipe.balbi@nokia.com>"); | ||
| 145 | |||
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c index 46b7caeb2817..c5a49aba418f 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c | |||
| @@ -54,27 +54,28 @@ static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned i | |||
| 54 | return 0; | 54 | return 0; |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | /* Atomically allocate an ID for the given request. Returns 0 on success. */ | ||
| 57 | static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request) | 58 | static int uinput_request_alloc_id(struct uinput_device *udev, struct uinput_request *request) |
| 58 | { | 59 | { |
| 59 | /* Atomically allocate an ID for the given request. Returns 0 on success. */ | ||
| 60 | int id; | 60 | int id; |
| 61 | int err = -1; | 61 | int err = -1; |
| 62 | 62 | ||
| 63 | spin_lock(&udev->requests_lock); | 63 | spin_lock(&udev->requests_lock); |
| 64 | 64 | ||
| 65 | for (id = 0; id < UINPUT_NUM_REQUESTS; id++) | 65 | for (id = 0; id < UINPUT_NUM_REQUESTS; id++) { |
| 66 | if (!udev->requests[id]) { | 66 | if (!udev->requests[id]) { |
| 67 | request->id = id; | 67 | request->id = id; |
| 68 | udev->requests[id] = request; | 68 | udev->requests[id] = request; |
| 69 | err = 0; | 69 | err = 0; |
| 70 | break; | 70 | break; |
| 71 | } | 71 | } |
| 72 | } | ||
| 72 | 73 | ||
| 73 | spin_unlock(&udev->requests_lock); | 74 | spin_unlock(&udev->requests_lock); |
| 74 | return err; | 75 | return err; |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 77 | static struct uinput_request* uinput_request_find(struct uinput_device *udev, int id) | 78 | static struct uinput_request *uinput_request_find(struct uinput_device *udev, int id) |
| 78 | { | 79 | { |
| 79 | /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ | 80 | /* Find an input request, by ID. Returns NULL if the ID isn't valid. */ |
| 80 | if (id >= UINPUT_NUM_REQUESTS || id < 0) | 81 | if (id >= UINPUT_NUM_REQUESTS || id < 0) |
| @@ -99,14 +100,51 @@ static void uinput_request_done(struct uinput_device *udev, struct uinput_reques | |||
| 99 | complete(&request->done); | 100 | complete(&request->done); |
| 100 | } | 101 | } |
| 101 | 102 | ||
| 102 | static int uinput_request_submit(struct input_dev *dev, struct uinput_request *request) | 103 | static int uinput_request_submit(struct uinput_device *udev, struct uinput_request *request) |
| 103 | { | 104 | { |
| 105 | int retval; | ||
| 106 | |||
| 107 | retval = uinput_request_reserve_slot(udev, request); | ||
| 108 | if (retval) | ||
| 109 | return retval; | ||
| 110 | |||
| 111 | retval = mutex_lock_interruptible(&udev->mutex); | ||
| 112 | if (retval) | ||
| 113 | return retval; | ||
| 114 | |||
| 115 | if (udev->state != UIST_CREATED) { | ||
| 116 | retval = -ENODEV; | ||
| 117 | goto out; | ||
| 118 | } | ||
| 119 | |||
| 104 | /* Tell our userspace app about this new request by queueing an input event */ | 120 | /* Tell our userspace app about this new request by queueing an input event */ |
| 105 | uinput_dev_event(dev, EV_UINPUT, request->code, request->id); | 121 | uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); |
| 122 | |||
| 123 | out: | ||
| 124 | mutex_unlock(&udev->mutex); | ||
| 125 | return retval; | ||
| 126 | } | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Fail all ouitstanding requests so handlers don't wait for the userspace | ||
| 130 | * to finish processing them. | ||
| 131 | */ | ||
| 132 | static void uinput_flush_requests(struct uinput_device *udev) | ||
| 133 | { | ||
| 134 | struct uinput_request *request; | ||
| 135 | int i; | ||
| 136 | |||
| 137 | spin_lock(&udev->requests_lock); | ||
| 138 | |||
| 139 | for (i = 0; i < UINPUT_NUM_REQUESTS; i++) { | ||
| 140 | request = udev->requests[i]; | ||
| 141 | if (request) { | ||
| 142 | request->retval = -ENODEV; | ||
| 143 | uinput_request_done(udev, request); | ||
| 144 | } | ||
| 145 | } | ||
| 106 | 146 | ||
| 107 | /* Wait for the request to complete */ | 147 | spin_unlock(&udev->requests_lock); |
| 108 | wait_for_completion(&request->done); | ||
| 109 | return request->retval; | ||
| 110 | } | 148 | } |
| 111 | 149 | ||
| 112 | static void uinput_dev_set_gain(struct input_dev *dev, u16 gain) | 150 | static void uinput_dev_set_gain(struct input_dev *dev, u16 gain) |
| @@ -126,6 +164,7 @@ static int uinput_dev_playback(struct input_dev *dev, int effect_id, int value) | |||
| 126 | 164 | ||
| 127 | static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old) | 165 | static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old) |
| 128 | { | 166 | { |
| 167 | struct uinput_device *udev = input_get_drvdata(dev); | ||
| 129 | struct uinput_request request; | 168 | struct uinput_request request; |
| 130 | int retval; | 169 | int retval; |
| 131 | 170 | ||
| @@ -146,15 +185,18 @@ static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *eff | |||
| 146 | request.u.upload.effect = effect; | 185 | request.u.upload.effect = effect; |
| 147 | request.u.upload.old = old; | 186 | request.u.upload.old = old; |
| 148 | 187 | ||
| 149 | retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request); | 188 | retval = uinput_request_submit(udev, &request); |
| 150 | if (!retval) | 189 | if (!retval) { |
| 151 | retval = uinput_request_submit(dev, &request); | 190 | wait_for_completion(&request.done); |
| 191 | retval = request.retval; | ||
| 192 | } | ||
| 152 | 193 | ||
| 153 | return retval; | 194 | return retval; |
| 154 | } | 195 | } |
| 155 | 196 | ||
| 156 | static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) | 197 | static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) |
| 157 | { | 198 | { |
| 199 | struct uinput_device *udev = input_get_drvdata(dev); | ||
| 158 | struct uinput_request request; | 200 | struct uinput_request request; |
| 159 | int retval; | 201 | int retval; |
| 160 | 202 | ||
| @@ -166,9 +208,11 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) | |||
| 166 | request.code = UI_FF_ERASE; | 208 | request.code = UI_FF_ERASE; |
| 167 | request.u.effect_id = effect_id; | 209 | request.u.effect_id = effect_id; |
| 168 | 210 | ||
| 169 | retval = uinput_request_reserve_slot(input_get_drvdata(dev), &request); | 211 | retval = uinput_request_submit(udev, &request); |
| 170 | if (!retval) | 212 | if (!retval) { |
| 171 | retval = uinput_request_submit(dev, &request); | 213 | wait_for_completion(&request.done); |
| 214 | retval = request.retval; | ||
| 215 | } | ||
| 172 | 216 | ||
| 173 | return retval; | 217 | return retval; |
| 174 | } | 218 | } |
| @@ -176,20 +220,24 @@ static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id) | |||
| 176 | static void uinput_destroy_device(struct uinput_device *udev) | 220 | static void uinput_destroy_device(struct uinput_device *udev) |
| 177 | { | 221 | { |
| 178 | const char *name, *phys; | 222 | const char *name, *phys; |
| 223 | struct input_dev *dev = udev->dev; | ||
| 224 | enum uinput_state old_state = udev->state; | ||
| 179 | 225 | ||
| 180 | if (udev->dev) { | 226 | udev->state = UIST_NEW_DEVICE; |
| 181 | name = udev->dev->name; | 227 | |
| 182 | phys = udev->dev->phys; | 228 | if (dev) { |
| 183 | if (udev->state == UIST_CREATED) | 229 | name = dev->name; |
| 184 | input_unregister_device(udev->dev); | 230 | phys = dev->phys; |
| 185 | else | 231 | if (old_state == UIST_CREATED) { |
| 186 | input_free_device(udev->dev); | 232 | uinput_flush_requests(udev); |
| 233 | input_unregister_device(dev); | ||
| 234 | } else { | ||
| 235 | input_free_device(dev); | ||
| 236 | } | ||
| 187 | kfree(name); | 237 | kfree(name); |
| 188 | kfree(phys); | 238 | kfree(phys); |
| 189 | udev->dev = NULL; | 239 | udev->dev = NULL; |
| 190 | } | 240 | } |
| 191 | |||
| 192 | udev->state = UIST_NEW_DEVICE; | ||
| 193 | } | 241 | } |
| 194 | 242 | ||
| 195 | static int uinput_create_device(struct uinput_device *udev) | 243 | static int uinput_create_device(struct uinput_device *udev) |
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index c66cc3d08c2f..8a2c5b14c8d8 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
| @@ -303,4 +303,22 @@ config MOUSE_MAPLE | |||
| 303 | To compile this driver as a module choose M here: the module will be | 303 | To compile this driver as a module choose M here: the module will be |
| 304 | called maplemouse. | 304 | called maplemouse. |
| 305 | 305 | ||
| 306 | config MOUSE_SYNAPTICS_I2C | ||
| 307 | tristate "Synaptics I2C Touchpad support" | ||
| 308 | depends on I2C | ||
| 309 | help | ||
| 310 | This driver supports Synaptics I2C touchpad controller on eXeda | ||
| 311 | mobile device. | ||
| 312 | The device will not work the synaptics X11 driver because | ||
| 313 | (i) it reports only relative coordinates and has no capabilities | ||
| 314 | to report absolute coordinates | ||
| 315 | (ii) the eXeda device itself uses Xfbdev as X Server and it does | ||
| 316 | not allow using xf86-input-* drivers. | ||
| 317 | |||
| 318 | Say y here if you have eXeda device and want to use a Synaptics | ||
| 319 | I2C Touchpad. | ||
| 320 | |||
| 321 | To compile this driver as a module, choose M here: the | ||
| 322 | module will be called synaptics_i2c. | ||
| 323 | |||
| 306 | endif | 324 | endif |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 472189468d67..010f265ec152 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
| @@ -18,6 +18,7 @@ obj-$(CONFIG_MOUSE_PS2) += psmouse.o | |||
| 18 | obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o | 18 | obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o |
| 19 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o | 19 | obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o |
| 20 | obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o | 20 | obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o |
| 21 | obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o | ||
| 21 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o | 22 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o |
| 22 | 23 | ||
| 23 | psmouse-objs := psmouse-base.o synaptics.o | 24 | psmouse-objs := psmouse-base.o synaptics.o |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index daecc75c72e6..5547e2429fbe 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
| @@ -38,25 +38,25 @@ | |||
| 38 | 38 | ||
| 39 | static const struct alps_model_info alps_model_data[] = { | 39 | static const struct alps_model_info alps_model_data[] = { |
| 40 | { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ | 40 | { { 0x32, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ |
| 41 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ | 41 | { { 0x33, 0x02, 0x0a }, 0x88, 0xf8, ALPS_OLDPROTO }, /* UMAX-530T */ |
| 42 | { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, | 42 | { { 0x53, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
| 43 | { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, | 43 | { { 0x53, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, |
| 44 | { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */ | 44 | { { 0x60, 0x03, 0xc8 }, 0xf8, 0xf8, 0 }, /* HP ze1115 */ |
| 45 | { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, | 45 | { { 0x63, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
| 46 | { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, | 46 | { { 0x63, 0x02, 0x14 }, 0xf8, 0xf8, 0 }, |
| 47 | { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ | 47 | { { 0x63, 0x02, 0x28 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Fujitsu Siemens S6010 */ |
| 48 | { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ | 48 | { { 0x63, 0x02, 0x3c }, 0x8f, 0x8f, ALPS_WHEEL }, /* Toshiba Satellite S2400-103 */ |
| 49 | { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */ | 49 | { { 0x63, 0x02, 0x50 }, 0xef, 0xef, ALPS_FW_BK_1 }, /* NEC Versa L320 */ |
| 50 | { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, | 50 | { { 0x63, 0x02, 0x64 }, 0xf8, 0xf8, 0 }, |
| 51 | { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS }, /* Dell Latitude D800 */ | 51 | { { 0x63, 0x03, 0xc8 }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D800 */ |
| 52 | { { 0x73, 0x00, 0x0a }, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */ | 52 | { { 0x73, 0x00, 0x0a }, 0xf8, 0xf8, ALPS_DUALPOINT }, /* ThinkPad R61 8918-5QG */ |
| 53 | { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, | 53 | { { 0x73, 0x02, 0x0a }, 0xf8, 0xf8, 0 }, |
| 54 | { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */ | 54 | { { 0x73, 0x02, 0x14 }, 0xf8, 0xf8, ALPS_FW_BK_2 }, /* Ahtec Laptop */ |
| 55 | { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ | 55 | { { 0x20, 0x02, 0x0e }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */ |
| 56 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, | 56 | { { 0x22, 0x02, 0x0a }, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, |
| 57 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ | 57 | { { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */ |
| 58 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */ | 58 | { { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */ |
| 59 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */ | 59 | { { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 }, /* Dell Vostro 1400 */ |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | /* | 62 | /* |
| @@ -132,18 +132,23 @@ static void alps_process_packet(struct psmouse *psmouse) | |||
| 132 | ges = packet[2] & 1; | 132 | ges = packet[2] & 1; |
| 133 | fin = packet[2] & 2; | 133 | fin = packet[2] & 2; |
| 134 | 134 | ||
| 135 | input_report_key(dev, BTN_LEFT, left); | ||
| 136 | input_report_key(dev, BTN_RIGHT, right); | ||
| 137 | input_report_key(dev, BTN_MIDDLE, middle); | ||
| 138 | |||
| 139 | if ((priv->i->flags & ALPS_DUALPOINT) && z == 127) { | 135 | if ((priv->i->flags & ALPS_DUALPOINT) && z == 127) { |
| 140 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); | 136 | input_report_rel(dev2, REL_X, (x > 383 ? (x - 768) : x)); |
| 141 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); | 137 | input_report_rel(dev2, REL_Y, -(y > 255 ? (y - 512) : y)); |
| 138 | |||
| 139 | input_report_key(dev2, BTN_LEFT, left); | ||
| 140 | input_report_key(dev2, BTN_RIGHT, right); | ||
| 141 | input_report_key(dev2, BTN_MIDDLE, middle); | ||
| 142 | |||
| 142 | input_sync(dev); | 143 | input_sync(dev); |
| 143 | input_sync(dev2); | 144 | input_sync(dev2); |
| 144 | return; | 145 | return; |
| 145 | } | 146 | } |
| 146 | 147 | ||
| 148 | input_report_key(dev, BTN_LEFT, left); | ||
| 149 | input_report_key(dev, BTN_RIGHT, right); | ||
| 150 | input_report_key(dev, BTN_MIDDLE, middle); | ||
| 151 | |||
| 147 | /* Convert hardware tap to a reasonable Z value */ | 152 | /* Convert hardware tap to a reasonable Z value */ |
| 148 | if (ges && !fin) z = 40; | 153 | if (ges && !fin) z = 40; |
| 149 | 154 | ||
diff --git a/drivers/input/mouse/appletouch.c b/drivers/input/mouse/appletouch.c index e0140fdc02a5..908b5b44052f 100644 --- a/drivers/input/mouse/appletouch.c +++ b/drivers/input/mouse/appletouch.c | |||
| @@ -361,7 +361,7 @@ static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact, | |||
| 361 | (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) { | 361 | (!is_increasing && xy_sensors[i - 1] < xy_sensors[i])) { |
| 362 | (*fingers)++; | 362 | (*fingers)++; |
| 363 | is_increasing = 1; | 363 | is_increasing = 1; |
| 364 | } else if (i > 0 && xy_sensors[i - 1] >= xy_sensors[i]) { | 364 | } else if (i > 0 && (xy_sensors[i - 1] - xy_sensors[i] > threshold)) { |
| 365 | is_increasing = 0; | 365 | is_increasing = 0; |
| 366 | } | 366 | } |
| 367 | 367 | ||
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 15ac3205ac05..dcd4236af1e3 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
| @@ -159,21 +159,22 @@ static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | |||
| 159 | if (!dev2) | 159 | if (!dev2) |
| 160 | printk(KERN_WARNING "lifebook.c: got relative packet " | 160 | printk(KERN_WARNING "lifebook.c: got relative packet " |
| 161 | "but no relative device set up\n"); | 161 | "but no relative device set up\n"); |
| 162 | } else if (lifebook_use_6byte_proto) { | ||
| 163 | input_report_abs(dev1, ABS_X, | ||
| 164 | ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f)); | ||
| 165 | input_report_abs(dev1, ABS_Y, | ||
| 166 | 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f))); | ||
| 167 | } else { | 162 | } else { |
| 168 | input_report_abs(dev1, ABS_X, | 163 | if (lifebook_use_6byte_proto) { |
| 169 | (packet[1] | ((packet[0] & 0x30) << 4))); | 164 | input_report_abs(dev1, ABS_X, |
| 170 | input_report_abs(dev1, ABS_Y, | 165 | ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f)); |
| 171 | 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); | 166 | input_report_abs(dev1, ABS_Y, |
| 167 | 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f))); | ||
| 168 | } else { | ||
| 169 | input_report_abs(dev1, ABS_X, | ||
| 170 | (packet[1] | ((packet[0] & 0x30) << 4))); | ||
| 171 | input_report_abs(dev1, ABS_Y, | ||
| 172 | 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); | ||
| 173 | } | ||
| 174 | input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04); | ||
| 175 | input_sync(dev1); | ||
| 172 | } | 176 | } |
| 173 | 177 | ||
| 174 | input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04); | ||
| 175 | input_sync(dev1); | ||
| 176 | |||
| 177 | if (dev2) { | 178 | if (dev2) { |
| 178 | if (relative_packet) { | 179 | if (relative_packet) { |
| 179 | input_report_rel(dev2, REL_X, | 180 | input_report_rel(dev2, REL_X, |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index f8f86de694bb..b407b355dceb 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
| @@ -327,7 +327,9 @@ static irqreturn_t psmouse_interrupt(struct serio *serio, | |||
| 327 | goto out; | 327 | goto out; |
| 328 | } | 328 | } |
| 329 | 329 | ||
| 330 | if (psmouse->packet[1] == PSMOUSE_RET_ID) { | 330 | if (psmouse->packet[1] == PSMOUSE_RET_ID || |
| 331 | (psmouse->type == PSMOUSE_HGPK && | ||
| 332 | psmouse->packet[1] == PSMOUSE_RET_BAT)) { | ||
| 331 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); | 333 | __psmouse_set_state(psmouse, PSMOUSE_IGNORE); |
| 332 | serio_reconnect(serio); | 334 | serio_reconnect(serio); |
| 333 | goto out; | 335 | goto out; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f3e4f7b0240d..19984bf06cad 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
| @@ -180,6 +180,29 @@ static int synaptics_identify(struct psmouse *psmouse) | |||
| 180 | return -1; | 180 | return -1; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | /* | ||
| 184 | * Read touchpad resolution | ||
| 185 | * Resolution is left zero if touchpad does not support the query | ||
| 186 | */ | ||
| 187 | static int synaptics_resolution(struct psmouse *psmouse) | ||
| 188 | { | ||
| 189 | struct synaptics_data *priv = psmouse->private; | ||
| 190 | unsigned char res[3]; | ||
| 191 | |||
| 192 | if (SYN_ID_MAJOR(priv->identity) < 4) | ||
| 193 | return 0; | ||
| 194 | |||
| 195 | if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res)) | ||
| 196 | return 0; | ||
| 197 | |||
| 198 | if ((res[0] != 0) && (res[1] & 0x80) && (res[2] != 0)) { | ||
| 199 | priv->x_res = res[0]; /* x resolution in units/mm */ | ||
| 200 | priv->y_res = res[2]; /* y resolution in units/mm */ | ||
| 201 | } | ||
| 202 | |||
| 203 | return 0; | ||
| 204 | } | ||
| 205 | |||
| 183 | static int synaptics_query_hardware(struct psmouse *psmouse) | 206 | static int synaptics_query_hardware(struct psmouse *psmouse) |
| 184 | { | 207 | { |
| 185 | if (synaptics_identify(psmouse)) | 208 | if (synaptics_identify(psmouse)) |
| @@ -188,6 +211,8 @@ static int synaptics_query_hardware(struct psmouse *psmouse) | |||
| 188 | return -1; | 211 | return -1; |
| 189 | if (synaptics_capability(psmouse)) | 212 | if (synaptics_capability(psmouse)) |
| 190 | return -1; | 213 | return -1; |
| 214 | if (synaptics_resolution(psmouse)) | ||
| 215 | return -1; | ||
| 191 | 216 | ||
| 192 | return 0; | 217 | return 0; |
| 193 | } | 218 | } |
| @@ -563,6 +588,9 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
| 563 | clear_bit(EV_REL, dev->evbit); | 588 | clear_bit(EV_REL, dev->evbit); |
| 564 | clear_bit(REL_X, dev->relbit); | 589 | clear_bit(REL_X, dev->relbit); |
| 565 | clear_bit(REL_Y, dev->relbit); | 590 | clear_bit(REL_Y, dev->relbit); |
| 591 | |||
| 592 | dev->absres[ABS_X] = priv->x_res; | ||
| 593 | dev->absres[ABS_Y] = priv->y_res; | ||
| 566 | } | 594 | } |
| 567 | 595 | ||
| 568 | static void synaptics_disconnect(struct psmouse *psmouse) | 596 | static void synaptics_disconnect(struct psmouse *psmouse) |
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 02aa4cf7bc77..302382151752 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
| @@ -97,6 +97,8 @@ struct synaptics_data { | |||
| 97 | unsigned long int capabilities; /* Capabilities */ | 97 | unsigned long int capabilities; /* Capabilities */ |
| 98 | unsigned long int ext_cap; /* Extended Capabilities */ | 98 | unsigned long int ext_cap; /* Extended Capabilities */ |
| 99 | unsigned long int identity; /* Identification */ | 99 | unsigned long int identity; /* Identification */ |
| 100 | int x_res; /* X resolution in units/mm */ | ||
| 101 | int y_res; /* Y resolution in units/mm */ | ||
| 100 | 102 | ||
| 101 | unsigned char pkt_type; /* packet type - old, new, etc */ | 103 | unsigned char pkt_type; /* packet type - old, new, etc */ |
| 102 | unsigned char mode; /* current mode byte */ | 104 | unsigned char mode; /* current mode byte */ |
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c new file mode 100644 index 000000000000..eac9fdde7ee9 --- /dev/null +++ b/drivers/input/mouse/synaptics_i2c.c | |||
| @@ -0,0 +1,676 @@ | |||
| 1 | /* | ||
| 2 | * Synaptics touchpad with I2C interface | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Compulab, Ltd. | ||
| 5 | * Mike Rapoport <mike@compulab.co.il> | ||
| 6 | * Igor Grinberg <grinberg@compulab.co.il> | ||
| 7 | * | ||
| 8 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 9 | * License. See the file COPYING in the main directory of this archive for | ||
| 10 | * more details. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/i2c.h> | ||
| 15 | #include <linux/irq.h> | ||
| 16 | #include <linux/interrupt.h> | ||
| 17 | #include <linux/input.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/workqueue.h> | ||
| 20 | |||
| 21 | #define DRIVER_NAME "synaptics_i2c" | ||
| 22 | /* maximum product id is 15 characters */ | ||
| 23 | #define PRODUCT_ID_LENGTH 15 | ||
| 24 | #define REGISTER_LENGTH 8 | ||
| 25 | |||
| 26 | /* | ||
| 27 | * after soft reset, we should wait for 1 ms | ||
| 28 | * before the device becomes operational | ||
| 29 | */ | ||
| 30 | #define SOFT_RESET_DELAY_MS 3 | ||
| 31 | /* and after hard reset, we should wait for max 500ms */ | ||
| 32 | #define HARD_RESET_DELAY_MS 500 | ||
| 33 | |||
| 34 | /* Registers by SMBus address */ | ||
| 35 | #define PAGE_SEL_REG 0xff | ||
| 36 | #define DEVICE_STATUS_REG 0x09 | ||
| 37 | |||
| 38 | /* Registers by RMI address */ | ||
| 39 | #define DEV_CONTROL_REG 0x0000 | ||
| 40 | #define INTERRUPT_EN_REG 0x0001 | ||
| 41 | #define ERR_STAT_REG 0x0002 | ||
| 42 | #define INT_REQ_STAT_REG 0x0003 | ||
| 43 | #define DEV_COMMAND_REG 0x0004 | ||
| 44 | |||
| 45 | #define RMI_PROT_VER_REG 0x0200 | ||
| 46 | #define MANUFACT_ID_REG 0x0201 | ||
| 47 | #define PHYS_INT_VER_REG 0x0202 | ||
| 48 | #define PROD_PROPERTY_REG 0x0203 | ||
| 49 | #define INFO_QUERY_REG0 0x0204 | ||
| 50 | #define INFO_QUERY_REG1 (INFO_QUERY_REG0 + 1) | ||
| 51 | #define INFO_QUERY_REG2 (INFO_QUERY_REG0 + 2) | ||
| 52 | #define INFO_QUERY_REG3 (INFO_QUERY_REG0 + 3) | ||
| 53 | |||
| 54 | #define PRODUCT_ID_REG0 0x0210 | ||
| 55 | #define PRODUCT_ID_REG1 (PRODUCT_ID_REG0 + 1) | ||
| 56 | #define PRODUCT_ID_REG2 (PRODUCT_ID_REG0 + 2) | ||
| 57 | #define PRODUCT_ID_REG3 (PRODUCT_ID_REG0 + 3) | ||
| 58 | #define PRODUCT_ID_REG4 (PRODUCT_ID_REG0 + 4) | ||
| 59 | #define PRODUCT_ID_REG5 (PRODUCT_ID_REG0 + 5) | ||
| 60 | #define PRODUCT_ID_REG6 (PRODUCT_ID_REG0 + 6) | ||
| 61 | #define PRODUCT_ID_REG7 (PRODUCT_ID_REG0 + 7) | ||
| 62 | #define PRODUCT_ID_REG8 (PRODUCT_ID_REG0 + 8) | ||
| 63 | #define PRODUCT_ID_REG9 (PRODUCT_ID_REG0 + 9) | ||
| 64 | #define PRODUCT_ID_REG10 (PRODUCT_ID_REG0 + 10) | ||
| 65 | #define PRODUCT_ID_REG11 (PRODUCT_ID_REG0 + 11) | ||
| 66 | #define PRODUCT_ID_REG12 (PRODUCT_ID_REG0 + 12) | ||
| 67 | #define PRODUCT_ID_REG13 (PRODUCT_ID_REG0 + 13) | ||
| 68 | #define PRODUCT_ID_REG14 (PRODUCT_ID_REG0 + 14) | ||
| 69 | #define PRODUCT_ID_REG15 (PRODUCT_ID_REG0 + 15) | ||
| 70 | |||
| 71 | #define DATA_REG0 0x0400 | ||
| 72 | #define ABS_PRESSURE_REG 0x0401 | ||
| 73 | #define ABS_MSB_X_REG 0x0402 | ||
| 74 | #define ABS_LSB_X_REG (ABS_MSB_X_REG + 1) | ||
| 75 | #define ABS_MSB_Y_REG 0x0404 | ||
| 76 | #define ABS_LSB_Y_REG (ABS_MSB_Y_REG + 1) | ||
| 77 | #define REL_X_REG 0x0406 | ||
| 78 | #define REL_Y_REG 0x0407 | ||
| 79 | |||
| 80 | #define DEV_QUERY_REG0 0x1000 | ||
| 81 | #define DEV_QUERY_REG1 (DEV_QUERY_REG0 + 1) | ||
| 82 | #define DEV_QUERY_REG2 (DEV_QUERY_REG0 + 2) | ||
| 83 | #define DEV_QUERY_REG3 (DEV_QUERY_REG0 + 3) | ||
| 84 | #define DEV_QUERY_REG4 (DEV_QUERY_REG0 + 4) | ||
| 85 | #define DEV_QUERY_REG5 (DEV_QUERY_REG0 + 5) | ||
| 86 | #define DEV_QUERY_REG6 (DEV_QUERY_REG0 + 6) | ||
| 87 | #define DEV_QUERY_REG7 (DEV_QUERY_REG0 + 7) | ||
| 88 | #define DEV_QUERY_REG8 (DEV_QUERY_REG0 + 8) | ||
| 89 | |||
| 90 | #define GENERAL_2D_CONTROL_REG 0x1041 | ||
| 91 | #define SENSOR_SENSITIVITY_REG 0x1044 | ||
| 92 | #define SENS_MAX_POS_MSB_REG 0x1046 | ||
| 93 | #define SENS_MAX_POS_LSB_REG (SENS_MAX_POS_UPPER_REG + 1) | ||
| 94 | |||
| 95 | /* Register bits */ | ||
| 96 | /* Device Control Register Bits */ | ||
| 97 | #define REPORT_RATE_1ST_BIT 6 | ||
| 98 | |||
| 99 | /* Interrupt Enable Register Bits (INTERRUPT_EN_REG) */ | ||
| 100 | #define F10_ABS_INT_ENA 0 | ||
| 101 | #define F10_REL_INT_ENA 1 | ||
| 102 | #define F20_INT_ENA 2 | ||
| 103 | |||
| 104 | /* Interrupt Request Register Bits (INT_REQ_STAT_REG | DEVICE_STATUS_REG) */ | ||
| 105 | #define F10_ABS_INT_REQ 0 | ||
| 106 | #define F10_REL_INT_REQ 1 | ||
| 107 | #define F20_INT_REQ 2 | ||
| 108 | /* Device Status Register Bits (DEVICE_STATUS_REG) */ | ||
| 109 | #define STAT_CONFIGURED 6 | ||
| 110 | #define STAT_ERROR 7 | ||
| 111 | |||
| 112 | /* Device Command Register Bits (DEV_COMMAND_REG) */ | ||
| 113 | #define RESET_COMMAND 0x01 | ||
| 114 | #define REZERO_COMMAND 0x02 | ||
| 115 | |||
| 116 | /* Data Register 0 Bits (DATA_REG0) */ | ||
| 117 | #define GESTURE 3 | ||
| 118 | |||
| 119 | /* Device Query Registers Bits */ | ||
| 120 | /* DEV_QUERY_REG3 */ | ||
| 121 | #define HAS_PALM_DETECT 1 | ||
| 122 | #define HAS_MULTI_FING 2 | ||
| 123 | #define HAS_SCROLLER 4 | ||
| 124 | #define HAS_2D_SCROLL 5 | ||
| 125 | |||
| 126 | /* General 2D Control Register Bits (GENERAL_2D_CONTROL_REG) */ | ||
| 127 | #define NO_DECELERATION 1 | ||
| 128 | #define REDUCE_REPORTING 3 | ||
| 129 | #define NO_FILTER 5 | ||
| 130 | |||
| 131 | /* Function Masks */ | ||
| 132 | /* Device Control Register Masks (DEV_CONTROL_REG) */ | ||
| 133 | #define REPORT_RATE_MSK 0xc0 | ||
| 134 | #define SLEEP_MODE_MSK 0x07 | ||
| 135 | |||
| 136 | /* Device Sleep Modes */ | ||
| 137 | #define FULL_AWAKE 0x0 | ||
| 138 | #define NORMAL_OP 0x1 | ||
| 139 | #define LOW_PWR_OP 0x2 | ||
| 140 | #define VERY_LOW_PWR_OP 0x3 | ||
| 141 | #define SENS_SLEEP 0x4 | ||
| 142 | #define SLEEP_MOD 0x5 | ||
| 143 | #define DEEP_SLEEP 0x6 | ||
| 144 | #define HIBERNATE 0x7 | ||
| 145 | |||
| 146 | /* Interrupt Register Mask */ | ||
| 147 | /* (INT_REQ_STAT_REG | DEVICE_STATUS_REG | INTERRUPT_EN_REG) */ | ||
| 148 | #define INT_ENA_REQ_MSK 0x07 | ||
| 149 | #define INT_ENA_ABS_MSK 0x01 | ||
| 150 | #define INT_ENA_REL_MSK 0x02 | ||
| 151 | #define INT_ENA_F20_MSK 0x04 | ||
| 152 | |||
| 153 | /* Device Status Register Masks (DEVICE_STATUS_REG) */ | ||
| 154 | #define CONFIGURED_MSK 0x40 | ||
| 155 | #define ERROR_MSK 0x80 | ||
| 156 | |||
| 157 | /* Data Register 0 Masks */ | ||
| 158 | #define FINGER_WIDTH_MSK 0xf0 | ||
| 159 | #define GESTURE_MSK 0x08 | ||
| 160 | #define SENSOR_STATUS_MSK 0x07 | ||
| 161 | |||
| 162 | /* | ||
| 163 | * MSB Position Register Masks | ||
| 164 | * ABS_MSB_X_REG | ABS_MSB_Y_REG | SENS_MAX_POS_MSB_REG | | ||
| 165 | * DEV_QUERY_REG3 | DEV_QUERY_REG5 | ||
| 166 | */ | ||
| 167 | #define MSB_POSITION_MSK 0x1f | ||
| 168 | |||
| 169 | /* Device Query Registers Masks */ | ||
| 170 | |||
| 171 | /* DEV_QUERY_REG2 */ | ||
| 172 | #define NUM_EXTRA_POS_MSK 0x07 | ||
| 173 | |||
| 174 | /* When in IRQ mode read the device every THREAD_IRQ_SLEEP_SECS */ | ||
| 175 | #define THREAD_IRQ_SLEEP_SECS 2 | ||
| 176 | #define THREAD_IRQ_SLEEP_MSECS (THREAD_IRQ_SLEEP_SECS * MSEC_PER_SEC) | ||
| 177 | |||
| 178 | /* | ||
| 179 | * When in Polling mode and no data received for NO_DATA_THRES msecs | ||
| 180 | * reduce the polling rate to NO_DATA_SLEEP_MSECS | ||
| 181 | */ | ||
| 182 | #define NO_DATA_THRES (MSEC_PER_SEC) | ||
| 183 | #define NO_DATA_SLEEP_MSECS (MSEC_PER_SEC / 4) | ||
| 184 | |||
| 185 | /* Control touchpad's No Deceleration option */ | ||
| 186 | static int no_decel = 1; | ||
| 187 | module_param(no_decel, bool, 0644); | ||
| 188 | MODULE_PARM_DESC(no_decel, "No Deceleration. Default = 1 (on)"); | ||
| 189 | |||
| 190 | /* Control touchpad's Reduced Reporting option */ | ||
| 191 | static int reduce_report; | ||
| 192 | module_param(reduce_report, bool, 0644); | ||
| 193 | MODULE_PARM_DESC(reduce_report, "Reduced Reporting. Default = 0 (off)"); | ||
| 194 | |||
| 195 | /* Control touchpad's No Filter option */ | ||
| 196 | static int no_filter; | ||
| 197 | module_param(no_filter, bool, 0644); | ||
| 198 | MODULE_PARM_DESC(no_filter, "No Filter. Default = 0 (off)"); | ||
| 199 | |||
| 200 | /* | ||
| 201 | * touchpad Attention line is Active Low and Open Drain, | ||
| 202 | * therefore should be connected to pulled up line | ||
| 203 | * and the irq configuration should be set to Falling Edge Trigger | ||
| 204 | */ | ||
| 205 | /* Control IRQ / Polling option */ | ||
| 206 | static int polling_req; | ||
| 207 | module_param(polling_req, bool, 0444); | ||
| 208 | MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)"); | ||
| 209 | |||
| 210 | /* Control Polling Rate */ | ||
| 211 | static int scan_rate = 80; | ||
| 212 | module_param(scan_rate, int, 0644); | ||
| 213 | MODULE_PARM_DESC(scan_rate, "Polling rate in times/sec. Default = 80"); | ||
| 214 | |||
| 215 | /* The main device structure */ | ||
| 216 | struct synaptics_i2c { | ||
| 217 | struct i2c_client *client; | ||
| 218 | struct input_dev *input; | ||
| 219 | struct delayed_work dwork; | ||
| 220 | int no_data_count; | ||
| 221 | int no_decel_param; | ||
| 222 | int reduce_report_param; | ||
| 223 | int no_filter_param; | ||
| 224 | int scan_rate_param; | ||
| 225 | int scan_ms; | ||
| 226 | }; | ||
| 227 | |||
| 228 | static inline void set_scan_rate(struct synaptics_i2c *touch, int scan_rate) | ||
| 229 | { | ||
| 230 | touch->scan_ms = MSEC_PER_SEC / scan_rate; | ||
| 231 | touch->scan_rate_param = scan_rate; | ||
| 232 | } | ||
| 233 | |||
| 234 | /* | ||
| 235 | * Driver's initial design makes no race condition possible on i2c bus, | ||
| 236 | * so there is no need in any locking. | ||
| 237 | * Keep it in mind, while playing with the code. | ||
| 238 | */ | ||
| 239 | static s32 synaptics_i2c_reg_get(struct i2c_client *client, u16 reg) | ||
| 240 | { | ||
| 241 | int ret; | ||
| 242 | |||
| 243 | ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); | ||
| 244 | if (ret == 0) | ||
| 245 | ret = i2c_smbus_read_byte_data(client, reg & 0xff); | ||
| 246 | |||
| 247 | return ret; | ||
| 248 | } | ||
| 249 | |||
| 250 | static s32 synaptics_i2c_reg_set(struct i2c_client *client, u16 reg, u8 val) | ||
| 251 | { | ||
| 252 | int ret; | ||
| 253 | |||
| 254 | ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); | ||
| 255 | if (ret == 0) | ||
| 256 | ret = i2c_smbus_write_byte_data(client, reg & 0xff, val); | ||
| 257 | |||
| 258 | return ret; | ||
| 259 | } | ||
| 260 | |||
| 261 | static s32 synaptics_i2c_word_get(struct i2c_client *client, u16 reg) | ||
| 262 | { | ||
| 263 | int ret; | ||
| 264 | |||
| 265 | ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8); | ||
| 266 | if (ret == 0) | ||
| 267 | ret = i2c_smbus_read_word_data(client, reg & 0xff); | ||
| 268 | |||
| 269 | return ret; | ||
| 270 | } | ||
| 271 | |||
| 272 | static int synaptics_i2c_config(struct i2c_client *client) | ||
| 273 | { | ||
| 274 | int ret, control; | ||
| 275 | u8 int_en; | ||
| 276 | |||
| 277 | /* set Report Rate to Device Highest (>=80) and Sleep to normal */ | ||
| 278 | ret = synaptics_i2c_reg_set(client, DEV_CONTROL_REG, 0xc1); | ||
| 279 | if (ret) | ||
| 280 | return ret; | ||
| 281 | |||
| 282 | /* set Interrupt Disable to Func20 / Enable to Func10) */ | ||
| 283 | int_en = (polling_req) ? 0 : INT_ENA_ABS_MSK | INT_ENA_REL_MSK; | ||
| 284 | ret = synaptics_i2c_reg_set(client, INTERRUPT_EN_REG, int_en); | ||
| 285 | if (ret) | ||
| 286 | return ret; | ||
| 287 | |||
| 288 | control = synaptics_i2c_reg_get(client, GENERAL_2D_CONTROL_REG); | ||
| 289 | /* No Deceleration */ | ||
| 290 | control |= no_decel ? 1 << NO_DECELERATION : 0; | ||
| 291 | /* Reduced Reporting */ | ||
| 292 | control |= reduce_report ? 1 << REDUCE_REPORTING : 0; | ||
| 293 | /* No Filter */ | ||
| 294 | control |= no_filter ? 1 << NO_FILTER : 0; | ||
| 295 | ret = synaptics_i2c_reg_set(client, GENERAL_2D_CONTROL_REG, control); | ||
| 296 | if (ret) | ||
| 297 | return ret; | ||
| 298 | |||
| 299 | return 0; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int synaptics_i2c_reset_config(struct i2c_client *client) | ||
| 303 | { | ||
| 304 | int ret; | ||
| 305 | |||
| 306 | /* Reset the Touchpad */ | ||
| 307 | ret = synaptics_i2c_reg_set(client, DEV_COMMAND_REG, RESET_COMMAND); | ||
| 308 | if (ret) { | ||
| 309 | dev_err(&client->dev, "Unable to reset device\n"); | ||
| 310 | } else { | ||
| 311 | msleep(SOFT_RESET_DELAY_MS); | ||
| 312 | ret = synaptics_i2c_config(client); | ||
| 313 | if (ret) | ||
| 314 | dev_err(&client->dev, "Unable to config device\n"); | ||
| 315 | } | ||
| 316 | |||
| 317 | return ret; | ||
| 318 | } | ||
| 319 | |||
| 320 | static int synaptics_i2c_check_error(struct i2c_client *client) | ||
| 321 | { | ||
| 322 | int status, ret = 0; | ||
| 323 | |||
| 324 | status = i2c_smbus_read_byte_data(client, DEVICE_STATUS_REG) & | ||
| 325 | (CONFIGURED_MSK | ERROR_MSK); | ||
| 326 | |||
| 327 | if (status != CONFIGURED_MSK) | ||
| 328 | ret = synaptics_i2c_reset_config(client); | ||
| 329 | |||
| 330 | return ret; | ||
| 331 | } | ||
| 332 | |||
| 333 | static bool synaptics_i2c_get_input(struct synaptics_i2c *touch) | ||
| 334 | { | ||
| 335 | struct input_dev *input = touch->input; | ||
| 336 | int xy_delta, gesture; | ||
| 337 | s32 data; | ||
| 338 | s8 x_delta, y_delta; | ||
| 339 | |||
| 340 | /* Deal with spontanious resets and errors */ | ||
| 341 | if (synaptics_i2c_check_error(touch->client)) | ||
| 342 | return 0; | ||
| 343 | |||
| 344 | /* Get Gesture Bit */ | ||
| 345 | data = synaptics_i2c_reg_get(touch->client, DATA_REG0); | ||
| 346 | gesture = (data >> GESTURE) & 0x1; | ||
| 347 | |||
| 348 | /* | ||
| 349 | * Get Relative axes. we have to get them in one shot, | ||
| 350 | * so we get 2 bytes starting from REL_X_REG. | ||
| 351 | */ | ||
| 352 | xy_delta = synaptics_i2c_word_get(touch->client, REL_X_REG) & 0xffff; | ||
| 353 | |||
| 354 | /* Separate X from Y */ | ||
| 355 | x_delta = xy_delta & 0xff; | ||
| 356 | y_delta = (xy_delta >> REGISTER_LENGTH) & 0xff; | ||
| 357 | |||
| 358 | /* Report the button event */ | ||
| 359 | input_report_key(input, BTN_LEFT, gesture); | ||
| 360 | |||
| 361 | /* Report the deltas */ | ||
| 362 | input_report_rel(input, REL_X, x_delta); | ||
| 363 | input_report_rel(input, REL_Y, -y_delta); | ||
| 364 | input_sync(input); | ||
| 365 | |||
| 366 | return xy_delta || gesture; | ||
| 367 | } | ||
| 368 | |||
| 369 | static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id) | ||
| 370 | { | ||
| 371 | struct synaptics_i2c *touch = dev_id; | ||
| 372 | |||
| 373 | /* | ||
| 374 | * We want to have the work run immediately but it might have | ||
| 375 | * already been scheduled with a delay, that's why we have to | ||
| 376 | * cancel it first. | ||
| 377 | */ | ||
| 378 | cancel_delayed_work(&touch->dwork); | ||
| 379 | schedule_delayed_work(&touch->dwork, 0); | ||
| 380 | |||
| 381 | return IRQ_HANDLED; | ||
| 382 | } | ||
| 383 | |||
| 384 | static void synaptics_i2c_check_params(struct synaptics_i2c *touch) | ||
| 385 | { | ||
| 386 | bool reset = false; | ||
| 387 | |||
| 388 | if (scan_rate != touch->scan_rate_param) | ||
| 389 | set_scan_rate(touch, scan_rate); | ||
| 390 | |||
| 391 | if (no_decel != touch->no_decel_param) { | ||
| 392 | touch->no_decel_param = no_decel; | ||
| 393 | reset = true; | ||
| 394 | } | ||
| 395 | |||
| 396 | if (no_filter != touch->no_filter_param) { | ||
| 397 | touch->no_filter_param = no_filter; | ||
| 398 | reset = true; | ||
| 399 | } | ||
| 400 | |||
| 401 | if (reduce_report != touch->reduce_report_param) { | ||
| 402 | touch->reduce_report_param = reduce_report; | ||
| 403 | reset = true; | ||
| 404 | } | ||
| 405 | |||
| 406 | if (reset) | ||
| 407 | synaptics_i2c_reset_config(touch->client); | ||
| 408 | } | ||
| 409 | |||
| 410 | /* Control the Device polling rate / Work Handler sleep time */ | ||
| 411 | unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch, | ||
| 412 | bool have_data) | ||
| 413 | { | ||
| 414 | unsigned long delay, nodata_count_thres; | ||
| 415 | |||
| 416 | if (polling_req) { | ||
| 417 | delay = touch->scan_ms; | ||
| 418 | if (have_data) { | ||
| 419 | touch->no_data_count = 0; | ||
| 420 | } else { | ||
| 421 | nodata_count_thres = NO_DATA_THRES / touch->scan_ms; | ||
| 422 | if (touch->no_data_count < nodata_count_thres) | ||
| 423 | touch->no_data_count++; | ||
| 424 | else | ||
| 425 | delay = NO_DATA_SLEEP_MSECS; | ||
| 426 | } | ||
| 427 | return msecs_to_jiffies(delay); | ||
| 428 | } else { | ||
| 429 | delay = msecs_to_jiffies(THREAD_IRQ_SLEEP_MSECS); | ||
| 430 | return round_jiffies_relative(delay); | ||
| 431 | } | ||
| 432 | } | ||
| 433 | |||
| 434 | /* Work Handler */ | ||
| 435 | static void synaptics_i2c_work_handler(struct work_struct *work) | ||
| 436 | { | ||
| 437 | bool have_data; | ||
| 438 | struct synaptics_i2c *touch = | ||
| 439 | container_of(work, struct synaptics_i2c, dwork.work); | ||
| 440 | unsigned long delay; | ||
| 441 | |||
| 442 | synaptics_i2c_check_params(touch); | ||
| 443 | |||
| 444 | have_data = synaptics_i2c_get_input(touch); | ||
| 445 | delay = synaptics_i2c_adjust_delay(touch, have_data); | ||
| 446 | |||
| 447 | /* | ||
| 448 | * While interrupt driven, there is no real need to poll the device. | ||
| 449 | * But touchpads are very sensitive, so there could be errors | ||
| 450 | * related to physical environment and the attention line isn't | ||
| 451 | * neccesarily asserted. In such case we can lose the touchpad. | ||
| 452 | * We poll the device once in THREAD_IRQ_SLEEP_SECS and | ||
| 453 | * if error is detected, we try to reset and reconfigure the touchpad. | ||
| 454 | */ | ||
| 455 | schedule_delayed_work(&touch->dwork, delay); | ||
| 456 | } | ||
| 457 | |||
| 458 | static int synaptics_i2c_open(struct input_dev *input) | ||
| 459 | { | ||
| 460 | struct synaptics_i2c *touch = input_get_drvdata(input); | ||
| 461 | int ret; | ||
| 462 | |||
| 463 | ret = synaptics_i2c_reset_config(touch->client); | ||
| 464 | if (ret) | ||
| 465 | return ret; | ||
| 466 | |||
| 467 | if (polling_req) | ||
| 468 | schedule_delayed_work(&touch->dwork, | ||
| 469 | msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); | ||
| 470 | |||
| 471 | return 0; | ||
| 472 | } | ||
| 473 | |||
| 474 | static void synaptics_i2c_close(struct input_dev *input) | ||
| 475 | { | ||
| 476 | struct synaptics_i2c *touch = input_get_drvdata(input); | ||
| 477 | |||
| 478 | if (!polling_req) | ||
| 479 | synaptics_i2c_reg_set(touch->client, INTERRUPT_EN_REG, 0); | ||
| 480 | |||
| 481 | cancel_delayed_work_sync(&touch->dwork); | ||
| 482 | |||
| 483 | /* Save some power */ | ||
| 484 | synaptics_i2c_reg_set(touch->client, DEV_CONTROL_REG, DEEP_SLEEP); | ||
| 485 | } | ||
| 486 | |||
| 487 | static void synaptics_i2c_set_input_params(struct synaptics_i2c *touch) | ||
| 488 | { | ||
| 489 | struct input_dev *input = touch->input; | ||
| 490 | |||
| 491 | input->name = touch->client->name; | ||
| 492 | input->phys = touch->client->adapter->name; | ||
| 493 | input->id.bustype = BUS_I2C; | ||
| 494 | input->id.version = synaptics_i2c_word_get(touch->client, | ||
| 495 | INFO_QUERY_REG0); | ||
| 496 | input->dev.parent = &touch->client->dev; | ||
| 497 | input->open = synaptics_i2c_open; | ||
| 498 | input->close = synaptics_i2c_close; | ||
| 499 | input_set_drvdata(input, touch); | ||
| 500 | |||
| 501 | /* Register the device as mouse */ | ||
| 502 | __set_bit(EV_REL, input->evbit); | ||
| 503 | __set_bit(REL_X, input->relbit); | ||
| 504 | __set_bit(REL_Y, input->relbit); | ||
| 505 | |||
| 506 | /* Register device's buttons and keys */ | ||
| 507 | __set_bit(EV_KEY, input->evbit); | ||
| 508 | __set_bit(BTN_LEFT, input->keybit); | ||
| 509 | } | ||
| 510 | |||
| 511 | struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client) | ||
| 512 | { | ||
| 513 | struct synaptics_i2c *touch; | ||
| 514 | |||
| 515 | touch = kzalloc(sizeof(struct synaptics_i2c), GFP_KERNEL); | ||
| 516 | if (!touch) | ||
| 517 | return NULL; | ||
| 518 | |||
| 519 | touch->client = client; | ||
| 520 | touch->no_decel_param = no_decel; | ||
| 521 | touch->scan_rate_param = scan_rate; | ||
| 522 | set_scan_rate(touch, scan_rate); | ||
| 523 | INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler); | ||
| 524 | |||
| 525 | return touch; | ||
| 526 | } | ||
| 527 | |||
| 528 | static int __devinit synaptics_i2c_probe(struct i2c_client *client, | ||
| 529 | const struct i2c_device_id *dev_id) | ||
| 530 | { | ||
| 531 | int ret; | ||
| 532 | struct synaptics_i2c *touch; | ||
| 533 | |||
| 534 | touch = synaptics_i2c_touch_create(client); | ||
| 535 | if (!touch) | ||
| 536 | return -ENOMEM; | ||
| 537 | |||
| 538 | i2c_set_clientdata(client, touch); | ||
| 539 | |||
| 540 | ret = synaptics_i2c_reset_config(client); | ||
| 541 | if (ret) | ||
| 542 | goto err_mem_free; | ||
| 543 | |||
| 544 | if (client->irq < 1) | ||
| 545 | polling_req = 1; | ||
| 546 | |||
| 547 | touch->input = input_allocate_device(); | ||
| 548 | if (!touch->input) { | ||
| 549 | ret = -ENOMEM; | ||
| 550 | goto err_mem_free; | ||
| 551 | } | ||
| 552 | |||
| 553 | synaptics_i2c_set_input_params(touch); | ||
| 554 | |||
| 555 | if (!polling_req) { | ||
| 556 | dev_dbg(&touch->client->dev, | ||
| 557 | "Requesting IRQ: %d\n", touch->client->irq); | ||
| 558 | |||
| 559 | ret = request_irq(touch->client->irq, synaptics_i2c_irq, | ||
| 560 | IRQF_DISABLED|IRQ_TYPE_EDGE_FALLING, | ||
| 561 | DRIVER_NAME, touch); | ||
| 562 | if (ret) { | ||
| 563 | dev_warn(&touch->client->dev, | ||
| 564 | "IRQ request failed: %d, " | ||
| 565 | "falling back to polling\n", ret); | ||
| 566 | polling_req = 1; | ||
| 567 | synaptics_i2c_reg_set(touch->client, | ||
| 568 | INTERRUPT_EN_REG, 0); | ||
| 569 | } | ||
| 570 | } | ||
| 571 | |||
| 572 | if (polling_req) | ||
| 573 | dev_dbg(&touch->client->dev, | ||
| 574 | "Using polling at rate: %d times/sec\n", scan_rate); | ||
| 575 | |||
| 576 | /* Register the device in input subsystem */ | ||
| 577 | ret = input_register_device(touch->input); | ||
| 578 | if (ret) { | ||
| 579 | dev_err(&client->dev, | ||
| 580 | "Input device register failed: %d\n", ret); | ||
| 581 | goto err_input_free; | ||
| 582 | } | ||
| 583 | return 0; | ||
| 584 | |||
| 585 | err_input_free: | ||
| 586 | input_free_device(touch->input); | ||
| 587 | err_mem_free: | ||
| 588 | i2c_set_clientdata(client, NULL); | ||
| 589 | kfree(touch); | ||
| 590 | |||
| 591 | return ret; | ||
| 592 | } | ||
| 593 | |||
| 594 | static int __devexit synaptics_i2c_remove(struct i2c_client *client) | ||
| 595 | { | ||
| 596 | struct synaptics_i2c *touch = i2c_get_clientdata(client); | ||
| 597 | |||
| 598 | if (!polling_req) | ||
| 599 | free_irq(touch->client->irq, touch); | ||
| 600 | |||
| 601 | input_unregister_device(touch->input); | ||
| 602 | i2c_set_clientdata(client, NULL); | ||
| 603 | kfree(touch); | ||
| 604 | |||
| 605 | return 0; | ||
| 606 | } | ||
| 607 | |||
| 608 | #ifdef CONFIG_PM | ||
| 609 | static int synaptics_i2c_suspend(struct i2c_client *client, pm_message_t mesg) | ||
| 610 | { | ||
| 611 | struct synaptics_i2c *touch = i2c_get_clientdata(client); | ||
| 612 | |||
| 613 | cancel_delayed_work_sync(&touch->dwork); | ||
| 614 | |||
| 615 | /* Save some power */ | ||
| 616 | synaptics_i2c_reg_set(touch->client, DEV_CONTROL_REG, DEEP_SLEEP); | ||
| 617 | |||
| 618 | return 0; | ||
| 619 | } | ||
| 620 | |||
| 621 | static int synaptics_i2c_resume(struct i2c_client *client) | ||
| 622 | { | ||
| 623 | int ret; | ||
| 624 | struct synaptics_i2c *touch = i2c_get_clientdata(client); | ||
| 625 | |||
| 626 | ret = synaptics_i2c_reset_config(client); | ||
| 627 | if (ret) | ||
| 628 | return ret; | ||
| 629 | |||
| 630 | schedule_delayed_work(&touch->dwork, | ||
| 631 | msecs_to_jiffies(NO_DATA_SLEEP_MSECS)); | ||
| 632 | |||
| 633 | return 0; | ||
| 634 | } | ||
| 635 | #else | ||
| 636 | #define synaptics_i2c_suspend NULL | ||
| 637 | #define synaptics_i2c_resume NULL | ||
| 638 | #endif | ||
| 639 | |||
| 640 | static const struct i2c_device_id synaptics_i2c_id_table[] = { | ||
| 641 | { "synaptics_i2c", 0 }, | ||
| 642 | { }, | ||
| 643 | }; | ||
| 644 | MODULE_DEVICE_TABLE(i2c, synaptics_i2c_id_table); | ||
| 645 | |||
| 646 | static struct i2c_driver synaptics_i2c_driver = { | ||
| 647 | .driver = { | ||
| 648 | .name = DRIVER_NAME, | ||
| 649 | .owner = THIS_MODULE, | ||
| 650 | }, | ||
| 651 | |||
| 652 | .probe = synaptics_i2c_probe, | ||
| 653 | .remove = __devexit_p(synaptics_i2c_remove), | ||
| 654 | |||
| 655 | .suspend = synaptics_i2c_suspend, | ||
| 656 | .resume = synaptics_i2c_resume, | ||
| 657 | .id_table = synaptics_i2c_id_table, | ||
| 658 | }; | ||
| 659 | |||
| 660 | static int __init synaptics_i2c_init(void) | ||
| 661 | { | ||
| 662 | return i2c_add_driver(&synaptics_i2c_driver); | ||
| 663 | } | ||
| 664 | |||
| 665 | static void __exit synaptics_i2c_exit(void) | ||
| 666 | { | ||
| 667 | i2c_del_driver(&synaptics_i2c_driver); | ||
| 668 | } | ||
| 669 | |||
| 670 | module_init(synaptics_i2c_init); | ||
| 671 | module_exit(synaptics_i2c_exit); | ||
| 672 | |||
| 673 | MODULE_DESCRIPTION("Synaptics I2C touchpad driver"); | ||
| 674 | MODULE_AUTHOR("Mike Rapoport, Igor Grinberg, Compulab"); | ||
| 675 | MODULE_LICENSE("GPL"); | ||
| 676 | |||
diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 17fd6d46d082..966b8868f792 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c | |||
| @@ -60,7 +60,6 @@ struct mousedev { | |||
| 60 | int exist; | 60 | int exist; |
| 61 | int open; | 61 | int open; |
| 62 | int minor; | 62 | int minor; |
| 63 | char name[16]; | ||
| 64 | struct input_handle handle; | 63 | struct input_handle handle; |
| 65 | wait_queue_head_t wait; | 64 | wait_queue_head_t wait; |
| 66 | struct list_head client_list; | 65 | struct list_head client_list; |
| @@ -863,19 +862,17 @@ static struct mousedev *mousedev_create(struct input_dev *dev, | |||
| 863 | init_waitqueue_head(&mousedev->wait); | 862 | init_waitqueue_head(&mousedev->wait); |
| 864 | 863 | ||
| 865 | if (minor == MOUSEDEV_MIX) | 864 | if (minor == MOUSEDEV_MIX) |
| 866 | strlcpy(mousedev->name, "mice", sizeof(mousedev->name)); | 865 | dev_set_name(&mousedev->dev, "mice"); |
| 867 | else | 866 | else |
| 868 | snprintf(mousedev->name, sizeof(mousedev->name), | 867 | dev_set_name(&mousedev->dev, "mouse%d", minor); |
| 869 | "mouse%d", minor); | ||
| 870 | 868 | ||
| 871 | mousedev->minor = minor; | 869 | mousedev->minor = minor; |
| 872 | mousedev->exist = 1; | 870 | mousedev->exist = 1; |
| 873 | mousedev->handle.dev = input_get_device(dev); | 871 | mousedev->handle.dev = input_get_device(dev); |
| 874 | mousedev->handle.name = mousedev->name; | 872 | mousedev->handle.name = dev_name(&mousedev->dev); |
| 875 | mousedev->handle.handler = handler; | 873 | mousedev->handle.handler = handler; |
| 876 | mousedev->handle.private = mousedev; | 874 | mousedev->handle.private = mousedev; |
| 877 | 875 | ||
| 878 | dev_set_name(&mousedev->dev, mousedev->name); | ||
| 879 | mousedev->dev.class = &input_class; | 876 | mousedev->dev.class = &input_class; |
| 880 | if (dev) | 877 | if (dev) |
| 881 | mousedev->dev.parent = &dev->dev; | 878 | mousedev->dev.parent = &dev->dev; |
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 3cffb704e374..f919bf57293c 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | * the Free Software Foundation. | 10 | * the Free Software Foundation. |
| 11 | */ | 11 | */ |
| 12 | 12 | ||
| 13 | #include <linux/types.h> | ||
| 13 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
| 14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
| @@ -921,6 +922,9 @@ static void i8042_dritek_enable(void) | |||
| 921 | #endif | 922 | #endif |
| 922 | 923 | ||
| 923 | #ifdef CONFIG_PM | 924 | #ifdef CONFIG_PM |
| 925 | |||
| 926 | static bool i8042_suspended; | ||
| 927 | |||
| 924 | /* | 928 | /* |
| 925 | * Here we try to restore the original BIOS settings. We only want to | 929 | * Here we try to restore the original BIOS settings. We only want to |
| 926 | * do that once, when we really suspend, not when we taking memory | 930 | * do that once, when we really suspend, not when we taking memory |
| @@ -930,11 +934,9 @@ static void i8042_dritek_enable(void) | |||
| 930 | 934 | ||
| 931 | static int i8042_suspend(struct platform_device *dev, pm_message_t state) | 935 | static int i8042_suspend(struct platform_device *dev, pm_message_t state) |
| 932 | { | 936 | { |
| 933 | if (dev->dev.power.power_state.event != state.event) { | 937 | if (!i8042_suspended && state.event == PM_EVENT_SUSPEND) { |
| 934 | if (state.event == PM_EVENT_SUSPEND) | 938 | i8042_controller_reset(); |
| 935 | i8042_controller_reset(); | 939 | i8042_suspended = true; |
| 936 | |||
| 937 | dev->dev.power.power_state = state; | ||
| 938 | } | 940 | } |
| 939 | 941 | ||
| 940 | return 0; | 942 | return 0; |
| @@ -952,7 +954,7 @@ static int i8042_resume(struct platform_device *dev) | |||
| 952 | /* | 954 | /* |
| 953 | * Do not bother with restoring state if we haven't suspened yet | 955 | * Do not bother with restoring state if we haven't suspened yet |
| 954 | */ | 956 | */ |
| 955 | if (dev->dev.power.power_state.event == PM_EVENT_ON) | 957 | if (!i8042_suspended) |
| 956 | return 0; | 958 | return 0; |
| 957 | 959 | ||
| 958 | error = i8042_controller_check(); | 960 | error = i8042_controller_check(); |
| @@ -998,10 +1000,9 @@ static int i8042_resume(struct platform_device *dev) | |||
| 998 | if (i8042_ports[I8042_KBD_PORT_NO].serio) | 1000 | if (i8042_ports[I8042_KBD_PORT_NO].serio) |
| 999 | i8042_enable_kbd_port(); | 1001 | i8042_enable_kbd_port(); |
| 1000 | 1002 | ||
| 1003 | i8042_suspended = false; | ||
| 1001 | i8042_interrupt(0, NULL); | 1004 | i8042_interrupt(0, NULL); |
| 1002 | 1005 | ||
| 1003 | dev->dev.power.power_state = PMSG_ON; | ||
| 1004 | |||
| 1005 | return 0; | 1006 | return 0; |
| 1006 | } | 1007 | } |
| 1007 | #endif /* CONFIG_PM */ | 1008 | #endif /* CONFIG_PM */ |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index bc033250dfcd..fb17573f8f2d 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
| @@ -41,17 +41,6 @@ MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>"); | |||
| 41 | MODULE_DESCRIPTION("Serio abstraction core"); | 41 | MODULE_DESCRIPTION("Serio abstraction core"); |
| 42 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
| 43 | 43 | ||
| 44 | EXPORT_SYMBOL(serio_interrupt); | ||
| 45 | EXPORT_SYMBOL(__serio_register_port); | ||
| 46 | EXPORT_SYMBOL(serio_unregister_port); | ||
| 47 | EXPORT_SYMBOL(serio_unregister_child_port); | ||
| 48 | EXPORT_SYMBOL(__serio_register_driver); | ||
| 49 | EXPORT_SYMBOL(serio_unregister_driver); | ||
| 50 | EXPORT_SYMBOL(serio_open); | ||
| 51 | EXPORT_SYMBOL(serio_close); | ||
| 52 | EXPORT_SYMBOL(serio_rescan); | ||
| 53 | EXPORT_SYMBOL(serio_reconnect); | ||
| 54 | |||
| 55 | /* | 44 | /* |
| 56 | * serio_mutex protects entire serio subsystem and is taken every time | 45 | * serio_mutex protects entire serio subsystem and is taken every time |
| 57 | * serio port or driver registrered or unregistered. | 46 | * serio port or driver registrered or unregistered. |
| @@ -506,9 +495,9 @@ static ssize_t serio_set_bind_mode(struct device *dev, struct device_attribute * | |||
| 506 | 495 | ||
| 507 | retval = count; | 496 | retval = count; |
| 508 | if (!strncmp(buf, "manual", count)) { | 497 | if (!strncmp(buf, "manual", count)) { |
| 509 | serio->manual_bind = 1; | 498 | serio->manual_bind = true; |
| 510 | } else if (!strncmp(buf, "auto", count)) { | 499 | } else if (!strncmp(buf, "auto", count)) { |
| 511 | serio->manual_bind = 0; | 500 | serio->manual_bind = false; |
| 512 | } else { | 501 | } else { |
| 513 | retval = -EINVAL; | 502 | retval = -EINVAL; |
| 514 | } | 503 | } |
| @@ -581,7 +570,7 @@ static void serio_add_port(struct serio *serio) | |||
| 581 | "serio: device_add() failed for %s (%s), error: %d\n", | 570 | "serio: device_add() failed for %s (%s), error: %d\n", |
| 582 | serio->phys, serio->name, error); | 571 | serio->phys, serio->name, error); |
| 583 | else { | 572 | else { |
| 584 | serio->registered = 1; | 573 | serio->registered = true; |
| 585 | error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | 574 | error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); |
| 586 | if (error) | 575 | if (error) |
| 587 | printk(KERN_ERR | 576 | printk(KERN_ERR |
| @@ -617,7 +606,7 @@ static void serio_destroy_port(struct serio *serio) | |||
| 617 | if (serio->registered) { | 606 | if (serio->registered) { |
| 618 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | 607 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); |
| 619 | device_del(&serio->dev); | 608 | device_del(&serio->dev); |
| 620 | serio->registered = 0; | 609 | serio->registered = false; |
| 621 | } | 610 | } |
| 622 | 611 | ||
| 623 | list_del_init(&serio->node); | 612 | list_del_init(&serio->node); |
| @@ -692,11 +681,13 @@ void serio_rescan(struct serio *serio) | |||
| 692 | { | 681 | { |
| 693 | serio_queue_event(serio, NULL, SERIO_RESCAN_PORT); | 682 | serio_queue_event(serio, NULL, SERIO_RESCAN_PORT); |
| 694 | } | 683 | } |
| 684 | EXPORT_SYMBOL(serio_rescan); | ||
| 695 | 685 | ||
| 696 | void serio_reconnect(struct serio *serio) | 686 | void serio_reconnect(struct serio *serio) |
| 697 | { | 687 | { |
| 698 | serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN); | 688 | serio_queue_event(serio, NULL, SERIO_RECONNECT_CHAIN); |
| 699 | } | 689 | } |
| 690 | EXPORT_SYMBOL(serio_reconnect); | ||
| 700 | 691 | ||
| 701 | /* | 692 | /* |
| 702 | * Submits register request to kseriod for subsequent execution. | 693 | * Submits register request to kseriod for subsequent execution. |
| @@ -707,6 +698,7 @@ void __serio_register_port(struct serio *serio, struct module *owner) | |||
| 707 | serio_init_port(serio); | 698 | serio_init_port(serio); |
| 708 | serio_queue_event(serio, owner, SERIO_REGISTER_PORT); | 699 | serio_queue_event(serio, owner, SERIO_REGISTER_PORT); |
| 709 | } | 700 | } |
| 701 | EXPORT_SYMBOL(__serio_register_port); | ||
| 710 | 702 | ||
| 711 | /* | 703 | /* |
| 712 | * Synchronously unregisters serio port. | 704 | * Synchronously unregisters serio port. |
| @@ -718,6 +710,7 @@ void serio_unregister_port(struct serio *serio) | |||
| 718 | serio_destroy_port(serio); | 710 | serio_destroy_port(serio); |
| 719 | mutex_unlock(&serio_mutex); | 711 | mutex_unlock(&serio_mutex); |
| 720 | } | 712 | } |
| 713 | EXPORT_SYMBOL(serio_unregister_port); | ||
| 721 | 714 | ||
| 722 | /* | 715 | /* |
| 723 | * Safely unregisters child port if one is present. | 716 | * Safely unregisters child port if one is present. |
| @@ -731,6 +724,7 @@ void serio_unregister_child_port(struct serio *serio) | |||
| 731 | } | 724 | } |
| 732 | mutex_unlock(&serio_mutex); | 725 | mutex_unlock(&serio_mutex); |
| 733 | } | 726 | } |
| 727 | EXPORT_SYMBOL(serio_unregister_child_port); | ||
| 734 | 728 | ||
| 735 | 729 | ||
| 736 | /* | 730 | /* |
| @@ -756,9 +750,9 @@ static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char | |||
| 756 | 750 | ||
| 757 | retval = count; | 751 | retval = count; |
| 758 | if (!strncmp(buf, "manual", count)) { | 752 | if (!strncmp(buf, "manual", count)) { |
| 759 | serio_drv->manual_bind = 1; | 753 | serio_drv->manual_bind = true; |
| 760 | } else if (!strncmp(buf, "auto", count)) { | 754 | } else if (!strncmp(buf, "auto", count)) { |
| 761 | serio_drv->manual_bind = 0; | 755 | serio_drv->manual_bind = false; |
| 762 | } else { | 756 | } else { |
| 763 | retval = -EINVAL; | 757 | retval = -EINVAL; |
| 764 | } | 758 | } |
| @@ -818,7 +812,7 @@ static void serio_attach_driver(struct serio_driver *drv) | |||
| 818 | 812 | ||
| 819 | int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) | 813 | int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) |
| 820 | { | 814 | { |
| 821 | int manual_bind = drv->manual_bind; | 815 | bool manual_bind = drv->manual_bind; |
| 822 | int error; | 816 | int error; |
| 823 | 817 | ||
| 824 | drv->driver.bus = &serio_bus; | 818 | drv->driver.bus = &serio_bus; |
| @@ -829,7 +823,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons | |||
| 829 | * Temporarily disable automatic binding because probing | 823 | * Temporarily disable automatic binding because probing |
| 830 | * takes long time and we are better off doing it in kseriod | 824 | * takes long time and we are better off doing it in kseriod |
| 831 | */ | 825 | */ |
| 832 | drv->manual_bind = 1; | 826 | drv->manual_bind = true; |
| 833 | 827 | ||
| 834 | error = driver_register(&drv->driver); | 828 | error = driver_register(&drv->driver); |
| 835 | if (error) { | 829 | if (error) { |
| @@ -844,7 +838,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons | |||
| 844 | * driver to free ports | 838 | * driver to free ports |
| 845 | */ | 839 | */ |
| 846 | if (!manual_bind) { | 840 | if (!manual_bind) { |
| 847 | drv->manual_bind = 0; | 841 | drv->manual_bind = false; |
| 848 | error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER); | 842 | error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER); |
| 849 | if (error) { | 843 | if (error) { |
| 850 | driver_unregister(&drv->driver); | 844 | driver_unregister(&drv->driver); |
| @@ -854,6 +848,7 @@ int __serio_register_driver(struct serio_driver *drv, struct module *owner, cons | |||
| 854 | 848 | ||
| 855 | return 0; | 849 | return 0; |
| 856 | } | 850 | } |
| 851 | EXPORT_SYMBOL(__serio_register_driver); | ||
| 857 | 852 | ||
| 858 | void serio_unregister_driver(struct serio_driver *drv) | 853 | void serio_unregister_driver(struct serio_driver *drv) |
| 859 | { | 854 | { |
| @@ -861,7 +856,7 @@ void serio_unregister_driver(struct serio_driver *drv) | |||
| 861 | 856 | ||
| 862 | mutex_lock(&serio_mutex); | 857 | mutex_lock(&serio_mutex); |
| 863 | 858 | ||
| 864 | drv->manual_bind = 1; /* so serio_find_driver ignores it */ | 859 | drv->manual_bind = true; /* so serio_find_driver ignores it */ |
| 865 | serio_remove_pending_events(drv); | 860 | serio_remove_pending_events(drv); |
| 866 | 861 | ||
| 867 | start_over: | 862 | start_over: |
| @@ -877,6 +872,7 @@ start_over: | |||
| 877 | driver_unregister(&drv->driver); | 872 | driver_unregister(&drv->driver); |
| 878 | mutex_unlock(&serio_mutex); | 873 | mutex_unlock(&serio_mutex); |
| 879 | } | 874 | } |
| 875 | EXPORT_SYMBOL(serio_unregister_driver); | ||
| 880 | 876 | ||
| 881 | static void serio_set_drv(struct serio *serio, struct serio_driver *drv) | 877 | static void serio_set_drv(struct serio *serio, struct serio_driver *drv) |
| 882 | { | 878 | { |
| @@ -937,11 +933,11 @@ static int serio_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
| 937 | #ifdef CONFIG_PM | 933 | #ifdef CONFIG_PM |
| 938 | static int serio_suspend(struct device *dev, pm_message_t state) | 934 | static int serio_suspend(struct device *dev, pm_message_t state) |
| 939 | { | 935 | { |
| 940 | if (dev->power.power_state.event != state.event) { | 936 | struct serio *serio = to_serio_port(dev); |
| 941 | if (state.event == PM_EVENT_SUSPEND) | ||
| 942 | serio_cleanup(to_serio_port(dev)); | ||
| 943 | 937 | ||
| 944 | dev->power.power_state = state; | 938 | if (!serio->suspended && state.event == PM_EVENT_SUSPEND) { |
| 939 | serio_cleanup(serio); | ||
| 940 | serio->suspended = true; | ||
| 945 | } | 941 | } |
| 946 | 942 | ||
| 947 | return 0; | 943 | return 0; |
| @@ -949,14 +945,15 @@ static int serio_suspend(struct device *dev, pm_message_t state) | |||
| 949 | 945 | ||
| 950 | static int serio_resume(struct device *dev) | 946 | static int serio_resume(struct device *dev) |
| 951 | { | 947 | { |
| 948 | struct serio *serio = to_serio_port(dev); | ||
| 949 | |||
| 952 | /* | 950 | /* |
| 953 | * Driver reconnect can take a while, so better let kseriod | 951 | * Driver reconnect can take a while, so better let kseriod |
| 954 | * deal with it. | 952 | * deal with it. |
| 955 | */ | 953 | */ |
| 956 | if (dev->power.power_state.event != PM_EVENT_ON) { | 954 | if (serio->suspended) { |
| 957 | dev->power.power_state = PMSG_ON; | 955 | serio->suspended = false; |
| 958 | serio_queue_event(to_serio_port(dev), NULL, | 956 | serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); |
| 959 | SERIO_RECONNECT_PORT); | ||
| 960 | } | 957 | } |
| 961 | 958 | ||
| 962 | return 0; | 959 | return 0; |
| @@ -974,6 +971,7 @@ int serio_open(struct serio *serio, struct serio_driver *drv) | |||
| 974 | } | 971 | } |
| 975 | return 0; | 972 | return 0; |
| 976 | } | 973 | } |
| 974 | EXPORT_SYMBOL(serio_open); | ||
| 977 | 975 | ||
| 978 | /* called from serio_driver->connect/disconnect methods under serio_mutex */ | 976 | /* called from serio_driver->connect/disconnect methods under serio_mutex */ |
| 979 | void serio_close(struct serio *serio) | 977 | void serio_close(struct serio *serio) |
| @@ -983,6 +981,7 @@ void serio_close(struct serio *serio) | |||
| 983 | 981 | ||
| 984 | serio_set_drv(serio, NULL); | 982 | serio_set_drv(serio, NULL); |
| 985 | } | 983 | } |
| 984 | EXPORT_SYMBOL(serio_close); | ||
| 986 | 985 | ||
| 987 | irqreturn_t serio_interrupt(struct serio *serio, | 986 | irqreturn_t serio_interrupt(struct serio *serio, |
| 988 | unsigned char data, unsigned int dfl) | 987 | unsigned char data, unsigned int dfl) |
| @@ -1003,6 +1002,7 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
| 1003 | 1002 | ||
| 1004 | return ret; | 1003 | return ret; |
| 1005 | } | 1004 | } |
| 1005 | EXPORT_SYMBOL(serio_interrupt); | ||
| 1006 | 1006 | ||
| 1007 | static struct bus_type serio_bus = { | 1007 | static struct bus_type serio_bus = { |
| 1008 | .name = "serio", | 1008 | .name = "serio", |
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c index 2e18a1c0c351..3d32d3f4e486 100644 --- a/drivers/input/tablet/gtco.c +++ b/drivers/input/tablet/gtco.c | |||
| @@ -1050,4 +1050,5 @@ static void __exit gtco_exit(void) | |||
| 1050 | module_init(gtco_init); | 1050 | module_init(gtco_init); |
| 1051 | module_exit(gtco_exit); | 1051 | module_exit(gtco_exit); |
| 1052 | 1052 | ||
| 1053 | MODULE_DESCRIPTION("GTCO digitizer USB driver"); | ||
| 1053 | MODULE_LICENSE("GPL"); | 1054 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/input/tablet/wacom.h b/drivers/input/tablet/wacom.h index 9710bfd49cf9..9114ae1c7488 100644 --- a/drivers/input/tablet/wacom.h +++ b/drivers/input/tablet/wacom.h | |||
| @@ -68,6 +68,7 @@ | |||
| 68 | * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX | 68 | * v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX |
| 69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) | 69 | * v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A) |
| 70 | * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 | 70 | * v1.50 (pc) - Fixed a TabletPC touch bug in 2.6.28 |
| 71 | * v1.51 (pc) - Added support for Intuos4 | ||
| 71 | */ | 72 | */ |
| 72 | 73 | ||
| 73 | /* | 74 | /* |
| @@ -88,7 +89,7 @@ | |||
| 88 | /* | 89 | /* |
| 89 | * Version Information | 90 | * Version Information |
| 90 | */ | 91 | */ |
| 91 | #define DRIVER_VERSION "v1.50" | 92 | #define DRIVER_VERSION "v1.51" |
| 92 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" | 93 | #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>" |
| 93 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" | 94 | #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver" |
| 94 | #define DRIVER_LICENSE "GPL" | 95 | #define DRIVER_LICENSE "GPL" |
| @@ -128,6 +129,8 @@ extern void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac | |||
| 128 | extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 129 | extern void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
| 129 | extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 130 | extern void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
| 130 | extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 131 | extern void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
| 132 | extern void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
| 133 | extern void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | ||
| 131 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 134 | extern void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
| 132 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 135 | extern void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
| 133 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); | 136 | extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac); |
diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index b8624f27abf9..a9d5031b855e 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c | |||
| @@ -229,6 +229,19 @@ void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
| 229 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); | 229 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
| 230 | } | 230 | } |
| 231 | 231 | ||
| 232 | void input_dev_i4s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
| 233 | { | ||
| 234 | input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER); | ||
| 235 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) | BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3); | ||
| 236 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) | BIT_MASK(BTN_5) | BIT_MASK(BTN_6); | ||
| 237 | input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0); | ||
| 238 | } | ||
| 239 | |||
| 240 | void input_dev_i4(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | ||
| 241 | { | ||
| 242 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_7) | BIT_MASK(BTN_8); | ||
| 243 | } | ||
| 244 | |||
| 232 | void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 245 | void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
| 233 | { | 246 | { |
| 234 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); | 247 | input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9); |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 2638811c61ac..38bf86384aeb 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
| @@ -283,10 +283,11 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 283 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | 283 | static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) |
| 284 | { | 284 | { |
| 285 | unsigned char *data = wacom->data; | 285 | unsigned char *data = wacom->data; |
| 286 | int idx; | 286 | int idx = 0; |
| 287 | 287 | ||
| 288 | /* tool number */ | 288 | /* tool number */ |
| 289 | idx = data[1] & 0x01; | 289 | if (wacom->features->type == INTUOS) |
| 290 | idx = data[1] & 0x01; | ||
| 290 | 291 | ||
| 291 | /* Enter report */ | 292 | /* Enter report */ |
| 292 | if ((data[1] & 0xfc) == 0xc0) { | 293 | if ((data[1] & 0xfc) == 0xc0) { |
| @@ -299,6 +300,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
| 299 | switch (wacom->id[idx]) { | 300 | switch (wacom->id[idx]) { |
| 300 | case 0x812: /* Inking pen */ | 301 | case 0x812: /* Inking pen */ |
| 301 | case 0x801: /* Intuos3 Inking pen */ | 302 | case 0x801: /* Intuos3 Inking pen */ |
| 303 | case 0x20802: /* Intuos4 Classic Pen */ | ||
| 302 | case 0x012: | 304 | case 0x012: |
| 303 | wacom->tool[idx] = BTN_TOOL_PENCIL; | 305 | wacom->tool[idx] = BTN_TOOL_PENCIL; |
| 304 | break; | 306 | break; |
| @@ -308,6 +310,9 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
| 308 | case 0x823: /* Intuos3 Grip Pen */ | 310 | case 0x823: /* Intuos3 Grip Pen */ |
| 309 | case 0x813: /* Intuos3 Classic Pen */ | 311 | case 0x813: /* Intuos3 Classic Pen */ |
| 310 | case 0x885: /* Intuos3 Marker Pen */ | 312 | case 0x885: /* Intuos3 Marker Pen */ |
| 313 | case 0x802: /* Intuos4 Grip Pen Eraser */ | ||
| 314 | case 0x804: /* Intuos4 Marker Pen */ | ||
| 315 | case 0x40802: /* Intuos4 Classic Pen */ | ||
| 311 | case 0x022: | 316 | case 0x022: |
| 312 | wacom->tool[idx] = BTN_TOOL_PEN; | 317 | wacom->tool[idx] = BTN_TOOL_PEN; |
| 313 | break; | 318 | break; |
| @@ -319,10 +324,12 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
| 319 | case 0x09c: | 324 | case 0x09c: |
| 320 | case 0x094: | 325 | case 0x094: |
| 321 | case 0x017: /* Intuos3 2D Mouse */ | 326 | case 0x017: /* Intuos3 2D Mouse */ |
| 327 | case 0x806: /* Intuos4 Mouse */ | ||
| 322 | wacom->tool[idx] = BTN_TOOL_MOUSE; | 328 | wacom->tool[idx] = BTN_TOOL_MOUSE; |
| 323 | break; | 329 | break; |
| 324 | case 0x096: /* Lens cursor */ | 330 | case 0x096: /* Lens cursor */ |
| 325 | case 0x097: /* Intuos3 Lens cursor */ | 331 | case 0x097: /* Intuos3 Lens cursor */ |
| 332 | case 0x006: /* Intuos4 Lens cursor */ | ||
| 326 | wacom->tool[idx] = BTN_TOOL_LENS; | 333 | wacom->tool[idx] = BTN_TOOL_LENS; |
| 327 | break; | 334 | break; |
| 328 | case 0x82a: /* Eraser */ | 335 | case 0x82a: /* Eraser */ |
| @@ -333,12 +340,17 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
| 333 | case 0x82b: /* Intuos3 Grip Pen Eraser */ | 340 | case 0x82b: /* Intuos3 Grip Pen Eraser */ |
| 334 | case 0x81b: /* Intuos3 Classic Pen Eraser */ | 341 | case 0x81b: /* Intuos3 Classic Pen Eraser */ |
| 335 | case 0x91b: /* Intuos3 Airbrush Eraser */ | 342 | case 0x91b: /* Intuos3 Airbrush Eraser */ |
| 343 | case 0x80c: /* Intuos4 Marker Pen Eraser */ | ||
| 344 | case 0x80a: /* Intuos4 Grip Pen Eraser */ | ||
| 345 | case 0x4080a: /* Intuos4 Classic Pen Eraser */ | ||
| 346 | case 0x90a: /* Intuos4 Airbrush Eraser */ | ||
| 336 | wacom->tool[idx] = BTN_TOOL_RUBBER; | 347 | wacom->tool[idx] = BTN_TOOL_RUBBER; |
| 337 | break; | 348 | break; |
| 338 | case 0xd12: | 349 | case 0xd12: |
| 339 | case 0x912: | 350 | case 0x912: |
| 340 | case 0x112: | 351 | case 0x112: |
| 341 | case 0x913: /* Intuos3 Airbrush */ | 352 | case 0x913: /* Intuos3 Airbrush */ |
| 353 | case 0x902: /* Intuos4 Airbrush */ | ||
| 342 | wacom->tool[idx] = BTN_TOOL_AIRBRUSH; | 354 | wacom->tool[idx] = BTN_TOOL_AIRBRUSH; |
| 343 | break; | 355 | break; |
| 344 | default: /* Unknown tool */ | 356 | default: /* Unknown tool */ |
| @@ -349,9 +361,15 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
| 349 | 361 | ||
| 350 | /* Exit report */ | 362 | /* Exit report */ |
| 351 | if ((data[1] & 0xfe) == 0x80) { | 363 | if ((data[1] & 0xfe) == 0x80) { |
| 364 | /* | ||
| 365 | * Reset all states otherwise we lose the initial states | ||
| 366 | * when in-prox next time | ||
| 367 | */ | ||
| 352 | wacom_report_abs(wcombo, ABS_X, 0); | 368 | wacom_report_abs(wcombo, ABS_X, 0); |
| 353 | wacom_report_abs(wcombo, ABS_Y, 0); | 369 | wacom_report_abs(wcombo, ABS_Y, 0); |
| 354 | wacom_report_abs(wcombo, ABS_DISTANCE, 0); | 370 | wacom_report_abs(wcombo, ABS_DISTANCE, 0); |
| 371 | wacom_report_abs(wcombo, ABS_TILT_X, 0); | ||
| 372 | wacom_report_abs(wcombo, ABS_TILT_Y, 0); | ||
| 355 | if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { | 373 | if (wacom->tool[idx] >= BTN_TOOL_MOUSE) { |
| 356 | wacom_report_key(wcombo, BTN_LEFT, 0); | 374 | wacom_report_key(wcombo, BTN_LEFT, 0); |
| 357 | wacom_report_key(wcombo, BTN_MIDDLE, 0); | 375 | wacom_report_key(wcombo, BTN_MIDDLE, 0); |
| @@ -362,8 +380,6 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
| 362 | wacom_report_abs(wcombo, ABS_RZ, 0); | 380 | wacom_report_abs(wcombo, ABS_RZ, 0); |
| 363 | } else { | 381 | } else { |
| 364 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); | 382 | wacom_report_abs(wcombo, ABS_PRESSURE, 0); |
| 365 | wacom_report_abs(wcombo, ABS_TILT_X, 0); | ||
| 366 | wacom_report_abs(wcombo, ABS_TILT_Y, 0); | ||
| 367 | wacom_report_key(wcombo, BTN_STYLUS, 0); | 383 | wacom_report_key(wcombo, BTN_STYLUS, 0); |
| 368 | wacom_report_key(wcombo, BTN_STYLUS2, 0); | 384 | wacom_report_key(wcombo, BTN_STYLUS2, 0); |
| 369 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 385 | wacom_report_key(wcombo, BTN_TOUCH, 0); |
| @@ -372,6 +388,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom, void *wcombo) | |||
| 372 | wacom_report_key(wcombo, wacom->tool[idx], 0); | 388 | wacom_report_key(wcombo, wacom->tool[idx], 0); |
| 373 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 389 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ |
| 374 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); | 390 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, wacom->serial[idx]); |
| 391 | wacom->id[idx] = 0; | ||
| 375 | return 2; | 392 | return 2; |
| 376 | } | 393 | } |
| 377 | return 0; | 394 | return 0; |
| @@ -385,6 +402,8 @@ static void wacom_intuos_general(struct wacom_wac *wacom, void *wcombo) | |||
| 385 | /* general pen packet */ | 402 | /* general pen packet */ |
| 386 | if ((data[1] & 0xb8) == 0xa0) { | 403 | if ((data[1] & 0xb8) == 0xa0) { |
| 387 | t = (data[6] << 2) | ((data[7] >> 6) & 3); | 404 | t = (data[6] << 2) | ((data[7] >> 6) & 3); |
| 405 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) | ||
| 406 | t = (t << 1) | (data[1] & 1); | ||
| 388 | wacom_report_abs(wcombo, ABS_PRESSURE, t); | 407 | wacom_report_abs(wcombo, ABS_PRESSURE, t); |
| 389 | wacom_report_abs(wcombo, ABS_TILT_X, | 408 | wacom_report_abs(wcombo, ABS_TILT_X, |
| 390 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | 409 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); |
| @@ -409,7 +428,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 409 | { | 428 | { |
| 410 | unsigned char *data = wacom->data; | 429 | unsigned char *data = wacom->data; |
| 411 | unsigned int t; | 430 | unsigned int t; |
| 412 | int idx, result; | 431 | int idx = 0, result; |
| 413 | 432 | ||
| 414 | if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { | 433 | if (data[0] != 2 && data[0] != 5 && data[0] != 6 && data[0] != 12) { |
| 415 | dbg("wacom_intuos_irq: received unknown report #%d", data[0]); | 434 | dbg("wacom_intuos_irq: received unknown report #%d", data[0]); |
| @@ -417,7 +436,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 417 | } | 436 | } |
| 418 | 437 | ||
| 419 | /* tool number */ | 438 | /* tool number */ |
| 420 | idx = data[1] & 0x01; | 439 | if (wacom->features->type == INTUOS) |
| 440 | idx = data[1] & 0x01; | ||
| 421 | 441 | ||
| 422 | /* pad packets. Works as a second tool and is always in prox */ | 442 | /* pad packets. Works as a second tool and is always in prox */ |
| 423 | if (data[0] == 12) { | 443 | if (data[0] == 12) { |
| @@ -425,25 +445,54 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 425 | if (wacom->tool[1] != BTN_TOOL_FINGER) | 445 | if (wacom->tool[1] != BTN_TOOL_FINGER) |
| 426 | wacom->tool[1] = BTN_TOOL_FINGER; | 446 | wacom->tool[1] = BTN_TOOL_FINGER; |
| 427 | 447 | ||
| 428 | wacom_report_key(wcombo, BTN_0, (data[5] & 0x01)); | 448 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { |
| 429 | wacom_report_key(wcombo, BTN_1, (data[5] & 0x02)); | 449 | wacom_report_key(wcombo, BTN_0, (data[2] & 0x01)); |
| 430 | wacom_report_key(wcombo, BTN_2, (data[5] & 0x04)); | 450 | wacom_report_key(wcombo, BTN_1, (data[3] & 0x01)); |
| 431 | wacom_report_key(wcombo, BTN_3, (data[5] & 0x08)); | 451 | wacom_report_key(wcombo, BTN_2, (data[3] & 0x02)); |
| 432 | wacom_report_key(wcombo, BTN_4, (data[6] & 0x01)); | 452 | wacom_report_key(wcombo, BTN_3, (data[3] & 0x04)); |
| 433 | wacom_report_key(wcombo, BTN_5, (data[6] & 0x02)); | 453 | wacom_report_key(wcombo, BTN_4, (data[3] & 0x08)); |
| 434 | wacom_report_key(wcombo, BTN_6, (data[6] & 0x04)); | 454 | wacom_report_key(wcombo, BTN_5, (data[3] & 0x10)); |
| 435 | wacom_report_key(wcombo, BTN_7, (data[6] & 0x08)); | 455 | wacom_report_key(wcombo, BTN_6, (data[3] & 0x20)); |
| 436 | wacom_report_key(wcombo, BTN_8, (data[5] & 0x10)); | 456 | if (data[1] & 0x80) { |
| 437 | wacom_report_key(wcombo, BTN_9, (data[6] & 0x10)); | 457 | wacom_report_abs(wcombo, ABS_WHEEL, (data[1] & 0x7f)); |
| 438 | wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); | 458 | } else { |
| 439 | wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); | 459 | /* Out of proximity, clear wheel value. */ |
| 440 | 460 | wacom_report_abs(wcombo, ABS_WHEEL, 0); | |
| 441 | if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | | 461 | } |
| 442 | data[2] | (data[3] & 0x1f) | data[4]) | 462 | if (wacom->features->type != INTUOS4S) { |
| 443 | wacom_report_key(wcombo, wacom->tool[1], 1); | 463 | wacom_report_key(wcombo, BTN_7, (data[3] & 0x40)); |
| 444 | else | 464 | wacom_report_key(wcombo, BTN_8, (data[3] & 0x80)); |
| 445 | wacom_report_key(wcombo, wacom->tool[1], 0); | 465 | } |
| 446 | wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); | 466 | if (data[1] | (data[2] & 0x01) | data[3]) { |
| 467 | wacom_report_key(wcombo, wacom->tool[1], 1); | ||
| 468 | wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); | ||
| 469 | } else { | ||
| 470 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
| 471 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
| 472 | } | ||
| 473 | } else { | ||
| 474 | wacom_report_key(wcombo, BTN_0, (data[5] & 0x01)); | ||
| 475 | wacom_report_key(wcombo, BTN_1, (data[5] & 0x02)); | ||
| 476 | wacom_report_key(wcombo, BTN_2, (data[5] & 0x04)); | ||
| 477 | wacom_report_key(wcombo, BTN_3, (data[5] & 0x08)); | ||
| 478 | wacom_report_key(wcombo, BTN_4, (data[6] & 0x01)); | ||
| 479 | wacom_report_key(wcombo, BTN_5, (data[6] & 0x02)); | ||
| 480 | wacom_report_key(wcombo, BTN_6, (data[6] & 0x04)); | ||
| 481 | wacom_report_key(wcombo, BTN_7, (data[6] & 0x08)); | ||
| 482 | wacom_report_key(wcombo, BTN_8, (data[5] & 0x10)); | ||
| 483 | wacom_report_key(wcombo, BTN_9, (data[6] & 0x10)); | ||
| 484 | wacom_report_abs(wcombo, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); | ||
| 485 | wacom_report_abs(wcombo, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); | ||
| 486 | |||
| 487 | if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | | ||
| 488 | data[2] | (data[3] & 0x1f) | data[4]) { | ||
| 489 | wacom_report_key(wcombo, wacom->tool[1], 1); | ||
| 490 | wacom_report_abs(wcombo, ABS_MISC, PAD_DEVICE_ID); | ||
| 491 | } else { | ||
| 492 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
| 493 | wacom_report_abs(wcombo, ABS_MISC, 0); | ||
| 494 | } | ||
| 495 | } | ||
| 447 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff); | 496 | wacom_input_event(wcombo, EV_MSC, MSC_SERIAL, 0xffffffff); |
| 448 | return 1; | 497 | return 1; |
| 449 | } | 498 | } |
| @@ -453,10 +502,16 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 453 | if (result) | 502 | if (result) |
| 454 | return result-1; | 503 | return result-1; |
| 455 | 504 | ||
| 456 | /* Only large I3 and I1 & I2 support Lense Cursor */ | 505 | /* don't proceed if we don't know the ID */ |
| 506 | if (!wacom->id[idx]) | ||
| 507 | return 0; | ||
| 508 | |||
| 509 | /* Only large Intuos support Lense Cursor */ | ||
| 457 | if ((wacom->tool[idx] == BTN_TOOL_LENS) | 510 | if ((wacom->tool[idx] == BTN_TOOL_LENS) |
| 458 | && ((wacom->features->type == INTUOS3) | 511 | && ((wacom->features->type == INTUOS3) |
| 459 | || (wacom->features->type == INTUOS3S))) | 512 | || (wacom->features->type == INTUOS3S) |
| 513 | || (wacom->features->type == INTUOS4) | ||
| 514 | || (wacom->features->type == INTUOS4S))) | ||
| 460 | return 0; | 515 | return 0; |
| 461 | 516 | ||
| 462 | /* Cintiq doesn't send data when RDY bit isn't set */ | 517 | /* Cintiq doesn't send data when RDY bit isn't set */ |
| @@ -476,8 +531,8 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 476 | /* process general packets */ | 531 | /* process general packets */ |
| 477 | wacom_intuos_general(wacom, wcombo); | 532 | wacom_intuos_general(wacom, wcombo); |
| 478 | 533 | ||
| 479 | /* 4D mouse, 2D mouse, marker pen rotation, or Lens cursor packets */ | 534 | /* 4D mouse, 2D mouse, marker pen rotation, tilt mouse, or Lens cursor packets */ |
| 480 | if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0) { | 535 | if ((data[1] & 0xbc) == 0xa8 || (data[1] & 0xbe) == 0xb0 || (data[1] & 0xbc) == 0xac) { |
| 481 | 536 | ||
| 482 | if (data[1] & 0x02) { | 537 | if (data[1] & 0x02) { |
| 483 | /* Rotation packet */ | 538 | /* Rotation packet */ |
| @@ -506,20 +561,36 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 506 | wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); | 561 | wacom_report_abs(wcombo, ABS_THROTTLE, (data[8] & 0x08) ? -t : t); |
| 507 | 562 | ||
| 508 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { | 563 | } else if (wacom->tool[idx] == BTN_TOOL_MOUSE) { |
| 509 | /* 2D mouse packet */ | 564 | /* I4 mouse */ |
| 510 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04); | 565 | if (wacom->features->type >= INTUOS4S && wacom->features->type <= INTUOS4L) { |
| 511 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08); | 566 | wacom_report_key(wcombo, BTN_LEFT, data[6] & 0x01); |
| 512 | wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10); | 567 | wacom_report_key(wcombo, BTN_MIDDLE, data[6] & 0x02); |
| 513 | wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01) | 568 | wacom_report_key(wcombo, BTN_RIGHT, data[6] & 0x04); |
| 569 | wacom_report_rel(wcombo, REL_WHEEL, ((data[7] & 0x80) >> 7) | ||
| 570 | - ((data[7] & 0x40) >> 6)); | ||
| 571 | wacom_report_key(wcombo, BTN_SIDE, data[6] & 0x08); | ||
| 572 | wacom_report_key(wcombo, BTN_EXTRA, data[6] & 0x10); | ||
| 573 | |||
| 574 | wacom_report_abs(wcombo, ABS_TILT_X, | ||
| 575 | ((data[7] << 1) & 0x7e) | (data[8] >> 7)); | ||
| 576 | wacom_report_abs(wcombo, ABS_TILT_Y, data[8] & 0x7f); | ||
| 577 | } else { | ||
| 578 | /* 2D mouse packet */ | ||
| 579 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x04); | ||
| 580 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x08); | ||
| 581 | wacom_report_key(wcombo, BTN_RIGHT, data[8] & 0x10); | ||
| 582 | wacom_report_rel(wcombo, REL_WHEEL, (data[8] & 0x01) | ||
| 514 | - ((data[8] & 0x02) >> 1)); | 583 | - ((data[8] & 0x02) >> 1)); |
| 515 | 584 | ||
| 516 | /* I3 2D mouse side buttons */ | 585 | /* I3 2D mouse side buttons */ |
| 517 | if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { | 586 | if (wacom->features->type >= INTUOS3S && wacom->features->type <= INTUOS3L) { |
| 518 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); | 587 | wacom_report_key(wcombo, BTN_SIDE, data[8] & 0x40); |
| 519 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); | 588 | wacom_report_key(wcombo, BTN_EXTRA, data[8] & 0x20); |
| 589 | } | ||
| 520 | } | 590 | } |
| 521 | 591 | } else if ((wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L || | |
| 522 | } else if (wacom->features->type < INTUOS3S || wacom->features->type == INTUOS3L) { | 592 | wacom->features->type == INTUOS4L) && |
| 593 | wacom->tool[idx] == BTN_TOOL_LENS) { | ||
| 523 | /* Lens cursor packets */ | 594 | /* Lens cursor packets */ |
| 524 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); | 595 | wacom_report_key(wcombo, BTN_LEFT, data[8] & 0x01); |
| 525 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); | 596 | wacom_report_key(wcombo, BTN_MIDDLE, data[8] & 0x02); |
| @@ -581,6 +652,7 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo) | |||
| 581 | } | 652 | } |
| 582 | } else if (touchOut || !prox) { /* force touch out-prox */ | 653 | } else if (touchOut || !prox) { /* force touch out-prox */ |
| 583 | wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); | 654 | wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID); |
| 655 | wacom_report_key(wcombo, wacom->tool[1], 0); | ||
| 584 | wacom_report_key(wcombo, BTN_TOUCH, 0); | 656 | wacom_report_key(wcombo, BTN_TOUCH, 0); |
| 585 | touchOut = 0; | 657 | touchOut = 0; |
| 586 | touchInProx = 1; | 658 | touchInProx = 1; |
| @@ -669,6 +741,9 @@ int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo) | |||
| 669 | case INTUOS3S: | 741 | case INTUOS3S: |
| 670 | case INTUOS3: | 742 | case INTUOS3: |
| 671 | case INTUOS3L: | 743 | case INTUOS3L: |
| 744 | case INTUOS4S: | ||
| 745 | case INTUOS4: | ||
| 746 | case INTUOS4L: | ||
| 672 | case CINTIQ: | 747 | case CINTIQ: |
| 673 | case WACOM_BEE: | 748 | case WACOM_BEE: |
| 674 | return wacom_intuos_irq(wacom_wac, wcombo); | 749 | return wacom_intuos_irq(wacom_wac, wcombo); |
| @@ -706,6 +781,14 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w | |||
| 706 | case INTUOS: | 781 | case INTUOS: |
| 707 | input_dev_i(input_dev, wacom_wac); | 782 | input_dev_i(input_dev, wacom_wac); |
| 708 | break; | 783 | break; |
| 784 | case INTUOS4: | ||
| 785 | case INTUOS4L: | ||
| 786 | input_dev_i4(input_dev, wacom_wac); | ||
| 787 | /* fall through */ | ||
| 788 | case INTUOS4S: | ||
| 789 | input_dev_i4s(input_dev, wacom_wac); | ||
| 790 | input_dev_i(input_dev, wacom_wac); | ||
| 791 | break; | ||
| 709 | case PL: | 792 | case PL: |
| 710 | case PTU: | 793 | case PTU: |
| 711 | case TABLETPC: | 794 | case TABLETPC: |
| @@ -766,6 +849,10 @@ static struct wacom_features wacom_features[] = { | |||
| 766 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, | 849 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, |
| 767 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, | 850 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, |
| 768 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, | 851 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, |
| 852 | { "Wacom Intuos4 4x6", 10, 31496, 19685, 2047, 63, INTUOS4S }, | ||
| 853 | { "Wacom Intuos4 6x9", 10, 44704, 27940, 2047, 63, INTUOS4 }, | ||
| 854 | { "Wacom Intuos4 8x13", 10, 65024, 40640, 2047, 63, INTUOS4L }, | ||
| 855 | { "Wacom Intuos4 12x19", 10, 97536, 60960, 2047, 63, INTUOS4L }, | ||
| 769 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, | 856 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, |
| 770 | { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, | 857 | { "Wacom Cintiq 20WSX", 10, 86680, 54180, 1023, 63, WACOM_BEE }, |
| 771 | { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, | 858 | { "Wacom Cintiq 12WX", 10, 53020, 33440, 1023, 63, WACOM_BEE }, |
| @@ -825,6 +912,10 @@ static struct usb_device_id wacom_ids[] = { | |||
| 825 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, | 912 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB4) }, |
| 826 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, | 913 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB5) }, |
| 827 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, | 914 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB7) }, |
| 915 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB8) }, | ||
| 916 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xB9) }, | ||
| 917 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBA) }, | ||
| 918 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xBB) }, | ||
| 828 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, | 919 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) }, |
| 829 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, | 920 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) }, |
| 830 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, | 921 | { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) }, |
diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index f9c8b69673b7..c10235aba7e5 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h | |||
| @@ -25,6 +25,9 @@ enum { | |||
| 25 | INTUOS3S, | 25 | INTUOS3S, |
| 26 | INTUOS3, | 26 | INTUOS3, |
| 27 | INTUOS3L, | 27 | INTUOS3L, |
| 28 | INTUOS4S, | ||
| 29 | INTUOS4, | ||
| 30 | INTUOS4L, | ||
| 28 | CINTIQ, | 31 | CINTIQ, |
| 29 | WACOM_BEE, | 32 | WACOM_BEE, |
| 30 | WACOM_MO, | 33 | WACOM_MO, |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index b01fd61dadcc..72e2712c7e2a 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
| @@ -111,6 +111,15 @@ config TOUCHSCREEN_DA9034 | |||
| 111 | Say Y here to enable the support for the touchscreen found | 111 | Say Y here to enable the support for the touchscreen found |
| 112 | on Dialog Semiconductor DA9034 PMIC. | 112 | on Dialog Semiconductor DA9034 PMIC. |
| 113 | 113 | ||
| 114 | config TOUCHSCREEN_EETI | ||
| 115 | tristate "EETI touchscreen panel support" | ||
| 116 | depends on I2C | ||
| 117 | help | ||
| 118 | Say Y here to enable support for I2C connected EETI touch panels. | ||
| 119 | |||
| 120 | To compile this driver as a module, choose M here: the | ||
| 121 | module will be called eeti_ts. | ||
| 122 | |||
| 114 | config TOUCHSCREEN_FUJITSU | 123 | config TOUCHSCREEN_FUJITSU |
| 115 | tristate "Fujitsu serial touchscreen" | 124 | tristate "Fujitsu serial touchscreen" |
| 116 | select SERIO | 125 | select SERIO |
| @@ -341,6 +350,21 @@ config TOUCHSCREEN_WM9713 | |||
| 341 | Say Y here to enable support for the Wolfson Microelectronics | 350 | Say Y here to enable support for the Wolfson Microelectronics |
| 342 | WM9713 touchscreen controller. | 351 | WM9713 touchscreen controller. |
| 343 | 352 | ||
| 353 | config TOUCHSCREEN_WM97XX_ATMEL | ||
| 354 | tristate "WM97xx Atmel accelerated touch" | ||
| 355 | depends on TOUCHSCREEN_WM97XX && (AVR32 || ARCH_AT91) | ||
| 356 | help | ||
| 357 | Say Y here for support for streaming mode with WM97xx touchscreens | ||
| 358 | on Atmel AT91 or AVR32 systems with an AC97C module. | ||
| 359 | |||
| 360 | Be aware that this will use channel B in the controller for | ||
| 361 | streaming data, this must not conflict with other AC97C drivers. | ||
| 362 | |||
| 363 | If unsure, say N. | ||
| 364 | |||
| 365 | To compile this driver as a module, choose M here: the module will | ||
| 366 | be called atmel-wm97xx. | ||
| 367 | |||
| 344 | config TOUCHSCREEN_WM97XX_MAINSTONE | 368 | config TOUCHSCREEN_WM97XX_MAINSTONE |
| 345 | tristate "WM97xx Mainstone accelerated touch" | 369 | tristate "WM97xx Mainstone accelerated touch" |
| 346 | depends on TOUCHSCREEN_WM97XX && ARCH_PXA | 370 | depends on TOUCHSCREEN_WM97XX && ARCH_PXA |
| @@ -466,4 +490,12 @@ config TOUCHSCREEN_TSC2007 | |||
| 466 | To compile this driver as a module, choose M here: the | 490 | To compile this driver as a module, choose M here: the |
| 467 | module will be called tsc2007. | 491 | module will be called tsc2007. |
| 468 | 492 | ||
| 493 | config TOUCHSCREEN_W90X900 | ||
| 494 | tristate "W90P910 touchscreen driver" | ||
| 495 | help | ||
| 496 | Say Y here if you have a W90P910 based touchscreen. | ||
| 497 | |||
| 498 | To compile this driver as a module, choose M here: the | ||
| 499 | module will be called w90p910_ts. | ||
| 500 | |||
| 469 | endif | 501 | endif |
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 6700f7b9d165..3e1c5e0b952f 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile | |||
| @@ -13,6 +13,7 @@ obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o | |||
| 13 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o | 13 | obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o |
| 14 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o | 14 | obj-$(CONFIG_TOUCHSCREEN_CORGI) += corgi_ts.o |
| 15 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o | 15 | obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o |
| 16 | obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o | ||
| 16 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o | 17 | obj-$(CONFIG_TOUCHSCREEN_ELO) += elo.o |
| 17 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o | 18 | obj-$(CONFIG_TOUCHSCREEN_FUJITSU) += fujitsu_ts.o |
| 18 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o | 19 | obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o |
| @@ -35,5 +36,7 @@ obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o | |||
| 35 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o | 36 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9705) += wm9705.o |
| 36 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o | 37 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9712) += wm9712.o |
| 37 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o | 38 | wm97xx-ts-$(CONFIG_TOUCHSCREEN_WM9713) += wm9713.o |
| 39 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o | ||
| 38 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o | 40 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o |
| 39 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o | 41 | obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o |
| 42 | obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o | ||
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 2b01e56568f8..ba9d38c3f412 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c | |||
| @@ -83,6 +83,7 @@ struct ads7846_packet { | |||
| 83 | struct ads7846 { | 83 | struct ads7846 { |
| 84 | struct input_dev *input; | 84 | struct input_dev *input; |
| 85 | char phys[32]; | 85 | char phys[32]; |
| 86 | char name[32]; | ||
| 86 | 87 | ||
| 87 | struct spi_device *spi; | 88 | struct spi_device *spi; |
| 88 | 89 | ||
| @@ -97,6 +98,8 @@ struct ads7846 { | |||
| 97 | u16 x_plate_ohms; | 98 | u16 x_plate_ohms; |
| 98 | u16 pressure_max; | 99 | u16 pressure_max; |
| 99 | 100 | ||
| 101 | bool swap_xy; | ||
| 102 | |||
| 100 | struct ads7846_packet *packet; | 103 | struct ads7846_packet *packet; |
| 101 | 104 | ||
| 102 | struct spi_transfer xfer[18]; | 105 | struct spi_transfer xfer[18]; |
| @@ -599,6 +602,10 @@ static void ads7846_rx(void *ads) | |||
| 599 | dev_dbg(&ts->spi->dev, "DOWN\n"); | 602 | dev_dbg(&ts->spi->dev, "DOWN\n"); |
| 600 | #endif | 603 | #endif |
| 601 | } | 604 | } |
| 605 | |||
| 606 | if (ts->swap_xy) | ||
| 607 | swap(x, y); | ||
| 608 | |||
| 602 | input_report_abs(input, ABS_X, x); | 609 | input_report_abs(input, ABS_X, x); |
| 603 | input_report_abs(input, ABS_Y, y); | 610 | input_report_abs(input, ABS_Y, y); |
| 604 | input_report_abs(input, ABS_PRESSURE, Rt); | 611 | input_report_abs(input, ABS_PRESSURE, Rt); |
| @@ -917,6 +924,7 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 917 | ts->spi = spi; | 924 | ts->spi = spi; |
| 918 | ts->input = input_dev; | 925 | ts->input = input_dev; |
| 919 | ts->vref_mv = pdata->vref_mv; | 926 | ts->vref_mv = pdata->vref_mv; |
| 927 | ts->swap_xy = pdata->swap_xy; | ||
| 920 | 928 | ||
| 921 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 929 | hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 922 | ts->timer.function = ads7846_timer; | 930 | ts->timer.function = ads7846_timer; |
| @@ -958,8 +966,9 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 958 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; | 966 | ts->wait_for_sync = pdata->wait_for_sync ? : null_wait_for_sync; |
| 959 | 967 | ||
| 960 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); | 968 | snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(&spi->dev)); |
| 969 | snprintf(ts->name, sizeof(ts->name), "ADS%d Touchscreen", ts->model); | ||
| 961 | 970 | ||
| 962 | input_dev->name = "ADS784x Touchscreen"; | 971 | input_dev->name = ts->name; |
| 963 | input_dev->phys = ts->phys; | 972 | input_dev->phys = ts->phys; |
| 964 | input_dev->dev.parent = &spi->dev; | 973 | input_dev->dev.parent = &spi->dev; |
| 965 | 974 | ||
| @@ -1141,9 +1150,15 @@ static int __devinit ads7846_probe(struct spi_device *spi) | |||
| 1141 | 1150 | ||
| 1142 | if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, | 1151 | if (request_irq(spi->irq, ads7846_irq, IRQF_TRIGGER_FALLING, |
| 1143 | spi->dev.driver->name, ts)) { | 1152 | spi->dev.driver->name, ts)) { |
| 1144 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | 1153 | dev_info(&spi->dev, |
| 1145 | err = -EBUSY; | 1154 | "trying pin change workaround on irq %d\n", spi->irq); |
| 1146 | goto err_free_gpio; | 1155 | err = request_irq(spi->irq, ads7846_irq, |
| 1156 | IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, | ||
| 1157 | spi->dev.driver->name, ts); | ||
| 1158 | if (err) { | ||
| 1159 | dev_dbg(&spi->dev, "irq %d busy?\n", spi->irq); | ||
| 1160 | goto err_free_gpio; | ||
| 1161 | } | ||
| 1147 | } | 1162 | } |
| 1148 | 1163 | ||
| 1149 | err = ads784x_hwmon_register(spi, ts); | 1164 | err = ads784x_hwmon_register(spi, ts); |
diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c new file mode 100644 index 000000000000..35377f583e28 --- /dev/null +++ b/drivers/input/touchscreen/atmel-wm97xx.c | |||
| @@ -0,0 +1,446 @@ | |||
| 1 | /* | ||
| 2 | * Atmel AT91 and AVR32 continuous touch screen driver for Wolfson WM97xx AC97 | ||
| 3 | * codecs. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2008 - 2009 Atmel Corporation | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or modify it | ||
| 8 | * under the terms of the GNU General Public License version 2 as published by | ||
| 9 | * the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/moduleparam.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/delay.h> | ||
| 16 | #include <linux/irq.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | #include <linux/wm97xx.h> | ||
| 19 | #include <linux/timer.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | #include <linux/io.h> | ||
| 22 | |||
| 23 | #define AC97C_ICA 0x10 | ||
| 24 | #define AC97C_CBRHR 0x30 | ||
| 25 | #define AC97C_CBSR 0x38 | ||
| 26 | #define AC97C_CBMR 0x3c | ||
| 27 | #define AC97C_IER 0x54 | ||
| 28 | #define AC97C_IDR 0x58 | ||
| 29 | |||
| 30 | #define AC97C_RXRDY (1 << 4) | ||
| 31 | #define AC97C_OVRUN (1 << 5) | ||
| 32 | |||
| 33 | #define AC97C_CMR_SIZE_20 (0 << 16) | ||
| 34 | #define AC97C_CMR_SIZE_18 (1 << 16) | ||
| 35 | #define AC97C_CMR_SIZE_16 (2 << 16) | ||
| 36 | #define AC97C_CMR_SIZE_10 (3 << 16) | ||
| 37 | #define AC97C_CMR_CEM_LITTLE (1 << 18) | ||
| 38 | #define AC97C_CMR_CEM_BIG (0 << 18) | ||
| 39 | #define AC97C_CMR_CENA (1 << 21) | ||
| 40 | |||
| 41 | #define AC97C_INT_CBEVT (1 << 4) | ||
| 42 | |||
| 43 | #define AC97C_SR_CAEVT (1 << 3) | ||
| 44 | |||
| 45 | #define AC97C_CH_MASK(slot) \ | ||
| 46 | (0x7 << (3 * (slot - 3))) | ||
| 47 | #define AC97C_CH_ASSIGN(slot, channel) \ | ||
| 48 | (AC97C_CHANNEL_##channel << (3 * (slot - 3))) | ||
| 49 | #define AC97C_CHANNEL_NONE 0x0 | ||
| 50 | #define AC97C_CHANNEL_B 0x2 | ||
| 51 | |||
| 52 | #define ac97c_writel(chip, reg, val) \ | ||
| 53 | __raw_writel((val), (chip)->regs + AC97C_##reg) | ||
| 54 | #define ac97c_readl(chip, reg) \ | ||
| 55 | __raw_readl((chip)->regs + AC97C_##reg) | ||
| 56 | |||
| 57 | #ifdef CONFIG_CPU_AT32AP700X | ||
| 58 | #define ATMEL_WM97XX_AC97C_IOMEM (0xfff02800) | ||
| 59 | #define ATMEL_WM97XX_AC97C_IRQ (29) | ||
| 60 | #define ATMEL_WM97XX_GPIO_DEFAULT (32+16) /* Pin 16 on port B. */ | ||
| 61 | #else | ||
| 62 | #error Unkown CPU, this driver only supports AT32AP700X CPUs. | ||
| 63 | #endif | ||
| 64 | |||
| 65 | struct continuous { | ||
| 66 | u16 id; /* codec id */ | ||
| 67 | u8 code; /* continuous code */ | ||
| 68 | u8 reads; /* number of coord reads per read cycle */ | ||
| 69 | u32 speed; /* number of coords per second */ | ||
| 70 | }; | ||
| 71 | |||
| 72 | #define WM_READS(sp) ((sp / HZ) + 1) | ||
| 73 | |||
| 74 | static const struct continuous cinfo[] = { | ||
| 75 | {WM9705_ID2, 0, WM_READS(94), 94}, | ||
| 76 | {WM9705_ID2, 1, WM_READS(188), 188}, | ||
| 77 | {WM9705_ID2, 2, WM_READS(375), 375}, | ||
| 78 | {WM9705_ID2, 3, WM_READS(750), 750}, | ||
| 79 | {WM9712_ID2, 0, WM_READS(94), 94}, | ||
| 80 | {WM9712_ID2, 1, WM_READS(188), 188}, | ||
| 81 | {WM9712_ID2, 2, WM_READS(375), 375}, | ||
| 82 | {WM9712_ID2, 3, WM_READS(750), 750}, | ||
| 83 | {WM9713_ID2, 0, WM_READS(94), 94}, | ||
| 84 | {WM9713_ID2, 1, WM_READS(120), 120}, | ||
| 85 | {WM9713_ID2, 2, WM_READS(154), 154}, | ||
| 86 | {WM9713_ID2, 3, WM_READS(188), 188}, | ||
| 87 | }; | ||
| 88 | |||
| 89 | /* Continuous speed index. */ | ||
| 90 | static int sp_idx; | ||
| 91 | |||
| 92 | /* | ||
| 93 | * Pen sampling frequency (Hz) in continuous mode. | ||
| 94 | */ | ||
| 95 | static int cont_rate = 188; | ||
| 96 | module_param(cont_rate, int, 0); | ||
| 97 | MODULE_PARM_DESC(cont_rate, "Sampling rate in continuous mode (Hz)"); | ||
| 98 | |||
| 99 | /* | ||
| 100 | * Pen down detection. | ||
| 101 | * | ||
| 102 | * This driver can either poll or use an interrupt to indicate a pen down | ||
| 103 | * event. If the irq request fails then it will fall back to polling mode. | ||
| 104 | */ | ||
| 105 | static int pen_int = 1; | ||
| 106 | module_param(pen_int, int, 0); | ||
| 107 | MODULE_PARM_DESC(pen_int, "Pen down detection (1 = interrupt, 0 = polling)"); | ||
| 108 | |||
| 109 | /* | ||
| 110 | * Pressure readback. | ||
| 111 | * | ||
| 112 | * Set to 1 to read back pen down pressure. | ||
| 113 | */ | ||
| 114 | static int pressure; | ||
| 115 | module_param(pressure, int, 0); | ||
| 116 | MODULE_PARM_DESC(pressure, "Pressure readback (1 = pressure, 0 = no pressure)"); | ||
| 117 | |||
| 118 | /* | ||
| 119 | * AC97 touch data slot. | ||
| 120 | * | ||
| 121 | * Touch screen readback data ac97 slot. | ||
| 122 | */ | ||
| 123 | static int ac97_touch_slot = 5; | ||
| 124 | module_param(ac97_touch_slot, int, 0); | ||
| 125 | MODULE_PARM_DESC(ac97_touch_slot, "Touch screen data slot AC97 number"); | ||
| 126 | |||
| 127 | /* | ||
| 128 | * GPIO line number. | ||
| 129 | * | ||
| 130 | * Set to GPIO number where the signal from the WM97xx device is hooked up. | ||
| 131 | */ | ||
| 132 | static int atmel_gpio_line = ATMEL_WM97XX_GPIO_DEFAULT; | ||
| 133 | module_param(atmel_gpio_line, int, 0); | ||
| 134 | MODULE_PARM_DESC(atmel_gpio_line, "GPIO line number connected to WM97xx"); | ||
| 135 | |||
| 136 | struct atmel_wm97xx { | ||
| 137 | struct wm97xx *wm; | ||
| 138 | struct timer_list pen_timer; | ||
| 139 | void __iomem *regs; | ||
| 140 | unsigned long ac97c_irq; | ||
| 141 | unsigned long gpio_pen; | ||
| 142 | unsigned long gpio_irq; | ||
| 143 | unsigned short x; | ||
| 144 | unsigned short y; | ||
| 145 | }; | ||
| 146 | |||
| 147 | static irqreturn_t atmel_wm97xx_channel_b_interrupt(int irq, void *dev_id) | ||
| 148 | { | ||
| 149 | struct atmel_wm97xx *atmel_wm97xx = dev_id; | ||
| 150 | struct wm97xx *wm = atmel_wm97xx->wm; | ||
| 151 | int status = ac97c_readl(atmel_wm97xx, CBSR); | ||
| 152 | irqreturn_t retval = IRQ_NONE; | ||
| 153 | |||
| 154 | if (status & AC97C_OVRUN) { | ||
| 155 | dev_dbg(&wm->touch_dev->dev, "AC97C overrun\n"); | ||
| 156 | ac97c_readl(atmel_wm97xx, CBRHR); | ||
| 157 | retval = IRQ_HANDLED; | ||
| 158 | } else if (status & AC97C_RXRDY) { | ||
| 159 | u16 data; | ||
| 160 | u16 value; | ||
| 161 | u16 source; | ||
| 162 | u16 pen_down; | ||
| 163 | |||
| 164 | data = ac97c_readl(atmel_wm97xx, CBRHR); | ||
| 165 | value = data & 0x0fff; | ||
| 166 | source = data & WM97XX_ADCSRC_MASK; | ||
| 167 | pen_down = (data & WM97XX_PEN_DOWN) >> 8; | ||
| 168 | |||
| 169 | if (source == WM97XX_ADCSEL_X) | ||
| 170 | atmel_wm97xx->x = value; | ||
| 171 | if (source == WM97XX_ADCSEL_Y) | ||
| 172 | atmel_wm97xx->y = value; | ||
| 173 | |||
| 174 | if (!pressure && source == WM97XX_ADCSEL_Y) { | ||
| 175 | input_report_abs(wm->input_dev, ABS_X, atmel_wm97xx->x); | ||
| 176 | input_report_abs(wm->input_dev, ABS_Y, atmel_wm97xx->y); | ||
| 177 | input_report_key(wm->input_dev, BTN_TOUCH, pen_down); | ||
| 178 | input_sync(wm->input_dev); | ||
| 179 | } else if (pressure && source == WM97XX_ADCSEL_PRES) { | ||
| 180 | input_report_abs(wm->input_dev, ABS_X, atmel_wm97xx->x); | ||
| 181 | input_report_abs(wm->input_dev, ABS_Y, atmel_wm97xx->y); | ||
| 182 | input_report_abs(wm->input_dev, ABS_PRESSURE, value); | ||
| 183 | input_report_key(wm->input_dev, BTN_TOUCH, value); | ||
| 184 | input_sync(wm->input_dev); | ||
| 185 | } | ||
| 186 | |||
| 187 | retval = IRQ_HANDLED; | ||
| 188 | } | ||
| 189 | |||
| 190 | return retval; | ||
| 191 | } | ||
| 192 | |||
| 193 | static void atmel_wm97xx_acc_pen_up(struct wm97xx *wm) | ||
| 194 | { | ||
| 195 | struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(wm->touch_dev); | ||
| 196 | struct input_dev *input_dev = wm->input_dev; | ||
| 197 | int pen_down = gpio_get_value(atmel_wm97xx->gpio_pen); | ||
| 198 | |||
| 199 | if (pen_down != 0) { | ||
| 200 | mod_timer(&atmel_wm97xx->pen_timer, | ||
| 201 | jiffies + msecs_to_jiffies(1)); | ||
| 202 | } else { | ||
| 203 | if (pressure) | ||
| 204 | input_report_abs(input_dev, ABS_PRESSURE, 0); | ||
| 205 | input_report_key(input_dev, BTN_TOUCH, 0); | ||
| 206 | input_sync(input_dev); | ||
| 207 | } | ||
| 208 | } | ||
| 209 | |||
| 210 | static void atmel_wm97xx_pen_timer(unsigned long data) | ||
| 211 | { | ||
| 212 | atmel_wm97xx_acc_pen_up((struct wm97xx *)data); | ||
| 213 | } | ||
| 214 | |||
| 215 | static int atmel_wm97xx_acc_startup(struct wm97xx *wm) | ||
| 216 | { | ||
| 217 | struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(wm->touch_dev); | ||
| 218 | int idx = 0; | ||
| 219 | |||
| 220 | if (wm->ac97 == NULL) | ||
| 221 | return -ENODEV; | ||
| 222 | |||
| 223 | for (idx = 0; idx < ARRAY_SIZE(cinfo); idx++) { | ||
| 224 | if (wm->id != cinfo[idx].id) | ||
| 225 | continue; | ||
| 226 | |||
| 227 | sp_idx = idx; | ||
| 228 | |||
| 229 | if (cont_rate <= cinfo[idx].speed) | ||
| 230 | break; | ||
| 231 | } | ||
| 232 | |||
| 233 | wm->acc_rate = cinfo[sp_idx].code; | ||
| 234 | wm->acc_slot = ac97_touch_slot; | ||
| 235 | dev_info(&wm->touch_dev->dev, "atmel accelerated touchscreen driver, " | ||
| 236 | "%d samples/sec\n", cinfo[sp_idx].speed); | ||
| 237 | |||
| 238 | if (pen_int) { | ||
| 239 | unsigned long reg; | ||
| 240 | |||
| 241 | wm->pen_irq = atmel_wm97xx->gpio_irq; | ||
| 242 | |||
| 243 | switch (wm->id) { | ||
| 244 | case WM9712_ID2: /* Fall through. */ | ||
| 245 | case WM9713_ID2: | ||
| 246 | /* | ||
| 247 | * Use GPIO 13 (PEN_DOWN) to assert GPIO line 3 | ||
| 248 | * (PENDOWN). | ||
| 249 | */ | ||
| 250 | wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN, | ||
| 251 | WM97XX_GPIO_POL_HIGH, | ||
| 252 | WM97XX_GPIO_STICKY, | ||
| 253 | WM97XX_GPIO_WAKE); | ||
| 254 | wm97xx_config_gpio(wm, WM97XX_GPIO_3, WM97XX_GPIO_OUT, | ||
| 255 | WM97XX_GPIO_POL_HIGH, | ||
| 256 | WM97XX_GPIO_NOTSTICKY, | ||
| 257 | WM97XX_GPIO_NOWAKE); | ||
| 258 | case WM9705_ID2: /* Fall through. */ | ||
| 259 | /* | ||
| 260 | * Enable touch data slot in AC97 controller channel B. | ||
| 261 | */ | ||
| 262 | reg = ac97c_readl(atmel_wm97xx, ICA); | ||
| 263 | reg &= ~AC97C_CH_MASK(wm->acc_slot); | ||
| 264 | reg |= AC97C_CH_ASSIGN(wm->acc_slot, B); | ||
| 265 | ac97c_writel(atmel_wm97xx, ICA, reg); | ||
| 266 | |||
| 267 | /* | ||
| 268 | * Enable channel and interrupt for RXRDY and OVERRUN. | ||
| 269 | */ | ||
| 270 | ac97c_writel(atmel_wm97xx, CBMR, AC97C_CMR_CENA | ||
| 271 | | AC97C_CMR_CEM_BIG | ||
| 272 | | AC97C_CMR_SIZE_16 | ||
| 273 | | AC97C_OVRUN | ||
| 274 | | AC97C_RXRDY); | ||
| 275 | /* Dummy read to empty RXRHR. */ | ||
| 276 | ac97c_readl(atmel_wm97xx, CBRHR); | ||
| 277 | /* | ||
| 278 | * Enable interrupt for channel B in the AC97 | ||
| 279 | * controller. | ||
| 280 | */ | ||
| 281 | ac97c_writel(atmel_wm97xx, IER, AC97C_INT_CBEVT); | ||
| 282 | break; | ||
| 283 | default: | ||
| 284 | dev_err(&wm->touch_dev->dev, "pen down irq not " | ||
| 285 | "supported on this device\n"); | ||
| 286 | pen_int = 0; | ||
| 287 | break; | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | return 0; | ||
| 292 | } | ||
| 293 | |||
| 294 | static void atmel_wm97xx_acc_shutdown(struct wm97xx *wm) | ||
| 295 | { | ||
| 296 | if (pen_int) { | ||
| 297 | struct atmel_wm97xx *atmel_wm97xx = | ||
| 298 | platform_get_drvdata(wm->touch_dev); | ||
| 299 | unsigned long ica; | ||
| 300 | |||
| 301 | switch (wm->id & 0xffff) { | ||
| 302 | case WM9705_ID2: /* Fall through. */ | ||
| 303 | case WM9712_ID2: /* Fall through. */ | ||
| 304 | case WM9713_ID2: | ||
| 305 | /* Disable slot and turn off channel B interrupts. */ | ||
| 306 | ica = ac97c_readl(atmel_wm97xx, ICA); | ||
| 307 | ica &= ~AC97C_CH_MASK(wm->acc_slot); | ||
| 308 | ac97c_writel(atmel_wm97xx, ICA, ica); | ||
| 309 | ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); | ||
| 310 | ac97c_writel(atmel_wm97xx, CBMR, 0); | ||
| 311 | wm->pen_irq = 0; | ||
| 312 | break; | ||
| 313 | default: | ||
| 314 | dev_err(&wm->touch_dev->dev, "unknown codec\n"); | ||
| 315 | break; | ||
| 316 | } | ||
| 317 | } | ||
| 318 | } | ||
| 319 | |||
| 320 | static void atmel_wm97xx_irq_enable(struct wm97xx *wm, int enable) | ||
| 321 | { | ||
| 322 | /* Intentionally left empty. */ | ||
| 323 | } | ||
| 324 | |||
| 325 | static struct wm97xx_mach_ops atmel_mach_ops = { | ||
| 326 | .acc_enabled = 1, | ||
| 327 | .acc_pen_up = atmel_wm97xx_acc_pen_up, | ||
| 328 | .acc_startup = atmel_wm97xx_acc_startup, | ||
| 329 | .acc_shutdown = atmel_wm97xx_acc_shutdown, | ||
| 330 | .irq_enable = atmel_wm97xx_irq_enable, | ||
| 331 | .irq_gpio = WM97XX_GPIO_3, | ||
| 332 | }; | ||
| 333 | |||
| 334 | static int __init atmel_wm97xx_probe(struct platform_device *pdev) | ||
| 335 | { | ||
| 336 | struct wm97xx *wm = platform_get_drvdata(pdev); | ||
| 337 | struct atmel_wm97xx *atmel_wm97xx; | ||
| 338 | int ret; | ||
| 339 | |||
| 340 | atmel_wm97xx = kzalloc(sizeof(struct atmel_wm97xx), GFP_KERNEL); | ||
| 341 | if (!atmel_wm97xx) { | ||
| 342 | dev_dbg(&pdev->dev, "out of memory\n"); | ||
| 343 | return -ENOMEM; | ||
| 344 | } | ||
| 345 | |||
| 346 | atmel_wm97xx->wm = wm; | ||
| 347 | atmel_wm97xx->regs = (void *)ATMEL_WM97XX_AC97C_IOMEM; | ||
| 348 | atmel_wm97xx->ac97c_irq = ATMEL_WM97XX_AC97C_IRQ; | ||
| 349 | atmel_wm97xx->gpio_pen = atmel_gpio_line; | ||
| 350 | atmel_wm97xx->gpio_irq = gpio_to_irq(atmel_wm97xx->gpio_pen); | ||
| 351 | |||
| 352 | setup_timer(&atmel_wm97xx->pen_timer, atmel_wm97xx_pen_timer, | ||
| 353 | (unsigned long)wm); | ||
| 354 | |||
| 355 | ret = request_irq(atmel_wm97xx->ac97c_irq, | ||
| 356 | atmel_wm97xx_channel_b_interrupt, | ||
| 357 | IRQF_SHARED, "atmel-wm97xx-ch-b", atmel_wm97xx); | ||
| 358 | if (ret) { | ||
| 359 | dev_dbg(&pdev->dev, "could not request ac97c irq\n"); | ||
| 360 | goto err; | ||
| 361 | } | ||
| 362 | |||
| 363 | platform_set_drvdata(pdev, atmel_wm97xx); | ||
| 364 | |||
| 365 | ret = wm97xx_register_mach_ops(wm, &atmel_mach_ops); | ||
| 366 | if (ret) | ||
| 367 | goto err_irq; | ||
| 368 | |||
| 369 | return ret; | ||
| 370 | |||
| 371 | err_irq: | ||
| 372 | free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx); | ||
| 373 | err: | ||
| 374 | platform_set_drvdata(pdev, NULL); | ||
| 375 | kfree(atmel_wm97xx); | ||
| 376 | return ret; | ||
| 377 | } | ||
| 378 | |||
| 379 | static int __exit atmel_wm97xx_remove(struct platform_device *pdev) | ||
| 380 | { | ||
| 381 | struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); | ||
| 382 | struct wm97xx *wm = atmel_wm97xx->wm; | ||
| 383 | |||
| 384 | ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); | ||
| 385 | free_irq(atmel_wm97xx->ac97c_irq, atmel_wm97xx); | ||
| 386 | del_timer_sync(&atmel_wm97xx->pen_timer); | ||
| 387 | wm97xx_unregister_mach_ops(wm); | ||
| 388 | platform_set_drvdata(pdev, NULL); | ||
| 389 | kfree(atmel_wm97xx); | ||
| 390 | |||
| 391 | return 0; | ||
| 392 | } | ||
| 393 | |||
| 394 | #ifdef CONFIG_PM | ||
| 395 | static int atmel_wm97xx_suspend(struct platform_device *pdev, pm_message_t msg) | ||
| 396 | { | ||
| 397 | struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); | ||
| 398 | |||
| 399 | ac97c_writel(atmel_wm97xx, IDR, AC97C_INT_CBEVT); | ||
| 400 | disable_irq(atmel_wm97xx->gpio_irq); | ||
| 401 | del_timer_sync(&atmel_wm97xx->pen_timer); | ||
| 402 | |||
| 403 | return 0; | ||
| 404 | } | ||
| 405 | |||
| 406 | static int atmel_wm97xx_resume(struct platform_device *pdev) | ||
| 407 | { | ||
| 408 | struct atmel_wm97xx *atmel_wm97xx = platform_get_drvdata(pdev); | ||
| 409 | struct wm97xx *wm = atmel_wm97xx->wm; | ||
| 410 | |||
| 411 | if (wm->input_dev->users) { | ||
| 412 | enable_irq(atmel_wm97xx->gpio_irq); | ||
| 413 | ac97c_writel(atmel_wm97xx, IER, AC97C_INT_CBEVT); | ||
| 414 | } | ||
| 415 | |||
| 416 | return 0; | ||
| 417 | } | ||
| 418 | #else | ||
| 419 | #define atmel_wm97xx_suspend NULL | ||
| 420 | #define atmel_wm97xx_resume NULL | ||
| 421 | #endif | ||
| 422 | |||
| 423 | static struct platform_driver atmel_wm97xx_driver = { | ||
| 424 | .remove = __exit_p(atmel_wm97xx_remove), | ||
| 425 | .driver = { | ||
| 426 | .name = "wm97xx-touch", | ||
| 427 | }, | ||
| 428 | .suspend = atmel_wm97xx_suspend, | ||
| 429 | .resume = atmel_wm97xx_resume, | ||
| 430 | }; | ||
| 431 | |||
| 432 | static int __init atmel_wm97xx_init(void) | ||
| 433 | { | ||
| 434 | return platform_driver_probe(&atmel_wm97xx_driver, atmel_wm97xx_probe); | ||
| 435 | } | ||
| 436 | module_init(atmel_wm97xx_init); | ||
| 437 | |||
| 438 | static void __exit atmel_wm97xx_exit(void) | ||
| 439 | { | ||
| 440 | platform_driver_unregister(&atmel_wm97xx_driver); | ||
| 441 | } | ||
| 442 | module_exit(atmel_wm97xx_exit); | ||
| 443 | |||
| 444 | MODULE_AUTHOR("Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>"); | ||
| 445 | MODULE_DESCRIPTION("wm97xx continuous touch driver for Atmel AT91 and AVR32"); | ||
| 446 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c new file mode 100644 index 000000000000..3ab92222a525 --- /dev/null +++ b/drivers/input/touchscreen/eeti_ts.c | |||
| @@ -0,0 +1,286 @@ | |||
| 1 | /* | ||
| 2 | * Touch Screen driver for EETI's I2C connected touch screen panels | ||
| 3 | * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> | ||
| 4 | * | ||
| 5 | * See EETI's software guide for the protocol specification: | ||
| 6 | * http://home.eeti.com.tw/web20/eg/guide.htm | ||
| 7 | * | ||
| 8 | * Based on migor_ts.c | ||
| 9 | * Copyright (c) 2008 Magnus Damm | ||
| 10 | * Copyright (c) 2007 Ujjwal Pande <ujjwal@kenati.com> | ||
| 11 | * | ||
| 12 | * This file is free software; you can redistribute it and/or | ||
| 13 | * modify it under the terms of the GNU General Public | ||
| 14 | * License as published by the Free Software Foundation; either | ||
| 15 | * version 2 of the License, or (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This file is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 20 | * General Public License for more details. | ||
| 21 | * | ||
| 22 | * You should have received a copy of the GNU General Public | ||
| 23 | * License along with this library; if not, write to the Free Software | ||
| 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 25 | */ | ||
| 26 | |||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/moduleparam.h> | ||
| 29 | #include <linux/kernel.h> | ||
| 30 | #include <linux/input.h> | ||
| 31 | #include <linux/interrupt.h> | ||
| 32 | #include <linux/i2c.h> | ||
| 33 | #include <linux/timer.h> | ||
| 34 | #include <linux/gpio.h> | ||
| 35 | |||
| 36 | static int flip_x; | ||
| 37 | module_param(flip_x, bool, 0644); | ||
| 38 | MODULE_PARM_DESC(flip_x, "flip x coordinate"); | ||
| 39 | |||
| 40 | static int flip_y; | ||
| 41 | module_param(flip_y, bool, 0644); | ||
| 42 | MODULE_PARM_DESC(flip_y, "flip y coordinate"); | ||
| 43 | |||
| 44 | struct eeti_ts_priv { | ||
| 45 | struct i2c_client *client; | ||
| 46 | struct input_dev *input; | ||
| 47 | struct work_struct work; | ||
| 48 | struct mutex mutex; | ||
| 49 | int irq; | ||
| 50 | }; | ||
| 51 | |||
| 52 | #define EETI_TS_BITDEPTH (11) | ||
| 53 | #define EETI_MAXVAL ((1 << (EETI_TS_BITDEPTH + 1)) - 1) | ||
| 54 | |||
| 55 | #define REPORT_BIT_PRESSED (1 << 0) | ||
| 56 | #define REPORT_BIT_AD0 (1 << 1) | ||
| 57 | #define REPORT_BIT_AD1 (1 << 2) | ||
| 58 | #define REPORT_BIT_HAS_PRESSURE (1 << 6) | ||
| 59 | #define REPORT_RES_BITS(v) (((v) >> 1) + EETI_TS_BITDEPTH) | ||
| 60 | |||
| 61 | static void eeti_ts_read(struct work_struct *work) | ||
| 62 | { | ||
| 63 | char buf[6]; | ||
| 64 | unsigned int x, y, res, pressed, to = 100; | ||
| 65 | struct eeti_ts_priv *priv = | ||
| 66 | container_of(work, struct eeti_ts_priv, work); | ||
| 67 | |||
| 68 | mutex_lock(&priv->mutex); | ||
| 69 | |||
| 70 | while (!gpio_get_value(irq_to_gpio(priv->irq)) && --to) | ||
| 71 | i2c_master_recv(priv->client, buf, sizeof(buf)); | ||
| 72 | |||
| 73 | if (!to) { | ||
| 74 | dev_err(&priv->client->dev, | ||
| 75 | "unable to clear IRQ - line stuck?\n"); | ||
| 76 | goto out; | ||
| 77 | } | ||
| 78 | |||
| 79 | /* drop non-report packets */ | ||
| 80 | if (!(buf[0] & 0x80)) | ||
| 81 | goto out; | ||
| 82 | |||
| 83 | pressed = buf[0] & REPORT_BIT_PRESSED; | ||
| 84 | res = REPORT_RES_BITS(buf[0] & (REPORT_BIT_AD0 | REPORT_BIT_AD1)); | ||
| 85 | x = buf[2] | (buf[1] << 8); | ||
| 86 | y = buf[4] | (buf[3] << 8); | ||
| 87 | |||
| 88 | /* fix the range to 11 bits */ | ||
| 89 | x >>= res - EETI_TS_BITDEPTH; | ||
| 90 | y >>= res - EETI_TS_BITDEPTH; | ||
| 91 | |||
| 92 | if (flip_x) | ||
| 93 | x = EETI_MAXVAL - x; | ||
| 94 | |||
| 95 | if (flip_y) | ||
| 96 | y = EETI_MAXVAL - y; | ||
| 97 | |||
| 98 | if (buf[0] & REPORT_BIT_HAS_PRESSURE) | ||
| 99 | input_report_abs(priv->input, ABS_PRESSURE, buf[5]); | ||
| 100 | |||
| 101 | input_report_abs(priv->input, ABS_X, x); | ||
| 102 | input_report_abs(priv->input, ABS_Y, y); | ||
| 103 | input_report_key(priv->input, BTN_TOUCH, !!pressed); | ||
| 104 | input_sync(priv->input); | ||
| 105 | |||
| 106 | out: | ||
| 107 | mutex_unlock(&priv->mutex); | ||
| 108 | } | ||
| 109 | |||
| 110 | static irqreturn_t eeti_ts_isr(int irq, void *dev_id) | ||
| 111 | { | ||
| 112 | struct eeti_ts_priv *priv = dev_id; | ||
| 113 | |||
| 114 | /* postpone I2C transactions as we are atomic */ | ||
| 115 | schedule_work(&priv->work); | ||
| 116 | |||
| 117 | return IRQ_HANDLED; | ||
| 118 | } | ||
| 119 | |||
| 120 | static int eeti_ts_open(struct input_dev *dev) | ||
| 121 | { | ||
| 122 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | ||
| 123 | |||
| 124 | enable_irq(priv->irq); | ||
| 125 | |||
| 126 | /* Read the events once to arm the IRQ */ | ||
| 127 | eeti_ts_read(&priv->work); | ||
| 128 | |||
| 129 | return 0; | ||
| 130 | } | ||
| 131 | |||
| 132 | static void eeti_ts_close(struct input_dev *dev) | ||
| 133 | { | ||
| 134 | struct eeti_ts_priv *priv = input_get_drvdata(dev); | ||
| 135 | |||
| 136 | disable_irq(priv->irq); | ||
| 137 | cancel_work_sync(&priv->work); | ||
| 138 | } | ||
| 139 | |||
| 140 | static int __devinit eeti_ts_probe(struct i2c_client *client, | ||
| 141 | const struct i2c_device_id *idp) | ||
| 142 | { | ||
| 143 | struct eeti_ts_priv *priv; | ||
| 144 | struct input_dev *input; | ||
| 145 | int err = -ENOMEM; | ||
| 146 | |||
| 147 | /* In contrast to what's described in the datasheet, there seems | ||
| 148 | * to be no way of probing the presence of that device using I2C | ||
| 149 | * commands. So we need to blindly believe it is there, and wait | ||
| 150 | * for interrupts to occur. */ | ||
| 151 | |||
| 152 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 153 | if (!priv) { | ||
| 154 | dev_err(&client->dev, "failed to allocate driver data\n"); | ||
| 155 | goto err0; | ||
| 156 | } | ||
| 157 | |||
| 158 | mutex_init(&priv->mutex); | ||
| 159 | input = input_allocate_device(); | ||
| 160 | |||
| 161 | if (!input) { | ||
| 162 | dev_err(&client->dev, "Failed to allocate input device.\n"); | ||
| 163 | goto err1; | ||
| 164 | } | ||
| 165 | |||
| 166 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
| 167 | input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
| 168 | |||
| 169 | input_set_abs_params(input, ABS_X, 0, EETI_MAXVAL, 0, 0); | ||
| 170 | input_set_abs_params(input, ABS_Y, 0, EETI_MAXVAL, 0, 0); | ||
| 171 | input_set_abs_params(input, ABS_PRESSURE, 0, 0xff, 0, 0); | ||
| 172 | |||
| 173 | input->name = client->name; | ||
| 174 | input->id.bustype = BUS_I2C; | ||
| 175 | input->dev.parent = &client->dev; | ||
| 176 | input->open = eeti_ts_open; | ||
| 177 | input->close = eeti_ts_close; | ||
| 178 | |||
| 179 | priv->client = client; | ||
| 180 | priv->input = input; | ||
| 181 | priv->irq = client->irq; | ||
| 182 | |||
| 183 | INIT_WORK(&priv->work, eeti_ts_read); | ||
| 184 | i2c_set_clientdata(client, priv); | ||
| 185 | input_set_drvdata(input, priv); | ||
| 186 | |||
| 187 | err = input_register_device(input); | ||
| 188 | if (err) | ||
| 189 | goto err1; | ||
| 190 | |||
| 191 | err = request_irq(priv->irq, eeti_ts_isr, IRQF_TRIGGER_FALLING, | ||
| 192 | client->name, priv); | ||
| 193 | if (err) { | ||
| 194 | dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); | ||
| 195 | goto err2; | ||
| 196 | } | ||
| 197 | |||
| 198 | /* Disable the irq for now. It will be enabled once the input device | ||
| 199 | * is opened. */ | ||
| 200 | disable_irq(priv->irq); | ||
| 201 | |||
| 202 | device_init_wakeup(&client->dev, 0); | ||
| 203 | return 0; | ||
| 204 | |||
| 205 | err2: | ||
| 206 | input_unregister_device(input); | ||
| 207 | input = NULL; /* so we dont try to free it below */ | ||
| 208 | err1: | ||
| 209 | input_free_device(input); | ||
| 210 | i2c_set_clientdata(client, NULL); | ||
| 211 | kfree(priv); | ||
| 212 | err0: | ||
| 213 | return err; | ||
| 214 | } | ||
| 215 | |||
| 216 | static int __devexit eeti_ts_remove(struct i2c_client *client) | ||
| 217 | { | ||
| 218 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | ||
| 219 | |||
| 220 | free_irq(priv->irq, priv); | ||
| 221 | input_unregister_device(priv->input); | ||
| 222 | i2c_set_clientdata(client, NULL); | ||
| 223 | kfree(priv); | ||
| 224 | |||
| 225 | return 0; | ||
| 226 | } | ||
| 227 | |||
| 228 | #ifdef CONFIG_PM | ||
| 229 | static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg) | ||
| 230 | { | ||
| 231 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | ||
| 232 | |||
| 233 | if (device_may_wakeup(&client->dev)) | ||
| 234 | enable_irq_wake(priv->irq); | ||
| 235 | |||
| 236 | return 0; | ||
| 237 | } | ||
| 238 | |||
| 239 | static int eeti_ts_resume(struct i2c_client *client) | ||
| 240 | { | ||
| 241 | struct eeti_ts_priv *priv = i2c_get_clientdata(client); | ||
| 242 | |||
| 243 | if (device_may_wakeup(&client->dev)) | ||
| 244 | disable_irq_wake(priv->irq); | ||
| 245 | |||
| 246 | return 0; | ||
| 247 | } | ||
| 248 | #else | ||
| 249 | #define eeti_ts_suspend NULL | ||
| 250 | #define eeti_ts_resume NULL | ||
| 251 | #endif | ||
| 252 | |||
| 253 | static const struct i2c_device_id eeti_ts_id[] = { | ||
| 254 | { "eeti_ts", 0 }, | ||
| 255 | { } | ||
| 256 | }; | ||
| 257 | MODULE_DEVICE_TABLE(i2c, eeti_ts_id); | ||
| 258 | |||
| 259 | static struct i2c_driver eeti_ts_driver = { | ||
| 260 | .driver = { | ||
| 261 | .name = "eeti_ts", | ||
| 262 | }, | ||
| 263 | .probe = eeti_ts_probe, | ||
| 264 | .remove = __devexit_p(eeti_ts_remove), | ||
| 265 | .suspend = eeti_ts_suspend, | ||
| 266 | .resume = eeti_ts_resume, | ||
| 267 | .id_table = eeti_ts_id, | ||
| 268 | }; | ||
| 269 | |||
| 270 | static int __init eeti_ts_init(void) | ||
| 271 | { | ||
| 272 | return i2c_add_driver(&eeti_ts_driver); | ||
| 273 | } | ||
| 274 | |||
| 275 | static void __exit eeti_ts_exit(void) | ||
| 276 | { | ||
| 277 | i2c_del_driver(&eeti_ts_driver); | ||
| 278 | } | ||
| 279 | |||
| 280 | MODULE_DESCRIPTION("EETI Touchscreen driver"); | ||
| 281 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | ||
| 282 | MODULE_LICENSE("GPL"); | ||
| 283 | |||
| 284 | module_init(eeti_ts_init); | ||
| 285 | module_exit(eeti_ts_exit); | ||
| 286 | |||
diff --git a/drivers/input/touchscreen/tsc2007.c b/drivers/input/touchscreen/tsc2007.c index 948e167557f1..880f58c6a7c4 100644 --- a/drivers/input/touchscreen/tsc2007.c +++ b/drivers/input/touchscreen/tsc2007.c | |||
| @@ -257,7 +257,7 @@ static int tsc2007_probe(struct i2c_client *client, | |||
| 257 | struct input_dev *input_dev; | 257 | struct input_dev *input_dev; |
| 258 | int err; | 258 | int err; |
| 259 | 259 | ||
| 260 | if (!pdata) { | 260 | if (!pdata || !pdata->get_pendown_state) { |
| 261 | dev_err(&client->dev, "platform data is required!\n"); | 261 | dev_err(&client->dev, "platform data is required!\n"); |
| 262 | return -EINVAL; | 262 | return -EINVAL; |
| 263 | } | 263 | } |
diff --git a/drivers/input/touchscreen/w90p910_ts.c b/drivers/input/touchscreen/w90p910_ts.c new file mode 100644 index 000000000000..6071f5882572 --- /dev/null +++ b/drivers/input/touchscreen/w90p910_ts.c | |||
| @@ -0,0 +1,350 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2008 Nuvoton technology corporation. | ||
| 3 | * | ||
| 4 | * Wan ZongShun <mcuos.com@gmail.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation;version 2 of the License. | ||
| 9 | * | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/delay.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/platform_device.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | #include <linux/input.h> | ||
| 17 | #include <linux/interrupt.h> | ||
| 18 | |||
| 19 | /* ADC controller bit defines */ | ||
| 20 | #define ADC_DELAY 0xf00 | ||
| 21 | #define ADC_DOWN 0x01 | ||
| 22 | #define ADC_TSC_Y (0x01 << 8) | ||
| 23 | #define ADC_TSC_X (0x00 << 8) | ||
| 24 | #define TSC_FOURWIRE (~(0x03 << 1)) | ||
| 25 | #define ADC_CLK_EN (0x01 << 28) /* ADC clock enable */ | ||
| 26 | #define ADC_READ_CON (0x01 << 12) | ||
| 27 | #define ADC_CONV (0x01 << 13) | ||
| 28 | #define ADC_SEMIAUTO (0x01 << 14) | ||
| 29 | #define ADC_WAITTRIG (0x03 << 14) | ||
| 30 | #define ADC_RST1 (0x01 << 16) | ||
| 31 | #define ADC_RST0 (0x00 << 16) | ||
| 32 | #define ADC_EN (0x01 << 17) | ||
| 33 | #define ADC_INT (0x01 << 18) | ||
| 34 | #define WT_INT (0x01 << 20) | ||
| 35 | #define ADC_INT_EN (0x01 << 21) | ||
| 36 | #define LVD_INT_EN (0x01 << 22) | ||
| 37 | #define WT_INT_EN (0x01 << 23) | ||
| 38 | #define ADC_DIV (0x04 << 1) /* div = 6 */ | ||
| 39 | |||
| 40 | enum ts_state { | ||
| 41 | TS_WAIT_NEW_PACKET, /* We are waiting next touch report */ | ||
| 42 | TS_WAIT_X_COORD, /* We are waiting for ADC to report X coord */ | ||
| 43 | TS_WAIT_Y_COORD, /* We are waiting for ADC to report Y coord */ | ||
| 44 | TS_IDLE, /* Input device is closed, don't do anything */ | ||
| 45 | }; | ||
| 46 | |||
| 47 | struct w90p910_ts { | ||
| 48 | struct input_dev *input; | ||
| 49 | struct timer_list timer; | ||
| 50 | int irq_num; | ||
| 51 | void __iomem *clocken; | ||
| 52 | void __iomem *ts_reg; | ||
| 53 | spinlock_t lock; | ||
| 54 | enum ts_state state; | ||
| 55 | }; | ||
| 56 | |||
| 57 | static void w90p910_report_event(struct w90p910_ts *w90p910_ts, bool down) | ||
| 58 | { | ||
| 59 | struct input_dev *dev = w90p910_ts->input; | ||
| 60 | |||
| 61 | if (down) { | ||
| 62 | input_report_abs(dev, ABS_X, | ||
| 63 | __raw_readl(w90p910_ts->ts_reg + 0x0c)); | ||
| 64 | input_report_abs(dev, ABS_Y, | ||
| 65 | __raw_readl(w90p910_ts->ts_reg + 0x10)); | ||
| 66 | } | ||
| 67 | |||
| 68 | input_report_key(dev, BTN_TOUCH, down); | ||
| 69 | input_sync(dev); | ||
| 70 | } | ||
| 71 | |||
| 72 | static void w90p910_prepare_x_reading(struct w90p910_ts *w90p910_ts) | ||
| 73 | { | ||
| 74 | unsigned long ctlreg; | ||
| 75 | |||
| 76 | __raw_writel(ADC_TSC_X, w90p910_ts->ts_reg + 0x04); | ||
| 77 | ctlreg = __raw_readl(w90p910_ts->ts_reg); | ||
| 78 | ctlreg &= ~(ADC_WAITTRIG | WT_INT | WT_INT_EN); | ||
| 79 | ctlreg |= ADC_SEMIAUTO | ADC_INT_EN | ADC_CONV; | ||
| 80 | __raw_writel(ctlreg, w90p910_ts->ts_reg); | ||
| 81 | |||
| 82 | w90p910_ts->state = TS_WAIT_X_COORD; | ||
| 83 | } | ||
| 84 | |||
| 85 | static void w90p910_prepare_y_reading(struct w90p910_ts *w90p910_ts) | ||
| 86 | { | ||
| 87 | unsigned long ctlreg; | ||
| 88 | |||
| 89 | __raw_writel(ADC_TSC_Y, w90p910_ts->ts_reg + 0x04); | ||
| 90 | ctlreg = __raw_readl(w90p910_ts->ts_reg); | ||
| 91 | ctlreg &= ~(ADC_WAITTRIG | ADC_INT | WT_INT_EN); | ||
| 92 | ctlreg |= ADC_SEMIAUTO | ADC_INT_EN | ADC_CONV; | ||
| 93 | __raw_writel(ctlreg, w90p910_ts->ts_reg); | ||
| 94 | |||
| 95 | w90p910_ts->state = TS_WAIT_Y_COORD; | ||
| 96 | } | ||
| 97 | |||
| 98 | static void w90p910_prepare_next_packet(struct w90p910_ts *w90p910_ts) | ||
| 99 | { | ||
| 100 | unsigned long ctlreg; | ||
| 101 | |||
| 102 | ctlreg = __raw_readl(w90p910_ts->ts_reg); | ||
| 103 | ctlreg &= ~(ADC_INT | ADC_INT_EN | ADC_SEMIAUTO | ADC_CONV); | ||
| 104 | ctlreg |= ADC_WAITTRIG | WT_INT_EN; | ||
| 105 | __raw_writel(ctlreg, w90p910_ts->ts_reg); | ||
| 106 | |||
| 107 | w90p910_ts->state = TS_WAIT_NEW_PACKET; | ||
| 108 | } | ||
| 109 | |||
| 110 | static irqreturn_t w90p910_ts_interrupt(int irq, void *dev_id) | ||
| 111 | { | ||
| 112 | struct w90p910_ts *w90p910_ts = dev_id; | ||
| 113 | unsigned long flags; | ||
| 114 | |||
| 115 | spin_lock_irqsave(&w90p910_ts->lock, flags); | ||
| 116 | |||
| 117 | switch (w90p910_ts->state) { | ||
| 118 | case TS_WAIT_NEW_PACKET: | ||
| 119 | /* | ||
| 120 | * The controller only generates interrupts when pen | ||
| 121 | * is down. | ||
| 122 | */ | ||
| 123 | del_timer(&w90p910_ts->timer); | ||
| 124 | w90p910_prepare_x_reading(w90p910_ts); | ||
| 125 | break; | ||
| 126 | |||
| 127 | |||
| 128 | case TS_WAIT_X_COORD: | ||
| 129 | w90p910_prepare_y_reading(w90p910_ts); | ||
| 130 | break; | ||
| 131 | |||
| 132 | case TS_WAIT_Y_COORD: | ||
| 133 | w90p910_report_event(w90p910_ts, true); | ||
| 134 | w90p910_prepare_next_packet(w90p910_ts); | ||
| 135 | mod_timer(&w90p910_ts->timer, jiffies + msecs_to_jiffies(100)); | ||
| 136 | break; | ||
| 137 | |||
| 138 | case TS_IDLE: | ||
| 139 | break; | ||
| 140 | } | ||
| 141 | |||
| 142 | spin_unlock_irqrestore(&w90p910_ts->lock, flags); | ||
| 143 | |||
| 144 | return IRQ_HANDLED; | ||
| 145 | } | ||
| 146 | |||
| 147 | static void w90p910_check_pen_up(unsigned long data) | ||
| 148 | { | ||
| 149 | struct w90p910_ts *w90p910_ts = (struct w90p910_ts *) data; | ||
| 150 | unsigned long flags; | ||
| 151 | |||
| 152 | spin_lock_irqsave(&w90p910_ts->lock, flags); | ||
| 153 | |||
| 154 | if (w90p910_ts->state == TS_WAIT_NEW_PACKET && | ||
| 155 | !(__raw_readl(w90p910_ts->ts_reg + 0x04) & ADC_DOWN)) { | ||
| 156 | |||
| 157 | w90p910_report_event(w90p910_ts, false); | ||
| 158 | } | ||
| 159 | |||
| 160 | spin_unlock_irqrestore(&w90p910_ts->lock, flags); | ||
| 161 | } | ||
| 162 | |||
| 163 | static int w90p910_open(struct input_dev *dev) | ||
| 164 | { | ||
| 165 | struct w90p910_ts *w90p910_ts = input_get_drvdata(dev); | ||
| 166 | unsigned long val; | ||
| 167 | |||
| 168 | /* enable the ADC clock */ | ||
| 169 | val = __raw_readl(w90p910_ts->clocken); | ||
| 170 | __raw_writel(val | ADC_CLK_EN, w90p910_ts->clocken); | ||
| 171 | |||
| 172 | __raw_writel(ADC_RST1, w90p910_ts->ts_reg); | ||
| 173 | msleep(1); | ||
| 174 | __raw_writel(ADC_RST0, w90p910_ts->ts_reg); | ||
| 175 | msleep(1); | ||
| 176 | |||
| 177 | /* set delay and screen type */ | ||
| 178 | val = __raw_readl(w90p910_ts->ts_reg + 0x04); | ||
| 179 | __raw_writel(val & TSC_FOURWIRE, w90p910_ts->ts_reg + 0x04); | ||
| 180 | __raw_writel(ADC_DELAY, w90p910_ts->ts_reg + 0x08); | ||
| 181 | |||
| 182 | w90p910_ts->state = TS_WAIT_NEW_PACKET; | ||
| 183 | wmb(); | ||
| 184 | |||
| 185 | /* set trigger mode */ | ||
| 186 | val = __raw_readl(w90p910_ts->ts_reg); | ||
| 187 | val |= ADC_WAITTRIG | ADC_DIV | ADC_EN | WT_INT_EN; | ||
| 188 | __raw_writel(val, w90p910_ts->ts_reg); | ||
| 189 | |||
| 190 | return 0; | ||
| 191 | } | ||
| 192 | |||
| 193 | static void w90p910_close(struct input_dev *dev) | ||
| 194 | { | ||
| 195 | struct w90p910_ts *w90p910_ts = input_get_drvdata(dev); | ||
| 196 | unsigned long val; | ||
| 197 | |||
| 198 | /* disable trigger mode */ | ||
| 199 | |||
| 200 | spin_lock_irq(&w90p910_ts->lock); | ||
| 201 | |||
| 202 | w90p910_ts->state = TS_IDLE; | ||
| 203 | |||
| 204 | val = __raw_readl(w90p910_ts->ts_reg); | ||
| 205 | val &= ~(ADC_WAITTRIG | ADC_DIV | ADC_EN | WT_INT_EN | ADC_INT_EN); | ||
| 206 | __raw_writel(val, w90p910_ts->ts_reg); | ||
| 207 | |||
| 208 | spin_unlock_irq(&w90p910_ts->lock); | ||
| 209 | |||
| 210 | /* Now that interrupts are shut off we can safely delete timer */ | ||
| 211 | del_timer_sync(&w90p910_ts->timer); | ||
| 212 | |||
| 213 | /* stop the ADC clock */ | ||
| 214 | val = __raw_readl(w90p910_ts->clocken); | ||
| 215 | __raw_writel(val & ~ADC_CLK_EN, w90p910_ts->clocken); | ||
| 216 | } | ||
| 217 | |||
| 218 | static int __devinit w90x900ts_probe(struct platform_device *pdev) | ||
| 219 | { | ||
| 220 | struct w90p910_ts *w90p910_ts; | ||
| 221 | struct input_dev *input_dev; | ||
| 222 | struct resource *res; | ||
| 223 | int err; | ||
| 224 | |||
| 225 | w90p910_ts = kzalloc(sizeof(struct w90p910_ts), GFP_KERNEL); | ||
| 226 | input_dev = input_allocate_device(); | ||
| 227 | if (!w90p910_ts || !input_dev) { | ||
| 228 | err = -ENOMEM; | ||
| 229 | goto fail1; | ||
| 230 | } | ||
| 231 | |||
| 232 | w90p910_ts->input = input_dev; | ||
| 233 | w90p910_ts->state = TS_IDLE; | ||
| 234 | spin_lock_init(&w90p910_ts->lock); | ||
| 235 | setup_timer(&w90p910_ts->timer, w90p910_check_pen_up, | ||
| 236 | (unsigned long)&w90p910_ts); | ||
| 237 | |||
| 238 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 239 | if (!res) { | ||
| 240 | err = -ENXIO; | ||
| 241 | goto fail1; | ||
| 242 | } | ||
| 243 | |||
| 244 | if (!request_mem_region(res->start, res->end - res->start + 1, | ||
| 245 | pdev->name)) { | ||
| 246 | err = -EBUSY; | ||
| 247 | goto fail1; | ||
| 248 | } | ||
| 249 | |||
| 250 | w90p910_ts->ts_reg = ioremap(res->start, res->end - res->start + 1); | ||
| 251 | if (!w90p910_ts->ts_reg) { | ||
| 252 | err = -ENOMEM; | ||
| 253 | goto fail2; | ||
| 254 | } | ||
| 255 | |||
| 256 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 257 | if (!res) { | ||
| 258 | err = -ENXIO; | ||
| 259 | goto fail3; | ||
| 260 | } | ||
| 261 | |||
| 262 | w90p910_ts->clocken = (void __iomem *)res->start; | ||
| 263 | |||
| 264 | input_dev->name = "W90P910 TouchScreen"; | ||
| 265 | input_dev->phys = "w90p910ts/event0"; | ||
| 266 | input_dev->id.bustype = BUS_HOST; | ||
| 267 | input_dev->id.vendor = 0x0005; | ||
| 268 | input_dev->id.product = 0x0001; | ||
| 269 | input_dev->id.version = 0x0100; | ||
| 270 | input_dev->dev.parent = &pdev->dev; | ||
| 271 | input_dev->open = w90p910_open; | ||
| 272 | input_dev->close = w90p910_close; | ||
| 273 | |||
| 274 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
| 275 | input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); | ||
| 276 | |||
| 277 | input_set_abs_params(input_dev, ABS_X, 0, 0x400, 0, 0); | ||
| 278 | input_set_abs_params(input_dev, ABS_Y, 0, 0x400, 0, 0); | ||
| 279 | |||
| 280 | input_set_drvdata(input_dev, w90p910_ts); | ||
| 281 | |||
| 282 | w90p910_ts->irq_num = platform_get_irq(pdev, 0); | ||
| 283 | if (request_irq(w90p910_ts->irq_num, w90p910_ts_interrupt, | ||
| 284 | IRQF_DISABLED, "w90p910ts", w90p910_ts)) { | ||
| 285 | err = -EBUSY; | ||
| 286 | goto fail3; | ||
| 287 | } | ||
| 288 | |||
| 289 | err = input_register_device(w90p910_ts->input); | ||
| 290 | if (err) | ||
| 291 | goto fail4; | ||
| 292 | |||
| 293 | platform_set_drvdata(pdev, w90p910_ts); | ||
| 294 | |||
| 295 | return 0; | ||
| 296 | |||
| 297 | fail4: free_irq(w90p910_ts->irq_num, w90p910_ts); | ||
| 298 | fail3: iounmap(w90p910_ts->ts_reg); | ||
| 299 | fail2: release_mem_region(res->start, res->end - res->start + 1); | ||
| 300 | fail1: input_free_device(input_dev); | ||
| 301 | kfree(w90p910_ts); | ||
| 302 | return err; | ||
| 303 | } | ||
| 304 | |||
| 305 | static int __devexit w90x900ts_remove(struct platform_device *pdev) | ||
| 306 | { | ||
| 307 | struct w90p910_ts *w90p910_ts = platform_get_drvdata(pdev); | ||
| 308 | struct resource *res; | ||
| 309 | |||
| 310 | free_irq(w90p910_ts->irq_num, w90p910_ts); | ||
| 311 | del_timer_sync(&w90p910_ts->timer); | ||
| 312 | iounmap(w90p910_ts->ts_reg); | ||
| 313 | |||
| 314 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 315 | release_mem_region(res->start, res->end - res->start + 1); | ||
| 316 | |||
| 317 | input_unregister_device(w90p910_ts->input); | ||
| 318 | kfree(w90p910_ts); | ||
| 319 | |||
| 320 | platform_set_drvdata(pdev, NULL); | ||
| 321 | |||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | static struct platform_driver w90x900ts_driver = { | ||
| 326 | .probe = w90x900ts_probe, | ||
| 327 | .remove = __devexit_p(w90x900ts_remove), | ||
| 328 | .driver = { | ||
| 329 | .name = "w90x900-ts", | ||
| 330 | .owner = THIS_MODULE, | ||
| 331 | }, | ||
| 332 | }; | ||
| 333 | |||
| 334 | static int __init w90x900ts_init(void) | ||
| 335 | { | ||
| 336 | return platform_driver_register(&w90x900ts_driver); | ||
| 337 | } | ||
| 338 | |||
| 339 | static void __exit w90x900ts_exit(void) | ||
| 340 | { | ||
| 341 | platform_driver_unregister(&w90x900ts_driver); | ||
| 342 | } | ||
| 343 | |||
| 344 | module_init(w90x900ts_init); | ||
| 345 | module_exit(w90x900ts_exit); | ||
| 346 | |||
| 347 | MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>"); | ||
| 348 | MODULE_DESCRIPTION("w90p910 touch screen driver!"); | ||
| 349 | MODULE_LICENSE("GPL"); | ||
| 350 | MODULE_ALIAS("platform:w90p910-ts"); | ||
diff --git a/drivers/mfd/ucb1400_core.c b/drivers/mfd/ucb1400_core.c index 178159e264ce..78c2135c5de6 100644 --- a/drivers/mfd/ucb1400_core.c +++ b/drivers/mfd/ucb1400_core.c | |||
| @@ -23,6 +23,26 @@ | |||
| 23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
| 24 | #include <linux/ucb1400.h> | 24 | #include <linux/ucb1400.h> |
| 25 | 25 | ||
| 26 | unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, | ||
| 27 | int adcsync) | ||
| 28 | { | ||
| 29 | unsigned int val; | ||
| 30 | |||
| 31 | if (adcsync) | ||
| 32 | adc_channel |= UCB_ADC_SYNC_ENA; | ||
| 33 | |||
| 34 | ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel); | ||
| 35 | ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel | | ||
| 36 | UCB_ADC_START); | ||
| 37 | |||
| 38 | while (!((val = ucb1400_reg_read(ac97, UCB_ADC_DATA)) | ||
| 39 | & UCB_ADC_DAT_VALID)) | ||
| 40 | schedule_timeout_uninterruptible(1); | ||
| 41 | |||
| 42 | return val & UCB_ADC_DAT_MASK; | ||
| 43 | } | ||
| 44 | EXPORT_SYMBOL_GPL(ucb1400_adc_read); | ||
| 45 | |||
| 26 | static int ucb1400_core_probe(struct device *dev) | 46 | static int ucb1400_core_probe(struct device *dev) |
| 27 | { | 47 | { |
| 28 | int err; | 48 | int err; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 304b411cb8bc..8970d8c49bb0 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
| @@ -966,7 +966,7 @@ static int parse_options(char *options, int is_vfat, int silent, int *debug, | |||
| 966 | 966 | ||
| 967 | opts->fs_uid = current_uid(); | 967 | opts->fs_uid = current_uid(); |
| 968 | opts->fs_gid = current_gid(); | 968 | opts->fs_gid = current_gid(); |
| 969 | opts->fs_fmask = current_umask(); | 969 | opts->fs_fmask = opts->fs_dmask = current_umask(); |
| 970 | opts->allow_utime = -1; | 970 | opts->allow_utime = -1; |
| 971 | opts->codepage = fat_default_codepage; | 971 | opts->codepage = fat_default_codepage; |
| 972 | opts->iocharset = fat_default_iocharset; | 972 | opts->iocharset = fat_default_iocharset; |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d4ddc22e46bb..45b67d9c39c1 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -34,9 +34,6 @@ | |||
| 34 | #ifndef _DRM_P_H_ | 34 | #ifndef _DRM_P_H_ |
| 35 | #define _DRM_P_H_ | 35 | #define _DRM_P_H_ |
| 36 | 36 | ||
| 37 | /* If you want the memory alloc debug functionality, change define below */ | ||
| 38 | /* #define DEBUG_MEMORY */ | ||
| 39 | |||
| 40 | #ifdef __KERNEL__ | 37 | #ifdef __KERNEL__ |
| 41 | #ifdef __alpha__ | 38 | #ifdef __alpha__ |
| 42 | /* add include of current.h so that "current" is defined | 39 | /* add include of current.h so that "current" is defined |
| @@ -133,31 +130,6 @@ extern void drm_ut_debug_printk(unsigned int request_level, | |||
| 133 | 130 | ||
| 134 | #define DRM_FLAG_DEBUG 0x01 | 131 | #define DRM_FLAG_DEBUG 0x01 |
| 135 | 132 | ||
| 136 | #define DRM_MEM_DMA 0 | ||
| 137 | #define DRM_MEM_SAREA 1 | ||
| 138 | #define DRM_MEM_DRIVER 2 | ||
| 139 | #define DRM_MEM_MAGIC 3 | ||
| 140 | #define DRM_MEM_IOCTLS 4 | ||
| 141 | #define DRM_MEM_MAPS 5 | ||
| 142 | #define DRM_MEM_VMAS 6 | ||
| 143 | #define DRM_MEM_BUFS 7 | ||
| 144 | #define DRM_MEM_SEGS 8 | ||
| 145 | #define DRM_MEM_PAGES 9 | ||
| 146 | #define DRM_MEM_FILES 10 | ||
| 147 | #define DRM_MEM_QUEUES 11 | ||
| 148 | #define DRM_MEM_CMDS 12 | ||
| 149 | #define DRM_MEM_MAPPINGS 13 | ||
| 150 | #define DRM_MEM_BUFLISTS 14 | ||
| 151 | #define DRM_MEM_AGPLISTS 15 | ||
| 152 | #define DRM_MEM_TOTALAGP 16 | ||
| 153 | #define DRM_MEM_BOUNDAGP 17 | ||
| 154 | #define DRM_MEM_CTXBITMAP 18 | ||
| 155 | #define DRM_MEM_STUB 19 | ||
| 156 | #define DRM_MEM_SGLISTS 20 | ||
| 157 | #define DRM_MEM_CTXLIST 21 | ||
| 158 | #define DRM_MEM_MM 22 | ||
| 159 | #define DRM_MEM_HASHTAB 23 | ||
| 160 | |||
| 161 | #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) | 133 | #define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8) |
| 162 | #define DRM_MAP_HASH_OFFSET 0x10000000 | 134 | #define DRM_MAP_HASH_OFFSET 0x10000000 |
| 163 | 135 | ||
| @@ -1517,24 +1489,6 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map) | |||
| 1517 | { | 1489 | { |
| 1518 | } | 1490 | } |
| 1519 | 1491 | ||
| 1520 | #ifndef DEBUG_MEMORY | ||
| 1521 | /** Wrapper around kmalloc() */ | ||
| 1522 | static __inline__ void *drm_alloc(size_t size, int area) | ||
| 1523 | { | ||
| 1524 | return kmalloc(size, GFP_KERNEL); | ||
| 1525 | } | ||
| 1526 | |||
| 1527 | /** Wrapper around kfree() */ | ||
| 1528 | static __inline__ void drm_free(void *pt, size_t size, int area) | ||
| 1529 | { | ||
| 1530 | kfree(pt); | ||
| 1531 | } | ||
| 1532 | |||
| 1533 | /** Wrapper around kcalloc() */ | ||
| 1534 | static __inline__ void *drm_calloc(size_t nmemb, size_t size, int area) | ||
| 1535 | { | ||
| 1536 | return kcalloc(nmemb, size, GFP_KERNEL); | ||
| 1537 | } | ||
| 1538 | 1492 | ||
| 1539 | static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) | 1493 | static __inline__ void *drm_calloc_large(size_t nmemb, size_t size) |
| 1540 | { | 1494 | { |
| @@ -1555,12 +1509,6 @@ static __inline void drm_free_large(void *ptr) | |||
| 1555 | 1509 | ||
| 1556 | vfree(ptr); | 1510 | vfree(ptr); |
| 1557 | } | 1511 | } |
| 1558 | #else | ||
| 1559 | extern void *drm_alloc(size_t size, int area); | ||
| 1560 | extern void drm_free(void *pt, size_t size, int area); | ||
| 1561 | extern void *drm_calloc(size_t nmemb, size_t size, int area); | ||
| 1562 | #endif | ||
| 1563 | |||
| 1564 | /*@}*/ | 1512 | /*@}*/ |
| 1565 | 1513 | ||
| 1566 | #endif /* __KERNEL__ */ | 1514 | #endif /* __KERNEL__ */ |
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h index a11cc9d32591..c263e4d71754 100644 --- a/include/drm/drm_edid.h +++ b/include/drm/drm_edid.h | |||
| @@ -28,53 +28,49 @@ | |||
| 28 | #define EDID_LENGTH 128 | 28 | #define EDID_LENGTH 128 |
| 29 | #define DDC_ADDR 0x50 | 29 | #define DDC_ADDR 0x50 |
| 30 | 30 | ||
| 31 | #ifdef BIG_ENDIAN | ||
| 32 | #error "EDID structure is little endian, need big endian versions" | ||
| 33 | #else | ||
| 34 | |||
| 35 | struct est_timings { | 31 | struct est_timings { |
| 36 | u8 t1; | 32 | u8 t1; |
| 37 | u8 t2; | 33 | u8 t2; |
| 38 | u8 mfg_rsvd; | 34 | u8 mfg_rsvd; |
| 39 | } __attribute__((packed)); | 35 | } __attribute__((packed)); |
| 40 | 36 | ||
| 37 | /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ | ||
| 38 | #define EDID_TIMING_ASPECT_SHIFT 0 | ||
| 39 | #define EDID_TIMING_ASPECT_MASK (0x3 << EDID_TIMING_ASPECT_SHIFT) | ||
| 40 | |||
| 41 | /* need to add 60 */ | ||
| 42 | #define EDID_TIMING_VFREQ_SHIFT 2 | ||
| 43 | #define EDID_TIMING_VFREQ_MASK (0x3f << EDID_TIMING_VFREQ_SHIFT) | ||
| 44 | |||
| 41 | struct std_timing { | 45 | struct std_timing { |
| 42 | u8 hsize; /* need to multiply by 8 then add 248 */ | 46 | u8 hsize; /* need to multiply by 8 then add 248 */ |
| 43 | u8 vfreq:6; /* need to add 60 */ | 47 | u8 vfreq_aspect; |
| 44 | u8 aspect_ratio:2; /* 00=16:10, 01=4:3, 10=5:4, 11=16:9 */ | ||
| 45 | } __attribute__((packed)); | 48 | } __attribute__((packed)); |
| 46 | 49 | ||
| 50 | #define DRM_EDID_PT_HSYNC_POSITIVE (1 << 6) | ||
| 51 | #define DRM_EDID_PT_VSYNC_POSITIVE (1 << 5) | ||
| 52 | #define DRM_EDID_PT_SEPARATE_SYNC (3 << 3) | ||
| 53 | #define DRM_EDID_PT_STEREO (1 << 2) | ||
| 54 | #define DRM_EDID_PT_INTERLACED (1 << 1) | ||
| 55 | |||
| 47 | /* If detailed data is pixel timing */ | 56 | /* If detailed data is pixel timing */ |
| 48 | struct detailed_pixel_timing { | 57 | struct detailed_pixel_timing { |
| 49 | u8 hactive_lo; | 58 | u8 hactive_lo; |
| 50 | u8 hblank_lo; | 59 | u8 hblank_lo; |
| 51 | u8 hblank_hi:4; | 60 | u8 hactive_hblank_hi; |
| 52 | u8 hactive_hi:4; | ||
| 53 | u8 vactive_lo; | 61 | u8 vactive_lo; |
| 54 | u8 vblank_lo; | 62 | u8 vblank_lo; |
| 55 | u8 vblank_hi:4; | 63 | u8 vactive_vblank_hi; |
| 56 | u8 vactive_hi:4; | ||
| 57 | u8 hsync_offset_lo; | 64 | u8 hsync_offset_lo; |
| 58 | u8 hsync_pulse_width_lo; | 65 | u8 hsync_pulse_width_lo; |
| 59 | u8 vsync_pulse_width_lo:4; | 66 | u8 vsync_offset_pulse_width_lo; |
| 60 | u8 vsync_offset_lo:4; | 67 | u8 hsync_vsync_offset_pulse_width_hi; |
| 61 | u8 vsync_pulse_width_hi:2; | ||
| 62 | u8 vsync_offset_hi:2; | ||
| 63 | u8 hsync_pulse_width_hi:2; | ||
| 64 | u8 hsync_offset_hi:2; | ||
| 65 | u8 width_mm_lo; | 68 | u8 width_mm_lo; |
| 66 | u8 height_mm_lo; | 69 | u8 height_mm_lo; |
| 67 | u8 height_mm_hi:4; | 70 | u8 width_height_mm_hi; |
| 68 | u8 width_mm_hi:4; | ||
| 69 | u8 hborder; | 71 | u8 hborder; |
| 70 | u8 vborder; | 72 | u8 vborder; |
| 71 | u8 unknown0:1; | 73 | u8 misc; |
| 72 | u8 hsync_positive:1; | ||
| 73 | u8 vsync_positive:1; | ||
| 74 | u8 separate_sync:2; | ||
| 75 | u8 stereo:1; | ||
| 76 | u8 unknown6:1; | ||
| 77 | u8 interlaced:1; | ||
| 78 | } __attribute__((packed)); | 74 | } __attribute__((packed)); |
| 79 | 75 | ||
| 80 | /* If it's not pixel timing, it'll be one of the below */ | 76 | /* If it's not pixel timing, it'll be one of the below */ |
| @@ -88,18 +84,16 @@ struct detailed_data_monitor_range { | |||
| 88 | u8 min_hfreq_khz; | 84 | u8 min_hfreq_khz; |
| 89 | u8 max_hfreq_khz; | 85 | u8 max_hfreq_khz; |
| 90 | u8 pixel_clock_mhz; /* need to multiply by 10 */ | 86 | u8 pixel_clock_mhz; /* need to multiply by 10 */ |
| 91 | u16 sec_gtf_toggle; /* A000=use above, 20=use below */ /* FIXME: byte order */ | 87 | __le16 sec_gtf_toggle; /* A000=use above, 20=use below */ |
| 92 | u8 hfreq_start_khz; /* need to multiply by 2 */ | 88 | u8 hfreq_start_khz; /* need to multiply by 2 */ |
| 93 | u8 c; /* need to divide by 2 */ | 89 | u8 c; /* need to divide by 2 */ |
| 94 | u16 m; /* FIXME: byte order */ | 90 | __le16 m; |
| 95 | u8 k; | 91 | u8 k; |
| 96 | u8 j; /* need to divide by 2 */ | 92 | u8 j; /* need to divide by 2 */ |
| 97 | } __attribute__((packed)); | 93 | } __attribute__((packed)); |
| 98 | 94 | ||
| 99 | struct detailed_data_wpindex { | 95 | struct detailed_data_wpindex { |
| 100 | u8 white_y_lo:2; | 96 | u8 white_xy_lo; /* Upper 2 bits each */ |
| 101 | u8 white_x_lo:2; | ||
| 102 | u8 pad:4; | ||
| 103 | u8 white_x_hi; | 97 | u8 white_x_hi; |
| 104 | u8 white_y_hi; | 98 | u8 white_y_hi; |
| 105 | u8 gamma; /* need to divide by 100 then add 1 */ | 99 | u8 gamma; /* need to divide by 100 then add 1 */ |
| @@ -134,13 +128,29 @@ struct detailed_non_pixel { | |||
| 134 | #define EDID_DETAIL_MONITOR_SERIAL 0xff | 128 | #define EDID_DETAIL_MONITOR_SERIAL 0xff |
| 135 | 129 | ||
| 136 | struct detailed_timing { | 130 | struct detailed_timing { |
| 137 | u16 pixel_clock; /* need to multiply by 10 KHz */ /* FIXME: byte order */ | 131 | __le16 pixel_clock; /* need to multiply by 10 KHz */ |
| 138 | union { | 132 | union { |
| 139 | struct detailed_pixel_timing pixel_data; | 133 | struct detailed_pixel_timing pixel_data; |
| 140 | struct detailed_non_pixel other_data; | 134 | struct detailed_non_pixel other_data; |
| 141 | } data; | 135 | } data; |
| 142 | } __attribute__((packed)); | 136 | } __attribute__((packed)); |
| 143 | 137 | ||
| 138 | #define DRM_EDID_INPUT_SERRATION_VSYNC (1 << 7) | ||
| 139 | #define DRM_EDID_INPUT_SYNC_ON_GREEN (1 << 5) | ||
| 140 | #define DRM_EDID_INPUT_COMPOSITE_SYNC (1 << 4) | ||
| 141 | #define DRM_EDID_INPUT_SEPARATE_SYNCS (1 << 3) | ||
| 142 | #define DRM_EDID_INPUT_BLANK_TO_BLACK (1 << 2) | ||
| 143 | #define DRM_EDID_INPUT_VIDEO_LEVEL (3 << 1) | ||
| 144 | #define DRM_EDID_INPUT_DIGITAL (1 << 0) /* bits above must be zero if set */ | ||
| 145 | |||
| 146 | #define DRM_EDID_FEATURE_DEFAULT_GTF (1 << 7) | ||
| 147 | #define DRM_EDID_FEATURE_PREFERRED_TIMING (1 << 6) | ||
| 148 | #define DRM_EDID_FEATURE_STANDARD_COLOR (1 << 5) | ||
| 149 | #define DRM_EDID_FEATURE_DISPLAY_TYPE (3 << 3) /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ | ||
| 150 | #define DRM_EDID_FEATURE_PM_ACTIVE_OFF (1 << 2) | ||
| 151 | #define DRM_EDID_FEATURE_PM_SUSPEND (1 << 1) | ||
| 152 | #define DRM_EDID_FEATURE_PM_STANDBY (1 << 0) | ||
| 153 | |||
| 144 | struct edid { | 154 | struct edid { |
| 145 | u8 header[8]; | 155 | u8 header[8]; |
| 146 | /* Vendor & product info */ | 156 | /* Vendor & product info */ |
| @@ -153,25 +163,11 @@ struct edid { | |||
| 153 | u8 version; | 163 | u8 version; |
| 154 | u8 revision; | 164 | u8 revision; |
| 155 | /* Display info: */ | 165 | /* Display info: */ |
| 156 | /* input definition */ | 166 | u8 input; |
| 157 | u8 serration_vsync:1; | ||
| 158 | u8 sync_on_green:1; | ||
| 159 | u8 composite_sync:1; | ||
| 160 | u8 separate_syncs:1; | ||
| 161 | u8 blank_to_black:1; | ||
| 162 | u8 video_level:2; | ||
| 163 | u8 digital:1; /* bits below must be zero if set */ | ||
| 164 | u8 width_cm; | 167 | u8 width_cm; |
| 165 | u8 height_cm; | 168 | u8 height_cm; |
| 166 | u8 gamma; | 169 | u8 gamma; |
| 167 | /* feature support */ | 170 | u8 features; |
| 168 | u8 default_gtf:1; | ||
| 169 | u8 preferred_timing:1; | ||
| 170 | u8 standard_color:1; | ||
| 171 | u8 display_type:2; /* 00=mono, 01=rgb, 10=non-rgb, 11=unknown */ | ||
| 172 | u8 pm_active_off:1; | ||
| 173 | u8 pm_suspend:1; | ||
| 174 | u8 pm_standby:1; | ||
| 175 | /* Color characteristics */ | 171 | /* Color characteristics */ |
| 176 | u8 red_green_lo; | 172 | u8 red_green_lo; |
| 177 | u8 black_white_lo; | 173 | u8 black_white_lo; |
| @@ -195,8 +191,6 @@ struct edid { | |||
| 195 | u8 checksum; | 191 | u8 checksum; |
| 196 | } __attribute__((packed)); | 192 | } __attribute__((packed)); |
| 197 | 193 | ||
| 198 | #endif /* little endian structs */ | ||
| 199 | |||
| 200 | #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) | 194 | #define EDID_PRODUCT_ID(e) ((e)->prod_code[0] | ((e)->prod_code[1] << 8)) |
| 201 | 195 | ||
| 202 | #endif /* __DRM_EDID_H__ */ | 196 | #endif /* __DRM_EDID_H__ */ |
diff --git a/include/drm/drm_memory_debug.h b/include/drm/drm_memory_debug.h deleted file mode 100644 index 6463271deea8..000000000000 --- a/include/drm/drm_memory_debug.h +++ /dev/null | |||
| @@ -1,309 +0,0 @@ | |||
| 1 | /** | ||
| 2 | * \file drm_memory_debug.h | ||
| 3 | * Memory management wrappers for DRM. | ||
| 4 | * | ||
| 5 | * \author Rickard E. (Rik) Faith <faith@valinux.com> | ||
| 6 | * \author Gareth Hughes <gareth@valinux.com> | ||
| 7 | */ | ||
| 8 | |||
| 9 | /* | ||
| 10 | * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | ||
| 11 | * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | ||
| 12 | * All Rights Reserved. | ||
| 13 | * | ||
| 14 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
| 15 | * copy of this software and associated documentation files (the "Software"), | ||
| 16 | * to deal in the Software without restriction, including without limitation | ||
| 17 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| 18 | * and/or sell copies of the Software, and to permit persons to whom the | ||
| 19 | * Software is furnished to do so, subject to the following conditions: | ||
| 20 | * | ||
| 21 | * The above copyright notice and this permission notice (including the next | ||
| 22 | * paragraph) shall be included in all copies or substantial portions of the | ||
| 23 | * Software. | ||
| 24 | * | ||
| 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 26 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 27 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| 28 | * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
| 29 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
| 30 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
| 31 | * OTHER DEALINGS IN THE SOFTWARE. | ||
| 32 | */ | ||
| 33 | |||
| 34 | #include "drmP.h" | ||
| 35 | |||
| 36 | typedef struct drm_mem_stats { | ||
| 37 | const char *name; | ||
| 38 | int succeed_count; | ||
| 39 | int free_count; | ||
| 40 | int fail_count; | ||
| 41 | unsigned long bytes_allocated; | ||
| 42 | unsigned long bytes_freed; | ||
| 43 | } drm_mem_stats_t; | ||
| 44 | |||
| 45 | static DEFINE_SPINLOCK(drm_mem_lock); | ||
| 46 | static unsigned long drm_ram_available = 0; /* In pages */ | ||
| 47 | static unsigned long drm_ram_used = 0; | ||
| 48 | static drm_mem_stats_t drm_mem_stats[] = | ||
| 49 | { | ||
| 50 | [DRM_MEM_DMA] = {"dmabufs"}, | ||
| 51 | [DRM_MEM_SAREA] = {"sareas"}, | ||
| 52 | [DRM_MEM_DRIVER] = {"driver"}, | ||
| 53 | [DRM_MEM_MAGIC] = {"magic"}, | ||
| 54 | [DRM_MEM_IOCTLS] = {"ioctltab"}, | ||
| 55 | [DRM_MEM_MAPS] = {"maplist"}, | ||
| 56 | [DRM_MEM_VMAS] = {"vmalist"}, | ||
| 57 | [DRM_MEM_BUFS] = {"buflist"}, | ||
| 58 | [DRM_MEM_SEGS] = {"seglist"}, | ||
| 59 | [DRM_MEM_PAGES] = {"pagelist"}, | ||
| 60 | [DRM_MEM_FILES] = {"files"}, | ||
| 61 | [DRM_MEM_QUEUES] = {"queues"}, | ||
| 62 | [DRM_MEM_CMDS] = {"commands"}, | ||
| 63 | [DRM_MEM_MAPPINGS] = {"mappings"}, | ||
| 64 | [DRM_MEM_BUFLISTS] = {"buflists"}, | ||
| 65 | [DRM_MEM_AGPLISTS] = {"agplist"}, | ||
| 66 | [DRM_MEM_SGLISTS] = {"sglist"}, | ||
| 67 | [DRM_MEM_TOTALAGP] = {"totalagp"}, | ||
| 68 | [DRM_MEM_BOUNDAGP] = {"boundagp"}, | ||
| 69 | [DRM_MEM_CTXBITMAP] = {"ctxbitmap"}, | ||
| 70 | [DRM_MEM_CTXLIST] = {"ctxlist"}, | ||
| 71 | [DRM_MEM_STUB] = {"stub"}, | ||
| 72 | {NULL, 0,} /* Last entry must be null */ | ||
| 73 | }; | ||
| 74 | |||
| 75 | void drm_mem_init (void) { | ||
| 76 | drm_mem_stats_t *mem; | ||
| 77 | struct sysinfo si; | ||
| 78 | |||
| 79 | for (mem = drm_mem_stats; mem->name; ++mem) { | ||
| 80 | mem->succeed_count = 0; | ||
| 81 | mem->free_count = 0; | ||
| 82 | mem->fail_count = 0; | ||
| 83 | mem->bytes_allocated = 0; | ||
| 84 | mem->bytes_freed = 0; | ||
| 85 | } | ||
| 86 | |||
| 87 | si_meminfo(&si); | ||
| 88 | drm_ram_available = si.totalram; | ||
| 89 | drm_ram_used = 0; | ||
| 90 | } | ||
| 91 | |||
| 92 | /* drm_mem_info is called whenever a process reads /dev/drm/mem. */ | ||
| 93 | |||
| 94 | static int drm__mem_info (char *buf, char **start, off_t offset, | ||
| 95 | int request, int *eof, void *data) { | ||
| 96 | drm_mem_stats_t *pt; | ||
| 97 | int len = 0; | ||
| 98 | |||
| 99 | if (offset > DRM_PROC_LIMIT) { | ||
| 100 | *eof = 1; | ||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | *eof = 0; | ||
| 105 | *start = &buf[offset]; | ||
| 106 | |||
| 107 | DRM_PROC_PRINT(" total counts " | ||
| 108 | " | outstanding \n"); | ||
| 109 | DRM_PROC_PRINT("type alloc freed fail bytes freed" | ||
| 110 | " | allocs bytes\n\n"); | ||
| 111 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", | ||
| 112 | "system", 0, 0, 0, | ||
| 113 | drm_ram_available << (PAGE_SHIFT - 10)); | ||
| 114 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n", | ||
| 115 | "locked", 0, 0, 0, drm_ram_used >> 10); | ||
| 116 | DRM_PROC_PRINT("\n"); | ||
| 117 | for (pt = drm_mem_stats; pt->name; pt++) { | ||
| 118 | DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n", | ||
| 119 | pt->name, | ||
| 120 | pt->succeed_count, | ||
| 121 | pt->free_count, | ||
| 122 | pt->fail_count, | ||
| 123 | pt->bytes_allocated, | ||
| 124 | pt->bytes_freed, | ||
| 125 | pt->succeed_count - pt->free_count, | ||
| 126 | (long)pt->bytes_allocated | ||
| 127 | - (long)pt->bytes_freed); | ||
| 128 | } | ||
| 129 | |||
| 130 | if (len > request + offset) | ||
| 131 | return request; | ||
| 132 | *eof = 1; | ||
| 133 | return len - offset; | ||
| 134 | } | ||
| 135 | |||
| 136 | int drm_mem_info (char *buf, char **start, off_t offset, | ||
| 137 | int len, int *eof, void *data) { | ||
| 138 | int ret; | ||
| 139 | |||
| 140 | spin_lock(&drm_mem_lock); | ||
| 141 | ret = drm__mem_info (buf, start, offset, len, eof, data); | ||
| 142 | spin_unlock(&drm_mem_lock); | ||
| 143 | return ret; | ||
| 144 | } | ||
| 145 | |||
| 146 | void *drm_alloc (size_t size, int area) { | ||
| 147 | void *pt; | ||
| 148 | |||
| 149 | if (!size) { | ||
| 150 | DRM_MEM_ERROR(area, "Allocating 0 bytes\n"); | ||
| 151 | return NULL; | ||
| 152 | } | ||
| 153 | |||
| 154 | if (!(pt = kmalloc(size, GFP_KERNEL))) { | ||
| 155 | spin_lock(&drm_mem_lock); | ||
| 156 | ++drm_mem_stats[area].fail_count; | ||
| 157 | spin_unlock(&drm_mem_lock); | ||
| 158 | return NULL; | ||
| 159 | } | ||
| 160 | spin_lock(&drm_mem_lock); | ||
| 161 | ++drm_mem_stats[area].succeed_count; | ||
| 162 | drm_mem_stats[area].bytes_allocated += size; | ||
| 163 | spin_unlock(&drm_mem_lock); | ||
| 164 | return pt; | ||
| 165 | } | ||
| 166 | |||
| 167 | void *drm_calloc (size_t nmemb, size_t size, int area) { | ||
| 168 | void *addr; | ||
| 169 | |||
| 170 | addr = drm_alloc (nmemb * size, area); | ||
| 171 | if (addr != NULL) | ||
| 172 | memset((void *)addr, 0, size * nmemb); | ||
| 173 | |||
| 174 | return addr; | ||
| 175 | } | ||
| 176 | |||
| 177 | void *drm_realloc (void *oldpt, size_t oldsize, size_t size, int area) { | ||
| 178 | void *pt; | ||
| 179 | |||
| 180 | if (!(pt = drm_alloc (size, area))) | ||
| 181 | return NULL; | ||
| 182 | if (oldpt && oldsize) { | ||
| 183 | memcpy(pt, oldpt, oldsize); | ||
| 184 | drm_free (oldpt, oldsize, area); | ||
| 185 | } | ||
| 186 | return pt; | ||
| 187 | } | ||
| 188 | |||
| 189 | void drm_free (void *pt, size_t size, int area) { | ||
| 190 | int alloc_count; | ||
| 191 | int free_count; | ||
| 192 | |||
| 193 | if (!pt) | ||
| 194 | DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n"); | ||
| 195 | else | ||
| 196 | kfree(pt); | ||
| 197 | spin_lock(&drm_mem_lock); | ||
| 198 | drm_mem_stats[area].bytes_freed += size; | ||
| 199 | free_count = ++drm_mem_stats[area].free_count; | ||
| 200 | alloc_count = drm_mem_stats[area].succeed_count; | ||
| 201 | spin_unlock(&drm_mem_lock); | ||
| 202 | if (free_count > alloc_count) { | ||
| 203 | DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n", | ||
| 204 | free_count, alloc_count); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | #if __OS_HAS_AGP | ||
| 209 | |||
| 210 | DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) { | ||
| 211 | DRM_AGP_MEM *handle; | ||
| 212 | |||
| 213 | if (!pages) { | ||
| 214 | DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n"); | ||
| 215 | return NULL; | ||
| 216 | } | ||
| 217 | |||
| 218 | if ((handle = drm_agp_allocate_memory (pages, type))) { | ||
| 219 | spin_lock(&drm_mem_lock); | ||
| 220 | ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; | ||
| 221 | drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated | ||
| 222 | += pages << PAGE_SHIFT; | ||
| 223 | spin_unlock(&drm_mem_lock); | ||
| 224 | return handle; | ||
| 225 | } | ||
| 226 | spin_lock(&drm_mem_lock); | ||
| 227 | ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count; | ||
| 228 | spin_unlock(&drm_mem_lock); | ||
| 229 | return NULL; | ||
| 230 | } | ||
| 231 | |||
| 232 | int drm_free_agp (DRM_AGP_MEM * handle, int pages) { | ||
| 233 | int alloc_count; | ||
| 234 | int free_count; | ||
| 235 | int retval = -EINVAL; | ||
| 236 | |||
| 237 | if (!handle) { | ||
| 238 | DRM_MEM_ERROR(DRM_MEM_TOTALAGP, | ||
| 239 | "Attempt to free NULL AGP handle\n"); | ||
| 240 | return retval; | ||
| 241 | } | ||
| 242 | |||
| 243 | if (drm_agp_free_memory (handle)) { | ||
| 244 | spin_lock(&drm_mem_lock); | ||
| 245 | free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count; | ||
| 246 | alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count; | ||
| 247 | drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed | ||
| 248 | += pages << PAGE_SHIFT; | ||
| 249 | spin_unlock(&drm_mem_lock); | ||
| 250 | if (free_count > alloc_count) { | ||
| 251 | DRM_MEM_ERROR(DRM_MEM_TOTALAGP, | ||
| 252 | "Excess frees: %d frees, %d allocs\n", | ||
| 253 | free_count, alloc_count); | ||
| 254 | } | ||
| 255 | return 0; | ||
| 256 | } | ||
| 257 | return retval; | ||
| 258 | } | ||
| 259 | |||
| 260 | int drm_bind_agp (DRM_AGP_MEM * handle, unsigned int start) { | ||
| 261 | int retcode = -EINVAL; | ||
| 262 | |||
| 263 | if (!handle) { | ||
| 264 | DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, | ||
| 265 | "Attempt to bind NULL AGP handle\n"); | ||
| 266 | return retcode; | ||
| 267 | } | ||
| 268 | |||
| 269 | if (!(retcode = drm_agp_bind_memory (handle, start))) { | ||
| 270 | spin_lock(&drm_mem_lock); | ||
| 271 | ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; | ||
| 272 | drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated | ||
| 273 | += handle->page_count << PAGE_SHIFT; | ||
| 274 | spin_unlock(&drm_mem_lock); | ||
| 275 | return retcode; | ||
| 276 | } | ||
| 277 | spin_lock(&drm_mem_lock); | ||
| 278 | ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count; | ||
| 279 | spin_unlock(&drm_mem_lock); | ||
| 280 | return retcode; | ||
| 281 | } | ||
| 282 | |||
| 283 | int drm_unbind_agp (DRM_AGP_MEM * handle) { | ||
| 284 | int alloc_count; | ||
| 285 | int free_count; | ||
| 286 | int retcode = -EINVAL; | ||
| 287 | |||
| 288 | if (!handle) { | ||
| 289 | DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, | ||
| 290 | "Attempt to unbind NULL AGP handle\n"); | ||
| 291 | return retcode; | ||
| 292 | } | ||
| 293 | |||
| 294 | if ((retcode = drm_agp_unbind_memory (handle))) | ||
| 295 | return retcode; | ||
| 296 | spin_lock(&drm_mem_lock); | ||
| 297 | free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count; | ||
| 298 | alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count; | ||
| 299 | drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed | ||
| 300 | += handle->page_count << PAGE_SHIFT; | ||
| 301 | spin_unlock(&drm_mem_lock); | ||
| 302 | if (free_count > alloc_count) { | ||
| 303 | DRM_MEM_ERROR(DRM_MEM_BOUNDAGP, | ||
| 304 | "Excess frees: %d frees, %d allocs\n", | ||
| 305 | free_count, alloc_count); | ||
| 306 | } | ||
| 307 | return retcode; | ||
| 308 | } | ||
| 309 | #endif | ||
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index 5662f4278ef3..f8332073d277 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h | |||
| @@ -59,13 +59,22 @@ struct drm_mm { | |||
| 59 | /* | 59 | /* |
| 60 | * Basic range manager support (drm_mm.c) | 60 | * Basic range manager support (drm_mm.c) |
| 61 | */ | 61 | */ |
| 62 | 62 | extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, | |
| 63 | extern struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent, | 63 | unsigned long size, |
| 64 | unsigned long size, | 64 | unsigned alignment, |
| 65 | unsigned alignment); | 65 | int atomic); |
| 66 | extern struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent, | 66 | static inline struct drm_mm_node *drm_mm_get_block(struct drm_mm_node *parent, |
| 67 | unsigned long size, | 67 | unsigned long size, |
| 68 | unsigned alignment); | 68 | unsigned alignment) |
| 69 | { | ||
| 70 | return drm_mm_get_block_generic(parent, size, alignment, 0); | ||
| 71 | } | ||
| 72 | static inline struct drm_mm_node *drm_mm_get_block_atomic(struct drm_mm_node *parent, | ||
| 73 | unsigned long size, | ||
| 74 | unsigned alignment) | ||
| 75 | { | ||
| 76 | return drm_mm_get_block_generic(parent, size, alignment, 1); | ||
| 77 | } | ||
| 69 | extern void drm_mm_put_block(struct drm_mm_node *cur); | 78 | extern void drm_mm_put_block(struct drm_mm_node *cur); |
| 70 | extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, | 79 | extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, |
| 71 | unsigned long size, | 80 | unsigned long size, |
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h index 2b8df8b420fd..76fa794fdac0 100644 --- a/include/linux/agp_backend.h +++ b/include/linux/agp_backend.h | |||
| @@ -70,7 +70,7 @@ struct agp_memory { | |||
| 70 | struct agp_memory *next; | 70 | struct agp_memory *next; |
| 71 | struct agp_memory *prev; | 71 | struct agp_memory *prev; |
| 72 | struct agp_bridge_data *bridge; | 72 | struct agp_bridge_data *bridge; |
| 73 | unsigned long *memory; | 73 | struct page **pages; |
| 74 | size_t page_count; | 74 | size_t page_count; |
| 75 | int key; | 75 | int key; |
| 76 | int num_scratch_pages; | 76 | int num_scratch_pages; |
diff --git a/include/linux/ata.h b/include/linux/ata.h index 915da43edee1..9c75921f0c16 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
| @@ -800,6 +800,20 @@ static inline int ata_id_is_ssd(const u16 *id) | |||
| 800 | return id[ATA_ID_ROT_SPEED] == 0x01; | 800 | return id[ATA_ID_ROT_SPEED] == 0x01; |
| 801 | } | 801 | } |
| 802 | 802 | ||
| 803 | static inline int ata_id_pio_need_iordy(const u16 *id, const u8 pio) | ||
| 804 | { | ||
| 805 | /* CF spec. r4.1 Table 22 says no IORDY on PIO5 and PIO6. */ | ||
| 806 | if (pio > 4 && ata_id_is_cfa(id)) | ||
| 807 | return 0; | ||
| 808 | /* For PIO3 and higher it is mandatory. */ | ||
| 809 | if (pio > 2) | ||
| 810 | return 1; | ||
| 811 | /* Turn it on when possible. */ | ||
| 812 | if (ata_id_has_iordy(id)) | ||
| 813 | return 1; | ||
| 814 | return 0; | ||
| 815 | } | ||
| 816 | |||
| 803 | static inline int ata_drive_40wire(const u16 *dev_id) | 817 | static inline int ata_drive_40wire(const u16 *dev_id) |
| 804 | { | 818 | { |
| 805 | if (ata_id_is_sata(dev_id)) | 819 | if (ata_id_is_sata(dev_id)) |
diff --git a/include/linux/gameport.h b/include/linux/gameport.h index 0cd825f7363a..1bc08541c2b9 100644 --- a/include/linux/gameport.h +++ b/include/linux/gameport.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
| 13 | #include <asm/io.h> | 13 | #include <asm/io.h> |
| 14 | #include <linux/types.h> | ||
| 14 | #include <linux/list.h> | 15 | #include <linux/list.h> |
| 15 | #include <linux/mutex.h> | 16 | #include <linux/mutex.h> |
| 16 | #include <linux/device.h> | 17 | #include <linux/device.h> |
| @@ -62,7 +63,7 @@ struct gameport_driver { | |||
| 62 | 63 | ||
| 63 | struct device_driver driver; | 64 | struct device_driver driver; |
| 64 | 65 | ||
| 65 | unsigned int ignore; | 66 | bool ignore; |
| 66 | }; | 67 | }; |
| 67 | #define to_gameport_driver(d) container_of(d, struct gameport_driver, driver) | 68 | #define to_gameport_driver(d) container_of(d, struct gameport_driver, driver) |
| 68 | 69 | ||
diff --git a/include/linux/i2c/lm8323.h b/include/linux/i2c/lm8323.h new file mode 100644 index 000000000000..478d668bc590 --- /dev/null +++ b/include/linux/i2c/lm8323.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /* | ||
| 2 | * lm8323.h - Configuration for LM8323 keypad driver. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation (version 2 of the License only). | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License | ||
| 14 | * along with this program; if not, write to the Free Software | ||
| 15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 16 | */ | ||
| 17 | |||
| 18 | #ifndef __LINUX_LM8323_H | ||
| 19 | #define __LINUX_LM8323_H | ||
| 20 | |||
| 21 | #include <linux/types.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * Largest keycode that the chip can send, plus one, | ||
| 25 | * so keys can be mapped directly at the index of the | ||
| 26 | * LM8323 keycode instead of subtracting one. | ||
| 27 | */ | ||
| 28 | #define LM8323_KEYMAP_SIZE (0x7f + 1) | ||
| 29 | |||
| 30 | #define LM8323_NUM_PWMS 3 | ||
| 31 | |||
| 32 | struct lm8323_platform_data { | ||
| 33 | int debounce_time; /* Time to watch for key bouncing, in ms. */ | ||
| 34 | int active_time; /* Idle time until sleep, in ms. */ | ||
| 35 | |||
| 36 | int size_x; | ||
| 37 | int size_y; | ||
| 38 | bool repeat; | ||
| 39 | const unsigned short *keymap; | ||
| 40 | |||
| 41 | const char *pwm_names[LM8323_NUM_PWMS]; | ||
| 42 | |||
| 43 | const char *name; /* Device name. */ | ||
| 44 | }; | ||
| 45 | |||
| 46 | #endif /* __LINUX_LM8323_H */ | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index a6c6a2fad7c8..95c6e00a72e8 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
| @@ -157,12 +157,6 @@ enum { | |||
| 157 | #define REQ_UNPARK_HEADS 0x23 | 157 | #define REQ_UNPARK_HEADS 0x23 |
| 158 | 158 | ||
| 159 | /* | 159 | /* |
| 160 | * Check for an interrupt and acknowledge the interrupt status | ||
| 161 | */ | ||
| 162 | struct hwif_s; | ||
| 163 | typedef int (ide_ack_intr_t)(struct hwif_s *); | ||
| 164 | |||
| 165 | /* | ||
| 166 | * hwif_chipset_t is used to keep track of the specific hardware | 160 | * hwif_chipset_t is used to keep track of the specific hardware |
| 167 | * chipset used by each IDE interface, if known. | 161 | * chipset used by each IDE interface, if known. |
| 168 | */ | 162 | */ |
| @@ -185,7 +179,6 @@ struct ide_hw { | |||
| 185 | }; | 179 | }; |
| 186 | 180 | ||
| 187 | int irq; /* our irq number */ | 181 | int irq; /* our irq number */ |
| 188 | ide_ack_intr_t *ack_intr; /* acknowledge interrupt */ | ||
| 189 | struct device *dev, *parent; | 182 | struct device *dev, *parent; |
| 190 | unsigned long config; | 183 | unsigned long config; |
| 191 | }; | 184 | }; |
| @@ -331,11 +324,6 @@ enum { | |||
| 331 | PC_FLAG_WRITING = (1 << 6), | 324 | PC_FLAG_WRITING = (1 << 6), |
| 332 | }; | 325 | }; |
| 333 | 326 | ||
| 334 | /* | ||
| 335 | * With each packet command, we allocate a buffer of IDE_PC_BUFFER_SIZE bytes. | ||
| 336 | * This is used for several packet commands (not for READ/WRITE commands). | ||
| 337 | */ | ||
| 338 | #define IDE_PC_BUFFER_SIZE 64 | ||
| 339 | #define ATAPI_WAIT_PC (60 * HZ) | 327 | #define ATAPI_WAIT_PC (60 * HZ) |
| 340 | 328 | ||
| 341 | struct ide_atapi_pc { | 329 | struct ide_atapi_pc { |
| @@ -347,12 +335,6 @@ struct ide_atapi_pc { | |||
| 347 | 335 | ||
| 348 | /* bytes to transfer */ | 336 | /* bytes to transfer */ |
| 349 | int req_xfer; | 337 | int req_xfer; |
| 350 | /* bytes actually transferred */ | ||
| 351 | int xferred; | ||
| 352 | |||
| 353 | /* data buffer */ | ||
| 354 | u8 *buf; | ||
| 355 | int buf_size; | ||
| 356 | 338 | ||
| 357 | /* the corresponding request */ | 339 | /* the corresponding request */ |
| 358 | struct request *rq; | 340 | struct request *rq; |
| @@ -363,8 +345,6 @@ struct ide_atapi_pc { | |||
| 363 | * those are more or less driver-specific and some of them are subject | 345 | * those are more or less driver-specific and some of them are subject |
| 364 | * to change/removal later. | 346 | * to change/removal later. |
| 365 | */ | 347 | */ |
| 366 | u8 pc_buf[IDE_PC_BUFFER_SIZE]; | ||
| 367 | |||
| 368 | unsigned long timeout; | 348 | unsigned long timeout; |
| 369 | }; | 349 | }; |
| 370 | 350 | ||
| @@ -552,7 +532,7 @@ struct ide_drive_s { | |||
| 552 | 532 | ||
| 553 | unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ | 533 | unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ |
| 554 | unsigned int cyl; /* "real" number of cyls */ | 534 | unsigned int cyl; /* "real" number of cyls */ |
| 555 | unsigned int drive_data; /* used by set_pio_mode/dev_select() */ | 535 | void *drive_data; /* used by set_pio_mode/dev_select() */ |
| 556 | unsigned int failures; /* current failure count */ | 536 | unsigned int failures; /* current failure count */ |
| 557 | unsigned int max_failures; /* maximum allowed failure count */ | 537 | unsigned int max_failures; /* maximum allowed failure count */ |
| 558 | u64 probed_capacity;/* initial/native media capacity */ | 538 | u64 probed_capacity;/* initial/native media capacity */ |
| @@ -649,6 +629,7 @@ struct ide_port_ops { | |||
| 649 | void (*maskproc)(ide_drive_t *, int); | 629 | void (*maskproc)(ide_drive_t *, int); |
| 650 | void (*quirkproc)(ide_drive_t *); | 630 | void (*quirkproc)(ide_drive_t *); |
| 651 | void (*clear_irq)(ide_drive_t *); | 631 | void (*clear_irq)(ide_drive_t *); |
| 632 | int (*test_irq)(struct hwif_s *); | ||
| 652 | 633 | ||
| 653 | u8 (*mdma_filter)(ide_drive_t *); | 634 | u8 (*mdma_filter)(ide_drive_t *); |
| 654 | u8 (*udma_filter)(ide_drive_t *); | 635 | u8 (*udma_filter)(ide_drive_t *); |
| @@ -674,6 +655,10 @@ struct ide_dma_ops { | |||
| 674 | u8 (*dma_sff_read_status)(struct hwif_s *); | 655 | u8 (*dma_sff_read_status)(struct hwif_s *); |
| 675 | }; | 656 | }; |
| 676 | 657 | ||
| 658 | enum { | ||
| 659 | IDE_PFLAG_PROBING = (1 << 0), | ||
| 660 | }; | ||
| 661 | |||
| 677 | struct ide_host; | 662 | struct ide_host; |
| 678 | 663 | ||
| 679 | typedef struct hwif_s { | 664 | typedef struct hwif_s { |
| @@ -690,6 +675,8 @@ typedef struct hwif_s { | |||
| 690 | 675 | ||
| 691 | ide_drive_t *devices[MAX_DRIVES + 1]; | 676 | ide_drive_t *devices[MAX_DRIVES + 1]; |
| 692 | 677 | ||
| 678 | unsigned long port_flags; | ||
| 679 | |||
| 693 | u8 major; /* our major number */ | 680 | u8 major; /* our major number */ |
| 694 | u8 index; /* 0 for ide0; 1 for ide1; ... */ | 681 | u8 index; /* 0 for ide0; 1 for ide1; ... */ |
| 695 | u8 channel; /* for dual-port chips: 0=primary, 1=secondary */ | 682 | u8 channel; /* for dual-port chips: 0=primary, 1=secondary */ |
| @@ -708,8 +695,6 @@ typedef struct hwif_s { | |||
| 708 | 695 | ||
| 709 | struct device *dev; | 696 | struct device *dev; |
| 710 | 697 | ||
| 711 | ide_ack_intr_t *ack_intr; | ||
| 712 | |||
| 713 | void (*rw_disk)(ide_drive_t *, struct request *); | 698 | void (*rw_disk)(ide_drive_t *, struct request *); |
| 714 | 699 | ||
| 715 | const struct ide_tp_ops *tp_ops; | 700 | const struct ide_tp_ops *tp_ops; |
| @@ -1130,6 +1115,8 @@ void SELECT_MASK(ide_drive_t *, int); | |||
| 1130 | u8 ide_read_error(ide_drive_t *); | 1115 | u8 ide_read_error(ide_drive_t *); |
| 1131 | void ide_read_bcount_and_ireason(ide_drive_t *, u16 *, u8 *); | 1116 | void ide_read_bcount_and_ireason(ide_drive_t *, u16 *, u8 *); |
| 1132 | 1117 | ||
| 1118 | int ide_check_ireason(ide_drive_t *, struct request *, int, int, int); | ||
| 1119 | |||
| 1133 | int ide_check_atapi_device(ide_drive_t *, const char *); | 1120 | int ide_check_atapi_device(ide_drive_t *, const char *); |
| 1134 | 1121 | ||
| 1135 | void ide_init_pc(struct ide_atapi_pc *); | 1122 | void ide_init_pc(struct ide_atapi_pc *); |
| @@ -1154,7 +1141,8 @@ enum { | |||
| 1154 | REQ_IDETAPE_WRITE = (1 << 3), | 1141 | REQ_IDETAPE_WRITE = (1 << 3), |
| 1155 | }; | 1142 | }; |
| 1156 | 1143 | ||
| 1157 | int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *); | 1144 | int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *, |
| 1145 | void *, unsigned int); | ||
| 1158 | 1146 | ||
| 1159 | int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); | 1147 | int ide_do_test_unit_ready(ide_drive_t *, struct gendisk *); |
| 1160 | int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); | 1148 | int ide_do_start_stop(ide_drive_t *, struct gendisk *, int); |
| @@ -1524,6 +1512,7 @@ int ide_timing_compute(ide_drive_t *, u8, struct ide_timing *, int, int); | |||
| 1524 | int ide_scan_pio_blacklist(char *); | 1512 | int ide_scan_pio_blacklist(char *); |
| 1525 | const char *ide_xfer_verbose(u8); | 1513 | const char *ide_xfer_verbose(u8); |
| 1526 | u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8); | 1514 | u8 ide_get_best_pio_mode(ide_drive_t *, u8, u8); |
| 1515 | int ide_pio_need_iordy(ide_drive_t *, const u8); | ||
| 1527 | int ide_set_pio_mode(ide_drive_t *, u8); | 1516 | int ide_set_pio_mode(ide_drive_t *, u8); |
| 1528 | int ide_set_dma_mode(ide_drive_t *, u8); | 1517 | int ide_set_dma_mode(ide_drive_t *, u8); |
| 1529 | void ide_set_pio(ide_drive_t *, u8); | 1518 | void ide_set_pio(ide_drive_t *, u8); |
| @@ -1561,6 +1550,16 @@ static inline ide_drive_t *ide_get_pair_dev(ide_drive_t *drive) | |||
| 1561 | return (peer->dev_flags & IDE_DFLAG_PRESENT) ? peer : NULL; | 1550 | return (peer->dev_flags & IDE_DFLAG_PRESENT) ? peer : NULL; |
| 1562 | } | 1551 | } |
| 1563 | 1552 | ||
| 1553 | static inline void *ide_get_drivedata(ide_drive_t *drive) | ||
| 1554 | { | ||
| 1555 | return drive->drive_data; | ||
| 1556 | } | ||
| 1557 | |||
| 1558 | static inline void ide_set_drivedata(ide_drive_t *drive, void *data) | ||
| 1559 | { | ||
| 1560 | drive->drive_data = data; | ||
| 1561 | } | ||
| 1562 | |||
| 1564 | #define ide_port_for_each_dev(i, dev, port) \ | 1563 | #define ide_port_for_each_dev(i, dev, port) \ |
| 1565 | for ((i) = 0; ((dev) = (port)->devices[i]) || (i) < MAX_DRIVES; (i)++) | 1564 | for ((i) = 0; ((dev) = (port)->devices[i]) || (i) < MAX_DRIVES; (i)++) |
| 1566 | 1565 | ||
diff --git a/include/linux/input.h b/include/linux/input.h index 6fed4f6a9c9e..8b3bc3e0d146 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -53,6 +53,7 @@ struct input_absinfo { | |||
| 53 | __s32 maximum; | 53 | __s32 maximum; |
| 54 | __s32 fuzz; | 54 | __s32 fuzz; |
| 55 | __s32 flat; | 55 | __s32 flat; |
| 56 | __s32 resolution; | ||
| 56 | }; | 57 | }; |
| 57 | 58 | ||
| 58 | #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ | 59 | #define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ |
| @@ -1109,6 +1110,7 @@ struct input_dev { | |||
| 1109 | int absmin[ABS_MAX + 1]; | 1110 | int absmin[ABS_MAX + 1]; |
| 1110 | int absfuzz[ABS_MAX + 1]; | 1111 | int absfuzz[ABS_MAX + 1]; |
| 1111 | int absflat[ABS_MAX + 1]; | 1112 | int absflat[ABS_MAX + 1]; |
| 1113 | int absres[ABS_MAX + 1]; | ||
| 1112 | 1114 | ||
| 1113 | int (*open)(struct input_dev *dev); | 1115 | int (*open)(struct input_dev *dev); |
| 1114 | void (*close)(struct input_dev *dev); | 1116 | void (*close)(struct input_dev *dev); |
diff --git a/include/linux/rotary_encoder.h b/include/linux/rotary_encoder.h index 12d63a30c347..215278b8df2a 100644 --- a/include/linux/rotary_encoder.h +++ b/include/linux/rotary_encoder.h | |||
| @@ -8,6 +8,8 @@ struct rotary_encoder_platform_data { | |||
| 8 | unsigned int gpio_b; | 8 | unsigned int gpio_b; |
| 9 | unsigned int inverted_a; | 9 | unsigned int inverted_a; |
| 10 | unsigned int inverted_b; | 10 | unsigned int inverted_b; |
| 11 | bool relative_axis; | ||
| 12 | bool rollover; | ||
| 11 | }; | 13 | }; |
| 12 | 14 | ||
| 13 | #endif /* __ROTARY_ENCODER_H__ */ | 15 | #endif /* __ROTARY_ENCODER_H__ */ |
diff --git a/include/linux/serio.h b/include/linux/serio.h index e0417e4d3f15..126d24c9eaa8 100644 --- a/include/linux/serio.h +++ b/include/linux/serio.h | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | #ifdef __KERNEL__ | 16 | #ifdef __KERNEL__ |
| 17 | 17 | ||
| 18 | #include <linux/types.h> | ||
| 18 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 19 | #include <linux/list.h> | 20 | #include <linux/list.h> |
| 20 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
| @@ -28,7 +29,10 @@ struct serio { | |||
| 28 | char name[32]; | 29 | char name[32]; |
| 29 | char phys[32]; | 30 | char phys[32]; |
| 30 | 31 | ||
| 31 | unsigned int manual_bind; | 32 | bool manual_bind; |
| 33 | bool registered; /* port has been fully registered with driver core */ | ||
| 34 | bool suspended; /* port is suspended */ | ||
| 35 | |||
| 32 | 36 | ||
| 33 | struct serio_device_id id; | 37 | struct serio_device_id id; |
| 34 | 38 | ||
| @@ -47,7 +51,6 @@ struct serio { | |||
| 47 | struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ | 51 | struct mutex drv_mutex; /* protects serio->drv so attributes can pin driver */ |
| 48 | 52 | ||
| 49 | struct device dev; | 53 | struct device dev; |
| 50 | unsigned int registered; /* port has been fully registered with driver core */ | ||
| 51 | 54 | ||
| 52 | struct list_head node; | 55 | struct list_head node; |
| 53 | }; | 56 | }; |
| @@ -58,7 +61,7 @@ struct serio_driver { | |||
| 58 | char *description; | 61 | char *description; |
| 59 | 62 | ||
| 60 | struct serio_device_id *id_table; | 63 | struct serio_device_id *id_table; |
| 61 | unsigned int manual_bind; | 64 | bool manual_bind; |
| 62 | 65 | ||
| 63 | void (*write_wakeup)(struct serio *); | 66 | void (*write_wakeup)(struct serio *); |
| 64 | irqreturn_t (*interrupt)(struct serio *, unsigned char, unsigned int); | 67 | irqreturn_t (*interrupt)(struct serio *, unsigned char, unsigned int); |
diff --git a/include/linux/spi/ads7846.h b/include/linux/spi/ads7846.h index 2ea20320c093..51948eb6927a 100644 --- a/include/linux/spi/ads7846.h +++ b/include/linux/spi/ads7846.h | |||
| @@ -17,6 +17,7 @@ struct ads7846_platform_data { | |||
| 17 | u16 vref_mv; /* external vref value, milliVolts */ | 17 | u16 vref_mv; /* external vref value, milliVolts */ |
| 18 | bool keep_vref_on; /* set to keep vref on for differential | 18 | bool keep_vref_on; /* set to keep vref on for differential |
| 19 | * measurements as well */ | 19 | * measurements as well */ |
| 20 | bool swap_xy; /* swap x and y axes */ | ||
| 20 | 21 | ||
| 21 | /* Settling time of the analog signals; a function of Vcc and the | 22 | /* Settling time of the analog signals; a function of Vcc and the |
| 22 | * capacitance on the X/Y drivers. If set to non-zero, two samples | 23 | * capacitance on the X/Y drivers. If set to non-zero, two samples |
diff --git a/include/linux/ucb1400.h b/include/linux/ucb1400.h index 970473bf8d5a..ed889f4168f3 100644 --- a/include/linux/ucb1400.h +++ b/include/linux/ucb1400.h | |||
| @@ -134,28 +134,13 @@ static inline void ucb1400_adc_enable(struct snd_ac97 *ac97) | |||
| 134 | ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA); | 134 | ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | static unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, | ||
| 138 | int adcsync) | ||
| 139 | { | ||
| 140 | unsigned int val; | ||
| 141 | |||
| 142 | if (adcsync) | ||
| 143 | adc_channel |= UCB_ADC_SYNC_ENA; | ||
| 144 | |||
| 145 | ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel); | ||
| 146 | ucb1400_reg_write(ac97, UCB_ADC_CR, UCB_ADC_ENA | adc_channel | | ||
| 147 | UCB_ADC_START); | ||
| 148 | |||
| 149 | while (!((val = ucb1400_reg_read(ac97, UCB_ADC_DATA)) | ||
| 150 | & UCB_ADC_DAT_VALID)) | ||
| 151 | schedule_timeout_uninterruptible(1); | ||
| 152 | |||
| 153 | return val & UCB_ADC_DAT_MASK; | ||
| 154 | } | ||
| 155 | |||
| 156 | static inline void ucb1400_adc_disable(struct snd_ac97 *ac97) | 137 | static inline void ucb1400_adc_disable(struct snd_ac97 *ac97) |
| 157 | { | 138 | { |
| 158 | ucb1400_reg_write(ac97, UCB_ADC_CR, 0); | 139 | ucb1400_reg_write(ac97, UCB_ADC_CR, 0); |
| 159 | } | 140 | } |
| 160 | 141 | ||
| 142 | |||
| 143 | unsigned int ucb1400_adc_read(struct snd_ac97 *ac97, u16 adc_channel, | ||
| 144 | int adcsync); | ||
| 145 | |||
| 161 | #endif | 146 | #endif |
