diff options
Diffstat (limited to 'drivers')
186 files changed, 3368 insertions, 645 deletions
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 5d1d07645132..e8cd652d2017 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -1206,9 +1206,9 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1206 | 1206 | ||
1207 | out_unmap_both: | 1207 | out_unmap_both: |
1208 | pci_set_drvdata(dev, NULL); | 1208 | pci_set_drvdata(dev, NULL); |
1209 | pci_iounmap(dev, card->config_regs); | ||
1210 | out_unmap_config: | ||
1211 | pci_iounmap(dev, card->buffers); | 1209 | pci_iounmap(dev, card->buffers); |
1210 | out_unmap_config: | ||
1211 | pci_iounmap(dev, card->config_regs); | ||
1212 | out_release_regions: | 1212 | out_release_regions: |
1213 | pci_release_regions(dev); | 1213 | pci_release_regions(dev); |
1214 | out: | 1214 | out: |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index e086fbbbe853..8db9089127c5 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -1177,7 +1177,8 @@ static bool DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T | |||
1177 | int TimeoutCounter; | 1177 | int TimeoutCounter; |
1178 | int i; | 1178 | int i; |
1179 | 1179 | ||
1180 | 1180 | memset(&CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T)); | |
1181 | |||
1181 | if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32))) | 1182 | if (pci_set_dma_mask(Controller->PCIDevice, DMA_BIT_MASK(32))) |
1182 | return DAC960_Failure(Controller, "DMA mask out of range"); | 1183 | return DAC960_Failure(Controller, "DMA mask out of range"); |
1183 | Controller->BounceBufferLimit = DMA_BIT_MASK(32); | 1184 | Controller->BounceBufferLimit = DMA_BIT_MASK(32); |
@@ -4627,7 +4628,8 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
4627 | DAC960_Controller_T *Controller = Command->Controller; | 4628 | DAC960_Controller_T *Controller = Command->Controller; |
4628 | DAC960_CommandType_T CommandType = Command->CommandType; | 4629 | DAC960_CommandType_T CommandType = Command->CommandType; |
4629 | DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; | 4630 | DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; |
4630 | DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode; | 4631 | DAC960_V2_IOCTL_Opcode_T IOCTLOpcode = CommandMailbox->Common.IOCTL_Opcode; |
4632 | DAC960_V2_CommandOpcode_T CommandOpcode = CommandMailbox->SCSI_10.CommandOpcode; | ||
4631 | DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus; | 4633 | DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus; |
4632 | 4634 | ||
4633 | if (CommandType == DAC960_ReadCommand || | 4635 | if (CommandType == DAC960_ReadCommand || |
@@ -4699,7 +4701,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
4699 | { | 4701 | { |
4700 | if (Controller->ShutdownMonitoringTimer) | 4702 | if (Controller->ShutdownMonitoringTimer) |
4701 | return; | 4703 | return; |
4702 | if (CommandOpcode == DAC960_V2_GetControllerInfo) | 4704 | if (IOCTLOpcode == DAC960_V2_GetControllerInfo) |
4703 | { | 4705 | { |
4704 | DAC960_V2_ControllerInfo_T *NewControllerInfo = | 4706 | DAC960_V2_ControllerInfo_T *NewControllerInfo = |
4705 | Controller->V2.NewControllerInformation; | 4707 | Controller->V2.NewControllerInformation; |
@@ -4719,14 +4721,14 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
4719 | memcpy(ControllerInfo, NewControllerInfo, | 4721 | memcpy(ControllerInfo, NewControllerInfo, |
4720 | sizeof(DAC960_V2_ControllerInfo_T)); | 4722 | sizeof(DAC960_V2_ControllerInfo_T)); |
4721 | } | 4723 | } |
4722 | else if (CommandOpcode == DAC960_V2_GetEvent) | 4724 | else if (IOCTLOpcode == DAC960_V2_GetEvent) |
4723 | { | 4725 | { |
4724 | if (CommandStatus == DAC960_V2_NormalCompletion) { | 4726 | if (CommandStatus == DAC960_V2_NormalCompletion) { |
4725 | DAC960_V2_ReportEvent(Controller, Controller->V2.Event); | 4727 | DAC960_V2_ReportEvent(Controller, Controller->V2.Event); |
4726 | } | 4728 | } |
4727 | Controller->V2.NextEventSequenceNumber++; | 4729 | Controller->V2.NextEventSequenceNumber++; |
4728 | } | 4730 | } |
4729 | else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && | 4731 | else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid && |
4730 | CommandStatus == DAC960_V2_NormalCompletion) | 4732 | CommandStatus == DAC960_V2_NormalCompletion) |
4731 | { | 4733 | { |
4732 | DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo = | 4734 | DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo = |
@@ -4915,7 +4917,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
4915 | NewPhysicalDeviceInfo->LogicalUnit++; | 4917 | NewPhysicalDeviceInfo->LogicalUnit++; |
4916 | Controller->V2.PhysicalDeviceIndex++; | 4918 | Controller->V2.PhysicalDeviceIndex++; |
4917 | } | 4919 | } |
4918 | else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) | 4920 | else if (IOCTLOpcode == DAC960_V2_GetPhysicalDeviceInfoValid) |
4919 | { | 4921 | { |
4920 | unsigned int DeviceIndex; | 4922 | unsigned int DeviceIndex; |
4921 | for (DeviceIndex = Controller->V2.PhysicalDeviceIndex; | 4923 | for (DeviceIndex = Controller->V2.PhysicalDeviceIndex; |
@@ -4938,7 +4940,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
4938 | } | 4940 | } |
4939 | Controller->V2.NeedPhysicalDeviceInformation = false; | 4941 | Controller->V2.NeedPhysicalDeviceInformation = false; |
4940 | } | 4942 | } |
4941 | else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid && | 4943 | else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid && |
4942 | CommandStatus == DAC960_V2_NormalCompletion) | 4944 | CommandStatus == DAC960_V2_NormalCompletion) |
4943 | { | 4945 | { |
4944 | DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo = | 4946 | DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo = |
@@ -5065,7 +5067,7 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
5065 | [LogicalDeviceNumber] = true; | 5067 | [LogicalDeviceNumber] = true; |
5066 | NewLogicalDeviceInfo->LogicalDeviceNumber++; | 5068 | NewLogicalDeviceInfo->LogicalDeviceNumber++; |
5067 | } | 5069 | } |
5068 | else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid) | 5070 | else if (IOCTLOpcode == DAC960_V2_GetLogicalDeviceInfoValid) |
5069 | { | 5071 | { |
5070 | int LogicalDriveNumber; | 5072 | int LogicalDriveNumber; |
5071 | for (LogicalDriveNumber = 0; | 5073 | for (LogicalDriveNumber = 0; |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 9baf11e86362..744f078f4dd8 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -3832,7 +3832,7 @@ static int __floppy_read_block_0(struct block_device *bdev) | |||
3832 | bio.bi_size = size; | 3832 | bio.bi_size = size; |
3833 | bio.bi_bdev = bdev; | 3833 | bio.bi_bdev = bdev; |
3834 | bio.bi_sector = 0; | 3834 | bio.bi_sector = 0; |
3835 | bio.bi_flags = BIO_QUIET; | 3835 | bio.bi_flags = (1 << BIO_QUIET); |
3836 | init_completion(&complete); | 3836 | init_completion(&complete); |
3837 | bio.bi_private = &complete; | 3837 | bio.bi_private = &complete; |
3838 | bio.bi_end_io = floppy_rb0_complete; | 3838 | bio.bi_end_io = floppy_rb0_complete; |
diff --git a/drivers/block/sx8.c b/drivers/block/sx8.c index e7472f567c9d..3fb6ab4c8b4e 100644 --- a/drivers/block/sx8.c +++ b/drivers/block/sx8.c | |||
@@ -1120,7 +1120,7 @@ static inline void carm_handle_resp(struct carm_host *host, | |||
1120 | break; | 1120 | break; |
1121 | case MISC_GET_FW_VER: { | 1121 | case MISC_GET_FW_VER: { |
1122 | struct carm_fw_ver *ver = (struct carm_fw_ver *) | 1122 | struct carm_fw_ver *ver = (struct carm_fw_ver *) |
1123 | mem + sizeof(struct carm_msg_get_fw_ver); | 1123 | (mem + sizeof(struct carm_msg_get_fw_ver)); |
1124 | if (!error) { | 1124 | if (!error) { |
1125 | host->fw_ver = le32_to_cpu(ver->version); | 1125 | host->fw_ver = le32_to_cpu(ver->version); |
1126 | host->flags |= (ver->features & FL_FW_VER_MASK); | 1126 | host->flags |= (ver->features & FL_FW_VER_MASK); |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f00f596c1029..789c9b579aea 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = { | |||
102 | 102 | ||
103 | /* Broadcom BCM20702A0 */ | 103 | /* Broadcom BCM20702A0 */ |
104 | { USB_DEVICE(0x0a5c, 0x21e3) }, | 104 | { USB_DEVICE(0x0a5c, 0x21e3) }, |
105 | { USB_DEVICE(0x0a5c, 0x21f3) }, | ||
105 | { USB_DEVICE(0x413c, 0x8197) }, | 106 | { USB_DEVICE(0x413c, 0x8197) }, |
106 | 107 | ||
107 | { } /* Terminating entry */ | 108 | { } /* Terminating entry */ |
@@ -726,9 +727,6 @@ static int btusb_send_frame(struct sk_buff *skb) | |||
726 | usb_fill_bulk_urb(urb, data->udev, pipe, | 727 | usb_fill_bulk_urb(urb, data->udev, pipe, |
727 | skb->data, skb->len, btusb_tx_complete, skb); | 728 | skb->data, skb->len, btusb_tx_complete, skb); |
728 | 729 | ||
729 | if (skb->priority >= HCI_PRIO_MAX - 1) | ||
730 | urb->transfer_flags = URB_ISO_ASAP; | ||
731 | |||
732 | hdev->stat.acl_tx++; | 730 | hdev->stat.acl_tx++; |
733 | break; | 731 | break; |
734 | 732 | ||
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 597235a2f8f9..0d40cf66b3cc 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c | |||
@@ -714,6 +714,7 @@ static int mv_hash_final(struct ahash_request *req) | |||
714 | { | 714 | { |
715 | struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); | 715 | struct mv_req_hash_ctx *ctx = ahash_request_ctx(req); |
716 | 716 | ||
717 | ahash_request_set_crypt(req, NULL, req->result, 0); | ||
717 | mv_update_hash_req_ctx(ctx, 1, 0); | 718 | mv_update_hash_req_ctx(ctx, 1, 0); |
718 | return mv_handle_req(&req->base); | 719 | return mv_handle_req(&req->base); |
719 | } | 720 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index d620b0784257..99d5527b2ca6 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "drmP.h" | 28 | #include "drmP.h" |
29 | #include "drm_crtc_helper.h" | 29 | #include "drm_crtc_helper.h" |
30 | 30 | ||
31 | #include <drm/exynos_drm.h> | ||
31 | #include "exynos_drm_drv.h" | 32 | #include "exynos_drm_drv.h" |
32 | #include "exynos_drm_encoder.h" | 33 | #include "exynos_drm_encoder.h" |
33 | 34 | ||
@@ -44,22 +45,25 @@ struct exynos_drm_connector { | |||
44 | /* convert exynos_video_timings to drm_display_mode */ | 45 | /* convert exynos_video_timings to drm_display_mode */ |
45 | static inline void | 46 | static inline void |
46 | convert_to_display_mode(struct drm_display_mode *mode, | 47 | convert_to_display_mode(struct drm_display_mode *mode, |
47 | struct fb_videomode *timing) | 48 | struct exynos_drm_panel_info *panel) |
48 | { | 49 | { |
50 | struct fb_videomode *timing = &panel->timing; | ||
49 | DRM_DEBUG_KMS("%s\n", __FILE__); | 51 | DRM_DEBUG_KMS("%s\n", __FILE__); |
50 | 52 | ||
51 | mode->clock = timing->pixclock / 1000; | 53 | mode->clock = timing->pixclock / 1000; |
52 | mode->vrefresh = timing->refresh; | 54 | mode->vrefresh = timing->refresh; |
53 | 55 | ||
54 | mode->hdisplay = timing->xres; | 56 | mode->hdisplay = timing->xres; |
55 | mode->hsync_start = mode->hdisplay + timing->left_margin; | 57 | mode->hsync_start = mode->hdisplay + timing->right_margin; |
56 | mode->hsync_end = mode->hsync_start + timing->hsync_len; | 58 | mode->hsync_end = mode->hsync_start + timing->hsync_len; |
57 | mode->htotal = mode->hsync_end + timing->right_margin; | 59 | mode->htotal = mode->hsync_end + timing->left_margin; |
58 | 60 | ||
59 | mode->vdisplay = timing->yres; | 61 | mode->vdisplay = timing->yres; |
60 | mode->vsync_start = mode->vdisplay + timing->upper_margin; | 62 | mode->vsync_start = mode->vdisplay + timing->lower_margin; |
61 | mode->vsync_end = mode->vsync_start + timing->vsync_len; | 63 | mode->vsync_end = mode->vsync_start + timing->vsync_len; |
62 | mode->vtotal = mode->vsync_end + timing->lower_margin; | 64 | mode->vtotal = mode->vsync_end + timing->upper_margin; |
65 | mode->width_mm = panel->width_mm; | ||
66 | mode->height_mm = panel->height_mm; | ||
63 | 67 | ||
64 | if (timing->vmode & FB_VMODE_INTERLACED) | 68 | if (timing->vmode & FB_VMODE_INTERLACED) |
65 | mode->flags |= DRM_MODE_FLAG_INTERLACE; | 69 | mode->flags |= DRM_MODE_FLAG_INTERLACE; |
@@ -81,14 +85,14 @@ convert_to_video_timing(struct fb_videomode *timing, | |||
81 | timing->refresh = drm_mode_vrefresh(mode); | 85 | timing->refresh = drm_mode_vrefresh(mode); |
82 | 86 | ||
83 | timing->xres = mode->hdisplay; | 87 | timing->xres = mode->hdisplay; |
84 | timing->left_margin = mode->hsync_start - mode->hdisplay; | 88 | timing->right_margin = mode->hsync_start - mode->hdisplay; |
85 | timing->hsync_len = mode->hsync_end - mode->hsync_start; | 89 | timing->hsync_len = mode->hsync_end - mode->hsync_start; |
86 | timing->right_margin = mode->htotal - mode->hsync_end; | 90 | timing->left_margin = mode->htotal - mode->hsync_end; |
87 | 91 | ||
88 | timing->yres = mode->vdisplay; | 92 | timing->yres = mode->vdisplay; |
89 | timing->upper_margin = mode->vsync_start - mode->vdisplay; | 93 | timing->lower_margin = mode->vsync_start - mode->vdisplay; |
90 | timing->vsync_len = mode->vsync_end - mode->vsync_start; | 94 | timing->vsync_len = mode->vsync_end - mode->vsync_start; |
91 | timing->lower_margin = mode->vtotal - mode->vsync_end; | 95 | timing->upper_margin = mode->vtotal - mode->vsync_end; |
92 | 96 | ||
93 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | 97 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
94 | timing->vmode = FB_VMODE_INTERLACED; | 98 | timing->vmode = FB_VMODE_INTERLACED; |
@@ -148,16 +152,18 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
148 | connector->display_info.raw_edid = edid; | 152 | connector->display_info.raw_edid = edid; |
149 | } else { | 153 | } else { |
150 | struct drm_display_mode *mode = drm_mode_create(connector->dev); | 154 | struct drm_display_mode *mode = drm_mode_create(connector->dev); |
151 | struct fb_videomode *timing; | 155 | struct exynos_drm_panel_info *panel; |
152 | 156 | ||
153 | if (display_ops->get_timing) | 157 | if (display_ops->get_panel) |
154 | timing = display_ops->get_timing(manager->dev); | 158 | panel = display_ops->get_panel(manager->dev); |
155 | else { | 159 | else { |
156 | drm_mode_destroy(connector->dev, mode); | 160 | drm_mode_destroy(connector->dev, mode); |
157 | return 0; | 161 | return 0; |
158 | } | 162 | } |
159 | 163 | ||
160 | convert_to_display_mode(mode, timing); | 164 | convert_to_display_mode(mode, panel); |
165 | connector->display_info.width_mm = mode->width_mm; | ||
166 | connector->display_info.height_mm = mode->height_mm; | ||
161 | 167 | ||
162 | mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; | 168 | mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; |
163 | drm_mode_set_name(mode); | 169 | drm_mode_set_name(mode); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 58820ebd3558..09cc13f791b3 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c | |||
@@ -246,7 +246,7 @@ static struct platform_driver exynos_drm_platform_driver = { | |||
246 | .remove = __devexit_p(exynos_drm_platform_remove), | 246 | .remove = __devexit_p(exynos_drm_platform_remove), |
247 | .driver = { | 247 | .driver = { |
248 | .owner = THIS_MODULE, | 248 | .owner = THIS_MODULE, |
249 | .name = DRIVER_NAME, | 249 | .name = "exynos-drm", |
250 | }, | 250 | }, |
251 | }; | 251 | }; |
252 | 252 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index e685e1e33055..13540de90bfc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -136,7 +136,7 @@ struct exynos_drm_overlay { | |||
136 | * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. | 136 | * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. |
137 | * @is_connected: check for that display is connected or not. | 137 | * @is_connected: check for that display is connected or not. |
138 | * @get_edid: get edid modes from display driver. | 138 | * @get_edid: get edid modes from display driver. |
139 | * @get_timing: get timing object from display driver. | 139 | * @get_panel: get panel object from display driver. |
140 | * @check_timing: check if timing is valid or not. | 140 | * @check_timing: check if timing is valid or not. |
141 | * @power_on: display device on or off. | 141 | * @power_on: display device on or off. |
142 | */ | 142 | */ |
@@ -145,7 +145,7 @@ struct exynos_drm_display_ops { | |||
145 | bool (*is_connected)(struct device *dev); | 145 | bool (*is_connected)(struct device *dev); |
146 | int (*get_edid)(struct device *dev, struct drm_connector *connector, | 146 | int (*get_edid)(struct device *dev, struct drm_connector *connector, |
147 | u8 *edid, int len); | 147 | u8 *edid, int len); |
148 | void *(*get_timing)(struct device *dev); | 148 | void *(*get_panel)(struct device *dev); |
149 | int (*check_timing)(struct device *dev, void *timing); | 149 | int (*check_timing)(struct device *dev, void *timing); |
150 | int (*power_on)(struct device *dev, int mode); | 150 | int (*power_on)(struct device *dev, int mode); |
151 | }; | 151 | }; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 3508700e529b..54f8f074822f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
@@ -46,39 +46,13 @@ struct exynos_drm_fbdev { | |||
46 | struct exynos_drm_gem_obj *exynos_gem_obj; | 46 | struct exynos_drm_gem_obj *exynos_gem_obj; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static int exynos_drm_fbdev_set_par(struct fb_info *info) | ||
50 | { | ||
51 | struct fb_var_screeninfo *var = &info->var; | ||
52 | |||
53 | switch (var->bits_per_pixel) { | ||
54 | case 32: | ||
55 | case 24: | ||
56 | case 18: | ||
57 | case 16: | ||
58 | case 12: | ||
59 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
60 | break; | ||
61 | case 1: | ||
62 | info->fix.visual = FB_VISUAL_MONO01; | ||
63 | break; | ||
64 | default: | ||
65 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; | ||
70 | |||
71 | return drm_fb_helper_set_par(info); | ||
72 | } | ||
73 | |||
74 | |||
75 | static struct fb_ops exynos_drm_fb_ops = { | 49 | static struct fb_ops exynos_drm_fb_ops = { |
76 | .owner = THIS_MODULE, | 50 | .owner = THIS_MODULE, |
77 | .fb_fillrect = cfb_fillrect, | 51 | .fb_fillrect = cfb_fillrect, |
78 | .fb_copyarea = cfb_copyarea, | 52 | .fb_copyarea = cfb_copyarea, |
79 | .fb_imageblit = cfb_imageblit, | 53 | .fb_imageblit = cfb_imageblit, |
80 | .fb_check_var = drm_fb_helper_check_var, | 54 | .fb_check_var = drm_fb_helper_check_var, |
81 | .fb_set_par = exynos_drm_fbdev_set_par, | 55 | .fb_set_par = drm_fb_helper_set_par, |
82 | .fb_blank = drm_fb_helper_blank, | 56 | .fb_blank = drm_fb_helper_blank, |
83 | .fb_pan_display = drm_fb_helper_pan_display, | 57 | .fb_pan_display = drm_fb_helper_pan_display, |
84 | .fb_setcmap = drm_fb_helper_setcmap, | 58 | .fb_setcmap = drm_fb_helper_setcmap, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 0dbb32bb18a3..56458eea0501 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c | |||
@@ -89,7 +89,7 @@ struct fimd_context { | |||
89 | bool suspended; | 89 | bool suspended; |
90 | struct mutex lock; | 90 | struct mutex lock; |
91 | 91 | ||
92 | struct fb_videomode *timing; | 92 | struct exynos_drm_panel_info *panel; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | static bool fimd_display_is_connected(struct device *dev) | 95 | static bool fimd_display_is_connected(struct device *dev) |
@@ -101,13 +101,13 @@ static bool fimd_display_is_connected(struct device *dev) | |||
101 | return true; | 101 | return true; |
102 | } | 102 | } |
103 | 103 | ||
104 | static void *fimd_get_timing(struct device *dev) | 104 | static void *fimd_get_panel(struct device *dev) |
105 | { | 105 | { |
106 | struct fimd_context *ctx = get_fimd_context(dev); | 106 | struct fimd_context *ctx = get_fimd_context(dev); |
107 | 107 | ||
108 | DRM_DEBUG_KMS("%s\n", __FILE__); | 108 | DRM_DEBUG_KMS("%s\n", __FILE__); |
109 | 109 | ||
110 | return ctx->timing; | 110 | return ctx->panel; |
111 | } | 111 | } |
112 | 112 | ||
113 | static int fimd_check_timing(struct device *dev, void *timing) | 113 | static int fimd_check_timing(struct device *dev, void *timing) |
@@ -131,7 +131,7 @@ static int fimd_display_power_on(struct device *dev, int mode) | |||
131 | static struct exynos_drm_display_ops fimd_display_ops = { | 131 | static struct exynos_drm_display_ops fimd_display_ops = { |
132 | .type = EXYNOS_DISPLAY_TYPE_LCD, | 132 | .type = EXYNOS_DISPLAY_TYPE_LCD, |
133 | .is_connected = fimd_display_is_connected, | 133 | .is_connected = fimd_display_is_connected, |
134 | .get_timing = fimd_get_timing, | 134 | .get_panel = fimd_get_panel, |
135 | .check_timing = fimd_check_timing, | 135 | .check_timing = fimd_check_timing, |
136 | .power_on = fimd_display_power_on, | 136 | .power_on = fimd_display_power_on, |
137 | }; | 137 | }; |
@@ -193,7 +193,8 @@ static void fimd_apply(struct device *subdrv_dev) | |||
193 | static void fimd_commit(struct device *dev) | 193 | static void fimd_commit(struct device *dev) |
194 | { | 194 | { |
195 | struct fimd_context *ctx = get_fimd_context(dev); | 195 | struct fimd_context *ctx = get_fimd_context(dev); |
196 | struct fb_videomode *timing = ctx->timing; | 196 | struct exynos_drm_panel_info *panel = ctx->panel; |
197 | struct fb_videomode *timing = &panel->timing; | ||
197 | u32 val; | 198 | u32 val; |
198 | 199 | ||
199 | if (ctx->suspended) | 200 | if (ctx->suspended) |
@@ -786,7 +787,7 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
786 | struct fimd_context *ctx; | 787 | struct fimd_context *ctx; |
787 | struct exynos_drm_subdrv *subdrv; | 788 | struct exynos_drm_subdrv *subdrv; |
788 | struct exynos_drm_fimd_pdata *pdata; | 789 | struct exynos_drm_fimd_pdata *pdata; |
789 | struct fb_videomode *timing; | 790 | struct exynos_drm_panel_info *panel; |
790 | struct resource *res; | 791 | struct resource *res; |
791 | int win; | 792 | int win; |
792 | int ret = -EINVAL; | 793 | int ret = -EINVAL; |
@@ -799,9 +800,9 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
799 | return -EINVAL; | 800 | return -EINVAL; |
800 | } | 801 | } |
801 | 802 | ||
802 | timing = &pdata->timing; | 803 | panel = &pdata->panel; |
803 | if (!timing) { | 804 | if (!panel) { |
804 | dev_err(dev, "timing is null.\n"); | 805 | dev_err(dev, "panel is null.\n"); |
805 | return -EINVAL; | 806 | return -EINVAL; |
806 | } | 807 | } |
807 | 808 | ||
@@ -816,8 +817,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
816 | goto err_clk_get; | 817 | goto err_clk_get; |
817 | } | 818 | } |
818 | 819 | ||
819 | clk_enable(ctx->bus_clk); | ||
820 | |||
821 | ctx->lcd_clk = clk_get(dev, "sclk_fimd"); | 820 | ctx->lcd_clk = clk_get(dev, "sclk_fimd"); |
822 | if (IS_ERR(ctx->lcd_clk)) { | 821 | if (IS_ERR(ctx->lcd_clk)) { |
823 | dev_err(dev, "failed to get lcd clock\n"); | 822 | dev_err(dev, "failed to get lcd clock\n"); |
@@ -825,8 +824,6 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
825 | goto err_bus_clk; | 824 | goto err_bus_clk; |
826 | } | 825 | } |
827 | 826 | ||
828 | clk_enable(ctx->lcd_clk); | ||
829 | |||
830 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 827 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
831 | if (!res) { | 828 | if (!res) { |
832 | dev_err(dev, "failed to find registers\n"); | 829 | dev_err(dev, "failed to find registers\n"); |
@@ -863,16 +860,10 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
863 | goto err_req_irq; | 860 | goto err_req_irq; |
864 | } | 861 | } |
865 | 862 | ||
866 | ctx->clkdiv = fimd_calc_clkdiv(ctx, timing); | ||
867 | ctx->vidcon0 = pdata->vidcon0; | 863 | ctx->vidcon0 = pdata->vidcon0; |
868 | ctx->vidcon1 = pdata->vidcon1; | 864 | ctx->vidcon1 = pdata->vidcon1; |
869 | ctx->default_win = pdata->default_win; | 865 | ctx->default_win = pdata->default_win; |
870 | ctx->timing = timing; | 866 | ctx->panel = panel; |
871 | |||
872 | timing->pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; | ||
873 | |||
874 | DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", | ||
875 | timing->pixclock, ctx->clkdiv); | ||
876 | 867 | ||
877 | subdrv = &ctx->subdrv; | 868 | subdrv = &ctx->subdrv; |
878 | 869 | ||
@@ -888,10 +879,15 @@ static int __devinit fimd_probe(struct platform_device *pdev) | |||
888 | 879 | ||
889 | platform_set_drvdata(pdev, ctx); | 880 | platform_set_drvdata(pdev, ctx); |
890 | 881 | ||
891 | pm_runtime_set_active(dev); | ||
892 | pm_runtime_enable(dev); | 882 | pm_runtime_enable(dev); |
893 | pm_runtime_get_sync(dev); | 883 | pm_runtime_get_sync(dev); |
894 | 884 | ||
885 | ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing); | ||
886 | panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; | ||
887 | |||
888 | DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", | ||
889 | panel->timing.pixclock, ctx->clkdiv); | ||
890 | |||
895 | for (win = 0; win < WINDOWS_NR; win++) | 891 | for (win = 0; win < WINDOWS_NR; win++) |
896 | fimd_clear_win(ctx, win); | 892 | fimd_clear_win(ctx, win); |
897 | 893 | ||
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index 4a5b099c3bc5..53404af2e748 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c | |||
@@ -321,6 +321,8 @@ static int cdv_chip_setup(struct drm_device *dev) | |||
321 | cdv_get_core_freq(dev); | 321 | cdv_get_core_freq(dev); |
322 | gma_intel_opregion_init(dev); | 322 | gma_intel_opregion_init(dev); |
323 | psb_intel_init_bios(dev); | 323 | psb_intel_init_bios(dev); |
324 | REG_WRITE(PORT_HOTPLUG_EN, 0); | ||
325 | REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); | ||
324 | return 0; | 326 | return 0; |
325 | } | 327 | } |
326 | 328 | ||
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 830dfdd6bf15..be616735ec91 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c | |||
@@ -247,7 +247,6 @@ static struct fb_ops psbfb_roll_ops = { | |||
247 | .fb_imageblit = cfb_imageblit, | 247 | .fb_imageblit = cfb_imageblit, |
248 | .fb_pan_display = psbfb_pan, | 248 | .fb_pan_display = psbfb_pan, |
249 | .fb_mmap = psbfb_mmap, | 249 | .fb_mmap = psbfb_mmap, |
250 | .fb_sync = psbfb_sync, | ||
251 | .fb_ioctl = psbfb_ioctl, | 250 | .fb_ioctl = psbfb_ioctl, |
252 | }; | 251 | }; |
253 | 252 | ||
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 5d5330f667f1..aff194fbe9f3 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c | |||
@@ -446,10 +446,9 @@ int psb_gtt_init(struct drm_device *dev, int resume) | |||
446 | pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); | 446 | pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); |
447 | gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) | 447 | gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) |
448 | >> PAGE_SHIFT; | 448 | >> PAGE_SHIFT; |
449 | /* Some CDV firmware doesn't report this currently. In which case the | 449 | /* CDV doesn't report this. In which case the system has 64 gtt pages */ |
450 | system has 64 gtt pages */ | ||
451 | if (pg->gtt_start == 0 || gtt_pages == 0) { | 450 | if (pg->gtt_start == 0 || gtt_pages == 0) { |
452 | dev_err(dev->dev, "GTT PCI BAR not initialized.\n"); | 451 | dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n"); |
453 | gtt_pages = 64; | 452 | gtt_pages = 64; |
454 | pg->gtt_start = dev_priv->pge_ctl; | 453 | pg->gtt_start = dev_priv->pge_ctl; |
455 | } | 454 | } |
@@ -461,10 +460,10 @@ int psb_gtt_init(struct drm_device *dev, int resume) | |||
461 | 460 | ||
462 | if (pg->gatt_pages == 0 || pg->gatt_start == 0) { | 461 | if (pg->gatt_pages == 0 || pg->gatt_start == 0) { |
463 | static struct resource fudge; /* Preferably peppermint */ | 462 | static struct resource fudge; /* Preferably peppermint */ |
464 | /* This can occur on CDV SDV systems. Fudge it in this case. | 463 | /* This can occur on CDV systems. Fudge it in this case. |
465 | We really don't care what imaginary space is being allocated | 464 | We really don't care what imaginary space is being allocated |
466 | at this point */ | 465 | at this point */ |
467 | dev_err(dev->dev, "GATT PCI BAR not initialized.\n"); | 466 | dev_dbg(dev->dev, "GATT PCI BAR not initialized.\n"); |
468 | pg->gatt_start = 0x40000000; | 467 | pg->gatt_start = 0x40000000; |
469 | pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; | 468 | pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; |
470 | /* This is a little confusing but in fact the GTT is providing | 469 | /* This is a little confusing but in fact the GTT is providing |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 03c53fcf8653..558ac716a328 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -2689,7 +2689,7 @@ | |||
2689 | #define DVS_FORMAT_RGBX888 (2<<25) | 2689 | #define DVS_FORMAT_RGBX888 (2<<25) |
2690 | #define DVS_FORMAT_RGBX161616 (3<<25) | 2690 | #define DVS_FORMAT_RGBX161616 (3<<25) |
2691 | #define DVS_SOURCE_KEY (1<<22) | 2691 | #define DVS_SOURCE_KEY (1<<22) |
2692 | #define DVS_RGB_ORDER_RGBX (1<<20) | 2692 | #define DVS_RGB_ORDER_XBGR (1<<20) |
2693 | #define DVS_YUV_BYTE_ORDER_MASK (3<<16) | 2693 | #define DVS_YUV_BYTE_ORDER_MASK (3<<16) |
2694 | #define DVS_YUV_ORDER_YUYV (0<<16) | 2694 | #define DVS_YUV_ORDER_YUYV (0<<16) |
2695 | #define DVS_YUV_ORDER_UYVY (1<<16) | 2695 | #define DVS_YUV_ORDER_UYVY (1<<16) |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f425b23e3803..397087cf689e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -4680,8 +4680,17 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, | |||
4680 | 4680 | ||
4681 | crtc = intel_get_crtc_for_plane(dev, plane); | 4681 | crtc = intel_get_crtc_for_plane(dev, plane); |
4682 | clock = crtc->mode.clock; | 4682 | clock = crtc->mode.clock; |
4683 | if (!clock) { | ||
4684 | *sprite_wm = 0; | ||
4685 | return false; | ||
4686 | } | ||
4683 | 4687 | ||
4684 | line_time_us = (sprite_width * 1000) / clock; | 4688 | line_time_us = (sprite_width * 1000) / clock; |
4689 | if (!line_time_us) { | ||
4690 | *sprite_wm = 0; | ||
4691 | return false; | ||
4692 | } | ||
4693 | |||
4685 | line_count = (latency_ns / line_time_us + 1000) / 1000; | 4694 | line_count = (latency_ns / line_time_us + 1000) / 1000; |
4686 | line_size = sprite_width * pixel_size; | 4695 | line_size = sprite_width * pixel_size; |
4687 | 4696 | ||
@@ -6175,7 +6184,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) | |||
6175 | int i; | 6184 | int i; |
6176 | 6185 | ||
6177 | /* The clocks have to be on to load the palette. */ | 6186 | /* The clocks have to be on to load the palette. */ |
6178 | if (!crtc->enabled) | 6187 | if (!crtc->enabled || !intel_crtc->active) |
6179 | return; | 6188 | return; |
6180 | 6189 | ||
6181 | /* use legacy palette for Ironlake */ | 6190 | /* use legacy palette for Ironlake */ |
@@ -6561,7 +6570,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev, | |||
6561 | mode_cmd.height = mode->vdisplay; | 6570 | mode_cmd.height = mode->vdisplay; |
6562 | mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width, | 6571 | mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width, |
6563 | bpp); | 6572 | bpp); |
6564 | mode_cmd.pixel_format = 0; | 6573 | mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); |
6565 | 6574 | ||
6566 | return intel_framebuffer_create(dev, &mode_cmd, obj); | 6575 | return intel_framebuffer_create(dev, &mode_cmd, obj); |
6567 | } | 6576 | } |
@@ -7819,6 +7828,7 @@ int intel_framebuffer_init(struct drm_device *dev, | |||
7819 | case DRM_FORMAT_RGB332: | 7828 | case DRM_FORMAT_RGB332: |
7820 | case DRM_FORMAT_RGB565: | 7829 | case DRM_FORMAT_RGB565: |
7821 | case DRM_FORMAT_XRGB8888: | 7830 | case DRM_FORMAT_XRGB8888: |
7831 | case DRM_FORMAT_XBGR8888: | ||
7822 | case DRM_FORMAT_ARGB8888: | 7832 | case DRM_FORMAT_ARGB8888: |
7823 | case DRM_FORMAT_XRGB2101010: | 7833 | case DRM_FORMAT_XRGB2101010: |
7824 | case DRM_FORMAT_ARGB2101010: | 7834 | case DRM_FORMAT_ARGB2101010: |
@@ -8185,7 +8195,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) | |||
8185 | 8195 | ||
8186 | if (intel_enable_rc6(dev_priv->dev)) | 8196 | if (intel_enable_rc6(dev_priv->dev)) |
8187 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE | | 8197 | rc6_mask = GEN6_RC_CTL_RC6_ENABLE | |
8188 | (IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0; | 8198 | ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0); |
8189 | 8199 | ||
8190 | I915_WRITE(GEN6_RC_CONTROL, | 8200 | I915_WRITE(GEN6_RC_CONTROL, |
8191 | rc6_mask | | 8201 | rc6_mask | |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 1ab842c6032e..536191540b03 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -301,7 +301,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
301 | 301 | ||
302 | I915_WRITE_CTL(ring, | 302 | I915_WRITE_CTL(ring, |
303 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | 303 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) |
304 | | RING_REPORT_64K | RING_VALID); | 304 | | RING_VALID); |
305 | 305 | ||
306 | /* If the head is still not zero, the ring is dead */ | 306 | /* If the head is still not zero, the ring is dead */ |
307 | if ((I915_READ_CTL(ring) & RING_VALID) == 0 || | 307 | if ((I915_READ_CTL(ring) & RING_VALID) == 0 || |
@@ -1132,18 +1132,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) | |||
1132 | struct drm_device *dev = ring->dev; | 1132 | struct drm_device *dev = ring->dev; |
1133 | struct drm_i915_private *dev_priv = dev->dev_private; | 1133 | struct drm_i915_private *dev_priv = dev->dev_private; |
1134 | unsigned long end; | 1134 | unsigned long end; |
1135 | u32 head; | ||
1136 | |||
1137 | /* If the reported head position has wrapped or hasn't advanced, | ||
1138 | * fallback to the slow and accurate path. | ||
1139 | */ | ||
1140 | head = intel_read_status_page(ring, 4); | ||
1141 | if (head > ring->head) { | ||
1142 | ring->head = head; | ||
1143 | ring->space = ring_space(ring); | ||
1144 | if (ring->space >= n) | ||
1145 | return 0; | ||
1146 | } | ||
1147 | 1135 | ||
1148 | trace_i915_ring_wait_begin(ring); | 1136 | trace_i915_ring_wait_begin(ring); |
1149 | if (drm_core_check_feature(dev, DRIVER_GEM)) | 1137 | if (drm_core_check_feature(dev, DRIVER_GEM)) |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index 2288abf88cce..a0835040c86b 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -225,16 +225,16 @@ snb_update_plane(struct drm_plane *plane, struct drm_framebuffer *fb, | |||
225 | 225 | ||
226 | /* Mask out pixel format bits in case we change it */ | 226 | /* Mask out pixel format bits in case we change it */ |
227 | dvscntr &= ~DVS_PIXFORMAT_MASK; | 227 | dvscntr &= ~DVS_PIXFORMAT_MASK; |
228 | dvscntr &= ~DVS_RGB_ORDER_RGBX; | 228 | dvscntr &= ~DVS_RGB_ORDER_XBGR; |
229 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; | 229 | dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK; |
230 | 230 | ||
231 | switch (fb->pixel_format) { | 231 | switch (fb->pixel_format) { |
232 | case DRM_FORMAT_XBGR8888: | 232 | case DRM_FORMAT_XBGR8888: |
233 | dvscntr |= DVS_FORMAT_RGBX888; | 233 | dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR; |
234 | pixel_size = 4; | 234 | pixel_size = 4; |
235 | break; | 235 | break; |
236 | case DRM_FORMAT_XRGB8888: | 236 | case DRM_FORMAT_XRGB8888: |
237 | dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_RGBX; | 237 | dvscntr |= DVS_FORMAT_RGBX888; |
238 | pixel_size = 4; | 238 | pixel_size = 4; |
239 | break; | 239 | break; |
240 | case DRM_FORMAT_YUYV: | 240 | case DRM_FORMAT_YUYV: |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index fbcd84803b60..17ca72ce3027 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2362,6 +2362,9 @@ void r600_semaphore_ring_emit(struct radeon_device *rdev, | |||
2362 | uint64_t addr = semaphore->gpu_addr; | 2362 | uint64_t addr = semaphore->gpu_addr; |
2363 | unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; | 2363 | unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; |
2364 | 2364 | ||
2365 | if (rdev->family < CHIP_CAYMAN) | ||
2366 | sel |= PACKET3_SEM_WAIT_ON_SIGNAL; | ||
2367 | |||
2365 | radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); | 2368 | radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); |
2366 | radeon_ring_write(ring, addr & 0xffffffff); | 2369 | radeon_ring_write(ring, addr & 0xffffffff); |
2367 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); | 2370 | radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); |
diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 2d1f6c5ee2a7..73e2c7c6edbc 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c | |||
@@ -314,6 +314,10 @@ const u32 r6xx_default_state[] = | |||
314 | 0x00000000, /* VGT_VTX_CNT_EN */ | 314 | 0x00000000, /* VGT_VTX_CNT_EN */ |
315 | 315 | ||
316 | 0xc0016900, | 316 | 0xc0016900, |
317 | 0x000000d4, | ||
318 | 0x00000000, /* SX_MISC */ | ||
319 | |||
320 | 0xc0016900, | ||
317 | 0x000002c8, | 321 | 0x000002c8, |
318 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ | 322 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ |
319 | 323 | ||
@@ -626,6 +630,10 @@ const u32 r7xx_default_state[] = | |||
626 | 0x00000000, /* VGT_VTX_CNT_EN */ | 630 | 0x00000000, /* VGT_VTX_CNT_EN */ |
627 | 631 | ||
628 | 0xc0016900, | 632 | 0xc0016900, |
633 | 0x000000d4, | ||
634 | 0x00000000, /* SX_MISC */ | ||
635 | |||
636 | 0xc0016900, | ||
629 | 0x000002c8, | 637 | 0x000002c8, |
630 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ | 638 | 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ |
631 | 639 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 38ce5d0427e3..387fcc9f03ef 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -1304,6 +1304,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1304 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1304 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
1305 | d0 = G_038004_TEX_DEPTH(word1); | 1305 | d0 = G_038004_TEX_DEPTH(word1); |
1306 | nfaces = 1; | 1306 | nfaces = 1; |
1307 | array = 0; | ||
1307 | switch (G_038000_DIM(word0)) { | 1308 | switch (G_038000_DIM(word0)) { |
1308 | case V_038000_SQ_TEX_DIM_1D: | 1309 | case V_038000_SQ_TEX_DIM_1D: |
1309 | case V_038000_SQ_TEX_DIM_2D: | 1310 | case V_038000_SQ_TEX_DIM_2D: |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 3ee1fd7ef394..9b23670716f1 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -831,6 +831,7 @@ | |||
831 | #define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 | 831 | #define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 |
832 | #define PACKET3_INDIRECT_BUFFER_MP 0x38 | 832 | #define PACKET3_INDIRECT_BUFFER_MP 0x38 |
833 | #define PACKET3_MEM_SEMAPHORE 0x39 | 833 | #define PACKET3_MEM_SEMAPHORE 0x39 |
834 | # define PACKET3_SEM_WAIT_ON_SIGNAL (0x1 << 12) | ||
834 | # define PACKET3_SEM_SEL_SIGNAL (0x6 << 29) | 835 | # define PACKET3_SEM_SEL_SIGNAL (0x6 << 29) |
835 | # define PACKET3_SEM_SEL_WAIT (0x7 << 29) | 836 | # define PACKET3_SEM_SEL_WAIT (0x7 << 29) |
836 | #define PACKET3_MPEG_INDEX 0x3A | 837 | #define PACKET3_MPEG_INDEX 0x3A |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index e7cb3ab09243..8c9a8115b632 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -1057,7 +1057,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, | |||
1057 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) | 1057 | (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) |
1058 | return MODE_OK; | 1058 | return MODE_OK; |
1059 | else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { | 1059 | else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { |
1060 | if (ASIC_IS_DCE3(rdev)) { | 1060 | if (0) { |
1061 | /* HDMI 1.3+ supports max clock of 340 Mhz */ | 1061 | /* HDMI 1.3+ supports max clock of 340 Mhz */ |
1062 | if (mode->clock > 340000) | 1062 | if (mode->clock > 340000) |
1063 | return MODE_CLOCK_HIGH; | 1063 | return MODE_CLOCK_HIGH; |
@@ -1117,13 +1117,23 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
1117 | (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { | 1117 | (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { |
1118 | struct drm_display_mode *mode; | 1118 | struct drm_display_mode *mode; |
1119 | 1119 | ||
1120 | if (!radeon_dig_connector->edp_on) | 1120 | if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
1121 | atombios_set_edp_panel_power(connector, | 1121 | if (!radeon_dig_connector->edp_on) |
1122 | ATOM_TRANSMITTER_ACTION_POWER_ON); | 1122 | atombios_set_edp_panel_power(connector, |
1123 | ret = radeon_ddc_get_modes(radeon_connector); | 1123 | ATOM_TRANSMITTER_ACTION_POWER_ON); |
1124 | if (!radeon_dig_connector->edp_on) | 1124 | ret = radeon_ddc_get_modes(radeon_connector); |
1125 | atombios_set_edp_panel_power(connector, | 1125 | if (!radeon_dig_connector->edp_on) |
1126 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | 1126 | atombios_set_edp_panel_power(connector, |
1127 | ATOM_TRANSMITTER_ACTION_POWER_OFF); | ||
1128 | } else { | ||
1129 | /* need to setup ddc on the bridge */ | ||
1130 | if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != | ||
1131 | ENCODER_OBJECT_ID_NONE) { | ||
1132 | if (encoder) | ||
1133 | radeon_atom_ext_encoder_setup_ddc(encoder); | ||
1134 | } | ||
1135 | ret = radeon_ddc_get_modes(radeon_connector); | ||
1136 | } | ||
1127 | 1137 | ||
1128 | if (ret > 0) { | 1138 | if (ret > 0) { |
1129 | if (encoder) { | 1139 | if (encoder) { |
@@ -1134,7 +1144,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector) | |||
1134 | return ret; | 1144 | return ret; |
1135 | } | 1145 | } |
1136 | 1146 | ||
1137 | encoder = radeon_best_single_encoder(connector); | ||
1138 | if (!encoder) | 1147 | if (!encoder) |
1139 | return 0; | 1148 | return 0; |
1140 | 1149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8c49fef1ce78..3d314338d843 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -1078,15 +1078,21 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = { | |||
1078 | .create_handle = radeon_user_framebuffer_create_handle, | 1078 | .create_handle = radeon_user_framebuffer_create_handle, |
1079 | }; | 1079 | }; |
1080 | 1080 | ||
1081 | void | 1081 | int |
1082 | radeon_framebuffer_init(struct drm_device *dev, | 1082 | radeon_framebuffer_init(struct drm_device *dev, |
1083 | struct radeon_framebuffer *rfb, | 1083 | struct radeon_framebuffer *rfb, |
1084 | struct drm_mode_fb_cmd2 *mode_cmd, | 1084 | struct drm_mode_fb_cmd2 *mode_cmd, |
1085 | struct drm_gem_object *obj) | 1085 | struct drm_gem_object *obj) |
1086 | { | 1086 | { |
1087 | int ret; | ||
1087 | rfb->obj = obj; | 1088 | rfb->obj = obj; |
1088 | drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); | 1089 | ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); |
1090 | if (ret) { | ||
1091 | rfb->obj = NULL; | ||
1092 | return ret; | ||
1093 | } | ||
1089 | drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd); | 1094 | drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd); |
1095 | return 0; | ||
1090 | } | 1096 | } |
1091 | 1097 | ||
1092 | static struct drm_framebuffer * | 1098 | static struct drm_framebuffer * |
@@ -1096,6 +1102,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, | |||
1096 | { | 1102 | { |
1097 | struct drm_gem_object *obj; | 1103 | struct drm_gem_object *obj; |
1098 | struct radeon_framebuffer *radeon_fb; | 1104 | struct radeon_framebuffer *radeon_fb; |
1105 | int ret; | ||
1099 | 1106 | ||
1100 | obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); | 1107 | obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); |
1101 | if (obj == NULL) { | 1108 | if (obj == NULL) { |
@@ -1108,7 +1115,12 @@ radeon_user_framebuffer_create(struct drm_device *dev, | |||
1108 | if (radeon_fb == NULL) | 1115 | if (radeon_fb == NULL) |
1109 | return ERR_PTR(-ENOMEM); | 1116 | return ERR_PTR(-ENOMEM); |
1110 | 1117 | ||
1111 | radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); | 1118 | ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); |
1119 | if (ret) { | ||
1120 | kfree(radeon_fb); | ||
1121 | drm_gem_object_unreference_unlocked(obj); | ||
1122 | return NULL; | ||
1123 | } | ||
1112 | 1124 | ||
1113 | return &radeon_fb->base; | 1125 | return &radeon_fb->base; |
1114 | } | 1126 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 9419c51bcf50..26e92708d114 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c | |||
@@ -307,8 +307,6 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, | |||
307 | bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | 307 | bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, |
308 | u32 pixel_clock) | 308 | u32 pixel_clock) |
309 | { | 309 | { |
310 | struct drm_device *dev = encoder->dev; | ||
311 | struct radeon_device *rdev = dev->dev_private; | ||
312 | struct drm_connector *connector; | 310 | struct drm_connector *connector; |
313 | struct radeon_connector *radeon_connector; | 311 | struct radeon_connector *radeon_connector; |
314 | struct radeon_connector_atom_dig *dig_connector; | 312 | struct radeon_connector_atom_dig *dig_connector; |
@@ -326,7 +324,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | |||
326 | case DRM_MODE_CONNECTOR_HDMIB: | 324 | case DRM_MODE_CONNECTOR_HDMIB: |
327 | if (radeon_connector->use_digital) { | 325 | if (radeon_connector->use_digital) { |
328 | /* HDMI 1.3 supports up to 340 Mhz over single link */ | 326 | /* HDMI 1.3 supports up to 340 Mhz over single link */ |
329 | if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { | 327 | if (0 && drm_detect_hdmi_monitor(radeon_connector->edid)) { |
330 | if (pixel_clock > 340000) | 328 | if (pixel_clock > 340000) |
331 | return true; | 329 | return true; |
332 | else | 330 | else |
@@ -348,7 +346,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, | |||
348 | return false; | 346 | return false; |
349 | else { | 347 | else { |
350 | /* HDMI 1.3 supports up to 340 Mhz over single link */ | 348 | /* HDMI 1.3 supports up to 340 Mhz over single link */ |
351 | if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { | 349 | if (0 && drm_detect_hdmi_monitor(radeon_connector->edid)) { |
352 | if (pixel_clock > 340000) | 350 | if (pixel_clock > 340000) |
353 | return true; | 351 | return true; |
354 | else | 352 | else |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index cf2bf35b56b8..195471cf65d3 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -209,6 +209,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
209 | sizes->surface_depth); | 209 | sizes->surface_depth); |
210 | 210 | ||
211 | ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); | 211 | ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); |
212 | if (ret) { | ||
213 | DRM_ERROR("failed to create fbcon object %d\n", ret); | ||
214 | return ret; | ||
215 | } | ||
216 | |||
212 | rbo = gem_to_radeon_bo(gobj); | 217 | rbo = gem_to_radeon_bo(gobj); |
213 | 218 | ||
214 | /* okay we have an object now allocate the framebuffer */ | 219 | /* okay we have an object now allocate the framebuffer */ |
@@ -220,7 +225,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
220 | 225 | ||
221 | info->par = rfbdev; | 226 | info->par = rfbdev; |
222 | 227 | ||
223 | radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); | 228 | ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); |
229 | if (ret) { | ||
230 | DRM_ERROR("failed to initalise framebuffer %d\n", ret); | ||
231 | goto out_unref; | ||
232 | } | ||
224 | 233 | ||
225 | fb = &rfbdev->rfb.base; | 234 | fb = &rfbdev->rfb.base; |
226 | 235 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 010dad8b66ae..c58a036233fb 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -597,13 +597,13 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
597 | if (bo_va == NULL) | 597 | if (bo_va == NULL) |
598 | return 0; | 598 | return 0; |
599 | 599 | ||
600 | list_del(&bo_va->bo_list); | ||
601 | mutex_lock(&vm->mutex); | 600 | mutex_lock(&vm->mutex); |
602 | radeon_mutex_lock(&rdev->cs_mutex); | 601 | radeon_mutex_lock(&rdev->cs_mutex); |
603 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 602 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
604 | radeon_mutex_unlock(&rdev->cs_mutex); | 603 | radeon_mutex_unlock(&rdev->cs_mutex); |
605 | list_del(&bo_va->vm_list); | 604 | list_del(&bo_va->vm_list); |
606 | mutex_unlock(&vm->mutex); | 605 | mutex_unlock(&vm->mutex); |
606 | list_del(&bo_va->bo_list); | ||
607 | 607 | ||
608 | kfree(bo_va); | 608 | kfree(bo_va); |
609 | return 0; | 609 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 4330e3253573..8a85598fb242 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -649,7 +649,7 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, | |||
649 | u16 blue, int regno); | 649 | u16 blue, int regno); |
650 | extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, | 650 | extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, |
651 | u16 *blue, int regno); | 651 | u16 *blue, int regno); |
652 | void radeon_framebuffer_init(struct drm_device *dev, | 652 | int radeon_framebuffer_init(struct drm_device *dev, |
653 | struct radeon_framebuffer *rfb, | 653 | struct radeon_framebuffer *rfb, |
654 | struct drm_mode_fb_cmd2 *mode_cmd, | 654 | struct drm_mode_fb_cmd2 *mode_cmd, |
655 | struct drm_gem_object *obj); | 655 | struct drm_gem_object *obj); |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b8574cddd953..63552e30d0c3 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -59,6 +59,9 @@ | |||
59 | #define USB_VENDOR_ID_AIRCABLE 0x16CA | 59 | #define USB_VENDOR_ID_AIRCABLE 0x16CA |
60 | #define USB_DEVICE_ID_AIRCABLE1 0x1502 | 60 | #define USB_DEVICE_ID_AIRCABLE1 0x1502 |
61 | 61 | ||
62 | #define USB_VENDOR_ID_AIREN 0x1a2c | ||
63 | #define USB_DEVICE_ID_AIREN_SLIMPLUS 0x0002 | ||
64 | |||
62 | #define USB_VENDOR_ID_ALCOR 0x058f | 65 | #define USB_VENDOR_ID_ALCOR 0x058f |
63 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 | 66 | #define USB_DEVICE_ID_ALCOR_USBRS232 0x9720 |
64 | 67 | ||
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 9333d692a786..627850a54d34 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -986,8 +986,13 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct | |||
986 | return; | 986 | return; |
987 | } | 987 | } |
988 | 988 | ||
989 | /* Ignore out-of-range values as per HID specification, section 5.10 */ | 989 | /* |
990 | if (value < field->logical_minimum || value > field->logical_maximum) { | 990 | * Ignore out-of-range values as per HID specification, |
991 | * section 5.10 and 6.2.25 | ||
992 | */ | ||
993 | if ((field->flags & HID_MAIN_ITEM_VARIABLE) && | ||
994 | (value < field->logical_minimum || | ||
995 | value > field->logical_maximum)) { | ||
991 | dbg_hid("Ignoring out-of-range value %x\n", value); | 996 | dbg_hid("Ignoring out-of-range value %x\n", value); |
992 | return; | 997 | return; |
993 | } | 998 | } |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index c831af937481..57d4e1e1df48 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -54,6 +54,7 @@ static const struct hid_blacklist { | |||
54 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, | 54 | { USB_VENDOR_ID_PLAYDOTCOM, USB_DEVICE_ID_PLAYDOTCOM_EMS_USBII, HID_QUIRK_MULTI_INPUT }, |
55 | { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, | 55 | { USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS, HID_QUIRK_MULTI_INPUT }, |
56 | 56 | ||
57 | { USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET }, | ||
57 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, | 58 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET }, |
58 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, | 59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET }, |
59 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, | 60 | { USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET }, |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 02260406b9e4..dad895fec62a 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -497,8 +497,9 @@ config SENSORS_JC42 | |||
497 | If you say yes here, you get support for JEDEC JC42.4 compliant | 497 | If you say yes here, you get support for JEDEC JC42.4 compliant |
498 | temperature sensors, which are used on many DDR3 memory modules for | 498 | temperature sensors, which are used on many DDR3 memory modules for |
499 | mobile devices and servers. Support will include, but not be limited | 499 | mobile devices and servers. Support will include, but not be limited |
500 | to, ADT7408, CAT34TS02, CAT6095, MAX6604, MCP9805, MCP98242, MCP98243, | 500 | to, ADT7408, AT30TS00, CAT34TS02, CAT6095, MAX6604, MCP9804, MCP9805, |
501 | MCP9843, SE97, SE98, STTS424(E), TSE2002B3, and TS3000B3. | 501 | MCP98242, MCP98243, MCP9843, SE97, SE98, STTS424(E), STTS2002, |
502 | STTS3000, TSE2002B3, TSE2002GB2, TS3000B3, and TS3000GB2. | ||
502 | 503 | ||
503 | This driver can also be built as a module. If so, the module | 504 | This driver can also be built as a module. If so, the module |
504 | will be called jc42. | 505 | will be called jc42. |
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 6bab2001ef3b..6aa5a9fad879 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c | |||
@@ -178,6 +178,16 @@ static inline void f75375_write16(struct i2c_client *client, u8 reg, | |||
178 | i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); | 178 | i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF)); |
179 | } | 179 | } |
180 | 180 | ||
181 | static void f75375_write_pwm(struct i2c_client *client, int nr) | ||
182 | { | ||
183 | struct f75375_data *data = i2c_get_clientdata(client); | ||
184 | if (data->kind == f75387) | ||
185 | f75375_write16(client, F75375_REG_FAN_EXP(nr), data->pwm[nr]); | ||
186 | else | ||
187 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), | ||
188 | data->pwm[nr]); | ||
189 | } | ||
190 | |||
181 | static struct f75375_data *f75375_update_device(struct device *dev) | 191 | static struct f75375_data *f75375_update_device(struct device *dev) |
182 | { | 192 | { |
183 | struct i2c_client *client = to_i2c_client(dev); | 193 | struct i2c_client *client = to_i2c_client(dev); |
@@ -254,6 +264,36 @@ static inline u16 rpm_to_reg(int rpm) | |||
254 | return 1500000 / rpm; | 264 | return 1500000 / rpm; |
255 | } | 265 | } |
256 | 266 | ||
267 | static bool duty_mode_enabled(u8 pwm_enable) | ||
268 | { | ||
269 | switch (pwm_enable) { | ||
270 | case 0: /* Manual, duty mode (full speed) */ | ||
271 | case 1: /* Manual, duty mode */ | ||
272 | case 4: /* Auto, duty mode */ | ||
273 | return true; | ||
274 | case 2: /* Auto, speed mode */ | ||
275 | case 3: /* Manual, speed mode */ | ||
276 | return false; | ||
277 | default: | ||
278 | BUG(); | ||
279 | } | ||
280 | } | ||
281 | |||
282 | static bool auto_mode_enabled(u8 pwm_enable) | ||
283 | { | ||
284 | switch (pwm_enable) { | ||
285 | case 0: /* Manual, duty mode (full speed) */ | ||
286 | case 1: /* Manual, duty mode */ | ||
287 | case 3: /* Manual, speed mode */ | ||
288 | return false; | ||
289 | case 2: /* Auto, speed mode */ | ||
290 | case 4: /* Auto, duty mode */ | ||
291 | return true; | ||
292 | default: | ||
293 | BUG(); | ||
294 | } | ||
295 | } | ||
296 | |||
257 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | 297 | static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, |
258 | const char *buf, size_t count) | 298 | const char *buf, size_t count) |
259 | { | 299 | { |
@@ -287,6 +327,11 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *attr, | |||
287 | if (err < 0) | 327 | if (err < 0) |
288 | return err; | 328 | return err; |
289 | 329 | ||
330 | if (auto_mode_enabled(data->pwm_enable[nr])) | ||
331 | return -EINVAL; | ||
332 | if (data->kind == f75387 && duty_mode_enabled(data->pwm_enable[nr])) | ||
333 | return -EINVAL; | ||
334 | |||
290 | mutex_lock(&data->update_lock); | 335 | mutex_lock(&data->update_lock); |
291 | data->fan_target[nr] = rpm_to_reg(val); | 336 | data->fan_target[nr] = rpm_to_reg(val); |
292 | f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]); | 337 | f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]); |
@@ -307,9 +352,13 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
307 | if (err < 0) | 352 | if (err < 0) |
308 | return err; | 353 | return err; |
309 | 354 | ||
355 | if (auto_mode_enabled(data->pwm_enable[nr]) || | ||
356 | !duty_mode_enabled(data->pwm_enable[nr])) | ||
357 | return -EINVAL; | ||
358 | |||
310 | mutex_lock(&data->update_lock); | 359 | mutex_lock(&data->update_lock); |
311 | data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); | 360 | data->pwm[nr] = SENSORS_LIMIT(val, 0, 255); |
312 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]); | 361 | f75375_write_pwm(client, nr); |
313 | mutex_unlock(&data->update_lock); | 362 | mutex_unlock(&data->update_lock); |
314 | return count; | 363 | return count; |
315 | } | 364 | } |
@@ -327,11 +376,15 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) | |||
327 | struct f75375_data *data = i2c_get_clientdata(client); | 376 | struct f75375_data *data = i2c_get_clientdata(client); |
328 | u8 fanmode; | 377 | u8 fanmode; |
329 | 378 | ||
330 | if (val < 0 || val > 3) | 379 | if (val < 0 || val > 4) |
331 | return -EINVAL; | 380 | return -EINVAL; |
332 | 381 | ||
333 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); | 382 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); |
334 | if (data->kind == f75387) { | 383 | if (data->kind == f75387) { |
384 | /* For now, deny dangerous toggling of duty mode */ | ||
385 | if (duty_mode_enabled(data->pwm_enable[nr]) != | ||
386 | duty_mode_enabled(val)) | ||
387 | return -EOPNOTSUPP; | ||
335 | /* clear each fanX_mode bit before setting them properly */ | 388 | /* clear each fanX_mode bit before setting them properly */ |
336 | fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr)); | 389 | fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr)); |
337 | fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr)); | 390 | fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr)); |
@@ -345,12 +398,14 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) | |||
345 | fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); | 398 | fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); |
346 | fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); | 399 | fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); |
347 | break; | 400 | break; |
348 | case 2: /* AUTOMATIC*/ | 401 | case 2: /* Automatic, speed mode */ |
349 | fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); | ||
350 | break; | 402 | break; |
351 | case 3: /* fan speed */ | 403 | case 3: /* fan speed */ |
352 | fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); | 404 | fanmode |= (1 << F75387_FAN_MANU_MODE(nr)); |
353 | break; | 405 | break; |
406 | case 4: /* Automatic, pwm */ | ||
407 | fanmode |= (1 << F75387_FAN_DUTY_MODE(nr)); | ||
408 | break; | ||
354 | } | 409 | } |
355 | } else { | 410 | } else { |
356 | /* clear each fanX_mode bit before setting them properly */ | 411 | /* clear each fanX_mode bit before setting them properly */ |
@@ -368,14 +423,15 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) | |||
368 | break; | 423 | break; |
369 | case 3: /* fan speed */ | 424 | case 3: /* fan speed */ |
370 | break; | 425 | break; |
426 | case 4: /* Automatic pwm */ | ||
427 | return -EINVAL; | ||
371 | } | 428 | } |
372 | } | 429 | } |
373 | 430 | ||
374 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); | 431 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); |
375 | data->pwm_enable[nr] = val; | 432 | data->pwm_enable[nr] = val; |
376 | if (val == 0) | 433 | if (val == 0) |
377 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), | 434 | f75375_write_pwm(client, nr); |
378 | data->pwm[nr]); | ||
379 | return 0; | 435 | return 0; |
380 | } | 436 | } |
381 | 437 | ||
@@ -726,14 +782,17 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data, | |||
726 | 782 | ||
727 | manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1); | 783 | manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1); |
728 | duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1); | 784 | duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1); |
729 | if (manu && duty) | 785 | if (!manu && duty) |
730 | /* speed */ | 786 | /* auto, pwm */ |
787 | data->pwm_enable[nr] = 4; | ||
788 | else if (manu && !duty) | ||
789 | /* manual, speed */ | ||
731 | data->pwm_enable[nr] = 3; | 790 | data->pwm_enable[nr] = 3; |
732 | else if (!manu && duty) | 791 | else if (!manu && !duty) |
733 | /* automatic */ | 792 | /* automatic, speed */ |
734 | data->pwm_enable[nr] = 2; | 793 | data->pwm_enable[nr] = 2; |
735 | else | 794 | else |
736 | /* manual */ | 795 | /* manual, pwm */ |
737 | data->pwm_enable[nr] = 1; | 796 | data->pwm_enable[nr] = 1; |
738 | } else { | 797 | } else { |
739 | if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr)))) | 798 | if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr)))) |
@@ -758,9 +817,11 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data, | |||
758 | set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); | 817 | set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); |
759 | set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); | 818 | set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); |
760 | for (nr = 0; nr < 2; nr++) { | 819 | for (nr = 0; nr < 2; nr++) { |
820 | if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) || | ||
821 | !duty_mode_enabled(f75375s_pdata->pwm_enable[nr])) | ||
822 | continue; | ||
761 | data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); | 823 | data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); |
762 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), | 824 | f75375_write_pwm(client, nr); |
763 | data->pwm[nr]); | ||
764 | } | 825 | } |
765 | 826 | ||
766 | } | 827 | } |
@@ -787,7 +848,7 @@ static int f75375_probe(struct i2c_client *client, | |||
787 | if (err) | 848 | if (err) |
788 | goto exit_free; | 849 | goto exit_free; |
789 | 850 | ||
790 | if (data->kind == f75375) { | 851 | if (data->kind != f75373) { |
791 | err = sysfs_chmod_file(&client->dev.kobj, | 852 | err = sysfs_chmod_file(&client->dev.kobj, |
792 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | 853 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, |
793 | S_IRUGO | S_IWUSR); | 854 | S_IRUGO | S_IWUSR); |
diff --git a/drivers/hwmon/jc42.c b/drivers/hwmon/jc42.c index 28c09eead36b..b927ee5ccdd7 100644 --- a/drivers/hwmon/jc42.c +++ b/drivers/hwmon/jc42.c | |||
@@ -64,6 +64,7 @@ static const unsigned short normal_i2c[] = { | |||
64 | 64 | ||
65 | /* Manufacturer IDs */ | 65 | /* Manufacturer IDs */ |
66 | #define ADT_MANID 0x11d4 /* Analog Devices */ | 66 | #define ADT_MANID 0x11d4 /* Analog Devices */ |
67 | #define ATMEL_MANID 0x001f /* Atmel */ | ||
67 | #define MAX_MANID 0x004d /* Maxim */ | 68 | #define MAX_MANID 0x004d /* Maxim */ |
68 | #define IDT_MANID 0x00b3 /* IDT */ | 69 | #define IDT_MANID 0x00b3 /* IDT */ |
69 | #define MCP_MANID 0x0054 /* Microchip */ | 70 | #define MCP_MANID 0x0054 /* Microchip */ |
@@ -77,15 +78,25 @@ static const unsigned short normal_i2c[] = { | |||
77 | #define ADT7408_DEVID 0x0801 | 78 | #define ADT7408_DEVID 0x0801 |
78 | #define ADT7408_DEVID_MASK 0xffff | 79 | #define ADT7408_DEVID_MASK 0xffff |
79 | 80 | ||
81 | /* Atmel */ | ||
82 | #define AT30TS00_DEVID 0x8201 | ||
83 | #define AT30TS00_DEVID_MASK 0xffff | ||
84 | |||
80 | /* IDT */ | 85 | /* IDT */ |
81 | #define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */ | 86 | #define TS3000B3_DEVID 0x2903 /* Also matches TSE2002B3 */ |
82 | #define TS3000B3_DEVID_MASK 0xffff | 87 | #define TS3000B3_DEVID_MASK 0xffff |
83 | 88 | ||
89 | #define TS3000GB2_DEVID 0x2912 /* Also matches TSE2002GB2 */ | ||
90 | #define TS3000GB2_DEVID_MASK 0xffff | ||
91 | |||
84 | /* Maxim */ | 92 | /* Maxim */ |
85 | #define MAX6604_DEVID 0x3e00 | 93 | #define MAX6604_DEVID 0x3e00 |
86 | #define MAX6604_DEVID_MASK 0xffff | 94 | #define MAX6604_DEVID_MASK 0xffff |
87 | 95 | ||
88 | /* Microchip */ | 96 | /* Microchip */ |
97 | #define MCP9804_DEVID 0x0200 | ||
98 | #define MCP9804_DEVID_MASK 0xfffc | ||
99 | |||
89 | #define MCP98242_DEVID 0x2000 | 100 | #define MCP98242_DEVID 0x2000 |
90 | #define MCP98242_DEVID_MASK 0xfffc | 101 | #define MCP98242_DEVID_MASK 0xfffc |
91 | 102 | ||
@@ -113,6 +124,12 @@ static const unsigned short normal_i2c[] = { | |||
113 | #define STTS424E_DEVID 0x0000 | 124 | #define STTS424E_DEVID 0x0000 |
114 | #define STTS424E_DEVID_MASK 0xfffe | 125 | #define STTS424E_DEVID_MASK 0xfffe |
115 | 126 | ||
127 | #define STTS2002_DEVID 0x0300 | ||
128 | #define STTS2002_DEVID_MASK 0xffff | ||
129 | |||
130 | #define STTS3000_DEVID 0x0200 | ||
131 | #define STTS3000_DEVID_MASK 0xffff | ||
132 | |||
116 | static u16 jc42_hysteresis[] = { 0, 1500, 3000, 6000 }; | 133 | static u16 jc42_hysteresis[] = { 0, 1500, 3000, 6000 }; |
117 | 134 | ||
118 | struct jc42_chips { | 135 | struct jc42_chips { |
@@ -123,8 +140,11 @@ struct jc42_chips { | |||
123 | 140 | ||
124 | static struct jc42_chips jc42_chips[] = { | 141 | static struct jc42_chips jc42_chips[] = { |
125 | { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK }, | 142 | { ADT_MANID, ADT7408_DEVID, ADT7408_DEVID_MASK }, |
143 | { ATMEL_MANID, AT30TS00_DEVID, AT30TS00_DEVID_MASK }, | ||
126 | { IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK }, | 144 | { IDT_MANID, TS3000B3_DEVID, TS3000B3_DEVID_MASK }, |
145 | { IDT_MANID, TS3000GB2_DEVID, TS3000GB2_DEVID_MASK }, | ||
127 | { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, | 146 | { MAX_MANID, MAX6604_DEVID, MAX6604_DEVID_MASK }, |
147 | { MCP_MANID, MCP9804_DEVID, MCP9804_DEVID_MASK }, | ||
128 | { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK }, | 148 | { MCP_MANID, MCP98242_DEVID, MCP98242_DEVID_MASK }, |
129 | { MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK }, | 149 | { MCP_MANID, MCP98243_DEVID, MCP98243_DEVID_MASK }, |
130 | { MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK }, | 150 | { MCP_MANID, MCP9843_DEVID, MCP9843_DEVID_MASK }, |
@@ -133,6 +153,8 @@ static struct jc42_chips jc42_chips[] = { | |||
133 | { NXP_MANID, SE98_DEVID, SE98_DEVID_MASK }, | 153 | { NXP_MANID, SE98_DEVID, SE98_DEVID_MASK }, |
134 | { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK }, | 154 | { STM_MANID, STTS424_DEVID, STTS424_DEVID_MASK }, |
135 | { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK }, | 155 | { STM_MANID, STTS424E_DEVID, STTS424E_DEVID_MASK }, |
156 | { STM_MANID, STTS2002_DEVID, STTS2002_DEVID_MASK }, | ||
157 | { STM_MANID, STTS3000_DEVID, STTS3000_DEVID_MASK }, | ||
136 | }; | 158 | }; |
137 | 159 | ||
138 | /* Each client has this additional data */ | 160 | /* Each client has this additional data */ |
@@ -159,10 +181,12 @@ static struct jc42_data *jc42_update_device(struct device *dev); | |||
159 | 181 | ||
160 | static const struct i2c_device_id jc42_id[] = { | 182 | static const struct i2c_device_id jc42_id[] = { |
161 | { "adt7408", 0 }, | 183 | { "adt7408", 0 }, |
184 | { "at30ts00", 0 }, | ||
162 | { "cat94ts02", 0 }, | 185 | { "cat94ts02", 0 }, |
163 | { "cat6095", 0 }, | 186 | { "cat6095", 0 }, |
164 | { "jc42", 0 }, | 187 | { "jc42", 0 }, |
165 | { "max6604", 0 }, | 188 | { "max6604", 0 }, |
189 | { "mcp9804", 0 }, | ||
166 | { "mcp9805", 0 }, | 190 | { "mcp9805", 0 }, |
167 | { "mcp98242", 0 }, | 191 | { "mcp98242", 0 }, |
168 | { "mcp98243", 0 }, | 192 | { "mcp98243", 0 }, |
@@ -171,8 +195,10 @@ static const struct i2c_device_id jc42_id[] = { | |||
171 | { "se97b", 0 }, | 195 | { "se97b", 0 }, |
172 | { "se98", 0 }, | 196 | { "se98", 0 }, |
173 | { "stts424", 0 }, | 197 | { "stts424", 0 }, |
174 | { "tse2002b3", 0 }, | 198 | { "stts2002", 0 }, |
175 | { "ts3000b3", 0 }, | 199 | { "stts3000", 0 }, |
200 | { "tse2002", 0 }, | ||
201 | { "ts3000", 0 }, | ||
176 | { } | 202 | { } |
177 | }; | 203 | }; |
178 | MODULE_DEVICE_TABLE(i2c, jc42_id); | 204 | MODULE_DEVICE_TABLE(i2c, jc42_id); |
diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 00460d8d8423..d89b33967a85 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c | |||
@@ -54,7 +54,8 @@ | |||
54 | lcrit_alarm, crit_alarm */ | 54 | lcrit_alarm, crit_alarm */ |
55 | #define PMBUS_IOUT_BOOLEANS_PER_PAGE 3 /* alarm, lcrit_alarm, | 55 | #define PMBUS_IOUT_BOOLEANS_PER_PAGE 3 /* alarm, lcrit_alarm, |
56 | crit_alarm */ | 56 | crit_alarm */ |
57 | #define PMBUS_POUT_BOOLEANS_PER_PAGE 2 /* alarm, crit_alarm */ | 57 | #define PMBUS_POUT_BOOLEANS_PER_PAGE 3 /* cap_alarm, alarm, crit_alarm |
58 | */ | ||
58 | #define PMBUS_MAX_BOOLEANS_PER_FAN 2 /* alarm, fault */ | 59 | #define PMBUS_MAX_BOOLEANS_PER_FAN 2 /* alarm, fault */ |
59 | #define PMBUS_MAX_BOOLEANS_PER_TEMP 4 /* min_alarm, max_alarm, | 60 | #define PMBUS_MAX_BOOLEANS_PER_TEMP 4 /* min_alarm, max_alarm, |
60 | lcrit_alarm, crit_alarm */ | 61 | lcrit_alarm, crit_alarm */ |
diff --git a/drivers/hwmon/pmbus/zl6100.c b/drivers/hwmon/pmbus/zl6100.c index 48c7b4a716ae..e3e8420b7b81 100644 --- a/drivers/hwmon/pmbus/zl6100.c +++ b/drivers/hwmon/pmbus/zl6100.c | |||
@@ -33,6 +33,7 @@ enum chips { zl2004, zl2005, zl2006, zl2008, zl2105, zl2106, zl6100, zl6105 }; | |||
33 | struct zl6100_data { | 33 | struct zl6100_data { |
34 | int id; | 34 | int id; |
35 | ktime_t access; /* chip access time */ | 35 | ktime_t access; /* chip access time */ |
36 | int delay; /* Delay between chip accesses in uS */ | ||
36 | struct pmbus_driver_info info; | 37 | struct pmbus_driver_info info; |
37 | }; | 38 | }; |
38 | 39 | ||
@@ -52,10 +53,10 @@ MODULE_PARM_DESC(delay, "Delay between chip accesses in uS"); | |||
52 | /* Some chips need a delay between accesses */ | 53 | /* Some chips need a delay between accesses */ |
53 | static inline void zl6100_wait(const struct zl6100_data *data) | 54 | static inline void zl6100_wait(const struct zl6100_data *data) |
54 | { | 55 | { |
55 | if (delay) { | 56 | if (data->delay) { |
56 | s64 delta = ktime_us_delta(ktime_get(), data->access); | 57 | s64 delta = ktime_us_delta(ktime_get(), data->access); |
57 | if (delta < delay) | 58 | if (delta < data->delay) |
58 | udelay(delay - delta); | 59 | udelay(data->delay - delta); |
59 | } | 60 | } |
60 | } | 61 | } |
61 | 62 | ||
@@ -199,16 +200,11 @@ static int zl6100_probe(struct i2c_client *client, | |||
199 | data->id = mid->driver_data; | 200 | data->id = mid->driver_data; |
200 | 201 | ||
201 | /* | 202 | /* |
202 | * ZL2005, ZL2008, ZL2105, and ZL6100 are known to require a wait time | 203 | * According to information from the chip vendor, all currently |
203 | * between I2C accesses. ZL2004 and ZL6105 are known to be safe. | 204 | * supported chips are known to require a wait time between I2C |
204 | * Other chips have not yet been tested. | 205 | * accesses. |
205 | * | ||
206 | * Only clear the wait time for chips known to be safe. The wait time | ||
207 | * can be cleared later for additional chips if tests show that it | ||
208 | * is not needed (in other words, better be safe than sorry). | ||
209 | */ | 206 | */ |
210 | if (data->id == zl2004 || data->id == zl6105) | 207 | data->delay = delay; |
211 | delay = 0; | ||
212 | 208 | ||
213 | /* | 209 | /* |
214 | * Since there was a direct I2C device access above, wait before | 210 | * Since there was a direct I2C device access above, wait before |
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index 5276d1933dbc..a658d62c5e10 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 0x8860 0xa1 | 39 | 0x8860 0xa1 |
40 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 | 40 | w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 |
41 | w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 | 41 | w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3 |
42 | w83627uhg 8 2 2 2 0xa230 0xc1 0x5ca3 | 42 | w83627uhg 8 2 2 3 0xa230 0xc1 0x5ca3 |
43 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 | 43 | w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3 |
44 | w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 | 44 | w83667hg-b 9 5 3 4 0xb350 0xc1 0x5ca3 |
45 | nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 | 45 | nct6775f 9 4 3 9 0xb470 0xc1 0x5ca3 |
@@ -1607,7 +1607,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \ | |||
1607 | val = step_time_to_reg(val, data->pwm_mode[nr]); \ | 1607 | val = step_time_to_reg(val, data->pwm_mode[nr]); \ |
1608 | mutex_lock(&data->update_lock); \ | 1608 | mutex_lock(&data->update_lock); \ |
1609 | data->reg[nr] = val; \ | 1609 | data->reg[nr] = val; \ |
1610 | w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \ | 1610 | w83627ehf_write_value(data, data->REG_##REG[nr], val); \ |
1611 | mutex_unlock(&data->update_lock); \ | 1611 | mutex_unlock(&data->update_lock); \ |
1612 | return count; \ | 1612 | return count; \ |
1613 | } \ | 1613 | } \ |
@@ -2004,7 +2004,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2004 | goto exit; | 2004 | goto exit; |
2005 | } | 2005 | } |
2006 | 2006 | ||
2007 | data = kzalloc(sizeof(struct w83627ehf_data), GFP_KERNEL); | 2007 | data = devm_kzalloc(&pdev->dev, sizeof(struct w83627ehf_data), |
2008 | GFP_KERNEL); | ||
2008 | if (!data) { | 2009 | if (!data) { |
2009 | err = -ENOMEM; | 2010 | err = -ENOMEM; |
2010 | goto exit_release; | 2011 | goto exit_release; |
@@ -2157,16 +2158,16 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2157 | w83627ehf_set_temp_reg_ehf(data, 3); | 2158 | w83627ehf_set_temp_reg_ehf(data, 3); |
2158 | 2159 | ||
2159 | /* | 2160 | /* |
2160 | * Temperature sources for temp1 and temp2 are selected with | 2161 | * Temperature sources for temp2 and temp3 are selected with |
2161 | * bank 0, registers 0x49 and 0x4a. | 2162 | * bank 0, registers 0x49 and 0x4a. |
2162 | */ | 2163 | */ |
2163 | data->temp_src[0] = 0; /* SYSTIN */ | 2164 | data->temp_src[0] = 0; /* SYSTIN */ |
2164 | reg = w83627ehf_read_value(data, 0x49) & 0x07; | 2165 | reg = w83627ehf_read_value(data, 0x49) & 0x07; |
2165 | /* Adjust to have the same mapping as other source registers */ | 2166 | /* Adjust to have the same mapping as other source registers */ |
2166 | if (reg == 0) | 2167 | if (reg == 0) |
2167 | data->temp_src[1]++; | 2168 | data->temp_src[1] = 1; |
2168 | else if (reg >= 2 && reg <= 5) | 2169 | else if (reg >= 2 && reg <= 5) |
2169 | data->temp_src[1] += 2; | 2170 | data->temp_src[1] = reg + 2; |
2170 | else /* should never happen */ | 2171 | else /* should never happen */ |
2171 | data->have_temp &= ~(1 << 1); | 2172 | data->have_temp &= ~(1 << 1); |
2172 | reg = w83627ehf_read_value(data, 0x4a); | 2173 | reg = w83627ehf_read_value(data, 0x4a); |
@@ -2493,9 +2494,8 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) | |||
2493 | 2494 | ||
2494 | exit_remove: | 2495 | exit_remove: |
2495 | w83627ehf_device_remove_files(dev); | 2496 | w83627ehf_device_remove_files(dev); |
2496 | kfree(data); | ||
2497 | platform_set_drvdata(pdev, NULL); | ||
2498 | exit_release: | 2497 | exit_release: |
2498 | platform_set_drvdata(pdev, NULL); | ||
2499 | release_region(res->start, IOREGION_LENGTH); | 2499 | release_region(res->start, IOREGION_LENGTH); |
2500 | exit: | 2500 | exit: |
2501 | return err; | 2501 | return err; |
@@ -2509,7 +2509,6 @@ static int __devexit w83627ehf_remove(struct platform_device *pdev) | |||
2509 | w83627ehf_device_remove_files(&pdev->dev); | 2509 | w83627ehf_device_remove_files(&pdev->dev); |
2510 | release_region(data->addr, IOREGION_LENGTH); | 2510 | release_region(data->addr, IOREGION_LENGTH); |
2511 | platform_set_drvdata(pdev, NULL); | 2511 | platform_set_drvdata(pdev, NULL); |
2512 | kfree(data); | ||
2513 | 2512 | ||
2514 | return 0; | 2513 | return 0; |
2515 | } | 2514 | } |
diff --git a/drivers/i2c/algos/i2c-algo-bit.c b/drivers/i2c/algos/i2c-algo-bit.c index 525c7345fa0b..24f94f4ae395 100644 --- a/drivers/i2c/algos/i2c-algo-bit.c +++ b/drivers/i2c/algos/i2c-algo-bit.c | |||
@@ -103,8 +103,14 @@ static int sclhi(struct i2c_algo_bit_data *adap) | |||
103 | * chips may hold it low ("clock stretching") while they | 103 | * chips may hold it low ("clock stretching") while they |
104 | * are processing data internally. | 104 | * are processing data internally. |
105 | */ | 105 | */ |
106 | if (time_after(jiffies, start + adap->timeout)) | 106 | if (time_after(jiffies, start + adap->timeout)) { |
107 | /* Test one last time, as we may have been preempted | ||
108 | * between last check and timeout test. | ||
109 | */ | ||
110 | if (getscl(adap)) | ||
111 | break; | ||
107 | return -ETIMEDOUT; | 112 | return -ETIMEDOUT; |
113 | } | ||
108 | cond_resched(); | 114 | cond_resched(); |
109 | } | 115 | } |
110 | #ifdef DEBUG | 116 | #ifdef DEBUG |
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c index 7e78f7c87857..3d471d56bf15 100644 --- a/drivers/i2c/busses/i2c-mxs.c +++ b/drivers/i2c/busses/i2c-mxs.c | |||
@@ -72,6 +72,7 @@ | |||
72 | 72 | ||
73 | #define MXS_I2C_QUEUESTAT (0x70) | 73 | #define MXS_I2C_QUEUESTAT (0x70) |
74 | #define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 | 74 | #define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000 |
75 | #define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F | ||
75 | 76 | ||
76 | #define MXS_I2C_QUEUECMD (0x80) | 77 | #define MXS_I2C_QUEUECMD (0x80) |
77 | 78 | ||
@@ -219,14 +220,14 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, | |||
219 | int ret; | 220 | int ret; |
220 | int flags; | 221 | int flags; |
221 | 222 | ||
222 | init_completion(&i2c->cmd_complete); | ||
223 | |||
224 | dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", | 223 | dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n", |
225 | msg->addr, msg->len, msg->flags, stop); | 224 | msg->addr, msg->len, msg->flags, stop); |
226 | 225 | ||
227 | if (msg->len == 0) | 226 | if (msg->len == 0) |
228 | return -EINVAL; | 227 | return -EINVAL; |
229 | 228 | ||
229 | init_completion(&i2c->cmd_complete); | ||
230 | |||
230 | flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; | 231 | flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0; |
231 | 232 | ||
232 | if (msg->flags & I2C_M_RD) | 233 | if (msg->flags & I2C_M_RD) |
@@ -286,6 +287,7 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) | |||
286 | { | 287 | { |
287 | struct mxs_i2c_dev *i2c = dev_id; | 288 | struct mxs_i2c_dev *i2c = dev_id; |
288 | u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; | 289 | u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK; |
290 | bool is_last_cmd; | ||
289 | 291 | ||
290 | if (!stat) | 292 | if (!stat) |
291 | return IRQ_NONE; | 293 | return IRQ_NONE; |
@@ -300,9 +302,14 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id) | |||
300 | else | 302 | else |
301 | i2c->cmd_err = 0; | 303 | i2c->cmd_err = 0; |
302 | 304 | ||
303 | complete(&i2c->cmd_complete); | 305 | is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) & |
306 | MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0; | ||
307 | |||
308 | if (is_last_cmd || i2c->cmd_err) | ||
309 | complete(&i2c->cmd_complete); | ||
304 | 310 | ||
305 | writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); | 311 | writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR); |
312 | |||
306 | return IRQ_HANDLED; | 313 | return IRQ_HANDLED; |
307 | } | 314 | } |
308 | 315 | ||
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 1e5606185b4f..e9c18939eda7 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -1386,8 +1386,10 @@ int i2c_master_send(const struct i2c_client *client, const char *buf, int count) | |||
1386 | 1386 | ||
1387 | ret = i2c_transfer(adap, &msg, 1); | 1387 | ret = i2c_transfer(adap, &msg, 1); |
1388 | 1388 | ||
1389 | /* If everything went ok (i.e. 1 msg transmitted), return #bytes | 1389 | /* |
1390 | transmitted, else error code. */ | 1390 | * If everything went ok (i.e. 1 msg transmitted), return #bytes |
1391 | * transmitted, else error code. | ||
1392 | */ | ||
1391 | return (ret == 1) ? count : ret; | 1393 | return (ret == 1) ? count : ret; |
1392 | } | 1394 | } |
1393 | EXPORT_SYMBOL(i2c_master_send); | 1395 | EXPORT_SYMBOL(i2c_master_send); |
@@ -1414,8 +1416,10 @@ int i2c_master_recv(const struct i2c_client *client, char *buf, int count) | |||
1414 | 1416 | ||
1415 | ret = i2c_transfer(adap, &msg, 1); | 1417 | ret = i2c_transfer(adap, &msg, 1); |
1416 | 1418 | ||
1417 | /* If everything went ok (i.e. 1 msg transmitted), return #bytes | 1419 | /* |
1418 | transmitted, else error code. */ | 1420 | * If everything went ok (i.e. 1 msg received), return #bytes received, |
1421 | * else error code. | ||
1422 | */ | ||
1419 | return (ret == 1) ? count : ret; | 1423 | return (ret == 1) ? count : ret; |
1420 | } | 1424 | } |
1421 | EXPORT_SYMBOL(i2c_master_recv); | 1425 | EXPORT_SYMBOL(i2c_master_recv); |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index afc166fcc3d9..7df5bfef2624 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -332,7 +332,7 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, | |||
332 | struct evdev_client *client = file->private_data; | 332 | struct evdev_client *client = file->private_data; |
333 | struct evdev *evdev = client->evdev; | 333 | struct evdev *evdev = client->evdev; |
334 | struct input_event event; | 334 | struct input_event event; |
335 | int retval; | 335 | int retval = 0; |
336 | 336 | ||
337 | if (count < input_event_size()) | 337 | if (count < input_event_size()) |
338 | return -EINVAL; | 338 | return -EINVAL; |
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c index 37651373a95b..f3bc4189a7ba 100644 --- a/drivers/input/misc/twl4030-vibra.c +++ b/drivers/input/misc/twl4030-vibra.c | |||
@@ -172,7 +172,7 @@ static void twl4030_vibra_close(struct input_dev *input) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | /*** Module ***/ | 174 | /*** Module ***/ |
175 | #if CONFIG_PM | 175 | #if CONFIG_PM_SLEEP |
176 | static int twl4030_vibra_suspend(struct device *dev) | 176 | static int twl4030_vibra_suspend(struct device *dev) |
177 | { | 177 | { |
178 | struct platform_device *pdev = to_platform_device(dev); | 178 | struct platform_device *pdev = to_platform_device(dev); |
@@ -189,10 +189,10 @@ static int twl4030_vibra_resume(struct device *dev) | |||
189 | vibra_disable_leds(); | 189 | vibra_disable_leds(); |
190 | return 0; | 190 | return 0; |
191 | } | 191 | } |
192 | #endif | ||
192 | 193 | ||
193 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, | 194 | static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops, |
194 | twl4030_vibra_suspend, twl4030_vibra_resume); | 195 | twl4030_vibra_suspend, twl4030_vibra_resume); |
195 | #endif | ||
196 | 196 | ||
197 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) | 197 | static int __devinit twl4030_vibra_probe(struct platform_device *pdev) |
198 | { | 198 | { |
@@ -273,9 +273,7 @@ static struct platform_driver twl4030_vibra_driver = { | |||
273 | .driver = { | 273 | .driver = { |
274 | .name = "twl4030-vibra", | 274 | .name = "twl4030-vibra", |
275 | .owner = THIS_MODULE, | 275 | .owner = THIS_MODULE, |
276 | #ifdef CONFIG_PM | ||
277 | .pm = &twl4030_vibra_pm_ops, | 276 | .pm = &twl4030_vibra_pm_ops, |
278 | #endif | ||
279 | }, | 277 | }, |
280 | }; | 278 | }; |
281 | module_platform_driver(twl4030_vibra_driver); | 279 | module_platform_driver(twl4030_vibra_driver); |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index bd87380bd879..4c6a72d3d48c 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -952,7 +952,9 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
952 | 952 | ||
953 | /* | 953 | /* |
954 | * First try "E6 report". | 954 | * First try "E6 report". |
955 | * ALPS should return 0,0,10 or 0,0,100 | 955 | * ALPS should return 0,0,10 or 0,0,100 if no buttons are pressed. |
956 | * The bits 0-2 of the first byte will be 1s if some buttons are | ||
957 | * pressed. | ||
956 | */ | 958 | */ |
957 | param[0] = 0; | 959 | param[0] = 0; |
958 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || | 960 | if (ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES) || |
@@ -968,7 +970,8 @@ static const struct alps_model_info *alps_get_model(struct psmouse *psmouse, int | |||
968 | psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x", | 970 | psmouse_dbg(psmouse, "E6 report: %2.2x %2.2x %2.2x", |
969 | param[0], param[1], param[2]); | 971 | param[0], param[1], param[2]); |
970 | 972 | ||
971 | if (param[0] != 0 || param[1] != 0 || (param[2] != 10 && param[2] != 100)) | 973 | if ((param[0] & 0xf8) != 0 || param[1] != 0 || |
974 | (param[2] != 10 && param[2] != 100)) | ||
972 | return NULL; | 975 | return NULL; |
973 | 976 | ||
974 | /* | 977 | /* |
diff --git a/drivers/input/tablet/Kconfig b/drivers/input/tablet/Kconfig index 58a87755b936..e53f4081a586 100644 --- a/drivers/input/tablet/Kconfig +++ b/drivers/input/tablet/Kconfig | |||
@@ -77,6 +77,8 @@ config TABLET_USB_WACOM | |||
77 | tristate "Wacom Intuos/Graphire tablet support (USB)" | 77 | tristate "Wacom Intuos/Graphire tablet support (USB)" |
78 | depends on USB_ARCH_HAS_HCD | 78 | depends on USB_ARCH_HAS_HCD |
79 | select USB | 79 | select USB |
80 | select NEW_LEDS | ||
81 | select LEDS_CLASS | ||
80 | help | 82 | help |
81 | Say Y here if you want to use the USB version of the Wacom Intuos | 83 | Say Y here if you want to use the USB version of the Wacom Intuos |
82 | or Graphire tablet. Make sure to say Y to "Mouse support" | 84 | or Graphire tablet. Make sure to say Y to "Mouse support" |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 88672ec296c1..cd3ed29e0801 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -926,7 +926,7 @@ static int wacom_bpt3_touch(struct wacom_wac *wacom) | |||
926 | { | 926 | { |
927 | struct input_dev *input = wacom->input; | 927 | struct input_dev *input = wacom->input; |
928 | unsigned char *data = wacom->data; | 928 | unsigned char *data = wacom->data; |
929 | int count = data[1] & 0x03; | 929 | int count = data[1] & 0x07; |
930 | int i; | 930 | int i; |
931 | 931 | ||
932 | if (data[0] != 0x02) | 932 | if (data[0] != 0x02) |
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 6bea6962f8ee..3bd9fff5c589 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig | |||
@@ -142,4 +142,24 @@ config OMAP_IOMMU_DEBUG | |||
142 | 142 | ||
143 | Say N unless you know you need this. | 143 | Say N unless you know you need this. |
144 | 144 | ||
145 | config TEGRA_IOMMU_GART | ||
146 | bool "Tegra GART IOMMU Support" | ||
147 | depends on ARCH_TEGRA_2x_SOC | ||
148 | select IOMMU_API | ||
149 | help | ||
150 | Enables support for remapping discontiguous physical memory | ||
151 | shared with the operating system into contiguous I/O virtual | ||
152 | space through the GART (Graphics Address Relocation Table) | ||
153 | hardware included on Tegra SoCs. | ||
154 | |||
155 | config TEGRA_IOMMU_SMMU | ||
156 | bool "Tegra SMMU IOMMU Support" | ||
157 | depends on ARCH_TEGRA_3x_SOC | ||
158 | select IOMMU_API | ||
159 | help | ||
160 | Enables support for remapping discontiguous physical memory | ||
161 | shared with the operating system into contiguous I/O virtual | ||
162 | space through the SMMU (System Memory Management Unit) | ||
163 | hardware included on Tegra SoCs. | ||
164 | |||
145 | endif # IOMMU_SUPPORT | 165 | endif # IOMMU_SUPPORT |
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 0e36b4934aff..7ad7a3bc1242 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile | |||
@@ -8,3 +8,5 @@ obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o | |||
8 | obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o | 8 | obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o |
9 | obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o | 9 | obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o |
10 | obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o | 10 | obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o |
11 | obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o | ||
12 | obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o | ||
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index a051f9a88bd2..c56790375e0f 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -277,7 +277,7 @@ static void iommu_set_exclusion_range(struct amd_iommu *iommu) | |||
277 | } | 277 | } |
278 | 278 | ||
279 | /* Programs the physical address of the device table into the IOMMU hardware */ | 279 | /* Programs the physical address of the device table into the IOMMU hardware */ |
280 | static void __init iommu_set_device_table(struct amd_iommu *iommu) | 280 | static void iommu_set_device_table(struct amd_iommu *iommu) |
281 | { | 281 | { |
282 | u64 entry; | 282 | u64 entry; |
283 | 283 | ||
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c index 288da5c1499d..103dbd92e256 100644 --- a/drivers/iommu/omap-iommu-debug.c +++ b/drivers/iommu/omap-iommu-debug.c | |||
@@ -44,7 +44,8 @@ static ssize_t debug_read_ver(struct file *file, char __user *userbuf, | |||
44 | static ssize_t debug_read_regs(struct file *file, char __user *userbuf, | 44 | static ssize_t debug_read_regs(struct file *file, char __user *userbuf, |
45 | size_t count, loff_t *ppos) | 45 | size_t count, loff_t *ppos) |
46 | { | 46 | { |
47 | struct omap_iommu *obj = file->private_data; | 47 | struct device *dev = file->private_data; |
48 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
48 | char *p, *buf; | 49 | char *p, *buf; |
49 | ssize_t bytes; | 50 | ssize_t bytes; |
50 | 51 | ||
@@ -67,7 +68,8 @@ static ssize_t debug_read_regs(struct file *file, char __user *userbuf, | |||
67 | static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, | 68 | static ssize_t debug_read_tlb(struct file *file, char __user *userbuf, |
68 | size_t count, loff_t *ppos) | 69 | size_t count, loff_t *ppos) |
69 | { | 70 | { |
70 | struct omap_iommu *obj = file->private_data; | 71 | struct device *dev = file->private_data; |
72 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
71 | char *p, *buf; | 73 | char *p, *buf; |
72 | ssize_t bytes, rest; | 74 | ssize_t bytes, rest; |
73 | 75 | ||
@@ -97,7 +99,8 @@ static ssize_t debug_write_pagetable(struct file *file, | |||
97 | struct iotlb_entry e; | 99 | struct iotlb_entry e; |
98 | struct cr_regs cr; | 100 | struct cr_regs cr; |
99 | int err; | 101 | int err; |
100 | struct omap_iommu *obj = file->private_data; | 102 | struct device *dev = file->private_data; |
103 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
101 | char buf[MAXCOLUMN], *p = buf; | 104 | char buf[MAXCOLUMN], *p = buf; |
102 | 105 | ||
103 | count = min(count, sizeof(buf)); | 106 | count = min(count, sizeof(buf)); |
@@ -184,7 +187,8 @@ out: | |||
184 | static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, | 187 | static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, |
185 | size_t count, loff_t *ppos) | 188 | size_t count, loff_t *ppos) |
186 | { | 189 | { |
187 | struct omap_iommu *obj = file->private_data; | 190 | struct device *dev = file->private_data; |
191 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
188 | char *p, *buf; | 192 | char *p, *buf; |
189 | size_t bytes; | 193 | size_t bytes; |
190 | 194 | ||
@@ -212,7 +216,8 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf, | |||
212 | static ssize_t debug_read_mmap(struct file *file, char __user *userbuf, | 216 | static ssize_t debug_read_mmap(struct file *file, char __user *userbuf, |
213 | size_t count, loff_t *ppos) | 217 | size_t count, loff_t *ppos) |
214 | { | 218 | { |
215 | struct omap_iommu *obj = file->private_data; | 219 | struct device *dev = file->private_data; |
220 | struct omap_iommu *obj = dev_to_omap_iommu(dev); | ||
216 | char *p, *buf; | 221 | char *p, *buf; |
217 | struct iovm_struct *tmp; | 222 | struct iovm_struct *tmp; |
218 | int uninitialized_var(i); | 223 | int uninitialized_var(i); |
@@ -254,7 +259,7 @@ static ssize_t debug_read_mmap(struct file *file, char __user *userbuf, | |||
254 | static ssize_t debug_read_mem(struct file *file, char __user *userbuf, | 259 | static ssize_t debug_read_mem(struct file *file, char __user *userbuf, |
255 | size_t count, loff_t *ppos) | 260 | size_t count, loff_t *ppos) |
256 | { | 261 | { |
257 | struct omap_iommu *obj = file->private_data; | 262 | struct device *dev = file->private_data; |
258 | char *p, *buf; | 263 | char *p, *buf; |
259 | struct iovm_struct *area; | 264 | struct iovm_struct *area; |
260 | ssize_t bytes; | 265 | ssize_t bytes; |
@@ -268,8 +273,8 @@ static ssize_t debug_read_mem(struct file *file, char __user *userbuf, | |||
268 | 273 | ||
269 | mutex_lock(&iommu_debug_lock); | 274 | mutex_lock(&iommu_debug_lock); |
270 | 275 | ||
271 | area = omap_find_iovm_area(obj, (u32)ppos); | 276 | area = omap_find_iovm_area(dev, (u32)ppos); |
272 | if (IS_ERR(area)) { | 277 | if (!area) { |
273 | bytes = -EINVAL; | 278 | bytes = -EINVAL; |
274 | goto err_out; | 279 | goto err_out; |
275 | } | 280 | } |
@@ -287,7 +292,7 @@ err_out: | |||
287 | static ssize_t debug_write_mem(struct file *file, const char __user *userbuf, | 292 | static ssize_t debug_write_mem(struct file *file, const char __user *userbuf, |
288 | size_t count, loff_t *ppos) | 293 | size_t count, loff_t *ppos) |
289 | { | 294 | { |
290 | struct omap_iommu *obj = file->private_data; | 295 | struct device *dev = file->private_data; |
291 | struct iovm_struct *area; | 296 | struct iovm_struct *area; |
292 | char *p, *buf; | 297 | char *p, *buf; |
293 | 298 | ||
@@ -305,8 +310,8 @@ static ssize_t debug_write_mem(struct file *file, const char __user *userbuf, | |||
305 | goto err_out; | 310 | goto err_out; |
306 | } | 311 | } |
307 | 312 | ||
308 | area = omap_find_iovm_area(obj, (u32)ppos); | 313 | area = omap_find_iovm_area(dev, (u32)ppos); |
309 | if (IS_ERR(area)) { | 314 | if (!area) { |
310 | count = -EINVAL; | 315 | count = -EINVAL; |
311 | goto err_out; | 316 | goto err_out; |
312 | } | 317 | } |
@@ -350,7 +355,7 @@ DEBUG_FOPS(mem); | |||
350 | { \ | 355 | { \ |
351 | struct dentry *dent; \ | 356 | struct dentry *dent; \ |
352 | dent = debugfs_create_file(#attr, mode, parent, \ | 357 | dent = debugfs_create_file(#attr, mode, parent, \ |
353 | obj, &debug_##attr##_fops); \ | 358 | dev, &debug_##attr##_fops); \ |
354 | if (!dent) \ | 359 | if (!dent) \ |
355 | return -ENOMEM; \ | 360 | return -ENOMEM; \ |
356 | } | 361 | } |
@@ -362,20 +367,29 @@ static int iommu_debug_register(struct device *dev, void *data) | |||
362 | { | 367 | { |
363 | struct platform_device *pdev = to_platform_device(dev); | 368 | struct platform_device *pdev = to_platform_device(dev); |
364 | struct omap_iommu *obj = platform_get_drvdata(pdev); | 369 | struct omap_iommu *obj = platform_get_drvdata(pdev); |
370 | struct omap_iommu_arch_data *arch_data; | ||
365 | struct dentry *d, *parent; | 371 | struct dentry *d, *parent; |
366 | 372 | ||
367 | if (!obj || !obj->dev) | 373 | if (!obj || !obj->dev) |
368 | return -EINVAL; | 374 | return -EINVAL; |
369 | 375 | ||
376 | arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL); | ||
377 | if (!arch_data) | ||
378 | return -ENOMEM; | ||
379 | |||
380 | arch_data->iommu_dev = obj; | ||
381 | |||
382 | dev->archdata.iommu = arch_data; | ||
383 | |||
370 | d = debugfs_create_dir(obj->name, iommu_debug_root); | 384 | d = debugfs_create_dir(obj->name, iommu_debug_root); |
371 | if (!d) | 385 | if (!d) |
372 | return -ENOMEM; | 386 | goto nomem; |
373 | parent = d; | 387 | parent = d; |
374 | 388 | ||
375 | d = debugfs_create_u8("nr_tlb_entries", 400, parent, | 389 | d = debugfs_create_u8("nr_tlb_entries", 400, parent, |
376 | (u8 *)&obj->nr_tlb_entries); | 390 | (u8 *)&obj->nr_tlb_entries); |
377 | if (!d) | 391 | if (!d) |
378 | return -ENOMEM; | 392 | goto nomem; |
379 | 393 | ||
380 | DEBUG_ADD_FILE_RO(ver); | 394 | DEBUG_ADD_FILE_RO(ver); |
381 | DEBUG_ADD_FILE_RO(regs); | 395 | DEBUG_ADD_FILE_RO(regs); |
@@ -385,6 +399,22 @@ static int iommu_debug_register(struct device *dev, void *data) | |||
385 | DEBUG_ADD_FILE(mem); | 399 | DEBUG_ADD_FILE(mem); |
386 | 400 | ||
387 | return 0; | 401 | return 0; |
402 | |||
403 | nomem: | ||
404 | kfree(arch_data); | ||
405 | return -ENOMEM; | ||
406 | } | ||
407 | |||
408 | static int iommu_debug_unregister(struct device *dev, void *data) | ||
409 | { | ||
410 | if (!dev->archdata.iommu) | ||
411 | return 0; | ||
412 | |||
413 | kfree(dev->archdata.iommu); | ||
414 | |||
415 | dev->archdata.iommu = NULL; | ||
416 | |||
417 | return 0; | ||
388 | } | 418 | } |
389 | 419 | ||
390 | static int __init iommu_debug_init(void) | 420 | static int __init iommu_debug_init(void) |
@@ -411,6 +441,7 @@ module_init(iommu_debug_init) | |||
411 | static void __exit iommu_debugfs_exit(void) | 441 | static void __exit iommu_debugfs_exit(void) |
412 | { | 442 | { |
413 | debugfs_remove_recursive(iommu_debug_root); | 443 | debugfs_remove_recursive(iommu_debug_root); |
444 | omap_foreach_iommu_device(NULL, iommu_debug_unregister); | ||
414 | } | 445 | } |
415 | module_exit(iommu_debugfs_exit) | 446 | module_exit(iommu_debugfs_exit) |
416 | 447 | ||
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c index d8edd979d01b..6899dcd02dfa 100644 --- a/drivers/iommu/omap-iommu.c +++ b/drivers/iommu/omap-iommu.c | |||
@@ -1223,7 +1223,8 @@ static int __init omap_iommu_init(void) | |||
1223 | 1223 | ||
1224 | return platform_driver_register(&omap_iommu_driver); | 1224 | return platform_driver_register(&omap_iommu_driver); |
1225 | } | 1225 | } |
1226 | module_init(omap_iommu_init); | 1226 | /* must be ready before omap3isp is probed */ |
1227 | subsys_initcall(omap_iommu_init); | ||
1227 | 1228 | ||
1228 | static void __exit omap_iommu_exit(void) | 1229 | static void __exit omap_iommu_exit(void) |
1229 | { | 1230 | { |
diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c new file mode 100644 index 000000000000..779306ee7b16 --- /dev/null +++ b/drivers/iommu/tegra-gart.c | |||
@@ -0,0 +1,451 @@ | |||
1 | /* | ||
2 | * IOMMU API for GART in Tegra20 | ||
3 | * | ||
4 | * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #define pr_fmt(fmt) "%s(): " fmt, __func__ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/vmalloc.h> | ||
27 | #include <linux/mm.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/iommu.h> | ||
32 | |||
33 | #include <asm/cacheflush.h> | ||
34 | |||
35 | /* bitmap of the page sizes currently supported */ | ||
36 | #define GART_IOMMU_PGSIZES (SZ_4K) | ||
37 | |||
38 | #define GART_CONFIG 0x24 | ||
39 | #define GART_ENTRY_ADDR 0x28 | ||
40 | #define GART_ENTRY_DATA 0x2c | ||
41 | #define GART_ENTRY_PHYS_ADDR_VALID (1 << 31) | ||
42 | |||
43 | #define GART_PAGE_SHIFT 12 | ||
44 | #define GART_PAGE_SIZE (1 << GART_PAGE_SHIFT) | ||
45 | #define GART_PAGE_MASK \ | ||
46 | (~(GART_PAGE_SIZE - 1) & ~GART_ENTRY_PHYS_ADDR_VALID) | ||
47 | |||
48 | struct gart_client { | ||
49 | struct device *dev; | ||
50 | struct list_head list; | ||
51 | }; | ||
52 | |||
53 | struct gart_device { | ||
54 | void __iomem *regs; | ||
55 | u32 *savedata; | ||
56 | u32 page_count; /* total remappable size */ | ||
57 | dma_addr_t iovmm_base; /* offset to vmm_area */ | ||
58 | spinlock_t pte_lock; /* for pagetable */ | ||
59 | struct list_head client; | ||
60 | spinlock_t client_lock; /* for client list */ | ||
61 | struct device *dev; | ||
62 | }; | ||
63 | |||
64 | static struct gart_device *gart_handle; /* unique for a system */ | ||
65 | |||
66 | #define GART_PTE(_pfn) \ | ||
67 | (GART_ENTRY_PHYS_ADDR_VALID | ((_pfn) << PAGE_SHIFT)) | ||
68 | |||
69 | /* | ||
70 | * Any interaction between any block on PPSB and a block on APB or AHB | ||
71 | * must have these read-back to ensure the APB/AHB bus transaction is | ||
72 | * complete before initiating activity on the PPSB block. | ||
73 | */ | ||
74 | #define FLUSH_GART_REGS(gart) ((void)readl((gart)->regs + GART_CONFIG)) | ||
75 | |||
76 | #define for_each_gart_pte(gart, iova) \ | ||
77 | for (iova = gart->iovmm_base; \ | ||
78 | iova < gart->iovmm_base + GART_PAGE_SIZE * gart->page_count; \ | ||
79 | iova += GART_PAGE_SIZE) | ||
80 | |||
81 | static inline void gart_set_pte(struct gart_device *gart, | ||
82 | unsigned long offs, u32 pte) | ||
83 | { | ||
84 | writel(offs, gart->regs + GART_ENTRY_ADDR); | ||
85 | writel(pte, gart->regs + GART_ENTRY_DATA); | ||
86 | |||
87 | dev_dbg(gart->dev, "%s %08lx:%08x\n", | ||
88 | pte ? "map" : "unmap", offs, pte & GART_PAGE_MASK); | ||
89 | } | ||
90 | |||
91 | static inline unsigned long gart_read_pte(struct gart_device *gart, | ||
92 | unsigned long offs) | ||
93 | { | ||
94 | unsigned long pte; | ||
95 | |||
96 | writel(offs, gart->regs + GART_ENTRY_ADDR); | ||
97 | pte = readl(gart->regs + GART_ENTRY_DATA); | ||
98 | |||
99 | return pte; | ||
100 | } | ||
101 | |||
102 | static void do_gart_setup(struct gart_device *gart, const u32 *data) | ||
103 | { | ||
104 | unsigned long iova; | ||
105 | |||
106 | for_each_gart_pte(gart, iova) | ||
107 | gart_set_pte(gart, iova, data ? *(data++) : 0); | ||
108 | |||
109 | writel(1, gart->regs + GART_CONFIG); | ||
110 | FLUSH_GART_REGS(gart); | ||
111 | } | ||
112 | |||
113 | #ifdef DEBUG | ||
114 | static void gart_dump_table(struct gart_device *gart) | ||
115 | { | ||
116 | unsigned long iova; | ||
117 | unsigned long flags; | ||
118 | |||
119 | spin_lock_irqsave(&gart->pte_lock, flags); | ||
120 | for_each_gart_pte(gart, iova) { | ||
121 | unsigned long pte; | ||
122 | |||
123 | pte = gart_read_pte(gart, iova); | ||
124 | |||
125 | dev_dbg(gart->dev, "%s %08lx:%08lx\n", | ||
126 | (GART_ENTRY_PHYS_ADDR_VALID & pte) ? "v" : " ", | ||
127 | iova, pte & GART_PAGE_MASK); | ||
128 | } | ||
129 | spin_unlock_irqrestore(&gart->pte_lock, flags); | ||
130 | } | ||
131 | #else | ||
132 | static inline void gart_dump_table(struct gart_device *gart) | ||
133 | { | ||
134 | } | ||
135 | #endif | ||
136 | |||
137 | static inline bool gart_iova_range_valid(struct gart_device *gart, | ||
138 | unsigned long iova, size_t bytes) | ||
139 | { | ||
140 | unsigned long iova_start, iova_end, gart_start, gart_end; | ||
141 | |||
142 | iova_start = iova; | ||
143 | iova_end = iova_start + bytes - 1; | ||
144 | gart_start = gart->iovmm_base; | ||
145 | gart_end = gart_start + gart->page_count * GART_PAGE_SIZE - 1; | ||
146 | |||
147 | if (iova_start < gart_start) | ||
148 | return false; | ||
149 | if (iova_end > gart_end) | ||
150 | return false; | ||
151 | return true; | ||
152 | } | ||
153 | |||
154 | static int gart_iommu_attach_dev(struct iommu_domain *domain, | ||
155 | struct device *dev) | ||
156 | { | ||
157 | struct gart_device *gart; | ||
158 | struct gart_client *client, *c; | ||
159 | int err = 0; | ||
160 | |||
161 | gart = dev_get_drvdata(dev->parent); | ||
162 | if (!gart) | ||
163 | return -EINVAL; | ||
164 | domain->priv = gart; | ||
165 | |||
166 | client = devm_kzalloc(gart->dev, sizeof(*c), GFP_KERNEL); | ||
167 | if (!client) | ||
168 | return -ENOMEM; | ||
169 | client->dev = dev; | ||
170 | |||
171 | spin_lock(&gart->client_lock); | ||
172 | list_for_each_entry(c, &gart->client, list) { | ||
173 | if (c->dev == dev) { | ||
174 | dev_err(gart->dev, | ||
175 | "%s is already attached\n", dev_name(dev)); | ||
176 | err = -EINVAL; | ||
177 | goto fail; | ||
178 | } | ||
179 | } | ||
180 | list_add(&client->list, &gart->client); | ||
181 | spin_unlock(&gart->client_lock); | ||
182 | dev_dbg(gart->dev, "Attached %s\n", dev_name(dev)); | ||
183 | return 0; | ||
184 | |||
185 | fail: | ||
186 | devm_kfree(gart->dev, client); | ||
187 | spin_unlock(&gart->client_lock); | ||
188 | return err; | ||
189 | } | ||
190 | |||
191 | static void gart_iommu_detach_dev(struct iommu_domain *domain, | ||
192 | struct device *dev) | ||
193 | { | ||
194 | struct gart_device *gart = domain->priv; | ||
195 | struct gart_client *c; | ||
196 | |||
197 | spin_lock(&gart->client_lock); | ||
198 | |||
199 | list_for_each_entry(c, &gart->client, list) { | ||
200 | if (c->dev == dev) { | ||
201 | list_del(&c->list); | ||
202 | devm_kfree(gart->dev, c); | ||
203 | dev_dbg(gart->dev, "Detached %s\n", dev_name(dev)); | ||
204 | goto out; | ||
205 | } | ||
206 | } | ||
207 | dev_err(gart->dev, "Couldn't find\n"); | ||
208 | out: | ||
209 | spin_unlock(&gart->client_lock); | ||
210 | } | ||
211 | |||
212 | static int gart_iommu_domain_init(struct iommu_domain *domain) | ||
213 | { | ||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static void gart_iommu_domain_destroy(struct iommu_domain *domain) | ||
218 | { | ||
219 | struct gart_device *gart = domain->priv; | ||
220 | |||
221 | if (!gart) | ||
222 | return; | ||
223 | |||
224 | spin_lock(&gart->client_lock); | ||
225 | if (!list_empty(&gart->client)) { | ||
226 | struct gart_client *c; | ||
227 | |||
228 | list_for_each_entry(c, &gart->client, list) | ||
229 | gart_iommu_detach_dev(domain, c->dev); | ||
230 | } | ||
231 | spin_unlock(&gart->client_lock); | ||
232 | domain->priv = NULL; | ||
233 | } | ||
234 | |||
235 | static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova, | ||
236 | phys_addr_t pa, size_t bytes, int prot) | ||
237 | { | ||
238 | struct gart_device *gart = domain->priv; | ||
239 | unsigned long flags; | ||
240 | unsigned long pfn; | ||
241 | |||
242 | if (!gart_iova_range_valid(gart, iova, bytes)) | ||
243 | return -EINVAL; | ||
244 | |||
245 | spin_lock_irqsave(&gart->pte_lock, flags); | ||
246 | pfn = __phys_to_pfn(pa); | ||
247 | if (!pfn_valid(pfn)) { | ||
248 | dev_err(gart->dev, "Invalid page: %08x\n", pa); | ||
249 | spin_unlock_irqrestore(&gart->pte_lock, flags); | ||
250 | return -EINVAL; | ||
251 | } | ||
252 | gart_set_pte(gart, iova, GART_PTE(pfn)); | ||
253 | FLUSH_GART_REGS(gart); | ||
254 | spin_unlock_irqrestore(&gart->pte_lock, flags); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova, | ||
259 | size_t bytes) | ||
260 | { | ||
261 | struct gart_device *gart = domain->priv; | ||
262 | unsigned long flags; | ||
263 | |||
264 | if (!gart_iova_range_valid(gart, iova, bytes)) | ||
265 | return 0; | ||
266 | |||
267 | spin_lock_irqsave(&gart->pte_lock, flags); | ||
268 | gart_set_pte(gart, iova, 0); | ||
269 | FLUSH_GART_REGS(gart); | ||
270 | spin_unlock_irqrestore(&gart->pte_lock, flags); | ||
271 | return 0; | ||
272 | } | ||
273 | |||
274 | static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain, | ||
275 | unsigned long iova) | ||
276 | { | ||
277 | struct gart_device *gart = domain->priv; | ||
278 | unsigned long pte; | ||
279 | phys_addr_t pa; | ||
280 | unsigned long flags; | ||
281 | |||
282 | if (!gart_iova_range_valid(gart, iova, 0)) | ||
283 | return -EINVAL; | ||
284 | |||
285 | spin_lock_irqsave(&gart->pte_lock, flags); | ||
286 | pte = gart_read_pte(gart, iova); | ||
287 | spin_unlock_irqrestore(&gart->pte_lock, flags); | ||
288 | |||
289 | pa = (pte & GART_PAGE_MASK); | ||
290 | if (!pfn_valid(__phys_to_pfn(pa))) { | ||
291 | dev_err(gart->dev, "No entry for %08lx:%08x\n", iova, pa); | ||
292 | gart_dump_table(gart); | ||
293 | return -EINVAL; | ||
294 | } | ||
295 | return pa; | ||
296 | } | ||
297 | |||
298 | static int gart_iommu_domain_has_cap(struct iommu_domain *domain, | ||
299 | unsigned long cap) | ||
300 | { | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static struct iommu_ops gart_iommu_ops = { | ||
305 | .domain_init = gart_iommu_domain_init, | ||
306 | .domain_destroy = gart_iommu_domain_destroy, | ||
307 | .attach_dev = gart_iommu_attach_dev, | ||
308 | .detach_dev = gart_iommu_detach_dev, | ||
309 | .map = gart_iommu_map, | ||
310 | .unmap = gart_iommu_unmap, | ||
311 | .iova_to_phys = gart_iommu_iova_to_phys, | ||
312 | .domain_has_cap = gart_iommu_domain_has_cap, | ||
313 | .pgsize_bitmap = GART_IOMMU_PGSIZES, | ||
314 | }; | ||
315 | |||
316 | static int tegra_gart_suspend(struct device *dev) | ||
317 | { | ||
318 | struct gart_device *gart = dev_get_drvdata(dev); | ||
319 | unsigned long iova; | ||
320 | u32 *data = gart->savedata; | ||
321 | unsigned long flags; | ||
322 | |||
323 | spin_lock_irqsave(&gart->pte_lock, flags); | ||
324 | for_each_gart_pte(gart, iova) | ||
325 | *(data++) = gart_read_pte(gart, iova); | ||
326 | spin_unlock_irqrestore(&gart->pte_lock, flags); | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static int tegra_gart_resume(struct device *dev) | ||
331 | { | ||
332 | struct gart_device *gart = dev_get_drvdata(dev); | ||
333 | unsigned long flags; | ||
334 | |||
335 | spin_lock_irqsave(&gart->pte_lock, flags); | ||
336 | do_gart_setup(gart, gart->savedata); | ||
337 | spin_unlock_irqrestore(&gart->pte_lock, flags); | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static int tegra_gart_probe(struct platform_device *pdev) | ||
342 | { | ||
343 | struct gart_device *gart; | ||
344 | struct resource *res, *res_remap; | ||
345 | void __iomem *gart_regs; | ||
346 | int err; | ||
347 | struct device *dev = &pdev->dev; | ||
348 | |||
349 | if (gart_handle) | ||
350 | return -EIO; | ||
351 | |||
352 | BUILD_BUG_ON(PAGE_SHIFT != GART_PAGE_SHIFT); | ||
353 | |||
354 | /* the GART memory aperture is required */ | ||
355 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
356 | res_remap = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
357 | if (!res || !res_remap) { | ||
358 | dev_err(dev, "GART memory aperture expected\n"); | ||
359 | return -ENXIO; | ||
360 | } | ||
361 | |||
362 | gart = devm_kzalloc(dev, sizeof(*gart), GFP_KERNEL); | ||
363 | if (!gart) { | ||
364 | dev_err(dev, "failed to allocate gart_device\n"); | ||
365 | return -ENOMEM; | ||
366 | } | ||
367 | |||
368 | gart_regs = devm_ioremap(dev, res->start, resource_size(res)); | ||
369 | if (!gart_regs) { | ||
370 | dev_err(dev, "failed to remap GART registers\n"); | ||
371 | err = -ENXIO; | ||
372 | goto fail; | ||
373 | } | ||
374 | |||
375 | gart->dev = &pdev->dev; | ||
376 | spin_lock_init(&gart->pte_lock); | ||
377 | spin_lock_init(&gart->client_lock); | ||
378 | INIT_LIST_HEAD(&gart->client); | ||
379 | gart->regs = gart_regs; | ||
380 | gart->iovmm_base = (dma_addr_t)res_remap->start; | ||
381 | gart->page_count = (resource_size(res_remap) >> GART_PAGE_SHIFT); | ||
382 | |||
383 | gart->savedata = vmalloc(sizeof(u32) * gart->page_count); | ||
384 | if (!gart->savedata) { | ||
385 | dev_err(dev, "failed to allocate context save area\n"); | ||
386 | err = -ENOMEM; | ||
387 | goto fail; | ||
388 | } | ||
389 | |||
390 | platform_set_drvdata(pdev, gart); | ||
391 | do_gart_setup(gart, NULL); | ||
392 | |||
393 | gart_handle = gart; | ||
394 | return 0; | ||
395 | |||
396 | fail: | ||
397 | if (gart_regs) | ||
398 | devm_iounmap(dev, gart_regs); | ||
399 | if (gart && gart->savedata) | ||
400 | vfree(gart->savedata); | ||
401 | devm_kfree(dev, gart); | ||
402 | return err; | ||
403 | } | ||
404 | |||
405 | static int tegra_gart_remove(struct platform_device *pdev) | ||
406 | { | ||
407 | struct gart_device *gart = platform_get_drvdata(pdev); | ||
408 | struct device *dev = gart->dev; | ||
409 | |||
410 | writel(0, gart->regs + GART_CONFIG); | ||
411 | if (gart->savedata) | ||
412 | vfree(gart->savedata); | ||
413 | if (gart->regs) | ||
414 | devm_iounmap(dev, gart->regs); | ||
415 | devm_kfree(dev, gart); | ||
416 | gart_handle = NULL; | ||
417 | return 0; | ||
418 | } | ||
419 | |||
420 | const struct dev_pm_ops tegra_gart_pm_ops = { | ||
421 | .suspend = tegra_gart_suspend, | ||
422 | .resume = tegra_gart_resume, | ||
423 | }; | ||
424 | |||
425 | static struct platform_driver tegra_gart_driver = { | ||
426 | .probe = tegra_gart_probe, | ||
427 | .remove = tegra_gart_remove, | ||
428 | .driver = { | ||
429 | .owner = THIS_MODULE, | ||
430 | .name = "tegra-gart", | ||
431 | .pm = &tegra_gart_pm_ops, | ||
432 | }, | ||
433 | }; | ||
434 | |||
435 | static int __devinit tegra_gart_init(void) | ||
436 | { | ||
437 | bus_set_iommu(&platform_bus_type, &gart_iommu_ops); | ||
438 | return platform_driver_register(&tegra_gart_driver); | ||
439 | } | ||
440 | |||
441 | static void __exit tegra_gart_exit(void) | ||
442 | { | ||
443 | platform_driver_unregister(&tegra_gart_driver); | ||
444 | } | ||
445 | |||
446 | subsys_initcall(tegra_gart_init); | ||
447 | module_exit(tegra_gart_exit); | ||
448 | |||
449 | MODULE_DESCRIPTION("IOMMU API for GART in Tegra20"); | ||
450 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); | ||
451 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c new file mode 100644 index 000000000000..eb93c821f592 --- /dev/null +++ b/drivers/iommu/tegra-smmu.c | |||
@@ -0,0 +1,1034 @@ | |||
1 | /* | ||
2 | * IOMMU API for SMMU in Tegra30 | ||
3 | * | ||
4 | * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms and conditions of the GNU General Public License, | ||
8 | * version 2, as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
13 | * more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License along with | ||
16 | * this program; if not, write to the Free Software Foundation, Inc., | ||
17 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
18 | */ | ||
19 | |||
20 | #define pr_fmt(fmt) "%s(): " fmt, __func__ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/vmalloc.h> | ||
27 | #include <linux/mm.h> | ||
28 | #include <linux/pagemap.h> | ||
29 | #include <linux/device.h> | ||
30 | #include <linux/sched.h> | ||
31 | #include <linux/iommu.h> | ||
32 | #include <linux/io.h> | ||
33 | |||
34 | #include <asm/page.h> | ||
35 | #include <asm/cacheflush.h> | ||
36 | |||
37 | #include <mach/iomap.h> | ||
38 | #include <mach/smmu.h> | ||
39 | |||
40 | /* bitmap of the page sizes currently supported */ | ||
41 | #define SMMU_IOMMU_PGSIZES (SZ_4K) | ||
42 | |||
43 | #define SMMU_CONFIG 0x10 | ||
44 | #define SMMU_CONFIG_DISABLE 0 | ||
45 | #define SMMU_CONFIG_ENABLE 1 | ||
46 | |||
47 | #define SMMU_TLB_CONFIG 0x14 | ||
48 | #define SMMU_TLB_CONFIG_STATS__MASK (1 << 31) | ||
49 | #define SMMU_TLB_CONFIG_STATS__ENABLE (1 << 31) | ||
50 | #define SMMU_TLB_CONFIG_HIT_UNDER_MISS__ENABLE (1 << 29) | ||
51 | #define SMMU_TLB_CONFIG_ACTIVE_LINES__VALUE 0x10 | ||
52 | #define SMMU_TLB_CONFIG_RESET_VAL 0x20000010 | ||
53 | |||
54 | #define SMMU_PTC_CONFIG 0x18 | ||
55 | #define SMMU_PTC_CONFIG_STATS__MASK (1 << 31) | ||
56 | #define SMMU_PTC_CONFIG_STATS__ENABLE (1 << 31) | ||
57 | #define SMMU_PTC_CONFIG_CACHE__ENABLE (1 << 29) | ||
58 | #define SMMU_PTC_CONFIG_INDEX_MAP__PATTERN 0x3f | ||
59 | #define SMMU_PTC_CONFIG_RESET_VAL 0x2000003f | ||
60 | |||
61 | #define SMMU_PTB_ASID 0x1c | ||
62 | #define SMMU_PTB_ASID_CURRENT_SHIFT 0 | ||
63 | |||
64 | #define SMMU_PTB_DATA 0x20 | ||
65 | #define SMMU_PTB_DATA_RESET_VAL 0 | ||
66 | #define SMMU_PTB_DATA_ASID_NONSECURE_SHIFT 29 | ||
67 | #define SMMU_PTB_DATA_ASID_WRITABLE_SHIFT 30 | ||
68 | #define SMMU_PTB_DATA_ASID_READABLE_SHIFT 31 | ||
69 | |||
70 | #define SMMU_TLB_FLUSH 0x30 | ||
71 | #define SMMU_TLB_FLUSH_VA_MATCH_ALL 0 | ||
72 | #define SMMU_TLB_FLUSH_VA_MATCH_SECTION 2 | ||
73 | #define SMMU_TLB_FLUSH_VA_MATCH_GROUP 3 | ||
74 | #define SMMU_TLB_FLUSH_ASID_SHIFT 29 | ||
75 | #define SMMU_TLB_FLUSH_ASID_MATCH_DISABLE 0 | ||
76 | #define SMMU_TLB_FLUSH_ASID_MATCH_ENABLE 1 | ||
77 | #define SMMU_TLB_FLUSH_ASID_MATCH_SHIFT 31 | ||
78 | |||
79 | #define SMMU_PTC_FLUSH 0x34 | ||
80 | #define SMMU_PTC_FLUSH_TYPE_ALL 0 | ||
81 | #define SMMU_PTC_FLUSH_TYPE_ADR 1 | ||
82 | #define SMMU_PTC_FLUSH_ADR_SHIFT 4 | ||
83 | |||
84 | #define SMMU_ASID_SECURITY 0x38 | ||
85 | |||
86 | #define SMMU_STATS_TLB_HIT_COUNT 0x1f0 | ||
87 | #define SMMU_STATS_TLB_MISS_COUNT 0x1f4 | ||
88 | #define SMMU_STATS_PTC_HIT_COUNT 0x1f8 | ||
89 | #define SMMU_STATS_PTC_MISS_COUNT 0x1fc | ||
90 | |||
91 | #define SMMU_TRANSLATION_ENABLE_0 0x228 | ||
92 | #define SMMU_TRANSLATION_ENABLE_1 0x22c | ||
93 | #define SMMU_TRANSLATION_ENABLE_2 0x230 | ||
94 | |||
95 | #define SMMU_AFI_ASID 0x238 /* PCIE */ | ||
96 | #define SMMU_AVPC_ASID 0x23c /* AVP */ | ||
97 | #define SMMU_DC_ASID 0x240 /* Display controller */ | ||
98 | #define SMMU_DCB_ASID 0x244 /* Display controller B */ | ||
99 | #define SMMU_EPP_ASID 0x248 /* Encoder pre-processor */ | ||
100 | #define SMMU_G2_ASID 0x24c /* 2D engine */ | ||
101 | #define SMMU_HC_ASID 0x250 /* Host1x */ | ||
102 | #define SMMU_HDA_ASID 0x254 /* High-def audio */ | ||
103 | #define SMMU_ISP_ASID 0x258 /* Image signal processor */ | ||
104 | #define SMMU_MPE_ASID 0x264 /* MPEG encoder */ | ||
105 | #define SMMU_NV_ASID 0x268 /* (3D) */ | ||
106 | #define SMMU_NV2_ASID 0x26c /* (3D) */ | ||
107 | #define SMMU_PPCS_ASID 0x270 /* AHB */ | ||
108 | #define SMMU_SATA_ASID 0x278 /* SATA */ | ||
109 | #define SMMU_VDE_ASID 0x27c /* Video decoder */ | ||
110 | #define SMMU_VI_ASID 0x280 /* Video input */ | ||
111 | |||
112 | #define SMMU_PDE_NEXT_SHIFT 28 | ||
113 | |||
114 | /* AHB Arbiter Registers */ | ||
115 | #define AHB_XBAR_CTRL 0xe0 | ||
116 | #define AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE 1 | ||
117 | #define AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT 17 | ||
118 | |||
119 | #define SMMU_NUM_ASIDS 4 | ||
120 | #define SMMU_TLB_FLUSH_VA_SECTION__MASK 0xffc00000 | ||
121 | #define SMMU_TLB_FLUSH_VA_SECTION__SHIFT 12 /* right shift */ | ||
122 | #define SMMU_TLB_FLUSH_VA_GROUP__MASK 0xffffc000 | ||
123 | #define SMMU_TLB_FLUSH_VA_GROUP__SHIFT 12 /* right shift */ | ||
124 | #define SMMU_TLB_FLUSH_VA(iova, which) \ | ||
125 | ((((iova) & SMMU_TLB_FLUSH_VA_##which##__MASK) >> \ | ||
126 | SMMU_TLB_FLUSH_VA_##which##__SHIFT) | \ | ||
127 | SMMU_TLB_FLUSH_VA_MATCH_##which) | ||
128 | #define SMMU_PTB_ASID_CUR(n) \ | ||
129 | ((n) << SMMU_PTB_ASID_CURRENT_SHIFT) | ||
130 | #define SMMU_TLB_FLUSH_ASID_MATCH_disable \ | ||
131 | (SMMU_TLB_FLUSH_ASID_MATCH_DISABLE << \ | ||
132 | SMMU_TLB_FLUSH_ASID_MATCH_SHIFT) | ||
133 | #define SMMU_TLB_FLUSH_ASID_MATCH__ENABLE \ | ||
134 | (SMMU_TLB_FLUSH_ASID_MATCH_ENABLE << \ | ||
135 | SMMU_TLB_FLUSH_ASID_MATCH_SHIFT) | ||
136 | |||
137 | #define SMMU_PAGE_SHIFT 12 | ||
138 | #define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT) | ||
139 | |||
140 | #define SMMU_PDIR_COUNT 1024 | ||
141 | #define SMMU_PDIR_SIZE (sizeof(unsigned long) * SMMU_PDIR_COUNT) | ||
142 | #define SMMU_PTBL_COUNT 1024 | ||
143 | #define SMMU_PTBL_SIZE (sizeof(unsigned long) * SMMU_PTBL_COUNT) | ||
144 | #define SMMU_PDIR_SHIFT 12 | ||
145 | #define SMMU_PDE_SHIFT 12 | ||
146 | #define SMMU_PTE_SHIFT 12 | ||
147 | #define SMMU_PFN_MASK 0x000fffff | ||
148 | |||
149 | #define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) | ||
150 | #define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) | ||
151 | #define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22) | ||
152 | |||
153 | #define _READABLE (1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT) | ||
154 | #define _WRITABLE (1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT) | ||
155 | #define _NONSECURE (1 << SMMU_PTB_DATA_ASID_NONSECURE_SHIFT) | ||
156 | #define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT) | ||
157 | #define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE) | ||
158 | |||
159 | #define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE) | ||
160 | |||
161 | #define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE) | ||
162 | #define _PDE_ATTR_N (_PDE_ATTR | _PDE_NEXT) | ||
163 | #define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR) | ||
164 | |||
165 | #define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE) | ||
166 | #define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR) | ||
167 | |||
168 | #define SMMU_MK_PDIR(page, attr) \ | ||
169 | ((page_to_phys(page) >> SMMU_PDIR_SHIFT) | (attr)) | ||
170 | #define SMMU_MK_PDE(page, attr) \ | ||
171 | (unsigned long)((page_to_phys(page) >> SMMU_PDE_SHIFT) | (attr)) | ||
172 | #define SMMU_EX_PTBL_PAGE(pde) \ | ||
173 | pfn_to_page((unsigned long)(pde) & SMMU_PFN_MASK) | ||
174 | #define SMMU_PFN_TO_PTE(pfn, attr) (unsigned long)((pfn) | (attr)) | ||
175 | |||
176 | #define SMMU_ASID_ENABLE(asid) ((asid) | (1 << 31)) | ||
177 | #define SMMU_ASID_DISABLE 0 | ||
178 | #define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0)) | ||
179 | |||
180 | #define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1) | ||
181 | #define smmu_client_disable_hwgrp(c) smmu_client_set_hwgrp(c, 0, 0) | ||
182 | #define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1) | ||
183 | #define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0) | ||
184 | |||
185 | #define HWGRP_INIT(client) [HWGRP_##client] = SMMU_##client##_ASID | ||
186 | |||
187 | static const u32 smmu_hwgrp_asid_reg[] = { | ||
188 | HWGRP_INIT(AFI), | ||
189 | HWGRP_INIT(AVPC), | ||
190 | HWGRP_INIT(DC), | ||
191 | HWGRP_INIT(DCB), | ||
192 | HWGRP_INIT(EPP), | ||
193 | HWGRP_INIT(G2), | ||
194 | HWGRP_INIT(HC), | ||
195 | HWGRP_INIT(HDA), | ||
196 | HWGRP_INIT(ISP), | ||
197 | HWGRP_INIT(MPE), | ||
198 | HWGRP_INIT(NV), | ||
199 | HWGRP_INIT(NV2), | ||
200 | HWGRP_INIT(PPCS), | ||
201 | HWGRP_INIT(SATA), | ||
202 | HWGRP_INIT(VDE), | ||
203 | HWGRP_INIT(VI), | ||
204 | }; | ||
205 | #define HWGRP_ASID_REG(x) (smmu_hwgrp_asid_reg[x]) | ||
206 | |||
207 | /* | ||
208 | * Per client for address space | ||
209 | */ | ||
210 | struct smmu_client { | ||
211 | struct device *dev; | ||
212 | struct list_head list; | ||
213 | struct smmu_as *as; | ||
214 | u32 hwgrp; | ||
215 | }; | ||
216 | |||
217 | /* | ||
218 | * Per address space | ||
219 | */ | ||
220 | struct smmu_as { | ||
221 | struct smmu_device *smmu; /* back pointer to container */ | ||
222 | unsigned int asid; | ||
223 | spinlock_t lock; /* for pagetable */ | ||
224 | struct page *pdir_page; | ||
225 | unsigned long pdir_attr; | ||
226 | unsigned long pde_attr; | ||
227 | unsigned long pte_attr; | ||
228 | unsigned int *pte_count; | ||
229 | |||
230 | struct list_head client; | ||
231 | spinlock_t client_lock; /* for client list */ | ||
232 | }; | ||
233 | |||
234 | /* | ||
235 | * Per SMMU device - IOMMU device | ||
236 | */ | ||
237 | struct smmu_device { | ||
238 | void __iomem *regs, *regs_ahbarb; | ||
239 | unsigned long iovmm_base; /* remappable base address */ | ||
240 | unsigned long page_count; /* total remappable size */ | ||
241 | spinlock_t lock; | ||
242 | char *name; | ||
243 | struct device *dev; | ||
244 | int num_as; | ||
245 | struct smmu_as *as; /* Run-time allocated array */ | ||
246 | struct page *avp_vector_page; /* dummy page shared by all AS's */ | ||
247 | |||
248 | /* | ||
249 | * Register image savers for suspend/resume | ||
250 | */ | ||
251 | unsigned long translation_enable_0; | ||
252 | unsigned long translation_enable_1; | ||
253 | unsigned long translation_enable_2; | ||
254 | unsigned long asid_security; | ||
255 | }; | ||
256 | |||
257 | static struct smmu_device *smmu_handle; /* unique for a system */ | ||
258 | |||
259 | /* | ||
260 | * SMMU/AHB register accessors | ||
261 | */ | ||
262 | static inline u32 smmu_read(struct smmu_device *smmu, size_t offs) | ||
263 | { | ||
264 | return readl(smmu->regs + offs); | ||
265 | } | ||
266 | static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs) | ||
267 | { | ||
268 | writel(val, smmu->regs + offs); | ||
269 | } | ||
270 | |||
271 | static inline u32 ahb_read(struct smmu_device *smmu, size_t offs) | ||
272 | { | ||
273 | return readl(smmu->regs_ahbarb + offs); | ||
274 | } | ||
275 | static inline void ahb_write(struct smmu_device *smmu, u32 val, size_t offs) | ||
276 | { | ||
277 | writel(val, smmu->regs_ahbarb + offs); | ||
278 | } | ||
279 | |||
280 | #define VA_PAGE_TO_PA(va, page) \ | ||
281 | (page_to_phys(page) + ((unsigned long)(va) & ~PAGE_MASK)) | ||
282 | |||
283 | #define FLUSH_CPU_DCACHE(va, page, size) \ | ||
284 | do { \ | ||
285 | unsigned long _pa_ = VA_PAGE_TO_PA(va, page); \ | ||
286 | __cpuc_flush_dcache_area((void *)(va), (size_t)(size)); \ | ||
287 | outer_flush_range(_pa_, _pa_+(size_t)(size)); \ | ||
288 | } while (0) | ||
289 | |||
290 | /* | ||
291 | * Any interaction between any block on PPSB and a block on APB or AHB | ||
292 | * must have these read-back barriers to ensure the APB/AHB bus | ||
293 | * transaction is complete before initiating activity on the PPSB | ||
294 | * block. | ||
295 | */ | ||
296 | #define FLUSH_SMMU_REGS(smmu) smmu_read(smmu, SMMU_CONFIG) | ||
297 | |||
298 | #define smmu_client_hwgrp(c) (u32)((c)->dev->platform_data) | ||
299 | |||
300 | static int __smmu_client_set_hwgrp(struct smmu_client *c, | ||
301 | unsigned long map, int on) | ||
302 | { | ||
303 | int i; | ||
304 | struct smmu_as *as = c->as; | ||
305 | u32 val, offs, mask = SMMU_ASID_ENABLE(as->asid); | ||
306 | struct smmu_device *smmu = as->smmu; | ||
307 | |||
308 | WARN_ON(!on && map); | ||
309 | if (on && !map) | ||
310 | return -EINVAL; | ||
311 | if (!on) | ||
312 | map = smmu_client_hwgrp(c); | ||
313 | |||
314 | for_each_set_bit(i, &map, HWGRP_COUNT) { | ||
315 | offs = HWGRP_ASID_REG(i); | ||
316 | val = smmu_read(smmu, offs); | ||
317 | if (on) { | ||
318 | if (WARN_ON(val & mask)) | ||
319 | goto err_hw_busy; | ||
320 | val |= mask; | ||
321 | } else { | ||
322 | WARN_ON((val & mask) == mask); | ||
323 | val &= ~mask; | ||
324 | } | ||
325 | smmu_write(smmu, val, offs); | ||
326 | } | ||
327 | FLUSH_SMMU_REGS(smmu); | ||
328 | c->hwgrp = map; | ||
329 | return 0; | ||
330 | |||
331 | err_hw_busy: | ||
332 | for_each_set_bit(i, &map, HWGRP_COUNT) { | ||
333 | offs = HWGRP_ASID_REG(i); | ||
334 | val = smmu_read(smmu, offs); | ||
335 | val &= ~mask; | ||
336 | smmu_write(smmu, val, offs); | ||
337 | } | ||
338 | return -EBUSY; | ||
339 | } | ||
340 | |||
341 | static int smmu_client_set_hwgrp(struct smmu_client *c, u32 map, int on) | ||
342 | { | ||
343 | u32 val; | ||
344 | unsigned long flags; | ||
345 | struct smmu_as *as = c->as; | ||
346 | struct smmu_device *smmu = as->smmu; | ||
347 | |||
348 | spin_lock_irqsave(&smmu->lock, flags); | ||
349 | val = __smmu_client_set_hwgrp(c, map, on); | ||
350 | spin_unlock_irqrestore(&smmu->lock, flags); | ||
351 | return val; | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * Flush all TLB entries and all PTC entries | ||
356 | * Caller must lock smmu | ||
357 | */ | ||
358 | static void smmu_flush_regs(struct smmu_device *smmu, int enable) | ||
359 | { | ||
360 | u32 val; | ||
361 | |||
362 | smmu_write(smmu, SMMU_PTC_FLUSH_TYPE_ALL, SMMU_PTC_FLUSH); | ||
363 | FLUSH_SMMU_REGS(smmu); | ||
364 | val = SMMU_TLB_FLUSH_VA_MATCH_ALL | | ||
365 | SMMU_TLB_FLUSH_ASID_MATCH_disable; | ||
366 | smmu_write(smmu, val, SMMU_TLB_FLUSH); | ||
367 | |||
368 | if (enable) | ||
369 | smmu_write(smmu, SMMU_CONFIG_ENABLE, SMMU_CONFIG); | ||
370 | FLUSH_SMMU_REGS(smmu); | ||
371 | } | ||
372 | |||
373 | static void smmu_setup_regs(struct smmu_device *smmu) | ||
374 | { | ||
375 | int i; | ||
376 | u32 val; | ||
377 | |||
378 | for (i = 0; i < smmu->num_as; i++) { | ||
379 | struct smmu_as *as = &smmu->as[i]; | ||
380 | struct smmu_client *c; | ||
381 | |||
382 | smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); | ||
383 | val = as->pdir_page ? | ||
384 | SMMU_MK_PDIR(as->pdir_page, as->pdir_attr) : | ||
385 | SMMU_PTB_DATA_RESET_VAL; | ||
386 | smmu_write(smmu, val, SMMU_PTB_DATA); | ||
387 | |||
388 | list_for_each_entry(c, &as->client, list) | ||
389 | __smmu_client_set_hwgrp(c, c->hwgrp, 1); | ||
390 | } | ||
391 | |||
392 | smmu_write(smmu, smmu->translation_enable_0, SMMU_TRANSLATION_ENABLE_0); | ||
393 | smmu_write(smmu, smmu->translation_enable_1, SMMU_TRANSLATION_ENABLE_1); | ||
394 | smmu_write(smmu, smmu->translation_enable_2, SMMU_TRANSLATION_ENABLE_2); | ||
395 | smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY); | ||
396 | smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_TLB_CONFIG); | ||
397 | smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_PTC_CONFIG); | ||
398 | |||
399 | smmu_flush_regs(smmu, 1); | ||
400 | |||
401 | val = ahb_read(smmu, AHB_XBAR_CTRL); | ||
402 | val |= AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE << | ||
403 | AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT; | ||
404 | ahb_write(smmu, val, AHB_XBAR_CTRL); | ||
405 | } | ||
406 | |||
407 | static void flush_ptc_and_tlb(struct smmu_device *smmu, | ||
408 | struct smmu_as *as, dma_addr_t iova, | ||
409 | unsigned long *pte, struct page *page, int is_pde) | ||
410 | { | ||
411 | u32 val; | ||
412 | unsigned long tlb_flush_va = is_pde | ||
413 | ? SMMU_TLB_FLUSH_VA(iova, SECTION) | ||
414 | : SMMU_TLB_FLUSH_VA(iova, GROUP); | ||
415 | |||
416 | val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page); | ||
417 | smmu_write(smmu, val, SMMU_PTC_FLUSH); | ||
418 | FLUSH_SMMU_REGS(smmu); | ||
419 | val = tlb_flush_va | | ||
420 | SMMU_TLB_FLUSH_ASID_MATCH__ENABLE | | ||
421 | (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT); | ||
422 | smmu_write(smmu, val, SMMU_TLB_FLUSH); | ||
423 | FLUSH_SMMU_REGS(smmu); | ||
424 | } | ||
425 | |||
426 | static void free_ptbl(struct smmu_as *as, dma_addr_t iova) | ||
427 | { | ||
428 | unsigned long pdn = SMMU_ADDR_TO_PDN(iova); | ||
429 | unsigned long *pdir = (unsigned long *)page_address(as->pdir_page); | ||
430 | |||
431 | if (pdir[pdn] != _PDE_VACANT(pdn)) { | ||
432 | dev_dbg(as->smmu->dev, "pdn: %lx\n", pdn); | ||
433 | |||
434 | ClearPageReserved(SMMU_EX_PTBL_PAGE(pdir[pdn])); | ||
435 | __free_page(SMMU_EX_PTBL_PAGE(pdir[pdn])); | ||
436 | pdir[pdn] = _PDE_VACANT(pdn); | ||
437 | FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]); | ||
438 | flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn], | ||
439 | as->pdir_page, 1); | ||
440 | } | ||
441 | } | ||
442 | |||
443 | static void free_pdir(struct smmu_as *as) | ||
444 | { | ||
445 | unsigned addr; | ||
446 | int count; | ||
447 | struct device *dev = as->smmu->dev; | ||
448 | |||
449 | if (!as->pdir_page) | ||
450 | return; | ||
451 | |||
452 | addr = as->smmu->iovmm_base; | ||
453 | count = as->smmu->page_count; | ||
454 | while (count-- > 0) { | ||
455 | free_ptbl(as, addr); | ||
456 | addr += SMMU_PAGE_SIZE * SMMU_PTBL_COUNT; | ||
457 | } | ||
458 | ClearPageReserved(as->pdir_page); | ||
459 | __free_page(as->pdir_page); | ||
460 | as->pdir_page = NULL; | ||
461 | devm_kfree(dev, as->pte_count); | ||
462 | as->pte_count = NULL; | ||
463 | } | ||
464 | |||
465 | /* | ||
466 | * Maps PTBL for given iova and returns the PTE address | ||
467 | * Caller must unmap the mapped PTBL returned in *ptbl_page_p | ||
468 | */ | ||
469 | static unsigned long *locate_pte(struct smmu_as *as, | ||
470 | dma_addr_t iova, bool allocate, | ||
471 | struct page **ptbl_page_p, | ||
472 | unsigned int **count) | ||
473 | { | ||
474 | unsigned long ptn = SMMU_ADDR_TO_PFN(iova); | ||
475 | unsigned long pdn = SMMU_ADDR_TO_PDN(iova); | ||
476 | unsigned long *pdir = page_address(as->pdir_page); | ||
477 | unsigned long *ptbl; | ||
478 | |||
479 | if (pdir[pdn] != _PDE_VACANT(pdn)) { | ||
480 | /* Mapped entry table already exists */ | ||
481 | *ptbl_page_p = SMMU_EX_PTBL_PAGE(pdir[pdn]); | ||
482 | ptbl = page_address(*ptbl_page_p); | ||
483 | } else if (!allocate) { | ||
484 | return NULL; | ||
485 | } else { | ||
486 | int pn; | ||
487 | unsigned long addr = SMMU_PDN_TO_ADDR(pdn); | ||
488 | |||
489 | /* Vacant - allocate a new page table */ | ||
490 | dev_dbg(as->smmu->dev, "New PTBL pdn: %lx\n", pdn); | ||
491 | |||
492 | *ptbl_page_p = alloc_page(GFP_ATOMIC); | ||
493 | if (!*ptbl_page_p) { | ||
494 | dev_err(as->smmu->dev, | ||
495 | "failed to allocate smmu_device page table\n"); | ||
496 | return NULL; | ||
497 | } | ||
498 | SetPageReserved(*ptbl_page_p); | ||
499 | ptbl = (unsigned long *)page_address(*ptbl_page_p); | ||
500 | for (pn = 0; pn < SMMU_PTBL_COUNT; | ||
501 | pn++, addr += SMMU_PAGE_SIZE) { | ||
502 | ptbl[pn] = _PTE_VACANT(addr); | ||
503 | } | ||
504 | FLUSH_CPU_DCACHE(ptbl, *ptbl_page_p, SMMU_PTBL_SIZE); | ||
505 | pdir[pdn] = SMMU_MK_PDE(*ptbl_page_p, | ||
506 | as->pde_attr | _PDE_NEXT); | ||
507 | FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]); | ||
508 | flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn], | ||
509 | as->pdir_page, 1); | ||
510 | } | ||
511 | *count = &as->pte_count[pdn]; | ||
512 | |||
513 | return &ptbl[ptn % SMMU_PTBL_COUNT]; | ||
514 | } | ||
515 | |||
516 | #ifdef CONFIG_SMMU_SIG_DEBUG | ||
517 | static void put_signature(struct smmu_as *as, | ||
518 | dma_addr_t iova, unsigned long pfn) | ||
519 | { | ||
520 | struct page *page; | ||
521 | unsigned long *vaddr; | ||
522 | |||
523 | page = pfn_to_page(pfn); | ||
524 | vaddr = page_address(page); | ||
525 | if (!vaddr) | ||
526 | return; | ||
527 | |||
528 | vaddr[0] = iova; | ||
529 | vaddr[1] = pfn << PAGE_SHIFT; | ||
530 | FLUSH_CPU_DCACHE(vaddr, page, sizeof(vaddr[0]) * 2); | ||
531 | } | ||
532 | #else | ||
533 | static inline void put_signature(struct smmu_as *as, | ||
534 | unsigned long addr, unsigned long pfn) | ||
535 | { | ||
536 | } | ||
537 | #endif | ||
538 | |||
539 | /* | ||
540 | * Caller must lock/unlock as | ||
541 | */ | ||
542 | static int alloc_pdir(struct smmu_as *as) | ||
543 | { | ||
544 | unsigned long *pdir; | ||
545 | int pdn; | ||
546 | u32 val; | ||
547 | struct smmu_device *smmu = as->smmu; | ||
548 | |||
549 | if (as->pdir_page) | ||
550 | return 0; | ||
551 | |||
552 | as->pte_count = devm_kzalloc(smmu->dev, | ||
553 | sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL); | ||
554 | if (!as->pte_count) { | ||
555 | dev_err(smmu->dev, | ||
556 | "failed to allocate smmu_device PTE cunters\n"); | ||
557 | return -ENOMEM; | ||
558 | } | ||
559 | as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA); | ||
560 | if (!as->pdir_page) { | ||
561 | dev_err(smmu->dev, | ||
562 | "failed to allocate smmu_device page directory\n"); | ||
563 | devm_kfree(smmu->dev, as->pte_count); | ||
564 | as->pte_count = NULL; | ||
565 | return -ENOMEM; | ||
566 | } | ||
567 | SetPageReserved(as->pdir_page); | ||
568 | pdir = page_address(as->pdir_page); | ||
569 | |||
570 | for (pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++) | ||
571 | pdir[pdn] = _PDE_VACANT(pdn); | ||
572 | FLUSH_CPU_DCACHE(pdir, as->pdir_page, SMMU_PDIR_SIZE); | ||
573 | val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pdir, as->pdir_page); | ||
574 | smmu_write(smmu, val, SMMU_PTC_FLUSH); | ||
575 | FLUSH_SMMU_REGS(as->smmu); | ||
576 | val = SMMU_TLB_FLUSH_VA_MATCH_ALL | | ||
577 | SMMU_TLB_FLUSH_ASID_MATCH__ENABLE | | ||
578 | (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT); | ||
579 | smmu_write(smmu, val, SMMU_TLB_FLUSH); | ||
580 | FLUSH_SMMU_REGS(as->smmu); | ||
581 | |||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static void __smmu_iommu_unmap(struct smmu_as *as, dma_addr_t iova) | ||
586 | { | ||
587 | unsigned long *pte; | ||
588 | struct page *page; | ||
589 | unsigned int *count; | ||
590 | |||
591 | pte = locate_pte(as, iova, false, &page, &count); | ||
592 | if (WARN_ON(!pte)) | ||
593 | return; | ||
594 | |||
595 | if (WARN_ON(*pte == _PTE_VACANT(iova))) | ||
596 | return; | ||
597 | |||
598 | *pte = _PTE_VACANT(iova); | ||
599 | FLUSH_CPU_DCACHE(pte, page, sizeof(*pte)); | ||
600 | flush_ptc_and_tlb(as->smmu, as, iova, pte, page, 0); | ||
601 | if (!--(*count)) { | ||
602 | free_ptbl(as, iova); | ||
603 | smmu_flush_regs(as->smmu, 0); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | static void __smmu_iommu_map_pfn(struct smmu_as *as, dma_addr_t iova, | ||
608 | unsigned long pfn) | ||
609 | { | ||
610 | struct smmu_device *smmu = as->smmu; | ||
611 | unsigned long *pte; | ||
612 | unsigned int *count; | ||
613 | struct page *page; | ||
614 | |||
615 | pte = locate_pte(as, iova, true, &page, &count); | ||
616 | if (WARN_ON(!pte)) | ||
617 | return; | ||
618 | |||
619 | if (*pte == _PTE_VACANT(iova)) | ||
620 | (*count)++; | ||
621 | *pte = SMMU_PFN_TO_PTE(pfn, as->pte_attr); | ||
622 | if (unlikely((*pte == _PTE_VACANT(iova)))) | ||
623 | (*count)--; | ||
624 | FLUSH_CPU_DCACHE(pte, page, sizeof(*pte)); | ||
625 | flush_ptc_and_tlb(smmu, as, iova, pte, page, 0); | ||
626 | put_signature(as, iova, pfn); | ||
627 | } | ||
628 | |||
629 | static int smmu_iommu_map(struct iommu_domain *domain, unsigned long iova, | ||
630 | phys_addr_t pa, size_t bytes, int prot) | ||
631 | { | ||
632 | struct smmu_as *as = domain->priv; | ||
633 | unsigned long pfn = __phys_to_pfn(pa); | ||
634 | unsigned long flags; | ||
635 | |||
636 | dev_dbg(as->smmu->dev, "[%d] %08lx:%08x\n", as->asid, iova, pa); | ||
637 | |||
638 | if (!pfn_valid(pfn)) | ||
639 | return -ENOMEM; | ||
640 | |||
641 | spin_lock_irqsave(&as->lock, flags); | ||
642 | __smmu_iommu_map_pfn(as, iova, pfn); | ||
643 | spin_unlock_irqrestore(&as->lock, flags); | ||
644 | return 0; | ||
645 | } | ||
646 | |||
647 | static size_t smmu_iommu_unmap(struct iommu_domain *domain, unsigned long iova, | ||
648 | size_t bytes) | ||
649 | { | ||
650 | struct smmu_as *as = domain->priv; | ||
651 | unsigned long flags; | ||
652 | |||
653 | dev_dbg(as->smmu->dev, "[%d] %08lx\n", as->asid, iova); | ||
654 | |||
655 | spin_lock_irqsave(&as->lock, flags); | ||
656 | __smmu_iommu_unmap(as, iova); | ||
657 | spin_unlock_irqrestore(&as->lock, flags); | ||
658 | return SMMU_PAGE_SIZE; | ||
659 | } | ||
660 | |||
661 | static phys_addr_t smmu_iommu_iova_to_phys(struct iommu_domain *domain, | ||
662 | unsigned long iova) | ||
663 | { | ||
664 | struct smmu_as *as = domain->priv; | ||
665 | unsigned long *pte; | ||
666 | unsigned int *count; | ||
667 | struct page *page; | ||
668 | unsigned long pfn; | ||
669 | unsigned long flags; | ||
670 | |||
671 | spin_lock_irqsave(&as->lock, flags); | ||
672 | |||
673 | pte = locate_pte(as, iova, true, &page, &count); | ||
674 | pfn = *pte & SMMU_PFN_MASK; | ||
675 | WARN_ON(!pfn_valid(pfn)); | ||
676 | dev_dbg(as->smmu->dev, | ||
677 | "iova:%08lx pfn:%08lx asid:%d\n", iova, pfn, as->asid); | ||
678 | |||
679 | spin_unlock_irqrestore(&as->lock, flags); | ||
680 | return PFN_PHYS(pfn); | ||
681 | } | ||
682 | |||
683 | static int smmu_iommu_domain_has_cap(struct iommu_domain *domain, | ||
684 | unsigned long cap) | ||
685 | { | ||
686 | return 0; | ||
687 | } | ||
688 | |||
689 | static int smmu_iommu_attach_dev(struct iommu_domain *domain, | ||
690 | struct device *dev) | ||
691 | { | ||
692 | struct smmu_as *as = domain->priv; | ||
693 | struct smmu_device *smmu = as->smmu; | ||
694 | struct smmu_client *client, *c; | ||
695 | u32 map; | ||
696 | int err; | ||
697 | |||
698 | client = devm_kzalloc(smmu->dev, sizeof(*c), GFP_KERNEL); | ||
699 | if (!client) | ||
700 | return -ENOMEM; | ||
701 | client->dev = dev; | ||
702 | client->as = as; | ||
703 | map = (unsigned long)dev->platform_data; | ||
704 | if (!map) | ||
705 | return -EINVAL; | ||
706 | |||
707 | err = smmu_client_enable_hwgrp(client, map); | ||
708 | if (err) | ||
709 | goto err_hwgrp; | ||
710 | |||
711 | spin_lock(&as->client_lock); | ||
712 | list_for_each_entry(c, &as->client, list) { | ||
713 | if (c->dev == dev) { | ||
714 | dev_err(smmu->dev, | ||
715 | "%s is already attached\n", dev_name(c->dev)); | ||
716 | err = -EINVAL; | ||
717 | goto err_client; | ||
718 | } | ||
719 | } | ||
720 | list_add(&client->list, &as->client); | ||
721 | spin_unlock(&as->client_lock); | ||
722 | |||
723 | /* | ||
724 | * Reserve "page zero" for AVP vectors using a common dummy | ||
725 | * page. | ||
726 | */ | ||
727 | if (map & HWG_AVPC) { | ||
728 | struct page *page; | ||
729 | |||
730 | page = as->smmu->avp_vector_page; | ||
731 | __smmu_iommu_map_pfn(as, 0, page_to_pfn(page)); | ||
732 | |||
733 | pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n"); | ||
734 | } | ||
735 | |||
736 | dev_dbg(smmu->dev, "%s is attached\n", dev_name(c->dev)); | ||
737 | return 0; | ||
738 | |||
739 | err_client: | ||
740 | smmu_client_disable_hwgrp(client); | ||
741 | spin_unlock(&as->client_lock); | ||
742 | err_hwgrp: | ||
743 | devm_kfree(smmu->dev, client); | ||
744 | return err; | ||
745 | } | ||
746 | |||
747 | static void smmu_iommu_detach_dev(struct iommu_domain *domain, | ||
748 | struct device *dev) | ||
749 | { | ||
750 | struct smmu_as *as = domain->priv; | ||
751 | struct smmu_device *smmu = as->smmu; | ||
752 | struct smmu_client *c; | ||
753 | |||
754 | spin_lock(&as->client_lock); | ||
755 | |||
756 | list_for_each_entry(c, &as->client, list) { | ||
757 | if (c->dev == dev) { | ||
758 | smmu_client_disable_hwgrp(c); | ||
759 | list_del(&c->list); | ||
760 | devm_kfree(smmu->dev, c); | ||
761 | c->as = NULL; | ||
762 | dev_dbg(smmu->dev, | ||
763 | "%s is detached\n", dev_name(c->dev)); | ||
764 | goto out; | ||
765 | } | ||
766 | } | ||
767 | dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev)); | ||
768 | out: | ||
769 | spin_unlock(&as->client_lock); | ||
770 | } | ||
771 | |||
772 | static int smmu_iommu_domain_init(struct iommu_domain *domain) | ||
773 | { | ||
774 | int i; | ||
775 | unsigned long flags; | ||
776 | struct smmu_as *as; | ||
777 | struct smmu_device *smmu = smmu_handle; | ||
778 | |||
779 | /* Look for a free AS with lock held */ | ||
780 | for (i = 0; i < smmu->num_as; i++) { | ||
781 | struct smmu_as *tmp = &smmu->as[i]; | ||
782 | |||
783 | spin_lock_irqsave(&tmp->lock, flags); | ||
784 | if (!tmp->pdir_page) { | ||
785 | as = tmp; | ||
786 | goto found; | ||
787 | } | ||
788 | spin_unlock_irqrestore(&tmp->lock, flags); | ||
789 | } | ||
790 | dev_err(smmu->dev, "no free AS\n"); | ||
791 | return -ENODEV; | ||
792 | |||
793 | found: | ||
794 | if (alloc_pdir(as) < 0) | ||
795 | goto err_alloc_pdir; | ||
796 | |||
797 | spin_lock(&smmu->lock); | ||
798 | |||
799 | /* Update PDIR register */ | ||
800 | smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); | ||
801 | smmu_write(smmu, | ||
802 | SMMU_MK_PDIR(as->pdir_page, as->pdir_attr), SMMU_PTB_DATA); | ||
803 | FLUSH_SMMU_REGS(smmu); | ||
804 | |||
805 | spin_unlock(&smmu->lock); | ||
806 | |||
807 | spin_unlock_irqrestore(&as->lock, flags); | ||
808 | domain->priv = as; | ||
809 | |||
810 | dev_dbg(smmu->dev, "smmu_as@%p\n", as); | ||
811 | return 0; | ||
812 | |||
813 | err_alloc_pdir: | ||
814 | spin_unlock_irqrestore(&as->lock, flags); | ||
815 | return -ENODEV; | ||
816 | } | ||
817 | |||
818 | static void smmu_iommu_domain_destroy(struct iommu_domain *domain) | ||
819 | { | ||
820 | struct smmu_as *as = domain->priv; | ||
821 | struct smmu_device *smmu = as->smmu; | ||
822 | unsigned long flags; | ||
823 | |||
824 | spin_lock_irqsave(&as->lock, flags); | ||
825 | |||
826 | if (as->pdir_page) { | ||
827 | spin_lock(&smmu->lock); | ||
828 | smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); | ||
829 | smmu_write(smmu, SMMU_PTB_DATA_RESET_VAL, SMMU_PTB_DATA); | ||
830 | FLUSH_SMMU_REGS(smmu); | ||
831 | spin_unlock(&smmu->lock); | ||
832 | |||
833 | free_pdir(as); | ||
834 | } | ||
835 | |||
836 | if (!list_empty(&as->client)) { | ||
837 | struct smmu_client *c; | ||
838 | |||
839 | list_for_each_entry(c, &as->client, list) | ||
840 | smmu_iommu_detach_dev(domain, c->dev); | ||
841 | } | ||
842 | |||
843 | spin_unlock_irqrestore(&as->lock, flags); | ||
844 | |||
845 | domain->priv = NULL; | ||
846 | dev_dbg(smmu->dev, "smmu_as@%p\n", as); | ||
847 | } | ||
848 | |||
849 | static struct iommu_ops smmu_iommu_ops = { | ||
850 | .domain_init = smmu_iommu_domain_init, | ||
851 | .domain_destroy = smmu_iommu_domain_destroy, | ||
852 | .attach_dev = smmu_iommu_attach_dev, | ||
853 | .detach_dev = smmu_iommu_detach_dev, | ||
854 | .map = smmu_iommu_map, | ||
855 | .unmap = smmu_iommu_unmap, | ||
856 | .iova_to_phys = smmu_iommu_iova_to_phys, | ||
857 | .domain_has_cap = smmu_iommu_domain_has_cap, | ||
858 | .pgsize_bitmap = SMMU_IOMMU_PGSIZES, | ||
859 | }; | ||
860 | |||
861 | static int tegra_smmu_suspend(struct device *dev) | ||
862 | { | ||
863 | struct smmu_device *smmu = dev_get_drvdata(dev); | ||
864 | |||
865 | smmu->translation_enable_0 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_0); | ||
866 | smmu->translation_enable_1 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_1); | ||
867 | smmu->translation_enable_2 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_2); | ||
868 | smmu->asid_security = smmu_read(smmu, SMMU_ASID_SECURITY); | ||
869 | return 0; | ||
870 | } | ||
871 | |||
872 | static int tegra_smmu_resume(struct device *dev) | ||
873 | { | ||
874 | struct smmu_device *smmu = dev_get_drvdata(dev); | ||
875 | unsigned long flags; | ||
876 | |||
877 | spin_lock_irqsave(&smmu->lock, flags); | ||
878 | smmu_setup_regs(smmu); | ||
879 | spin_unlock_irqrestore(&smmu->lock, flags); | ||
880 | return 0; | ||
881 | } | ||
882 | |||
883 | static int tegra_smmu_probe(struct platform_device *pdev) | ||
884 | { | ||
885 | struct smmu_device *smmu; | ||
886 | struct resource *regs, *regs2, *window; | ||
887 | struct device *dev = &pdev->dev; | ||
888 | int i, err = 0; | ||
889 | |||
890 | if (smmu_handle) | ||
891 | return -EIO; | ||
892 | |||
893 | BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT); | ||
894 | |||
895 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
896 | regs2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
897 | window = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
898 | if (!regs || !regs2 || !window) { | ||
899 | dev_err(dev, "No SMMU resources\n"); | ||
900 | return -ENODEV; | ||
901 | } | ||
902 | |||
903 | smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); | ||
904 | if (!smmu) { | ||
905 | dev_err(dev, "failed to allocate smmu_device\n"); | ||
906 | return -ENOMEM; | ||
907 | } | ||
908 | |||
909 | smmu->dev = dev; | ||
910 | smmu->num_as = SMMU_NUM_ASIDS; | ||
911 | smmu->iovmm_base = (unsigned long)window->start; | ||
912 | smmu->page_count = resource_size(window) >> SMMU_PAGE_SHIFT; | ||
913 | smmu->regs = devm_ioremap(dev, regs->start, resource_size(regs)); | ||
914 | smmu->regs_ahbarb = devm_ioremap(dev, regs2->start, | ||
915 | resource_size(regs2)); | ||
916 | if (!smmu->regs || !smmu->regs_ahbarb) { | ||
917 | dev_err(dev, "failed to remap SMMU registers\n"); | ||
918 | err = -ENXIO; | ||
919 | goto fail; | ||
920 | } | ||
921 | |||
922 | smmu->translation_enable_0 = ~0; | ||
923 | smmu->translation_enable_1 = ~0; | ||
924 | smmu->translation_enable_2 = ~0; | ||
925 | smmu->asid_security = 0; | ||
926 | |||
927 | smmu->as = devm_kzalloc(dev, | ||
928 | sizeof(smmu->as[0]) * smmu->num_as, GFP_KERNEL); | ||
929 | if (!smmu->as) { | ||
930 | dev_err(dev, "failed to allocate smmu_as\n"); | ||
931 | err = -ENOMEM; | ||
932 | goto fail; | ||
933 | } | ||
934 | |||
935 | for (i = 0; i < smmu->num_as; i++) { | ||
936 | struct smmu_as *as = &smmu->as[i]; | ||
937 | |||
938 | as->smmu = smmu; | ||
939 | as->asid = i; | ||
940 | as->pdir_attr = _PDIR_ATTR; | ||
941 | as->pde_attr = _PDE_ATTR; | ||
942 | as->pte_attr = _PTE_ATTR; | ||
943 | |||
944 | spin_lock_init(&as->lock); | ||
945 | INIT_LIST_HEAD(&as->client); | ||
946 | } | ||
947 | spin_lock_init(&smmu->lock); | ||
948 | smmu_setup_regs(smmu); | ||
949 | platform_set_drvdata(pdev, smmu); | ||
950 | |||
951 | smmu->avp_vector_page = alloc_page(GFP_KERNEL); | ||
952 | if (!smmu->avp_vector_page) | ||
953 | goto fail; | ||
954 | |||
955 | smmu_handle = smmu; | ||
956 | return 0; | ||
957 | |||
958 | fail: | ||
959 | if (smmu->avp_vector_page) | ||
960 | __free_page(smmu->avp_vector_page); | ||
961 | if (smmu->regs) | ||
962 | devm_iounmap(dev, smmu->regs); | ||
963 | if (smmu->regs_ahbarb) | ||
964 | devm_iounmap(dev, smmu->regs_ahbarb); | ||
965 | if (smmu && smmu->as) { | ||
966 | for (i = 0; i < smmu->num_as; i++) { | ||
967 | if (smmu->as[i].pdir_page) { | ||
968 | ClearPageReserved(smmu->as[i].pdir_page); | ||
969 | __free_page(smmu->as[i].pdir_page); | ||
970 | } | ||
971 | } | ||
972 | devm_kfree(dev, smmu->as); | ||
973 | } | ||
974 | devm_kfree(dev, smmu); | ||
975 | return err; | ||
976 | } | ||
977 | |||
978 | static int tegra_smmu_remove(struct platform_device *pdev) | ||
979 | { | ||
980 | struct smmu_device *smmu = platform_get_drvdata(pdev); | ||
981 | struct device *dev = smmu->dev; | ||
982 | |||
983 | smmu_write(smmu, SMMU_CONFIG_DISABLE, SMMU_CONFIG); | ||
984 | platform_set_drvdata(pdev, NULL); | ||
985 | if (smmu->as) { | ||
986 | int i; | ||
987 | |||
988 | for (i = 0; i < smmu->num_as; i++) | ||
989 | free_pdir(&smmu->as[i]); | ||
990 | devm_kfree(dev, smmu->as); | ||
991 | } | ||
992 | if (smmu->avp_vector_page) | ||
993 | __free_page(smmu->avp_vector_page); | ||
994 | if (smmu->regs) | ||
995 | devm_iounmap(dev, smmu->regs); | ||
996 | if (smmu->regs_ahbarb) | ||
997 | devm_iounmap(dev, smmu->regs_ahbarb); | ||
998 | devm_kfree(dev, smmu); | ||
999 | smmu_handle = NULL; | ||
1000 | return 0; | ||
1001 | } | ||
1002 | |||
1003 | const struct dev_pm_ops tegra_smmu_pm_ops = { | ||
1004 | .suspend = tegra_smmu_suspend, | ||
1005 | .resume = tegra_smmu_resume, | ||
1006 | }; | ||
1007 | |||
1008 | static struct platform_driver tegra_smmu_driver = { | ||
1009 | .probe = tegra_smmu_probe, | ||
1010 | .remove = tegra_smmu_remove, | ||
1011 | .driver = { | ||
1012 | .owner = THIS_MODULE, | ||
1013 | .name = "tegra-smmu", | ||
1014 | .pm = &tegra_smmu_pm_ops, | ||
1015 | }, | ||
1016 | }; | ||
1017 | |||
1018 | static int __devinit tegra_smmu_init(void) | ||
1019 | { | ||
1020 | bus_set_iommu(&platform_bus_type, &smmu_iommu_ops); | ||
1021 | return platform_driver_register(&tegra_smmu_driver); | ||
1022 | } | ||
1023 | |||
1024 | static void __exit tegra_smmu_exit(void) | ||
1025 | { | ||
1026 | platform_driver_unregister(&tegra_smmu_driver); | ||
1027 | } | ||
1028 | |||
1029 | subsys_initcall(tegra_smmu_init); | ||
1030 | module_exit(tegra_smmu_exit); | ||
1031 | |||
1032 | MODULE_DESCRIPTION("IOMMU API for SMMU in Tegra30"); | ||
1033 | MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>"); | ||
1034 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 9fb18c147825..b280c433e4a0 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c | |||
@@ -323,7 +323,7 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, | |||
323 | * Corrupt successful READs while in down state. | 323 | * Corrupt successful READs while in down state. |
324 | * If flags were specified, only corrupt those that match. | 324 | * If flags were specified, only corrupt those that match. |
325 | */ | 325 | */ |
326 | if (!error && bio_submitted_while_down && | 326 | if (fc->corrupt_bio_byte && !error && bio_submitted_while_down && |
327 | (bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) && | 327 | (bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) && |
328 | all_corrupt_bio_flags_match(bio, fc)) | 328 | all_corrupt_bio_flags_match(bio, fc)) |
329 | corrupt_bio_data(bio, fc); | 329 | corrupt_bio_data(bio, fc); |
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c index ad2eba40e319..ea5dd289fe2a 100644 --- a/drivers/md/dm-io.c +++ b/drivers/md/dm-io.c | |||
@@ -296,6 +296,8 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | |||
296 | unsigned offset; | 296 | unsigned offset; |
297 | unsigned num_bvecs; | 297 | unsigned num_bvecs; |
298 | sector_t remaining = where->count; | 298 | sector_t remaining = where->count; |
299 | struct request_queue *q = bdev_get_queue(where->bdev); | ||
300 | sector_t discard_sectors; | ||
299 | 301 | ||
300 | /* | 302 | /* |
301 | * where->count may be zero if rw holds a flush and we need to | 303 | * where->count may be zero if rw holds a flush and we need to |
@@ -305,9 +307,12 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | |||
305 | /* | 307 | /* |
306 | * Allocate a suitably sized-bio. | 308 | * Allocate a suitably sized-bio. |
307 | */ | 309 | */ |
308 | num_bvecs = dm_sector_div_up(remaining, | 310 | if (rw & REQ_DISCARD) |
309 | (PAGE_SIZE >> SECTOR_SHIFT)); | 311 | num_bvecs = 1; |
310 | num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), num_bvecs); | 312 | else |
313 | num_bvecs = min_t(int, bio_get_nr_vecs(where->bdev), | ||
314 | dm_sector_div_up(remaining, (PAGE_SIZE >> SECTOR_SHIFT))); | ||
315 | |||
311 | bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); | 316 | bio = bio_alloc_bioset(GFP_NOIO, num_bvecs, io->client->bios); |
312 | bio->bi_sector = where->sector + (where->count - remaining); | 317 | bio->bi_sector = where->sector + (where->count - remaining); |
313 | bio->bi_bdev = where->bdev; | 318 | bio->bi_bdev = where->bdev; |
@@ -315,10 +320,14 @@ static void do_region(int rw, unsigned region, struct dm_io_region *where, | |||
315 | bio->bi_destructor = dm_bio_destructor; | 320 | bio->bi_destructor = dm_bio_destructor; |
316 | store_io_and_region_in_bio(bio, io, region); | 321 | store_io_and_region_in_bio(bio, io, region); |
317 | 322 | ||
318 | /* | 323 | if (rw & REQ_DISCARD) { |
319 | * Try and add as many pages as possible. | 324 | discard_sectors = min_t(sector_t, q->limits.max_discard_sectors, remaining); |
320 | */ | 325 | bio->bi_size = discard_sectors << SECTOR_SHIFT; |
321 | while (remaining) { | 326 | remaining -= discard_sectors; |
327 | } else while (remaining) { | ||
328 | /* | ||
329 | * Try and add as many pages as possible. | ||
330 | */ | ||
322 | dp->get_page(dp, &page, &len, &offset); | 331 | dp->get_page(dp, &page, &len, &offset); |
323 | len = min(len, to_bytes(remaining)); | 332 | len = min(len, to_bytes(remaining)); |
324 | if (!bio_add_page(bio, page, len, offset)) | 333 | if (!bio_add_page(bio, page, len, offset)) |
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c index 31c2dc25886d..1ce84ed0b765 100644 --- a/drivers/md/dm-ioctl.c +++ b/drivers/md/dm-ioctl.c | |||
@@ -1437,7 +1437,7 @@ static int target_message(struct dm_ioctl *param, size_t param_size) | |||
1437 | 1437 | ||
1438 | if (!argc) { | 1438 | if (!argc) { |
1439 | DMWARN("Empty message received."); | 1439 | DMWARN("Empty message received."); |
1440 | goto out; | 1440 | goto out_argv; |
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | table = dm_get_live_table(md); | 1443 | table = dm_get_live_table(md); |
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 86cb7e5d83d5..787022c18187 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c | |||
@@ -668,7 +668,14 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev) | |||
668 | return ret; | 668 | return ret; |
669 | 669 | ||
670 | sb = page_address(rdev->sb_page); | 670 | sb = page_address(rdev->sb_page); |
671 | if (sb->magic != cpu_to_le32(DM_RAID_MAGIC)) { | 671 | |
672 | /* | ||
673 | * Two cases that we want to write new superblocks and rebuild: | ||
674 | * 1) New device (no matching magic number) | ||
675 | * 2) Device specified for rebuild (!In_sync w/ offset == 0) | ||
676 | */ | ||
677 | if ((sb->magic != cpu_to_le32(DM_RAID_MAGIC)) || | ||
678 | (!test_bit(In_sync, &rdev->flags) && !rdev->recovery_offset)) { | ||
672 | super_sync(rdev->mddev, rdev); | 679 | super_sync(rdev->mddev, rdev); |
673 | 680 | ||
674 | set_bit(FirstUse, &rdev->flags); | 681 | set_bit(FirstUse, &rdev->flags); |
@@ -745,11 +752,8 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev) | |||
745 | */ | 752 | */ |
746 | rdev_for_each(r, t, mddev) { | 753 | rdev_for_each(r, t, mddev) { |
747 | if (!test_bit(In_sync, &r->flags)) { | 754 | if (!test_bit(In_sync, &r->flags)) { |
748 | if (!test_bit(FirstUse, &r->flags)) | 755 | DMINFO("Device %d specified for rebuild: " |
749 | DMERR("Superblock area of " | 756 | "Clearing superblock", r->raid_disk); |
750 | "rebuild device %d should have been " | ||
751 | "cleared.", r->raid_disk); | ||
752 | set_bit(FirstUse, &r->flags); | ||
753 | rebuilds++; | 757 | rebuilds++; |
754 | } else if (test_bit(FirstUse, &r->flags)) | 758 | } else if (test_bit(FirstUse, &r->flags)) |
755 | new_devs++; | 759 | new_devs++; |
@@ -971,6 +975,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) | |||
971 | 975 | ||
972 | INIT_WORK(&rs->md.event_work, do_table_event); | 976 | INIT_WORK(&rs->md.event_work, do_table_event); |
973 | ti->private = rs; | 977 | ti->private = rs; |
978 | ti->num_flush_requests = 1; | ||
974 | 979 | ||
975 | mutex_lock(&rs->md.reconfig_mutex); | 980 | mutex_lock(&rs->md.reconfig_mutex); |
976 | ret = md_run(&rs->md); | 981 | ret = md_run(&rs->md); |
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 59c4f0446ffa..237571af77fd 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
@@ -385,6 +385,7 @@ static int init_pmd(struct dm_pool_metadata *pmd, | |||
385 | data_sm = dm_sm_disk_create(tm, nr_blocks); | 385 | data_sm = dm_sm_disk_create(tm, nr_blocks); |
386 | if (IS_ERR(data_sm)) { | 386 | if (IS_ERR(data_sm)) { |
387 | DMERR("sm_disk_create failed"); | 387 | DMERR("sm_disk_create failed"); |
388 | dm_tm_unlock(tm, sblock); | ||
388 | r = PTR_ERR(data_sm); | 389 | r = PTR_ERR(data_sm); |
389 | goto bad; | 390 | goto bad; |
390 | } | 391 | } |
@@ -789,6 +790,11 @@ int dm_pool_metadata_close(struct dm_pool_metadata *pmd) | |||
789 | return 0; | 790 | return 0; |
790 | } | 791 | } |
791 | 792 | ||
793 | /* | ||
794 | * __open_device: Returns @td corresponding to device with id @dev, | ||
795 | * creating it if @create is set and incrementing @td->open_count. | ||
796 | * On failure, @td is undefined. | ||
797 | */ | ||
792 | static int __open_device(struct dm_pool_metadata *pmd, | 798 | static int __open_device(struct dm_pool_metadata *pmd, |
793 | dm_thin_id dev, int create, | 799 | dm_thin_id dev, int create, |
794 | struct dm_thin_device **td) | 800 | struct dm_thin_device **td) |
@@ -799,10 +805,16 @@ static int __open_device(struct dm_pool_metadata *pmd, | |||
799 | struct disk_device_details details_le; | 805 | struct disk_device_details details_le; |
800 | 806 | ||
801 | /* | 807 | /* |
802 | * Check the device isn't already open. | 808 | * If the device is already open, return it. |
803 | */ | 809 | */ |
804 | list_for_each_entry(td2, &pmd->thin_devices, list) | 810 | list_for_each_entry(td2, &pmd->thin_devices, list) |
805 | if (td2->id == dev) { | 811 | if (td2->id == dev) { |
812 | /* | ||
813 | * May not create an already-open device. | ||
814 | */ | ||
815 | if (create) | ||
816 | return -EEXIST; | ||
817 | |||
806 | td2->open_count++; | 818 | td2->open_count++; |
807 | *td = td2; | 819 | *td = td2; |
808 | return 0; | 820 | return 0; |
@@ -817,6 +829,9 @@ static int __open_device(struct dm_pool_metadata *pmd, | |||
817 | if (r != -ENODATA || !create) | 829 | if (r != -ENODATA || !create) |
818 | return r; | 830 | return r; |
819 | 831 | ||
832 | /* | ||
833 | * Create new device. | ||
834 | */ | ||
820 | changed = 1; | 835 | changed = 1; |
821 | details_le.mapped_blocks = 0; | 836 | details_le.mapped_blocks = 0; |
822 | details_le.transaction_id = cpu_to_le64(pmd->trans_id); | 837 | details_le.transaction_id = cpu_to_le64(pmd->trans_id); |
@@ -882,12 +897,10 @@ static int __create_thin(struct dm_pool_metadata *pmd, | |||
882 | 897 | ||
883 | r = __open_device(pmd, dev, 1, &td); | 898 | r = __open_device(pmd, dev, 1, &td); |
884 | if (r) { | 899 | if (r) { |
885 | __close_device(td); | ||
886 | dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root); | 900 | dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root); |
887 | dm_btree_del(&pmd->bl_info, dev_root); | 901 | dm_btree_del(&pmd->bl_info, dev_root); |
888 | return r; | 902 | return r; |
889 | } | 903 | } |
890 | td->changed = 1; | ||
891 | __close_device(td); | 904 | __close_device(td); |
892 | 905 | ||
893 | return r; | 906 | return r; |
@@ -967,14 +980,14 @@ static int __create_snap(struct dm_pool_metadata *pmd, | |||
967 | goto bad; | 980 | goto bad; |
968 | 981 | ||
969 | r = __set_snapshot_details(pmd, td, origin, pmd->time); | 982 | r = __set_snapshot_details(pmd, td, origin, pmd->time); |
983 | __close_device(td); | ||
984 | |||
970 | if (r) | 985 | if (r) |
971 | goto bad; | 986 | goto bad; |
972 | 987 | ||
973 | __close_device(td); | ||
974 | return 0; | 988 | return 0; |
975 | 989 | ||
976 | bad: | 990 | bad: |
977 | __close_device(td); | ||
978 | dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root); | 991 | dm_btree_remove(&pmd->tl_info, pmd->root, &key, &pmd->root); |
979 | dm_btree_remove(&pmd->details_info, pmd->details_root, | 992 | dm_btree_remove(&pmd->details_info, pmd->details_root, |
980 | &key, &pmd->details_root); | 993 | &key, &pmd->details_root); |
@@ -1211,6 +1224,8 @@ static int __remove(struct dm_thin_device *td, dm_block_t block) | |||
1211 | if (r) | 1224 | if (r) |
1212 | return r; | 1225 | return r; |
1213 | 1226 | ||
1227 | td->mapped_blocks--; | ||
1228 | td->changed = 1; | ||
1214 | pmd->need_commit = 1; | 1229 | pmd->need_commit = 1; |
1215 | 1230 | ||
1216 | return 0; | 1231 | return 0; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index a368db2431a5..a0b225eb4ac4 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -624,7 +624,7 @@ int md_raid1_congested(struct mddev *mddev, int bits) | |||
624 | return 1; | 624 | return 1; |
625 | 625 | ||
626 | rcu_read_lock(); | 626 | rcu_read_lock(); |
627 | for (i = 0; i < conf->raid_disks; i++) { | 627 | for (i = 0; i < conf->raid_disks * 2; i++) { |
628 | struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev); | 628 | struct md_rdev *rdev = rcu_dereference(conf->mirrors[i].rdev); |
629 | if (rdev && !test_bit(Faulty, &rdev->flags)) { | 629 | if (rdev && !test_bit(Faulty, &rdev->flags)) { |
630 | struct request_queue *q = bdev_get_queue(rdev->bdev); | 630 | struct request_queue *q = bdev_get_queue(rdev->bdev); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 6e8aa213f0d5..58c44d6453a0 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -67,6 +67,7 @@ static int max_queued_requests = 1024; | |||
67 | 67 | ||
68 | static void allow_barrier(struct r10conf *conf); | 68 | static void allow_barrier(struct r10conf *conf); |
69 | static void lower_barrier(struct r10conf *conf); | 69 | static void lower_barrier(struct r10conf *conf); |
70 | static int enough(struct r10conf *conf, int ignore); | ||
70 | 71 | ||
71 | static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data) | 72 | static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data) |
72 | { | 73 | { |
@@ -347,6 +348,19 @@ static void raid10_end_read_request(struct bio *bio, int error) | |||
347 | * wait for the 'master' bio. | 348 | * wait for the 'master' bio. |
348 | */ | 349 | */ |
349 | set_bit(R10BIO_Uptodate, &r10_bio->state); | 350 | set_bit(R10BIO_Uptodate, &r10_bio->state); |
351 | } else { | ||
352 | /* If all other devices that store this block have | ||
353 | * failed, we want to return the error upwards rather | ||
354 | * than fail the last device. Here we redefine | ||
355 | * "uptodate" to mean "Don't want to retry" | ||
356 | */ | ||
357 | unsigned long flags; | ||
358 | spin_lock_irqsave(&conf->device_lock, flags); | ||
359 | if (!enough(conf, rdev->raid_disk)) | ||
360 | uptodate = 1; | ||
361 | spin_unlock_irqrestore(&conf->device_lock, flags); | ||
362 | } | ||
363 | if (uptodate) { | ||
350 | raid_end_bio_io(r10_bio); | 364 | raid_end_bio_io(r10_bio); |
351 | rdev_dec_pending(rdev, conf->mddev); | 365 | rdev_dec_pending(rdev, conf->mddev); |
352 | } else { | 366 | } else { |
@@ -2052,6 +2066,7 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 | |||
2052 | "md/raid10:%s: %s: Failing raid device\n", | 2066 | "md/raid10:%s: %s: Failing raid device\n", |
2053 | mdname(mddev), b); | 2067 | mdname(mddev), b); |
2054 | md_error(mddev, conf->mirrors[d].rdev); | 2068 | md_error(mddev, conf->mirrors[d].rdev); |
2069 | r10_bio->devs[r10_bio->read_slot].bio = IO_BLOCKED; | ||
2055 | return; | 2070 | return; |
2056 | } | 2071 | } |
2057 | 2072 | ||
@@ -2105,8 +2120,11 @@ static void fix_read_error(struct r10conf *conf, struct mddev *mddev, struct r10 | |||
2105 | rdev, | 2120 | rdev, |
2106 | r10_bio->devs[r10_bio->read_slot].addr | 2121 | r10_bio->devs[r10_bio->read_slot].addr |
2107 | + sect, | 2122 | + sect, |
2108 | s, 0)) | 2123 | s, 0)) { |
2109 | md_error(mddev, rdev); | 2124 | md_error(mddev, rdev); |
2125 | r10_bio->devs[r10_bio->read_slot].bio | ||
2126 | = IO_BLOCKED; | ||
2127 | } | ||
2110 | break; | 2128 | break; |
2111 | } | 2129 | } |
2112 | 2130 | ||
@@ -2299,17 +2317,20 @@ static void handle_read_error(struct mddev *mddev, struct r10bio *r10_bio) | |||
2299 | * This is all done synchronously while the array is | 2317 | * This is all done synchronously while the array is |
2300 | * frozen. | 2318 | * frozen. |
2301 | */ | 2319 | */ |
2320 | bio = r10_bio->devs[slot].bio; | ||
2321 | bdevname(bio->bi_bdev, b); | ||
2322 | bio_put(bio); | ||
2323 | r10_bio->devs[slot].bio = NULL; | ||
2324 | |||
2302 | if (mddev->ro == 0) { | 2325 | if (mddev->ro == 0) { |
2303 | freeze_array(conf); | 2326 | freeze_array(conf); |
2304 | fix_read_error(conf, mddev, r10_bio); | 2327 | fix_read_error(conf, mddev, r10_bio); |
2305 | unfreeze_array(conf); | 2328 | unfreeze_array(conf); |
2306 | } | 2329 | } else |
2330 | r10_bio->devs[slot].bio = IO_BLOCKED; | ||
2331 | |||
2307 | rdev_dec_pending(rdev, mddev); | 2332 | rdev_dec_pending(rdev, mddev); |
2308 | 2333 | ||
2309 | bio = r10_bio->devs[slot].bio; | ||
2310 | bdevname(bio->bi_bdev, b); | ||
2311 | r10_bio->devs[slot].bio = | ||
2312 | mddev->ro ? IO_BLOCKED : NULL; | ||
2313 | read_more: | 2334 | read_more: |
2314 | rdev = read_balance(conf, r10_bio, &max_sectors); | 2335 | rdev = read_balance(conf, r10_bio, &max_sectors); |
2315 | if (rdev == NULL) { | 2336 | if (rdev == NULL) { |
@@ -2318,13 +2339,10 @@ read_more: | |||
2318 | mdname(mddev), b, | 2339 | mdname(mddev), b, |
2319 | (unsigned long long)r10_bio->sector); | 2340 | (unsigned long long)r10_bio->sector); |
2320 | raid_end_bio_io(r10_bio); | 2341 | raid_end_bio_io(r10_bio); |
2321 | bio_put(bio); | ||
2322 | return; | 2342 | return; |
2323 | } | 2343 | } |
2324 | 2344 | ||
2325 | do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC); | 2345 | do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC); |
2326 | if (bio) | ||
2327 | bio_put(bio); | ||
2328 | slot = r10_bio->read_slot; | 2346 | slot = r10_bio->read_slot; |
2329 | printk_ratelimited( | 2347 | printk_ratelimited( |
2330 | KERN_ERR | 2348 | KERN_ERR |
@@ -2360,7 +2378,6 @@ read_more: | |||
2360 | mbio->bi_phys_segments++; | 2378 | mbio->bi_phys_segments++; |
2361 | spin_unlock_irq(&conf->device_lock); | 2379 | spin_unlock_irq(&conf->device_lock); |
2362 | generic_make_request(bio); | 2380 | generic_make_request(bio); |
2363 | bio = NULL; | ||
2364 | 2381 | ||
2365 | r10_bio = mempool_alloc(conf->r10bio_pool, | 2382 | r10_bio = mempool_alloc(conf->r10bio_pool, |
2366 | GFP_NOIO); | 2383 | GFP_NOIO); |
@@ -3243,7 +3260,6 @@ static int run(struct mddev *mddev) | |||
3243 | disk->rdev = rdev; | 3260 | disk->rdev = rdev; |
3244 | } | 3261 | } |
3245 | 3262 | ||
3246 | disk->rdev = rdev; | ||
3247 | disk_stack_limits(mddev->gendisk, rdev->bdev, | 3263 | disk_stack_limits(mddev->gendisk, rdev->bdev, |
3248 | rdev->data_offset << 9); | 3264 | rdev->data_offset << 9); |
3249 | /* as we don't honour merge_bvec_fn, we must never risk | 3265 | /* as we don't honour merge_bvec_fn, we must never risk |
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c index 654685c9303e..aa77e54a8fae 100644 --- a/drivers/media/dvb/siano/smsdvb.c +++ b/drivers/media/dvb/siano/smsdvb.c | |||
@@ -49,9 +49,6 @@ struct smsdvb_client_t { | |||
49 | 49 | ||
50 | struct completion tune_done; | 50 | struct completion tune_done; |
51 | 51 | ||
52 | /* todo: save freq/band instead whole struct */ | ||
53 | struct dtv_frontend_properties fe_params; | ||
54 | |||
55 | struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; | 52 | struct SMSHOSTLIB_STATISTICS_DVB_S sms_stat_dvb; |
56 | int event_fe_state; | 53 | int event_fe_state; |
57 | int event_unc_state; | 54 | int event_unc_state; |
@@ -744,12 +741,124 @@ static int smsdvb_get_frontend(struct dvb_frontend *fe) | |||
744 | struct dtv_frontend_properties *fep = &fe->dtv_property_cache; | 741 | struct dtv_frontend_properties *fep = &fe->dtv_property_cache; |
745 | struct smsdvb_client_t *client = | 742 | struct smsdvb_client_t *client = |
746 | container_of(fe, struct smsdvb_client_t, frontend); | 743 | container_of(fe, struct smsdvb_client_t, frontend); |
744 | struct smscore_device_t *coredev = client->coredev; | ||
745 | struct TRANSMISSION_STATISTICS_S *td = | ||
746 | &client->sms_stat_dvb.TransmissionData; | ||
747 | 747 | ||
748 | sms_debug(""); | 748 | switch (smscore_get_device_mode(coredev)) { |
749 | case DEVICE_MODE_DVBT: | ||
750 | case DEVICE_MODE_DVBT_BDA: | ||
751 | fep->frequency = td->Frequency; | ||
752 | |||
753 | switch (td->Bandwidth) { | ||
754 | case 6: | ||
755 | fep->bandwidth_hz = 6000000; | ||
756 | break; | ||
757 | case 7: | ||
758 | fep->bandwidth_hz = 7000000; | ||
759 | break; | ||
760 | case 8: | ||
761 | fep->bandwidth_hz = 8000000; | ||
762 | break; | ||
763 | } | ||
764 | |||
765 | switch (td->TransmissionMode) { | ||
766 | case 2: | ||
767 | fep->transmission_mode = TRANSMISSION_MODE_2K; | ||
768 | break; | ||
769 | case 8: | ||
770 | fep->transmission_mode = TRANSMISSION_MODE_8K; | ||
771 | } | ||
772 | |||
773 | switch (td->GuardInterval) { | ||
774 | case 0: | ||
775 | fep->guard_interval = GUARD_INTERVAL_1_32; | ||
776 | break; | ||
777 | case 1: | ||
778 | fep->guard_interval = GUARD_INTERVAL_1_16; | ||
779 | break; | ||
780 | case 2: | ||
781 | fep->guard_interval = GUARD_INTERVAL_1_8; | ||
782 | break; | ||
783 | case 3: | ||
784 | fep->guard_interval = GUARD_INTERVAL_1_4; | ||
785 | break; | ||
786 | } | ||
787 | |||
788 | switch (td->CodeRate) { | ||
789 | case 0: | ||
790 | fep->code_rate_HP = FEC_1_2; | ||
791 | break; | ||
792 | case 1: | ||
793 | fep->code_rate_HP = FEC_2_3; | ||
794 | break; | ||
795 | case 2: | ||
796 | fep->code_rate_HP = FEC_3_4; | ||
797 | break; | ||
798 | case 3: | ||
799 | fep->code_rate_HP = FEC_5_6; | ||
800 | break; | ||
801 | case 4: | ||
802 | fep->code_rate_HP = FEC_7_8; | ||
803 | break; | ||
804 | } | ||
805 | |||
806 | switch (td->LPCodeRate) { | ||
807 | case 0: | ||
808 | fep->code_rate_LP = FEC_1_2; | ||
809 | break; | ||
810 | case 1: | ||
811 | fep->code_rate_LP = FEC_2_3; | ||
812 | break; | ||
813 | case 2: | ||
814 | fep->code_rate_LP = FEC_3_4; | ||
815 | break; | ||
816 | case 3: | ||
817 | fep->code_rate_LP = FEC_5_6; | ||
818 | break; | ||
819 | case 4: | ||
820 | fep->code_rate_LP = FEC_7_8; | ||
821 | break; | ||
822 | } | ||
823 | |||
824 | switch (td->Constellation) { | ||
825 | case 0: | ||
826 | fep->modulation = QPSK; | ||
827 | break; | ||
828 | case 1: | ||
829 | fep->modulation = QAM_16; | ||
830 | break; | ||
831 | case 2: | ||
832 | fep->modulation = QAM_64; | ||
833 | break; | ||
834 | } | ||
835 | |||
836 | switch (td->Hierarchy) { | ||
837 | case 0: | ||
838 | fep->hierarchy = HIERARCHY_NONE; | ||
839 | break; | ||
840 | case 1: | ||
841 | fep->hierarchy = HIERARCHY_1; | ||
842 | break; | ||
843 | case 2: | ||
844 | fep->hierarchy = HIERARCHY_2; | ||
845 | break; | ||
846 | case 3: | ||
847 | fep->hierarchy = HIERARCHY_4; | ||
848 | break; | ||
849 | } | ||
749 | 850 | ||
750 | /* todo: */ | 851 | fep->inversion = INVERSION_AUTO; |
751 | memcpy(fep, &client->fe_params, | 852 | break; |
752 | sizeof(struct dtv_frontend_properties)); | 853 | case DEVICE_MODE_ISDBT: |
854 | case DEVICE_MODE_ISDBT_BDA: | ||
855 | fep->frequency = td->Frequency; | ||
856 | fep->bandwidth_hz = 6000000; | ||
857 | /* todo: retrive the other parameters */ | ||
858 | break; | ||
859 | default: | ||
860 | return -EINVAL; | ||
861 | } | ||
753 | 862 | ||
754 | return 0; | 863 | return 0; |
755 | } | 864 | } |
@@ -872,11 +981,11 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev, | |||
872 | switch (smscore_get_device_mode(coredev)) { | 981 | switch (smscore_get_device_mode(coredev)) { |
873 | case DEVICE_MODE_DVBT: | 982 | case DEVICE_MODE_DVBT: |
874 | case DEVICE_MODE_DVBT_BDA: | 983 | case DEVICE_MODE_DVBT_BDA: |
875 | smsdvb_fe_ops.delsys[0] = SYS_DVBT; | 984 | client->frontend.ops.delsys[0] = SYS_DVBT; |
876 | break; | 985 | break; |
877 | case DEVICE_MODE_ISDBT: | 986 | case DEVICE_MODE_ISDBT: |
878 | case DEVICE_MODE_ISDBT_BDA: | 987 | case DEVICE_MODE_ISDBT_BDA: |
879 | smsdvb_fe_ops.delsys[0] = SYS_ISDBT; | 988 | client->frontend.ops.delsys[0] = SYS_ISDBT; |
880 | break; | 989 | break; |
881 | } | 990 | } |
882 | 991 | ||
diff --git a/drivers/media/video/davinci/isif.c b/drivers/media/video/davinci/isif.c index 1e63852374be..5278fe7d6d0c 100644 --- a/drivers/media/video/davinci/isif.c +++ b/drivers/media/video/davinci/isif.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/videodev2.h> | 34 | #include <linux/videodev2.h> |
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/module.h> | ||
37 | 38 | ||
38 | #include <mach/mux.h> | 39 | #include <mach/mux.h> |
39 | 40 | ||
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index c7e69b8f81c9..4a44f9a1bae0 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -611,9 +611,11 @@ void uvc_video_clock_update(struct uvc_streaming *stream, | |||
611 | delta_stc = buf->pts - (1UL << 31); | 611 | delta_stc = buf->pts - (1UL << 31); |
612 | x1 = first->dev_stc - delta_stc; | 612 | x1 = first->dev_stc - delta_stc; |
613 | x2 = last->dev_stc - delta_stc; | 613 | x2 = last->dev_stc - delta_stc; |
614 | if (x1 == x2) | ||
615 | goto done; | ||
616 | |||
614 | y1 = (first->dev_sof + 2048) << 16; | 617 | y1 = (first->dev_sof + 2048) << 16; |
615 | y2 = (last->dev_sof + 2048) << 16; | 618 | y2 = (last->dev_sof + 2048) << 16; |
616 | |||
617 | if (y2 < y1) | 619 | if (y2 < y1) |
618 | y2 += 2048 << 16; | 620 | y2 += 2048 << 16; |
619 | 621 | ||
@@ -631,14 +633,16 @@ void uvc_video_clock_update(struct uvc_streaming *stream, | |||
631 | x1, x2, y1, y2, clock->sof_offset); | 633 | x1, x2, y1, y2, clock->sof_offset); |
632 | 634 | ||
633 | /* Second step, SOF to host clock conversion. */ | 635 | /* Second step, SOF to host clock conversion. */ |
634 | ts = timespec_sub(last->host_ts, first->host_ts); | ||
635 | x1 = (uvc_video_clock_host_sof(first) + 2048) << 16; | 636 | x1 = (uvc_video_clock_host_sof(first) + 2048) << 16; |
636 | x2 = (uvc_video_clock_host_sof(last) + 2048) << 16; | 637 | x2 = (uvc_video_clock_host_sof(last) + 2048) << 16; |
637 | y1 = NSEC_PER_SEC; | ||
638 | y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec; | ||
639 | |||
640 | if (x2 < x1) | 638 | if (x2 < x1) |
641 | x2 += 2048 << 16; | 639 | x2 += 2048 << 16; |
640 | if (x1 == x2) | ||
641 | goto done; | ||
642 | |||
643 | ts = timespec_sub(last->host_ts, first->host_ts); | ||
644 | y1 = NSEC_PER_SEC; | ||
645 | y2 = (ts.tv_sec + 1) * NSEC_PER_SEC + ts.tv_nsec; | ||
642 | 646 | ||
643 | /* Interpolated and host SOF timestamps can wrap around at slightly | 647 | /* Interpolated and host SOF timestamps can wrap around at slightly |
644 | * different times. Handle this by adding or removing 2048 to or from | 648 | * different times. Handle this by adding or removing 2048 to or from |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 53e2a80f42fa..d295941c9a3d 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -956,11 +956,12 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
956 | return ret; | 956 | return ret; |
957 | 957 | ||
958 | out_freeirq: | 958 | out_freeirq: |
959 | if (ab8500->irq_base) { | 959 | if (ab8500->irq_base) |
960 | free_irq(ab8500->irq, ab8500); | 960 | free_irq(ab8500->irq, ab8500); |
961 | out_removeirq: | 961 | out_removeirq: |
962 | if (ab8500->irq_base) | ||
962 | ab8500_irq_remove(ab8500); | 963 | ab8500_irq_remove(ab8500); |
963 | } | 964 | |
964 | return ret; | 965 | return ret; |
965 | } | 966 | } |
966 | 967 | ||
diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c index 0f5922812bff..411f523d4878 100644 --- a/drivers/mfd/mfd-core.c +++ b/drivers/mfd/mfd-core.c | |||
@@ -123,7 +123,7 @@ static int mfd_add_device(struct device *parent, int id, | |||
123 | } | 123 | } |
124 | 124 | ||
125 | if (!cell->ignore_resource_conflicts) { | 125 | if (!cell->ignore_resource_conflicts) { |
126 | ret = acpi_check_resource_conflict(res); | 126 | ret = acpi_check_resource_conflict(&res[r]); |
127 | if (ret) | 127 | if (ret) |
128 | goto fail_res; | 128 | goto fail_res; |
129 | } | 129 | } |
diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c index e075c113eec6..caadabeed8e9 100644 --- a/drivers/mfd/s5m-core.c +++ b/drivers/mfd/s5m-core.c | |||
@@ -105,7 +105,7 @@ static int s5m87xx_i2c_probe(struct i2c_client *i2c, | |||
105 | s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); | 105 | s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); |
106 | i2c_set_clientdata(s5m87xx->rtc, s5m87xx); | 106 | i2c_set_clientdata(s5m87xx->rtc, s5m87xx); |
107 | 107 | ||
108 | if (pdata->cfg_pmic_irq) | 108 | if (pdata && pdata->cfg_pmic_irq) |
109 | pdata->cfg_pmic_irq(); | 109 | pdata->cfg_pmic_irq(); |
110 | 110 | ||
111 | s5m_irq_init(s5m87xx); | 111 | s5m_irq_init(s5m87xx); |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index 01cf5012a08f..4392f6bca156 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -168,7 +168,7 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, | |||
168 | goto err; | 168 | goto err; |
169 | 169 | ||
170 | init_data->irq = pmic_plat_data->irq; | 170 | init_data->irq = pmic_plat_data->irq; |
171 | init_data->irq_base = pmic_plat_data->irq; | 171 | init_data->irq_base = pmic_plat_data->irq_base; |
172 | 172 | ||
173 | tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); | 173 | tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); |
174 | 174 | ||
diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 5fec23a9ac03..74fd8cb5f372 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c | |||
@@ -151,7 +151,7 @@ int tps65912_device_init(struct tps65912 *tps65912) | |||
151 | goto err; | 151 | goto err; |
152 | 152 | ||
153 | init_data->irq = pmic_plat_data->irq; | 153 | init_data->irq = pmic_plat_data->irq; |
154 | init_data->irq_base = pmic_plat_data->irq; | 154 | init_data->irq_base = pmic_plat_data->irq_base; |
155 | ret = tps65912_irq_init(tps65912, init_data->irq, init_data); | 155 | ret = tps65912_irq_init(tps65912, init_data->irq, init_data); |
156 | if (ret < 0) | 156 | if (ret < 0) |
157 | goto err; | 157 | goto err; |
diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c index 8a1fafd0bf7d..9fd01bf63c51 100644 --- a/drivers/mfd/wm8350-irq.c +++ b/drivers/mfd/wm8350-irq.c | |||
@@ -496,7 +496,6 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq, | |||
496 | 496 | ||
497 | mutex_init(&wm8350->irq_lock); | 497 | mutex_init(&wm8350->irq_lock); |
498 | wm8350->chip_irq = irq; | 498 | wm8350->chip_irq = irq; |
499 | wm8350->irq_base = pdata->irq_base; | ||
500 | 499 | ||
501 | if (pdata && pdata->irq_base > 0) | 500 | if (pdata && pdata->irq_base > 0) |
502 | irq_base = pdata->irq_base; | 501 | irq_base = pdata->irq_base; |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index f117e7fb9321..a04b3c108c8c 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
@@ -256,6 +256,20 @@ static int wm8994_suspend(struct device *dev) | |||
256 | break; | 256 | break; |
257 | } | 257 | } |
258 | 258 | ||
259 | switch (wm8994->type) { | ||
260 | case WM1811: | ||
261 | ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2); | ||
262 | if (ret < 0) { | ||
263 | dev_err(dev, "Failed to read jackdet: %d\n", ret); | ||
264 | } else if (ret & WM1811_JACKDET_MODE_MASK) { | ||
265 | dev_dbg(dev, "CODEC still active, ignoring suspend\n"); | ||
266 | return 0; | ||
267 | } | ||
268 | break; | ||
269 | default: | ||
270 | break; | ||
271 | } | ||
272 | |||
259 | /* Disable LDO pulldowns while the device is suspended if we | 273 | /* Disable LDO pulldowns while the device is suspended if we |
260 | * don't know that something will be driving them. */ | 274 | * don't know that something will be driving them. */ |
261 | if (!wm8994->ldo_ena_always_driven) | 275 | if (!wm8994->ldo_ena_always_driven) |
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c index c598ae69b8ff..bc0c5096539a 100644 --- a/drivers/mfd/wm8994-regmap.c +++ b/drivers/mfd/wm8994-regmap.c | |||
@@ -806,6 +806,7 @@ static bool wm1811_readable_register(struct device *dev, unsigned int reg) | |||
806 | case WM8994_DC_SERVO_2: | 806 | case WM8994_DC_SERVO_2: |
807 | case WM8994_DC_SERVO_READBACK: | 807 | case WM8994_DC_SERVO_READBACK: |
808 | case WM8994_DC_SERVO_4: | 808 | case WM8994_DC_SERVO_4: |
809 | case WM8994_DC_SERVO_4E: | ||
809 | case WM8994_ANALOGUE_HP_1: | 810 | case WM8994_ANALOGUE_HP_1: |
810 | case WM8958_MIC_DETECT_1: | 811 | case WM8958_MIC_DETECT_1: |
811 | case WM8958_MIC_DETECT_2: | 812 | case WM8958_MIC_DETECT_2: |
diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index 19fc7c1cb428..f428d86bfc10 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c | |||
@@ -984,9 +984,9 @@ static int __init c2port_init(void) | |||
984 | " - (C) 2007 Rodolfo Giometti\n"); | 984 | " - (C) 2007 Rodolfo Giometti\n"); |
985 | 985 | ||
986 | c2port_class = class_create(THIS_MODULE, "c2port"); | 986 | c2port_class = class_create(THIS_MODULE, "c2port"); |
987 | if (!c2port_class) { | 987 | if (IS_ERR(c2port_class)) { |
988 | printk(KERN_ERR "c2port: failed to allocate class\n"); | 988 | printk(KERN_ERR "c2port: failed to allocate class\n"); |
989 | return -ENOMEM; | 989 | return PTR_ERR(c2port_class); |
990 | } | 990 | } |
991 | c2port_class->dev_attrs = c2port_attrs; | 991 | c2port_class->dev_attrs = c2port_attrs; |
992 | 992 | ||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 690255c7d4dc..132378b89d76 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -2068,6 +2068,9 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) | |||
2068 | */ | 2068 | */ |
2069 | mmc_hw_reset_for_init(host); | 2069 | mmc_hw_reset_for_init(host); |
2070 | 2070 | ||
2071 | /* Initialization should be done at 3.3 V I/O voltage. */ | ||
2072 | mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0); | ||
2073 | |||
2071 | /* | 2074 | /* |
2072 | * sdio_reset sends CMD52 to reset card. Since we do not know | 2075 | * sdio_reset sends CMD52 to reset card. Since we do not know |
2073 | * if the card is being re-initialized, just send it. CMD52 | 2076 | * if the card is being re-initialized, just send it. CMD52 |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 30055f2b0d44..c3704e293a7b 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -238,10 +238,10 @@ static inline void mmc_host_clk_init(struct mmc_host *host) | |||
238 | /* Hold MCI clock for 8 cycles by default */ | 238 | /* Hold MCI clock for 8 cycles by default */ |
239 | host->clk_delay = 8; | 239 | host->clk_delay = 8; |
240 | /* | 240 | /* |
241 | * Default clock gating delay is 200ms. | 241 | * Default clock gating delay is 0ms to avoid wasting power. |
242 | * This value can be tuned by writing into sysfs entry. | 242 | * This value can be tuned by writing into sysfs entry. |
243 | */ | 243 | */ |
244 | host->clkgate_delay = 200; | 244 | host->clkgate_delay = 0; |
245 | host->clk_gated = false; | 245 | host->clk_gated = false; |
246 | INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); | 246 | INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); |
247 | spin_lock_init(&host->clk_lock); | 247 | spin_lock_init(&host->clk_lock); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index a48066344fa8..2b9ed1401dc4 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -816,6 +816,9 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
816 | if (!mmc_host_is_spi(host)) | 816 | if (!mmc_host_is_spi(host)) |
817 | mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); | 817 | mmc_set_bus_mode(host, MMC_BUSMODE_OPENDRAIN); |
818 | 818 | ||
819 | /* Initialization should be done at 3.3 V I/O voltage. */ | ||
820 | mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0); | ||
821 | |||
819 | /* | 822 | /* |
820 | * Since we're changing the OCR value, we seem to | 823 | * Since we're changing the OCR value, we seem to |
821 | * need to tell some cards to go back to the idle | 824 | * need to tell some cards to go back to the idle |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index 5017f9354ce2..c272c6868ecf 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -911,6 +911,9 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
911 | BUG_ON(!host); | 911 | BUG_ON(!host); |
912 | WARN_ON(!host->claimed); | 912 | WARN_ON(!host->claimed); |
913 | 913 | ||
914 | /* The initialization should be done at 3.3 V I/O voltage. */ | ||
915 | mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0); | ||
916 | |||
914 | err = mmc_sd_get_cid(host, ocr, cid, &rocr); | 917 | err = mmc_sd_get_cid(host, ocr, cid, &rocr); |
915 | if (err) | 918 | if (err) |
916 | return err; | 919 | return err; |
@@ -1156,11 +1159,6 @@ int mmc_attach_sd(struct mmc_host *host) | |||
1156 | BUG_ON(!host); | 1159 | BUG_ON(!host); |
1157 | WARN_ON(!host->claimed); | 1160 | WARN_ON(!host->claimed); |
1158 | 1161 | ||
1159 | /* Make sure we are at 3.3V signalling voltage */ | ||
1160 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, false); | ||
1161 | if (err) | ||
1162 | return err; | ||
1163 | |||
1164 | /* Disable preset value enable if already set since last time */ | 1162 | /* Disable preset value enable if already set since last time */ |
1165 | if (host->ops->enable_preset_value) { | 1163 | if (host->ops->enable_preset_value) { |
1166 | mmc_host_clk_hold(host); | 1164 | mmc_host_clk_hold(host); |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 12cde6ee17f5..2c7c83f832d2 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -585,6 +585,9 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
585 | * Inform the card of the voltage | 585 | * Inform the card of the voltage |
586 | */ | 586 | */ |
587 | if (!powered_resume) { | 587 | if (!powered_resume) { |
588 | /* The initialization should be done at 3.3 V I/O voltage. */ | ||
589 | mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0); | ||
590 | |||
588 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); | 591 | err = mmc_send_io_op_cond(host, host->ocr, &ocr); |
589 | if (err) | 592 | if (err) |
590 | goto err; | 593 | goto err; |
@@ -996,6 +999,11 @@ static int mmc_sdio_power_restore(struct mmc_host *host) | |||
996 | * With these steps taken, mmc_select_voltage() is also required to | 999 | * With these steps taken, mmc_select_voltage() is also required to |
997 | * restore the correct voltage setting of the card. | 1000 | * restore the correct voltage setting of the card. |
998 | */ | 1001 | */ |
1002 | |||
1003 | /* The initialization should be done at 3.3 V I/O voltage. */ | ||
1004 | if (!mmc_card_keep_power(host)) | ||
1005 | mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, 0); | ||
1006 | |||
999 | sdio_reset(host); | 1007 | sdio_reset(host); |
1000 | mmc_go_idle(host); | 1008 | mmc_go_idle(host); |
1001 | mmc_send_if_cond(host, host->ocr_avail); | 1009 | mmc_send_if_cond(host, host->ocr_avail); |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 6985cdb0bb26..e4449a54ae8f 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -1948,12 +1948,12 @@ static bool atmci_filter(struct dma_chan *chan, void *slave) | |||
1948 | } | 1948 | } |
1949 | } | 1949 | } |
1950 | 1950 | ||
1951 | static void atmci_configure_dma(struct atmel_mci *host) | 1951 | static bool atmci_configure_dma(struct atmel_mci *host) |
1952 | { | 1952 | { |
1953 | struct mci_platform_data *pdata; | 1953 | struct mci_platform_data *pdata; |
1954 | 1954 | ||
1955 | if (host == NULL) | 1955 | if (host == NULL) |
1956 | return; | 1956 | return false; |
1957 | 1957 | ||
1958 | pdata = host->pdev->dev.platform_data; | 1958 | pdata = host->pdev->dev.platform_data; |
1959 | 1959 | ||
@@ -1970,12 +1970,15 @@ static void atmci_configure_dma(struct atmel_mci *host) | |||
1970 | host->dma.chan = | 1970 | host->dma.chan = |
1971 | dma_request_channel(mask, atmci_filter, pdata->dma_slave); | 1971 | dma_request_channel(mask, atmci_filter, pdata->dma_slave); |
1972 | } | 1972 | } |
1973 | if (!host->dma.chan) | 1973 | if (!host->dma.chan) { |
1974 | dev_notice(&host->pdev->dev, "DMA not available, using PIO\n"); | 1974 | dev_warn(&host->pdev->dev, "no DMA channel available\n"); |
1975 | else | 1975 | return false; |
1976 | } else { | ||
1976 | dev_info(&host->pdev->dev, | 1977 | dev_info(&host->pdev->dev, |
1977 | "Using %s for DMA transfers\n", | 1978 | "Using %s for DMA transfers\n", |
1978 | dma_chan_name(host->dma.chan)); | 1979 | dma_chan_name(host->dma.chan)); |
1980 | return true; | ||
1981 | } | ||
1979 | } | 1982 | } |
1980 | 1983 | ||
1981 | static inline unsigned int atmci_get_version(struct atmel_mci *host) | 1984 | static inline unsigned int atmci_get_version(struct atmel_mci *host) |
@@ -2085,8 +2088,7 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
2085 | 2088 | ||
2086 | /* Get MCI capabilities and set operations according to it */ | 2089 | /* Get MCI capabilities and set operations according to it */ |
2087 | atmci_get_cap(host); | 2090 | atmci_get_cap(host); |
2088 | if (host->caps.has_dma) { | 2091 | if (host->caps.has_dma && atmci_configure_dma(host)) { |
2089 | dev_info(&pdev->dev, "using DMA\n"); | ||
2090 | host->prepare_data = &atmci_prepare_data_dma; | 2092 | host->prepare_data = &atmci_prepare_data_dma; |
2091 | host->submit_data = &atmci_submit_data_dma; | 2093 | host->submit_data = &atmci_submit_data_dma; |
2092 | host->stop_transfer = &atmci_stop_transfer_dma; | 2094 | host->stop_transfer = &atmci_stop_transfer_dma; |
@@ -2096,15 +2098,12 @@ static int __init atmci_probe(struct platform_device *pdev) | |||
2096 | host->submit_data = &atmci_submit_data_pdc; | 2098 | host->submit_data = &atmci_submit_data_pdc; |
2097 | host->stop_transfer = &atmci_stop_transfer_pdc; | 2099 | host->stop_transfer = &atmci_stop_transfer_pdc; |
2098 | } else { | 2100 | } else { |
2099 | dev_info(&pdev->dev, "no DMA, no PDC\n"); | 2101 | dev_info(&pdev->dev, "using PIO\n"); |
2100 | host->prepare_data = &atmci_prepare_data; | 2102 | host->prepare_data = &atmci_prepare_data; |
2101 | host->submit_data = &atmci_submit_data; | 2103 | host->submit_data = &atmci_submit_data; |
2102 | host->stop_transfer = &atmci_stop_transfer; | 2104 | host->stop_transfer = &atmci_stop_transfer; |
2103 | } | 2105 | } |
2104 | 2106 | ||
2105 | if (host->caps.has_dma) | ||
2106 | atmci_configure_dma(host); | ||
2107 | |||
2108 | platform_set_drvdata(pdev, host); | 2107 | platform_set_drvdata(pdev, host); |
2109 | 2108 | ||
2110 | /* We need at least one slot to succeed */ | 2109 | /* We need at least one slot to succeed */ |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44e..11e589cd8233 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -1271,12 +1271,13 @@ static int __devinit mmci_probe(struct amba_device *dev, | |||
1271 | /* | 1271 | /* |
1272 | * Block size can be up to 2048 bytes, but must be a power of two. | 1272 | * Block size can be up to 2048 bytes, but must be a power of two. |
1273 | */ | 1273 | */ |
1274 | mmc->max_blk_size = 2048; | 1274 | mmc->max_blk_size = 1 << 11; |
1275 | 1275 | ||
1276 | /* | 1276 | /* |
1277 | * No limit on the number of blocks transferred. | 1277 | * Limit the number of blocks transferred so that we don't overflow |
1278 | * the maximum request size. | ||
1278 | */ | 1279 | */ |
1279 | mmc->max_blk_count = mmc->max_req_size; | 1280 | mmc->max_blk_count = mmc->max_req_size >> 11; |
1280 | 1281 | ||
1281 | spin_lock_init(&host->lock); | 1282 | spin_lock_init(&host->lock); |
1282 | 1283 | ||
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index d601e41af282..0be4e2013632 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -269,8 +269,9 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg) | |||
269 | imx_data->scratchpad = val; | 269 | imx_data->scratchpad = val; |
270 | return; | 270 | return; |
271 | case SDHCI_COMMAND: | 271 | case SDHCI_COMMAND: |
272 | if ((host->cmd->opcode == MMC_STOP_TRANSMISSION) | 272 | if ((host->cmd->opcode == MMC_STOP_TRANSMISSION || |
273 | && (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) | 273 | host->cmd->opcode == MMC_SET_BLOCK_COUNT) && |
274 | (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)) | ||
274 | val |= SDHCI_CMD_ABORTCMD; | 275 | val |= SDHCI_CMD_ABORTCMD; |
275 | 276 | ||
276 | if (is_imx6q_usdhc(imx_data)) { | 277 | if (is_imx6q_usdhc(imx_data)) { |
diff --git a/drivers/net/caif/caif_hsi.c b/drivers/net/caif/caif_hsi.c index 0a4fc62a381d..c998e1afebc6 100644 --- a/drivers/net/caif/caif_hsi.c +++ b/drivers/net/caif/caif_hsi.c | |||
@@ -978,7 +978,7 @@ static void cfhsi_setup(struct net_device *dev) | |||
978 | dev->netdev_ops = &cfhsi_ops; | 978 | dev->netdev_ops = &cfhsi_ops; |
979 | dev->type = ARPHRD_CAIF; | 979 | dev->type = ARPHRD_CAIF; |
980 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; | 980 | dev->flags = IFF_POINTOPOINT | IFF_NOARP; |
981 | dev->mtu = CFHSI_MAX_PAYLOAD_SZ; | 981 | dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ; |
982 | dev->tx_queue_len = 0; | 982 | dev->tx_queue_len = 0; |
983 | dev->destructor = free_netdev; | 983 | dev->destructor = free_netdev; |
984 | skb_queue_head_init(&cfhsi->qhead); | 984 | skb_queue_head_init(&cfhsi->qhead); |
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 04a3f1b756a8..192b0d118df4 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c | |||
@@ -95,11 +95,16 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val) | |||
95 | spin_unlock_irqrestore(&priv->cmdreg_lock, flags); | 95 | spin_unlock_irqrestore(&priv->cmdreg_lock, flags); |
96 | } | 96 | } |
97 | 97 | ||
98 | static int sja1000_is_absent(struct sja1000_priv *priv) | ||
99 | { | ||
100 | return (priv->read_reg(priv, REG_MOD) == 0xFF); | ||
101 | } | ||
102 | |||
98 | static int sja1000_probe_chip(struct net_device *dev) | 103 | static int sja1000_probe_chip(struct net_device *dev) |
99 | { | 104 | { |
100 | struct sja1000_priv *priv = netdev_priv(dev); | 105 | struct sja1000_priv *priv = netdev_priv(dev); |
101 | 106 | ||
102 | if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) { | 107 | if (priv->reg_base && sja1000_is_absent(priv)) { |
103 | printk(KERN_INFO "%s: probing @0x%lX failed\n", | 108 | printk(KERN_INFO "%s: probing @0x%lX failed\n", |
104 | DRV_NAME, dev->base_addr); | 109 | DRV_NAME, dev->base_addr); |
105 | return 0; | 110 | return 0; |
@@ -493,6 +498,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) | |||
493 | while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) { | 498 | while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) { |
494 | n++; | 499 | n++; |
495 | status = priv->read_reg(priv, REG_SR); | 500 | status = priv->read_reg(priv, REG_SR); |
501 | /* check for absent controller due to hw unplug */ | ||
502 | if (status == 0xFF && sja1000_is_absent(priv)) | ||
503 | return IRQ_NONE; | ||
496 | 504 | ||
497 | if (isrc & IRQ_WUI) | 505 | if (isrc & IRQ_WUI) |
498 | dev_warn(dev->dev.parent, "wakeup interrupt\n"); | 506 | dev_warn(dev->dev.parent, "wakeup interrupt\n"); |
@@ -509,6 +517,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) | |||
509 | while (status & SR_RBS) { | 517 | while (status & SR_RBS) { |
510 | sja1000_rx(dev); | 518 | sja1000_rx(dev); |
511 | status = priv->read_reg(priv, REG_SR); | 519 | status = priv->read_reg(priv, REG_SR); |
520 | /* check for absent controller */ | ||
521 | if (status == 0xFF && sja1000_is_absent(priv)) | ||
522 | return IRQ_NONE; | ||
512 | } | 523 | } |
513 | } | 524 | } |
514 | if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) { | 525 | if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) { |
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index b8591246eb4c..47a9bb2c813c 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c | |||
@@ -1710,7 +1710,7 @@ static irqreturn_t atl1c_intr(int irq, void *data) | |||
1710 | "atl1c hardware error (status = 0x%x)\n", | 1710 | "atl1c hardware error (status = 0x%x)\n", |
1711 | status & ISR_ERROR); | 1711 | status & ISR_ERROR); |
1712 | /* reset MAC */ | 1712 | /* reset MAC */ |
1713 | adapter->work_event |= ATL1C_WORK_EVENT_RESET; | 1713 | set_bit(ATL1C_WORK_EVENT_RESET, &adapter->work_event); |
1714 | schedule_work(&adapter->common_task); | 1714 | schedule_work(&adapter->common_task); |
1715 | return IRQ_HANDLED; | 1715 | return IRQ_HANDLED; |
1716 | } | 1716 | } |
@@ -2244,10 +2244,6 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb, | |||
2244 | dev_info(&adapter->pdev->dev, "tx locked\n"); | 2244 | dev_info(&adapter->pdev->dev, "tx locked\n"); |
2245 | return NETDEV_TX_LOCKED; | 2245 | return NETDEV_TX_LOCKED; |
2246 | } | 2246 | } |
2247 | if (skb->mark == 0x01) | ||
2248 | type = atl1c_trans_high; | ||
2249 | else | ||
2250 | type = atl1c_trans_normal; | ||
2251 | 2247 | ||
2252 | if (atl1c_tpd_avail(adapter, type) < tpd_req) { | 2248 | if (atl1c_tpd_avail(adapter, type) < tpd_req) { |
2253 | /* no enough descriptor, just stop queue */ | 2249 | /* no enough descriptor, just stop queue */ |
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 3fb66d09ece5..cab87456a34a 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c | |||
@@ -2339,7 +2339,7 @@ static inline int __init b44_pci_init(void) | |||
2339 | return err; | 2339 | return err; |
2340 | } | 2340 | } |
2341 | 2341 | ||
2342 | static inline void __exit b44_pci_exit(void) | 2342 | static inline void b44_pci_exit(void) |
2343 | { | 2343 | { |
2344 | #ifdef CONFIG_B44_PCI | 2344 | #ifdef CONFIG_B44_PCI |
2345 | ssb_pcihost_unregister(&b44_pci_driver); | 2345 | ssb_pcihost_unregister(&b44_pci_driver); |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 7aee46983be4..99389c8dda21 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | |||
@@ -1934,7 +1934,7 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
1934 | } | 1934 | } |
1935 | 1935 | ||
1936 | if (bp->port.pmf) | 1936 | if (bp->port.pmf) |
1937 | bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); | 1937 | bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0); |
1938 | else | 1938 | else |
1939 | bnx2x__link_status_update(bp); | 1939 | bnx2x__link_status_update(bp); |
1940 | 1940 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index bf27c54ff2e0..4f40f7d7d8c6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | |||
@@ -1179,10 +1179,16 @@ static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp, | |||
1179 | */ | 1179 | */ |
1180 | static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp) | 1180 | static inline u8 bnx2x_stats_id(struct bnx2x_fastpath *fp) |
1181 | { | 1181 | { |
1182 | if (!CHIP_IS_E1x(fp->bp)) | 1182 | struct bnx2x *bp = fp->bp; |
1183 | if (!CHIP_IS_E1x(bp)) { | ||
1184 | #ifdef BCM_CNIC | ||
1185 | /* there are special statistics counters for FCoE 136..140 */ | ||
1186 | if (IS_FCOE_FP(fp)) | ||
1187 | return bp->cnic_base_cl_id + (bp->pf_num >> 1); | ||
1188 | #endif | ||
1183 | return fp->cl_id; | 1189 | return fp->cl_id; |
1184 | else | 1190 | } |
1185 | return fp->cl_id + BP_PORT(fp->bp) * FP_SB_MAX_E1x; | 1191 | return fp->cl_id + BP_PORT(bp) * FP_SB_MAX_E1x; |
1186 | } | 1192 | } |
1187 | 1193 | ||
1188 | static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp, | 1194 | static inline void bnx2x_init_vlan_mac_fp_objs(struct bnx2x_fastpath *fp, |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index 5051cf3deb20..6d82ade4c31c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | |||
@@ -735,7 +735,9 @@ void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state) | |||
735 | bp->dcbx_error); | 735 | bp->dcbx_error); |
736 | 736 | ||
737 | /* mark DCBX result for PMF migration */ | 737 | /* mark DCBX result for PMF migration */ |
738 | bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 1); | 738 | bnx2x_update_drv_flags(bp, |
739 | 1 << DRV_FLAGS_DCB_CONFIGURED, | ||
740 | 1); | ||
739 | #ifdef BCM_DCBNL | 741 | #ifdef BCM_DCBNL |
740 | /* | 742 | /* |
741 | * Add new app tlvs to dcbnl | 743 | * Add new app tlvs to dcbnl |
@@ -1020,7 +1022,7 @@ void bnx2x_dcbx_init(struct bnx2x *bp) | |||
1020 | DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n", | 1022 | DP(NETIF_MSG_LINK, "dcbx_lldp_params_offset 0x%x\n", |
1021 | dcbx_lldp_params_offset); | 1023 | dcbx_lldp_params_offset); |
1022 | 1024 | ||
1023 | bnx2x_update_drv_flags(bp, DRV_FLAGS_DCB_CONFIGURED, 0); | 1025 | bnx2x_update_drv_flags(bp, 1 << DRV_FLAGS_DCB_CONFIGURED, 0); |
1024 | 1026 | ||
1025 | if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { | 1027 | if (SHMEM_LLDP_DCBX_PARAMS_NONE != dcbx_lldp_params_offset) { |
1026 | bnx2x_dcbx_admin_mib_updated_params(bp, | 1028 | bnx2x_dcbx_admin_mib_updated_params(bp, |
@@ -1857,7 +1859,7 @@ void bnx2x_dcbx_pmf_update(struct bnx2x *bp) | |||
1857 | * read it from shmem and update bp and netdev accordingly | 1859 | * read it from shmem and update bp and netdev accordingly |
1858 | */ | 1860 | */ |
1859 | if (SHMEM2_HAS(bp, drv_flags) && | 1861 | if (SHMEM2_HAS(bp, drv_flags) && |
1860 | GET_FLAGS(SHMEM2_RD(bp, drv_flags), DRV_FLAGS_DCB_CONFIGURED)) { | 1862 | GET_FLAGS(SHMEM2_RD(bp, drv_flags), 1 << DRV_FLAGS_DCB_CONFIGURED)) { |
1861 | /* Read neg results if dcbx is in the FW */ | 1863 | /* Read neg results if dcbx is in the FW */ |
1862 | if (bnx2x_dcbx_read_shmem_neg_results(bp)) | 1864 | if (bnx2x_dcbx_read_shmem_neg_results(bp)) |
1863 | return; | 1865 | return; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 254521319150..b69f8762b339 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -10824,38 +10824,36 @@ do { \ | |||
10824 | 10824 | ||
10825 | int bnx2x_init_firmware(struct bnx2x *bp) | 10825 | int bnx2x_init_firmware(struct bnx2x *bp) |
10826 | { | 10826 | { |
10827 | const char *fw_file_name; | ||
10827 | struct bnx2x_fw_file_hdr *fw_hdr; | 10828 | struct bnx2x_fw_file_hdr *fw_hdr; |
10828 | int rc; | 10829 | int rc; |
10829 | 10830 | ||
10831 | if (bp->firmware) | ||
10832 | return 0; | ||
10830 | 10833 | ||
10831 | if (!bp->firmware) { | 10834 | if (CHIP_IS_E1(bp)) |
10832 | const char *fw_file_name; | 10835 | fw_file_name = FW_FILE_NAME_E1; |
10833 | 10836 | else if (CHIP_IS_E1H(bp)) | |
10834 | if (CHIP_IS_E1(bp)) | 10837 | fw_file_name = FW_FILE_NAME_E1H; |
10835 | fw_file_name = FW_FILE_NAME_E1; | 10838 | else if (!CHIP_IS_E1x(bp)) |
10836 | else if (CHIP_IS_E1H(bp)) | 10839 | fw_file_name = FW_FILE_NAME_E2; |
10837 | fw_file_name = FW_FILE_NAME_E1H; | 10840 | else { |
10838 | else if (!CHIP_IS_E1x(bp)) | 10841 | BNX2X_ERR("Unsupported chip revision\n"); |
10839 | fw_file_name = FW_FILE_NAME_E2; | 10842 | return -EINVAL; |
10840 | else { | 10843 | } |
10841 | BNX2X_ERR("Unsupported chip revision\n"); | 10844 | BNX2X_DEV_INFO("Loading %s\n", fw_file_name); |
10842 | return -EINVAL; | ||
10843 | } | ||
10844 | BNX2X_DEV_INFO("Loading %s\n", fw_file_name); | ||
10845 | 10845 | ||
10846 | rc = request_firmware(&bp->firmware, fw_file_name, | 10846 | rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); |
10847 | &bp->pdev->dev); | 10847 | if (rc) { |
10848 | if (rc) { | 10848 | BNX2X_ERR("Can't load firmware file %s\n", |
10849 | BNX2X_ERR("Can't load firmware file %s\n", | 10849 | fw_file_name); |
10850 | fw_file_name); | 10850 | goto request_firmware_exit; |
10851 | goto request_firmware_exit; | 10851 | } |
10852 | } | ||
10853 | 10852 | ||
10854 | rc = bnx2x_check_firmware(bp); | 10853 | rc = bnx2x_check_firmware(bp); |
10855 | if (rc) { | 10854 | if (rc) { |
10856 | BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); | 10855 | BNX2X_ERR("Corrupt firmware file %s\n", fw_file_name); |
10857 | goto request_firmware_exit; | 10856 | goto request_firmware_exit; |
10858 | } | ||
10859 | } | 10857 | } |
10860 | 10858 | ||
10861 | fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data; | 10859 | fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data; |
@@ -10901,6 +10899,7 @@ init_ops_alloc_err: | |||
10901 | kfree(bp->init_data); | 10899 | kfree(bp->init_data); |
10902 | request_firmware_exit: | 10900 | request_firmware_exit: |
10903 | release_firmware(bp->firmware); | 10901 | release_firmware(bp->firmware); |
10902 | bp->firmware = NULL; | ||
10904 | 10903 | ||
10905 | return rc; | 10904 | return rc; |
10906 | } | 10905 | } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index cb6339c35571..94110e9ce51d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -5601,7 +5601,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, | |||
5601 | 5601 | ||
5602 | /* Fill the ramrod data with provided parameters */ | 5602 | /* Fill the ramrod data with provided parameters */ |
5603 | rdata->function_mode = cpu_to_le16(start_params->mf_mode); | 5603 | rdata->function_mode = cpu_to_le16(start_params->mf_mode); |
5604 | rdata->sd_vlan_tag = start_params->sd_vlan_tag; | 5604 | rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); |
5605 | rdata->path_id = BP_PATH(bp); | 5605 | rdata->path_id = BP_PATH(bp); |
5606 | rdata->network_cos_mode = start_params->network_cos_mode; | 5606 | rdata->network_cos_mode = start_params->network_cos_mode; |
5607 | 5607 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index 1adef266fcd5..a766b25eec5f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | |||
@@ -554,23 +554,11 @@ static void bnx2x_bmac_stats_update(struct bnx2x *bp) | |||
554 | UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl); | 554 | UPDATE_STAT64(tx_stat_gtufl, tx_stat_mac_ufl); |
555 | 555 | ||
556 | /* collect PFC stats */ | 556 | /* collect PFC stats */ |
557 | DIFF_64(diff.hi, new->tx_stat_gtpp_hi, | ||
558 | pstats->pfc_frames_tx_hi, | ||
559 | diff.lo, new->tx_stat_gtpp_lo, | ||
560 | pstats->pfc_frames_tx_lo); | ||
561 | pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi; | 557 | pstats->pfc_frames_tx_hi = new->tx_stat_gtpp_hi; |
562 | pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo; | 558 | pstats->pfc_frames_tx_lo = new->tx_stat_gtpp_lo; |
563 | ADD_64(pstats->pfc_frames_tx_hi, diff.hi, | ||
564 | pstats->pfc_frames_tx_lo, diff.lo); | ||
565 | 559 | ||
566 | DIFF_64(diff.hi, new->rx_stat_grpp_hi, | ||
567 | pstats->pfc_frames_rx_hi, | ||
568 | diff.lo, new->rx_stat_grpp_lo, | ||
569 | pstats->pfc_frames_rx_lo); | ||
570 | pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi; | 560 | pstats->pfc_frames_rx_hi = new->rx_stat_grpp_hi; |
571 | pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo; | 561 | pstats->pfc_frames_rx_lo = new->rx_stat_grpp_lo; |
572 | ADD_64(pstats->pfc_frames_rx_hi, diff.hi, | ||
573 | pstats->pfc_frames_rx_lo, diff.lo); | ||
574 | } | 562 | } |
575 | 563 | ||
576 | estats->pause_frames_received_hi = | 564 | estats->pause_frames_received_hi = |
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index dd3a0a232ea0..818a573669e6 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c | |||
@@ -3584,7 +3584,11 @@ static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr, | |||
3584 | fl6.flowi6_oif = dst_addr->sin6_scope_id; | 3584 | fl6.flowi6_oif = dst_addr->sin6_scope_id; |
3585 | 3585 | ||
3586 | *dst = ip6_route_output(&init_net, NULL, &fl6); | 3586 | *dst = ip6_route_output(&init_net, NULL, &fl6); |
3587 | if (*dst) | 3587 | if ((*dst)->error) { |
3588 | dst_release(*dst); | ||
3589 | *dst = NULL; | ||
3590 | return -ENETUNREACH; | ||
3591 | } else | ||
3588 | return 0; | 3592 | return 0; |
3589 | #endif | 3593 | #endif |
3590 | 3594 | ||
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a1f2e0fed78b..35c2a202d67a 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c | |||
@@ -5352,7 +5352,7 @@ static void tg3_tx(struct tg3_napi *tnapi) | |||
5352 | } | 5352 | } |
5353 | } | 5353 | } |
5354 | 5354 | ||
5355 | netdev_completed_queue(tp->dev, pkts_compl, bytes_compl); | 5355 | netdev_tx_completed_queue(txq, pkts_compl, bytes_compl); |
5356 | 5356 | ||
5357 | tnapi->tx_cons = sw_idx; | 5357 | tnapi->tx_cons = sw_idx; |
5358 | 5358 | ||
@@ -6793,7 +6793,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
6793 | } | 6793 | } |
6794 | 6794 | ||
6795 | skb_tx_timestamp(skb); | 6795 | skb_tx_timestamp(skb); |
6796 | netdev_sent_queue(tp->dev, skb->len); | 6796 | netdev_tx_sent_queue(txq, skb->len); |
6797 | 6797 | ||
6798 | /* Packets are ready, update Tx producer idx local and on card. */ | 6798 | /* Packets are ready, update Tx producer idx local and on card. */ |
6799 | tw32_tx_mbox(tnapi->prodmbox, entry); | 6799 | tw32_tx_mbox(tnapi->prodmbox, entry); |
@@ -7275,8 +7275,8 @@ static void tg3_free_rings(struct tg3 *tp) | |||
7275 | 7275 | ||
7276 | dev_kfree_skb_any(skb); | 7276 | dev_kfree_skb_any(skb); |
7277 | } | 7277 | } |
7278 | netdev_tx_reset_queue(netdev_get_tx_queue(tp->dev, j)); | ||
7278 | } | 7279 | } |
7279 | netdev_reset_queue(tp->dev); | ||
7280 | } | 7280 | } |
7281 | 7281 | ||
7282 | /* Initialize tx/rx rings for packet processing. | 7282 | /* Initialize tx/rx rings for packet processing. |
@@ -7886,10 +7886,8 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
7886 | return 0; | 7886 | return 0; |
7887 | } | 7887 | } |
7888 | 7888 | ||
7889 | static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *, | 7889 | static void tg3_get_nstats(struct tg3 *, struct rtnl_link_stats64 *); |
7890 | struct rtnl_link_stats64 *); | 7890 | static void tg3_get_estats(struct tg3 *, struct tg3_ethtool_stats *); |
7891 | static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *, | ||
7892 | struct tg3_ethtool_stats *); | ||
7893 | 7891 | ||
7894 | /* tp->lock is held. */ | 7892 | /* tp->lock is held. */ |
7895 | static int tg3_halt(struct tg3 *tp, int kind, int silent) | 7893 | static int tg3_halt(struct tg3 *tp, int kind, int silent) |
@@ -7910,7 +7908,7 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent) | |||
7910 | 7908 | ||
7911 | if (tp->hw_stats) { | 7909 | if (tp->hw_stats) { |
7912 | /* Save the stats across chip resets... */ | 7910 | /* Save the stats across chip resets... */ |
7913 | tg3_get_stats64(tp->dev, &tp->net_stats_prev), | 7911 | tg3_get_nstats(tp, &tp->net_stats_prev), |
7914 | tg3_get_estats(tp, &tp->estats_prev); | 7912 | tg3_get_estats(tp, &tp->estats_prev); |
7915 | 7913 | ||
7916 | /* And make sure the next sample is new data */ | 7914 | /* And make sure the next sample is new data */ |
@@ -9847,7 +9845,7 @@ static inline u64 get_stat64(tg3_stat64_t *val) | |||
9847 | return ((u64)val->high << 32) | ((u64)val->low); | 9845 | return ((u64)val->high << 32) | ((u64)val->low); |
9848 | } | 9846 | } |
9849 | 9847 | ||
9850 | static u64 calc_crc_errors(struct tg3 *tp) | 9848 | static u64 tg3_calc_crc_errors(struct tg3 *tp) |
9851 | { | 9849 | { |
9852 | struct tg3_hw_stats *hw_stats = tp->hw_stats; | 9850 | struct tg3_hw_stats *hw_stats = tp->hw_stats; |
9853 | 9851 | ||
@@ -9856,14 +9854,12 @@ static u64 calc_crc_errors(struct tg3 *tp) | |||
9856 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { | 9854 | GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) { |
9857 | u32 val; | 9855 | u32 val; |
9858 | 9856 | ||
9859 | spin_lock_bh(&tp->lock); | ||
9860 | if (!tg3_readphy(tp, MII_TG3_TEST1, &val)) { | 9857 | if (!tg3_readphy(tp, MII_TG3_TEST1, &val)) { |
9861 | tg3_writephy(tp, MII_TG3_TEST1, | 9858 | tg3_writephy(tp, MII_TG3_TEST1, |
9862 | val | MII_TG3_TEST1_CRC_EN); | 9859 | val | MII_TG3_TEST1_CRC_EN); |
9863 | tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &val); | 9860 | tg3_readphy(tp, MII_TG3_RXR_COUNTERS, &val); |
9864 | } else | 9861 | } else |
9865 | val = 0; | 9862 | val = 0; |
9866 | spin_unlock_bh(&tp->lock); | ||
9867 | 9863 | ||
9868 | tp->phy_crc_errors += val; | 9864 | tp->phy_crc_errors += val; |
9869 | 9865 | ||
@@ -9877,14 +9873,13 @@ static u64 calc_crc_errors(struct tg3 *tp) | |||
9877 | estats->member = old_estats->member + \ | 9873 | estats->member = old_estats->member + \ |
9878 | get_stat64(&hw_stats->member) | 9874 | get_stat64(&hw_stats->member) |
9879 | 9875 | ||
9880 | static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp, | 9876 | static void tg3_get_estats(struct tg3 *tp, struct tg3_ethtool_stats *estats) |
9881 | struct tg3_ethtool_stats *estats) | ||
9882 | { | 9877 | { |
9883 | struct tg3_ethtool_stats *old_estats = &tp->estats_prev; | 9878 | struct tg3_ethtool_stats *old_estats = &tp->estats_prev; |
9884 | struct tg3_hw_stats *hw_stats = tp->hw_stats; | 9879 | struct tg3_hw_stats *hw_stats = tp->hw_stats; |
9885 | 9880 | ||
9886 | if (!hw_stats) | 9881 | if (!hw_stats) |
9887 | return old_estats; | 9882 | return; |
9888 | 9883 | ||
9889 | ESTAT_ADD(rx_octets); | 9884 | ESTAT_ADD(rx_octets); |
9890 | ESTAT_ADD(rx_fragments); | 9885 | ESTAT_ADD(rx_fragments); |
@@ -9963,20 +9958,13 @@ static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp, | |||
9963 | ESTAT_ADD(nic_tx_threshold_hit); | 9958 | ESTAT_ADD(nic_tx_threshold_hit); |
9964 | 9959 | ||
9965 | ESTAT_ADD(mbuf_lwm_thresh_hit); | 9960 | ESTAT_ADD(mbuf_lwm_thresh_hit); |
9966 | |||
9967 | return estats; | ||
9968 | } | 9961 | } |
9969 | 9962 | ||
9970 | static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, | 9963 | static void tg3_get_nstats(struct tg3 *tp, struct rtnl_link_stats64 *stats) |
9971 | struct rtnl_link_stats64 *stats) | ||
9972 | { | 9964 | { |
9973 | struct tg3 *tp = netdev_priv(dev); | ||
9974 | struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev; | 9965 | struct rtnl_link_stats64 *old_stats = &tp->net_stats_prev; |
9975 | struct tg3_hw_stats *hw_stats = tp->hw_stats; | 9966 | struct tg3_hw_stats *hw_stats = tp->hw_stats; |
9976 | 9967 | ||
9977 | if (!hw_stats) | ||
9978 | return old_stats; | ||
9979 | |||
9980 | stats->rx_packets = old_stats->rx_packets + | 9968 | stats->rx_packets = old_stats->rx_packets + |
9981 | get_stat64(&hw_stats->rx_ucast_packets) + | 9969 | get_stat64(&hw_stats->rx_ucast_packets) + |
9982 | get_stat64(&hw_stats->rx_mcast_packets) + | 9970 | get_stat64(&hw_stats->rx_mcast_packets) + |
@@ -10019,15 +10007,13 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, | |||
10019 | get_stat64(&hw_stats->tx_carrier_sense_errors); | 10007 | get_stat64(&hw_stats->tx_carrier_sense_errors); |
10020 | 10008 | ||
10021 | stats->rx_crc_errors = old_stats->rx_crc_errors + | 10009 | stats->rx_crc_errors = old_stats->rx_crc_errors + |
10022 | calc_crc_errors(tp); | 10010 | tg3_calc_crc_errors(tp); |
10023 | 10011 | ||
10024 | stats->rx_missed_errors = old_stats->rx_missed_errors + | 10012 | stats->rx_missed_errors = old_stats->rx_missed_errors + |
10025 | get_stat64(&hw_stats->rx_discards); | 10013 | get_stat64(&hw_stats->rx_discards); |
10026 | 10014 | ||
10027 | stats->rx_dropped = tp->rx_dropped; | 10015 | stats->rx_dropped = tp->rx_dropped; |
10028 | stats->tx_dropped = tp->tx_dropped; | 10016 | stats->tx_dropped = tp->tx_dropped; |
10029 | |||
10030 | return stats; | ||
10031 | } | 10017 | } |
10032 | 10018 | ||
10033 | static inline u32 calc_crc(unsigned char *buf, int len) | 10019 | static inline u32 calc_crc(unsigned char *buf, int len) |
@@ -15409,6 +15395,21 @@ static void __devinit tg3_init_coal(struct tg3 *tp) | |||
15409 | } | 15395 | } |
15410 | } | 15396 | } |
15411 | 15397 | ||
15398 | static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, | ||
15399 | struct rtnl_link_stats64 *stats) | ||
15400 | { | ||
15401 | struct tg3 *tp = netdev_priv(dev); | ||
15402 | |||
15403 | if (!tp->hw_stats) | ||
15404 | return &tp->net_stats_prev; | ||
15405 | |||
15406 | spin_lock_bh(&tp->lock); | ||
15407 | tg3_get_nstats(tp, stats); | ||
15408 | spin_unlock_bh(&tp->lock); | ||
15409 | |||
15410 | return stats; | ||
15411 | } | ||
15412 | |||
15412 | static const struct net_device_ops tg3_netdev_ops = { | 15413 | static const struct net_device_ops tg3_netdev_ops = { |
15413 | .ndo_open = tg3_open, | 15414 | .ndo_open = tg3_open, |
15414 | .ndo_stop = tg3_close, | 15415 | .ndo_stop = tg3_close, |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index e83d12c7bf20..9d76e59d9526 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -196,6 +196,8 @@ static DEFINE_PCI_DEVICE_TABLE(cxgb4_pci_tbl) = { | |||
196 | CH_DEVICE(0x4408, 4), | 196 | CH_DEVICE(0x4408, 4), |
197 | CH_DEVICE(0x4409, 4), | 197 | CH_DEVICE(0x4409, 4), |
198 | CH_DEVICE(0x440a, 4), | 198 | CH_DEVICE(0x440a, 4), |
199 | CH_DEVICE(0x440d, 4), | ||
200 | CH_DEVICE(0x440e, 4), | ||
199 | { 0, } | 201 | { 0, } |
200 | }; | 202 | }; |
201 | 203 | ||
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index e53365a71484..d963c1d57f71 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | |||
@@ -2892,6 +2892,8 @@ static struct pci_device_id cxgb4vf_pci_tbl[] = { | |||
2892 | CH_DEVICE(0x4808, 0), /* T420-cx */ | 2892 | CH_DEVICE(0x4808, 0), /* T420-cx */ |
2893 | CH_DEVICE(0x4809, 0), /* T420-bt */ | 2893 | CH_DEVICE(0x4809, 0), /* T420-bt */ |
2894 | CH_DEVICE(0x480a, 0), /* T404-bt */ | 2894 | CH_DEVICE(0x480a, 0), /* T404-bt */ |
2895 | CH_DEVICE(0x480d, 0), /* T480-cr */ | ||
2896 | CH_DEVICE(0x480e, 0), /* T440-lp-cr */ | ||
2895 | { 0, } | 2897 | { 0, } |
2896 | }; | 2898 | }; |
2897 | 2899 | ||
diff --git a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h index c2c0680a1146..ac37cacc6136 100644 --- a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h +++ b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h | |||
@@ -157,7 +157,7 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc, | |||
157 | CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0; | 157 | CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0; |
158 | *fcoe_enc_error = (desc->flags & | 158 | *fcoe_enc_error = (desc->flags & |
159 | CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0; | 159 | CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0; |
160 | *fcoe_eof = (u8)((desc->checksum_fcoe >> | 160 | *fcoe_eof = (u8)((le16_to_cpu(desc->checksum_fcoe) >> |
161 | CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) & | 161 | CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) & |
162 | CQ_ENET_RQ_DESC_FCOE_EOF_MASK); | 162 | CQ_ENET_RQ_DESC_FCOE_EOF_MASK); |
163 | *checksum = 0; | 163 | *checksum = 0; |
diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h index ee93a2087fe6..c52295cd05ef 100644 --- a/drivers/net/ethernet/cisco/enic/enic.h +++ b/drivers/net/ethernet/cisco/enic/enic.h | |||
@@ -94,7 +94,7 @@ struct enic { | |||
94 | u32 rx_coalesce_usecs; | 94 | u32 rx_coalesce_usecs; |
95 | u32 tx_coalesce_usecs; | 95 | u32 tx_coalesce_usecs; |
96 | #ifdef CONFIG_PCI_IOV | 96 | #ifdef CONFIG_PCI_IOV |
97 | u32 num_vfs; | 97 | u16 num_vfs; |
98 | #endif | 98 | #endif |
99 | struct enic_port_profile *pp; | 99 | struct enic_port_profile *pp; |
100 | 100 | ||
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index ab3f67f980d8..0e4edd3b6bee 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c | |||
@@ -2370,7 +2370,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, | |||
2370 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); | 2370 | pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); |
2371 | if (pos) { | 2371 | if (pos) { |
2372 | pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF, | 2372 | pci_read_config_word(pdev, pos + PCI_SRIOV_TOTAL_VF, |
2373 | (u16 *)&enic->num_vfs); | 2373 | &enic->num_vfs); |
2374 | if (enic->num_vfs) { | 2374 | if (enic->num_vfs) { |
2375 | err = pci_enable_sriov(pdev, enic->num_vfs); | 2375 | err = pci_enable_sriov(pdev, enic->num_vfs); |
2376 | if (err) { | 2376 | if (err) { |
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c index 22bf03a1829e..c347b6236f8f 100644 --- a/drivers/net/ethernet/cisco/enic/enic_pp.c +++ b/drivers/net/ethernet/cisco/enic/enic_pp.c | |||
@@ -72,7 +72,7 @@ static int enic_set_port_profile(struct enic *enic, int vf) | |||
72 | struct enic_port_profile *pp; | 72 | struct enic_port_profile *pp; |
73 | struct vic_provinfo *vp; | 73 | struct vic_provinfo *vp; |
74 | const u8 oui[3] = VIC_PROVINFO_CISCO_OUI; | 74 | const u8 oui[3] = VIC_PROVINFO_CISCO_OUI; |
75 | const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX); | 75 | const __be16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX); |
76 | char uuid_str[38]; | 76 | char uuid_str[38]; |
77 | char client_mac_str[18]; | 77 | char client_mac_str[18]; |
78 | u8 *client_mac; | 78 | u8 *client_mac; |
diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 5d5fb2627184..e6893cdfd13b 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c | |||
@@ -336,7 +336,9 @@ static struct rtnl_link_stats64 *ehea_get_stats64(struct net_device *dev, | |||
336 | stats->tx_bytes = tx_bytes; | 336 | stats->tx_bytes = tx_bytes; |
337 | stats->rx_packets = rx_packets; | 337 | stats->rx_packets = rx_packets; |
338 | 338 | ||
339 | return &port->stats; | 339 | stats->multicast = port->stats.multicast; |
340 | stats->rx_errors = port->stats.rx_errors; | ||
341 | return stats; | ||
340 | } | 342 | } |
341 | 343 | ||
342 | static void ehea_update_stats(struct work_struct *work) | 344 | static void ehea_update_stats(struct work_struct *work) |
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 27d651a80f3f..55cbf65512c3 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c | |||
@@ -2328,19 +2328,11 @@ jme_change_mtu(struct net_device *netdev, int new_mtu) | |||
2328 | ((new_mtu) < IPV6_MIN_MTU)) | 2328 | ((new_mtu) < IPV6_MIN_MTU)) |
2329 | return -EINVAL; | 2329 | return -EINVAL; |
2330 | 2330 | ||
2331 | if (new_mtu > 4000) { | ||
2332 | jme->reg_rxcs &= ~RXCS_FIFOTHNP; | ||
2333 | jme->reg_rxcs |= RXCS_FIFOTHNP_64QW; | ||
2334 | jme_restart_rx_engine(jme); | ||
2335 | } else { | ||
2336 | jme->reg_rxcs &= ~RXCS_FIFOTHNP; | ||
2337 | jme->reg_rxcs |= RXCS_FIFOTHNP_128QW; | ||
2338 | jme_restart_rx_engine(jme); | ||
2339 | } | ||
2340 | 2331 | ||
2341 | netdev->mtu = new_mtu; | 2332 | netdev->mtu = new_mtu; |
2342 | netdev_update_features(netdev); | 2333 | netdev_update_features(netdev); |
2343 | 2334 | ||
2335 | jme_restart_rx_engine(jme); | ||
2344 | jme_reset_link(jme); | 2336 | jme_reset_link(jme); |
2345 | 2337 | ||
2346 | return 0; | 2338 | return 0; |
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h index 4304072bd3c5..3efc897c9913 100644 --- a/drivers/net/ethernet/jme.h +++ b/drivers/net/ethernet/jme.h | |||
@@ -730,7 +730,7 @@ enum jme_rxcs_values { | |||
730 | RXCS_RETRYCNT_60 = 0x00000F00, | 730 | RXCS_RETRYCNT_60 = 0x00000F00, |
731 | 731 | ||
732 | RXCS_DEFAULT = RXCS_FIFOTHTP_128T | | 732 | RXCS_DEFAULT = RXCS_FIFOTHTP_128T | |
733 | RXCS_FIFOTHNP_128QW | | 733 | RXCS_FIFOTHNP_16QW | |
734 | RXCS_DMAREQSZ_128B | | 734 | RXCS_DMAREQSZ_128B | |
735 | RXCS_RETRYGAP_256ns | | 735 | RXCS_RETRYGAP_256ns | |
736 | RXCS_RETRYCNT_32, | 736 | RXCS_RETRYCNT_32, |
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 8fa41f3082cf..9129ace02560 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c | |||
@@ -1036,7 +1036,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector) | |||
1036 | struct mlx4_priv *priv = mlx4_priv(dev); | 1036 | struct mlx4_priv *priv = mlx4_priv(dev); |
1037 | int vec = 0, err = 0, i; | 1037 | int vec = 0, err = 0, i; |
1038 | 1038 | ||
1039 | spin_lock(&priv->msix_ctl.pool_lock); | 1039 | mutex_lock(&priv->msix_ctl.pool_lock); |
1040 | for (i = 0; !vec && i < dev->caps.comp_pool; i++) { | 1040 | for (i = 0; !vec && i < dev->caps.comp_pool; i++) { |
1041 | if (~priv->msix_ctl.pool_bm & 1ULL << i) { | 1041 | if (~priv->msix_ctl.pool_bm & 1ULL << i) { |
1042 | priv->msix_ctl.pool_bm |= 1ULL << i; | 1042 | priv->msix_ctl.pool_bm |= 1ULL << i; |
@@ -1058,7 +1058,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector) | |||
1058 | eq_set_ci(&priv->eq_table.eq[vec], 1); | 1058 | eq_set_ci(&priv->eq_table.eq[vec], 1); |
1059 | } | 1059 | } |
1060 | } | 1060 | } |
1061 | spin_unlock(&priv->msix_ctl.pool_lock); | 1061 | mutex_unlock(&priv->msix_ctl.pool_lock); |
1062 | 1062 | ||
1063 | if (vec) { | 1063 | if (vec) { |
1064 | *vector = vec; | 1064 | *vector = vec; |
@@ -1079,13 +1079,13 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec) | |||
1079 | if (likely(i >= 0)) { | 1079 | if (likely(i >= 0)) { |
1080 | /*sanity check , making sure were not trying to free irq's | 1080 | /*sanity check , making sure were not trying to free irq's |
1081 | Belonging to a legacy EQ*/ | 1081 | Belonging to a legacy EQ*/ |
1082 | spin_lock(&priv->msix_ctl.pool_lock); | 1082 | mutex_lock(&priv->msix_ctl.pool_lock); |
1083 | if (priv->msix_ctl.pool_bm & 1ULL << i) { | 1083 | if (priv->msix_ctl.pool_bm & 1ULL << i) { |
1084 | free_irq(priv->eq_table.eq[vec].irq, | 1084 | free_irq(priv->eq_table.eq[vec].irq, |
1085 | &priv->eq_table.eq[vec]); | 1085 | &priv->eq_table.eq[vec]); |
1086 | priv->msix_ctl.pool_bm &= ~(1ULL << i); | 1086 | priv->msix_ctl.pool_bm &= ~(1ULL << i); |
1087 | } | 1087 | } |
1088 | spin_unlock(&priv->msix_ctl.pool_lock); | 1088 | mutex_unlock(&priv->msix_ctl.pool_lock); |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | } | 1091 | } |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index 678558b502fc..d498f049c74e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -531,15 +531,14 @@ int mlx4_change_port_types(struct mlx4_dev *dev, | |||
531 | for (port = 0; port < dev->caps.num_ports; port++) { | 531 | for (port = 0; port < dev->caps.num_ports; port++) { |
532 | /* Change the port type only if the new type is different | 532 | /* Change the port type only if the new type is different |
533 | * from the current, and not set to Auto */ | 533 | * from the current, and not set to Auto */ |
534 | if (port_types[port] != dev->caps.port_type[port + 1]) { | 534 | if (port_types[port] != dev->caps.port_type[port + 1]) |
535 | change = 1; | 535 | change = 1; |
536 | dev->caps.port_type[port + 1] = port_types[port]; | ||
537 | } | ||
538 | } | 536 | } |
539 | if (change) { | 537 | if (change) { |
540 | mlx4_unregister_device(dev); | 538 | mlx4_unregister_device(dev); |
541 | for (port = 1; port <= dev->caps.num_ports; port++) { | 539 | for (port = 1; port <= dev->caps.num_ports; port++) { |
542 | mlx4_CLOSE_PORT(dev, port); | 540 | mlx4_CLOSE_PORT(dev, port); |
541 | dev->caps.port_type[port] = port_types[port - 1]; | ||
543 | err = mlx4_SET_PORT(dev, port); | 542 | err = mlx4_SET_PORT(dev, port); |
544 | if (err) { | 543 | if (err) { |
545 | mlx4_err(dev, "Failed to set port %d, " | 544 | mlx4_err(dev, "Failed to set port %d, " |
@@ -986,6 +985,9 @@ static int map_bf_area(struct mlx4_dev *dev) | |||
986 | resource_size_t bf_len; | 985 | resource_size_t bf_len; |
987 | int err = 0; | 986 | int err = 0; |
988 | 987 | ||
988 | if (!dev->caps.bf_reg_size) | ||
989 | return -ENXIO; | ||
990 | |||
989 | bf_start = pci_resource_start(dev->pdev, 2) + | 991 | bf_start = pci_resource_start(dev->pdev, 2) + |
990 | (dev->caps.num_uars << PAGE_SHIFT); | 992 | (dev->caps.num_uars << PAGE_SHIFT); |
991 | bf_len = pci_resource_len(dev->pdev, 2) - | 993 | bf_len = pci_resource_len(dev->pdev, 2) - |
@@ -1825,7 +1827,7 @@ slave_start: | |||
1825 | goto err_master_mfunc; | 1827 | goto err_master_mfunc; |
1826 | 1828 | ||
1827 | priv->msix_ctl.pool_bm = 0; | 1829 | priv->msix_ctl.pool_bm = 0; |
1828 | spin_lock_init(&priv->msix_ctl.pool_lock); | 1830 | mutex_init(&priv->msix_ctl.pool_lock); |
1829 | 1831 | ||
1830 | mlx4_enable_msi_x(dev); | 1832 | mlx4_enable_msi_x(dev); |
1831 | if ((mlx4_is_mfunc(dev)) && | 1833 | if ((mlx4_is_mfunc(dev)) && |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index c92269f8c057..28f8251561f4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -697,7 +697,7 @@ struct mlx4_sense { | |||
697 | 697 | ||
698 | struct mlx4_msix_ctl { | 698 | struct mlx4_msix_ctl { |
699 | u64 pool_bm; | 699 | u64 pool_bm; |
700 | spinlock_t pool_lock; | 700 | struct mutex pool_lock; |
701 | }; | 701 | }; |
702 | 702 | ||
703 | struct mlx4_steer { | 703 | struct mlx4_steer { |
diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index 738f950a1ce5..fb2b36759cbf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c | |||
@@ -151,11 +151,6 @@ static int __mlx4_qp_modify(struct mlx4_dev *dev, struct mlx4_mtt *mtt, | |||
151 | context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT; | 151 | context->log_page_size = mtt->page_shift - MLX4_ICM_PAGE_SHIFT; |
152 | } | 152 | } |
153 | 153 | ||
154 | port = ((context->pri_path.sched_queue >> 6) & 1) + 1; | ||
155 | if (dev->caps.port_type[port] == MLX4_PORT_TYPE_ETH) | ||
156 | context->pri_path.sched_queue = (context->pri_path.sched_queue & | ||
157 | 0xc3); | ||
158 | |||
159 | *(__be32 *) mailbox->buf = cpu_to_be32(optpar); | 154 | *(__be32 *) mailbox->buf = cpu_to_be32(optpar); |
160 | memcpy(mailbox->buf + 8, context, sizeof *context); | 155 | memcpy(mailbox->buf + 8, context, sizeof *context); |
161 | 156 | ||
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index bfdb7af19e49..8752e6e08169 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -2255,8 +2255,7 @@ int mlx4_MODIFY_CQ_wrapper(struct mlx4_dev *dev, int slave, | |||
2255 | 2255 | ||
2256 | if (vhcr->op_modifier == 0) { | 2256 | if (vhcr->op_modifier == 0) { |
2257 | err = handle_resize(dev, slave, vhcr, inbox, outbox, cmd, cq); | 2257 | err = handle_resize(dev, slave, vhcr, inbox, outbox, cmd, cq); |
2258 | if (err) | 2258 | goto ex_put; |
2259 | goto ex_put; | ||
2260 | } | 2259 | } |
2261 | 2260 | ||
2262 | err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); | 2261 | err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd); |
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index 231176fcd2ba..2784bc706f1e 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c | |||
@@ -1545,7 +1545,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev) | |||
1545 | 1545 | ||
1546 | netdev->irq = platform_get_irq(pdev, 0); | 1546 | netdev->irq = platform_get_irq(pdev, 0); |
1547 | 1547 | ||
1548 | if (netdev->irq < 0) { | 1548 | if ((int)netdev->irq < 0) { |
1549 | err = netdev->irq; | 1549 | err = netdev->irq; |
1550 | goto err_get_irq; | 1550 | goto err_get_irq; |
1551 | } | 1551 | } |
diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c index 9cb5f912e489..29e23bec809c 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_param.c | |||
@@ -321,10 +321,10 @@ static void pch_gbe_check_copper_options(struct pch_gbe_adapter *adapter) | |||
321 | pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n"); | 321 | pr_debug("AutoNeg specified along with Speed or Duplex, AutoNeg parameter ignored\n"); |
322 | hw->phy.autoneg_advertised = opt.def; | 322 | hw->phy.autoneg_advertised = opt.def; |
323 | } else { | 323 | } else { |
324 | hw->phy.autoneg_advertised = AutoNeg; | 324 | int tmp = AutoNeg; |
325 | pch_gbe_validate_option( | 325 | |
326 | (int *)(&hw->phy.autoneg_advertised), | 326 | pch_gbe_validate_option(&tmp, &opt, adapter); |
327 | &opt, adapter); | 327 | hw->phy.autoneg_advertised = tmp; |
328 | } | 328 | } |
329 | } | 329 | } |
330 | 330 | ||
@@ -495,9 +495,10 @@ void pch_gbe_check_options(struct pch_gbe_adapter *adapter) | |||
495 | .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list), | 495 | .arg = { .l = { .nr = (int)ARRAY_SIZE(fc_list), |
496 | .p = fc_list } } | 496 | .p = fc_list } } |
497 | }; | 497 | }; |
498 | hw->mac.fc = FlowControl; | 498 | int tmp = FlowControl; |
499 | pch_gbe_validate_option((int *)(&hw->mac.fc), | 499 | |
500 | &opt, adapter); | 500 | pch_gbe_validate_option(&tmp, &opt, adapter); |
501 | hw->mac.fc = tmp; | ||
501 | } | 502 | } |
502 | 503 | ||
503 | pch_gbe_check_copper_options(adapter); | 504 | pch_gbe_check_copper_options(adapter); |
diff --git a/drivers/net/ethernet/packetengines/Kconfig b/drivers/net/ethernet/packetengines/Kconfig index b97132d9dff0..8f29feb35548 100644 --- a/drivers/net/ethernet/packetengines/Kconfig +++ b/drivers/net/ethernet/packetengines/Kconfig | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | config NET_PACKET_ENGINE | 5 | config NET_PACKET_ENGINE |
6 | bool "Packet Engine devices" | 6 | bool "Packet Engine devices" |
7 | default y | ||
7 | depends on PCI | 8 | depends on PCI |
8 | ---help--- | 9 | ---help--- |
9 | If you have a network (Ethernet) card belonging to this class, say Y | 10 | If you have a network (Ethernet) card belonging to this class, say Y |
diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index 7931531c3a40..e61560e16385 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c | |||
@@ -3017,7 +3017,6 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) | |||
3017 | (void __iomem *)port_regs; | 3017 | (void __iomem *)port_regs; |
3018 | u32 delay = 10; | 3018 | u32 delay = 10; |
3019 | int status = 0; | 3019 | int status = 0; |
3020 | unsigned long hw_flags = 0; | ||
3021 | 3020 | ||
3022 | if (ql_mii_setup(qdev)) | 3021 | if (ql_mii_setup(qdev)) |
3023 | return -1; | 3022 | return -1; |
@@ -3228,9 +3227,9 @@ static int ql_adapter_initialize(struct ql3_adapter *qdev) | |||
3228 | value = ql_read_page0_reg(qdev, &port_regs->portStatus); | 3227 | value = ql_read_page0_reg(qdev, &port_regs->portStatus); |
3229 | if (value & PORT_STATUS_IC) | 3228 | if (value & PORT_STATUS_IC) |
3230 | break; | 3229 | break; |
3231 | spin_unlock_irqrestore(&qdev->hw_lock, hw_flags); | 3230 | spin_unlock_irq(&qdev->hw_lock); |
3232 | msleep(500); | 3231 | msleep(500); |
3233 | spin_lock_irqsave(&qdev->hw_lock, hw_flags); | 3232 | spin_lock_irq(&qdev->hw_lock); |
3234 | } while (--delay); | 3233 | } while (--delay); |
3235 | 3234 | ||
3236 | if (delay == 0) { | 3235 | if (delay == 0) { |
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7a0c800b50ad..bbacb3741ec0 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -3781,12 +3781,20 @@ static void rtl8169_init_ring_indexes(struct rtl8169_private *tp) | |||
3781 | 3781 | ||
3782 | static void rtl_hw_jumbo_enable(struct rtl8169_private *tp) | 3782 | static void rtl_hw_jumbo_enable(struct rtl8169_private *tp) |
3783 | { | 3783 | { |
3784 | void __iomem *ioaddr = tp->mmio_addr; | ||
3785 | |||
3786 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
3784 | rtl_generic_op(tp, tp->jumbo_ops.enable); | 3787 | rtl_generic_op(tp, tp->jumbo_ops.enable); |
3788 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
3785 | } | 3789 | } |
3786 | 3790 | ||
3787 | static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) | 3791 | static void rtl_hw_jumbo_disable(struct rtl8169_private *tp) |
3788 | { | 3792 | { |
3793 | void __iomem *ioaddr = tp->mmio_addr; | ||
3794 | |||
3795 | RTL_W8(Cfg9346, Cfg9346_Unlock); | ||
3789 | rtl_generic_op(tp, tp->jumbo_ops.disable); | 3796 | rtl_generic_op(tp, tp->jumbo_ops.disable); |
3797 | RTL_W8(Cfg9346, Cfg9346_Lock); | ||
3790 | } | 3798 | } |
3791 | 3799 | ||
3792 | static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) | 3800 | static void r8168c_hw_jumbo_enable(struct rtl8169_private *tp) |
@@ -6186,6 +6194,9 @@ static void rtl_shutdown(struct pci_dev *pdev) | |||
6186 | { | 6194 | { |
6187 | struct net_device *dev = pci_get_drvdata(pdev); | 6195 | struct net_device *dev = pci_get_drvdata(pdev); |
6188 | struct rtl8169_private *tp = netdev_priv(dev); | 6196 | struct rtl8169_private *tp = netdev_priv(dev); |
6197 | struct device *d = &pdev->dev; | ||
6198 | |||
6199 | pm_runtime_get_sync(d); | ||
6189 | 6200 | ||
6190 | rtl8169_net_suspend(dev); | 6201 | rtl8169_net_suspend(dev); |
6191 | 6202 | ||
@@ -6207,6 +6218,8 @@ static void rtl_shutdown(struct pci_dev *pdev) | |||
6207 | pci_wake_from_d3(pdev, true); | 6218 | pci_wake_from_d3(pdev, true); |
6208 | pci_set_power_state(pdev, PCI_D3hot); | 6219 | pci_set_power_state(pdev, PCI_D3hot); |
6209 | } | 6220 | } |
6221 | |||
6222 | pm_runtime_put_noidle(d); | ||
6210 | } | 6223 | } |
6211 | 6224 | ||
6212 | static struct pci_driver rtl8169_pci_driver = { | 6225 | static struct pci_driver rtl8169_pci_driver = { |
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index aca349861767..fc52fca74193 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c | |||
@@ -156,11 +156,10 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) | |||
156 | if (unlikely(!skb)) | 156 | if (unlikely(!skb)) |
157 | return -ENOMEM; | 157 | return -ENOMEM; |
158 | 158 | ||
159 | /* Adjust the SKB for padding and checksum */ | 159 | /* Adjust the SKB for padding */ |
160 | skb_reserve(skb, NET_IP_ALIGN); | 160 | skb_reserve(skb, NET_IP_ALIGN); |
161 | rx_buf->len = skb_len - NET_IP_ALIGN; | 161 | rx_buf->len = skb_len - NET_IP_ALIGN; |
162 | rx_buf->is_page = false; | 162 | rx_buf->is_page = false; |
163 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
164 | 163 | ||
165 | rx_buf->dma_addr = pci_map_single(efx->pci_dev, | 164 | rx_buf->dma_addr = pci_map_single(efx->pci_dev, |
166 | skb->data, rx_buf->len, | 165 | skb->data, rx_buf->len, |
@@ -496,6 +495,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel, | |||
496 | 495 | ||
497 | EFX_BUG_ON_PARANOID(!checksummed); | 496 | EFX_BUG_ON_PARANOID(!checksummed); |
498 | rx_buf->u.skb = NULL; | 497 | rx_buf->u.skb = NULL; |
498 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
499 | 499 | ||
500 | gro_result = napi_gro_receive(napi, skb); | 500 | gro_result = napi_gro_receive(napi, skb); |
501 | } | 501 | } |
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 4fa0bcb25dfc..4b2f54565f64 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c | |||
@@ -1009,7 +1009,7 @@ static void emac_rx_handler(void *token, int len, int status) | |||
1009 | int ret; | 1009 | int ret; |
1010 | 1010 | ||
1011 | /* free and bail if we are shutting down */ | 1011 | /* free and bail if we are shutting down */ |
1012 | if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) { | 1012 | if (unlikely(!netif_running(ndev))) { |
1013 | dev_kfree_skb_any(skb); | 1013 | dev_kfree_skb_any(skb); |
1014 | return; | 1014 | return; |
1015 | } | 1015 | } |
@@ -1038,7 +1038,9 @@ static void emac_rx_handler(void *token, int len, int status) | |||
1038 | recycle: | 1038 | recycle: |
1039 | ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, | 1039 | ret = cpdma_chan_submit(priv->rxchan, skb, skb->data, |
1040 | skb_tailroom(skb), GFP_KERNEL); | 1040 | skb_tailroom(skb), GFP_KERNEL); |
1041 | if (WARN_ON(ret < 0)) | 1041 | |
1042 | WARN_ON(ret == -ENOMEM); | ||
1043 | if (unlikely(ret < 0)) | ||
1042 | dev_kfree_skb_any(skb); | 1044 | dev_kfree_skb_any(skb); |
1043 | } | 1045 | } |
1044 | 1046 | ||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 466c58a7353d..610860f28968 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -166,7 +166,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
166 | 166 | ||
167 | dev_kfree_skb(skb); | 167 | dev_kfree_skb(skb); |
168 | net->stats.tx_dropped++; | 168 | net->stats.tx_dropped++; |
169 | return NETDEV_TX_BUSY; | 169 | return NETDEV_TX_OK; |
170 | } | 170 | } |
171 | 171 | ||
172 | packet->extension = (void *)(unsigned long)packet + | 172 | packet->extension = (void *)(unsigned long)packet + |
@@ -226,7 +226,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
226 | dev_kfree_skb_any(skb); | 226 | dev_kfree_skb_any(skb); |
227 | } | 227 | } |
228 | 228 | ||
229 | return ret ? NETDEV_TX_BUSY : NETDEV_TX_OK; | 229 | return NETDEV_TX_OK; |
230 | } | 230 | } |
231 | 231 | ||
232 | /* | 232 | /* |
@@ -313,7 +313,7 @@ int netvsc_recv_callback(struct hv_device *device_obj, | |||
313 | static void netvsc_get_drvinfo(struct net_device *net, | 313 | static void netvsc_get_drvinfo(struct net_device *net, |
314 | struct ethtool_drvinfo *info) | 314 | struct ethtool_drvinfo *info) |
315 | { | 315 | { |
316 | strcpy(info->driver, "hv_netvsc"); | 316 | strcpy(info->driver, KBUILD_MODNAME); |
317 | strcpy(info->version, HV_DRV_VERSION); | 317 | strcpy(info->version, HV_DRV_VERSION); |
318 | strcpy(info->fw_version, "N/A"); | 318 | strcpy(info->fw_version, "N/A"); |
319 | } | 319 | } |
@@ -485,7 +485,7 @@ MODULE_DEVICE_TABLE(vmbus, id_table); | |||
485 | 485 | ||
486 | /* The one and only one */ | 486 | /* The one and only one */ |
487 | static struct hv_driver netvsc_drv = { | 487 | static struct hv_driver netvsc_drv = { |
488 | .name = "netvsc", | 488 | .name = KBUILD_MODNAME, |
489 | .id_table = id_table, | 489 | .id_table = id_table, |
490 | .probe = netvsc_probe, | 490 | .probe = netvsc_probe, |
491 | .remove = netvsc_remove, | 491 | .remove = netvsc_remove, |
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index c81f136ae670..0856e1b7a849 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c | |||
@@ -30,16 +30,16 @@ | |||
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
32 | 32 | ||
33 | MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IC1001 PHY drivers"); | 33 | MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers"); |
34 | MODULE_AUTHOR("Michael Barkowski"); | 34 | MODULE_AUTHOR("Michael Barkowski"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
37 | /* IP101A/IP1001 */ | 37 | /* IP101A/G - IP1001 */ |
38 | #define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ | 38 | #define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */ |
39 | #define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ | 39 | #define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */ |
40 | #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ | 40 | #define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */ |
41 | #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ | 41 | #define IP1001_APS_ON 11 /* IP1001 APS Mode bit */ |
42 | #define IP101A_APS_ON 2 /* IP101A APS Mode bit */ | 42 | #define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */ |
43 | 43 | ||
44 | static int ip175c_config_init(struct phy_device *phydev) | 44 | static int ip175c_config_init(struct phy_device *phydev) |
45 | { | 45 | { |
@@ -98,20 +98,24 @@ static int ip175c_config_init(struct phy_device *phydev) | |||
98 | 98 | ||
99 | static int ip1xx_reset(struct phy_device *phydev) | 99 | static int ip1xx_reset(struct phy_device *phydev) |
100 | { | 100 | { |
101 | int err, bmcr; | 101 | int bmcr; |
102 | 102 | ||
103 | /* Software Reset PHY */ | 103 | /* Software Reset PHY */ |
104 | bmcr = phy_read(phydev, MII_BMCR); | 104 | bmcr = phy_read(phydev, MII_BMCR); |
105 | if (bmcr < 0) | ||
106 | return bmcr; | ||
105 | bmcr |= BMCR_RESET; | 107 | bmcr |= BMCR_RESET; |
106 | err = phy_write(phydev, MII_BMCR, bmcr); | 108 | bmcr = phy_write(phydev, MII_BMCR, bmcr); |
107 | if (err < 0) | 109 | if (bmcr < 0) |
108 | return err; | 110 | return bmcr; |
109 | 111 | ||
110 | do { | 112 | do { |
111 | bmcr = phy_read(phydev, MII_BMCR); | 113 | bmcr = phy_read(phydev, MII_BMCR); |
114 | if (bmcr < 0) | ||
115 | return bmcr; | ||
112 | } while (bmcr & BMCR_RESET); | 116 | } while (bmcr & BMCR_RESET); |
113 | 117 | ||
114 | return err; | 118 | return 0; |
115 | } | 119 | } |
116 | 120 | ||
117 | static int ip1001_config_init(struct phy_device *phydev) | 121 | static int ip1001_config_init(struct phy_device *phydev) |
@@ -124,7 +128,10 @@ static int ip1001_config_init(struct phy_device *phydev) | |||
124 | 128 | ||
125 | /* Enable Auto Power Saving mode */ | 129 | /* Enable Auto Power Saving mode */ |
126 | c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2); | 130 | c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2); |
131 | if (c < 0) | ||
132 | return c; | ||
127 | c |= IP1001_APS_ON; | 133 | c |= IP1001_APS_ON; |
134 | c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c); | ||
128 | if (c < 0) | 135 | if (c < 0) |
129 | return c; | 136 | return c; |
130 | 137 | ||
@@ -132,14 +139,19 @@ static int ip1001_config_init(struct phy_device *phydev) | |||
132 | /* Additional delay (2ns) used to adjust RX clock phase | 139 | /* Additional delay (2ns) used to adjust RX clock phase |
133 | * at RGMII interface */ | 140 | * at RGMII interface */ |
134 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); | 141 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); |
142 | if (c < 0) | ||
143 | return c; | ||
144 | |||
135 | c |= IP1001_PHASE_SEL_MASK; | 145 | c |= IP1001_PHASE_SEL_MASK; |
136 | c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); | 146 | c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c); |
147 | if (c < 0) | ||
148 | return c; | ||
137 | } | 149 | } |
138 | 150 | ||
139 | return c; | 151 | return 0; |
140 | } | 152 | } |
141 | 153 | ||
142 | static int ip101a_config_init(struct phy_device *phydev) | 154 | static int ip101a_g_config_init(struct phy_device *phydev) |
143 | { | 155 | { |
144 | int c; | 156 | int c; |
145 | 157 | ||
@@ -149,7 +161,7 @@ static int ip101a_config_init(struct phy_device *phydev) | |||
149 | 161 | ||
150 | /* Enable Auto Power Saving mode */ | 162 | /* Enable Auto Power Saving mode */ |
151 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); | 163 | c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS); |
152 | c |= IP101A_APS_ON; | 164 | c |= IP101A_G_APS_ON; |
153 | return c; | 165 | return c; |
154 | } | 166 | } |
155 | 167 | ||
@@ -191,6 +203,7 @@ static struct phy_driver ip1001_driver = { | |||
191 | .phy_id_mask = 0x0ffffff0, | 203 | .phy_id_mask = 0x0ffffff0, |
192 | .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | | 204 | .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | |
193 | SUPPORTED_Asym_Pause, | 205 | SUPPORTED_Asym_Pause, |
206 | .flags = PHY_HAS_INTERRUPT, | ||
194 | .config_init = &ip1001_config_init, | 207 | .config_init = &ip1001_config_init, |
195 | .config_aneg = &genphy_config_aneg, | 208 | .config_aneg = &genphy_config_aneg, |
196 | .read_status = &genphy_read_status, | 209 | .read_status = &genphy_read_status, |
@@ -199,13 +212,14 @@ static struct phy_driver ip1001_driver = { | |||
199 | .driver = { .owner = THIS_MODULE,}, | 212 | .driver = { .owner = THIS_MODULE,}, |
200 | }; | 213 | }; |
201 | 214 | ||
202 | static struct phy_driver ip101a_driver = { | 215 | static struct phy_driver ip101a_g_driver = { |
203 | .phy_id = 0x02430c54, | 216 | .phy_id = 0x02430c54, |
204 | .name = "ICPlus IP101A", | 217 | .name = "ICPlus IP101A/G", |
205 | .phy_id_mask = 0x0ffffff0, | 218 | .phy_id_mask = 0x0ffffff0, |
206 | .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | | 219 | .features = PHY_BASIC_FEATURES | SUPPORTED_Pause | |
207 | SUPPORTED_Asym_Pause, | 220 | SUPPORTED_Asym_Pause, |
208 | .config_init = &ip101a_config_init, | 221 | .flags = PHY_HAS_INTERRUPT, |
222 | .config_init = &ip101a_g_config_init, | ||
209 | .config_aneg = &genphy_config_aneg, | 223 | .config_aneg = &genphy_config_aneg, |
210 | .read_status = &genphy_read_status, | 224 | .read_status = &genphy_read_status, |
211 | .suspend = genphy_suspend, | 225 | .suspend = genphy_suspend, |
@@ -221,7 +235,7 @@ static int __init icplus_init(void) | |||
221 | if (ret < 0) | 235 | if (ret < 0) |
222 | return -ENODEV; | 236 | return -ENODEV; |
223 | 237 | ||
224 | ret = phy_driver_register(&ip101a_driver); | 238 | ret = phy_driver_register(&ip101a_g_driver); |
225 | if (ret < 0) | 239 | if (ret < 0) |
226 | return -ENODEV; | 240 | return -ENODEV; |
227 | 241 | ||
@@ -231,7 +245,7 @@ static int __init icplus_init(void) | |||
231 | static void __exit icplus_exit(void) | 245 | static void __exit icplus_exit(void) |
232 | { | 246 | { |
233 | phy_driver_unregister(&ip1001_driver); | 247 | phy_driver_unregister(&ip1001_driver); |
234 | phy_driver_unregister(&ip101a_driver); | 248 | phy_driver_unregister(&ip101a_g_driver); |
235 | phy_driver_unregister(&ip175c_driver); | 249 | phy_driver_unregister(&ip175c_driver); |
236 | } | 250 | } |
237 | 251 | ||
@@ -241,6 +255,7 @@ module_exit(icplus_exit); | |||
241 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { | 255 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { |
242 | { 0x02430d80, 0x0ffffff0 }, | 256 | { 0x02430d80, 0x0ffffff0 }, |
243 | { 0x02430d90, 0x0ffffff0 }, | 257 | { 0x02430d90, 0x0ffffff0 }, |
258 | { 0x02430c54, 0x0ffffff0 }, | ||
244 | { } | 259 | { } |
245 | }; | 260 | }; |
246 | 261 | ||
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c index edfa15d2e795..486b4048850d 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c | |||
@@ -2024,14 +2024,22 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2024 | continue; | 2024 | continue; |
2025 | } | 2025 | } |
2026 | if (PPP_MP_CB(p)->sequence != seq) { | 2026 | if (PPP_MP_CB(p)->sequence != seq) { |
2027 | u32 oldseq; | ||
2027 | /* Fragment `seq' is missing. If it is after | 2028 | /* Fragment `seq' is missing. If it is after |
2028 | minseq, it might arrive later, so stop here. */ | 2029 | minseq, it might arrive later, so stop here. */ |
2029 | if (seq_after(seq, minseq)) | 2030 | if (seq_after(seq, minseq)) |
2030 | break; | 2031 | break; |
2031 | /* Fragment `seq' is lost, keep going. */ | 2032 | /* Fragment `seq' is lost, keep going. */ |
2032 | lost = 1; | 2033 | lost = 1; |
2034 | oldseq = seq; | ||
2033 | seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? | 2035 | seq = seq_before(minseq, PPP_MP_CB(p)->sequence)? |
2034 | minseq + 1: PPP_MP_CB(p)->sequence; | 2036 | minseq + 1: PPP_MP_CB(p)->sequence; |
2037 | |||
2038 | if (ppp->debug & 1) | ||
2039 | netdev_printk(KERN_DEBUG, ppp->dev, | ||
2040 | "lost frag %u..%u\n", | ||
2041 | oldseq, seq-1); | ||
2042 | |||
2035 | goto again; | 2043 | goto again; |
2036 | } | 2044 | } |
2037 | 2045 | ||
@@ -2076,6 +2084,10 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2076 | struct sk_buff *tmp2; | 2084 | struct sk_buff *tmp2; |
2077 | 2085 | ||
2078 | skb_queue_reverse_walk_from_safe(list, p, tmp2) { | 2086 | skb_queue_reverse_walk_from_safe(list, p, tmp2) { |
2087 | if (ppp->debug & 1) | ||
2088 | netdev_printk(KERN_DEBUG, ppp->dev, | ||
2089 | "discarding frag %u\n", | ||
2090 | PPP_MP_CB(p)->sequence); | ||
2079 | __skb_unlink(p, list); | 2091 | __skb_unlink(p, list); |
2080 | kfree_skb(p); | 2092 | kfree_skb(p); |
2081 | } | 2093 | } |
@@ -2091,6 +2103,17 @@ ppp_mp_reconstruct(struct ppp *ppp) | |||
2091 | /* If we have discarded any fragments, | 2103 | /* If we have discarded any fragments, |
2092 | signal a receive error. */ | 2104 | signal a receive error. */ |
2093 | if (PPP_MP_CB(head)->sequence != ppp->nextseq) { | 2105 | if (PPP_MP_CB(head)->sequence != ppp->nextseq) { |
2106 | skb_queue_walk_safe(list, p, tmp) { | ||
2107 | if (p == head) | ||
2108 | break; | ||
2109 | if (ppp->debug & 1) | ||
2110 | netdev_printk(KERN_DEBUG, ppp->dev, | ||
2111 | "discarding frag %u\n", | ||
2112 | PPP_MP_CB(p)->sequence); | ||
2113 | __skb_unlink(p, list); | ||
2114 | kfree_skb(p); | ||
2115 | } | ||
2116 | |||
2094 | if (ppp->debug & 1) | 2117 | if (ppp->debug & 1) |
2095 | netdev_printk(KERN_DEBUG, ppp->dev, | 2118 | netdev_printk(KERN_DEBUG, ppp->dev, |
2096 | " missed pkts %u..%u\n", | 2119 | " missed pkts %u..%u\n", |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 93c5d72711b0..2d7601dd6660 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -359,7 +359,7 @@ static void tun_free_netdev(struct net_device *dev) | |||
359 | { | 359 | { |
360 | struct tun_struct *tun = netdev_priv(dev); | 360 | struct tun_struct *tun = netdev_priv(dev); |
361 | 361 | ||
362 | sock_put(tun->socket.sk); | 362 | sk_release_kernel(tun->socket.sk); |
363 | } | 363 | } |
364 | 364 | ||
365 | /* Net device open. */ | 365 | /* Net device open. */ |
@@ -980,10 +980,18 @@ static int tun_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
980 | return ret; | 980 | return ret; |
981 | } | 981 | } |
982 | 982 | ||
983 | static int tun_release(struct socket *sock) | ||
984 | { | ||
985 | if (sock->sk) | ||
986 | sock_put(sock->sk); | ||
987 | return 0; | ||
988 | } | ||
989 | |||
983 | /* Ops structure to mimic raw sockets with tun */ | 990 | /* Ops structure to mimic raw sockets with tun */ |
984 | static const struct proto_ops tun_socket_ops = { | 991 | static const struct proto_ops tun_socket_ops = { |
985 | .sendmsg = tun_sendmsg, | 992 | .sendmsg = tun_sendmsg, |
986 | .recvmsg = tun_recvmsg, | 993 | .recvmsg = tun_recvmsg, |
994 | .release = tun_release, | ||
987 | }; | 995 | }; |
988 | 996 | ||
989 | static struct proto tun_proto = { | 997 | static struct proto tun_proto = { |
@@ -1110,10 +1118,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1110 | tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); | 1118 | tun->vnet_hdr_sz = sizeof(struct virtio_net_hdr); |
1111 | 1119 | ||
1112 | err = -ENOMEM; | 1120 | err = -ENOMEM; |
1113 | sk = sk_alloc(net, AF_UNSPEC, GFP_KERNEL, &tun_proto); | 1121 | sk = sk_alloc(&init_net, AF_UNSPEC, GFP_KERNEL, &tun_proto); |
1114 | if (!sk) | 1122 | if (!sk) |
1115 | goto err_free_dev; | 1123 | goto err_free_dev; |
1116 | 1124 | ||
1125 | sk_change_net(sk, net); | ||
1117 | tun->socket.wq = &tun->wq; | 1126 | tun->socket.wq = &tun->wq; |
1118 | init_waitqueue_head(&tun->wq.wait); | 1127 | init_waitqueue_head(&tun->wq.wait); |
1119 | tun->socket.ops = &tun_socket_ops; | 1128 | tun->socket.ops = &tun_socket_ops; |
@@ -1174,7 +1183,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1174 | return 0; | 1183 | return 0; |
1175 | 1184 | ||
1176 | err_free_sk: | 1185 | err_free_sk: |
1177 | sock_put(sk); | 1186 | tun_free_netdev(dev); |
1178 | err_free_dev: | 1187 | err_free_dev: |
1179 | free_netdev(dev); | 1188 | free_netdev(dev); |
1180 | failed: | 1189 | failed: |
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index 8e84f5bdd6ca..d6da5eed5453 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -1599,6 +1599,10 @@ static const struct usb_device_id products [] = { | |||
1599 | USB_DEVICE (0x6189, 0x182d), | 1599 | USB_DEVICE (0x6189, 0x182d), |
1600 | .driver_info = (unsigned long) &ax8817x_info, | 1600 | .driver_info = (unsigned long) &ax8817x_info, |
1601 | }, { | 1601 | }, { |
1602 | // Sitecom LN-031 "USB 2.0 10/100/1000 Ethernet adapter" | ||
1603 | USB_DEVICE (0x0df6, 0x0056), | ||
1604 | .driver_info = (unsigned long) &ax88178_info, | ||
1605 | }, { | ||
1602 | // corega FEther USB2-TX | 1606 | // corega FEther USB2-TX |
1603 | USB_DEVICE (0x07aa, 0x0017), | 1607 | USB_DEVICE (0x07aa, 0x0017), |
1604 | .driver_info = (unsigned long) &ax8817x_info, | 1608 | .driver_info = (unsigned long) &ax8817x_info, |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 41a61efc331e..90a30026a931 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
@@ -573,6 +573,13 @@ static const struct usb_device_id products [] = { | |||
573 | .driver_info = 0, | 573 | .driver_info = 0, |
574 | }, | 574 | }, |
575 | 575 | ||
576 | /* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */ | ||
577 | { | ||
578 | USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM, | ||
579 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | ||
580 | .driver_info = 0, | ||
581 | }, | ||
582 | |||
576 | /* | 583 | /* |
577 | * WHITELIST!!! | 584 | * WHITELIST!!! |
578 | * | 585 | * |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 304fe78ff60e..e1324b4a0f66 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -1632,7 +1632,7 @@ static int hso_get_count(struct tty_struct *tty, | |||
1632 | struct hso_serial *serial = get_serial_by_tty(tty); | 1632 | struct hso_serial *serial = get_serial_by_tty(tty); |
1633 | struct hso_tiocmget *tiocmget = serial->tiocmget; | 1633 | struct hso_tiocmget *tiocmget = serial->tiocmget; |
1634 | 1634 | ||
1635 | memset(&icount, 0, sizeof(struct serial_icounter_struct)); | 1635 | memset(icount, 0, sizeof(struct serial_icounter_struct)); |
1636 | 1636 | ||
1637 | if (!tiocmget) | 1637 | if (!tiocmget) |
1638 | return -ENOENT; | 1638 | return -ENOENT; |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index fae0fbd8bc88..59681f01a54e 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -328,13 +328,13 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags) | |||
328 | unsigned long lockflags; | 328 | unsigned long lockflags; |
329 | size_t size = dev->rx_urb_size; | 329 | size_t size = dev->rx_urb_size; |
330 | 330 | ||
331 | if ((skb = alloc_skb (size + NET_IP_ALIGN, flags)) == NULL) { | 331 | skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); |
332 | if (!skb) { | ||
332 | netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); | 333 | netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); |
333 | usbnet_defer_kevent (dev, EVENT_RX_MEMORY); | 334 | usbnet_defer_kevent (dev, EVENT_RX_MEMORY); |
334 | usb_free_urb (urb); | 335 | usb_free_urb (urb); |
335 | return -ENOMEM; | 336 | return -ENOMEM; |
336 | } | 337 | } |
337 | skb_reserve (skb, NET_IP_ALIGN); | ||
338 | 338 | ||
339 | entry = (struct skb_data *) skb->cb; | 339 | entry = (struct skb_data *) skb->cb; |
340 | entry->urb = urb; | 340 | entry->urb = urb; |
@@ -589,6 +589,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) | |||
589 | entry = (struct skb_data *) skb->cb; | 589 | entry = (struct skb_data *) skb->cb; |
590 | urb = entry->urb; | 590 | urb = entry->urb; |
591 | 591 | ||
592 | spin_unlock_irqrestore(&q->lock, flags); | ||
592 | // during some PM-driven resume scenarios, | 593 | // during some PM-driven resume scenarios, |
593 | // these (async) unlinks complete immediately | 594 | // these (async) unlinks complete immediately |
594 | retval = usb_unlink_urb (urb); | 595 | retval = usb_unlink_urb (urb); |
@@ -596,6 +597,7 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) | |||
596 | netdev_dbg(dev->net, "unlink urb err, %d\n", retval); | 597 | netdev_dbg(dev->net, "unlink urb err, %d\n", retval); |
597 | else | 598 | else |
598 | count++; | 599 | count++; |
600 | spin_lock_irqsave(&q->lock, flags); | ||
599 | } | 601 | } |
600 | spin_unlock_irqrestore (&q->lock, flags); | 602 | spin_unlock_irqrestore (&q->lock, flags); |
601 | return count; | 603 | return count; |
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c index f701d4127087..c3197ce0e2ad 100644 --- a/drivers/net/usb/zaurus.c +++ b/drivers/net/usb/zaurus.c | |||
@@ -316,6 +316,11 @@ static const struct usb_device_id products [] = { | |||
316 | ZAURUS_MASTER_INTERFACE, | 316 | ZAURUS_MASTER_INTERFACE, |
317 | .driver_info = ZAURUS_PXA_INFO, | 317 | .driver_info = ZAURUS_PXA_INFO, |
318 | }, { | 318 | }, { |
319 | /* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */ | ||
320 | USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM, | ||
321 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | ||
322 | .driver_info = (unsigned long) &bogus_mdlm_info, | ||
323 | }, { | ||
319 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | 324 | .match_flags = USB_DEVICE_ID_MATCH_INT_INFO |
320 | | USB_DEVICE_ID_MATCH_DEVICE, | 325 | | USB_DEVICE_ID_MATCH_DEVICE, |
321 | .idVendor = 0x04DD, | 326 | .idVendor = 0x04DD, |
@@ -349,6 +354,13 @@ static const struct usb_device_id products [] = { | |||
349 | ZAURUS_MASTER_INTERFACE, | 354 | ZAURUS_MASTER_INTERFACE, |
350 | .driver_info = OLYMPUS_MXL_INFO, | 355 | .driver_info = OLYMPUS_MXL_INFO, |
351 | }, | 356 | }, |
357 | |||
358 | /* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */ | ||
359 | { | ||
360 | USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM, | ||
361 | USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), | ||
362 | .driver_info = (unsigned long) &bogus_mdlm_info, | ||
363 | }, | ||
352 | { }, // END | 364 | { }, // END |
353 | }; | 365 | }; |
354 | MODULE_DEVICE_TABLE(usb, products); | 366 | MODULE_DEVICE_TABLE(usb, products); |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index de7fc345148a..756c0f5565a5 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -830,21 +830,16 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, | |||
830 | ctx->l4_hdr_size = ((struct tcphdr *) | 830 | ctx->l4_hdr_size = ((struct tcphdr *) |
831 | skb_transport_header(skb))->doff * 4; | 831 | skb_transport_header(skb))->doff * 4; |
832 | else if (iph->protocol == IPPROTO_UDP) | 832 | else if (iph->protocol == IPPROTO_UDP) |
833 | /* | ||
834 | * Use tcp header size so that bytes to | ||
835 | * be copied are more than required by | ||
836 | * the device. | ||
837 | */ | ||
838 | ctx->l4_hdr_size = | 833 | ctx->l4_hdr_size = |
839 | sizeof(struct tcphdr); | 834 | sizeof(struct udphdr); |
840 | else | 835 | else |
841 | ctx->l4_hdr_size = 0; | 836 | ctx->l4_hdr_size = 0; |
842 | } else { | 837 | } else { |
843 | /* for simplicity, don't copy L4 headers */ | 838 | /* for simplicity, don't copy L4 headers */ |
844 | ctx->l4_hdr_size = 0; | 839 | ctx->l4_hdr_size = 0; |
845 | } | 840 | } |
846 | ctx->copy_size = ctx->eth_ip_hdr_size + | 841 | ctx->copy_size = min(ctx->eth_ip_hdr_size + |
847 | ctx->l4_hdr_size; | 842 | ctx->l4_hdr_size, skb->len); |
848 | } else { | 843 | } else { |
849 | ctx->eth_ip_hdr_size = 0; | 844 | ctx->eth_ip_hdr_size = 0; |
850 | ctx->l4_hdr_size = 0; | 845 | ctx->l4_hdr_size = 0; |
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index ed54797db191..fc46a81ad538 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h | |||
@@ -70,10 +70,10 @@ | |||
70 | /* | 70 | /* |
71 | * Version numbers | 71 | * Version numbers |
72 | */ | 72 | */ |
73 | #define VMXNET3_DRIVER_VERSION_STRING "1.1.18.0-k" | 73 | #define VMXNET3_DRIVER_VERSION_STRING "1.1.29.0-k" |
74 | 74 | ||
75 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ | 75 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ |
76 | #define VMXNET3_DRIVER_VERSION_NUM 0x01011200 | 76 | #define VMXNET3_DRIVER_VERSION_NUM 0x01011D00 |
77 | 77 | ||
78 | #if defined(CONFIG_PCI_MSI) | 78 | #if defined(CONFIG_PCI_MSI) |
79 | /* RSS only makes sense if MSI-X is supported. */ | 79 | /* RSS only makes sense if MSI-X is supported. */ |
diff --git a/drivers/net/wimax/i2400m/netdev.c b/drivers/net/wimax/i2400m/netdev.c index 64a110604ad3..63e4b709efa9 100644 --- a/drivers/net/wimax/i2400m/netdev.c +++ b/drivers/net/wimax/i2400m/netdev.c | |||
@@ -367,38 +367,28 @@ netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb, | |||
367 | { | 367 | { |
368 | struct i2400m *i2400m = net_dev_to_i2400m(net_dev); | 368 | struct i2400m *i2400m = net_dev_to_i2400m(net_dev); |
369 | struct device *dev = i2400m_dev(i2400m); | 369 | struct device *dev = i2400m_dev(i2400m); |
370 | int result; | 370 | int result = -1; |
371 | 371 | ||
372 | d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev); | 372 | d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev); |
373 | if (skb_header_cloned(skb)) { | 373 | |
374 | /* | 374 | if (skb_header_cloned(skb) && |
375 | * Make tcpdump/wireshark happy -- if they are | 375 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) |
376 | * running, the skb is cloned and we will overwrite | 376 | goto drop; |
377 | * the mac fields in i2400m_tx_prep_header. Expand | ||
378 | * seems to fix this... | ||
379 | */ | ||
380 | result = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | ||
381 | if (result) { | ||
382 | result = NETDEV_TX_BUSY; | ||
383 | goto error_expand; | ||
384 | } | ||
385 | } | ||
386 | 377 | ||
387 | if (i2400m->state == I2400M_SS_IDLE) | 378 | if (i2400m->state == I2400M_SS_IDLE) |
388 | result = i2400m_net_wake_tx(i2400m, net_dev, skb); | 379 | result = i2400m_net_wake_tx(i2400m, net_dev, skb); |
389 | else | 380 | else |
390 | result = i2400m_net_tx(i2400m, net_dev, skb); | 381 | result = i2400m_net_tx(i2400m, net_dev, skb); |
391 | if (result < 0) | 382 | if (result < 0) { |
383 | drop: | ||
392 | net_dev->stats.tx_dropped++; | 384 | net_dev->stats.tx_dropped++; |
393 | else { | 385 | } else { |
394 | net_dev->stats.tx_packets++; | 386 | net_dev->stats.tx_packets++; |
395 | net_dev->stats.tx_bytes += skb->len; | 387 | net_dev->stats.tx_bytes += skb->len; |
396 | } | 388 | } |
397 | result = NETDEV_TX_OK; | 389 | dev_kfree_skb(skb); |
398 | error_expand: | ||
399 | kfree_skb(skb); | ||
400 | d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result); | 390 | d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result); |
401 | return result; | 391 | return NETDEV_TX_OK; |
402 | } | 392 | } |
403 | 393 | ||
404 | 394 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c index f901a17f76ba..86a891f93fc9 100644 --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -489,8 +489,6 @@ static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) | |||
489 | ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); | 489 | ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); |
490 | ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); | 490 | ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); |
491 | ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); | 491 | ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); |
492 | ATH_ALLOC_BANK(ah->addac5416_21, | ||
493 | ah->iniAddac.ia_rows * ah->iniAddac.ia_columns); | ||
494 | ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); | 492 | ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); |
495 | 493 | ||
496 | return 0; | 494 | return 0; |
@@ -519,7 +517,6 @@ static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah) | |||
519 | ATH_FREE_BANK(ah->analogBank6Data); | 517 | ATH_FREE_BANK(ah->analogBank6Data); |
520 | ATH_FREE_BANK(ah->analogBank6TPCData); | 518 | ATH_FREE_BANK(ah->analogBank6TPCData); |
521 | ATH_FREE_BANK(ah->analogBank7Data); | 519 | ATH_FREE_BANK(ah->analogBank7Data); |
522 | ATH_FREE_BANK(ah->addac5416_21); | ||
523 | ATH_FREE_BANK(ah->bank6Temp); | 520 | ATH_FREE_BANK(ah->bank6Temp); |
524 | 521 | ||
525 | #undef ATH_FREE_BANK | 522 | #undef ATH_FREE_BANK |
@@ -805,27 +802,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah, | |||
805 | if (ah->eep_ops->set_addac) | 802 | if (ah->eep_ops->set_addac) |
806 | ah->eep_ops->set_addac(ah, chan); | 803 | ah->eep_ops->set_addac(ah, chan); |
807 | 804 | ||
808 | if (AR_SREV_5416_22_OR_LATER(ah)) { | 805 | REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); |
809 | REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); | ||
810 | } else { | ||
811 | struct ar5416IniArray temp; | ||
812 | u32 addacSize = | ||
813 | sizeof(u32) * ah->iniAddac.ia_rows * | ||
814 | ah->iniAddac.ia_columns; | ||
815 | |||
816 | /* For AR5416 2.0/2.1 */ | ||
817 | memcpy(ah->addac5416_21, | ||
818 | ah->iniAddac.ia_array, addacSize); | ||
819 | |||
820 | /* override CLKDRV value at [row, column] = [31, 1] */ | ||
821 | (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; | ||
822 | |||
823 | temp.ia_array = ah->addac5416_21; | ||
824 | temp.ia_columns = ah->iniAddac.ia_columns; | ||
825 | temp.ia_rows = ah->iniAddac.ia_rows; | ||
826 | REG_WRITE_ARRAY(&temp, 1, regWrites); | ||
827 | } | ||
828 | |||
829 | REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); | 806 | REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); |
830 | 807 | ||
831 | ENABLE_REGWRITE_BUFFER(ah); | 808 | ENABLE_REGWRITE_BUFFER(ah); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 11f192a1ceb7..d190411ac8f5 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -180,6 +180,25 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
180 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, | 180 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, |
181 | ARRAY_SIZE(ar5416Addac), 2); | 181 | ARRAY_SIZE(ar5416Addac), 2); |
182 | } | 182 | } |
183 | |||
184 | /* iniAddac needs to be modified for these chips */ | ||
185 | if (AR_SREV_9160(ah) || !AR_SREV_5416_22_OR_LATER(ah)) { | ||
186 | struct ar5416IniArray *addac = &ah->iniAddac; | ||
187 | u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns; | ||
188 | u32 *data; | ||
189 | |||
190 | data = kmalloc(size, GFP_KERNEL); | ||
191 | if (!data) | ||
192 | return; | ||
193 | |||
194 | memcpy(data, addac->ia_array, size); | ||
195 | addac->ia_array = data; | ||
196 | |||
197 | if (!AR_SREV_5416_22_OR_LATER(ah)) { | ||
198 | /* override CLKDRV value */ | ||
199 | INI_RA(addac, 31,1) = 0; | ||
200 | } | ||
201 | } | ||
183 | } | 202 | } |
184 | 203 | ||
185 | /* Support for Japan ch.14 (2484) spread */ | 204 | /* Support for Japan ch.14 (2484) spread */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 6a29004a71b0..c8261d4fc780 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -940,7 +940,6 @@ struct ath_hw { | |||
940 | u32 *analogBank6Data; | 940 | u32 *analogBank6Data; |
941 | u32 *analogBank6TPCData; | 941 | u32 *analogBank6TPCData; |
942 | u32 *analogBank7Data; | 942 | u32 *analogBank7Data; |
943 | u32 *addac5416_21; | ||
944 | u32 *bank6Temp; | 943 | u32 *bank6Temp; |
945 | 944 | ||
946 | u8 txpower_limit; | 945 | u8 txpower_limit; |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 635b592ad961..a427a16bb739 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -1346,7 +1346,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1346 | fc = hdr->frame_control; | 1346 | fc = hdr->frame_control; |
1347 | for (i = 0; i < sc->hw->max_rates; i++) { | 1347 | for (i = 0; i < sc->hw->max_rates; i++) { |
1348 | struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; | 1348 | struct ieee80211_tx_rate *rate = &tx_info->status.rates[i]; |
1349 | if (!rate->count) | 1349 | if (rate->idx < 0 || !rate->count) |
1350 | break; | 1350 | break; |
1351 | 1351 | ||
1352 | final_ts_idx = i; | 1352 | final_ts_idx = i; |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index d19a9ee9d057..bbc813dee983 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -1234,6 +1234,7 @@ static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb) | |||
1234 | { | 1234 | { |
1235 | struct ieee80211_sta *sta; | 1235 | struct ieee80211_sta *sta; |
1236 | struct carl9170_sta_info *sta_info; | 1236 | struct carl9170_sta_info *sta_info; |
1237 | struct ieee80211_tx_info *tx_info; | ||
1237 | 1238 | ||
1238 | rcu_read_lock(); | 1239 | rcu_read_lock(); |
1239 | sta = __carl9170_get_tx_sta(ar, skb); | 1240 | sta = __carl9170_get_tx_sta(ar, skb); |
@@ -1241,16 +1242,18 @@ static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb) | |||
1241 | goto out_rcu; | 1242 | goto out_rcu; |
1242 | 1243 | ||
1243 | sta_info = (void *) sta->drv_priv; | 1244 | sta_info = (void *) sta->drv_priv; |
1244 | if (unlikely(sta_info->sleeping)) { | 1245 | tx_info = IEEE80211_SKB_CB(skb); |
1245 | struct ieee80211_tx_info *tx_info; | ||
1246 | 1246 | ||
1247 | if (unlikely(sta_info->sleeping) && | ||
1248 | !(tx_info->flags & (IEEE80211_TX_CTL_POLL_RESPONSE | | ||
1249 | IEEE80211_TX_CTL_CLEAR_PS_FILT))) { | ||
1247 | rcu_read_unlock(); | 1250 | rcu_read_unlock(); |
1248 | 1251 | ||
1249 | tx_info = IEEE80211_SKB_CB(skb); | ||
1250 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) | 1252 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) |
1251 | atomic_dec(&ar->tx_ampdu_upload); | 1253 | atomic_dec(&ar->tx_ampdu_upload); |
1252 | 1254 | ||
1253 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 1255 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
1256 | carl9170_release_dev_space(ar, skb); | ||
1254 | carl9170_tx_status(ar, skb, false); | 1257 | carl9170_tx_status(ar, skb, false); |
1255 | return true; | 1258 | return true; |
1256 | } | 1259 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 90911eec0cf5..30b58870b1b6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
@@ -1051,17 +1051,13 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1051 | } | 1051 | } |
1052 | /* either retransmit or send bar if ack not recd */ | 1052 | /* either retransmit or send bar if ack not recd */ |
1053 | if (!ack_recd) { | 1053 | if (!ack_recd) { |
1054 | struct ieee80211_tx_rate *txrate = | 1054 | if (retry && (ini->txretry[index] < (int)retry_limit)) { |
1055 | tx_info->status.rates; | ||
1056 | if (retry && (txrate[0].count < (int)retry_limit)) { | ||
1057 | ini->txretry[index]++; | 1055 | ini->txretry[index]++; |
1058 | ini->tx_in_transit--; | 1056 | ini->tx_in_transit--; |
1059 | /* | 1057 | /* |
1060 | * Use high prededence for retransmit to | 1058 | * Use high prededence for retransmit to |
1061 | * give some punch | 1059 | * give some punch |
1062 | */ | 1060 | */ |
1063 | /* brcms_c_txq_enq(wlc, scb, p, | ||
1064 | * BRCMS_PRIO_TO_PREC(tid)); */ | ||
1065 | brcms_c_txq_enq(wlc, scb, p, | 1061 | brcms_c_txq_enq(wlc, scb, p, |
1066 | BRCMS_PRIO_TO_HI_PREC(tid)); | 1062 | BRCMS_PRIO_TO_HI_PREC(tid)); |
1067 | } else { | 1063 | } else { |
@@ -1074,9 +1070,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1074 | IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1070 | IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1075 | skb_pull(p, D11_PHY_HDR_LEN); | 1071 | skb_pull(p, D11_PHY_HDR_LEN); |
1076 | skb_pull(p, D11_TXH_LEN); | 1072 | skb_pull(p, D11_TXH_LEN); |
1077 | wiphy_err(wiphy, "%s: BA Timeout, seq %d, in_" | 1073 | BCMMSG(wiphy, |
1078 | "transit %d\n", "AMPDU status", seq, | 1074 | "BA Timeout, seq %d, in_transit %d\n", |
1079 | ini->tx_in_transit); | 1075 | seq, ini->tx_in_transit); |
1080 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, | 1076 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, |
1081 | p); | 1077 | p); |
1082 | } | 1078 | } |
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c index 54b2d391e91a..a7dfba8d164e 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c | |||
@@ -2475,7 +2475,7 @@ il3945_bg_alive_start(struct work_struct *data) | |||
2475 | container_of(data, struct il_priv, alive_start.work); | 2475 | container_of(data, struct il_priv, alive_start.work); |
2476 | 2476 | ||
2477 | mutex_lock(&il->mutex); | 2477 | mutex_lock(&il->mutex); |
2478 | if (test_bit(S_EXIT_PENDING, &il->status)) | 2478 | if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL) |
2479 | goto out; | 2479 | goto out; |
2480 | 2480 | ||
2481 | il3945_alive_start(il); | 2481 | il3945_alive_start(il); |
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c index 1489b1573a6a..c80eb9b31551 100644 --- a/drivers/net/wireless/iwlegacy/3945.c +++ b/drivers/net/wireless/iwlegacy/3945.c | |||
@@ -1870,11 +1870,12 @@ il3945_bg_reg_txpower_periodic(struct work_struct *work) | |||
1870 | struct il_priv *il = container_of(work, struct il_priv, | 1870 | struct il_priv *il = container_of(work, struct il_priv, |
1871 | _3945.thermal_periodic.work); | 1871 | _3945.thermal_periodic.work); |
1872 | 1872 | ||
1873 | if (test_bit(S_EXIT_PENDING, &il->status)) | ||
1874 | return; | ||
1875 | |||
1876 | mutex_lock(&il->mutex); | 1873 | mutex_lock(&il->mutex); |
1874 | if (test_bit(S_EXIT_PENDING, &il->status) || il->txq == NULL) | ||
1875 | goto out; | ||
1876 | |||
1877 | il3945_reg_txpower_periodic(il); | 1877 | il3945_reg_txpower_periodic(il); |
1878 | out: | ||
1878 | mutex_unlock(&il->mutex); | 1879 | mutex_unlock(&il->mutex); |
1879 | } | 1880 | } |
1880 | 1881 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 64cf439035c3..ca78e91de86c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -1240,7 +1240,7 @@ int iwlagn_suspend(struct iwl_priv *priv, | |||
1240 | .flags = CMD_SYNC, | 1240 | .flags = CMD_SYNC, |
1241 | .data[0] = key_data.rsc_tsc, | 1241 | .data[0] = key_data.rsc_tsc, |
1242 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, | 1242 | .dataflags[0] = IWL_HCMD_DFL_NOCOPY, |
1243 | .len[0] = sizeof(key_data.rsc_tsc), | 1243 | .len[0] = sizeof(*key_data.rsc_tsc), |
1244 | }; | 1244 | }; |
1245 | 1245 | ||
1246 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); | 1246 | ret = iwl_trans_send_cmd(trans(priv), &rsc_tsc_cmd); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 7353826095f1..e483cfa8d14e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c | |||
@@ -1187,6 +1187,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
1187 | unsigned long flags; | 1187 | unsigned long flags; |
1188 | struct iwl_addsta_cmd sta_cmd; | 1188 | struct iwl_addsta_cmd sta_cmd; |
1189 | u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); | 1189 | u8 sta_id = iwlagn_key_sta_id(priv, ctx->vif, sta); |
1190 | __le16 key_flags; | ||
1190 | 1191 | ||
1191 | /* if station isn't there, neither is the key */ | 1192 | /* if station isn't there, neither is the key */ |
1192 | if (sta_id == IWL_INVALID_STATION) | 1193 | if (sta_id == IWL_INVALID_STATION) |
@@ -1212,7 +1213,14 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv, | |||
1212 | IWL_ERR(priv, "offset %d not used in uCode key table.\n", | 1213 | IWL_ERR(priv, "offset %d not used in uCode key table.\n", |
1213 | keyconf->hw_key_idx); | 1214 | keyconf->hw_key_idx); |
1214 | 1215 | ||
1215 | sta_cmd.key.key_flags = STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID; | 1216 | key_flags = cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); |
1217 | key_flags |= STA_KEY_FLG_MAP_KEY_MSK | STA_KEY_FLG_NO_ENC | | ||
1218 | STA_KEY_FLG_INVALID; | ||
1219 | |||
1220 | if (!(keyconf->flags & IEEE80211_KEY_FLAG_PAIRWISE)) | ||
1221 | key_flags |= STA_KEY_MULTICAST_MSK; | ||
1222 | |||
1223 | sta_cmd.key.key_flags = key_flags; | ||
1216 | sta_cmd.key.key_offset = WEP_INVALID_OFFSET; | 1224 | sta_cmd.key.key_offset = WEP_INVALID_OFFSET; |
1217 | sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK; | 1225 | sta_cmd.sta.modify_mask = STA_MODIFY_KEY_MASK; |
1218 | sta_cmd.mode = STA_CONTROL_MODIFY_MSK; | 1226 | sta_cmd.mode = STA_CONTROL_MODIFY_MSK; |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index c3b6c4652cd6..2210a0f9af2d 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -841,7 +841,13 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
841 | ret = mwifiex_set_rf_channel(priv, channel, | 841 | ret = mwifiex_set_rf_channel(priv, channel, |
842 | priv->adapter->channel_type); | 842 | priv->adapter->channel_type); |
843 | 843 | ||
844 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */ | 844 | /* As this is new association, clear locally stored |
845 | * keys and security related flags */ | ||
846 | priv->sec_info.wpa_enabled = false; | ||
847 | priv->sec_info.wpa2_enabled = false; | ||
848 | priv->wep_key_curr_index = 0; | ||
849 | priv->sec_info.encryption_mode = 0; | ||
850 | ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); | ||
845 | 851 | ||
846 | if (mode == NL80211_IFTYPE_ADHOC) { | 852 | if (mode == NL80211_IFTYPE_ADHOC) { |
847 | /* "privacy" is set only for ad-hoc mode */ | 853 | /* "privacy" is set only for ad-hoc mode */ |
@@ -886,6 +892,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
886 | dev_dbg(priv->adapter->dev, | 892 | dev_dbg(priv->adapter->dev, |
887 | "info: setting wep encryption" | 893 | "info: setting wep encryption" |
888 | " with key len %d\n", sme->key_len); | 894 | " with key len %d\n", sme->key_len); |
895 | priv->wep_key_curr_index = sme->key_idx; | ||
889 | ret = mwifiex_set_encode(priv, sme->key, sme->key_len, | 896 | ret = mwifiex_set_encode(priv, sme->key, sme->key_len, |
890 | sme->key_idx, 0); | 897 | sme->key_idx, 0); |
891 | } | 898 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index c3e1aa7c1a80..fd356b7c0476 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -426,10 +426,14 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
426 | /* | 426 | /* |
427 | * If the data queue was below the threshold before the txdone | 427 | * If the data queue was below the threshold before the txdone |
428 | * handler we must make sure the packet queue in the mac80211 stack | 428 | * handler we must make sure the packet queue in the mac80211 stack |
429 | * is reenabled when the txdone handler has finished. | 429 | * is reenabled when the txdone handler has finished. This has to be |
430 | * serialized with rt2x00mac_tx(), otherwise we can wake up queue | ||
431 | * before it was stopped. | ||
430 | */ | 432 | */ |
433 | spin_lock_bh(&entry->queue->tx_lock); | ||
431 | if (!rt2x00queue_threshold(entry->queue)) | 434 | if (!rt2x00queue_threshold(entry->queue)) |
432 | rt2x00queue_unpause_queue(entry->queue); | 435 | rt2x00queue_unpause_queue(entry->queue); |
436 | spin_unlock_bh(&entry->queue->tx_lock); | ||
433 | } | 437 | } |
434 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 438 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
435 | 439 | ||
@@ -1220,7 +1224,8 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1220 | cancel_work_sync(&rt2x00dev->rxdone_work); | 1224 | cancel_work_sync(&rt2x00dev->rxdone_work); |
1221 | cancel_work_sync(&rt2x00dev->txdone_work); | 1225 | cancel_work_sync(&rt2x00dev->txdone_work); |
1222 | } | 1226 | } |
1223 | destroy_workqueue(rt2x00dev->workqueue); | 1227 | if (rt2x00dev->workqueue) |
1228 | destroy_workqueue(rt2x00dev->workqueue); | ||
1224 | 1229 | ||
1225 | /* | 1230 | /* |
1226 | * Free the tx status fifo. | 1231 | * Free the tx status fifo. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index ede3c58e6783..2df2eb6d3e06 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -152,13 +152,22 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
152 | if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) | 152 | if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) |
153 | goto exit_fail; | 153 | goto exit_fail; |
154 | 154 | ||
155 | /* | ||
156 | * Pausing queue has to be serialized with rt2x00lib_txdone(). Note | ||
157 | * we should not use spin_lock_bh variant as bottom halve was already | ||
158 | * disabled before ieee80211_xmit() call. | ||
159 | */ | ||
160 | spin_lock(&queue->tx_lock); | ||
155 | if (rt2x00queue_threshold(queue)) | 161 | if (rt2x00queue_threshold(queue)) |
156 | rt2x00queue_pause_queue(queue); | 162 | rt2x00queue_pause_queue(queue); |
163 | spin_unlock(&queue->tx_lock); | ||
157 | 164 | ||
158 | return; | 165 | return; |
159 | 166 | ||
160 | exit_fail: | 167 | exit_fail: |
168 | spin_lock(&queue->tx_lock); | ||
161 | rt2x00queue_pause_queue(queue); | 169 | rt2x00queue_pause_queue(queue); |
170 | spin_unlock(&queue->tx_lock); | ||
162 | exit_free_skb: | 171 | exit_free_skb: |
163 | ieee80211_free_txskb(hw, skb); | 172 | ieee80211_free_txskb(hw, skb); |
164 | } | 173 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 5adfb3eab9cd..9b1b2b7a7807 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -619,6 +619,9 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
619 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) | 619 | else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags)) |
620 | rt2x00queue_align_frame(skb); | 620 | rt2x00queue_align_frame(skb); |
621 | 621 | ||
622 | /* | ||
623 | * That function must be called with bh disabled. | ||
624 | */ | ||
622 | spin_lock(&queue->tx_lock); | 625 | spin_lock(&queue->tx_lock); |
623 | 626 | ||
624 | if (unlikely(rt2x00queue_full(queue))) { | 627 | if (unlikely(rt2x00queue_full(queue))) { |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index ea2bd1be2640..91a375fb6ae6 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <asm/machdep.h> | 23 | #include <asm/machdep.h> |
24 | #endif /* CONFIG_PPC */ | 24 | #endif /* CONFIG_PPC */ |
25 | 25 | ||
26 | #include <asm/setup.h> | ||
27 | #include <asm/page.h> | 26 | #include <asm/page.h> |
28 | 27 | ||
29 | char *of_fdt_get_string(struct boot_param_header *blob, u32 offset) | 28 | char *of_fdt_get_string(struct boot_param_header *blob, u32 offset) |
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 980c079e4443..483c0adcad87 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c | |||
@@ -182,7 +182,7 @@ struct phy_device *of_phy_connect_fixed_link(struct net_device *dev, | |||
182 | if (!phy_id || sz < sizeof(*phy_id)) | 182 | if (!phy_id || sz < sizeof(*phy_id)) |
183 | return NULL; | 183 | return NULL; |
184 | 184 | ||
185 | sprintf(bus_id, PHY_ID_FMT, "0", be32_to_cpu(phy_id[0])); | 185 | sprintf(bus_id, PHY_ID_FMT, "fixed-0", be32_to_cpu(phy_id[0])); |
186 | 186 | ||
187 | phy = phy_connect(dev, bus_id, hndlr, 0, iface); | 187 | phy = phy_connect(dev, bus_id, hndlr, 0, iface); |
188 | return IS_ERR(phy) ? NULL : phy; | 188 | return IS_ERR(phy) ? NULL : phy; |
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h index a9c46cc2db37..8c33491b21fe 100644 --- a/drivers/parisc/iommu-helpers.h +++ b/drivers/parisc/iommu-helpers.h | |||
@@ -1,3 +1,5 @@ | |||
1 | #include <linux/prefetch.h> | ||
2 | |||
1 | /** | 3 | /** |
2 | * iommu_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir. | 4 | * iommu_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir. |
3 | * @ioc: The I/O Controller. | 5 | * @ioc: The I/O Controller. |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 1cfbf228fbb1..24f049e73952 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -500,6 +500,9 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
500 | int pos; | 500 | int pos; |
501 | u32 reg32; | 501 | u32 reg32; |
502 | 502 | ||
503 | if (aspm_disabled) | ||
504 | return 0; | ||
505 | |||
503 | /* | 506 | /* |
504 | * Some functions in a slot might not all be PCIe functions, | 507 | * Some functions in a slot might not all be PCIe functions, |
505 | * very strange. Disable ASPM for the whole slot | 508 | * very strange. Disable ASPM for the whole slot |
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index a87e2728b2c3..64d433ec4fc6 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c | |||
@@ -328,21 +328,15 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) | |||
328 | goto err1; | 328 | goto err1; |
329 | } | 329 | } |
330 | 330 | ||
331 | if (ret) { | 331 | pxa2xx_configure_sockets(&dev->dev); |
332 | while (--i >= 0) | 332 | dev_set_drvdata(&dev->dev, sinfo); |
333 | soc_pcmcia_remove_one(&sinfo->skt[i]); | ||
334 | kfree(sinfo); | ||
335 | clk_put(clk); | ||
336 | } else { | ||
337 | pxa2xx_configure_sockets(&dev->dev); | ||
338 | dev_set_drvdata(&dev->dev, sinfo); | ||
339 | } | ||
340 | 333 | ||
341 | return 0; | 334 | return 0; |
342 | 335 | ||
343 | err1: | 336 | err1: |
344 | while (--i >= 0) | 337 | while (--i >= 0) |
345 | soc_pcmcia_remove_one(&sinfo->skt[i]); | 338 | soc_pcmcia_remove_one(&sinfo->skt[i]); |
339 | clk_put(clk); | ||
346 | kfree(sinfo); | 340 | kfree(sinfo); |
347 | err0: | 341 | err0: |
348 | return ret; | 342 | return ret; |
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index f995e6e2f78c..15dbd8cc445f 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -143,6 +143,30 @@ config FUJITSU_LAPTOP_DEBUG | |||
143 | 143 | ||
144 | If you are not sure, say N here. | 144 | If you are not sure, say N here. |
145 | 145 | ||
146 | config FUJITSU_TABLET | ||
147 | tristate "Fujitsu Tablet Extras" | ||
148 | depends on ACPI | ||
149 | depends on INPUT | ||
150 | ---help--- | ||
151 | This is a driver for tablets built by Fujitsu: | ||
152 | |||
153 | * Lifebook P1510/P1610/P1620/Txxxx | ||
154 | * Stylistic ST5xxx | ||
155 | * Possibly other Fujitsu tablet models | ||
156 | |||
157 | It adds support for the panel buttons, docking station detection, | ||
158 | tablet/notebook mode detection for convertible and | ||
159 | orientation detection for docked slates. | ||
160 | |||
161 | If you have a Fujitsu convertible or slate, say Y or M here. | ||
162 | |||
163 | config AMILO_RFKILL | ||
164 | tristate "Fujitsu-Siemens Amilo rfkill support" | ||
165 | depends on RFKILL | ||
166 | ---help--- | ||
167 | This is a driver for enabling wifi on some Fujitsu-Siemens Amilo | ||
168 | laptops. | ||
169 | |||
146 | config TC1100_WMI | 170 | config TC1100_WMI |
147 | tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" | 171 | tristate "HP Compaq TC1100 Tablet WMI Extras (EXPERIMENTAL)" |
148 | depends on !X86_64 | 172 | depends on !X86_64 |
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 293a320d9faa..d328f21e9fdd 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile | |||
@@ -17,12 +17,14 @@ obj-$(CONFIG_ACER_WMI) += acer-wmi.o | |||
17 | obj-$(CONFIG_ACERHDF) += acerhdf.o | 17 | obj-$(CONFIG_ACERHDF) += acerhdf.o |
18 | obj-$(CONFIG_HP_ACCEL) += hp_accel.o | 18 | obj-$(CONFIG_HP_ACCEL) += hp_accel.o |
19 | obj-$(CONFIG_HP_WMI) += hp-wmi.o | 19 | obj-$(CONFIG_HP_WMI) += hp-wmi.o |
20 | obj-$(CONFIG_AMILO_RFKILL) += amilo-rfkill.o | ||
20 | obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o | 21 | obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o |
21 | obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o | 22 | obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o |
22 | obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o | 23 | obj-$(CONFIG_IDEAPAD_LAPTOP) += ideapad-laptop.o |
23 | obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o | 24 | obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o |
24 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o | 25 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o |
25 | obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o | 26 | obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o |
27 | obj-$(CONFIG_FUJITSU_TABLET) += fujitsu-tablet.o | ||
26 | obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o | 28 | obj-$(CONFIG_PANASONIC_LAPTOP) += panasonic-laptop.o |
27 | obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o | 29 | obj-$(CONFIG_INTEL_MENLOW) += intel_menlow.o |
28 | obj-$(CONFIG_ACPI_WMI) += wmi.o | 30 | obj-$(CONFIG_ACPI_WMI) += wmi.o |
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index b848277171a4..1e5290b5396d 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -679,6 +679,32 @@ static acpi_status AMW0_find_mailled(void) | |||
679 | return AE_OK; | 679 | return AE_OK; |
680 | } | 680 | } |
681 | 681 | ||
682 | static int AMW0_set_cap_acpi_check_device_found; | ||
683 | |||
684 | static acpi_status AMW0_set_cap_acpi_check_device_cb(acpi_handle handle, | ||
685 | u32 level, void *context, void **retval) | ||
686 | { | ||
687 | AMW0_set_cap_acpi_check_device_found = 1; | ||
688 | return AE_OK; | ||
689 | } | ||
690 | |||
691 | static const struct acpi_device_id norfkill_ids[] = { | ||
692 | { "VPC2004", 0}, | ||
693 | { "IBM0068", 0}, | ||
694 | { "LEN0068", 0}, | ||
695 | { "", 0}, | ||
696 | }; | ||
697 | |||
698 | static int AMW0_set_cap_acpi_check_device(void) | ||
699 | { | ||
700 | const struct acpi_device_id *id; | ||
701 | |||
702 | for (id = norfkill_ids; id->id[0]; id++) | ||
703 | acpi_get_devices(id->id, AMW0_set_cap_acpi_check_device_cb, | ||
704 | NULL, NULL); | ||
705 | return AMW0_set_cap_acpi_check_device_found; | ||
706 | } | ||
707 | |||
682 | static acpi_status AMW0_set_capabilities(void) | 708 | static acpi_status AMW0_set_capabilities(void) |
683 | { | 709 | { |
684 | struct wmab_args args; | 710 | struct wmab_args args; |
@@ -692,7 +718,9 @@ static acpi_status AMW0_set_capabilities(void) | |||
692 | * work. | 718 | * work. |
693 | */ | 719 | */ |
694 | if (wmi_has_guid(AMW0_GUID2)) { | 720 | if (wmi_has_guid(AMW0_GUID2)) { |
695 | interface->capability |= ACER_CAP_WIRELESS; | 721 | if ((quirks != &quirk_unknown) || |
722 | !AMW0_set_cap_acpi_check_device()) | ||
723 | interface->capability |= ACER_CAP_WIRELESS; | ||
696 | return AE_OK; | 724 | return AE_OK; |
697 | } | 725 | } |
698 | 726 | ||
diff --git a/drivers/platform/x86/amilo-rfkill.c b/drivers/platform/x86/amilo-rfkill.c new file mode 100644 index 000000000000..19170bb7700b --- /dev/null +++ b/drivers/platform/x86/amilo-rfkill.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * Support for rfkill on some Fujitsu-Siemens Amilo laptops. | ||
3 | * Copyright 2011 Ben Hutchings. | ||
4 | * | ||
5 | * Based in part on the fsam7440 driver, which is: | ||
6 | * Copyright 2005 Alejandro Vidal Mata & Javier Vidal Mata. | ||
7 | * and on the fsaa1655g driver, which is: | ||
8 | * Copyright 2006 Martin Večeřa. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/dmi.h> | ||
18 | #include <linux/i8042.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/moduleparam.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/rfkill.h> | ||
23 | |||
24 | /* | ||
25 | * These values were obtained from disassembling and debugging the | ||
26 | * PM.exe program installed in the Fujitsu-Siemens AMILO A1655G | ||
27 | */ | ||
28 | #define A1655_WIFI_COMMAND 0x10C5 | ||
29 | #define A1655_WIFI_ON 0x25 | ||
30 | #define A1655_WIFI_OFF 0x45 | ||
31 | |||
32 | static int amilo_a1655_rfkill_set_block(void *data, bool blocked) | ||
33 | { | ||
34 | u8 param = blocked ? A1655_WIFI_OFF : A1655_WIFI_ON; | ||
35 | int rc; | ||
36 | |||
37 | i8042_lock_chip(); | ||
38 | rc = i8042_command(¶m, A1655_WIFI_COMMAND); | ||
39 | i8042_unlock_chip(); | ||
40 | return rc; | ||
41 | } | ||
42 | |||
43 | static const struct rfkill_ops amilo_a1655_rfkill_ops = { | ||
44 | .set_block = amilo_a1655_rfkill_set_block | ||
45 | }; | ||
46 | |||
47 | /* | ||
48 | * These values were obtained from disassembling the PM.exe program | ||
49 | * installed in the Fujitsu-Siemens AMILO M 7440 | ||
50 | */ | ||
51 | #define M7440_PORT1 0x118f | ||
52 | #define M7440_PORT2 0x118e | ||
53 | #define M7440_RADIO_ON1 0x12 | ||
54 | #define M7440_RADIO_ON2 0x80 | ||
55 | #define M7440_RADIO_OFF1 0x10 | ||
56 | #define M7440_RADIO_OFF2 0x00 | ||
57 | |||
58 | static int amilo_m7440_rfkill_set_block(void *data, bool blocked) | ||
59 | { | ||
60 | u8 val1 = blocked ? M7440_RADIO_OFF1 : M7440_RADIO_ON1; | ||
61 | u8 val2 = blocked ? M7440_RADIO_OFF2 : M7440_RADIO_ON2; | ||
62 | |||
63 | outb(val1, M7440_PORT1); | ||
64 | outb(val2, M7440_PORT2); | ||
65 | |||
66 | /* Check whether the state has changed correctly */ | ||
67 | if (inb(M7440_PORT1) != val1 || inb(M7440_PORT2) != val2) | ||
68 | return -EIO; | ||
69 | |||
70 | return 0; | ||
71 | } | ||
72 | |||
73 | static const struct rfkill_ops amilo_m7440_rfkill_ops = { | ||
74 | .set_block = amilo_m7440_rfkill_set_block | ||
75 | }; | ||
76 | |||
77 | static const struct dmi_system_id __devinitdata amilo_rfkill_id_table[] = { | ||
78 | { | ||
79 | .matches = { | ||
80 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
81 | DMI_MATCH(DMI_BOARD_NAME, "AMILO A1655"), | ||
82 | }, | ||
83 | .driver_data = (void *)&amilo_a1655_rfkill_ops | ||
84 | }, | ||
85 | { | ||
86 | .matches = { | ||
87 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | ||
88 | DMI_MATCH(DMI_BOARD_NAME, "AMILO M7440"), | ||
89 | }, | ||
90 | .driver_data = (void *)&amilo_m7440_rfkill_ops | ||
91 | }, | ||
92 | {} | ||
93 | }; | ||
94 | |||
95 | static struct platform_device *amilo_rfkill_pdev; | ||
96 | static struct rfkill *amilo_rfkill_dev; | ||
97 | |||
98 | static int __devinit amilo_rfkill_probe(struct platform_device *device) | ||
99 | { | ||
100 | const struct dmi_system_id *system_id = | ||
101 | dmi_first_match(amilo_rfkill_id_table); | ||
102 | int rc; | ||
103 | |||
104 | amilo_rfkill_dev = rfkill_alloc(KBUILD_MODNAME, &device->dev, | ||
105 | RFKILL_TYPE_WLAN, | ||
106 | system_id->driver_data, NULL); | ||
107 | if (!amilo_rfkill_dev) | ||
108 | return -ENOMEM; | ||
109 | |||
110 | rc = rfkill_register(amilo_rfkill_dev); | ||
111 | if (rc) | ||
112 | goto fail; | ||
113 | |||
114 | return 0; | ||
115 | |||
116 | fail: | ||
117 | rfkill_destroy(amilo_rfkill_dev); | ||
118 | return rc; | ||
119 | } | ||
120 | |||
121 | static int amilo_rfkill_remove(struct platform_device *device) | ||
122 | { | ||
123 | rfkill_unregister(amilo_rfkill_dev); | ||
124 | rfkill_destroy(amilo_rfkill_dev); | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static struct platform_driver amilo_rfkill_driver = { | ||
129 | .driver = { | ||
130 | .name = KBUILD_MODNAME, | ||
131 | .owner = THIS_MODULE, | ||
132 | }, | ||
133 | .probe = amilo_rfkill_probe, | ||
134 | .remove = amilo_rfkill_remove, | ||
135 | }; | ||
136 | |||
137 | static int __init amilo_rfkill_init(void) | ||
138 | { | ||
139 | int rc; | ||
140 | |||
141 | if (dmi_first_match(amilo_rfkill_id_table) == NULL) | ||
142 | return -ENODEV; | ||
143 | |||
144 | rc = platform_driver_register(&amilo_rfkill_driver); | ||
145 | if (rc) | ||
146 | return rc; | ||
147 | |||
148 | amilo_rfkill_pdev = platform_device_register_simple(KBUILD_MODNAME, -1, | ||
149 | NULL, 0); | ||
150 | if (IS_ERR(amilo_rfkill_pdev)) { | ||
151 | rc = PTR_ERR(amilo_rfkill_pdev); | ||
152 | goto fail; | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | |||
157 | fail: | ||
158 | platform_driver_unregister(&amilo_rfkill_driver); | ||
159 | return rc; | ||
160 | } | ||
161 | |||
162 | static void __exit amilo_rfkill_exit(void) | ||
163 | { | ||
164 | platform_device_unregister(amilo_rfkill_pdev); | ||
165 | platform_driver_unregister(&amilo_rfkill_driver); | ||
166 | } | ||
167 | |||
168 | MODULE_AUTHOR("Ben Hutchings <ben@decadent.org.uk>"); | ||
169 | MODULE_LICENSE("GPL"); | ||
170 | MODULE_DEVICE_TABLE(dmi, amilo_rfkill_id_table); | ||
171 | |||
172 | module_init(amilo_rfkill_init); | ||
173 | module_exit(amilo_rfkill_exit); | ||
diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c new file mode 100644 index 000000000000..580d80a73c3a --- /dev/null +++ b/drivers/platform/x86/fujitsu-tablet.c | |||
@@ -0,0 +1,478 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2006-2012 Robert Gerlach <khnz@gmx.de> | ||
3 | * Copyright (C) 2005-2006 Jan Rychter <jan@rychter.com> | ||
4 | * | ||
5 | * You can redistribute and/or modify this program under the terms of the | ||
6 | * GNU General Public License version 2 as published by the Free Software | ||
7 | * Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
12 | * Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/bitops.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/acpi.h> | ||
26 | #include <linux/device.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/input.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/dmi.h> | ||
31 | |||
32 | #define MODULENAME "fujitsu-tablet" | ||
33 | |||
34 | #define ACPI_FUJITSU_CLASS "fujitsu" | ||
35 | |||
36 | #define INVERT_TABLET_MODE_BIT 0x01 | ||
37 | #define FORCE_TABLET_MODE_IF_UNDOCK 0x02 | ||
38 | |||
39 | #define KEYMAP_LEN 16 | ||
40 | |||
41 | static const struct acpi_device_id fujitsu_ids[] = { | ||
42 | { .id = "FUJ02BD" }, | ||
43 | { .id = "FUJ02BF" }, | ||
44 | { .id = "" } | ||
45 | }; | ||
46 | |||
47 | struct fujitsu_config { | ||
48 | unsigned short keymap[KEYMAP_LEN]; | ||
49 | unsigned int quirks; | ||
50 | }; | ||
51 | |||
52 | static unsigned short keymap_Lifebook_Tseries[KEYMAP_LEN] __initconst = { | ||
53 | KEY_RESERVED, | ||
54 | KEY_RESERVED, | ||
55 | KEY_RESERVED, | ||
56 | KEY_RESERVED, | ||
57 | KEY_SCROLLDOWN, | ||
58 | KEY_SCROLLUP, | ||
59 | KEY_DIRECTION, | ||
60 | KEY_LEFTCTRL, | ||
61 | KEY_BRIGHTNESSUP, | ||
62 | KEY_BRIGHTNESSDOWN, | ||
63 | KEY_BRIGHTNESS_ZERO, | ||
64 | KEY_RESERVED, | ||
65 | KEY_RESERVED, | ||
66 | KEY_RESERVED, | ||
67 | KEY_RESERVED, | ||
68 | KEY_LEFTALT | ||
69 | }; | ||
70 | |||
71 | static unsigned short keymap_Lifebook_U810[KEYMAP_LEN] __initconst = { | ||
72 | KEY_RESERVED, | ||
73 | KEY_RESERVED, | ||
74 | KEY_RESERVED, | ||
75 | KEY_RESERVED, | ||
76 | KEY_PROG1, | ||
77 | KEY_PROG2, | ||
78 | KEY_DIRECTION, | ||
79 | KEY_RESERVED, | ||
80 | KEY_RESERVED, | ||
81 | KEY_RESERVED, | ||
82 | KEY_UP, | ||
83 | KEY_DOWN, | ||
84 | KEY_RESERVED, | ||
85 | KEY_RESERVED, | ||
86 | KEY_LEFTCTRL, | ||
87 | KEY_LEFTALT | ||
88 | }; | ||
89 | |||
90 | static unsigned short keymap_Stylistic_Tseries[KEYMAP_LEN] __initconst = { | ||
91 | KEY_RESERVED, | ||
92 | KEY_RESERVED, | ||
93 | KEY_RESERVED, | ||
94 | KEY_RESERVED, | ||
95 | KEY_PRINT, | ||
96 | KEY_BACKSPACE, | ||
97 | KEY_SPACE, | ||
98 | KEY_ENTER, | ||
99 | KEY_BRIGHTNESSUP, | ||
100 | KEY_BRIGHTNESSDOWN, | ||
101 | KEY_DOWN, | ||
102 | KEY_UP, | ||
103 | KEY_SCROLLUP, | ||
104 | KEY_SCROLLDOWN, | ||
105 | KEY_LEFTCTRL, | ||
106 | KEY_LEFTALT | ||
107 | }; | ||
108 | |||
109 | static unsigned short keymap_Stylistic_ST5xxx[KEYMAP_LEN] __initconst = { | ||
110 | KEY_RESERVED, | ||
111 | KEY_RESERVED, | ||
112 | KEY_RESERVED, | ||
113 | KEY_RESERVED, | ||
114 | KEY_MAIL, | ||
115 | KEY_DIRECTION, | ||
116 | KEY_ESC, | ||
117 | KEY_ENTER, | ||
118 | KEY_BRIGHTNESSUP, | ||
119 | KEY_BRIGHTNESSDOWN, | ||
120 | KEY_DOWN, | ||
121 | KEY_UP, | ||
122 | KEY_SCROLLUP, | ||
123 | KEY_SCROLLDOWN, | ||
124 | KEY_LEFTCTRL, | ||
125 | KEY_LEFTALT | ||
126 | }; | ||
127 | |||
128 | static struct { | ||
129 | struct input_dev *idev; | ||
130 | struct fujitsu_config config; | ||
131 | unsigned long prev_keymask; | ||
132 | |||
133 | char phys[21]; | ||
134 | |||
135 | int irq; | ||
136 | int io_base; | ||
137 | int io_length; | ||
138 | } fujitsu; | ||
139 | |||
140 | static u8 fujitsu_ack(void) | ||
141 | { | ||
142 | return inb(fujitsu.io_base + 2); | ||
143 | } | ||
144 | |||
145 | static u8 fujitsu_status(void) | ||
146 | { | ||
147 | return inb(fujitsu.io_base + 6); | ||
148 | } | ||
149 | |||
150 | static u8 fujitsu_read_register(const u8 addr) | ||
151 | { | ||
152 | outb(addr, fujitsu.io_base); | ||
153 | return inb(fujitsu.io_base + 4); | ||
154 | } | ||
155 | |||
156 | static void fujitsu_send_state(void) | ||
157 | { | ||
158 | int state; | ||
159 | int dock, tablet_mode; | ||
160 | |||
161 | state = fujitsu_read_register(0xdd); | ||
162 | |||
163 | dock = state & 0x02; | ||
164 | |||
165 | if ((fujitsu.config.quirks & FORCE_TABLET_MODE_IF_UNDOCK) && (!dock)) { | ||
166 | tablet_mode = 1; | ||
167 | } else{ | ||
168 | tablet_mode = state & 0x01; | ||
169 | if (fujitsu.config.quirks & INVERT_TABLET_MODE_BIT) | ||
170 | tablet_mode = !tablet_mode; | ||
171 | } | ||
172 | |||
173 | input_report_switch(fujitsu.idev, SW_DOCK, dock); | ||
174 | input_report_switch(fujitsu.idev, SW_TABLET_MODE, tablet_mode); | ||
175 | input_sync(fujitsu.idev); | ||
176 | } | ||
177 | |||
178 | static void fujitsu_reset(void) | ||
179 | { | ||
180 | int timeout = 50; | ||
181 | |||
182 | fujitsu_ack(); | ||
183 | |||
184 | while ((fujitsu_status() & 0x02) && (--timeout)) | ||
185 | msleep(20); | ||
186 | |||
187 | fujitsu_send_state(); | ||
188 | } | ||
189 | |||
190 | static int __devinit input_fujitsu_setup(struct device *parent, | ||
191 | const char *name, const char *phys) | ||
192 | { | ||
193 | struct input_dev *idev; | ||
194 | int error; | ||
195 | int i; | ||
196 | |||
197 | idev = input_allocate_device(); | ||
198 | if (!idev) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | idev->dev.parent = parent; | ||
202 | idev->phys = phys; | ||
203 | idev->name = name; | ||
204 | idev->id.bustype = BUS_HOST; | ||
205 | idev->id.vendor = 0x1734; /* Fujitsu Siemens Computer GmbH */ | ||
206 | idev->id.product = 0x0001; | ||
207 | idev->id.version = 0x0101; | ||
208 | |||
209 | idev->keycode = fujitsu.config.keymap; | ||
210 | idev->keycodesize = sizeof(fujitsu.config.keymap[0]); | ||
211 | idev->keycodemax = ARRAY_SIZE(fujitsu.config.keymap); | ||
212 | |||
213 | __set_bit(EV_REP, idev->evbit); | ||
214 | |||
215 | for (i = 0; i < ARRAY_SIZE(fujitsu.config.keymap); i++) | ||
216 | if (fujitsu.config.keymap[i]) | ||
217 | input_set_capability(idev, EV_KEY, fujitsu.config.keymap[i]); | ||
218 | |||
219 | input_set_capability(idev, EV_MSC, MSC_SCAN); | ||
220 | |||
221 | input_set_capability(idev, EV_SW, SW_DOCK); | ||
222 | input_set_capability(idev, EV_SW, SW_TABLET_MODE); | ||
223 | |||
224 | input_set_capability(idev, EV_SW, SW_DOCK); | ||
225 | input_set_capability(idev, EV_SW, SW_TABLET_MODE); | ||
226 | |||
227 | error = input_register_device(idev); | ||
228 | if (error) { | ||
229 | input_free_device(idev); | ||
230 | return error; | ||
231 | } | ||
232 | |||
233 | fujitsu.idev = idev; | ||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static void input_fujitsu_remove(void) | ||
238 | { | ||
239 | input_unregister_device(fujitsu.idev); | ||
240 | } | ||
241 | |||
242 | static irqreturn_t fujitsu_interrupt(int irq, void *dev_id) | ||
243 | { | ||
244 | unsigned long keymask, changed; | ||
245 | unsigned int keycode; | ||
246 | int pressed; | ||
247 | int i; | ||
248 | |||
249 | if (unlikely(!(fujitsu_status() & 0x01))) | ||
250 | return IRQ_NONE; | ||
251 | |||
252 | fujitsu_send_state(); | ||
253 | |||
254 | keymask = fujitsu_read_register(0xde); | ||
255 | keymask |= fujitsu_read_register(0xdf) << 8; | ||
256 | keymask ^= 0xffff; | ||
257 | |||
258 | changed = keymask ^ fujitsu.prev_keymask; | ||
259 | if (changed) { | ||
260 | fujitsu.prev_keymask = keymask; | ||
261 | |||
262 | for_each_set_bit(i, &changed, KEYMAP_LEN) { | ||
263 | keycode = fujitsu.config.keymap[i]; | ||
264 | pressed = keymask & changed & BIT(i); | ||
265 | |||
266 | if (pressed) | ||
267 | input_event(fujitsu.idev, EV_MSC, MSC_SCAN, i); | ||
268 | |||
269 | input_report_key(fujitsu.idev, keycode, pressed); | ||
270 | input_sync(fujitsu.idev); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | fujitsu_ack(); | ||
275 | return IRQ_HANDLED; | ||
276 | } | ||
277 | |||
278 | static int __devinit fujitsu_dmi_default(const struct dmi_system_id *dmi) | ||
279 | { | ||
280 | printk(KERN_INFO MODULENAME ": %s\n", dmi->ident); | ||
281 | memcpy(fujitsu.config.keymap, dmi->driver_data, | ||
282 | sizeof(fujitsu.config.keymap)); | ||
283 | return 1; | ||
284 | } | ||
285 | |||
286 | static int __devinit fujitsu_dmi_stylistic(const struct dmi_system_id *dmi) | ||
287 | { | ||
288 | fujitsu_dmi_default(dmi); | ||
289 | fujitsu.config.quirks |= FORCE_TABLET_MODE_IF_UNDOCK; | ||
290 | fujitsu.config.quirks |= INVERT_TABLET_MODE_BIT; | ||
291 | return 1; | ||
292 | } | ||
293 | |||
294 | static struct dmi_system_id dmi_ids[] __initconst = { | ||
295 | { | ||
296 | .callback = fujitsu_dmi_default, | ||
297 | .ident = "Fujitsu Siemens P/T Series", | ||
298 | .matches = { | ||
299 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
300 | DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK") | ||
301 | }, | ||
302 | .driver_data = keymap_Lifebook_Tseries | ||
303 | }, | ||
304 | { | ||
305 | .callback = fujitsu_dmi_default, | ||
306 | .ident = "Fujitsu Lifebook T Series", | ||
307 | .matches = { | ||
308 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
309 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook T") | ||
310 | }, | ||
311 | .driver_data = keymap_Lifebook_Tseries | ||
312 | }, | ||
313 | { | ||
314 | .callback = fujitsu_dmi_stylistic, | ||
315 | .ident = "Fujitsu Siemens Stylistic T Series", | ||
316 | .matches = { | ||
317 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
318 | DMI_MATCH(DMI_PRODUCT_NAME, "Stylistic T") | ||
319 | }, | ||
320 | .driver_data = keymap_Stylistic_Tseries | ||
321 | }, | ||
322 | { | ||
323 | .callback = fujitsu_dmi_default, | ||
324 | .ident = "Fujitsu LifeBook U810", | ||
325 | .matches = { | ||
326 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
327 | DMI_MATCH(DMI_PRODUCT_NAME, "LifeBook U810") | ||
328 | }, | ||
329 | .driver_data = keymap_Lifebook_U810 | ||
330 | }, | ||
331 | { | ||
332 | .callback = fujitsu_dmi_stylistic, | ||
333 | .ident = "Fujitsu Siemens Stylistic ST5xxx Series", | ||
334 | .matches = { | ||
335 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
336 | DMI_MATCH(DMI_PRODUCT_NAME, "STYLISTIC ST5") | ||
337 | }, | ||
338 | .driver_data = keymap_Stylistic_ST5xxx | ||
339 | }, | ||
340 | { | ||
341 | .callback = fujitsu_dmi_stylistic, | ||
342 | .ident = "Fujitsu Siemens Stylistic ST5xxx Series", | ||
343 | .matches = { | ||
344 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"), | ||
345 | DMI_MATCH(DMI_PRODUCT_NAME, "Stylistic ST5") | ||
346 | }, | ||
347 | .driver_data = keymap_Stylistic_ST5xxx | ||
348 | }, | ||
349 | { | ||
350 | .callback = fujitsu_dmi_default, | ||
351 | .ident = "Unknown (using defaults)", | ||
352 | .matches = { | ||
353 | DMI_MATCH(DMI_SYS_VENDOR, ""), | ||
354 | DMI_MATCH(DMI_PRODUCT_NAME, "") | ||
355 | }, | ||
356 | .driver_data = keymap_Lifebook_Tseries | ||
357 | }, | ||
358 | { NULL } | ||
359 | }; | ||
360 | |||
361 | static acpi_status __devinit | ||
362 | fujitsu_walk_resources(struct acpi_resource *res, void *data) | ||
363 | { | ||
364 | switch (res->type) { | ||
365 | case ACPI_RESOURCE_TYPE_IRQ: | ||
366 | fujitsu.irq = res->data.irq.interrupts[0]; | ||
367 | return AE_OK; | ||
368 | |||
369 | case ACPI_RESOURCE_TYPE_IO: | ||
370 | fujitsu.io_base = res->data.io.minimum; | ||
371 | fujitsu.io_length = res->data.io.address_length; | ||
372 | return AE_OK; | ||
373 | |||
374 | case ACPI_RESOURCE_TYPE_END_TAG: | ||
375 | if (fujitsu.irq && fujitsu.io_base) | ||
376 | return AE_OK; | ||
377 | else | ||
378 | return AE_NOT_FOUND; | ||
379 | |||
380 | default: | ||
381 | return AE_ERROR; | ||
382 | } | ||
383 | } | ||
384 | |||
385 | static int __devinit acpi_fujitsu_add(struct acpi_device *adev) | ||
386 | { | ||
387 | acpi_status status; | ||
388 | int error; | ||
389 | |||
390 | if (!adev) | ||
391 | return -EINVAL; | ||
392 | |||
393 | status = acpi_walk_resources(adev->handle, METHOD_NAME__CRS, | ||
394 | fujitsu_walk_resources, NULL); | ||
395 | if (ACPI_FAILURE(status) || !fujitsu.irq || !fujitsu.io_base) | ||
396 | return -ENODEV; | ||
397 | |||
398 | sprintf(acpi_device_name(adev), "Fujitsu %s", acpi_device_hid(adev)); | ||
399 | sprintf(acpi_device_class(adev), "%s", ACPI_FUJITSU_CLASS); | ||
400 | |||
401 | snprintf(fujitsu.phys, sizeof(fujitsu.phys), | ||
402 | "%s/input0", acpi_device_hid(adev)); | ||
403 | |||
404 | error = input_fujitsu_setup(&adev->dev, | ||
405 | acpi_device_name(adev), fujitsu.phys); | ||
406 | if (error) | ||
407 | return error; | ||
408 | |||
409 | if (!request_region(fujitsu.io_base, fujitsu.io_length, MODULENAME)) { | ||
410 | input_fujitsu_remove(); | ||
411 | return -EBUSY; | ||
412 | } | ||
413 | |||
414 | fujitsu_reset(); | ||
415 | |||
416 | error = request_irq(fujitsu.irq, fujitsu_interrupt, | ||
417 | IRQF_SHARED, MODULENAME, fujitsu_interrupt); | ||
418 | if (error) { | ||
419 | release_region(fujitsu.io_base, fujitsu.io_length); | ||
420 | input_fujitsu_remove(); | ||
421 | return error; | ||
422 | } | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type) | ||
428 | { | ||
429 | free_irq(fujitsu.irq, fujitsu_interrupt); | ||
430 | release_region(fujitsu.io_base, fujitsu.io_length); | ||
431 | input_fujitsu_remove(); | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | static int acpi_fujitsu_resume(struct acpi_device *adev) | ||
436 | { | ||
437 | fujitsu_reset(); | ||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static struct acpi_driver acpi_fujitsu_driver = { | ||
442 | .name = MODULENAME, | ||
443 | .class = "hotkey", | ||
444 | .ids = fujitsu_ids, | ||
445 | .ops = { | ||
446 | .add = acpi_fujitsu_add, | ||
447 | .remove = acpi_fujitsu_remove, | ||
448 | .resume = acpi_fujitsu_resume, | ||
449 | } | ||
450 | }; | ||
451 | |||
452 | static int __init fujitsu_module_init(void) | ||
453 | { | ||
454 | int error; | ||
455 | |||
456 | dmi_check_system(dmi_ids); | ||
457 | |||
458 | error = acpi_bus_register_driver(&acpi_fujitsu_driver); | ||
459 | if (error) | ||
460 | return error; | ||
461 | |||
462 | return 0; | ||
463 | } | ||
464 | |||
465 | static void __exit fujitsu_module_exit(void) | ||
466 | { | ||
467 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | ||
468 | } | ||
469 | |||
470 | module_init(fujitsu_module_init); | ||
471 | module_exit(fujitsu_module_exit); | ||
472 | |||
473 | MODULE_AUTHOR("Robert Gerlach <khnz@gmx.de>"); | ||
474 | MODULE_DESCRIPTION("Fujitsu tablet pc extras driver"); | ||
475 | MODULE_LICENSE("GPL"); | ||
476 | MODULE_VERSION("2.4"); | ||
477 | |||
478 | MODULE_DEVICE_TABLE(acpi, fujitsu_ids); | ||
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 05be30ee158b..ffff8b4b4949 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
@@ -562,8 +562,8 @@ static int acpi_pcc_hotkey_add(struct acpi_device *device) | |||
562 | 562 | ||
563 | num_sifr = acpi_pcc_get_sqty(device); | 563 | num_sifr = acpi_pcc_get_sqty(device); |
564 | 564 | ||
565 | if (num_sifr > 255) { | 565 | if (num_sifr < 0 || num_sifr > 255) { |
566 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr too large")); | 566 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "num_sifr out of range")); |
567 | return -ENODEV; | 567 | return -ENODEV; |
568 | } | 568 | } |
569 | 569 | ||
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 2baadd21b7a6..98fbe62694d4 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c | |||
@@ -369,9 +369,9 @@ static int __init pps_init(void) | |||
369 | int err; | 369 | int err; |
370 | 370 | ||
371 | pps_class = class_create(THIS_MODULE, "pps"); | 371 | pps_class = class_create(THIS_MODULE, "pps"); |
372 | if (!pps_class) { | 372 | if (IS_ERR(pps_class)) { |
373 | pr_err("failed to allocate class\n"); | 373 | pr_err("failed to allocate class\n"); |
374 | return -ENOMEM; | 374 | return PTR_ERR(pps_class); |
375 | } | 375 | } |
376 | pps_class->dev_attrs = pps_attrs; | 376 | pps_class->dev_attrs = pps_attrs; |
377 | 377 | ||
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 691b1ab1a3d0..30d2072f480b 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -410,13 +410,14 @@ static void tsi721_db_dpc(struct work_struct *work) | |||
410 | */ | 410 | */ |
411 | mport = priv->mport; | 411 | mport = priv->mport; |
412 | 412 | ||
413 | wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)); | 413 | wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE; |
414 | rd_ptr = ioread32(priv->regs + TSI721_IDQ_RP(IDB_QUEUE)); | 414 | rd_ptr = ioread32(priv->regs + TSI721_IDQ_RP(IDB_QUEUE)) % IDB_QSIZE; |
415 | 415 | ||
416 | while (wr_ptr != rd_ptr) { | 416 | while (wr_ptr != rd_ptr) { |
417 | idb_entry = (u64 *)(priv->idb_base + | 417 | idb_entry = (u64 *)(priv->idb_base + |
418 | (TSI721_IDB_ENTRY_SIZE * rd_ptr)); | 418 | (TSI721_IDB_ENTRY_SIZE * rd_ptr)); |
419 | rd_ptr++; | 419 | rd_ptr++; |
420 | rd_ptr %= IDB_QSIZE; | ||
420 | idb.msg = *idb_entry; | 421 | idb.msg = *idb_entry; |
421 | *idb_entry = 0; | 422 | *idb_entry = 0; |
422 | 423 | ||
diff --git a/drivers/rapidio/devices/tsi721.h b/drivers/rapidio/devices/tsi721.h index 822e54c394d5..1c226b31af13 100644 --- a/drivers/rapidio/devices/tsi721.h +++ b/drivers/rapidio/devices/tsi721.h | |||
@@ -118,34 +118,34 @@ | |||
118 | 118 | ||
119 | #define TSI721_IDB_ENTRY_SIZE 64 | 119 | #define TSI721_IDB_ENTRY_SIZE 64 |
120 | 120 | ||
121 | #define TSI721_IDQ_CTL(x) (0x20000 + (x) * 1000) | 121 | #define TSI721_IDQ_CTL(x) (0x20000 + (x) * 0x1000) |
122 | #define TSI721_IDQ_SUSPEND 0x00000002 | 122 | #define TSI721_IDQ_SUSPEND 0x00000002 |
123 | #define TSI721_IDQ_INIT 0x00000001 | 123 | #define TSI721_IDQ_INIT 0x00000001 |
124 | 124 | ||
125 | #define TSI721_IDQ_STS(x) (0x20004 + (x) * 1000) | 125 | #define TSI721_IDQ_STS(x) (0x20004 + (x) * 0x1000) |
126 | #define TSI721_IDQ_RUN 0x00200000 | 126 | #define TSI721_IDQ_RUN 0x00200000 |
127 | 127 | ||
128 | #define TSI721_IDQ_MASK(x) (0x20008 + (x) * 1000) | 128 | #define TSI721_IDQ_MASK(x) (0x20008 + (x) * 0x1000) |
129 | #define TSI721_IDQ_MASK_MASK 0xffff0000 | 129 | #define TSI721_IDQ_MASK_MASK 0xffff0000 |
130 | #define TSI721_IDQ_MASK_PATT 0x0000ffff | 130 | #define TSI721_IDQ_MASK_PATT 0x0000ffff |
131 | 131 | ||
132 | #define TSI721_IDQ_RP(x) (0x2000c + (x) * 1000) | 132 | #define TSI721_IDQ_RP(x) (0x2000c + (x) * 0x1000) |
133 | #define TSI721_IDQ_RP_PTR 0x0007ffff | 133 | #define TSI721_IDQ_RP_PTR 0x0007ffff |
134 | 134 | ||
135 | #define TSI721_IDQ_WP(x) (0x20010 + (x) * 1000) | 135 | #define TSI721_IDQ_WP(x) (0x20010 + (x) * 0x1000) |
136 | #define TSI721_IDQ_WP_PTR 0x0007ffff | 136 | #define TSI721_IDQ_WP_PTR 0x0007ffff |
137 | 137 | ||
138 | #define TSI721_IDQ_BASEL(x) (0x20014 + (x) * 1000) | 138 | #define TSI721_IDQ_BASEL(x) (0x20014 + (x) * 0x1000) |
139 | #define TSI721_IDQ_BASEL_ADDR 0xffffffc0 | 139 | #define TSI721_IDQ_BASEL_ADDR 0xffffffc0 |
140 | #define TSI721_IDQ_BASEU(x) (0x20018 + (x) * 1000) | 140 | #define TSI721_IDQ_BASEU(x) (0x20018 + (x) * 0x1000) |
141 | #define TSI721_IDQ_SIZE(x) (0x2001c + (x) * 1000) | 141 | #define TSI721_IDQ_SIZE(x) (0x2001c + (x) * 0x1000) |
142 | #define TSI721_IDQ_SIZE_VAL(size) (__fls(size) - 4) | 142 | #define TSI721_IDQ_SIZE_VAL(size) (__fls(size) - 4) |
143 | #define TSI721_IDQ_SIZE_MIN 512 | 143 | #define TSI721_IDQ_SIZE_MIN 512 |
144 | #define TSI721_IDQ_SIZE_MAX (512 * 1024) | 144 | #define TSI721_IDQ_SIZE_MAX (512 * 1024) |
145 | 145 | ||
146 | #define TSI721_SR_CHINT(x) (0x20040 + (x) * 1000) | 146 | #define TSI721_SR_CHINT(x) (0x20040 + (x) * 0x1000) |
147 | #define TSI721_SR_CHINTE(x) (0x20044 + (x) * 1000) | 147 | #define TSI721_SR_CHINTE(x) (0x20044 + (x) * 0x1000) |
148 | #define TSI721_SR_CHINTSET(x) (0x20048 + (x) * 1000) | 148 | #define TSI721_SR_CHINTSET(x) (0x20048 + (x) * 0x1000) |
149 | #define TSI721_SR_CHINT_ODBOK 0x00000020 | 149 | #define TSI721_SR_CHINT_ODBOK 0x00000020 |
150 | #define TSI721_SR_CHINT_IDBQRCV 0x00000010 | 150 | #define TSI721_SR_CHINT_IDBQRCV 0x00000010 |
151 | #define TSI721_SR_CHINT_SUSP 0x00000008 | 151 | #define TSI721_SR_CHINT_SUSP 0x00000008 |
@@ -156,7 +156,7 @@ | |||
156 | 156 | ||
157 | #define TSI721_IBWIN_NUM 8 | 157 | #define TSI721_IBWIN_NUM 8 |
158 | 158 | ||
159 | #define TSI721_IBWINLB(x) (0x29000 + (x) * 20) | 159 | #define TSI721_IBWINLB(x) (0x29000 + (x) * 0x20) |
160 | #define TSI721_IBWINLB_BA 0xfffff000 | 160 | #define TSI721_IBWINLB_BA 0xfffff000 |
161 | #define TSI721_IBWINLB_WEN 0x00000001 | 161 | #define TSI721_IBWINLB_WEN 0x00000001 |
162 | 162 | ||
@@ -187,13 +187,13 @@ | |||
187 | */ | 187 | */ |
188 | #define TSI721_OBWIN_NUM TSI721_PC2SR_WINS | 188 | #define TSI721_OBWIN_NUM TSI721_PC2SR_WINS |
189 | 189 | ||
190 | #define TSI721_OBWINLB(x) (0x40000 + (x) * 20) | 190 | #define TSI721_OBWINLB(x) (0x40000 + (x) * 0x20) |
191 | #define TSI721_OBWINLB_BA 0xffff8000 | 191 | #define TSI721_OBWINLB_BA 0xffff8000 |
192 | #define TSI721_OBWINLB_WEN 0x00000001 | 192 | #define TSI721_OBWINLB_WEN 0x00000001 |
193 | 193 | ||
194 | #define TSI721_OBWINUB(x) (0x40004 + (x) * 20) | 194 | #define TSI721_OBWINUB(x) (0x40004 + (x) * 0x20) |
195 | 195 | ||
196 | #define TSI721_OBWINSZ(x) (0x40008 + (x) * 20) | 196 | #define TSI721_OBWINSZ(x) (0x40008 + (x) * 0x20) |
197 | #define TSI721_OBWINSZ_SIZE 0x00001f00 | 197 | #define TSI721_OBWINSZ_SIZE 0x00001f00 |
198 | #define TSI721_OBWIN_SIZE(size) (__fls(size) - 15) | 198 | #define TSI721_OBWIN_SIZE(size) (__fls(size) - 15) |
199 | 199 | ||
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c index df33530cec4a..28b81ae4cf7f 100644 --- a/drivers/regulator/88pm8607.c +++ b/drivers/regulator/88pm8607.c | |||
@@ -196,7 +196,7 @@ static const unsigned int LDO12_suspend_table[] = { | |||
196 | }; | 196 | }; |
197 | 197 | ||
198 | static const unsigned int LDO13_table[] = { | 198 | static const unsigned int LDO13_table[] = { |
199 | 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0, 0, | 199 | 1200000, 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0, |
200 | }; | 200 | }; |
201 | 201 | ||
202 | static const unsigned int LDO13_suspend_table[] = { | 202 | static const unsigned int LDO13_suspend_table[] = { |
@@ -389,10 +389,10 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = { | |||
389 | PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1), | 389 | PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1), |
390 | PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2), | 390 | PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2), |
391 | PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3), | 391 | PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3), |
392 | PM8607_LDO(10, LDO10, 0, 3, SUPPLIES_EN12, 4), | 392 | PM8607_LDO(10, LDO10, 0, 4, SUPPLIES_EN12, 4), |
393 | PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5), | 393 | PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5), |
394 | PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0), | 394 | PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0), |
395 | PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6), | 395 | PM8607_LDO(14, LDO14, 0, 3, SUPPLIES_EN12, 6), |
396 | }; | 396 | }; |
397 | 397 | ||
398 | static int __devinit pm8607_regulator_probe(struct platform_device *pdev) | 398 | static int __devinit pm8607_regulator_probe(struct platform_device *pdev) |
diff --git a/drivers/regulator/da9052-regulator.c b/drivers/regulator/da9052-regulator.c index 3767364452fd..09915e89705d 100644 --- a/drivers/regulator/da9052-regulator.c +++ b/drivers/regulator/da9052-regulator.c | |||
@@ -226,7 +226,7 @@ static int da9052_regulator_set_voltage_int(struct regulator_dev *rdev, | |||
226 | if (min_uV < info->min_uV) | 226 | if (min_uV < info->min_uV) |
227 | min_uV = info->min_uV; | 227 | min_uV = info->min_uV; |
228 | 228 | ||
229 | *selector = (min_uV - info->min_uV) / info->step_uV; | 229 | *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); |
230 | 230 | ||
231 | ret = da9052_list_voltage(rdev, *selector); | 231 | ret = da9052_list_voltage(rdev, *selector); |
232 | if (ret < 0) | 232 | if (ret < 0) |
@@ -260,8 +260,8 @@ static int da9052_set_ldo5_6_voltage(struct regulator_dev *rdev, | |||
260 | * the LDO activate bit to implment the changes on the | 260 | * the LDO activate bit to implment the changes on the |
261 | * LDO output. | 261 | * LDO output. |
262 | */ | 262 | */ |
263 | return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, 0, | 263 | return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, |
264 | info->activate_bit); | 264 | info->activate_bit, info->activate_bit); |
265 | } | 265 | } |
266 | 266 | ||
267 | static int da9052_set_dcdc_voltage(struct regulator_dev *rdev, | 267 | static int da9052_set_dcdc_voltage(struct regulator_dev *rdev, |
@@ -280,8 +280,8 @@ static int da9052_set_dcdc_voltage(struct regulator_dev *rdev, | |||
280 | * the DCDC activate bit to implment the changes on the | 280 | * the DCDC activate bit to implment the changes on the |
281 | * DCDC output. | 281 | * DCDC output. |
282 | */ | 282 | */ |
283 | return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, 0, | 283 | return da9052_reg_update(regulator->da9052, DA9052_SUPPLY_REG, |
284 | info->activate_bit); | 284 | info->activate_bit, info->activate_bit); |
285 | } | 285 | } |
286 | 286 | ||
287 | static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev) | 287 | static int da9052_get_regulator_voltage_sel(struct regulator_dev *rdev) |
@@ -318,10 +318,10 @@ static int da9052_set_buckperi_voltage(struct regulator_dev *rdev, int min_uV, | |||
318 | if ((regulator->da9052->chip_id == DA9052) && | 318 | if ((regulator->da9052->chip_id == DA9052) && |
319 | (min_uV >= DA9052_CONST_3uV)) | 319 | (min_uV >= DA9052_CONST_3uV)) |
320 | *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV + | 320 | *selector = DA9052_BUCK_PERI_REG_MAP_UPTO_3uV + |
321 | ((min_uV - DA9052_CONST_3uV) / | 321 | DIV_ROUND_UP(min_uV - DA9052_CONST_3uV, |
322 | (DA9052_BUCK_PERI_3uV_STEP)); | 322 | DA9052_BUCK_PERI_3uV_STEP); |
323 | else | 323 | else |
324 | *selector = (min_uV - info->min_uV) / info->step_uV; | 324 | *selector = DIV_ROUND_UP(min_uV - info->min_uV, info->step_uV); |
325 | 325 | ||
326 | ret = da9052_list_buckperi_voltage(rdev, *selector); | 326 | ret = da9052_list_buckperi_voltage(rdev, *selector); |
327 | if (ret < 0) | 327 | if (ret < 0) |
@@ -400,6 +400,7 @@ static struct regulator_ops da9052_ldo_ops = { | |||
400 | .ops = &da9052_ldo5_6_ops,\ | 400 | .ops = &da9052_ldo5_6_ops,\ |
401 | .type = REGULATOR_VOLTAGE,\ | 401 | .type = REGULATOR_VOLTAGE,\ |
402 | .id = _id,\ | 402 | .id = _id,\ |
403 | .n_voltages = (max - min) / step + 1, \ | ||
403 | .owner = THIS_MODULE,\ | 404 | .owner = THIS_MODULE,\ |
404 | },\ | 405 | },\ |
405 | .min_uV = (min) * 1000,\ | 406 | .min_uV = (min) * 1000,\ |
@@ -417,6 +418,7 @@ static struct regulator_ops da9052_ldo_ops = { | |||
417 | .ops = &da9052_ldo_ops,\ | 418 | .ops = &da9052_ldo_ops,\ |
418 | .type = REGULATOR_VOLTAGE,\ | 419 | .type = REGULATOR_VOLTAGE,\ |
419 | .id = _id,\ | 420 | .id = _id,\ |
421 | .n_voltages = (max - min) / step + 1, \ | ||
420 | .owner = THIS_MODULE,\ | 422 | .owner = THIS_MODULE,\ |
421 | },\ | 423 | },\ |
422 | .min_uV = (min) * 1000,\ | 424 | .min_uV = (min) * 1000,\ |
@@ -434,6 +436,7 @@ static struct regulator_ops da9052_ldo_ops = { | |||
434 | .ops = &da9052_dcdc_ops,\ | 436 | .ops = &da9052_dcdc_ops,\ |
435 | .type = REGULATOR_VOLTAGE,\ | 437 | .type = REGULATOR_VOLTAGE,\ |
436 | .id = _id,\ | 438 | .id = _id,\ |
439 | .n_voltages = (max - min) / step + 1, \ | ||
437 | .owner = THIS_MODULE,\ | 440 | .owner = THIS_MODULE,\ |
438 | },\ | 441 | },\ |
439 | .min_uV = (min) * 1000,\ | 442 | .min_uV = (min) * 1000,\ |
@@ -451,6 +454,7 @@ static struct regulator_ops da9052_ldo_ops = { | |||
451 | .ops = &da9052_buckperi_ops,\ | 454 | .ops = &da9052_buckperi_ops,\ |
452 | .type = REGULATOR_VOLTAGE,\ | 455 | .type = REGULATOR_VOLTAGE,\ |
453 | .id = _id,\ | 456 | .id = _id,\ |
457 | .n_voltages = (max - min) / step + 1, \ | ||
454 | .owner = THIS_MODULE,\ | 458 | .owner = THIS_MODULE,\ |
455 | },\ | 459 | },\ |
456 | .min_uV = (min) * 1000,\ | 460 | .min_uV = (min) * 1000,\ |
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c index 70b7b1f4f000..2e94686b6fe6 100644 --- a/drivers/regulator/tps6524x-regulator.c +++ b/drivers/regulator/tps6524x-regulator.c | |||
@@ -481,7 +481,7 @@ static int set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, | |||
481 | if (i >= info->n_voltages) | 481 | if (i >= info->n_voltages) |
482 | i = info->n_voltages - 1; | 482 | i = info->n_voltages - 1; |
483 | 483 | ||
484 | *selector = info->voltages[i]; | 484 | *selector = i; |
485 | 485 | ||
486 | return write_field(hw, &info->voltage, i); | 486 | return write_field(hw, &info->voltage, i); |
487 | } | 487 | } |
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 5c15ba01e9c7..40ecf5165899 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c | |||
@@ -662,7 +662,7 @@ static int tps65910_set_voltage_dcdc(struct regulator_dev *dev, | |||
662 | tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); | 662 | tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel); |
663 | break; | 663 | break; |
664 | case TPS65911_REG_VDDCTRL: | 664 | case TPS65911_REG_VDDCTRL: |
665 | vsel = selector; | 665 | vsel = selector + 3; |
666 | tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel); | 666 | tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel); |
667 | } | 667 | } |
668 | 668 | ||
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c index 9beba49c3c5b..2853c2a6f10f 100644 --- a/drivers/rtc/rtc-r9701.c +++ b/drivers/rtc/rtc-r9701.c | |||
@@ -125,6 +125,13 @@ static int __devinit r9701_probe(struct spi_device *spi) | |||
125 | unsigned char tmp; | 125 | unsigned char tmp; |
126 | int res; | 126 | int res; |
127 | 127 | ||
128 | tmp = R100CNT; | ||
129 | res = read_regs(&spi->dev, &tmp, 1); | ||
130 | if (res || tmp != 0x20) { | ||
131 | dev_err(&spi->dev, "cannot read RTC register\n"); | ||
132 | return -ENODEV; | ||
133 | } | ||
134 | |||
128 | rtc = rtc_device_register("r9701", | 135 | rtc = rtc_device_register("r9701", |
129 | &spi->dev, &r9701_rtc_ops, THIS_MODULE); | 136 | &spi->dev, &r9701_rtc_ops, THIS_MODULE); |
130 | if (IS_ERR(rtc)) | 137 | if (IS_ERR(rtc)) |
@@ -132,13 +139,6 @@ static int __devinit r9701_probe(struct spi_device *spi) | |||
132 | 139 | ||
133 | dev_set_drvdata(&spi->dev, rtc); | 140 | dev_set_drvdata(&spi->dev, rtc); |
134 | 141 | ||
135 | tmp = R100CNT; | ||
136 | res = read_regs(&spi->dev, &tmp, 1); | ||
137 | if (res || tmp != 0x20) { | ||
138 | rtc_device_unregister(rtc); | ||
139 | return res; | ||
140 | } | ||
141 | |||
142 | return 0; | 142 | return 0; |
143 | } | 143 | } |
144 | 144 | ||
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 70880be26015..2617b1ed4709 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c | |||
@@ -18,12 +18,12 @@ | |||
18 | #include <linux/hdreg.h> /* HDIO_GETGEO */ | 18 | #include <linux/hdreg.h> /* HDIO_GETGEO */ |
19 | #include <linux/bio.h> | 19 | #include <linux/bio.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/compat.h> | ||
21 | #include <linux/init.h> | 22 | #include <linux/init.h> |
22 | 23 | ||
23 | #include <asm/debug.h> | 24 | #include <asm/debug.h> |
24 | #include <asm/idals.h> | 25 | #include <asm/idals.h> |
25 | #include <asm/ebcdic.h> | 26 | #include <asm/ebcdic.h> |
26 | #include <asm/compat.h> | ||
27 | #include <asm/io.h> | 27 | #include <asm/io.h> |
28 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
29 | #include <asm/cio.h> | 29 | #include <asm/cio.h> |
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c index f1a2016829fc..792c69e78fe2 100644 --- a/drivers/s390/block/dasd_ioctl.c +++ b/drivers/s390/block/dasd_ioctl.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #define KMSG_COMPONENT "dasd" | 13 | #define KMSG_COMPONENT "dasd" |
14 | 14 | ||
15 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
16 | #include <linux/compat.h> | ||
16 | #include <linux/major.h> | 17 | #include <linux/major.h> |
17 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
18 | #include <linux/blkpg.h> | 19 | #include <linux/blkpg.h> |
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index e71298158f9e..911704571b9c 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/console.h> | 11 | #include <linux/console.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
14 | #include <linux/compat.h> | ||
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
15 | #include <linux/list.h> | 16 | #include <linux/list.h> |
16 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index 75bde6a8b7dc..89c03e6b1c0c 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/fs.h> | 14 | #include <linux/fs.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/compat.h> | ||
16 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
17 | #include <linux/miscdevice.h> | 18 | #include <linux/miscdevice.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 0c87b0fc7714..8f9a1a384496 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c | |||
@@ -8,6 +8,7 @@ | |||
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/compat.h> | ||
11 | #include <linux/device.h> | 12 | #include <linux/device.h> |
12 | #include <linux/module.h> | 13 | #include <linux/module.h> |
13 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 3ef8d071c64a..770a740a393c 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -167,7 +167,7 @@ again: | |||
167 | DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); | 167 | DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); |
168 | DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); | 168 | DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); |
169 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, | 169 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, |
170 | 0, -1, -1, q->irq_ptr->int_parm); | 170 | q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); |
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
@@ -215,7 +215,7 @@ again: | |||
215 | DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); | 215 | DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); |
216 | DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); | 216 | DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); |
217 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, | 217 | q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, |
218 | 0, -1, -1, q->irq_ptr->int_parm); | 218 | q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); |
219 | return 0; | 219 | return 0; |
220 | } | 220 | } |
221 | 221 | ||
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index 303dde09d294..fab2c2592a97 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #define KMSG_COMPONENT "zfcp" | 11 | #define KMSG_COMPONENT "zfcp" |
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
13 | 13 | ||
14 | #include <linux/compat.h> | ||
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
15 | #include <linux/types.h> | 16 | #include <linux/types.h> |
16 | #include <linux/miscdevice.h> | 17 | #include <linux/miscdevice.h> |
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index b31a8e3841d7..d4ed9eb52657 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c | |||
@@ -69,10 +69,10 @@ | |||
69 | #ifndef SCSI_OSD_MAJOR | 69 | #ifndef SCSI_OSD_MAJOR |
70 | # define SCSI_OSD_MAJOR 260 | 70 | # define SCSI_OSD_MAJOR 260 |
71 | #endif | 71 | #endif |
72 | #define SCSI_OSD_MAX_MINOR 64 | 72 | #define SCSI_OSD_MAX_MINOR MINORMASK |
73 | 73 | ||
74 | static const char osd_name[] = "osd"; | 74 | static const char osd_name[] = "osd"; |
75 | static const char *osd_version_string = "open-osd 0.2.0"; | 75 | static const char *osd_version_string = "open-osd 0.2.1"; |
76 | 76 | ||
77 | MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>"); | 77 | MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>"); |
78 | MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko"); | 78 | MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko"); |
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c index 0cb39ff21171..f8fb2d691c0a 100644 --- a/drivers/scsi/sd_dif.c +++ b/drivers/scsi/sd_dif.c | |||
@@ -408,7 +408,7 @@ int sd_dif_prepare(struct request *rq, sector_t hw_sector, unsigned int sector_s | |||
408 | kunmap_atomic(sdt, KM_USER0); | 408 | kunmap_atomic(sdt, KM_USER0); |
409 | } | 409 | } |
410 | 410 | ||
411 | bio->bi_flags |= BIO_MAPPED_INTEGRITY; | 411 | bio->bi_flags |= (1 << BIO_MAPPED_INTEGRITY); |
412 | } | 412 | } |
413 | 413 | ||
414 | return 0; | 414 | return 0; |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 2f9cb43a2398..f37ad2271ad5 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -1083,7 +1083,7 @@ err_alloc_rx_sg: | |||
1083 | return -ENOMEM; | 1083 | return -ENOMEM; |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | static int __init pl022_dma_probe(struct pl022 *pl022) | 1086 | static int __devinit pl022_dma_probe(struct pl022 *pl022) |
1087 | { | 1087 | { |
1088 | dma_cap_mask_t mask; | 1088 | dma_cap_mask_t mask; |
1089 | 1089 | ||
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 44262908def5..501b27c18145 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -1028,7 +1028,7 @@ done: | |||
1028 | return iscsit_add_reject_from_cmd( | 1028 | return iscsit_add_reject_from_cmd( |
1029 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, | 1029 | ISCSI_REASON_BOOKMARK_NO_RESOURCES, |
1030 | 1, 1, buf, cmd); | 1030 | 1, 1, buf, cmd); |
1031 | } else if (transport_ret == -EINVAL) { | 1031 | } else if (transport_ret < 0) { |
1032 | /* | 1032 | /* |
1033 | * Unsupported SAM Opcode. CHECK_CONDITION will be sent | 1033 | * Unsupported SAM Opcode. CHECK_CONDITION will be sent |
1034 | * in iscsit_execute_cmd() during the CmdSN OOO Execution | 1034 | * in iscsit_execute_cmd() during the CmdSN OOO Execution |
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c index b7c779389eea..63e703bb6ac9 100644 --- a/drivers/target/target_core_pr.c +++ b/drivers/target/target_core_pr.c | |||
@@ -117,7 +117,7 @@ static struct t10_pr_registration *core_scsi3_locate_pr_reg(struct se_device *, | |||
117 | struct se_node_acl *, struct se_session *); | 117 | struct se_node_acl *, struct se_session *); |
118 | static void core_scsi3_put_pr_reg(struct t10_pr_registration *); | 118 | static void core_scsi3_put_pr_reg(struct t10_pr_registration *); |
119 | 119 | ||
120 | static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | 120 | static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd) |
121 | { | 121 | { |
122 | struct se_session *se_sess = cmd->se_sess; | 122 | struct se_session *se_sess = cmd->se_sess; |
123 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; | 123 | struct se_subsystem_dev *su_dev = cmd->se_dev->se_sub_dev; |
@@ -127,7 +127,7 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | |||
127 | int conflict = 0; | 127 | int conflict = 0; |
128 | 128 | ||
129 | if (!crh) | 129 | if (!crh) |
130 | return false; | 130 | return -EINVAL; |
131 | 131 | ||
132 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, | 132 | pr_reg = core_scsi3_locate_pr_reg(cmd->se_dev, se_sess->se_node_acl, |
133 | se_sess); | 133 | se_sess); |
@@ -155,16 +155,14 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | |||
155 | */ | 155 | */ |
156 | if (pr_reg->pr_res_holder) { | 156 | if (pr_reg->pr_res_holder) { |
157 | core_scsi3_put_pr_reg(pr_reg); | 157 | core_scsi3_put_pr_reg(pr_reg); |
158 | *ret = 0; | 158 | return 1; |
159 | return false; | ||
160 | } | 159 | } |
161 | if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) || | 160 | if ((pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_REGONLY) || |
162 | (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) || | 161 | (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_REGONLY) || |
163 | (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || | 162 | (pr_reg->pr_res_type == PR_TYPE_WRITE_EXCLUSIVE_ALLREG) || |
164 | (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { | 163 | (pr_reg->pr_res_type == PR_TYPE_EXCLUSIVE_ACCESS_ALLREG)) { |
165 | core_scsi3_put_pr_reg(pr_reg); | 164 | core_scsi3_put_pr_reg(pr_reg); |
166 | *ret = 0; | 165 | return 1; |
167 | return true; | ||
168 | } | 166 | } |
169 | core_scsi3_put_pr_reg(pr_reg); | 167 | core_scsi3_put_pr_reg(pr_reg); |
170 | conflict = 1; | 168 | conflict = 1; |
@@ -189,10 +187,10 @@ static int target_check_scsi2_reservation_conflict(struct se_cmd *cmd, int *ret) | |||
189 | " while active SPC-3 registrations exist," | 187 | " while active SPC-3 registrations exist," |
190 | " returning RESERVATION_CONFLICT\n"); | 188 | " returning RESERVATION_CONFLICT\n"); |
191 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 189 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
192 | return true; | 190 | return -EBUSY; |
193 | } | 191 | } |
194 | 192 | ||
195 | return false; | 193 | return 0; |
196 | } | 194 | } |
197 | 195 | ||
198 | int target_scsi2_reservation_release(struct se_task *task) | 196 | int target_scsi2_reservation_release(struct se_task *task) |
@@ -201,12 +199,18 @@ int target_scsi2_reservation_release(struct se_task *task) | |||
201 | struct se_device *dev = cmd->se_dev; | 199 | struct se_device *dev = cmd->se_dev; |
202 | struct se_session *sess = cmd->se_sess; | 200 | struct se_session *sess = cmd->se_sess; |
203 | struct se_portal_group *tpg = sess->se_tpg; | 201 | struct se_portal_group *tpg = sess->se_tpg; |
204 | int ret = 0; | 202 | int ret = 0, rc; |
205 | 203 | ||
206 | if (!sess || !tpg) | 204 | if (!sess || !tpg) |
207 | goto out; | 205 | goto out; |
208 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) | 206 | rc = target_check_scsi2_reservation_conflict(cmd); |
207 | if (rc == 1) | ||
208 | goto out; | ||
209 | else if (rc < 0) { | ||
210 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
211 | ret = -EINVAL; | ||
209 | goto out; | 212 | goto out; |
213 | } | ||
210 | 214 | ||
211 | ret = 0; | 215 | ret = 0; |
212 | spin_lock(&dev->dev_reservation_lock); | 216 | spin_lock(&dev->dev_reservation_lock); |
@@ -243,7 +247,7 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
243 | struct se_device *dev = cmd->se_dev; | 247 | struct se_device *dev = cmd->se_dev; |
244 | struct se_session *sess = cmd->se_sess; | 248 | struct se_session *sess = cmd->se_sess; |
245 | struct se_portal_group *tpg = sess->se_tpg; | 249 | struct se_portal_group *tpg = sess->se_tpg; |
246 | int ret = 0; | 250 | int ret = 0, rc; |
247 | 251 | ||
248 | if ((cmd->t_task_cdb[1] & 0x01) && | 252 | if ((cmd->t_task_cdb[1] & 0x01) && |
249 | (cmd->t_task_cdb[1] & 0x02)) { | 253 | (cmd->t_task_cdb[1] & 0x02)) { |
@@ -259,8 +263,14 @@ int target_scsi2_reservation_reserve(struct se_task *task) | |||
259 | */ | 263 | */ |
260 | if (!sess || !tpg) | 264 | if (!sess || !tpg) |
261 | goto out; | 265 | goto out; |
262 | if (target_check_scsi2_reservation_conflict(cmd, &ret)) | 266 | rc = target_check_scsi2_reservation_conflict(cmd); |
267 | if (rc == 1) | ||
263 | goto out; | 268 | goto out; |
269 | else if (rc < 0) { | ||
270 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | ||
271 | ret = -EINVAL; | ||
272 | goto out; | ||
273 | } | ||
264 | 274 | ||
265 | ret = 0; | 275 | ret = 0; |
266 | spin_lock(&dev->dev_reservation_lock); | 276 | spin_lock(&dev->dev_reservation_lock); |
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index 58cea07b12fb..cd5cd95812bb 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c | |||
@@ -2539,6 +2539,7 @@ static int transport_generic_cmd_sequencer( | |||
2539 | cmd, cdb, pr_reg_type) != 0) { | 2539 | cmd, cdb, pr_reg_type) != 0) { |
2540 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; | 2540 | cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION; |
2541 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; | 2541 | cmd->se_cmd_flags |= SCF_SCSI_RESERVATION_CONFLICT; |
2542 | cmd->scsi_status = SAM_STAT_RESERVATION_CONFLICT; | ||
2542 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; | 2543 | cmd->scsi_sense_reason = TCM_RESERVATION_CONFLICT; |
2543 | return -EBUSY; | 2544 | return -EBUSY; |
2544 | } | 2545 | } |
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index b3d17416d86a..830cd62d8492 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig | |||
@@ -365,7 +365,7 @@ config PPC_EPAPR_HV_BYTECHAN | |||
365 | 365 | ||
366 | config PPC_EARLY_DEBUG_EHV_BC | 366 | config PPC_EARLY_DEBUG_EHV_BC |
367 | bool "Early console (udbg) support for ePAPR hypervisors" | 367 | bool "Early console (udbg) support for ePAPR hypervisors" |
368 | depends on PPC_EPAPR_HV_BYTECHAN | 368 | depends on PPC_EPAPR_HV_BYTECHAN=y |
369 | help | 369 | help |
370 | Select this option to enable early console (a.k.a. "udbg") support | 370 | Select this option to enable early console (a.k.a. "udbg") support |
371 | via an ePAPR byte channel. You also need to choose the byte channel | 371 | via an ePAPR byte channel. You also need to choose the byte channel |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 75085795528e..61b7fd2729cd 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -1710,6 +1710,8 @@ static int sci_startup(struct uart_port *port) | |||
1710 | 1710 | ||
1711 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | 1711 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); |
1712 | 1712 | ||
1713 | pm_runtime_put_noidle(port->dev); | ||
1714 | |||
1713 | sci_port_enable(s); | 1715 | sci_port_enable(s); |
1714 | 1716 | ||
1715 | ret = sci_request_irq(s); | 1717 | ret = sci_request_irq(s); |
@@ -1737,6 +1739,8 @@ static void sci_shutdown(struct uart_port *port) | |||
1737 | sci_free_irq(s); | 1739 | sci_free_irq(s); |
1738 | 1740 | ||
1739 | sci_port_disable(s); | 1741 | sci_port_disable(s); |
1742 | |||
1743 | pm_runtime_get_noresume(port->dev); | ||
1740 | } | 1744 | } |
1741 | 1745 | ||
1742 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, | 1746 | static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, |
@@ -2075,6 +2079,7 @@ static int __devinit sci_init_single(struct platform_device *dev, | |||
2075 | sci_init_gpios(sci_port); | 2079 | sci_init_gpios(sci_port); |
2076 | 2080 | ||
2077 | pm_runtime_irq_safe(&dev->dev); | 2081 | pm_runtime_irq_safe(&dev->dev); |
2082 | pm_runtime_get_noresume(&dev->dev); | ||
2078 | pm_runtime_enable(&dev->dev); | 2083 | pm_runtime_enable(&dev->dev); |
2079 | } | 2084 | } |
2080 | 2085 | ||
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index c26a82e83f6e..b556a72264d1 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -239,7 +239,7 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci, | |||
239 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); | 239 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); |
240 | } | 240 | } |
241 | 241 | ||
242 | static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) | 242 | static void ehci_fsl_usb_setup(struct ehci_hcd *ehci) |
243 | { | 243 | { |
244 | struct usb_hcd *hcd = ehci_to_hcd(ehci); | 244 | struct usb_hcd *hcd = ehci_to_hcd(ehci); |
245 | struct fsl_usb2_platform_data *pdata; | 245 | struct fsl_usb2_platform_data *pdata; |
@@ -299,19 +299,12 @@ static int ehci_fsl_usb_setup(struct ehci_hcd *ehci) | |||
299 | #endif | 299 | #endif |
300 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); | 300 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); |
301 | } | 301 | } |
302 | |||
303 | if (!(in_be32(non_ehci + FSL_SOC_USB_CTRL) & CTRL_PHY_CLK_VALID)) { | ||
304 | printk(KERN_WARNING "fsl-ehci: USB PHY clock invalid\n"); | ||
305 | return -ENODEV; | ||
306 | } | ||
307 | return 0; | ||
308 | } | 302 | } |
309 | 303 | ||
310 | /* called after powerup, by probe or system-pm "wakeup" */ | 304 | /* called after powerup, by probe or system-pm "wakeup" */ |
311 | static int ehci_fsl_reinit(struct ehci_hcd *ehci) | 305 | static int ehci_fsl_reinit(struct ehci_hcd *ehci) |
312 | { | 306 | { |
313 | if (ehci_fsl_usb_setup(ehci)) | 307 | ehci_fsl_usb_setup(ehci); |
314 | return -ENODEV; | ||
315 | ehci_port_power(ehci, 0); | 308 | ehci_port_power(ehci, 0); |
316 | 309 | ||
317 | return 0; | 310 | return 0; |
diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index bdf43e2adc51..491806221165 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h | |||
@@ -45,6 +45,5 @@ | |||
45 | #define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */ | 45 | #define FSL_SOC_USB_PRICTRL 0x40c /* NOTE: big-endian */ |
46 | #define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */ | 46 | #define FSL_SOC_USB_SICTRL 0x410 /* NOTE: big-endian */ |
47 | #define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */ | 47 | #define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */ |
48 | #define CTRL_PHY_CLK_VALID (1 << 17) | ||
49 | #define SNOOP_SIZE_2GB 0x1e | 48 | #define SNOOP_SIZE_2GB 0x1e |
50 | #endif /* _EHCI_FSL_H */ | 49 | #endif /* _EHCI_FSL_H */ |
diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c index e132157d8545..516db703dd24 100644 --- a/drivers/video/backlight/s6e63m0.c +++ b/drivers/video/backlight/s6e63m0.c | |||
@@ -690,7 +690,7 @@ static ssize_t s6e63m0_sysfs_store_gamma_mode(struct device *dev, | |||
690 | struct backlight_device *bd = NULL; | 690 | struct backlight_device *bd = NULL; |
691 | int brightness, rc; | 691 | int brightness, rc; |
692 | 692 | ||
693 | rc = strict_strtoul(buf, 0, (unsigned long *)&lcd->gamma_mode); | 693 | rc = kstrtouint(buf, 0, &lcd->gamma_mode); |
694 | if (rc < 0) | 694 | if (rc < 0) |
695 | return rc; | 695 | return rc; |
696 | 696 | ||
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 74d29b552901..408a9927be92 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig | |||
@@ -12,7 +12,7 @@ config PANEL_GENERIC_DPI | |||
12 | 12 | ||
13 | config PANEL_DVI | 13 | config PANEL_DVI |
14 | tristate "DVI output" | 14 | tristate "DVI output" |
15 | depends on OMAP2_DSS_DPI | 15 | depends on OMAP2_DSS_DPI && I2C |
16 | help | 16 | help |
17 | Driver for external monitors, connected via DVI. The driver uses i2c | 17 | Driver for external monitors, connected via DVI. The driver uses i2c |
18 | to read EDID information from the monitor. | 18 | to read EDID information from the monitor. |
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 052dc874cd3d..87b3e25294cf 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c | |||
@@ -1276,6 +1276,9 @@ int dss_ovl_enable(struct omap_overlay *ovl) | |||
1276 | 1276 | ||
1277 | spin_unlock_irqrestore(&data_lock, flags); | 1277 | spin_unlock_irqrestore(&data_lock, flags); |
1278 | 1278 | ||
1279 | /* wait for overlay to be enabled */ | ||
1280 | wait_pending_extra_info_updates(); | ||
1281 | |||
1279 | mutex_unlock(&apply_lock); | 1282 | mutex_unlock(&apply_lock); |
1280 | 1283 | ||
1281 | return 0; | 1284 | return 0; |
@@ -1313,6 +1316,9 @@ int dss_ovl_disable(struct omap_overlay *ovl) | |||
1313 | 1316 | ||
1314 | spin_unlock_irqrestore(&data_lock, flags); | 1317 | spin_unlock_irqrestore(&data_lock, flags); |
1315 | 1318 | ||
1319 | /* wait for the overlay to be disabled */ | ||
1320 | wait_pending_extra_info_updates(); | ||
1321 | |||
1316 | mutex_unlock(&apply_lock); | 1322 | mutex_unlock(&apply_lock); |
1317 | 1323 | ||
1318 | return 0; | 1324 | return 0; |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index d7aa3b056529..a36b934b2db4 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
@@ -165,9 +165,25 @@ static int hdmi_runtime_get(void) | |||
165 | 165 | ||
166 | DSSDBG("hdmi_runtime_get\n"); | 166 | DSSDBG("hdmi_runtime_get\n"); |
167 | 167 | ||
168 | /* | ||
169 | * HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled. | ||
170 | * This should be removed later. | ||
171 | */ | ||
172 | r = dss_runtime_get(); | ||
173 | if (r < 0) | ||
174 | goto err_get_dss; | ||
175 | |||
168 | r = pm_runtime_get_sync(&hdmi.pdev->dev); | 176 | r = pm_runtime_get_sync(&hdmi.pdev->dev); |
169 | WARN_ON(r < 0); | 177 | WARN_ON(r < 0); |
170 | return r < 0 ? r : 0; | 178 | if (r < 0) |
179 | goto err_get_hdmi; | ||
180 | |||
181 | return 0; | ||
182 | |||
183 | err_get_hdmi: | ||
184 | dss_runtime_put(); | ||
185 | err_get_dss: | ||
186 | return r; | ||
171 | } | 187 | } |
172 | 188 | ||
173 | static void hdmi_runtime_put(void) | 189 | static void hdmi_runtime_put(void) |
@@ -178,6 +194,12 @@ static void hdmi_runtime_put(void) | |||
178 | 194 | ||
179 | r = pm_runtime_put_sync(&hdmi.pdev->dev); | 195 | r = pm_runtime_put_sync(&hdmi.pdev->dev); |
180 | WARN_ON(r < 0); | 196 | WARN_ON(r < 0); |
197 | |||
198 | /* | ||
199 | * HACK: This is added to complement the dss_runtime_get() call in | ||
200 | * hdmi_runtime_get(). This should be removed later. | ||
201 | */ | ||
202 | dss_runtime_put(); | ||
181 | } | 203 | } |
182 | 204 | ||
183 | int hdmi_init_display(struct omap_dss_device *dssdev) | 205 | int hdmi_init_display(struct omap_dss_device *dssdev) |
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index 2d72334ca3da..6847a478b459 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | |||
@@ -479,14 +479,7 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, | |||
479 | 479 | ||
480 | bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data) | 480 | bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data) |
481 | { | 481 | { |
482 | int r; | 482 | return gpio_get_value(ip_data->hpd_gpio); |
483 | |||
484 | void __iomem *base = hdmi_core_sys_base(ip_data); | ||
485 | |||
486 | /* HPD */ | ||
487 | r = REG_GET(base, HDMI_CORE_SYS_SYS_STAT, 1, 1); | ||
488 | |||
489 | return r == 1; | ||
490 | } | 483 | } |
491 | 484 | ||
492 | static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, | 485 | static void hdmi_core_init(struct hdmi_core_video_config *video_cfg, |
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index d5aaca9cfa7e..8497727d66de 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
@@ -1810,7 +1810,11 @@ static void hw_init(void) | |||
1810 | break; | 1810 | break; |
1811 | } | 1811 | } |
1812 | 1812 | ||
1813 | /* magic required on VX900 for correct modesetting on IGA1 */ | ||
1814 | via_write_reg_mask(VIACR, 0x45, 0x00, 0x01); | ||
1815 | |||
1813 | /* probably this should go to the scaling code one day */ | 1816 | /* probably this should go to the scaling code one day */ |
1817 | via_write_reg_mask(VIACR, 0xFD, 0, 0x80); /* VX900 hw scale on IGA2 */ | ||
1814 | viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters)); | 1818 | viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters)); |
1815 | 1819 | ||
1816 | /* Fill VPIT Parameters */ | 1820 | /* Fill VPIT Parameters */ |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 95aeedf198f8..958e5129c601 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -367,29 +367,45 @@ static void __devexit virtballoon_remove(struct virtio_device *vdev) | |||
367 | #ifdef CONFIG_PM | 367 | #ifdef CONFIG_PM |
368 | static int virtballoon_freeze(struct virtio_device *vdev) | 368 | static int virtballoon_freeze(struct virtio_device *vdev) |
369 | { | 369 | { |
370 | struct virtio_balloon *vb = vdev->priv; | ||
371 | |||
370 | /* | 372 | /* |
371 | * The kthread is already frozen by the PM core before this | 373 | * The kthread is already frozen by the PM core before this |
372 | * function is called. | 374 | * function is called. |
373 | */ | 375 | */ |
374 | 376 | ||
377 | while (vb->num_pages) | ||
378 | leak_balloon(vb, vb->num_pages); | ||
379 | update_balloon_size(vb); | ||
380 | |||
375 | /* Ensure we don't get any more requests from the host */ | 381 | /* Ensure we don't get any more requests from the host */ |
376 | vdev->config->reset(vdev); | 382 | vdev->config->reset(vdev); |
377 | vdev->config->del_vqs(vdev); | 383 | vdev->config->del_vqs(vdev); |
378 | return 0; | 384 | return 0; |
379 | } | 385 | } |
380 | 386 | ||
387 | static int restore_common(struct virtio_device *vdev) | ||
388 | { | ||
389 | struct virtio_balloon *vb = vdev->priv; | ||
390 | int ret; | ||
391 | |||
392 | ret = init_vqs(vdev->priv); | ||
393 | if (ret) | ||
394 | return ret; | ||
395 | |||
396 | fill_balloon(vb, towards_target(vb)); | ||
397 | update_balloon_size(vb); | ||
398 | return 0; | ||
399 | } | ||
400 | |||
381 | static int virtballoon_thaw(struct virtio_device *vdev) | 401 | static int virtballoon_thaw(struct virtio_device *vdev) |
382 | { | 402 | { |
383 | return init_vqs(vdev->priv); | 403 | return restore_common(vdev); |
384 | } | 404 | } |
385 | 405 | ||
386 | static int virtballoon_restore(struct virtio_device *vdev) | 406 | static int virtballoon_restore(struct virtio_device *vdev) |
387 | { | 407 | { |
388 | struct virtio_balloon *vb = vdev->priv; | 408 | struct virtio_balloon *vb = vdev->priv; |
389 | struct page *page, *page2; | ||
390 | |||
391 | /* We're starting from a clean slate */ | ||
392 | vb->num_pages = 0; | ||
393 | 409 | ||
394 | /* | 410 | /* |
395 | * If a request wasn't complete at the time of freezing, this | 411 | * If a request wasn't complete at the time of freezing, this |
@@ -397,12 +413,7 @@ static int virtballoon_restore(struct virtio_device *vdev) | |||
397 | */ | 413 | */ |
398 | vb->need_stats_update = 0; | 414 | vb->need_stats_update = 0; |
399 | 415 | ||
400 | /* We don't have these pages in the balloon anymore! */ | 416 | return restore_common(vdev); |
401 | list_for_each_entry_safe(page, page2, &vb->pages, lru) { | ||
402 | list_del(&page->lru); | ||
403 | totalram_pages++; | ||
404 | } | ||
405 | return init_vqs(vdev->priv); | ||
406 | } | 417 | } |
407 | #endif | 418 | #endif |
408 | 419 | ||
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 877b107f77a7..df9e8f0e327d 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -1098,7 +1098,7 @@ config BOOKE_WDT_DEFAULT_TIMEOUT | |||
1098 | For Freescale Book-E processors, this is a number between 0 and 63. | 1098 | For Freescale Book-E processors, this is a number between 0 and 63. |
1099 | For other Book-E processors, this is a number between 0 and 3. | 1099 | For other Book-E processors, this is a number between 0 and 3. |
1100 | 1100 | ||
1101 | The value can be overidden by the wdt_period command-line parameter. | 1101 | The value can be overridden by the wdt_period command-line parameter. |
1102 | 1102 | ||
1103 | # PPC64 Architecture | 1103 | # PPC64 Architecture |
1104 | 1104 | ||
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 337265b47305..7c0fdfca2646 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c | |||
@@ -198,9 +198,13 @@ static long booke_wdt_ioctl(struct file *file, | |||
198 | booke_wdt_period = tmp; | 198 | booke_wdt_period = tmp; |
199 | #endif | 199 | #endif |
200 | booke_wdt_set(); | 200 | booke_wdt_set(); |
201 | return 0; | 201 | /* Fall */ |
202 | case WDIOC_GETTIMEOUT: | 202 | case WDIOC_GETTIMEOUT: |
203 | #ifdef CONFIG_FSL_BOOKE | ||
204 | return put_user(period_to_sec(booke_wdt_period), p); | ||
205 | #else | ||
203 | return put_user(booke_wdt_period, p); | 206 | return put_user(booke_wdt_period, p); |
207 | #endif | ||
204 | default: | 208 | default: |
205 | return -ENOTTY; | 209 | return -ENOTTY; |
206 | } | 210 | } |
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 8464ea1c36a1..3c166d3f4e55 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c | |||
@@ -231,7 +231,7 @@ static int __devinit cru_detect(unsigned long map_entry, | |||
231 | 231 | ||
232 | cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE; | 232 | cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE; |
233 | 233 | ||
234 | set_memory_x((unsigned long)bios32_entrypoint, (2 * PAGE_SIZE)); | 234 | set_memory_x((unsigned long)bios32_map, 2); |
235 | asminline_call(&cmn_regs, bios32_entrypoint); | 235 | asminline_call(&cmn_regs, bios32_entrypoint); |
236 | 236 | ||
237 | if (cmn_regs.u1.ral != 0) { | 237 | if (cmn_regs.u1.ral != 0) { |
@@ -250,7 +250,8 @@ static int __devinit cru_detect(unsigned long map_entry, | |||
250 | cru_rom_addr = | 250 | cru_rom_addr = |
251 | ioremap(cru_physical_address, cru_length); | 251 | ioremap(cru_physical_address, cru_length); |
252 | if (cru_rom_addr) { | 252 | if (cru_rom_addr) { |
253 | set_memory_x((unsigned long)cru_rom_addr, cru_length); | 253 | set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK, |
254 | (cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT); | ||
254 | retval = 0; | 255 | retval = 0; |
255 | } | 256 | } |
256 | } | 257 | } |
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 8e210aafdfd0..dfae030a7ef2 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
@@ -264,7 +264,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev) | |||
264 | wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 264 | wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
265 | if (wdt_mem == NULL) { | 265 | if (wdt_mem == NULL) { |
266 | printk(KERN_INFO MODULE_NAME | 266 | printk(KERN_INFO MODULE_NAME |
267 | "failed to get memory region resouce\n"); | 267 | "failed to get memory region resource\n"); |
268 | return -ENOENT; | 268 | return -ENOENT; |
269 | } | 269 | } |
270 | 270 | ||
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index 4bc3744e14e4..404172f02c9b 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c | |||
@@ -312,18 +312,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
312 | dev = &pdev->dev; | 312 | dev = &pdev->dev; |
313 | wdt_dev = &pdev->dev; | 313 | wdt_dev = &pdev->dev; |
314 | 314 | ||
315 | /* get the memory region for the watchdog timer */ | ||
316 | |||
317 | wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 315 | wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
318 | if (wdt_mem == NULL) { | 316 | if (wdt_mem == NULL) { |
319 | dev_err(dev, "no memory resource specified\n"); | 317 | dev_err(dev, "no memory resource specified\n"); |
320 | return -ENOENT; | 318 | return -ENOENT; |
321 | } | 319 | } |
322 | 320 | ||
321 | wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
322 | if (wdt_irq == NULL) { | ||
323 | dev_err(dev, "no irq resource specified\n"); | ||
324 | ret = -ENOENT; | ||
325 | goto err; | ||
326 | } | ||
327 | |||
328 | /* get the memory region for the watchdog timer */ | ||
329 | |||
323 | size = resource_size(wdt_mem); | 330 | size = resource_size(wdt_mem); |
324 | if (!request_mem_region(wdt_mem->start, size, pdev->name)) { | 331 | if (!request_mem_region(wdt_mem->start, size, pdev->name)) { |
325 | dev_err(dev, "failed to get memory region\n"); | 332 | dev_err(dev, "failed to get memory region\n"); |
326 | return -EBUSY; | 333 | ret = -EBUSY; |
334 | goto err; | ||
327 | } | 335 | } |
328 | 336 | ||
329 | wdt_base = ioremap(wdt_mem->start, size); | 337 | wdt_base = ioremap(wdt_mem->start, size); |
@@ -335,29 +343,17 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
335 | 343 | ||
336 | DBG("probe: mapped wdt_base=%p\n", wdt_base); | 344 | DBG("probe: mapped wdt_base=%p\n", wdt_base); |
337 | 345 | ||
338 | wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
339 | if (wdt_irq == NULL) { | ||
340 | dev_err(dev, "no irq resource specified\n"); | ||
341 | ret = -ENOENT; | ||
342 | goto err_map; | ||
343 | } | ||
344 | |||
345 | ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev); | ||
346 | if (ret != 0) { | ||
347 | dev_err(dev, "failed to install irq (%d)\n", ret); | ||
348 | goto err_map; | ||
349 | } | ||
350 | |||
351 | wdt_clock = clk_get(&pdev->dev, "watchdog"); | 346 | wdt_clock = clk_get(&pdev->dev, "watchdog"); |
352 | if (IS_ERR(wdt_clock)) { | 347 | if (IS_ERR(wdt_clock)) { |
353 | dev_err(dev, "failed to find watchdog clock source\n"); | 348 | dev_err(dev, "failed to find watchdog clock source\n"); |
354 | ret = PTR_ERR(wdt_clock); | 349 | ret = PTR_ERR(wdt_clock); |
355 | goto err_irq; | 350 | goto err_map; |
356 | } | 351 | } |
357 | 352 | ||
358 | clk_enable(wdt_clock); | 353 | clk_enable(wdt_clock); |
359 | 354 | ||
360 | if (s3c2410wdt_cpufreq_register() < 0) { | 355 | ret = s3c2410wdt_cpufreq_register(); |
356 | if (ret < 0) { | ||
361 | printk(KERN_ERR PFX "failed to register cpufreq\n"); | 357 | printk(KERN_ERR PFX "failed to register cpufreq\n"); |
362 | goto err_clk; | 358 | goto err_clk; |
363 | } | 359 | } |
@@ -378,12 +374,18 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
378 | "cannot start\n"); | 374 | "cannot start\n"); |
379 | } | 375 | } |
380 | 376 | ||
377 | ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev); | ||
378 | if (ret != 0) { | ||
379 | dev_err(dev, "failed to install irq (%d)\n", ret); | ||
380 | goto err_cpufreq; | ||
381 | } | ||
382 | |||
381 | watchdog_set_nowayout(&s3c2410_wdd, nowayout); | 383 | watchdog_set_nowayout(&s3c2410_wdd, nowayout); |
382 | 384 | ||
383 | ret = watchdog_register_device(&s3c2410_wdd); | 385 | ret = watchdog_register_device(&s3c2410_wdd); |
384 | if (ret) { | 386 | if (ret) { |
385 | dev_err(dev, "cannot register watchdog (%d)\n", ret); | 387 | dev_err(dev, "cannot register watchdog (%d)\n", ret); |
386 | goto err_cpufreq; | 388 | goto err_irq; |
387 | } | 389 | } |
388 | 390 | ||
389 | if (tmr_atboot && started == 0) { | 391 | if (tmr_atboot && started == 0) { |
@@ -408,23 +410,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev) | |||
408 | 410 | ||
409 | return 0; | 411 | return 0; |
410 | 412 | ||
413 | err_irq: | ||
414 | free_irq(wdt_irq->start, pdev); | ||
415 | |||
411 | err_cpufreq: | 416 | err_cpufreq: |
412 | s3c2410wdt_cpufreq_deregister(); | 417 | s3c2410wdt_cpufreq_deregister(); |
413 | 418 | ||
414 | err_clk: | 419 | err_clk: |
415 | clk_disable(wdt_clock); | 420 | clk_disable(wdt_clock); |
416 | clk_put(wdt_clock); | 421 | clk_put(wdt_clock); |
417 | 422 | wdt_clock = NULL; | |
418 | err_irq: | ||
419 | free_irq(wdt_irq->start, pdev); | ||
420 | 423 | ||
421 | err_map: | 424 | err_map: |
422 | iounmap(wdt_base); | 425 | iounmap(wdt_base); |
423 | 426 | ||
424 | err_req: | 427 | err_req: |
425 | release_mem_region(wdt_mem->start, size); | 428 | release_mem_region(wdt_mem->start, size); |
426 | wdt_mem = NULL; | ||
427 | 429 | ||
430 | err: | ||
431 | wdt_irq = NULL; | ||
432 | wdt_mem = NULL; | ||
428 | return ret; | 433 | return ret; |
429 | } | 434 | } |
430 | 435 | ||
@@ -432,18 +437,18 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev) | |||
432 | { | 437 | { |
433 | watchdog_unregister_device(&s3c2410_wdd); | 438 | watchdog_unregister_device(&s3c2410_wdd); |
434 | 439 | ||
440 | free_irq(wdt_irq->start, dev); | ||
441 | |||
435 | s3c2410wdt_cpufreq_deregister(); | 442 | s3c2410wdt_cpufreq_deregister(); |
436 | 443 | ||
437 | clk_disable(wdt_clock); | 444 | clk_disable(wdt_clock); |
438 | clk_put(wdt_clock); | 445 | clk_put(wdt_clock); |
439 | wdt_clock = NULL; | 446 | wdt_clock = NULL; |
440 | 447 | ||
441 | free_irq(wdt_irq->start, dev); | ||
442 | wdt_irq = NULL; | ||
443 | |||
444 | iounmap(wdt_base); | 448 | iounmap(wdt_base); |
445 | 449 | ||
446 | release_mem_region(wdt_mem->start, resource_size(wdt_mem)); | 450 | release_mem_region(wdt_mem->start, resource_size(wdt_mem)); |
451 | wdt_irq = NULL; | ||
447 | wdt_mem = NULL; | 452 | wdt_mem = NULL; |
448 | return 0; | 453 | return 0; |
449 | } | 454 | } |