diff options
| -rw-r--r-- | drivers/firewire/ohci.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 3a908038ff62..5e5d5d3d43d1 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 18 | * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <linux/bitops.h> | ||
| 21 | #include <linux/bug.h> | 22 | #include <linux/bug.h> |
| 22 | #include <linux/compiler.h> | 23 | #include <linux/compiler.h> |
| 23 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
| @@ -153,6 +154,7 @@ struct context { | |||
| 153 | descriptor_callback_t callback; | 154 | descriptor_callback_t callback; |
| 154 | 155 | ||
| 155 | struct tasklet_struct tasklet; | 156 | struct tasklet_struct tasklet; |
| 157 | bool active; | ||
| 156 | }; | 158 | }; |
| 157 | 159 | ||
| 158 | #define IT_HEADER_SY(v) ((v) << 0) | 160 | #define IT_HEADER_SY(v) ((v) << 0) |
| @@ -168,6 +170,9 @@ struct iso_context { | |||
| 168 | int excess_bytes; | 170 | int excess_bytes; |
| 169 | void *header; | 171 | void *header; |
| 170 | size_t header_length; | 172 | size_t header_length; |
| 173 | |||
| 174 | u8 sync; | ||
| 175 | u8 tags; | ||
| 171 | }; | 176 | }; |
| 172 | 177 | ||
| 173 | #define CONFIG_ROM_SIZE 1024 | 178 | #define CONFIG_ROM_SIZE 1024 |
| @@ -184,7 +189,8 @@ struct fw_ohci { | |||
| 184 | u32 bus_time; | 189 | u32 bus_time; |
| 185 | bool is_root; | 190 | bool is_root; |
| 186 | bool csr_state_setclear_abdicate; | 191 | bool csr_state_setclear_abdicate; |
| 187 | 192 | int n_ir; | |
| 193 | int n_it; | ||
| 188 | /* | 194 | /* |
| 189 | * Spinlock for accessing fw_ohci data. Never call out of | 195 | * Spinlock for accessing fw_ohci data. Never call out of |
| 190 | * this driver with this lock held. | 196 | * this driver with this lock held. |
| @@ -1161,6 +1167,7 @@ static struct descriptor *context_get_descriptors(struct context *ctx, | |||
| 1161 | static void context_run(struct context *ctx, u32 extra) | 1167 | static void context_run(struct context *ctx, u32 extra) |
| 1162 | { | 1168 | { |
| 1163 | struct fw_ohci *ohci = ctx->ohci; | 1169 | struct fw_ohci *ohci = ctx->ohci; |
| 1170 | ctx->active = true; | ||
| 1164 | 1171 | ||
| 1165 | reg_write(ohci, COMMAND_PTR(ctx->regs), | 1172 | reg_write(ohci, COMMAND_PTR(ctx->regs), |
| 1166 | le32_to_cpu(ctx->last->branch_address)); | 1173 | le32_to_cpu(ctx->last->branch_address)); |
| @@ -1192,6 +1199,7 @@ static void context_stop(struct context *ctx) | |||
| 1192 | u32 reg; | 1199 | u32 reg; |
| 1193 | int i; | 1200 | int i; |
| 1194 | 1201 | ||
| 1202 | ctx->active = false; | ||
| 1195 | reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); | 1203 | reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); |
| 1196 | flush_writes(ctx->ohci); | 1204 | flush_writes(ctx->ohci); |
| 1197 | 1205 | ||
| @@ -2641,6 +2649,10 @@ static int ohci_start_iso(struct fw_iso_context *base, | |||
| 2641 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index); | 2649 | reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index); |
| 2642 | reg_write(ohci, CONTEXT_MATCH(ctx->context.regs), match); | 2650 | reg_write(ohci, CONTEXT_MATCH(ctx->context.regs), match); |
| 2643 | context_run(&ctx->context, control); | 2651 | context_run(&ctx->context, control); |
| 2652 | |||
| 2653 | ctx->sync = sync; | ||
| 2654 | ctx->tags = tags; | ||
| 2655 | |||
| 2644 | break; | 2656 | break; |
| 2645 | } | 2657 | } |
| 2646 | 2658 | ||
| @@ -2738,6 +2750,26 @@ static int ohci_set_iso_channels(struct fw_iso_context *base, u64 *channels) | |||
| 2738 | return ret; | 2750 | return ret; |
| 2739 | } | 2751 | } |
| 2740 | 2752 | ||
| 2753 | #ifdef CONFIG_PM | ||
| 2754 | static void ohci_resume_iso_dma(struct fw_ohci *ohci) | ||
| 2755 | { | ||
| 2756 | int i; | ||
| 2757 | struct iso_context *ctx; | ||
| 2758 | |||
| 2759 | for (i = 0 ; i < ohci->n_ir ; i++) { | ||
| 2760 | ctx = &ohci->ir_context_list[i]; | ||
| 2761 | if (ctx->context.active) | ||
| 2762 | ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags); | ||
| 2763 | } | ||
| 2764 | |||
| 2765 | for (i = 0 ; i < ohci->n_it ; i++) { | ||
| 2766 | ctx = &ohci->it_context_list[i]; | ||
| 2767 | if (ctx->context.active) | ||
| 2768 | ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags); | ||
| 2769 | } | ||
| 2770 | } | ||
| 2771 | #endif | ||
| 2772 | |||
| 2741 | static int queue_iso_transmit(struct iso_context *ctx, | 2773 | static int queue_iso_transmit(struct iso_context *ctx, |
| 2742 | struct fw_iso_packet *packet, | 2774 | struct fw_iso_packet *packet, |
| 2743 | struct fw_iso_buffer *buffer, | 2775 | struct fw_iso_buffer *buffer, |
| @@ -3047,7 +3079,7 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
| 3047 | struct fw_ohci *ohci; | 3079 | struct fw_ohci *ohci; |
| 3048 | u32 bus_options, max_receive, link_speed, version; | 3080 | u32 bus_options, max_receive, link_speed, version; |
| 3049 | u64 guid; | 3081 | u64 guid; |
| 3050 | int i, err, n_ir, n_it; | 3082 | int i, err; |
| 3051 | size_t size; | 3083 | size_t size; |
| 3052 | 3084 | ||
| 3053 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); | 3085 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); |
| @@ -3141,15 +3173,15 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
| 3141 | ohci->ir_context_channels = ~0ULL; | 3173 | ohci->ir_context_channels = ~0ULL; |
| 3142 | ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); | 3174 | ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); |
| 3143 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); | 3175 | reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); |
| 3144 | n_ir = hweight32(ohci->ir_context_mask); | 3176 | ohci->n_ir = hweight32(ohci->ir_context_mask); |
| 3145 | size = sizeof(struct iso_context) * n_ir; | 3177 | size = sizeof(struct iso_context) * ohci->n_ir; |
| 3146 | ohci->ir_context_list = kzalloc(size, GFP_KERNEL); | 3178 | ohci->ir_context_list = kzalloc(size, GFP_KERNEL); |
| 3147 | 3179 | ||
| 3148 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); | 3180 | reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); |
| 3149 | ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); | 3181 | ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); |
| 3150 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); | 3182 | reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); |
| 3151 | n_it = hweight32(ohci->it_context_mask); | 3183 | ohci->n_it = hweight32(ohci->it_context_mask); |
| 3152 | size = sizeof(struct iso_context) * n_it; | 3184 | size = sizeof(struct iso_context) * ohci->n_it; |
| 3153 | ohci->it_context_list = kzalloc(size, GFP_KERNEL); | 3185 | ohci->it_context_list = kzalloc(size, GFP_KERNEL); |
| 3154 | 3186 | ||
| 3155 | if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { | 3187 | if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { |
| @@ -3174,7 +3206,7 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
| 3174 | fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " | 3206 | fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " |
| 3175 | "%d IR + %d IT contexts, quirks 0x%x\n", | 3207 | "%d IR + %d IT contexts, quirks 0x%x\n", |
| 3176 | dev_name(&dev->dev), version >> 16, version & 0xff, | 3208 | dev_name(&dev->dev), version >> 16, version & 0xff, |
| 3177 | n_ir, n_it, ohci->quirks); | 3209 | ohci->n_ir, ohci->n_it, ohci->quirks); |
| 3178 | 3210 | ||
| 3179 | return 0; | 3211 | return 0; |
| 3180 | 3212 | ||
| @@ -3291,7 +3323,13 @@ static int pci_resume(struct pci_dev *dev) | |||
| 3291 | reg_write(ohci, OHCI1394_GUIDHi, (u32)(ohci->card.guid >> 32)); | 3323 | reg_write(ohci, OHCI1394_GUIDHi, (u32)(ohci->card.guid >> 32)); |
| 3292 | } | 3324 | } |
| 3293 | 3325 | ||
| 3294 | return ohci_enable(&ohci->card, NULL, 0); | 3326 | err = ohci_enable(&ohci->card, NULL, 0); |
| 3327 | |||
| 3328 | if (err) | ||
| 3329 | return err; | ||
| 3330 | |||
| 3331 | ohci_resume_iso_dma(ohci); | ||
| 3332 | return 0; | ||
| 3295 | } | 3333 | } |
| 3296 | #endif | 3334 | #endif |
| 3297 | 3335 | ||
