diff options
Diffstat (limited to 'drivers')
224 files changed, 5307 insertions, 2142 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 1b3142127bf5..c07be024b962 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
@@ -97,7 +97,7 @@ obj-$(CONFIG_EISA) += eisa/ | |||
97 | obj-y += lguest/ | 97 | obj-y += lguest/ |
98 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ | 98 | obj-$(CONFIG_CPU_FREQ) += cpufreq/ |
99 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ | 99 | obj-$(CONFIG_CPU_IDLE) += cpuidle/ |
100 | obj-$(CONFIG_MMC) += mmc/ | 100 | obj-y += mmc/ |
101 | obj-$(CONFIG_MEMSTICK) += memstick/ | 101 | obj-$(CONFIG_MEMSTICK) += memstick/ |
102 | obj-y += leds/ | 102 | obj-y += leds/ |
103 | obj-$(CONFIG_INFINIBAND) += infiniband/ | 103 | obj-$(CONFIG_INFINIBAND) += infiniband/ |
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig index fcbec8ac134d..7be9f79018e9 100644 --- a/drivers/base/Kconfig +++ b/drivers/base/Kconfig | |||
@@ -179,7 +179,7 @@ config GENERIC_CPU_DEVICES | |||
179 | source "drivers/base/regmap/Kconfig" | 179 | source "drivers/base/regmap/Kconfig" |
180 | 180 | ||
181 | config DMA_SHARED_BUFFER | 181 | config DMA_SHARED_BUFFER |
182 | bool "Buffer framework to be shared between drivers" | 182 | bool |
183 | default n | 183 | default n |
184 | select ANON_INODES | 184 | select ANON_INODES |
185 | depends on EXPERIMENTAL | 185 | depends on EXPERIMENTAL |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index f17e3ea041c0..ed5de58c340f 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -295,11 +295,22 @@ static int memory_block_change_state(struct memory_block *mem, | |||
295 | 295 | ||
296 | ret = memory_block_action(mem->start_section_nr, to_state); | 296 | ret = memory_block_action(mem->start_section_nr, to_state); |
297 | 297 | ||
298 | if (ret) | 298 | if (ret) { |
299 | mem->state = from_state_req; | 299 | mem->state = from_state_req; |
300 | else | 300 | goto out; |
301 | mem->state = to_state; | 301 | } |
302 | 302 | ||
303 | mem->state = to_state; | ||
304 | switch (mem->state) { | ||
305 | case MEM_OFFLINE: | ||
306 | kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE); | ||
307 | break; | ||
308 | case MEM_ONLINE: | ||
309 | kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE); | ||
310 | break; | ||
311 | default: | ||
312 | break; | ||
313 | } | ||
303 | out: | 314 | out: |
304 | mutex_unlock(&mem->state_mutex); | 315 | mutex_unlock(&mem->state_mutex); |
305 | return ret; | 316 | return ret; |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 148ab944378d..3fd31dec8c9c 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -2184,6 +2184,8 @@ static ssize_t rbd_add(struct bus_type *bus, | |||
2184 | INIT_LIST_HEAD(&rbd_dev->node); | 2184 | INIT_LIST_HEAD(&rbd_dev->node); |
2185 | INIT_LIST_HEAD(&rbd_dev->snaps); | 2185 | INIT_LIST_HEAD(&rbd_dev->snaps); |
2186 | 2186 | ||
2187 | init_rwsem(&rbd_dev->header.snap_rwsem); | ||
2188 | |||
2187 | /* generate unique id: find highest unique id, add one */ | 2189 | /* generate unique id: find highest unique id, add one */ |
2188 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); | 2190 | mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); |
2189 | 2191 | ||
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c index 7c7f42a1f880..9fec3232b736 100644 --- a/drivers/char/ramoops.c +++ b/drivers/char/ramoops.c | |||
@@ -83,8 +83,7 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
83 | struct timeval timestamp; | 83 | struct timeval timestamp; |
84 | 84 | ||
85 | if (reason != KMSG_DUMP_OOPS && | 85 | if (reason != KMSG_DUMP_OOPS && |
86 | reason != KMSG_DUMP_PANIC && | 86 | reason != KMSG_DUMP_PANIC) |
87 | reason != KMSG_DUMP_KEXEC) | ||
88 | return; | 87 | return; |
89 | 88 | ||
90 | /* Only dump oopses if dump_oops is set */ | 89 | /* Only dump oopses if dump_oops is set */ |
@@ -126,8 +125,8 @@ static int __init ramoops_probe(struct platform_device *pdev) | |||
126 | goto fail3; | 125 | goto fail3; |
127 | } | 126 | } |
128 | 127 | ||
129 | rounddown_pow_of_two(pdata->mem_size); | 128 | pdata->mem_size = rounddown_pow_of_two(pdata->mem_size); |
130 | rounddown_pow_of_two(pdata->record_size); | 129 | pdata->record_size = rounddown_pow_of_two(pdata->record_size); |
131 | 130 | ||
132 | /* Check for the minimum memory size */ | 131 | /* Check for the minimum memory size */ |
133 | if (pdata->mem_size < MIN_MEM_SIZE && | 132 | if (pdata->mem_size < MIN_MEM_SIZE && |
@@ -148,14 +147,6 @@ static int __init ramoops_probe(struct platform_device *pdev) | |||
148 | cxt->phys_addr = pdata->mem_address; | 147 | cxt->phys_addr = pdata->mem_address; |
149 | cxt->record_size = pdata->record_size; | 148 | cxt->record_size = pdata->record_size; |
150 | cxt->dump_oops = pdata->dump_oops; | 149 | cxt->dump_oops = pdata->dump_oops; |
151 | /* | ||
152 | * Update the module parameter variables as well so they are visible | ||
153 | * through /sys/module/ramoops/parameters/ | ||
154 | */ | ||
155 | mem_size = pdata->mem_size; | ||
156 | mem_address = pdata->mem_address; | ||
157 | record_size = pdata->record_size; | ||
158 | dump_oops = pdata->dump_oops; | ||
159 | 150 | ||
160 | if (!request_mem_region(cxt->phys_addr, cxt->size, "ramoops")) { | 151 | if (!request_mem_region(cxt->phys_addr, cxt->size, "ramoops")) { |
161 | pr_err("request mem region failed\n"); | 152 | pr_err("request mem region failed\n"); |
@@ -176,6 +167,15 @@ static int __init ramoops_probe(struct platform_device *pdev) | |||
176 | goto fail1; | 167 | goto fail1; |
177 | } | 168 | } |
178 | 169 | ||
170 | /* | ||
171 | * Update the module parameter variables as well so they are visible | ||
172 | * through /sys/module/ramoops/parameters/ | ||
173 | */ | ||
174 | mem_size = pdata->mem_size; | ||
175 | mem_address = pdata->mem_address; | ||
176 | record_size = pdata->record_size; | ||
177 | dump_oops = pdata->dump_oops; | ||
178 | |||
179 | return 0; | 179 | return 0; |
180 | 180 | ||
181 | fail1: | 181 | fail1: |
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 4c980b573328..87a68a896abf 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c | |||
@@ -65,7 +65,14 @@ static void stmpe_gpio_set(struct gpio_chip *chip, unsigned offset, int val) | |||
65 | u8 reg = stmpe->regs[which] - (offset / 8); | 65 | u8 reg = stmpe->regs[which] - (offset / 8); |
66 | u8 mask = 1 << (offset % 8); | 66 | u8 mask = 1 << (offset % 8); |
67 | 67 | ||
68 | stmpe_reg_write(stmpe, reg, mask); | 68 | /* |
69 | * Some variants have single register for gpio set/clear functionality. | ||
70 | * For them we need to write 0 to clear and 1 to set. | ||
71 | */ | ||
72 | if (stmpe->regs[STMPE_IDX_GPSR_LSB] == stmpe->regs[STMPE_IDX_GPCR_LSB]) | ||
73 | stmpe_set_bits(stmpe, reg, mask, val ? mask : 0); | ||
74 | else | ||
75 | stmpe_reg_write(stmpe, reg, mask); | ||
69 | } | 76 | } |
70 | 77 | ||
71 | static int stmpe_gpio_direction_output(struct gpio_chip *chip, | 78 | static int stmpe_gpio_direction_output(struct gpio_chip *chip, |
@@ -132,6 +139,10 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) | |||
132 | if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) | 139 | if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH) |
133 | return -EINVAL; | 140 | return -EINVAL; |
134 | 141 | ||
142 | /* STMPE801 doesn't have RE and FE registers */ | ||
143 | if (stmpe_gpio->stmpe->partnum == STMPE801) | ||
144 | return 0; | ||
145 | |||
135 | if (type == IRQ_TYPE_EDGE_RISING) | 146 | if (type == IRQ_TYPE_EDGE_RISING) |
136 | stmpe_gpio->regs[REG_RE][regoffset] |= mask; | 147 | stmpe_gpio->regs[REG_RE][regoffset] |= mask; |
137 | else | 148 | else |
@@ -165,6 +176,11 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) | |||
165 | int i, j; | 176 | int i, j; |
166 | 177 | ||
167 | for (i = 0; i < CACHE_NR_REGS; i++) { | 178 | for (i = 0; i < CACHE_NR_REGS; i++) { |
179 | /* STMPE801 doesn't have RE and FE registers */ | ||
180 | if ((stmpe->partnum == STMPE801) && | ||
181 | (i != REG_IE)) | ||
182 | continue; | ||
183 | |||
168 | for (j = 0; j < num_banks; j++) { | 184 | for (j = 0; j < num_banks; j++) { |
169 | u8 old = stmpe_gpio->oldregs[i][j]; | 185 | u8 old = stmpe_gpio->oldregs[i][j]; |
170 | u8 new = stmpe_gpio->regs[i][j]; | 186 | u8 new = stmpe_gpio->regs[i][j]; |
@@ -241,8 +257,11 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) | |||
241 | } | 257 | } |
242 | 258 | ||
243 | stmpe_reg_write(stmpe, statmsbreg + i, status[i]); | 259 | stmpe_reg_write(stmpe, statmsbreg + i, status[i]); |
244 | stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB] + i, | 260 | |
245 | status[i]); | 261 | /* Edge detect register is not present on 801 */ |
262 | if (stmpe->partnum != STMPE801) | ||
263 | stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB] | ||
264 | + i, status[i]); | ||
246 | } | 265 | } |
247 | 266 | ||
248 | return IRQ_HANDLED; | 267 | return IRQ_HANDLED; |
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c index 6d0f10b7569c..c100f3e9c920 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_crt.c +++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c | |||
@@ -66,6 +66,7 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode) | |||
66 | static int cdv_intel_crt_mode_valid(struct drm_connector *connector, | 66 | static int cdv_intel_crt_mode_valid(struct drm_connector *connector, |
67 | struct drm_display_mode *mode) | 67 | struct drm_display_mode *mode) |
68 | { | 68 | { |
69 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
69 | int max_clock = 0; | 70 | int max_clock = 0; |
70 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 71 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
71 | return MODE_NO_DBLESCAN; | 72 | return MODE_NO_DBLESCAN; |
@@ -82,6 +83,11 @@ static int cdv_intel_crt_mode_valid(struct drm_connector *connector, | |||
82 | if (mode->hdisplay > 1680 || mode->vdisplay > 1050) | 83 | if (mode->hdisplay > 1680 || mode->vdisplay > 1050) |
83 | return MODE_PANEL; | 84 | return MODE_PANEL; |
84 | 85 | ||
86 | /* We assume worst case scenario of 32 bpp here, since we don't know */ | ||
87 | if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | ||
88 | dev_priv->vram_stolen_size) | ||
89 | return MODE_MEM; | ||
90 | |||
85 | return MODE_OK; | 91 | return MODE_OK; |
86 | } | 92 | } |
87 | 93 | ||
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index 50d7cfb51662..de25560e629d 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c | |||
@@ -241,6 +241,7 @@ static int cdv_hdmi_get_modes(struct drm_connector *connector) | |||
241 | static int cdv_hdmi_mode_valid(struct drm_connector *connector, | 241 | static int cdv_hdmi_mode_valid(struct drm_connector *connector, |
242 | struct drm_display_mode *mode) | 242 | struct drm_display_mode *mode) |
243 | { | 243 | { |
244 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
244 | 245 | ||
245 | if (mode->clock > 165000) | 246 | if (mode->clock > 165000) |
246 | return MODE_CLOCK_HIGH; | 247 | return MODE_CLOCK_HIGH; |
@@ -255,14 +256,11 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector, | |||
255 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | 256 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) |
256 | return MODE_NO_INTERLACE; | 257 | return MODE_NO_INTERLACE; |
257 | 258 | ||
258 | /* | 259 | /* We assume worst case scenario of 32 bpp here, since we don't know */ |
259 | * FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it | 260 | if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > |
260 | * will go beyond the stolen memory size allocated to the framebuffer | 261 | dev_priv->vram_stolen_size) |
261 | */ | 262 | return MODE_MEM; |
262 | if (mode->hdisplay > 1680) | 263 | |
263 | return MODE_PANEL; | ||
264 | if (mode->vdisplay > 1050) | ||
265 | return MODE_PANEL; | ||
266 | return MODE_OK; | 264 | return MODE_OK; |
267 | } | 265 | } |
268 | 266 | ||
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index 36878a60080d..025d30970cc0 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c | |||
@@ -506,6 +506,7 @@ int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc, | |||
506 | static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, | 506 | static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, |
507 | struct drm_display_mode *mode) | 507 | struct drm_display_mode *mode) |
508 | { | 508 | { |
509 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
509 | if (mode->clock > 165000) | 510 | if (mode->clock > 165000) |
510 | return MODE_CLOCK_HIGH; | 511 | return MODE_CLOCK_HIGH; |
511 | if (mode->clock < 20000) | 512 | if (mode->clock < 20000) |
@@ -514,6 +515,11 @@ static int oaktrail_hdmi_mode_valid(struct drm_connector *connector, | |||
514 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 515 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
515 | return MODE_NO_DBLESCAN; | 516 | return MODE_NO_DBLESCAN; |
516 | 517 | ||
518 | /* We assume worst case scenario of 32 bpp here, since we don't know */ | ||
519 | if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | ||
520 | dev_priv->vram_stolen_size) | ||
521 | return MODE_MEM; | ||
522 | |||
517 | return MODE_OK; | 523 | return MODE_OK; |
518 | } | 524 | } |
519 | 525 | ||
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 4882b29119e0..88b42971c0fd 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c | |||
@@ -1141,6 +1141,7 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) | |||
1141 | static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, | 1141 | static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, |
1142 | struct drm_display_mode *mode) | 1142 | struct drm_display_mode *mode) |
1143 | { | 1143 | { |
1144 | struct drm_psb_private *dev_priv = connector->dev->dev_private; | ||
1144 | struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); | 1145 | struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); |
1145 | 1146 | ||
1146 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) | 1147 | if (mode->flags & DRM_MODE_FLAG_DBLSCAN) |
@@ -1160,6 +1161,11 @@ static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, | |||
1160 | return MODE_PANEL; | 1161 | return MODE_PANEL; |
1161 | } | 1162 | } |
1162 | 1163 | ||
1164 | /* We assume worst case scenario of 32 bpp here, since we don't know */ | ||
1165 | if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) > | ||
1166 | dev_priv->vram_stolen_size) | ||
1167 | return MODE_MEM; | ||
1168 | |||
1163 | return MODE_OK; | 1169 | return MODE_OK; |
1164 | } | 1170 | } |
1165 | 1171 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 525744d593c1..7814a760c164 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -18,12 +18,6 @@ | |||
18 | 18 | ||
19 | #include <linux/vga_switcheroo.h> | 19 | #include <linux/vga_switcheroo.h> |
20 | 20 | ||
21 | #define NOUVEAU_DSM_SUPPORTED 0x00 | ||
22 | #define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00 | ||
23 | |||
24 | #define NOUVEAU_DSM_ACTIVE 0x01 | ||
25 | #define NOUVEAU_DSM_ACTIVE_QUERY 0x00 | ||
26 | |||
27 | #define NOUVEAU_DSM_LED 0x02 | 21 | #define NOUVEAU_DSM_LED 0x02 |
28 | #define NOUVEAU_DSM_LED_STATE 0x00 | 22 | #define NOUVEAU_DSM_LED_STATE 0x00 |
29 | #define NOUVEAU_DSM_LED_OFF 0x10 | 23 | #define NOUVEAU_DSM_LED_OFF 0x10 |
@@ -35,6 +29,9 @@ | |||
35 | #define NOUVEAU_DSM_POWER_SPEED 0x01 | 29 | #define NOUVEAU_DSM_POWER_SPEED 0x01 |
36 | #define NOUVEAU_DSM_POWER_STAMINA 0x02 | 30 | #define NOUVEAU_DSM_POWER_STAMINA 0x02 |
37 | 31 | ||
32 | #define NOUVEAU_DSM_OPTIMUS_FN 0x1A | ||
33 | #define NOUVEAU_DSM_OPTIMUS_ARGS 0x03000001 | ||
34 | |||
38 | static struct nouveau_dsm_priv { | 35 | static struct nouveau_dsm_priv { |
39 | bool dsm_detected; | 36 | bool dsm_detected; |
40 | bool optimus_detected; | 37 | bool optimus_detected; |
@@ -61,7 +58,8 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t * | |||
61 | struct acpi_object_list input; | 58 | struct acpi_object_list input; |
62 | union acpi_object params[4]; | 59 | union acpi_object params[4]; |
63 | union acpi_object *obj; | 60 | union acpi_object *obj; |
64 | int err; | 61 | int i, err; |
62 | char args_buff[4]; | ||
65 | 63 | ||
66 | input.count = 4; | 64 | input.count = 4; |
67 | input.pointer = params; | 65 | input.pointer = params; |
@@ -73,7 +71,11 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t * | |||
73 | params[2].type = ACPI_TYPE_INTEGER; | 71 | params[2].type = ACPI_TYPE_INTEGER; |
74 | params[2].integer.value = func; | 72 | params[2].integer.value = func; |
75 | params[3].type = ACPI_TYPE_BUFFER; | 73 | params[3].type = ACPI_TYPE_BUFFER; |
76 | params[3].buffer.length = 0; | 74 | params[3].buffer.length = 4; |
75 | /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */ | ||
76 | for (i = 0; i < 4; i++) | ||
77 | args_buff[i] = (arg >> i * 8) & 0xFF; | ||
78 | params[3].buffer.pointer = args_buff; | ||
77 | 79 | ||
78 | err = acpi_evaluate_object(handle, "_DSM", &input, &output); | 80 | err = acpi_evaluate_object(handle, "_DSM", &input, &output); |
79 | if (err) { | 81 | if (err) { |
@@ -148,6 +150,23 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result) | |||
148 | return 0; | 150 | return 0; |
149 | } | 151 | } |
150 | 152 | ||
153 | /* Returns 1 if a DSM function is usable and 0 otherwise */ | ||
154 | static int nouveau_test_dsm(acpi_handle test_handle, | ||
155 | int (*dsm_func)(acpi_handle, int, int, uint32_t *), | ||
156 | int sfnc) | ||
157 | { | ||
158 | u32 result = 0; | ||
159 | |||
160 | /* Function 0 returns a Buffer containing available functions. The args | ||
161 | * parameter is ignored for function 0, so just put 0 in it */ | ||
162 | if (dsm_func(test_handle, 0, 0, &result)) | ||
163 | return 0; | ||
164 | |||
165 | /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If | ||
166 | * the n-th bit is enabled, function n is supported */ | ||
167 | return result & 1 && result & (1 << sfnc); | ||
168 | } | ||
169 | |||
151 | static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) | 170 | static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id) |
152 | { | 171 | { |
153 | mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); | 172 | mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0); |
@@ -168,6 +187,10 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero | |||
168 | 187 | ||
169 | static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) | 188 | static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id) |
170 | { | 189 | { |
190 | /* perhaps the _DSM functions are mutually exclusive, but prepare for | ||
191 | * the future */ | ||
192 | if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected) | ||
193 | return 0; | ||
171 | if (id == VGA_SWITCHEROO_IGD) | 194 | if (id == VGA_SWITCHEROO_IGD) |
172 | return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA); | 195 | return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA); |
173 | else | 196 | else |
@@ -180,6 +203,11 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, | |||
180 | if (id == VGA_SWITCHEROO_IGD) | 203 | if (id == VGA_SWITCHEROO_IGD) |
181 | return 0; | 204 | return 0; |
182 | 205 | ||
206 | /* Optimus laptops have the card already disabled in | ||
207 | * nouveau_switcheroo_set_state */ | ||
208 | if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected) | ||
209 | return 0; | ||
210 | |||
183 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); | 211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); |
184 | } | 212 | } |
185 | 213 | ||
@@ -212,8 +240,7 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) | |||
212 | { | 240 | { |
213 | acpi_handle dhandle, nvidia_handle; | 241 | acpi_handle dhandle, nvidia_handle; |
214 | acpi_status status; | 242 | acpi_status status; |
215 | int ret, retval = 0; | 243 | int retval = 0; |
216 | uint32_t result; | ||
217 | 244 | ||
218 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); | 245 | dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); |
219 | if (!dhandle) | 246 | if (!dhandle) |
@@ -224,13 +251,11 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev) | |||
224 | return false; | 251 | return false; |
225 | } | 252 | } |
226 | 253 | ||
227 | ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED, | 254 | if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) |
228 | NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result); | ||
229 | if (ret == 0) | ||
230 | retval |= NOUVEAU_DSM_HAS_MUX; | 255 | retval |= NOUVEAU_DSM_HAS_MUX; |
231 | 256 | ||
232 | ret = nouveau_optimus_dsm(dhandle, 0, 0, &result); | 257 | if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm, |
233 | if (ret == 0) | 258 | NOUVEAU_DSM_OPTIMUS_FN)) |
234 | retval |= NOUVEAU_DSM_HAS_OPT; | 259 | retval |= NOUVEAU_DSM_HAS_OPT; |
235 | 260 | ||
236 | if (retval) | 261 | if (retval) |
@@ -269,15 +294,22 @@ static bool nouveau_dsm_detect(void) | |||
269 | } | 294 | } |
270 | 295 | ||
271 | if (vga_count == 2 && has_dsm && guid_valid) { | 296 | if (vga_count == 2 && has_dsm && guid_valid) { |
272 | acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer); | 297 | acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, |
298 | &buffer); | ||
273 | printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", | 299 | printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n", |
274 | acpi_method_name); | 300 | acpi_method_name); |
275 | nouveau_dsm_priv.dsm_detected = true; | 301 | nouveau_dsm_priv.dsm_detected = true; |
276 | ret = true; | 302 | ret = true; |
277 | } | 303 | } |
278 | 304 | ||
279 | if (has_optimus == 1) | 305 | if (has_optimus == 1) { |
306 | acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, | ||
307 | &buffer); | ||
308 | printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n", | ||
309 | acpi_method_name); | ||
280 | nouveau_dsm_priv.optimus_detected = true; | 310 | nouveau_dsm_priv.optimus_detected = true; |
311 | ret = true; | ||
312 | } | ||
281 | 313 | ||
282 | return ret; | 314 | return ret; |
283 | } | 315 | } |
@@ -293,6 +325,17 @@ void nouveau_register_dsm_handler(void) | |||
293 | vga_switcheroo_register_handler(&nouveau_dsm_handler); | 325 | vga_switcheroo_register_handler(&nouveau_dsm_handler); |
294 | } | 326 | } |
295 | 327 | ||
328 | /* Must be called for Optimus models before the card can be turned off */ | ||
329 | void nouveau_switcheroo_optimus_dsm(void) | ||
330 | { | ||
331 | u32 result = 0; | ||
332 | if (!nouveau_dsm_priv.optimus_detected) | ||
333 | return; | ||
334 | |||
335 | nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FN, | ||
336 | NOUVEAU_DSM_OPTIMUS_ARGS, &result); | ||
337 | } | ||
338 | |||
296 | void nouveau_unregister_dsm_handler(void) | 339 | void nouveau_unregister_dsm_handler(void) |
297 | { | 340 | { |
298 | vga_switcheroo_unregister_handler(); | 341 | vga_switcheroo_unregister_handler(); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 38134a9c7578..b82709828931 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -1055,12 +1055,14 @@ extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); | |||
1055 | #if defined(CONFIG_ACPI) | 1055 | #if defined(CONFIG_ACPI) |
1056 | void nouveau_register_dsm_handler(void); | 1056 | void nouveau_register_dsm_handler(void); |
1057 | void nouveau_unregister_dsm_handler(void); | 1057 | void nouveau_unregister_dsm_handler(void); |
1058 | void nouveau_switcheroo_optimus_dsm(void); | ||
1058 | int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); | 1059 | int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len); |
1059 | bool nouveau_acpi_rom_supported(struct pci_dev *pdev); | 1060 | bool nouveau_acpi_rom_supported(struct pci_dev *pdev); |
1060 | int nouveau_acpi_edid(struct drm_device *, struct drm_connector *); | 1061 | int nouveau_acpi_edid(struct drm_device *, struct drm_connector *); |
1061 | #else | 1062 | #else |
1062 | static inline void nouveau_register_dsm_handler(void) {} | 1063 | static inline void nouveau_register_dsm_handler(void) {} |
1063 | static inline void nouveau_unregister_dsm_handler(void) {} | 1064 | static inline void nouveau_unregister_dsm_handler(void) {} |
1065 | static inline void nouveau_switcheroo_optimus_dsm(void) {} | ||
1064 | static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } | 1066 | static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; } |
1065 | static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } | 1067 | static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; } |
1066 | static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; } | 1068 | static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index f5e98910d17f..f80c5e0762ff 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -525,6 +525,7 @@ static void nouveau_switcheroo_set_state(struct pci_dev *pdev, | |||
525 | printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); | 525 | printk(KERN_ERR "VGA switcheroo: switched nouveau off\n"); |
526 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; | 526 | dev->switch_power_state = DRM_SWITCH_POWER_CHANGING; |
527 | drm_kms_helper_poll_disable(dev); | 527 | drm_kms_helper_poll_disable(dev); |
528 | nouveau_switcheroo_optimus_dsm(); | ||
528 | nouveau_pci_suspend(pdev, pmm); | 529 | nouveau_pci_suspend(pdev, pmm); |
529 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; | 530 | dev->switch_power_state = DRM_SWITCH_POWER_OFF; |
530 | } | 531 | } |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index f7442e62c03f..8e8cd85e5c00 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -1793,10 +1793,12 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | |||
1793 | ret = -EINVAL; | 1793 | ret = -EINVAL; |
1794 | break; | 1794 | break; |
1795 | case PACKET_TYPE2: | 1795 | case PACKET_TYPE2: |
1796 | idx += 1; | ||
1796 | break; | 1797 | break; |
1797 | case PACKET_TYPE3: | 1798 | case PACKET_TYPE3: |
1798 | pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]); | 1799 | pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]); |
1799 | ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt); | 1800 | ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt); |
1801 | idx += pkt.count + 2; | ||
1800 | break; | 1802 | break; |
1801 | default: | 1803 | default: |
1802 | dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type); | 1804 | dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type); |
@@ -1805,7 +1807,6 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) | |||
1805 | } | 1807 | } |
1806 | if (ret) | 1808 | if (ret) |
1807 | break; | 1809 | break; |
1808 | idx += pkt.count + 2; | ||
1809 | } while (idx < ib->length_dw); | 1810 | } while (idx < ib->length_dw); |
1810 | 1811 | ||
1811 | return ret; | 1812 | return ret; |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 3ec81c3d5108..bfd36ab643a6 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -2186,7 +2186,6 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) | |||
2186 | void r100_bm_disable(struct radeon_device *rdev) | 2186 | void r100_bm_disable(struct radeon_device *rdev) |
2187 | { | 2187 | { |
2188 | u32 tmp; | 2188 | u32 tmp; |
2189 | u16 tmp16; | ||
2190 | 2189 | ||
2191 | /* disable bus mastering */ | 2190 | /* disable bus mastering */ |
2192 | tmp = RREG32(R_000030_BUS_CNTL); | 2191 | tmp = RREG32(R_000030_BUS_CNTL); |
@@ -2197,8 +2196,7 @@ void r100_bm_disable(struct radeon_device *rdev) | |||
2197 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040); | 2196 | WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040); |
2198 | tmp = RREG32(RADEON_BUS_CNTL); | 2197 | tmp = RREG32(RADEON_BUS_CNTL); |
2199 | mdelay(1); | 2198 | mdelay(1); |
2200 | pci_read_config_word(rdev->pdev, 0x4, &tmp16); | 2199 | pci_clear_master(rdev->pdev); |
2201 | pci_write_config_word(rdev->pdev, 0x4, tmp16 & 0xFFFB); | ||
2202 | mdelay(1); | 2200 | mdelay(1); |
2203 | } | 2201 | } |
2204 | 2202 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 31da622eef63..8032f1fedb11 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -145,7 +145,7 @@ module_param_named(vramlimit, radeon_vram_limit, int, 0600); | |||
145 | MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)"); | 145 | MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)"); |
146 | module_param_named(agpmode, radeon_agpmode, int, 0444); | 146 | module_param_named(agpmode, radeon_agpmode, int, 0444); |
147 | 147 | ||
148 | MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32,64, etc)\n"); | 148 | MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc)"); |
149 | module_param_named(gartsize, radeon_gart_size, int, 0600); | 149 | module_param_named(gartsize, radeon_gart_size, int, 0600); |
150 | 150 | ||
151 | MODULE_PARM_DESC(benchmark, "Run benchmark"); | 151 | MODULE_PARM_DESC(benchmark, "Run benchmark"); |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 803e0d3c1773..ec46eb45e34c 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -322,16 +322,6 @@ void rs600_hpd_fini(struct radeon_device *rdev) | |||
322 | } | 322 | } |
323 | } | 323 | } |
324 | 324 | ||
325 | void rs600_bm_disable(struct radeon_device *rdev) | ||
326 | { | ||
327 | u16 tmp; | ||
328 | |||
329 | /* disable bus mastering */ | ||
330 | pci_read_config_word(rdev->pdev, 0x4, &tmp); | ||
331 | pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB); | ||
332 | mdelay(1); | ||
333 | } | ||
334 | |||
335 | int rs600_asic_reset(struct radeon_device *rdev) | 325 | int rs600_asic_reset(struct radeon_device *rdev) |
336 | { | 326 | { |
337 | struct rv515_mc_save save; | 327 | struct rv515_mc_save save; |
@@ -355,7 +345,8 @@ int rs600_asic_reset(struct radeon_device *rdev) | |||
355 | WREG32(RADEON_CP_RB_CNTL, tmp); | 345 | WREG32(RADEON_CP_RB_CNTL, tmp); |
356 | pci_save_state(rdev->pdev); | 346 | pci_save_state(rdev->pdev); |
357 | /* disable bus mastering */ | 347 | /* disable bus mastering */ |
358 | rs600_bm_disable(rdev); | 348 | pci_clear_master(rdev->pdev); |
349 | mdelay(1); | ||
359 | /* reset GA+VAP */ | 350 | /* reset GA+VAP */ |
360 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) | | 351 | WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) | |
361 | S_0000F0_SOFT_RESET_GA(1)); | 352 | S_0000F0_SOFT_RESET_GA(1)); |
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c index 37ead6995c87..0c46d8cdc6ea 100644 --- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c | |||
@@ -952,10 +952,9 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev) | |||
952 | 952 | ||
953 | type = ttm_to_type(ttm->page_flags, ttm->caching_state); | 953 | type = ttm_to_type(ttm->page_flags, ttm->caching_state); |
954 | pool = ttm_dma_find_pool(dev, type); | 954 | pool = ttm_dma_find_pool(dev, type); |
955 | if (!pool) { | 955 | if (!pool) |
956 | WARN_ON(!pool); | ||
957 | return; | 956 | return; |
958 | } | 957 | |
959 | is_cached = (ttm_dma_find_pool(pool->dev, | 958 | is_cached = (ttm_dma_find_pool(pool->dev, |
960 | ttm_to_type(ttm->page_flags, tt_cached)) == pool); | 959 | ttm_to_type(ttm->page_flags, tt_cached)) == pool); |
961 | 960 | ||
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c index b6807db7b36f..e66d248fc126 100644 --- a/drivers/i2c/busses/i2c-ali1535.c +++ b/drivers/i2c/busses/i2c-ali1535.c | |||
@@ -132,7 +132,8 @@ | |||
132 | #define ALI1535_SMBIO_EN 0x04 /* SMB I/O Space enable */ | 132 | #define ALI1535_SMBIO_EN 0x04 /* SMB I/O Space enable */ |
133 | 133 | ||
134 | static struct pci_driver ali1535_driver; | 134 | static struct pci_driver ali1535_driver; |
135 | static unsigned short ali1535_smba; | 135 | static unsigned long ali1535_smba; |
136 | static unsigned short ali1535_offset; | ||
136 | 137 | ||
137 | /* Detect whether a ALI1535 can be found, and initialize it, where necessary. | 138 | /* Detect whether a ALI1535 can be found, and initialize it, where necessary. |
138 | Note the differences between kernels with the old PCI BIOS interface and | 139 | Note the differences between kernels with the old PCI BIOS interface and |
@@ -140,7 +141,7 @@ static unsigned short ali1535_smba; | |||
140 | defined to make the transition easier. */ | 141 | defined to make the transition easier. */ |
141 | static int __devinit ali1535_setup(struct pci_dev *dev) | 142 | static int __devinit ali1535_setup(struct pci_dev *dev) |
142 | { | 143 | { |
143 | int retval = -ENODEV; | 144 | int retval; |
144 | unsigned char temp; | 145 | unsigned char temp; |
145 | 146 | ||
146 | /* Check the following things: | 147 | /* Check the following things: |
@@ -149,15 +150,28 @@ static int __devinit ali1535_setup(struct pci_dev *dev) | |||
149 | - We can use the addresses | 150 | - We can use the addresses |
150 | */ | 151 | */ |
151 | 152 | ||
153 | retval = pci_enable_device(dev); | ||
154 | if (retval) { | ||
155 | dev_err(&dev->dev, "ALI1535_smb can't enable device\n"); | ||
156 | goto exit; | ||
157 | } | ||
158 | |||
152 | /* Determine the address of the SMBus area */ | 159 | /* Determine the address of the SMBus area */ |
153 | pci_read_config_word(dev, SMBBA, &ali1535_smba); | 160 | pci_read_config_word(dev, SMBBA, &ali1535_offset); |
154 | ali1535_smba &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1)); | 161 | dev_dbg(&dev->dev, "ALI1535_smb is at offset 0x%04x\n", ali1535_offset); |
155 | if (ali1535_smba == 0) { | 162 | ali1535_offset &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1)); |
163 | if (ali1535_offset == 0) { | ||
156 | dev_warn(&dev->dev, | 164 | dev_warn(&dev->dev, |
157 | "ALI1535_smb region uninitialized - upgrade BIOS?\n"); | 165 | "ALI1535_smb region uninitialized - upgrade BIOS?\n"); |
166 | retval = -ENODEV; | ||
158 | goto exit; | 167 | goto exit; |
159 | } | 168 | } |
160 | 169 | ||
170 | if (pci_resource_flags(dev, 0) & IORESOURCE_IO) | ||
171 | ali1535_smba = pci_resource_start(dev, 0) + ali1535_offset; | ||
172 | else | ||
173 | ali1535_smba = ali1535_offset; | ||
174 | |||
161 | retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE, | 175 | retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE, |
162 | ali1535_driver.name); | 176 | ali1535_driver.name); |
163 | if (retval) | 177 | if (retval) |
@@ -165,8 +179,9 @@ static int __devinit ali1535_setup(struct pci_dev *dev) | |||
165 | 179 | ||
166 | if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, | 180 | if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE, |
167 | ali1535_driver.name)) { | 181 | ali1535_driver.name)) { |
168 | dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n", | 182 | dev_err(&dev->dev, "ALI1535_smb region 0x%lx already in use!\n", |
169 | ali1535_smba); | 183 | ali1535_smba); |
184 | retval = -EBUSY; | ||
170 | goto exit; | 185 | goto exit; |
171 | } | 186 | } |
172 | 187 | ||
@@ -174,6 +189,7 @@ static int __devinit ali1535_setup(struct pci_dev *dev) | |||
174 | pci_read_config_byte(dev, SMBCFG, &temp); | 189 | pci_read_config_byte(dev, SMBCFG, &temp); |
175 | if ((temp & ALI1535_SMBIO_EN) == 0) { | 190 | if ((temp & ALI1535_SMBIO_EN) == 0) { |
176 | dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n"); | 191 | dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n"); |
192 | retval = -ENODEV; | ||
177 | goto exit_free; | 193 | goto exit_free; |
178 | } | 194 | } |
179 | 195 | ||
@@ -181,6 +197,7 @@ static int __devinit ali1535_setup(struct pci_dev *dev) | |||
181 | pci_read_config_byte(dev, SMBHSTCFG, &temp); | 197 | pci_read_config_byte(dev, SMBHSTCFG, &temp); |
182 | if ((temp & 1) == 0) { | 198 | if ((temp & 1) == 0) { |
183 | dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n"); | 199 | dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n"); |
200 | retval = -ENODEV; | ||
184 | goto exit_free; | 201 | goto exit_free; |
185 | } | 202 | } |
186 | 203 | ||
@@ -196,14 +213,13 @@ static int __devinit ali1535_setup(struct pci_dev *dev) | |||
196 | */ | 213 | */ |
197 | pci_read_config_byte(dev, SMBREV, &temp); | 214 | pci_read_config_byte(dev, SMBREV, &temp); |
198 | dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); | 215 | dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp); |
199 | dev_dbg(&dev->dev, "ALI1535_smba = 0x%X\n", ali1535_smba); | 216 | dev_dbg(&dev->dev, "ALI1535_smba = 0x%lx\n", ali1535_smba); |
200 | 217 | ||
201 | retval = 0; | 218 | return 0; |
202 | exit: | ||
203 | return retval; | ||
204 | 219 | ||
205 | exit_free: | 220 | exit_free: |
206 | release_region(ali1535_smba, ALI1535_SMB_IOSIZE); | 221 | release_region(ali1535_smba, ALI1535_SMB_IOSIZE); |
222 | exit: | ||
207 | return retval; | 223 | return retval; |
208 | } | 224 | } |
209 | 225 | ||
@@ -498,7 +514,7 @@ static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_ | |||
498 | ali1535_adapter.dev.parent = &dev->dev; | 514 | ali1535_adapter.dev.parent = &dev->dev; |
499 | 515 | ||
500 | snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name), | 516 | snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name), |
501 | "SMBus ALI1535 adapter at %04x", ali1535_smba); | 517 | "SMBus ALI1535 adapter at %04x", ali1535_offset); |
502 | return i2c_add_adapter(&ali1535_adapter); | 518 | return i2c_add_adapter(&ali1535_adapter); |
503 | } | 519 | } |
504 | 520 | ||
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c index a409cfcf0629..47ae0091e027 100644 --- a/drivers/i2c/busses/i2c-ali1563.c +++ b/drivers/i2c/busses/i2c-ali1563.c | |||
@@ -417,7 +417,7 @@ static void __devexit ali1563_remove(struct pci_dev * dev) | |||
417 | ali1563_shutdown(dev); | 417 | ali1563_shutdown(dev); |
418 | } | 418 | } |
419 | 419 | ||
420 | static const struct pci_device_id ali1563_id_table[] __devinitconst = { | 420 | static DEFINE_PCI_DEVICE_TABLE(ali1563_id_table) = { |
421 | { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) }, | 421 | { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) }, |
422 | {}, | 422 | {}, |
423 | }; | 423 | }; |
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c index 83e8a60cdc86..087ea9caa74d 100644 --- a/drivers/i2c/busses/i2c-ali15x3.c +++ b/drivers/i2c/busses/i2c-ali15x3.c | |||
@@ -477,7 +477,7 @@ static struct i2c_adapter ali15x3_adapter = { | |||
477 | .algo = &smbus_algorithm, | 477 | .algo = &smbus_algorithm, |
478 | }; | 478 | }; |
479 | 479 | ||
480 | static const struct pci_device_id ali15x3_ids[] = { | 480 | static DEFINE_PCI_DEVICE_TABLE(ali15x3_ids) = { |
481 | { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) }, | 481 | { PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) }, |
482 | { 0, } | 482 | { 0, } |
483 | }; | 483 | }; |
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c index 03bcd07c4697..eb778bf15c18 100644 --- a/drivers/i2c/busses/i2c-amd756.c +++ b/drivers/i2c/busses/i2c-amd756.c | |||
@@ -308,7 +308,7 @@ static const char* chipname[] = { | |||
308 | "nVidia nForce", "AMD8111", | 308 | "nVidia nForce", "AMD8111", |
309 | }; | 309 | }; |
310 | 310 | ||
311 | static const struct pci_device_id amd756_ids[] = { | 311 | static DEFINE_PCI_DEVICE_TABLE(amd756_ids) = { |
312 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B), | 312 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B), |
313 | .driver_data = AMD756 }, | 313 | .driver_data = AMD756 }, |
314 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413), | 314 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413), |
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c index 6b6a6b1d7025..e5ac53b99b04 100644 --- a/drivers/i2c/busses/i2c-amd8111.c +++ b/drivers/i2c/busses/i2c-amd8111.c | |||
@@ -415,7 +415,7 @@ static const struct i2c_algorithm smbus_algorithm = { | |||
415 | }; | 415 | }; |
416 | 416 | ||
417 | 417 | ||
418 | static const struct pci_device_id amd8111_ids[] = { | 418 | static DEFINE_PCI_DEVICE_TABLE(amd8111_ids) = { |
419 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) }, | 419 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) }, |
420 | { 0, } | 420 | { 0, } |
421 | }; | 421 | }; |
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 305c07504f7e..1679deef9c89 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c | |||
@@ -295,9 +295,6 @@ static int at91_i2c_resume(struct platform_device *pdev) | |||
295 | #define at91_i2c_resume NULL | 295 | #define at91_i2c_resume NULL |
296 | #endif | 296 | #endif |
297 | 297 | ||
298 | /* work with "modprobe at91_i2c" from hotplugging or coldplugging */ | ||
299 | MODULE_ALIAS("platform:at91_i2c"); | ||
300 | |||
301 | static struct platform_driver at91_i2c_driver = { | 298 | static struct platform_driver at91_i2c_driver = { |
302 | .probe = at91_i2c_probe, | 299 | .probe = at91_i2c_probe, |
303 | .remove = __devexit_p(at91_i2c_remove), | 300 | .remove = __devexit_p(at91_i2c_remove), |
@@ -309,19 +306,9 @@ static struct platform_driver at91_i2c_driver = { | |||
309 | }, | 306 | }, |
310 | }; | 307 | }; |
311 | 308 | ||
312 | static int __init at91_i2c_init(void) | 309 | module_platform_driver(at91_i2c_driver); |
313 | { | ||
314 | return platform_driver_register(&at91_i2c_driver); | ||
315 | } | ||
316 | |||
317 | static void __exit at91_i2c_exit(void) | ||
318 | { | ||
319 | platform_driver_unregister(&at91_i2c_driver); | ||
320 | } | ||
321 | |||
322 | module_init(at91_i2c_init); | ||
323 | module_exit(at91_i2c_exit); | ||
324 | 310 | ||
325 | MODULE_AUTHOR("Rick Bronson"); | 311 | MODULE_AUTHOR("Rick Bronson"); |
326 | MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91"); | 312 | MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91"); |
327 | MODULE_LICENSE("GPL"); | 313 | MODULE_LICENSE("GPL"); |
314 | MODULE_ALIAS("platform:at91_i2c"); | ||
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c index f314d7f433d3..582d616db346 100644 --- a/drivers/i2c/busses/i2c-au1550.c +++ b/drivers/i2c/busses/i2c-au1550.c | |||
@@ -426,20 +426,9 @@ static struct platform_driver au1xpsc_smbus_driver = { | |||
426 | .remove = __devexit_p(i2c_au1550_remove), | 426 | .remove = __devexit_p(i2c_au1550_remove), |
427 | }; | 427 | }; |
428 | 428 | ||
429 | static int __init i2c_au1550_init(void) | 429 | module_platform_driver(au1xpsc_smbus_driver); |
430 | { | ||
431 | return platform_driver_register(&au1xpsc_smbus_driver); | ||
432 | } | ||
433 | |||
434 | static void __exit i2c_au1550_exit(void) | ||
435 | { | ||
436 | platform_driver_unregister(&au1xpsc_smbus_driver); | ||
437 | } | ||
438 | 430 | ||
439 | MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); | 431 | MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC."); |
440 | MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550"); | 432 | MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550"); |
441 | MODULE_LICENSE("GPL"); | 433 | MODULE_LICENSE("GPL"); |
442 | MODULE_ALIAS("platform:au1xpsc_smbus"); | 434 | MODULE_ALIAS("platform:au1xpsc_smbus"); |
443 | |||
444 | module_init (i2c_au1550_init); | ||
445 | module_exit (i2c_au1550_exit); | ||
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c index b1d9cd28d8da..c1e1096ba069 100644 --- a/drivers/i2c/busses/i2c-cpm.c +++ b/drivers/i2c/busses/i2c-cpm.c | |||
@@ -724,18 +724,7 @@ static struct platform_driver cpm_i2c_driver = { | |||
724 | }, | 724 | }, |
725 | }; | 725 | }; |
726 | 726 | ||
727 | static int __init cpm_i2c_init(void) | 727 | module_platform_driver(cpm_i2c_driver); |
728 | { | ||
729 | return platform_driver_register(&cpm_i2c_driver); | ||
730 | } | ||
731 | |||
732 | static void __exit cpm_i2c_exit(void) | ||
733 | { | ||
734 | platform_driver_unregister(&cpm_i2c_driver); | ||
735 | } | ||
736 | |||
737 | module_init(cpm_i2c_init); | ||
738 | module_exit(cpm_i2c_exit); | ||
739 | 728 | ||
740 | MODULE_AUTHOR("Jochen Friedrich <jochen@scram.de>"); | 729 | MODULE_AUTHOR("Jochen Friedrich <jochen@scram.de>"); |
741 | MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards"); | 730 | MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards"); |
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c index 9e89e7313d62..37f42113af31 100644 --- a/drivers/i2c/busses/i2c-designware-pcidrv.c +++ b/drivers/i2c/busses/i2c-designware-pcidrv.c | |||
@@ -349,7 +349,7 @@ static void __devexit i2c_dw_pci_remove(struct pci_dev *pdev) | |||
349 | /* work with hotplug and coldplug */ | 349 | /* work with hotplug and coldplug */ |
350 | MODULE_ALIAS("i2c_designware-pci"); | 350 | MODULE_ALIAS("i2c_designware-pci"); |
351 | 351 | ||
352 | DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = { | 352 | static DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = { |
353 | /* Moorestown */ | 353 | /* Moorestown */ |
354 | { PCI_VDEVICE(INTEL, 0x0802), moorestown_0 }, | 354 | { PCI_VDEVICE(INTEL, 0x0802), moorestown_0 }, |
355 | { PCI_VDEVICE(INTEL, 0x0803), moorestown_1 }, | 355 | { PCI_VDEVICE(INTEL, 0x0803), moorestown_1 }, |
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c index 18936ac9d51c..3ef3557b6e32 100644 --- a/drivers/i2c/busses/i2c-eg20t.c +++ b/drivers/i2c/busses/i2c-eg20t.c | |||
@@ -185,7 +185,7 @@ static DEFINE_MUTEX(pch_mutex); | |||
185 | #define PCI_DEVICE_ID_ML7213_I2C 0x802D | 185 | #define PCI_DEVICE_ID_ML7213_I2C 0x802D |
186 | #define PCI_DEVICE_ID_ML7223_I2C 0x8010 | 186 | #define PCI_DEVICE_ID_ML7223_I2C 0x8010 |
187 | 187 | ||
188 | static struct pci_device_id __devinitdata pch_pcidev_id[] = { | 188 | static DEFINE_PCI_DEVICE_TABLE(pch_pcidev_id) = { |
189 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C), 1, }, | 189 | { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C), 1, }, |
190 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, }, | 190 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, }, |
191 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_I2C), 1, }, | 191 | { PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_I2C), 1, }, |
diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c index fa88868cb556..19515df61021 100644 --- a/drivers/i2c/busses/i2c-highlander.c +++ b/drivers/i2c/busses/i2c-highlander.c | |||
@@ -468,18 +468,7 @@ static struct platform_driver highlander_i2c_driver = { | |||
468 | .remove = __devexit_p(highlander_i2c_remove), | 468 | .remove = __devexit_p(highlander_i2c_remove), |
469 | }; | 469 | }; |
470 | 470 | ||
471 | static int __init highlander_i2c_init(void) | 471 | module_platform_driver(highlander_i2c_driver); |
472 | { | ||
473 | return platform_driver_register(&highlander_i2c_driver); | ||
474 | } | ||
475 | |||
476 | static void __exit highlander_i2c_exit(void) | ||
477 | { | ||
478 | platform_driver_unregister(&highlander_i2c_driver); | ||
479 | } | ||
480 | |||
481 | module_init(highlander_i2c_init); | ||
482 | module_exit(highlander_i2c_exit); | ||
483 | 472 | ||
484 | MODULE_AUTHOR("Paul Mundt"); | 473 | MODULE_AUTHOR("Paul Mundt"); |
485 | MODULE_DESCRIPTION("Renesas Highlander FPGA I2C/SMBus adapter"); | 474 | MODULE_DESCRIPTION("Renesas Highlander FPGA I2C/SMBus adapter"); |
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c index 9ff1695d8458..c527de17db4f 100644 --- a/drivers/i2c/busses/i2c-hydra.c +++ b/drivers/i2c/busses/i2c-hydra.c | |||
@@ -105,7 +105,7 @@ static struct i2c_adapter hydra_adap = { | |||
105 | .algo_data = &hydra_bit_data, | 105 | .algo_data = &hydra_bit_data, |
106 | }; | 106 | }; |
107 | 107 | ||
108 | static const struct pci_device_id hydra_ids[] = { | 108 | static DEFINE_PCI_DEVICE_TABLE(hydra_ids) = { |
109 | { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) }, | 109 | { PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) }, |
110 | { 0, } | 110 | { 0, } |
111 | }; | 111 | }; |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index ab26840d0c70..5d2e2816831f 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -609,7 +609,7 @@ static const struct i2c_algorithm smbus_algorithm = { | |||
609 | .functionality = i801_func, | 609 | .functionality = i801_func, |
610 | }; | 610 | }; |
611 | 611 | ||
612 | static const struct pci_device_id i801_ids[] = { | 612 | static DEFINE_PCI_DEVICE_TABLE(i801_ids) = { |
613 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) }, | 613 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) }, |
614 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) }, | 614 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) }, |
615 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) }, | 615 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) }, |
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c index c08ceb957aa7..806e225f3de7 100644 --- a/drivers/i2c/busses/i2c-ibm_iic.c +++ b/drivers/i2c/busses/i2c-ibm_iic.c | |||
@@ -815,15 +815,4 @@ static struct platform_driver ibm_iic_driver = { | |||
815 | .remove = __devexit_p(iic_remove), | 815 | .remove = __devexit_p(iic_remove), |
816 | }; | 816 | }; |
817 | 817 | ||
818 | static int __init iic_init(void) | 818 | module_platform_driver(ibm_iic_driver); |
819 | { | ||
820 | return platform_driver_register(&ibm_iic_driver); | ||
821 | } | ||
822 | |||
823 | static void __exit iic_exit(void) | ||
824 | { | ||
825 | platform_driver_unregister(&ibm_iic_driver); | ||
826 | } | ||
827 | |||
828 | module_init(iic_init); | ||
829 | module_exit(iic_exit); | ||
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c index e828ac85cfa7..365bad5b890b 100644 --- a/drivers/i2c/busses/i2c-intel-mid.c +++ b/drivers/i2c/busses/i2c-intel-mid.c | |||
@@ -1093,7 +1093,7 @@ static void __devexit intel_mid_i2c_remove(struct pci_dev *dev) | |||
1093 | pci_release_region(dev, 0); | 1093 | pci_release_region(dev, 0); |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | static struct pci_device_id intel_mid_i2c_ids[] = { | 1096 | static DEFINE_PCI_DEVICE_TABLE(intel_mid_i2c_ids) = { |
1097 | /* Moorestown */ | 1097 | /* Moorestown */ |
1098 | { PCI_VDEVICE(INTEL, 0x0802), 0 }, | 1098 | { PCI_VDEVICE(INTEL, 0x0802), 0 }, |
1099 | { PCI_VDEVICE(INTEL, 0x0803), 1 }, | 1099 | { PCI_VDEVICE(INTEL, 0x0803), 1 }, |
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c index f09c9319a2ba..93f147a96b62 100644 --- a/drivers/i2c/busses/i2c-iop3xx.c +++ b/drivers/i2c/busses/i2c-iop3xx.c | |||
@@ -523,21 +523,7 @@ static struct platform_driver iop3xx_i2c_driver = { | |||
523 | }, | 523 | }, |
524 | }; | 524 | }; |
525 | 525 | ||
526 | static int __init | 526 | module_platform_driver(iop3xx_i2c_driver); |
527 | i2c_iop3xx_init (void) | ||
528 | { | ||
529 | return platform_driver_register(&iop3xx_i2c_driver); | ||
530 | } | ||
531 | |||
532 | static void __exit | ||
533 | i2c_iop3xx_exit (void) | ||
534 | { | ||
535 | platform_driver_unregister(&iop3xx_i2c_driver); | ||
536 | return; | ||
537 | } | ||
538 | |||
539 | module_init (i2c_iop3xx_init); | ||
540 | module_exit (i2c_iop3xx_exit); | ||
541 | 527 | ||
542 | MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>"); | 528 | MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>"); |
543 | MODULE_DESCRIPTION("IOP3xx iic algorithm and driver"); | 529 | MODULE_DESCRIPTION("IOP3xx iic algorithm and driver"); |
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c index 0682f8f277b0..6561d275b8cf 100644 --- a/drivers/i2c/busses/i2c-isch.c +++ b/drivers/i2c/busses/i2c-isch.c | |||
@@ -306,20 +306,9 @@ static struct platform_driver smbus_sch_driver = { | |||
306 | .remove = __devexit_p(smbus_sch_remove), | 306 | .remove = __devexit_p(smbus_sch_remove), |
307 | }; | 307 | }; |
308 | 308 | ||
309 | static int __init i2c_sch_init(void) | 309 | module_platform_driver(smbus_sch_driver); |
310 | { | ||
311 | return platform_driver_register(&smbus_sch_driver); | ||
312 | } | ||
313 | |||
314 | static void __exit i2c_sch_exit(void) | ||
315 | { | ||
316 | platform_driver_unregister(&smbus_sch_driver); | ||
317 | } | ||
318 | 310 | ||
319 | MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>"); | 311 | MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>"); |
320 | MODULE_DESCRIPTION("Intel SCH SMBus driver"); | 312 | MODULE_DESCRIPTION("Intel SCH SMBus driver"); |
321 | MODULE_LICENSE("GPL"); | 313 | MODULE_LICENSE("GPL"); |
322 | |||
323 | module_init(i2c_sch_init); | ||
324 | module_exit(i2c_sch_exit); | ||
325 | MODULE_ALIAS("platform:isch_smbus"); | 314 | MODULE_ALIAS("platform:isch_smbus"); |
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c index c01e9519f6c1..5d263f9014d6 100644 --- a/drivers/i2c/busses/i2c-ixp2000.c +++ b/drivers/i2c/busses/i2c-ixp2000.c | |||
@@ -148,18 +148,7 @@ static struct platform_driver ixp2000_i2c_driver = { | |||
148 | }, | 148 | }, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static int __init ixp2000_i2c_init(void) | 151 | module_platform_driver(ixp2000_i2c_driver); |
152 | { | ||
153 | return platform_driver_register(&ixp2000_i2c_driver); | ||
154 | } | ||
155 | |||
156 | static void __exit ixp2000_i2c_exit(void) | ||
157 | { | ||
158 | platform_driver_unregister(&ixp2000_i2c_driver); | ||
159 | } | ||
160 | |||
161 | module_init(ixp2000_i2c_init); | ||
162 | module_exit(ixp2000_i2c_exit); | ||
163 | 152 | ||
164 | MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>"); | 153 | MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>"); |
165 | MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver"); | 154 | MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver"); |
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index 107397a606b4..a8ebb84e23f9 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c | |||
@@ -715,18 +715,7 @@ static struct platform_driver mpc_i2c_driver = { | |||
715 | }, | 715 | }, |
716 | }; | 716 | }; |
717 | 717 | ||
718 | static int __init fsl_i2c_init(void) | 718 | module_platform_driver(mpc_i2c_driver); |
719 | { | ||
720 | return platform_driver_register(&mpc_i2c_driver); | ||
721 | } | ||
722 | |||
723 | static void __exit fsl_i2c_exit(void) | ||
724 | { | ||
725 | platform_driver_unregister(&mpc_i2c_driver); | ||
726 | } | ||
727 | |||
728 | module_init(fsl_i2c_init); | ||
729 | module_exit(fsl_i2c_exit); | ||
730 | 719 | ||
731 | MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); | 720 | MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); |
732 | MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and " | 721 | MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and " |
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c index a9941c65f226..4f44a33017b0 100644 --- a/drivers/i2c/busses/i2c-mv64xxx.c +++ b/drivers/i2c/busses/i2c-mv64xxx.c | |||
@@ -611,20 +611,7 @@ static struct platform_driver mv64xxx_i2c_driver = { | |||
611 | }, | 611 | }, |
612 | }; | 612 | }; |
613 | 613 | ||
614 | static int __init | 614 | module_platform_driver(mv64xxx_i2c_driver); |
615 | mv64xxx_i2c_init(void) | ||
616 | { | ||
617 | return platform_driver_register(&mv64xxx_i2c_driver); | ||
618 | } | ||
619 | |||
620 | static void __exit | ||
621 | mv64xxx_i2c_exit(void) | ||
622 | { | ||
623 | platform_driver_unregister(&mv64xxx_i2c_driver); | ||
624 | } | ||
625 | |||
626 | module_init(mv64xxx_i2c_init); | ||
627 | module_exit(mv64xxx_i2c_exit); | ||
628 | 615 | ||
629 | MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>"); | 616 | MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>"); |
630 | MODULE_DESCRIPTION("Marvell mv64xxx host bridge i2c ctlr driver"); | 617 | MODULE_DESCRIPTION("Marvell mv64xxx host bridge i2c ctlr driver"); |
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c index ff1e127dfea8..43a96a123920 100644 --- a/drivers/i2c/busses/i2c-nforce2.c +++ b/drivers/i2c/busses/i2c-nforce2.c | |||
@@ -309,7 +309,7 @@ static struct i2c_algorithm smbus_algorithm = { | |||
309 | }; | 309 | }; |
310 | 310 | ||
311 | 311 | ||
312 | static const struct pci_device_id nforce2_ids[] = { | 312 | static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = { |
313 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) }, | 313 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) }, |
314 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) }, | 314 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) }, |
315 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, | 315 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) }, |
@@ -356,7 +356,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar, | |||
356 | error = acpi_check_region(smbus->base, smbus->size, | 356 | error = acpi_check_region(smbus->base, smbus->size, |
357 | nforce2_driver.name); | 357 | nforce2_driver.name); |
358 | if (error) | 358 | if (error) |
359 | return -1; | 359 | return error; |
360 | 360 | ||
361 | if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { | 361 | if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) { |
362 | dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", | 362 | dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n", |
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c index 1b46a9d9f907..18068dee48f1 100644 --- a/drivers/i2c/busses/i2c-ocores.c +++ b/drivers/i2c/busses/i2c-ocores.c | |||
@@ -394,9 +394,6 @@ static struct of_device_id ocores_i2c_match[] = { | |||
394 | }; | 394 | }; |
395 | MODULE_DEVICE_TABLE(of, ocores_i2c_match); | 395 | MODULE_DEVICE_TABLE(of, ocores_i2c_match); |
396 | 396 | ||
397 | /* work with hotplug and coldplug */ | ||
398 | MODULE_ALIAS("platform:ocores-i2c"); | ||
399 | |||
400 | static struct platform_driver ocores_i2c_driver = { | 397 | static struct platform_driver ocores_i2c_driver = { |
401 | .probe = ocores_i2c_probe, | 398 | .probe = ocores_i2c_probe, |
402 | .remove = __devexit_p(ocores_i2c_remove), | 399 | .remove = __devexit_p(ocores_i2c_remove), |
@@ -409,19 +406,9 @@ static struct platform_driver ocores_i2c_driver = { | |||
409 | }, | 406 | }, |
410 | }; | 407 | }; |
411 | 408 | ||
412 | static int __init ocores_i2c_init(void) | 409 | module_platform_driver(ocores_i2c_driver); |
413 | { | ||
414 | return platform_driver_register(&ocores_i2c_driver); | ||
415 | } | ||
416 | |||
417 | static void __exit ocores_i2c_exit(void) | ||
418 | { | ||
419 | platform_driver_unregister(&ocores_i2c_driver); | ||
420 | } | ||
421 | |||
422 | module_init(ocores_i2c_init); | ||
423 | module_exit(ocores_i2c_exit); | ||
424 | 410 | ||
425 | MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>"); | 411 | MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>"); |
426 | MODULE_DESCRIPTION("OpenCores I2C bus driver"); | 412 | MODULE_DESCRIPTION("OpenCores I2C bus driver"); |
427 | MODULE_LICENSE("GPL"); | 413 | MODULE_LICENSE("GPL"); |
414 | MODULE_ALIAS("platform:ocores-i2c"); | ||
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c index 56dbe54e8811..ee139a598814 100644 --- a/drivers/i2c/busses/i2c-octeon.c +++ b/drivers/i2c/busses/i2c-octeon.c | |||
@@ -629,24 +629,10 @@ static struct platform_driver octeon_i2c_driver = { | |||
629 | }, | 629 | }, |
630 | }; | 630 | }; |
631 | 631 | ||
632 | static int __init octeon_i2c_init(void) | 632 | module_platform_driver(octeon_i2c_driver); |
633 | { | ||
634 | int rv; | ||
635 | |||
636 | rv = platform_driver_register(&octeon_i2c_driver); | ||
637 | return rv; | ||
638 | } | ||
639 | |||
640 | static void __exit octeon_i2c_exit(void) | ||
641 | { | ||
642 | platform_driver_unregister(&octeon_i2c_driver); | ||
643 | } | ||
644 | 633 | ||
645 | MODULE_AUTHOR("Michael Lawnick <michael.lawnick.ext@nsn.com>"); | 634 | MODULE_AUTHOR("Michael Lawnick <michael.lawnick.ext@nsn.com>"); |
646 | MODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors"); | 635 | MODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors"); |
647 | MODULE_LICENSE("GPL"); | 636 | MODULE_LICENSE("GPL"); |
648 | MODULE_VERSION(DRV_VERSION); | 637 | MODULE_VERSION(DRV_VERSION); |
649 | MODULE_ALIAS("platform:" DRV_NAME); | 638 | MODULE_ALIAS("platform:" DRV_NAME); |
650 | |||
651 | module_init(octeon_i2c_init); | ||
652 | module_exit(octeon_i2c_exit); | ||
diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c index 837b8c1aa02a..eaaea73209c5 100644 --- a/drivers/i2c/busses/i2c-pasemi.c +++ b/drivers/i2c/busses/i2c-pasemi.c | |||
@@ -401,7 +401,7 @@ static void __devexit pasemi_smb_remove(struct pci_dev *dev) | |||
401 | kfree(smbus); | 401 | kfree(smbus); |
402 | } | 402 | } |
403 | 403 | ||
404 | static const struct pci_device_id pasemi_smb_ids[] = { | 404 | static DEFINE_PCI_DEVICE_TABLE(pasemi_smb_ids) = { |
405 | { PCI_DEVICE(0x1959, 0xa003) }, | 405 | { PCI_DEVICE(0x1959, 0xa003) }, |
406 | { 0, } | 406 | { 0, } |
407 | }; | 407 | }; |
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c index ace67995d7de..2adbf1a8fdea 100644 --- a/drivers/i2c/busses/i2c-pca-platform.c +++ b/drivers/i2c/busses/i2c-pca-platform.c | |||
@@ -286,20 +286,8 @@ static struct platform_driver i2c_pca_pf_driver = { | |||
286 | }, | 286 | }, |
287 | }; | 287 | }; |
288 | 288 | ||
289 | static int __init i2c_pca_pf_init(void) | 289 | module_platform_driver(i2c_pca_pf_driver); |
290 | { | ||
291 | return platform_driver_register(&i2c_pca_pf_driver); | ||
292 | } | ||
293 | |||
294 | static void __exit i2c_pca_pf_exit(void) | ||
295 | { | ||
296 | platform_driver_unregister(&i2c_pca_pf_driver); | ||
297 | } | ||
298 | 290 | ||
299 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); | 291 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); |
300 | MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver"); | 292 | MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver"); |
301 | MODULE_LICENSE("GPL"); | 293 | MODULE_LICENSE("GPL"); |
302 | |||
303 | module_init(i2c_pca_pf_init); | ||
304 | module_exit(i2c_pca_pf_exit); | ||
305 | |||
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c index 6d14ac2e3c41..c14d48dd601a 100644 --- a/drivers/i2c/busses/i2c-piix4.c +++ b/drivers/i2c/busses/i2c-piix4.c | |||
@@ -472,7 +472,7 @@ static struct i2c_adapter piix4_adapter = { | |||
472 | .algo = &smbus_algorithm, | 472 | .algo = &smbus_algorithm, |
473 | }; | 473 | }; |
474 | 474 | ||
475 | static const struct pci_device_id piix4_ids[] = { | 475 | static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = { |
476 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) }, | 476 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) }, |
477 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) }, | 477 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) }, |
478 | { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) }, | 478 | { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) }, |
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index 127051b06921..07b7447ecbc9 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c | |||
@@ -627,9 +627,6 @@ static struct i2c_adapter pmcmsptwi_adapter = { | |||
627 | .name = DRV_NAME, | 627 | .name = DRV_NAME, |
628 | }; | 628 | }; |
629 | 629 | ||
630 | /* work with hotplug and coldplug */ | ||
631 | MODULE_ALIAS("platform:" DRV_NAME); | ||
632 | |||
633 | static struct platform_driver pmcmsptwi_driver = { | 630 | static struct platform_driver pmcmsptwi_driver = { |
634 | .probe = pmcmsptwi_probe, | 631 | .probe = pmcmsptwi_probe, |
635 | .remove = __devexit_p(pmcmsptwi_remove), | 632 | .remove = __devexit_p(pmcmsptwi_remove), |
@@ -639,18 +636,8 @@ static struct platform_driver pmcmsptwi_driver = { | |||
639 | }, | 636 | }, |
640 | }; | 637 | }; |
641 | 638 | ||
642 | static int __init pmcmsptwi_init(void) | 639 | module_platform_driver(pmcmsptwi_driver); |
643 | { | ||
644 | return platform_driver_register(&pmcmsptwi_driver); | ||
645 | } | ||
646 | |||
647 | static void __exit pmcmsptwi_exit(void) | ||
648 | { | ||
649 | platform_driver_unregister(&pmcmsptwi_driver); | ||
650 | } | ||
651 | 640 | ||
652 | MODULE_DESCRIPTION("PMC MSP TWI/SMBus/I2C driver"); | 641 | MODULE_DESCRIPTION("PMC MSP TWI/SMBus/I2C driver"); |
653 | MODULE_LICENSE("GPL"); | 642 | MODULE_LICENSE("GPL"); |
654 | 643 | MODULE_ALIAS("platform:" DRV_NAME); | |
655 | module_init(pmcmsptwi_init); | ||
656 | module_exit(pmcmsptwi_exit); | ||
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index b289ec99eeba..7b397c6f607e 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c | |||
@@ -312,10 +312,6 @@ static int __devinit i2c_powermac_probe(struct platform_device *dev) | |||
312 | return rc; | 312 | return rc; |
313 | } | 313 | } |
314 | 314 | ||
315 | |||
316 | /* work with hotplug and coldplug */ | ||
317 | MODULE_ALIAS("platform:i2c-powermac"); | ||
318 | |||
319 | static struct platform_driver i2c_powermac_driver = { | 315 | static struct platform_driver i2c_powermac_driver = { |
320 | .probe = i2c_powermac_probe, | 316 | .probe = i2c_powermac_probe, |
321 | .remove = __devexit_p(i2c_powermac_remove), | 317 | .remove = __devexit_p(i2c_powermac_remove), |
@@ -325,17 +321,6 @@ static struct platform_driver i2c_powermac_driver = { | |||
325 | }, | 321 | }, |
326 | }; | 322 | }; |
327 | 323 | ||
328 | static int __init i2c_powermac_init(void) | 324 | module_platform_driver(i2c_powermac_driver); |
329 | { | ||
330 | platform_driver_register(&i2c_powermac_driver); | ||
331 | return 0; | ||
332 | } | ||
333 | 325 | ||
334 | 326 | MODULE_ALIAS("platform:i2c-powermac"); | |
335 | static void __exit i2c_powermac_cleanup(void) | ||
336 | { | ||
337 | platform_driver_unregister(&i2c_powermac_driver); | ||
338 | } | ||
339 | |||
340 | module_init(i2c_powermac_init); | ||
341 | module_exit(i2c_powermac_cleanup); | ||
diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c index 632e088760a3..a05817980556 100644 --- a/drivers/i2c/busses/i2c-pxa-pci.c +++ b/drivers/i2c/busses/i2c-pxa-pci.c | |||
@@ -150,7 +150,7 @@ static void __devexit ce4100_i2c_remove(struct pci_dev *dev) | |||
150 | kfree(sds); | 150 | kfree(sds); |
151 | } | 151 | } |
152 | 152 | ||
153 | static struct pci_device_id ce4100_i2c_devices[] __devinitdata = { | 153 | static DEFINE_PCI_DEVICE_TABLE(ce4100_i2c_devices) = { |
154 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)}, | 154 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)}, |
155 | { }, | 155 | { }, |
156 | }; | 156 | }; |
diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c index a67132b2e092..c0c9dffbdb12 100644 --- a/drivers/i2c/busses/i2c-sh7760.c +++ b/drivers/i2c/busses/i2c-sh7760.c | |||
@@ -560,18 +560,7 @@ static struct platform_driver sh7760_i2c_drv = { | |||
560 | .remove = __devexit_p(sh7760_i2c_remove), | 560 | .remove = __devexit_p(sh7760_i2c_remove), |
561 | }; | 561 | }; |
562 | 562 | ||
563 | static int __init sh7760_i2c_init(void) | 563 | module_platform_driver(sh7760_i2c_drv); |
564 | { | ||
565 | return platform_driver_register(&sh7760_i2c_drv); | ||
566 | } | ||
567 | |||
568 | static void __exit sh7760_i2c_exit(void) | ||
569 | { | ||
570 | platform_driver_unregister(&sh7760_i2c_drv); | ||
571 | } | ||
572 | |||
573 | module_init(sh7760_i2c_init); | ||
574 | module_exit(sh7760_i2c_exit); | ||
575 | 564 | ||
576 | MODULE_LICENSE("GPL"); | 565 | MODULE_LICENSE("GPL"); |
577 | MODULE_DESCRIPTION("SH7760 I2C bus driver"); | 566 | MODULE_DESCRIPTION("SH7760 I2C bus driver"); |
diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c index 2fc08fbf67a2..4fc87e7c94c9 100644 --- a/drivers/i2c/busses/i2c-simtec.c +++ b/drivers/i2c/busses/i2c-simtec.c | |||
@@ -156,12 +156,8 @@ static int simtec_i2c_remove(struct platform_device *dev) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | |||
160 | /* device driver */ | 159 | /* device driver */ |
161 | 160 | ||
162 | /* work with hotplug and coldplug */ | ||
163 | MODULE_ALIAS("platform:simtec-i2c"); | ||
164 | |||
165 | static struct platform_driver simtec_i2c_driver = { | 161 | static struct platform_driver simtec_i2c_driver = { |
166 | .driver = { | 162 | .driver = { |
167 | .name = "simtec-i2c", | 163 | .name = "simtec-i2c", |
@@ -171,19 +167,9 @@ static struct platform_driver simtec_i2c_driver = { | |||
171 | .remove = simtec_i2c_remove, | 167 | .remove = simtec_i2c_remove, |
172 | }; | 168 | }; |
173 | 169 | ||
174 | static int __init i2c_adap_simtec_init(void) | 170 | module_platform_driver(simtec_i2c_driver); |
175 | { | ||
176 | return platform_driver_register(&simtec_i2c_driver); | ||
177 | } | ||
178 | |||
179 | static void __exit i2c_adap_simtec_exit(void) | ||
180 | { | ||
181 | platform_driver_unregister(&simtec_i2c_driver); | ||
182 | } | ||
183 | |||
184 | module_init(i2c_adap_simtec_init); | ||
185 | module_exit(i2c_adap_simtec_exit); | ||
186 | 171 | ||
187 | MODULE_DESCRIPTION("Simtec Generic I2C Bus driver"); | 172 | MODULE_DESCRIPTION("Simtec Generic I2C Bus driver"); |
188 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 173 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
189 | MODULE_LICENSE("GPL"); | 174 | MODULE_LICENSE("GPL"); |
175 | MODULE_ALIAS("platform:simtec-i2c"); | ||
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c index 437586611d4a..87e5126d449c 100644 --- a/drivers/i2c/busses/i2c-sis5595.c +++ b/drivers/i2c/busses/i2c-sis5595.c | |||
@@ -147,7 +147,7 @@ static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev) | |||
147 | u16 a; | 147 | u16 a; |
148 | u8 val; | 148 | u8 val; |
149 | int *i; | 149 | int *i; |
150 | int retval = -ENODEV; | 150 | int retval; |
151 | 151 | ||
152 | /* Look for imposters */ | 152 | /* Look for imposters */ |
153 | for (i = blacklist; *i != 0; i++) { | 153 | for (i = blacklist; *i != 0; i++) { |
@@ -223,7 +223,7 @@ static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev) | |||
223 | 223 | ||
224 | error: | 224 | error: |
225 | release_region(sis5595_base + SMB_INDEX, 2); | 225 | release_region(sis5595_base + SMB_INDEX, 2); |
226 | return retval; | 226 | return -ENODEV; |
227 | } | 227 | } |
228 | 228 | ||
229 | static int sis5595_transaction(struct i2c_adapter *adap) | 229 | static int sis5595_transaction(struct i2c_adapter *adap) |
@@ -369,7 +369,7 @@ static struct i2c_adapter sis5595_adapter = { | |||
369 | .algo = &smbus_algorithm, | 369 | .algo = &smbus_algorithm, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | static const struct pci_device_id sis5595_ids[] __devinitconst = { | 372 | static DEFINE_PCI_DEVICE_TABLE(sis5595_ids) = { |
373 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, | 373 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, |
374 | { 0, } | 374 | { 0, } |
375 | }; | 375 | }; |
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c index 58893772c3d8..15cf78f65ce0 100644 --- a/drivers/i2c/busses/i2c-sis630.c +++ b/drivers/i2c/busses/i2c-sis630.c | |||
@@ -393,7 +393,7 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev) | |||
393 | { | 393 | { |
394 | unsigned char b; | 394 | unsigned char b; |
395 | struct pci_dev *dummy = NULL; | 395 | struct pci_dev *dummy = NULL; |
396 | int retval = -ENODEV, i; | 396 | int retval, i; |
397 | 397 | ||
398 | /* check for supported SiS devices */ | 398 | /* check for supported SiS devices */ |
399 | for (i=0; supported[i] > 0 ; i++) { | 399 | for (i=0; supported[i] > 0 ; i++) { |
@@ -418,18 +418,21 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev) | |||
418 | */ | 418 | */ |
419 | if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { | 419 | if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) { |
420 | dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n"); | 420 | dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n"); |
421 | retval = -ENODEV; | ||
421 | goto exit; | 422 | goto exit; |
422 | } | 423 | } |
423 | /* if ACPI already enabled , do nothing */ | 424 | /* if ACPI already enabled , do nothing */ |
424 | if (!(b & 0x80) && | 425 | if (!(b & 0x80) && |
425 | pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) { | 426 | pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) { |
426 | dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n"); | 427 | dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n"); |
428 | retval = -ENODEV; | ||
427 | goto exit; | 429 | goto exit; |
428 | } | 430 | } |
429 | 431 | ||
430 | /* Determine the ACPI base address */ | 432 | /* Determine the ACPI base address */ |
431 | if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { | 433 | if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) { |
432 | dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n"); | 434 | dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n"); |
435 | retval = -ENODEV; | ||
433 | goto exit; | 436 | goto exit; |
434 | } | 437 | } |
435 | 438 | ||
@@ -445,6 +448,7 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev) | |||
445 | sis630_driver.name)) { | 448 | sis630_driver.name)) { |
446 | dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already " | 449 | dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already " |
447 | "in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA); | 450 | "in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA); |
451 | retval = -EBUSY; | ||
448 | goto exit; | 452 | goto exit; |
449 | } | 453 | } |
450 | 454 | ||
@@ -468,7 +472,7 @@ static struct i2c_adapter sis630_adapter = { | |||
468 | .algo = &smbus_algorithm, | 472 | .algo = &smbus_algorithm, |
469 | }; | 473 | }; |
470 | 474 | ||
471 | static const struct pci_device_id sis630_ids[] __devinitconst = { | 475 | static DEFINE_PCI_DEVICE_TABLE(sis630_ids) = { |
472 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, | 476 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) }, |
473 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) }, | 477 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) }, |
474 | { 0, } | 478 | { 0, } |
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c index 86837f0c4cb9..cc5d149413f7 100644 --- a/drivers/i2c/busses/i2c-sis96x.c +++ b/drivers/i2c/busses/i2c-sis96x.c | |||
@@ -245,7 +245,7 @@ static struct i2c_adapter sis96x_adapter = { | |||
245 | .algo = &smbus_algorithm, | 245 | .algo = &smbus_algorithm, |
246 | }; | 246 | }; |
247 | 247 | ||
248 | static const struct pci_device_id sis96x_ids[] = { | 248 | static DEFINE_PCI_DEVICE_TABLE(sis96x_ids) = { |
249 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) }, | 249 | { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) }, |
250 | { 0, } | 250 | { 0, } |
251 | }; | 251 | }; |
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c index 7799fe5bda88..713d31ade26b 100644 --- a/drivers/i2c/busses/i2c-via.c +++ b/drivers/i2c/busses/i2c-via.c | |||
@@ -89,7 +89,7 @@ static struct i2c_adapter vt586b_adapter = { | |||
89 | }; | 89 | }; |
90 | 90 | ||
91 | 91 | ||
92 | static const struct pci_device_id vt586b_ids[] __devinitconst = { | 92 | static DEFINE_PCI_DEVICE_TABLE(vt586b_ids) = { |
93 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) }, | 93 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) }, |
94 | { 0, } | 94 | { 0, } |
95 | }; | 95 | }; |
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c index 2a62c998044a..333011c83d52 100644 --- a/drivers/i2c/busses/i2c-viapro.c +++ b/drivers/i2c/busses/i2c-viapro.c | |||
@@ -324,7 +324,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev, | |||
324 | const struct pci_device_id *id) | 324 | const struct pci_device_id *id) |
325 | { | 325 | { |
326 | unsigned char temp; | 326 | unsigned char temp; |
327 | int error = -ENODEV; | 327 | int error; |
328 | 328 | ||
329 | /* Determine the address of the SMBus areas */ | 329 | /* Determine the address of the SMBus areas */ |
330 | if (force_addr) { | 330 | if (force_addr) { |
@@ -390,6 +390,7 @@ found: | |||
390 | dev_err(&pdev->dev, "SMBUS: Error: Host SMBus " | 390 | dev_err(&pdev->dev, "SMBUS: Error: Host SMBus " |
391 | "controller not enabled! - upgrade BIOS or " | 391 | "controller not enabled! - upgrade BIOS or " |
392 | "use force=1\n"); | 392 | "use force=1\n"); |
393 | error = -ENODEV; | ||
393 | goto release_region; | 394 | goto release_region; |
394 | } | 395 | } |
395 | } | 396 | } |
@@ -422,9 +423,11 @@ found: | |||
422 | "SMBus Via Pro adapter at %04x", vt596_smba); | 423 | "SMBus Via Pro adapter at %04x", vt596_smba); |
423 | 424 | ||
424 | vt596_pdev = pci_dev_get(pdev); | 425 | vt596_pdev = pci_dev_get(pdev); |
425 | if (i2c_add_adapter(&vt596_adapter)) { | 426 | error = i2c_add_adapter(&vt596_adapter); |
427 | if (error) { | ||
426 | pci_dev_put(vt596_pdev); | 428 | pci_dev_put(vt596_pdev); |
427 | vt596_pdev = NULL; | 429 | vt596_pdev = NULL; |
430 | goto release_region; | ||
428 | } | 431 | } |
429 | 432 | ||
430 | /* Always return failure here. This is to allow other drivers to bind | 433 | /* Always return failure here. This is to allow other drivers to bind |
@@ -438,7 +441,7 @@ release_region: | |||
438 | return error; | 441 | return error; |
439 | } | 442 | } |
440 | 443 | ||
441 | static const struct pci_device_id vt596_ids[] = { | 444 | static DEFINE_PCI_DEVICE_TABLE(vt596_ids) = { |
442 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3), | 445 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3), |
443 | .driver_data = SMBBA1 }, | 446 | .driver_data = SMBBA1 }, |
444 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3), | 447 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3), |
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c index ac083a28ae08..2bded7647ef2 100644 --- a/drivers/i2c/busses/i2c-xiic.c +++ b/drivers/i2c/busses/i2c-xiic.c | |||
@@ -795,10 +795,6 @@ static int __devexit xiic_i2c_remove(struct platform_device* pdev) | |||
795 | return 0; | 795 | return 0; |
796 | } | 796 | } |
797 | 797 | ||
798 | |||
799 | /* work with hotplug and coldplug */ | ||
800 | MODULE_ALIAS("platform:"DRIVER_NAME); | ||
801 | |||
802 | static struct platform_driver xiic_i2c_driver = { | 798 | static struct platform_driver xiic_i2c_driver = { |
803 | .probe = xiic_i2c_probe, | 799 | .probe = xiic_i2c_probe, |
804 | .remove = __devexit_p(xiic_i2c_remove), | 800 | .remove = __devexit_p(xiic_i2c_remove), |
@@ -808,19 +804,9 @@ static struct platform_driver xiic_i2c_driver = { | |||
808 | }, | 804 | }, |
809 | }; | 805 | }; |
810 | 806 | ||
811 | static int __init xiic_i2c_init(void) | 807 | module_platform_driver(xiic_i2c_driver); |
812 | { | ||
813 | return platform_driver_register(&xiic_i2c_driver); | ||
814 | } | ||
815 | |||
816 | static void __exit xiic_i2c_exit(void) | ||
817 | { | ||
818 | platform_driver_unregister(&xiic_i2c_driver); | ||
819 | } | ||
820 | |||
821 | module_init(xiic_i2c_init); | ||
822 | module_exit(xiic_i2c_exit); | ||
823 | 808 | ||
824 | MODULE_AUTHOR("info@mocean-labs.com"); | 809 | MODULE_AUTHOR("info@mocean-labs.com"); |
825 | MODULE_DESCRIPTION("Xilinx I2C bus driver"); | 810 | MODULE_DESCRIPTION("Xilinx I2C bus driver"); |
826 | MODULE_LICENSE("GPL v2"); | 811 | MODULE_LICENSE("GPL v2"); |
812 | MODULE_ALIAS("platform:"DRIVER_NAME); | ||
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c index 91e349c884c5..2eacb7784d56 100644 --- a/drivers/i2c/busses/scx200_acb.c +++ b/drivers/i2c/busses/scx200_acb.c | |||
@@ -559,7 +559,7 @@ static struct platform_driver scx200_pci_driver = { | |||
559 | .remove = __devexit_p(scx200_remove), | 559 | .remove = __devexit_p(scx200_remove), |
560 | }; | 560 | }; |
561 | 561 | ||
562 | static const struct pci_device_id scx200_isa[] __initconst = { | 562 | static DEFINE_PCI_DEVICE_TABLE(scx200_isa) = { |
563 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, | 563 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) }, |
564 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, | 564 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) }, |
565 | { 0, } | 565 | { 0, } |
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index 57a45ce84b2d..10e7f1e76586 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c | |||
@@ -251,15 +251,10 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client, | |||
251 | if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS) | 251 | if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS) |
252 | return -EINVAL; | 252 | return -EINVAL; |
253 | 253 | ||
254 | rdwr_pa = kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL); | 254 | rdwr_pa = memdup_user(rdwr_arg.msgs, |
255 | if (!rdwr_pa) | 255 | rdwr_arg.nmsgs * sizeof(struct i2c_msg)); |
256 | return -ENOMEM; | 256 | if (IS_ERR(rdwr_pa)) |
257 | 257 | return PTR_ERR(rdwr_pa); | |
258 | if (copy_from_user(rdwr_pa, rdwr_arg.msgs, | ||
259 | rdwr_arg.nmsgs * sizeof(struct i2c_msg))) { | ||
260 | kfree(rdwr_pa); | ||
261 | return -EFAULT; | ||
262 | } | ||
263 | 258 | ||
264 | data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL); | 259 | data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL); |
265 | if (data_ptrs == NULL) { | 260 | if (data_ptrs == NULL) { |
diff --git a/drivers/i2c/muxes/gpio-i2cmux.c b/drivers/i2c/muxes/gpio-i2cmux.c index 7b6ce624cd6e..e5fa695eb0fa 100644 --- a/drivers/i2c/muxes/gpio-i2cmux.c +++ b/drivers/i2c/muxes/gpio-i2cmux.c | |||
@@ -165,18 +165,7 @@ static struct platform_driver gpiomux_driver = { | |||
165 | }, | 165 | }, |
166 | }; | 166 | }; |
167 | 167 | ||
168 | static int __init gpiomux_init(void) | 168 | module_platform_driver(gpiomux_driver); |
169 | { | ||
170 | return platform_driver_register(&gpiomux_driver); | ||
171 | } | ||
172 | |||
173 | static void __exit gpiomux_exit(void) | ||
174 | { | ||
175 | platform_driver_unregister(&gpiomux_driver); | ||
176 | } | ||
177 | |||
178 | module_init(gpiomux_init); | ||
179 | module_exit(gpiomux_exit); | ||
180 | 169 | ||
181 | MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver"); | 170 | MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver"); |
182 | MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>"); | 171 | MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>"); |
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 79d901633635..350fd0c385d2 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c | |||
@@ -12,7 +12,7 @@ | |||
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/input.h> | 13 | #include <linux/input.h> |
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/mfd/ab8500.h> | 15 | #include <linux/mfd/abx500/ab8500.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | 17 | ||
18 | /** | 18 | /** |
diff --git a/drivers/isdn/i4l/Kconfig b/drivers/isdn/i4l/Kconfig index 9c6650ea848e..2302fbe70ac6 100644 --- a/drivers/isdn/i4l/Kconfig +++ b/drivers/isdn/i4l/Kconfig | |||
@@ -6,7 +6,7 @@ if ISDN_I4L | |||
6 | 6 | ||
7 | config ISDN_PPP | 7 | config ISDN_PPP |
8 | bool "Support synchronous PPP" | 8 | bool "Support synchronous PPP" |
9 | depends on INET | 9 | depends on INET && NETDEVICES |
10 | select SLHC | 10 | select SLHC |
11 | help | 11 | help |
12 | Over digital connections such as ISDN, there is no need to | 12 | Over digital connections such as ISDN, there is no need to |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 897a77dfa9d7..c957c344233f 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -396,6 +396,13 @@ config LEDS_TCA6507 | |||
396 | LED driver chips accessed via the I2C bus. | 396 | LED driver chips accessed via the I2C bus. |
397 | Driver support brightness control and hardware-assisted blinking. | 397 | Driver support brightness control and hardware-assisted blinking. |
398 | 398 | ||
399 | config LEDS_MAX8997 | ||
400 | tristate "LED support for MAX8997 PMIC" | ||
401 | depends on LEDS_CLASS && MFD_MAX8997 | ||
402 | help | ||
403 | This option enables support for on-chip LED drivers on | ||
404 | MAXIM MAX8997 PMIC. | ||
405 | |||
399 | config LEDS_TRIGGERS | 406 | config LEDS_TRIGGERS |
400 | bool "LED Trigger support" | 407 | bool "LED Trigger support" |
401 | depends on LEDS_CLASS | 408 | depends on LEDS_CLASS |
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 5c9dc4b000d5..b8a9723477f0 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -44,6 +44,7 @@ obj-$(CONFIG_LEDS_NS2) += leds-ns2.o | |||
44 | obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o | 44 | obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o |
45 | obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o | 45 | obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o |
46 | obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o | 46 | obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o |
47 | obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o | ||
47 | 48 | ||
48 | # LED SPI Drivers | 49 | # LED SPI Drivers |
49 | obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o | 50 | obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o |
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c new file mode 100644 index 000000000000..f4c0e37fad1e --- /dev/null +++ b/drivers/leds/leds-max8997.c | |||
@@ -0,0 +1,372 @@ | |||
1 | /* | ||
2 | * leds-max8997.c - LED class driver for MAX8997 LEDs. | ||
3 | * | ||
4 | * Copyright (C) 2011 Samsung Electronics | ||
5 | * Donggeun Kim <dg77.kim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/module.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/slab.h> | ||
16 | #include <linux/workqueue.h> | ||
17 | #include <linux/leds.h> | ||
18 | #include <linux/mfd/max8997.h> | ||
19 | #include <linux/mfd/max8997-private.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | |||
22 | #define MAX8997_LED_FLASH_SHIFT 3 | ||
23 | #define MAX8997_LED_FLASH_CUR_MASK 0xf8 | ||
24 | #define MAX8997_LED_MOVIE_SHIFT 4 | ||
25 | #define MAX8997_LED_MOVIE_CUR_MASK 0xf0 | ||
26 | |||
27 | #define MAX8997_LED_FLASH_MAX_BRIGHTNESS 0x1f | ||
28 | #define MAX8997_LED_MOVIE_MAX_BRIGHTNESS 0xf | ||
29 | #define MAX8997_LED_NONE_MAX_BRIGHTNESS 0 | ||
30 | |||
31 | #define MAX8997_LED0_FLASH_MASK 0x1 | ||
32 | #define MAX8997_LED0_FLASH_PIN_MASK 0x5 | ||
33 | #define MAX8997_LED0_MOVIE_MASK 0x8 | ||
34 | #define MAX8997_LED0_MOVIE_PIN_MASK 0x28 | ||
35 | |||
36 | #define MAX8997_LED1_FLASH_MASK 0x2 | ||
37 | #define MAX8997_LED1_FLASH_PIN_MASK 0x6 | ||
38 | #define MAX8997_LED1_MOVIE_MASK 0x10 | ||
39 | #define MAX8997_LED1_MOVIE_PIN_MASK 0x30 | ||
40 | |||
41 | #define MAX8997_LED_BOOST_ENABLE_MASK (1 << 6) | ||
42 | |||
43 | struct max8997_led { | ||
44 | struct max8997_dev *iodev; | ||
45 | struct led_classdev cdev; | ||
46 | bool enabled; | ||
47 | int id; | ||
48 | enum max8997_led_mode led_mode; | ||
49 | struct mutex mutex; | ||
50 | }; | ||
51 | |||
52 | static void max8997_led_clear_mode(struct max8997_led *led, | ||
53 | enum max8997_led_mode mode) | ||
54 | { | ||
55 | struct i2c_client *client = led->iodev->i2c; | ||
56 | u8 val = 0, mask = 0; | ||
57 | int ret; | ||
58 | |||
59 | switch (mode) { | ||
60 | case MAX8997_FLASH_MODE: | ||
61 | mask = led->id ? | ||
62 | MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK; | ||
63 | break; | ||
64 | case MAX8997_MOVIE_MODE: | ||
65 | mask = led->id ? | ||
66 | MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK; | ||
67 | break; | ||
68 | case MAX8997_FLASH_PIN_CONTROL_MODE: | ||
69 | mask = led->id ? | ||
70 | MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK; | ||
71 | break; | ||
72 | case MAX8997_MOVIE_PIN_CONTROL_MODE: | ||
73 | mask = led->id ? | ||
74 | MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK; | ||
75 | break; | ||
76 | default: | ||
77 | break; | ||
78 | } | ||
79 | |||
80 | if (mask) { | ||
81 | ret = max8997_update_reg(client, | ||
82 | MAX8997_REG_LEN_CNTL, val, mask); | ||
83 | if (ret) | ||
84 | dev_err(led->iodev->dev, | ||
85 | "failed to update register(%d)\n", ret); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | static void max8997_led_set_mode(struct max8997_led *led, | ||
90 | enum max8997_led_mode mode) | ||
91 | { | ||
92 | int ret; | ||
93 | struct i2c_client *client = led->iodev->i2c; | ||
94 | u8 mask = 0; | ||
95 | |||
96 | /* First, clear the previous mode */ | ||
97 | max8997_led_clear_mode(led, led->led_mode); | ||
98 | |||
99 | switch (mode) { | ||
100 | case MAX8997_FLASH_MODE: | ||
101 | mask = led->id ? | ||
102 | MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK; | ||
103 | led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS; | ||
104 | break; | ||
105 | case MAX8997_MOVIE_MODE: | ||
106 | mask = led->id ? | ||
107 | MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK; | ||
108 | led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS; | ||
109 | break; | ||
110 | case MAX8997_FLASH_PIN_CONTROL_MODE: | ||
111 | mask = led->id ? | ||
112 | MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK; | ||
113 | led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS; | ||
114 | break; | ||
115 | case MAX8997_MOVIE_PIN_CONTROL_MODE: | ||
116 | mask = led->id ? | ||
117 | MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK; | ||
118 | led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS; | ||
119 | break; | ||
120 | default: | ||
121 | led->cdev.max_brightness = MAX8997_LED_NONE_MAX_BRIGHTNESS; | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | if (mask) { | ||
126 | ret = max8997_update_reg(client, | ||
127 | MAX8997_REG_LEN_CNTL, mask, mask); | ||
128 | if (ret) | ||
129 | dev_err(led->iodev->dev, | ||
130 | "failed to update register(%d)\n", ret); | ||
131 | } | ||
132 | |||
133 | led->led_mode = mode; | ||
134 | } | ||
135 | |||
136 | static void max8997_led_enable(struct max8997_led *led, bool enable) | ||
137 | { | ||
138 | int ret; | ||
139 | struct i2c_client *client = led->iodev->i2c; | ||
140 | u8 val = 0, mask = MAX8997_LED_BOOST_ENABLE_MASK; | ||
141 | |||
142 | if (led->enabled == enable) | ||
143 | return; | ||
144 | |||
145 | val = enable ? MAX8997_LED_BOOST_ENABLE_MASK : 0; | ||
146 | |||
147 | ret = max8997_update_reg(client, MAX8997_REG_BOOST_CNTL, val, mask); | ||
148 | if (ret) | ||
149 | dev_err(led->iodev->dev, | ||
150 | "failed to update register(%d)\n", ret); | ||
151 | |||
152 | led->enabled = enable; | ||
153 | } | ||
154 | |||
155 | static void max8997_led_set_current(struct max8997_led *led, | ||
156 | enum led_brightness value) | ||
157 | { | ||
158 | int ret; | ||
159 | struct i2c_client *client = led->iodev->i2c; | ||
160 | u8 val = 0, mask = 0, reg = 0; | ||
161 | |||
162 | switch (led->led_mode) { | ||
163 | case MAX8997_FLASH_MODE: | ||
164 | case MAX8997_FLASH_PIN_CONTROL_MODE: | ||
165 | val = value << MAX8997_LED_FLASH_SHIFT; | ||
166 | mask = MAX8997_LED_FLASH_CUR_MASK; | ||
167 | reg = led->id ? MAX8997_REG_FLASH2_CUR : MAX8997_REG_FLASH1_CUR; | ||
168 | break; | ||
169 | case MAX8997_MOVIE_MODE: | ||
170 | case MAX8997_MOVIE_PIN_CONTROL_MODE: | ||
171 | val = value << MAX8997_LED_MOVIE_SHIFT; | ||
172 | mask = MAX8997_LED_MOVIE_CUR_MASK; | ||
173 | reg = MAX8997_REG_MOVIE_CUR; | ||
174 | break; | ||
175 | default: | ||
176 | break; | ||
177 | } | ||
178 | |||
179 | if (mask) { | ||
180 | ret = max8997_update_reg(client, reg, val, mask); | ||
181 | if (ret) | ||
182 | dev_err(led->iodev->dev, | ||
183 | "failed to update register(%d)\n", ret); | ||
184 | } | ||
185 | } | ||
186 | |||
187 | static void max8997_led_brightness_set(struct led_classdev *led_cdev, | ||
188 | enum led_brightness value) | ||
189 | { | ||
190 | struct max8997_led *led = | ||
191 | container_of(led_cdev, struct max8997_led, cdev); | ||
192 | |||
193 | if (value) { | ||
194 | max8997_led_set_current(led, value); | ||
195 | max8997_led_enable(led, true); | ||
196 | } else { | ||
197 | max8997_led_set_current(led, value); | ||
198 | max8997_led_enable(led, false); | ||
199 | } | ||
200 | } | ||
201 | |||
202 | static ssize_t max8997_led_show_mode(struct device *dev, | ||
203 | struct device_attribute *attr, char *buf) | ||
204 | { | ||
205 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
206 | struct max8997_led *led = | ||
207 | container_of(led_cdev, struct max8997_led, cdev); | ||
208 | ssize_t ret = 0; | ||
209 | |||
210 | mutex_lock(&led->mutex); | ||
211 | |||
212 | switch (led->led_mode) { | ||
213 | case MAX8997_FLASH_MODE: | ||
214 | ret += sprintf(buf, "FLASH\n"); | ||
215 | break; | ||
216 | case MAX8997_MOVIE_MODE: | ||
217 | ret += sprintf(buf, "MOVIE\n"); | ||
218 | break; | ||
219 | case MAX8997_FLASH_PIN_CONTROL_MODE: | ||
220 | ret += sprintf(buf, "FLASH_PIN_CONTROL\n"); | ||
221 | break; | ||
222 | case MAX8997_MOVIE_PIN_CONTROL_MODE: | ||
223 | ret += sprintf(buf, "MOVIE_PIN_CONTROL\n"); | ||
224 | break; | ||
225 | default: | ||
226 | ret += sprintf(buf, "NONE\n"); | ||
227 | break; | ||
228 | } | ||
229 | |||
230 | mutex_unlock(&led->mutex); | ||
231 | |||
232 | return ret; | ||
233 | } | ||
234 | |||
235 | static ssize_t max8997_led_store_mode(struct device *dev, | ||
236 | struct device_attribute *attr, | ||
237 | const char *buf, size_t size) | ||
238 | { | ||
239 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | ||
240 | struct max8997_led *led = | ||
241 | container_of(led_cdev, struct max8997_led, cdev); | ||
242 | enum max8997_led_mode mode; | ||
243 | |||
244 | mutex_lock(&led->mutex); | ||
245 | |||
246 | if (!strncmp(buf, "FLASH_PIN_CONTROL", 17)) | ||
247 | mode = MAX8997_FLASH_PIN_CONTROL_MODE; | ||
248 | else if (!strncmp(buf, "MOVIE_PIN_CONTROL", 17)) | ||
249 | mode = MAX8997_MOVIE_PIN_CONTROL_MODE; | ||
250 | else if (!strncmp(buf, "FLASH", 5)) | ||
251 | mode = MAX8997_FLASH_MODE; | ||
252 | else if (!strncmp(buf, "MOVIE", 5)) | ||
253 | mode = MAX8997_MOVIE_MODE; | ||
254 | else | ||
255 | mode = MAX8997_NONE; | ||
256 | |||
257 | max8997_led_set_mode(led, mode); | ||
258 | |||
259 | mutex_unlock(&led->mutex); | ||
260 | |||
261 | return size; | ||
262 | } | ||
263 | |||
264 | static DEVICE_ATTR(mode, 0644, max8997_led_show_mode, max8997_led_store_mode); | ||
265 | |||
266 | static int __devinit max8997_led_probe(struct platform_device *pdev) | ||
267 | { | ||
268 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
269 | struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
270 | struct max8997_led *led; | ||
271 | char name[20]; | ||
272 | int ret = 0; | ||
273 | |||
274 | if (pdata == NULL) { | ||
275 | dev_err(&pdev->dev, "no platform data\n"); | ||
276 | return -ENODEV; | ||
277 | } | ||
278 | |||
279 | led = kzalloc(sizeof(*led), GFP_KERNEL); | ||
280 | if (led == NULL) { | ||
281 | ret = -ENOMEM; | ||
282 | goto err_mem; | ||
283 | } | ||
284 | |||
285 | led->id = pdev->id; | ||
286 | snprintf(name, sizeof(name), "max8997-led%d", pdev->id); | ||
287 | |||
288 | led->cdev.name = name; | ||
289 | led->cdev.brightness_set = max8997_led_brightness_set; | ||
290 | led->cdev.flags |= LED_CORE_SUSPENDRESUME; | ||
291 | led->cdev.brightness = 0; | ||
292 | led->iodev = iodev; | ||
293 | |||
294 | /* initialize mode and brightness according to platform_data */ | ||
295 | if (pdata->led_pdata) { | ||
296 | u8 mode = 0, brightness = 0; | ||
297 | |||
298 | mode = pdata->led_pdata->mode[led->id]; | ||
299 | brightness = pdata->led_pdata->brightness[led->id]; | ||
300 | |||
301 | max8997_led_set_mode(led, pdata->led_pdata->mode[led->id]); | ||
302 | |||
303 | if (brightness > led->cdev.max_brightness) | ||
304 | brightness = led->cdev.max_brightness; | ||
305 | max8997_led_set_current(led, brightness); | ||
306 | led->cdev.brightness = brightness; | ||
307 | } else { | ||
308 | max8997_led_set_mode(led, MAX8997_NONE); | ||
309 | max8997_led_set_current(led, 0); | ||
310 | } | ||
311 | |||
312 | mutex_init(&led->mutex); | ||
313 | |||
314 | platform_set_drvdata(pdev, led); | ||
315 | |||
316 | ret = led_classdev_register(&pdev->dev, &led->cdev); | ||
317 | if (ret < 0) | ||
318 | goto err_led; | ||
319 | |||
320 | ret = device_create_file(led->cdev.dev, &dev_attr_mode); | ||
321 | if (ret != 0) { | ||
322 | dev_err(&pdev->dev, | ||
323 | "failed to create file: %d\n", ret); | ||
324 | goto err_file; | ||
325 | } | ||
326 | |||
327 | return 0; | ||
328 | |||
329 | err_file: | ||
330 | led_classdev_unregister(&led->cdev); | ||
331 | err_led: | ||
332 | kfree(led); | ||
333 | err_mem: | ||
334 | return ret; | ||
335 | } | ||
336 | |||
337 | static int __devexit max8997_led_remove(struct platform_device *pdev) | ||
338 | { | ||
339 | struct max8997_led *led = platform_get_drvdata(pdev); | ||
340 | |||
341 | device_remove_file(led->cdev.dev, &dev_attr_mode); | ||
342 | led_classdev_unregister(&led->cdev); | ||
343 | kfree(led); | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static struct platform_driver max8997_led_driver = { | ||
349 | .driver = { | ||
350 | .name = "max8997-led", | ||
351 | .owner = THIS_MODULE, | ||
352 | }, | ||
353 | .probe = max8997_led_probe, | ||
354 | .remove = __devexit_p(max8997_led_remove), | ||
355 | }; | ||
356 | |||
357 | static int __init max8997_led_init(void) | ||
358 | { | ||
359 | return platform_driver_register(&max8997_led_driver); | ||
360 | } | ||
361 | module_init(max8997_led_init); | ||
362 | |||
363 | static void __exit max8997_led_exit(void) | ||
364 | { | ||
365 | platform_driver_unregister(&max8997_led_driver); | ||
366 | } | ||
367 | module_exit(max8997_led_exit); | ||
368 | |||
369 | MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); | ||
370 | MODULE_DESCRIPTION("MAX8997 LED driver"); | ||
371 | MODULE_LICENSE("GPL"); | ||
372 | MODULE_ALIAS("platform:max8997-led"); | ||
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c index e017dc88622a..f93dd9571c3c 100644 --- a/drivers/mfd/88pm860x-i2c.c +++ b/drivers/mfd/88pm860x-i2c.c | |||
@@ -12,51 +12,20 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/err.h> | ||
16 | #include <linux/regmap.h> | ||
15 | #include <linux/mfd/88pm860x.h> | 17 | #include <linux/mfd/88pm860x.h> |
16 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
17 | 19 | ||
18 | static inline int pm860x_read_device(struct i2c_client *i2c, | ||
19 | int reg, int bytes, void *dest) | ||
20 | { | ||
21 | unsigned char data; | ||
22 | int ret; | ||
23 | |||
24 | data = (unsigned char)reg; | ||
25 | ret = i2c_master_send(i2c, &data, 1); | ||
26 | if (ret < 0) | ||
27 | return ret; | ||
28 | |||
29 | ret = i2c_master_recv(i2c, dest, bytes); | ||
30 | if (ret < 0) | ||
31 | return ret; | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static inline int pm860x_write_device(struct i2c_client *i2c, | ||
36 | int reg, int bytes, void *src) | ||
37 | { | ||
38 | unsigned char buf[bytes + 1]; | ||
39 | int ret; | ||
40 | |||
41 | buf[0] = (unsigned char)reg; | ||
42 | memcpy(&buf[1], src, bytes); | ||
43 | |||
44 | ret = i2c_master_send(i2c, buf, bytes + 1); | ||
45 | if (ret < 0) | ||
46 | return ret; | ||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | int pm860x_reg_read(struct i2c_client *i2c, int reg) | 20 | int pm860x_reg_read(struct i2c_client *i2c, int reg) |
51 | { | 21 | { |
52 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | 22 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); |
53 | unsigned char data; | 23 | struct regmap *map = (i2c == chip->client) ? chip->regmap |
24 | : chip->regmap_companion; | ||
25 | unsigned int data; | ||
54 | int ret; | 26 | int ret; |
55 | 27 | ||
56 | mutex_lock(&chip->io_lock); | 28 | ret = regmap_read(map, reg, &data); |
57 | ret = pm860x_read_device(i2c, reg, 1, &data); | ||
58 | mutex_unlock(&chip->io_lock); | ||
59 | |||
60 | if (ret < 0) | 29 | if (ret < 0) |
61 | return ret; | 30 | return ret; |
62 | else | 31 | else |
@@ -68,12 +37,11 @@ int pm860x_reg_write(struct i2c_client *i2c, int reg, | |||
68 | unsigned char data) | 37 | unsigned char data) |
69 | { | 38 | { |
70 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | 39 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); |
40 | struct regmap *map = (i2c == chip->client) ? chip->regmap | ||
41 | : chip->regmap_companion; | ||
71 | int ret; | 42 | int ret; |
72 | 43 | ||
73 | mutex_lock(&chip->io_lock); | 44 | ret = regmap_write(map, reg, data); |
74 | ret = pm860x_write_device(i2c, reg, 1, &data); | ||
75 | mutex_unlock(&chip->io_lock); | ||
76 | |||
77 | return ret; | 45 | return ret; |
78 | } | 46 | } |
79 | EXPORT_SYMBOL(pm860x_reg_write); | 47 | EXPORT_SYMBOL(pm860x_reg_write); |
@@ -82,12 +50,11 @@ int pm860x_bulk_read(struct i2c_client *i2c, int reg, | |||
82 | int count, unsigned char *buf) | 50 | int count, unsigned char *buf) |
83 | { | 51 | { |
84 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | 52 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); |
53 | struct regmap *map = (i2c == chip->client) ? chip->regmap | ||
54 | : chip->regmap_companion; | ||
85 | int ret; | 55 | int ret; |
86 | 56 | ||
87 | mutex_lock(&chip->io_lock); | 57 | ret = regmap_raw_read(map, reg, buf, count); |
88 | ret = pm860x_read_device(i2c, reg, count, buf); | ||
89 | mutex_unlock(&chip->io_lock); | ||
90 | |||
91 | return ret; | 58 | return ret; |
92 | } | 59 | } |
93 | EXPORT_SYMBOL(pm860x_bulk_read); | 60 | EXPORT_SYMBOL(pm860x_bulk_read); |
@@ -96,12 +63,11 @@ int pm860x_bulk_write(struct i2c_client *i2c, int reg, | |||
96 | int count, unsigned char *buf) | 63 | int count, unsigned char *buf) |
97 | { | 64 | { |
98 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | 65 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); |
66 | struct regmap *map = (i2c == chip->client) ? chip->regmap | ||
67 | : chip->regmap_companion; | ||
99 | int ret; | 68 | int ret; |
100 | 69 | ||
101 | mutex_lock(&chip->io_lock); | 70 | ret = regmap_raw_write(map, reg, buf, count); |
102 | ret = pm860x_write_device(i2c, reg, count, buf); | ||
103 | mutex_unlock(&chip->io_lock); | ||
104 | |||
105 | return ret; | 71 | return ret; |
106 | } | 72 | } |
107 | EXPORT_SYMBOL(pm860x_bulk_write); | 73 | EXPORT_SYMBOL(pm860x_bulk_write); |
@@ -110,39 +76,78 @@ int pm860x_set_bits(struct i2c_client *i2c, int reg, | |||
110 | unsigned char mask, unsigned char data) | 76 | unsigned char mask, unsigned char data) |
111 | { | 77 | { |
112 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | 78 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); |
113 | unsigned char value; | 79 | struct regmap *map = (i2c == chip->client) ? chip->regmap |
80 | : chip->regmap_companion; | ||
114 | int ret; | 81 | int ret; |
115 | 82 | ||
116 | mutex_lock(&chip->io_lock); | 83 | ret = regmap_update_bits(map, reg, mask, data); |
117 | ret = pm860x_read_device(i2c, reg, 1, &value); | ||
118 | if (ret < 0) | ||
119 | goto out; | ||
120 | value &= ~mask; | ||
121 | value |= data; | ||
122 | ret = pm860x_write_device(i2c, reg, 1, &value); | ||
123 | out: | ||
124 | mutex_unlock(&chip->io_lock); | ||
125 | return ret; | 84 | return ret; |
126 | } | 85 | } |
127 | EXPORT_SYMBOL(pm860x_set_bits); | 86 | EXPORT_SYMBOL(pm860x_set_bits); |
128 | 87 | ||
88 | static int read_device(struct i2c_client *i2c, int reg, | ||
89 | int bytes, void *dest) | ||
90 | { | ||
91 | unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX + 3]; | ||
92 | unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX + 2]; | ||
93 | struct i2c_adapter *adap = i2c->adapter; | ||
94 | struct i2c_msg msg[2] = {{i2c->addr, 0, 1, msgbuf0}, | ||
95 | {i2c->addr, I2C_M_RD, 0, msgbuf1}, | ||
96 | }; | ||
97 | int num = 1, ret = 0; | ||
98 | |||
99 | if (dest == NULL) | ||
100 | return -EINVAL; | ||
101 | msgbuf0[0] = (unsigned char)reg; /* command */ | ||
102 | msg[1].len = bytes; | ||
103 | |||
104 | /* if data needs to read back, num should be 2 */ | ||
105 | if (bytes > 0) | ||
106 | num = 2; | ||
107 | ret = adap->algo->master_xfer(adap, msg, num); | ||
108 | memcpy(dest, msgbuf1, bytes); | ||
109 | if (ret < 0) | ||
110 | return ret; | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int write_device(struct i2c_client *i2c, int reg, | ||
115 | int bytes, void *src) | ||
116 | { | ||
117 | unsigned char buf[bytes + 1]; | ||
118 | struct i2c_adapter *adap = i2c->adapter; | ||
119 | struct i2c_msg msg; | ||
120 | int ret; | ||
121 | |||
122 | buf[0] = (unsigned char)reg; | ||
123 | memcpy(&buf[1], src, bytes); | ||
124 | msg.addr = i2c->addr; | ||
125 | msg.flags = 0; | ||
126 | msg.len = bytes + 1; | ||
127 | msg.buf = buf; | ||
128 | |||
129 | ret = adap->algo->master_xfer(adap, &msg, 1); | ||
130 | if (ret < 0) | ||
131 | return ret; | ||
132 | return 0; | ||
133 | } | ||
134 | |||
129 | int pm860x_page_reg_read(struct i2c_client *i2c, int reg) | 135 | int pm860x_page_reg_read(struct i2c_client *i2c, int reg) |
130 | { | 136 | { |
131 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | ||
132 | unsigned char zero = 0; | 137 | unsigned char zero = 0; |
133 | unsigned char data; | 138 | unsigned char data; |
134 | int ret; | 139 | int ret; |
135 | 140 | ||
136 | mutex_lock(&chip->io_lock); | 141 | i2c_lock_adapter(i2c->adapter); |
137 | pm860x_write_device(i2c, 0xFA, 0, &zero); | 142 | read_device(i2c, 0xFA, 0, &zero); |
138 | pm860x_write_device(i2c, 0xFB, 0, &zero); | 143 | read_device(i2c, 0xFB, 0, &zero); |
139 | pm860x_write_device(i2c, 0xFF, 0, &zero); | 144 | read_device(i2c, 0xFF, 0, &zero); |
140 | ret = pm860x_read_device(i2c, reg, 1, &data); | 145 | ret = read_device(i2c, reg, 1, &data); |
141 | if (ret >= 0) | 146 | if (ret >= 0) |
142 | ret = (int)data; | 147 | ret = (int)data; |
143 | pm860x_write_device(i2c, 0xFE, 0, &zero); | 148 | read_device(i2c, 0xFE, 0, &zero); |
144 | pm860x_write_device(i2c, 0xFC, 0, &zero); | 149 | read_device(i2c, 0xFC, 0, &zero); |
145 | mutex_unlock(&chip->io_lock); | 150 | i2c_unlock_adapter(i2c->adapter); |
146 | return ret; | 151 | return ret; |
147 | } | 152 | } |
148 | EXPORT_SYMBOL(pm860x_page_reg_read); | 153 | EXPORT_SYMBOL(pm860x_page_reg_read); |
@@ -150,18 +155,17 @@ EXPORT_SYMBOL(pm860x_page_reg_read); | |||
150 | int pm860x_page_reg_write(struct i2c_client *i2c, int reg, | 155 | int pm860x_page_reg_write(struct i2c_client *i2c, int reg, |
151 | unsigned char data) | 156 | unsigned char data) |
152 | { | 157 | { |
153 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | ||
154 | unsigned char zero; | 158 | unsigned char zero; |
155 | int ret; | 159 | int ret; |
156 | 160 | ||
157 | mutex_lock(&chip->io_lock); | 161 | i2c_lock_adapter(i2c->adapter); |
158 | pm860x_write_device(i2c, 0xFA, 0, &zero); | 162 | read_device(i2c, 0xFA, 0, &zero); |
159 | pm860x_write_device(i2c, 0xFB, 0, &zero); | 163 | read_device(i2c, 0xFB, 0, &zero); |
160 | pm860x_write_device(i2c, 0xFF, 0, &zero); | 164 | read_device(i2c, 0xFF, 0, &zero); |
161 | ret = pm860x_write_device(i2c, reg, 1, &data); | 165 | ret = write_device(i2c, reg, 1, &data); |
162 | pm860x_write_device(i2c, 0xFE, 0, &zero); | 166 | read_device(i2c, 0xFE, 0, &zero); |
163 | pm860x_write_device(i2c, 0xFC, 0, &zero); | 167 | read_device(i2c, 0xFC, 0, &zero); |
164 | mutex_unlock(&chip->io_lock); | 168 | i2c_unlock_adapter(i2c->adapter); |
165 | return ret; | 169 | return ret; |
166 | } | 170 | } |
167 | EXPORT_SYMBOL(pm860x_page_reg_write); | 171 | EXPORT_SYMBOL(pm860x_page_reg_write); |
@@ -169,18 +173,17 @@ EXPORT_SYMBOL(pm860x_page_reg_write); | |||
169 | int pm860x_page_bulk_read(struct i2c_client *i2c, int reg, | 173 | int pm860x_page_bulk_read(struct i2c_client *i2c, int reg, |
170 | int count, unsigned char *buf) | 174 | int count, unsigned char *buf) |
171 | { | 175 | { |
172 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | ||
173 | unsigned char zero = 0; | 176 | unsigned char zero = 0; |
174 | int ret; | 177 | int ret; |
175 | 178 | ||
176 | mutex_lock(&chip->io_lock); | 179 | i2c_lock_adapter(i2c->adapter); |
177 | pm860x_write_device(i2c, 0xFA, 0, &zero); | 180 | read_device(i2c, 0xfa, 0, &zero); |
178 | pm860x_write_device(i2c, 0xFB, 0, &zero); | 181 | read_device(i2c, 0xfb, 0, &zero); |
179 | pm860x_write_device(i2c, 0xFF, 0, &zero); | 182 | read_device(i2c, 0xff, 0, &zero); |
180 | ret = pm860x_read_device(i2c, reg, count, buf); | 183 | ret = read_device(i2c, reg, count, buf); |
181 | pm860x_write_device(i2c, 0xFE, 0, &zero); | 184 | read_device(i2c, 0xFE, 0, &zero); |
182 | pm860x_write_device(i2c, 0xFC, 0, &zero); | 185 | read_device(i2c, 0xFC, 0, &zero); |
183 | mutex_unlock(&chip->io_lock); | 186 | i2c_unlock_adapter(i2c->adapter); |
184 | return ret; | 187 | return ret; |
185 | } | 188 | } |
186 | EXPORT_SYMBOL(pm860x_page_bulk_read); | 189 | EXPORT_SYMBOL(pm860x_page_bulk_read); |
@@ -188,18 +191,18 @@ EXPORT_SYMBOL(pm860x_page_bulk_read); | |||
188 | int pm860x_page_bulk_write(struct i2c_client *i2c, int reg, | 191 | int pm860x_page_bulk_write(struct i2c_client *i2c, int reg, |
189 | int count, unsigned char *buf) | 192 | int count, unsigned char *buf) |
190 | { | 193 | { |
191 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | ||
192 | unsigned char zero = 0; | 194 | unsigned char zero = 0; |
193 | int ret; | 195 | int ret; |
194 | 196 | ||
195 | mutex_lock(&chip->io_lock); | 197 | i2c_lock_adapter(i2c->adapter); |
196 | pm860x_write_device(i2c, 0xFA, 0, &zero); | 198 | read_device(i2c, 0xFA, 0, &zero); |
197 | pm860x_write_device(i2c, 0xFB, 0, &zero); | 199 | read_device(i2c, 0xFB, 0, &zero); |
198 | pm860x_write_device(i2c, 0xFF, 0, &zero); | 200 | read_device(i2c, 0xFF, 0, &zero); |
199 | ret = pm860x_write_device(i2c, reg, count, buf); | 201 | ret = write_device(i2c, reg, count, buf); |
200 | pm860x_write_device(i2c, 0xFE, 0, &zero); | 202 | read_device(i2c, 0xFE, 0, &zero); |
201 | pm860x_write_device(i2c, 0xFC, 0, &zero); | 203 | read_device(i2c, 0xFC, 0, &zero); |
202 | mutex_unlock(&chip->io_lock); | 204 | i2c_unlock_adapter(i2c->adapter); |
205 | i2c_unlock_adapter(i2c->adapter); | ||
203 | return ret; | 206 | return ret; |
204 | } | 207 | } |
205 | EXPORT_SYMBOL(pm860x_page_bulk_write); | 208 | EXPORT_SYMBOL(pm860x_page_bulk_write); |
@@ -207,25 +210,24 @@ EXPORT_SYMBOL(pm860x_page_bulk_write); | |||
207 | int pm860x_page_set_bits(struct i2c_client *i2c, int reg, | 210 | int pm860x_page_set_bits(struct i2c_client *i2c, int reg, |
208 | unsigned char mask, unsigned char data) | 211 | unsigned char mask, unsigned char data) |
209 | { | 212 | { |
210 | struct pm860x_chip *chip = i2c_get_clientdata(i2c); | ||
211 | unsigned char zero; | 213 | unsigned char zero; |
212 | unsigned char value; | 214 | unsigned char value; |
213 | int ret; | 215 | int ret; |
214 | 216 | ||
215 | mutex_lock(&chip->io_lock); | 217 | i2c_lock_adapter(i2c->adapter); |
216 | pm860x_write_device(i2c, 0xFA, 0, &zero); | 218 | read_device(i2c, 0xFA, 0, &zero); |
217 | pm860x_write_device(i2c, 0xFB, 0, &zero); | 219 | read_device(i2c, 0xFB, 0, &zero); |
218 | pm860x_write_device(i2c, 0xFF, 0, &zero); | 220 | read_device(i2c, 0xFF, 0, &zero); |
219 | ret = pm860x_read_device(i2c, reg, 1, &value); | 221 | ret = read_device(i2c, reg, 1, &value); |
220 | if (ret < 0) | 222 | if (ret < 0) |
221 | goto out; | 223 | goto out; |
222 | value &= ~mask; | 224 | value &= ~mask; |
223 | value |= data; | 225 | value |= data; |
224 | ret = pm860x_write_device(i2c, reg, 1, &value); | 226 | ret = write_device(i2c, reg, 1, &value); |
225 | out: | 227 | out: |
226 | pm860x_write_device(i2c, 0xFE, 0, &zero); | 228 | read_device(i2c, 0xFE, 0, &zero); |
227 | pm860x_write_device(i2c, 0xFC, 0, &zero); | 229 | read_device(i2c, 0xFC, 0, &zero); |
228 | mutex_unlock(&chip->io_lock); | 230 | i2c_unlock_adapter(i2c->adapter); |
229 | return ret; | 231 | return ret; |
230 | } | 232 | } |
231 | EXPORT_SYMBOL(pm860x_page_set_bits); | 233 | EXPORT_SYMBOL(pm860x_page_set_bits); |
@@ -257,11 +259,17 @@ static int verify_addr(struct i2c_client *i2c) | |||
257 | return 0; | 259 | return 0; |
258 | } | 260 | } |
259 | 261 | ||
262 | static struct regmap_config pm860x_regmap_config = { | ||
263 | .reg_bits = 8, | ||
264 | .val_bits = 8, | ||
265 | }; | ||
266 | |||
260 | static int __devinit pm860x_probe(struct i2c_client *client, | 267 | static int __devinit pm860x_probe(struct i2c_client *client, |
261 | const struct i2c_device_id *id) | 268 | const struct i2c_device_id *id) |
262 | { | 269 | { |
263 | struct pm860x_platform_data *pdata = client->dev.platform_data; | 270 | struct pm860x_platform_data *pdata = client->dev.platform_data; |
264 | struct pm860x_chip *chip; | 271 | struct pm860x_chip *chip; |
272 | int ret; | ||
265 | 273 | ||
266 | if (!pdata) { | 274 | if (!pdata) { |
267 | pr_info("No platform data in %s!\n", __func__); | 275 | pr_info("No platform data in %s!\n", __func__); |
@@ -273,10 +281,17 @@ static int __devinit pm860x_probe(struct i2c_client *client, | |||
273 | return -ENOMEM; | 281 | return -ENOMEM; |
274 | 282 | ||
275 | chip->id = verify_addr(client); | 283 | chip->id = verify_addr(client); |
284 | chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config); | ||
285 | if (IS_ERR(chip->regmap)) { | ||
286 | ret = PTR_ERR(chip->regmap); | ||
287 | dev_err(&client->dev, "Failed to allocate register map: %d\n", | ||
288 | ret); | ||
289 | kfree(chip); | ||
290 | return ret; | ||
291 | } | ||
276 | chip->client = client; | 292 | chip->client = client; |
277 | i2c_set_clientdata(client, chip); | 293 | i2c_set_clientdata(client, chip); |
278 | chip->dev = &client->dev; | 294 | chip->dev = &client->dev; |
279 | mutex_init(&chip->io_lock); | ||
280 | dev_set_drvdata(chip->dev, chip); | 295 | dev_set_drvdata(chip->dev, chip); |
281 | 296 | ||
282 | /* | 297 | /* |
@@ -290,6 +305,14 @@ static int __devinit pm860x_probe(struct i2c_client *client, | |||
290 | chip->companion_addr = pdata->companion_addr; | 305 | chip->companion_addr = pdata->companion_addr; |
291 | chip->companion = i2c_new_dummy(chip->client->adapter, | 306 | chip->companion = i2c_new_dummy(chip->client->adapter, |
292 | chip->companion_addr); | 307 | chip->companion_addr); |
308 | chip->regmap_companion = regmap_init_i2c(chip->companion, | ||
309 | &pm860x_regmap_config); | ||
310 | if (IS_ERR(chip->regmap_companion)) { | ||
311 | ret = PTR_ERR(chip->regmap_companion); | ||
312 | dev_err(&chip->companion->dev, | ||
313 | "Failed to allocate register map: %d\n", ret); | ||
314 | return ret; | ||
315 | } | ||
293 | i2c_set_clientdata(chip->companion, chip); | 316 | i2c_set_clientdata(chip->companion, chip); |
294 | } | 317 | } |
295 | 318 | ||
@@ -302,7 +325,11 @@ static int __devexit pm860x_remove(struct i2c_client *client) | |||
302 | struct pm860x_chip *chip = i2c_get_clientdata(client); | 325 | struct pm860x_chip *chip = i2c_get_clientdata(client); |
303 | 326 | ||
304 | pm860x_device_exit(chip); | 327 | pm860x_device_exit(chip); |
305 | i2c_unregister_device(chip->companion); | 328 | if (chip->companion) { |
329 | regmap_exit(chip->regmap_companion); | ||
330 | i2c_unregister_device(chip->companion); | ||
331 | } | ||
332 | regmap_exit(chip->regmap); | ||
306 | kfree(chip); | 333 | kfree(chip); |
307 | return 0; | 334 | return 0; |
308 | } | 335 | } |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 053208d31fb9..cd13e9f2f5e6 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -12,6 +12,7 @@ config MFD_CORE | |||
12 | config MFD_88PM860X | 12 | config MFD_88PM860X |
13 | bool "Support Marvell 88PM8606/88PM8607" | 13 | bool "Support Marvell 88PM8606/88PM8607" |
14 | depends on I2C=y && GENERIC_HARDIRQS | 14 | depends on I2C=y && GENERIC_HARDIRQS |
15 | select REGMAP_I2C | ||
15 | select MFD_CORE | 16 | select MFD_CORE |
16 | help | 17 | help |
17 | This supports for Marvell 88PM8606/88PM8607 Power Management IC. | 18 | This supports for Marvell 88PM8606/88PM8607 Power Management IC. |
@@ -199,7 +200,7 @@ config MENELAUS | |||
199 | 200 | ||
200 | config TWL4030_CORE | 201 | config TWL4030_CORE |
201 | bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support" | 202 | bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support" |
202 | depends on I2C=y && GENERIC_HARDIRQS | 203 | depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN |
203 | help | 204 | help |
204 | Say yes here if you have TWL4030 / TWL6030 family chip on your board. | 205 | Say yes here if you have TWL4030 / TWL6030 family chip on your board. |
205 | This core driver provides register access and IRQ handling | 206 | This core driver provides register access and IRQ handling |
@@ -257,7 +258,7 @@ config TWL6040_CORE | |||
257 | 258 | ||
258 | config MFD_STMPE | 259 | config MFD_STMPE |
259 | bool "Support STMicroelectronics STMPE" | 260 | bool "Support STMicroelectronics STMPE" |
260 | depends on I2C=y && GENERIC_HARDIRQS | 261 | depends on (I2C=y || SPI_MASTER=y) && GENERIC_HARDIRQS |
261 | select MFD_CORE | 262 | select MFD_CORE |
262 | help | 263 | help |
263 | Support for the STMPE family of I/O Expanders from | 264 | Support for the STMPE family of I/O Expanders from |
@@ -278,6 +279,23 @@ config MFD_STMPE | |||
278 | Keypad: stmpe-keypad | 279 | Keypad: stmpe-keypad |
279 | Touchscreen: stmpe-ts | 280 | Touchscreen: stmpe-ts |
280 | 281 | ||
282 | menu "STMPE Interface Drivers" | ||
283 | depends on MFD_STMPE | ||
284 | |||
285 | config STMPE_I2C | ||
286 | bool "STMPE I2C Inteface" | ||
287 | depends on I2C=y | ||
288 | default y | ||
289 | help | ||
290 | This is used to enable I2C interface of STMPE | ||
291 | |||
292 | config STMPE_SPI | ||
293 | bool "STMPE SPI Inteface" | ||
294 | depends on SPI_MASTER | ||
295 | help | ||
296 | This is used to enable SPI interface of STMPE | ||
297 | endmenu | ||
298 | |||
281 | config MFD_TC3589X | 299 | config MFD_TC3589X |
282 | bool "Support Toshiba TC35892 and variants" | 300 | bool "Support Toshiba TC35892 and variants" |
283 | depends on I2C=y && GENERIC_HARDIRQS | 301 | depends on I2C=y && GENERIC_HARDIRQS |
@@ -311,7 +329,7 @@ config MFD_TC6387XB | |||
311 | 329 | ||
312 | config MFD_TC6393XB | 330 | config MFD_TC6393XB |
313 | bool "Support Toshiba TC6393XB" | 331 | bool "Support Toshiba TC6393XB" |
314 | depends on GPIOLIB && ARM | 332 | depends on GPIOLIB && ARM && HAVE_CLK |
315 | select MFD_CORE | 333 | select MFD_CORE |
316 | select MFD_TMIO | 334 | select MFD_TMIO |
317 | help | 335 | help |
@@ -399,6 +417,17 @@ config MFD_MAX8998 | |||
399 | additional drivers must be enabled in order to use the functionality | 417 | additional drivers must be enabled in order to use the functionality |
400 | of the device. | 418 | of the device. |
401 | 419 | ||
420 | config MFD_S5M_CORE | ||
421 | bool "SAMSUNG S5M Series Support" | ||
422 | depends on I2C=y && GENERIC_HARDIRQS | ||
423 | select MFD_CORE | ||
424 | select REGMAP_I2C | ||
425 | help | ||
426 | Support for the Samsung Electronics S5M MFD series. | ||
427 | This driver provies common support for accessing the device, | ||
428 | additional drivers must be enabled in order to use the functionality | ||
429 | of the device | ||
430 | |||
402 | config MFD_WM8400 | 431 | config MFD_WM8400 |
403 | tristate "Support Wolfson Microelectronics WM8400" | 432 | tristate "Support Wolfson Microelectronics WM8400" |
404 | select MFD_CORE | 433 | select MFD_CORE |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 47591fc7d0d2..b953bab934f7 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -16,6 +16,8 @@ obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o | |||
16 | obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o | 16 | obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o |
17 | 17 | ||
18 | obj-$(CONFIG_MFD_STMPE) += stmpe.o | 18 | obj-$(CONFIG_MFD_STMPE) += stmpe.o |
19 | obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o | ||
20 | obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o | ||
19 | obj-$(CONFIG_MFD_TC3589X) += tc3589x.o | 21 | obj-$(CONFIG_MFD_TC3589X) += tc3589x.o |
20 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o | 22 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o |
21 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o | 23 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o |
@@ -109,3 +111,4 @@ obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o | |||
109 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o | 111 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o |
110 | obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o | 112 | obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o |
111 | obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o | 113 | obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o |
114 | obj-$(CONFIG_MFD_S5M_CORE) += s5m-core.o s5m-irq.o | ||
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 02c42015ba51..3aa36eb5c79b 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c | |||
@@ -407,13 +407,13 @@ static int aat2870_i2c_probe(struct i2c_client *client, | |||
407 | aat2870->init(aat2870); | 407 | aat2870->init(aat2870); |
408 | 408 | ||
409 | if (aat2870->en_pin >= 0) { | 409 | if (aat2870->en_pin >= 0) { |
410 | ret = gpio_request(aat2870->en_pin, "aat2870-en"); | 410 | ret = gpio_request_one(aat2870->en_pin, GPIOF_OUT_INIT_HIGH, |
411 | "aat2870-en"); | ||
411 | if (ret < 0) { | 412 | if (ret < 0) { |
412 | dev_err(&client->dev, | 413 | dev_err(&client->dev, |
413 | "Failed to request GPIO %d\n", aat2870->en_pin); | 414 | "Failed to request GPIO %d\n", aat2870->en_pin); |
414 | goto out_kfree; | 415 | goto out_kfree; |
415 | } | 416 | } |
416 | gpio_direction_output(aat2870->en_pin, 1); | ||
417 | } | 417 | } |
418 | 418 | ||
419 | aat2870_enable(aat2870); | 419 | aat2870_enable(aat2870); |
@@ -468,9 +468,10 @@ static int aat2870_i2c_remove(struct i2c_client *client) | |||
468 | return 0; | 468 | return 0; |
469 | } | 469 | } |
470 | 470 | ||
471 | #ifdef CONFIG_PM | 471 | #ifdef CONFIG_PM_SLEEP |
472 | static int aat2870_i2c_suspend(struct i2c_client *client, pm_message_t state) | 472 | static int aat2870_i2c_suspend(struct device *dev) |
473 | { | 473 | { |
474 | struct i2c_client *client = to_i2c_client(dev); | ||
474 | struct aat2870_data *aat2870 = i2c_get_clientdata(client); | 475 | struct aat2870_data *aat2870 = i2c_get_clientdata(client); |
475 | 476 | ||
476 | aat2870_disable(aat2870); | 477 | aat2870_disable(aat2870); |
@@ -478,8 +479,9 @@ static int aat2870_i2c_suspend(struct i2c_client *client, pm_message_t state) | |||
478 | return 0; | 479 | return 0; |
479 | } | 480 | } |
480 | 481 | ||
481 | static int aat2870_i2c_resume(struct i2c_client *client) | 482 | static int aat2870_i2c_resume(struct device *dev) |
482 | { | 483 | { |
484 | struct i2c_client *client = to_i2c_client(dev); | ||
483 | struct aat2870_data *aat2870 = i2c_get_clientdata(client); | 485 | struct aat2870_data *aat2870 = i2c_get_clientdata(client); |
484 | struct aat2870_register *reg = NULL; | 486 | struct aat2870_register *reg = NULL; |
485 | int i; | 487 | int i; |
@@ -495,12 +497,12 @@ static int aat2870_i2c_resume(struct i2c_client *client) | |||
495 | 497 | ||
496 | return 0; | 498 | return 0; |
497 | } | 499 | } |
498 | #else | 500 | #endif /* CONFIG_PM_SLEEP */ |
499 | #define aat2870_i2c_suspend NULL | 501 | |
500 | #define aat2870_i2c_resume NULL | 502 | static SIMPLE_DEV_PM_OPS(aat2870_pm_ops, aat2870_i2c_suspend, |
501 | #endif /* CONFIG_PM */ | 503 | aat2870_i2c_resume); |
502 | 504 | ||
503 | static struct i2c_device_id aat2870_i2c_id_table[] = { | 505 | static const struct i2c_device_id aat2870_i2c_id_table[] = { |
504 | { "aat2870", 0 }, | 506 | { "aat2870", 0 }, |
505 | { } | 507 | { } |
506 | }; | 508 | }; |
@@ -510,11 +512,10 @@ static struct i2c_driver aat2870_i2c_driver = { | |||
510 | .driver = { | 512 | .driver = { |
511 | .name = "aat2870", | 513 | .name = "aat2870", |
512 | .owner = THIS_MODULE, | 514 | .owner = THIS_MODULE, |
515 | .pm = &aat2870_pm_ops, | ||
513 | }, | 516 | }, |
514 | .probe = aat2870_i2c_probe, | 517 | .probe = aat2870_i2c_probe, |
515 | .remove = aat2870_i2c_remove, | 518 | .remove = aat2870_i2c_remove, |
516 | .suspend = aat2870_i2c_suspend, | ||
517 | .resume = aat2870_i2c_resume, | ||
518 | .id_table = aat2870_i2c_id_table, | 519 | .id_table = aat2870_i2c_id_table, |
519 | }; | 520 | }; |
520 | 521 | ||
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c index ec10629a0b0b..bd56a764dea1 100644 --- a/drivers/mfd/ab5500-core.c +++ b/drivers/mfd/ab5500-core.c | |||
@@ -22,8 +22,8 @@ | |||
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/random.h> | 24 | #include <linux/random.h> |
25 | #include <linux/mfd/ab5500/ab5500.h> | ||
26 | #include <linux/mfd/abx500.h> | 25 | #include <linux/mfd/abx500.h> |
26 | #include <linux/mfd/abx500/ab5500.h> | ||
27 | #include <linux/list.h> | 27 | #include <linux/list.h> |
28 | #include <linux/bitops.h> | 28 | #include <linux/bitops.h> |
29 | #include <linux/spinlock.h> | 29 | #include <linux/spinlock.h> |
diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c index b7b2d3483fd4..72006940937a 100644 --- a/drivers/mfd/ab5500-debugfs.c +++ b/drivers/mfd/ab5500-debugfs.c | |||
@@ -7,8 +7,8 @@ | |||
7 | #include <linux/module.h> | 7 | #include <linux/module.h> |
8 | #include <linux/debugfs.h> | 8 | #include <linux/debugfs.h> |
9 | #include <linux/seq_file.h> | 9 | #include <linux/seq_file.h> |
10 | #include <linux/mfd/ab5500/ab5500.h> | ||
11 | #include <linux/mfd/abx500.h> | 10 | #include <linux/mfd/abx500.h> |
11 | #include <linux/mfd/abx500/ab5500.h> | ||
12 | #include <linux/uaccess.h> | 12 | #include <linux/uaccess.h> |
13 | 13 | ||
14 | #include "ab5500-core.h" | 14 | #include "ab5500-core.h" |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index d3d572b2317b..53e2a80f42fa 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/mfd/core.h> | 18 | #include <linux/mfd/core.h> |
19 | #include <linux/mfd/abx500.h> | 19 | #include <linux/mfd/abx500.h> |
20 | #include <linux/mfd/ab8500.h> | 20 | #include <linux/mfd/abx500/ab8500.h> |
21 | #include <linux/regulator/ab8500.h> | 21 | #include <linux/regulator/ab8500.h> |
22 | 22 | ||
23 | /* | 23 | /* |
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c index dedb7f65cea6..9a0211aa8897 100644 --- a/drivers/mfd/ab8500-debugfs.c +++ b/drivers/mfd/ab8500-debugfs.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | 14 | ||
15 | #include <linux/mfd/abx500.h> | 15 | #include <linux/mfd/abx500.h> |
16 | #include <linux/mfd/ab8500.h> | 16 | #include <linux/mfd/abx500/ab8500.h> |
17 | 17 | ||
18 | static u32 debug_bank; | 18 | static u32 debug_bank; |
19 | static u32 debug_address; | 19 | static u32 debug_address; |
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index e985d1701a83..c39fc716e1dc 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c | |||
@@ -18,9 +18,9 @@ | |||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | #include <linux/mfd/ab8500.h> | ||
22 | #include <linux/mfd/abx500.h> | 21 | #include <linux/mfd/abx500.h> |
23 | #include <linux/mfd/ab8500/gpadc.h> | 22 | #include <linux/mfd/abx500/ab8500.h> |
23 | #include <linux/mfd/abx500/ab8500-gpadc.h> | ||
24 | 24 | ||
25 | /* | 25 | /* |
26 | * GPADC register offsets | 26 | * GPADC register offsets |
diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c index 9be541c6b004..087fecd71ce0 100644 --- a/drivers/mfd/ab8500-i2c.c +++ b/drivers/mfd/ab8500-i2c.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/init.h> | 10 | #include <linux/init.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/mfd/ab8500.h> | 13 | #include <linux/mfd/abx500/ab8500.h> |
14 | #include <linux/mfd/db8500-prcmu.h> | 14 | #include <linux/mfd/db8500-prcmu.h> |
15 | 15 | ||
16 | static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) | 16 | static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data) |
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index f20feefac190..c28d4eb1eff0 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c | |||
@@ -7,9 +7,9 @@ | |||
7 | #include <linux/err.h> | 7 | #include <linux/err.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/platform_device.h> | 9 | #include <linux/platform_device.h> |
10 | #include <linux/mfd/ab8500.h> | ||
11 | #include <linux/mfd/abx500.h> | 10 | #include <linux/mfd/abx500.h> |
12 | #include <linux/mfd/ab8500/sysctrl.h> | 11 | #include <linux/mfd/abx500/ab8500.h> |
12 | #include <linux/mfd/abx500/ab8500-sysctrl.h> | ||
13 | 13 | ||
14 | static struct device *sysctrl_dev; | 14 | static struct device *sysctrl_dev; |
15 | 15 | ||
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c index 155fa0407882..315fef5d466a 100644 --- a/drivers/mfd/cs5535-mfd.c +++ b/drivers/mfd/cs5535-mfd.c | |||
@@ -172,14 +172,14 @@ static void __devexit cs5535_mfd_remove(struct pci_dev *pdev) | |||
172 | pci_disable_device(pdev); | 172 | pci_disable_device(pdev); |
173 | } | 173 | } |
174 | 174 | ||
175 | static struct pci_device_id cs5535_mfd_pci_tbl[] = { | 175 | static DEFINE_PCI_DEVICE_TABLE(cs5535_mfd_pci_tbl) = { |
176 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, | 176 | { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) }, |
177 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, | 177 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) }, |
178 | { 0, } | 178 | { 0, } |
179 | }; | 179 | }; |
180 | MODULE_DEVICE_TABLE(pci, cs5535_mfd_pci_tbl); | 180 | MODULE_DEVICE_TABLE(pci, cs5535_mfd_pci_tbl); |
181 | 181 | ||
182 | static struct pci_driver cs5535_mfd_drv = { | 182 | static struct pci_driver cs5535_mfd_driver = { |
183 | .name = DRV_NAME, | 183 | .name = DRV_NAME, |
184 | .id_table = cs5535_mfd_pci_tbl, | 184 | .id_table = cs5535_mfd_pci_tbl, |
185 | .probe = cs5535_mfd_probe, | 185 | .probe = cs5535_mfd_probe, |
@@ -188,12 +188,12 @@ static struct pci_driver cs5535_mfd_drv = { | |||
188 | 188 | ||
189 | static int __init cs5535_mfd_init(void) | 189 | static int __init cs5535_mfd_init(void) |
190 | { | 190 | { |
191 | return pci_register_driver(&cs5535_mfd_drv); | 191 | return pci_register_driver(&cs5535_mfd_driver); |
192 | } | 192 | } |
193 | 193 | ||
194 | static void __exit cs5535_mfd_exit(void) | 194 | static void __exit cs5535_mfd_exit(void) |
195 | { | 195 | { |
196 | pci_unregister_driver(&cs5535_mfd_drv); | 196 | pci_unregister_driver(&cs5535_mfd_driver); |
197 | } | 197 | } |
198 | 198 | ||
199 | module_init(cs5535_mfd_init); | 199 | module_init(cs5535_mfd_init); |
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c index 8ad88da647b9..7710227d284e 100644 --- a/drivers/mfd/dm355evm_msp.c +++ b/drivers/mfd/dm355evm_msp.c | |||
@@ -308,8 +308,7 @@ static int add_children(struct i2c_client *client) | |||
308 | for (i = 0; i < ARRAY_SIZE(config_inputs); i++) { | 308 | for (i = 0; i < ARRAY_SIZE(config_inputs); i++) { |
309 | int gpio = dm355evm_msp_gpio.base + config_inputs[i].offset; | 309 | int gpio = dm355evm_msp_gpio.base + config_inputs[i].offset; |
310 | 310 | ||
311 | gpio_request(gpio, config_inputs[i].label); | 311 | gpio_request_one(gpio, GPIOF_IN, config_inputs[i].label); |
312 | gpio_direction_input(gpio); | ||
313 | 312 | ||
314 | /* make it easy for userspace to see these */ | 313 | /* make it easy for userspace to see these */ |
315 | gpio_export(gpio, false); | 314 | gpio_export(gpio, false); |
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c index 97c27762174f..b76657eb0c51 100644 --- a/drivers/mfd/intel_msic.c +++ b/drivers/mfd/intel_msic.c | |||
@@ -485,17 +485,7 @@ static struct platform_driver intel_msic_driver = { | |||
485 | }, | 485 | }, |
486 | }; | 486 | }; |
487 | 487 | ||
488 | static int __init intel_msic_init(void) | 488 | module_platform_driver(intel_msic_driver); |
489 | { | ||
490 | return platform_driver_register(&intel_msic_driver); | ||
491 | } | ||
492 | module_init(intel_msic_init); | ||
493 | |||
494 | static void __exit intel_msic_exit(void) | ||
495 | { | ||
496 | platform_driver_unregister(&intel_msic_driver); | ||
497 | } | ||
498 | module_exit(intel_msic_exit); | ||
499 | 489 | ||
500 | MODULE_DESCRIPTION("Driver for Intel MSIC"); | 490 | MODULE_DESCRIPTION("Driver for Intel MSIC"); |
501 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); | 491 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>"); |
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c index ef39528088f2..87662a17dec6 100644 --- a/drivers/mfd/jz4740-adc.c +++ b/drivers/mfd/jz4740-adc.c | |||
@@ -181,7 +181,7 @@ static struct resource jz4740_battery_resources[] = { | |||
181 | }, | 181 | }, |
182 | }; | 182 | }; |
183 | 183 | ||
184 | const struct mfd_cell jz4740_adc_cells[] = { | 184 | static struct mfd_cell jz4740_adc_cells[] = { |
185 | { | 185 | { |
186 | .id = 0, | 186 | .id = 0, |
187 | .name = "jz4740-hwmon", | 187 | .name = "jz4740-hwmon", |
@@ -338,17 +338,7 @@ static struct platform_driver jz4740_adc_driver = { | |||
338 | }, | 338 | }, |
339 | }; | 339 | }; |
340 | 340 | ||
341 | static int __init jz4740_adc_init(void) | 341 | module_platform_driver(jz4740_adc_driver); |
342 | { | ||
343 | return platform_driver_register(&jz4740_adc_driver); | ||
344 | } | ||
345 | module_init(jz4740_adc_init); | ||
346 | |||
347 | static void __exit jz4740_adc_exit(void) | ||
348 | { | ||
349 | platform_driver_unregister(&jz4740_adc_driver); | ||
350 | } | ||
351 | module_exit(jz4740_adc_exit); | ||
352 | 342 | ||
353 | MODULE_DESCRIPTION("JZ4740 SoC ADC driver"); | 343 | MODULE_DESCRIPTION("JZ4740 SoC ADC driver"); |
354 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | 344 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); |
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c index ea1169b04779..abc421364a45 100644 --- a/drivers/mfd/lpc_sch.c +++ b/drivers/mfd/lpc_sch.c | |||
@@ -74,7 +74,7 @@ static struct mfd_cell tunnelcreek_cells[] = { | |||
74 | }, | 74 | }, |
75 | }; | 75 | }; |
76 | 76 | ||
77 | static struct pci_device_id lpc_sch_ids[] = { | 77 | static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = { |
78 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, | 78 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, |
79 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) }, | 79 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) }, |
80 | { 0, } | 80 | { 0, } |
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c index 0219115e00c7..d9e4b36edee9 100644 --- a/drivers/mfd/max8925-i2c.c +++ b/drivers/mfd/max8925-i2c.c | |||
@@ -161,6 +161,8 @@ static int __devinit max8925_probe(struct i2c_client *client, | |||
161 | chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); | 161 | chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR); |
162 | i2c_set_clientdata(chip->adc, chip); | 162 | i2c_set_clientdata(chip->adc, chip); |
163 | 163 | ||
164 | device_init_wakeup(&client->dev, 1); | ||
165 | |||
164 | max8925_device_init(chip, pdata); | 166 | max8925_device_init(chip, pdata); |
165 | 167 | ||
166 | return 0; | 168 | return 0; |
@@ -177,10 +179,35 @@ static int __devexit max8925_remove(struct i2c_client *client) | |||
177 | return 0; | 179 | return 0; |
178 | } | 180 | } |
179 | 181 | ||
182 | #ifdef CONFIG_PM_SLEEP | ||
183 | static int max8925_suspend(struct device *dev) | ||
184 | { | ||
185 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | ||
186 | struct max8925_chip *chip = i2c_get_clientdata(client); | ||
187 | |||
188 | if (device_may_wakeup(dev) && chip->wakeup_flag) | ||
189 | enable_irq_wake(chip->core_irq); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int max8925_resume(struct device *dev) | ||
194 | { | ||
195 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); | ||
196 | struct max8925_chip *chip = i2c_get_clientdata(client); | ||
197 | |||
198 | if (device_may_wakeup(dev) && chip->wakeup_flag) | ||
199 | disable_irq_wake(chip->core_irq); | ||
200 | return 0; | ||
201 | } | ||
202 | #endif | ||
203 | |||
204 | static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume); | ||
205 | |||
180 | static struct i2c_driver max8925_driver = { | 206 | static struct i2c_driver max8925_driver = { |
181 | .driver = { | 207 | .driver = { |
182 | .name = "max8925", | 208 | .name = "max8925", |
183 | .owner = THIS_MODULE, | 209 | .owner = THIS_MODULE, |
210 | .pm = &max8925_pm_ops, | ||
184 | }, | 211 | }, |
185 | .probe = max8925_probe, | 212 | .probe = max8925_probe, |
186 | .remove = __devexit_p(max8925_remove), | 213 | .remove = __devexit_p(max8925_remove), |
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c index 5be53ae9b61c..cb83a7ab53e7 100644 --- a/drivers/mfd/max8997.c +++ b/drivers/mfd/max8997.c | |||
@@ -43,7 +43,8 @@ static struct mfd_cell max8997_devs[] = { | |||
43 | { .name = "max8997-battery", }, | 43 | { .name = "max8997-battery", }, |
44 | { .name = "max8997-haptic", }, | 44 | { .name = "max8997-haptic", }, |
45 | { .name = "max8997-muic", }, | 45 | { .name = "max8997-muic", }, |
46 | { .name = "max8997-flash", }, | 46 | { .name = "max8997-led", .id = 1 }, |
47 | { .name = "max8997-led", .id = 2 }, | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) | 50 | int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest) |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c index de4096aee248..6ef56d28c056 100644 --- a/drivers/mfd/max8998.c +++ b/drivers/mfd/max8998.c | |||
@@ -176,6 +176,8 @@ static int max8998_i2c_probe(struct i2c_client *i2c, | |||
176 | if (ret < 0) | 176 | if (ret < 0) |
177 | goto err; | 177 | goto err; |
178 | 178 | ||
179 | device_init_wakeup(max8998->dev, max8998->wakeup); | ||
180 | |||
179 | return ret; | 181 | return ret; |
180 | 182 | ||
181 | err: | 183 | err: |
@@ -210,7 +212,7 @@ static int max8998_suspend(struct device *dev) | |||
210 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 212 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
211 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | 213 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); |
212 | 214 | ||
213 | if (max8998->wakeup) | 215 | if (device_may_wakeup(dev)) |
214 | irq_set_irq_wake(max8998->irq, 1); | 216 | irq_set_irq_wake(max8998->irq, 1); |
215 | return 0; | 217 | return 0; |
216 | } | 218 | } |
@@ -220,7 +222,7 @@ static int max8998_resume(struct device *dev) | |||
220 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); | 222 | struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); |
221 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | 223 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); |
222 | 224 | ||
223 | if (max8998->wakeup) | 225 | if (device_may_wakeup(dev)) |
224 | irq_set_irq_wake(max8998->irq, 0); | 226 | irq_set_irq_wake(max8998->irq, 0); |
225 | /* | 227 | /* |
226 | * In LP3974, if IRQ registers are not "read & clear" | 228 | * In LP3974, if IRQ registers are not "read & clear" |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index e9619acc0237..7122386b4e3c 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -18,11 +18,15 @@ | |||
18 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
19 | #include <linux/mfd/core.h> | 19 | #include <linux/mfd/core.h> |
20 | #include <linux/mfd/mc13xxx.h> | 20 | #include <linux/mfd/mc13xxx.h> |
21 | #include <linux/of.h> | ||
22 | #include <linux/of_device.h> | ||
23 | #include <linux/of_gpio.h> | ||
21 | 24 | ||
22 | struct mc13xxx { | 25 | struct mc13xxx { |
23 | struct spi_device *spidev; | 26 | struct spi_device *spidev; |
24 | struct mutex lock; | 27 | struct mutex lock; |
25 | int irq; | 28 | int irq; |
29 | int flags; | ||
26 | 30 | ||
27 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; | 31 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; |
28 | void *irqdata[MC13XXX_NUM_IRQ]; | 32 | void *irqdata[MC13XXX_NUM_IRQ]; |
@@ -550,10 +554,7 @@ static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx) | |||
550 | 554 | ||
551 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) | 555 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) |
552 | { | 556 | { |
553 | struct mc13xxx_platform_data *pdata = | 557 | return mc13xxx->flags; |
554 | dev_get_platdata(&mc13xxx->spidev->dev); | ||
555 | |||
556 | return pdata->flags; | ||
557 | } | 558 | } |
558 | EXPORT_SYMBOL(mc13xxx_get_flags); | 559 | EXPORT_SYMBOL(mc13xxx_get_flags); |
559 | 560 | ||
@@ -615,13 +616,13 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, | |||
615 | break; | 616 | break; |
616 | 617 | ||
617 | case MC13XXX_ADC_MODE_SINGLE_CHAN: | 618 | case MC13XXX_ADC_MODE_SINGLE_CHAN: |
618 | adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK; | 619 | adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK; |
619 | adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT; | 620 | adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT; |
620 | adc1 |= MC13XXX_ADC1_RAND; | 621 | adc1 |= MC13XXX_ADC1_RAND; |
621 | break; | 622 | break; |
622 | 623 | ||
623 | case MC13XXX_ADC_MODE_MULT_CHAN: | 624 | case MC13XXX_ADC_MODE_MULT_CHAN: |
624 | adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK; | 625 | adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK; |
625 | adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; | 626 | adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT; |
626 | break; | 627 | break; |
627 | 628 | ||
@@ -696,17 +697,67 @@ static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | |||
696 | return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0); | 697 | return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0); |
697 | } | 698 | } |
698 | 699 | ||
700 | #ifdef CONFIG_OF | ||
701 | static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) | ||
702 | { | ||
703 | struct device_node *np = mc13xxx->spidev->dev.of_node; | ||
704 | |||
705 | if (!np) | ||
706 | return -ENODEV; | ||
707 | |||
708 | if (of_get_property(np, "fsl,mc13xxx-uses-adc", NULL)) | ||
709 | mc13xxx->flags |= MC13XXX_USE_ADC; | ||
710 | |||
711 | if (of_get_property(np, "fsl,mc13xxx-uses-codec", NULL)) | ||
712 | mc13xxx->flags |= MC13XXX_USE_CODEC; | ||
713 | |||
714 | if (of_get_property(np, "fsl,mc13xxx-uses-rtc", NULL)) | ||
715 | mc13xxx->flags |= MC13XXX_USE_RTC; | ||
716 | |||
717 | if (of_get_property(np, "fsl,mc13xxx-uses-touch", NULL)) | ||
718 | mc13xxx->flags |= MC13XXX_USE_TOUCHSCREEN; | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | #else | ||
723 | static inline int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) | ||
724 | { | ||
725 | return -ENODEV; | ||
726 | } | ||
727 | #endif | ||
728 | |||
729 | static const struct spi_device_id mc13xxx_device_id[] = { | ||
730 | { | ||
731 | .name = "mc13783", | ||
732 | .driver_data = MC13XXX_ID_MC13783, | ||
733 | }, { | ||
734 | .name = "mc13892", | ||
735 | .driver_data = MC13XXX_ID_MC13892, | ||
736 | }, { | ||
737 | /* sentinel */ | ||
738 | } | ||
739 | }; | ||
740 | MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); | ||
741 | |||
742 | static const struct of_device_id mc13xxx_dt_ids[] = { | ||
743 | { .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, }, | ||
744 | { .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, }, | ||
745 | { /* sentinel */ } | ||
746 | }; | ||
747 | MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); | ||
748 | |||
699 | static int mc13xxx_probe(struct spi_device *spi) | 749 | static int mc13xxx_probe(struct spi_device *spi) |
700 | { | 750 | { |
751 | const struct of_device_id *of_id; | ||
752 | struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); | ||
701 | struct mc13xxx *mc13xxx; | 753 | struct mc13xxx *mc13xxx; |
702 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); | 754 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); |
703 | enum mc13xxx_id id; | 755 | enum mc13xxx_id id; |
704 | int ret; | 756 | int ret; |
705 | 757 | ||
706 | if (!pdata) { | 758 | of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); |
707 | dev_err(&spi->dev, "invalid platform data\n"); | 759 | if (of_id) |
708 | return -EINVAL; | 760 | sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data]; |
709 | } | ||
710 | 761 | ||
711 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); | 762 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); |
712 | if (!mc13xxx) | 763 | if (!mc13xxx) |
@@ -749,28 +800,33 @@ err_revision: | |||
749 | 800 | ||
750 | mc13xxx_unlock(mc13xxx); | 801 | mc13xxx_unlock(mc13xxx); |
751 | 802 | ||
752 | if (pdata->flags & MC13XXX_USE_ADC) | 803 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) |
804 | mc13xxx->flags = pdata->flags; | ||
805 | |||
806 | if (mc13xxx->flags & MC13XXX_USE_ADC) | ||
753 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); | 807 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); |
754 | 808 | ||
755 | if (pdata->flags & MC13XXX_USE_CODEC) | 809 | if (mc13xxx->flags & MC13XXX_USE_CODEC) |
756 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); | 810 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); |
757 | 811 | ||
758 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", | 812 | if (mc13xxx->flags & MC13XXX_USE_RTC) |
759 | &pdata->regulators, sizeof(pdata->regulators)); | ||
760 | |||
761 | if (pdata->flags & MC13XXX_USE_RTC) | ||
762 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); | 813 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); |
763 | 814 | ||
764 | if (pdata->flags & MC13XXX_USE_TOUCHSCREEN) | 815 | if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) |
765 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); | 816 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); |
766 | 817 | ||
767 | if (pdata->leds) | 818 | if (pdata) { |
819 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", | ||
820 | &pdata->regulators, sizeof(pdata->regulators)); | ||
768 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", | 821 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", |
769 | pdata->leds, sizeof(*pdata->leds)); | 822 | pdata->leds, sizeof(*pdata->leds)); |
770 | |||
771 | if (pdata->buttons) | ||
772 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", | 823 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", |
773 | pdata->buttons, sizeof(*pdata->buttons)); | 824 | pdata->buttons, sizeof(*pdata->buttons)); |
825 | } else { | ||
826 | mc13xxx_add_subdevice(mc13xxx, "%s-regulator"); | ||
827 | mc13xxx_add_subdevice(mc13xxx, "%s-led"); | ||
828 | mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton"); | ||
829 | } | ||
774 | 830 | ||
775 | return 0; | 831 | return 0; |
776 | } | 832 | } |
@@ -788,25 +844,12 @@ static int __devexit mc13xxx_remove(struct spi_device *spi) | |||
788 | return 0; | 844 | return 0; |
789 | } | 845 | } |
790 | 846 | ||
791 | static const struct spi_device_id mc13xxx_device_id[] = { | ||
792 | { | ||
793 | .name = "mc13783", | ||
794 | .driver_data = MC13XXX_ID_MC13783, | ||
795 | }, { | ||
796 | .name = "mc13892", | ||
797 | .driver_data = MC13XXX_ID_MC13892, | ||
798 | }, { | ||
799 | /* sentinel */ | ||
800 | } | ||
801 | }; | ||
802 | MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); | ||
803 | |||
804 | static struct spi_driver mc13xxx_driver = { | 847 | static struct spi_driver mc13xxx_driver = { |
805 | .id_table = mc13xxx_device_id, | 848 | .id_table = mc13xxx_device_id, |
806 | .driver = { | 849 | .driver = { |
807 | .name = "mc13xxx", | 850 | .name = "mc13xxx", |
808 | .bus = &spi_bus_type, | ||
809 | .owner = THIS_MODULE, | 851 | .owner = THIS_MODULE, |
852 | .of_match_table = mc13xxx_dt_ids, | ||
810 | }, | 853 | }, |
811 | .probe = mc13xxx_probe, | 854 | .probe = mc13xxx_probe, |
812 | .remove = __devexit_p(mc13xxx_remove), | 855 | .remove = __devexit_p(mc13xxx_remove), |
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c index 84815f9ef636..63be60bc3455 100644 --- a/drivers/mfd/mcp-core.c +++ b/drivers/mfd/mcp-core.c | |||
@@ -26,9 +26,35 @@ | |||
26 | #define to_mcp(d) container_of(d, struct mcp, attached_device) | 26 | #define to_mcp(d) container_of(d, struct mcp, attached_device) |
27 | #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) | 27 | #define to_mcp_driver(d) container_of(d, struct mcp_driver, drv) |
28 | 28 | ||
29 | static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id, | ||
30 | const char *codec) | ||
31 | { | ||
32 | while (id->name[0]) { | ||
33 | if (strcmp(codec, id->name) == 0) | ||
34 | return id; | ||
35 | id++; | ||
36 | } | ||
37 | return NULL; | ||
38 | } | ||
39 | |||
40 | const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp) | ||
41 | { | ||
42 | const struct mcp_driver *driver = | ||
43 | to_mcp_driver(mcp->attached_device.driver); | ||
44 | |||
45 | return mcp_match_id(driver->id_table, mcp->codec); | ||
46 | } | ||
47 | EXPORT_SYMBOL(mcp_get_device_id); | ||
48 | |||
29 | static int mcp_bus_match(struct device *dev, struct device_driver *drv) | 49 | static int mcp_bus_match(struct device *dev, struct device_driver *drv) |
30 | { | 50 | { |
31 | return 1; | 51 | const struct mcp *mcp = to_mcp(dev); |
52 | const struct mcp_driver *driver = to_mcp_driver(drv); | ||
53 | |||
54 | if (driver->id_table) | ||
55 | return !!mcp_match_id(driver->id_table, mcp->codec); | ||
56 | |||
57 | return 0; | ||
32 | } | 58 | } |
33 | 59 | ||
34 | static int mcp_bus_probe(struct device *dev) | 60 | static int mcp_bus_probe(struct device *dev) |
@@ -74,9 +100,18 @@ static int mcp_bus_resume(struct device *dev) | |||
74 | return ret; | 100 | return ret; |
75 | } | 101 | } |
76 | 102 | ||
103 | static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
104 | { | ||
105 | struct mcp *mcp = to_mcp(dev); | ||
106 | |||
107 | add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec); | ||
108 | return 0; | ||
109 | } | ||
110 | |||
77 | static struct bus_type mcp_bus_type = { | 111 | static struct bus_type mcp_bus_type = { |
78 | .name = "mcp", | 112 | .name = "mcp", |
79 | .match = mcp_bus_match, | 113 | .match = mcp_bus_match, |
114 | .uevent = mcp_bus_uevent, | ||
80 | .probe = mcp_bus_probe, | 115 | .probe = mcp_bus_probe, |
81 | .remove = mcp_bus_remove, | 116 | .remove = mcp_bus_remove, |
82 | .suspend = mcp_bus_suspend, | 117 | .suspend = mcp_bus_suspend, |
@@ -212,9 +247,14 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size) | |||
212 | } | 247 | } |
213 | EXPORT_SYMBOL(mcp_host_alloc); | 248 | EXPORT_SYMBOL(mcp_host_alloc); |
214 | 249 | ||
215 | int mcp_host_register(struct mcp *mcp) | 250 | int mcp_host_register(struct mcp *mcp, void *pdata) |
216 | { | 251 | { |
252 | if (!mcp->codec) | ||
253 | return -EINVAL; | ||
254 | |||
255 | mcp->attached_device.platform_data = pdata; | ||
217 | dev_set_name(&mcp->attached_device, "mcp0"); | 256 | dev_set_name(&mcp->attached_device, "mcp0"); |
257 | request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec); | ||
218 | return device_register(&mcp->attached_device); | 258 | return device_register(&mcp->attached_device); |
219 | } | 259 | } |
220 | EXPORT_SYMBOL(mcp_host_register); | 260 | EXPORT_SYMBOL(mcp_host_register); |
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c index 2dab02d9ac8b..9adc2eb69492 100644 --- a/drivers/mfd/mcp-sa11x0.c +++ b/drivers/mfd/mcp-sa11x0.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/mfd/mcp.h> | 21 | #include <linux/mfd/mcp.h> |
22 | #include <linux/io.h> | ||
22 | 23 | ||
23 | #include <mach/dma.h> | 24 | #include <mach/dma.h> |
24 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
@@ -26,12 +27,19 @@ | |||
26 | #include <asm/system.h> | 27 | #include <asm/system.h> |
27 | #include <mach/mcp.h> | 28 | #include <mach/mcp.h> |
28 | 29 | ||
29 | #include <mach/assabet.h> | 30 | /* Register offsets */ |
30 | 31 | #define MCCR0 0x00 | |
32 | #define MCDR0 0x08 | ||
33 | #define MCDR1 0x0C | ||
34 | #define MCDR2 0x10 | ||
35 | #define MCSR 0x18 | ||
36 | #define MCCR1 0x00 | ||
31 | 37 | ||
32 | struct mcp_sa11x0 { | 38 | struct mcp_sa11x0 { |
33 | u32 mccr0; | 39 | u32 mccr0; |
34 | u32 mccr1; | 40 | u32 mccr1; |
41 | unsigned char *mccr0_base; | ||
42 | unsigned char *mccr1_base; | ||
35 | }; | 43 | }; |
36 | 44 | ||
37 | #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) | 45 | #define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp)) |
@@ -39,25 +47,25 @@ struct mcp_sa11x0 { | |||
39 | static void | 47 | static void |
40 | mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) | 48 | mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor) |
41 | { | 49 | { |
42 | unsigned int mccr0; | 50 | struct mcp_sa11x0 *priv = priv(mcp); |
43 | 51 | ||
44 | divisor /= 32; | 52 | divisor /= 32; |
45 | 53 | ||
46 | mccr0 = Ser4MCCR0 & ~0x00007f00; | 54 | priv->mccr0 &= ~0x00007f00; |
47 | mccr0 |= divisor << 8; | 55 | priv->mccr0 |= divisor << 8; |
48 | Ser4MCCR0 = mccr0; | 56 | __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); |
49 | } | 57 | } |
50 | 58 | ||
51 | static void | 59 | static void |
52 | mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) | 60 | mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor) |
53 | { | 61 | { |
54 | unsigned int mccr0; | 62 | struct mcp_sa11x0 *priv = priv(mcp); |
55 | 63 | ||
56 | divisor /= 32; | 64 | divisor /= 32; |
57 | 65 | ||
58 | mccr0 = Ser4MCCR0 & ~0x0000007f; | 66 | priv->mccr0 &= ~0x0000007f; |
59 | mccr0 |= divisor; | 67 | priv->mccr0 |= divisor; |
60 | Ser4MCCR0 = mccr0; | 68 | __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); |
61 | } | 69 | } |
62 | 70 | ||
63 | /* | 71 | /* |
@@ -71,12 +79,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val) | |||
71 | { | 79 | { |
72 | int ret = -ETIME; | 80 | int ret = -ETIME; |
73 | int i; | 81 | int i; |
82 | u32 mcpreg; | ||
83 | struct mcp_sa11x0 *priv = priv(mcp); | ||
74 | 84 | ||
75 | Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff); | 85 | mcpreg = reg << 17 | MCDR2_Wr | (val & 0xffff); |
86 | __raw_writel(mcpreg, priv->mccr0_base + MCDR2); | ||
76 | 87 | ||
77 | for (i = 0; i < 2; i++) { | 88 | for (i = 0; i < 2; i++) { |
78 | udelay(mcp->rw_timeout); | 89 | udelay(mcp->rw_timeout); |
79 | if (Ser4MCSR & MCSR_CWC) { | 90 | mcpreg = __raw_readl(priv->mccr0_base + MCSR); |
91 | if (mcpreg & MCSR_CWC) { | ||
80 | ret = 0; | 92 | ret = 0; |
81 | break; | 93 | break; |
82 | } | 94 | } |
@@ -97,13 +109,18 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) | |||
97 | { | 109 | { |
98 | int ret = -ETIME; | 110 | int ret = -ETIME; |
99 | int i; | 111 | int i; |
112 | u32 mcpreg; | ||
113 | struct mcp_sa11x0 *priv = priv(mcp); | ||
100 | 114 | ||
101 | Ser4MCDR2 = reg << 17 | MCDR2_Rd; | 115 | mcpreg = reg << 17 | MCDR2_Rd; |
116 | __raw_writel(mcpreg, priv->mccr0_base + MCDR2); | ||
102 | 117 | ||
103 | for (i = 0; i < 2; i++) { | 118 | for (i = 0; i < 2; i++) { |
104 | udelay(mcp->rw_timeout); | 119 | udelay(mcp->rw_timeout); |
105 | if (Ser4MCSR & MCSR_CRC) { | 120 | mcpreg = __raw_readl(priv->mccr0_base + MCSR); |
106 | ret = Ser4MCDR2 & 0xffff; | 121 | if (mcpreg & MCSR_CRC) { |
122 | ret = __raw_readl(priv->mccr0_base + MCDR2) | ||
123 | & 0xffff; | ||
107 | break; | 124 | break; |
108 | } | 125 | } |
109 | } | 126 | } |
@@ -116,13 +133,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg) | |||
116 | 133 | ||
117 | static void mcp_sa11x0_enable(struct mcp *mcp) | 134 | static void mcp_sa11x0_enable(struct mcp *mcp) |
118 | { | 135 | { |
119 | Ser4MCSR = -1; | 136 | struct mcp_sa11x0 *priv = priv(mcp); |
120 | Ser4MCCR0 |= MCCR0_MCE; | 137 | |
138 | __raw_writel(-1, priv->mccr0_base + MCSR); | ||
139 | priv->mccr0 |= MCCR0_MCE; | ||
140 | __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); | ||
121 | } | 141 | } |
122 | 142 | ||
123 | static void mcp_sa11x0_disable(struct mcp *mcp) | 143 | static void mcp_sa11x0_disable(struct mcp *mcp) |
124 | { | 144 | { |
125 | Ser4MCCR0 &= ~MCCR0_MCE; | 145 | struct mcp_sa11x0 *priv = priv(mcp); |
146 | |||
147 | priv->mccr0 &= ~MCCR0_MCE; | ||
148 | __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); | ||
126 | } | 149 | } |
127 | 150 | ||
128 | /* | 151 | /* |
@@ -142,50 +165,69 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) | |||
142 | struct mcp_plat_data *data = pdev->dev.platform_data; | 165 | struct mcp_plat_data *data = pdev->dev.platform_data; |
143 | struct mcp *mcp; | 166 | struct mcp *mcp; |
144 | int ret; | 167 | int ret; |
168 | struct mcp_sa11x0 *priv; | ||
169 | struct resource *res_mem0, *res_mem1; | ||
170 | u32 size0, size1; | ||
145 | 171 | ||
146 | if (!data) | 172 | if (!data) |
147 | return -ENODEV; | 173 | return -ENODEV; |
148 | 174 | ||
149 | if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp")) | 175 | if (!data->codec) |
176 | return -ENODEV; | ||
177 | |||
178 | res_mem0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
179 | if (!res_mem0) | ||
180 | return -ENODEV; | ||
181 | size0 = res_mem0->end - res_mem0->start + 1; | ||
182 | |||
183 | res_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
184 | if (!res_mem1) | ||
185 | return -ENODEV; | ||
186 | size1 = res_mem1->end - res_mem1->start + 1; | ||
187 | |||
188 | if (!request_mem_region(res_mem0->start, size0, "sa11x0-mcp")) | ||
150 | return -EBUSY; | 189 | return -EBUSY; |
151 | 190 | ||
191 | if (!request_mem_region(res_mem1->start, size1, "sa11x0-mcp")) { | ||
192 | ret = -EBUSY; | ||
193 | goto release; | ||
194 | } | ||
195 | |||
152 | mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0)); | 196 | mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0)); |
153 | if (!mcp) { | 197 | if (!mcp) { |
154 | ret = -ENOMEM; | 198 | ret = -ENOMEM; |
155 | goto release; | 199 | goto release2; |
156 | } | 200 | } |
157 | 201 | ||
202 | priv = priv(mcp); | ||
203 | |||
158 | mcp->owner = THIS_MODULE; | 204 | mcp->owner = THIS_MODULE; |
159 | mcp->ops = &mcp_sa11x0; | 205 | mcp->ops = &mcp_sa11x0; |
160 | mcp->sclk_rate = data->sclk_rate; | 206 | mcp->sclk_rate = data->sclk_rate; |
161 | mcp->dma_audio_rd = DMA_Ser4MCP0Rd; | 207 | mcp->dma_audio_rd = DDAR_DevAdd(res_mem0->start + MCDR0) |
162 | mcp->dma_audio_wr = DMA_Ser4MCP0Wr; | 208 | + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev; |
163 | mcp->dma_telco_rd = DMA_Ser4MCP1Rd; | 209 | mcp->dma_audio_wr = DDAR_DevAdd(res_mem0->start + MCDR0) |
164 | mcp->dma_telco_wr = DMA_Ser4MCP1Wr; | 210 | + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev; |
165 | mcp->gpio_base = data->gpio_base; | 211 | mcp->dma_telco_rd = DDAR_DevAdd(res_mem0->start + MCDR1) |
212 | + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev; | ||
213 | mcp->dma_telco_wr = DDAR_DevAdd(res_mem0->start + MCDR1) | ||
214 | + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev; | ||
215 | mcp->codec = data->codec; | ||
166 | 216 | ||
167 | platform_set_drvdata(pdev, mcp); | 217 | platform_set_drvdata(pdev, mcp); |
168 | 218 | ||
169 | if (machine_is_assabet()) { | ||
170 | ASSABET_BCR_set(ASSABET_BCR_CODEC_RST); | ||
171 | } | ||
172 | |||
173 | /* | ||
174 | * Setup the PPC unit correctly. | ||
175 | */ | ||
176 | PPDR &= ~PPC_RXD4; | ||
177 | PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM; | ||
178 | PSDR |= PPC_RXD4; | ||
179 | PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); | ||
180 | PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM); | ||
181 | |||
182 | /* | 219 | /* |
183 | * Initialise device. Note that we initially | 220 | * Initialise device. Note that we initially |
184 | * set the sampling rate to minimum. | 221 | * set the sampling rate to minimum. |
185 | */ | 222 | */ |
186 | Ser4MCSR = -1; | 223 | priv->mccr0_base = ioremap(res_mem0->start, size0); |
187 | Ser4MCCR1 = data->mccr1; | 224 | priv->mccr1_base = ioremap(res_mem1->start, size1); |
188 | Ser4MCCR0 = data->mccr0 | 0x7f7f; | 225 | |
226 | __raw_writel(-1, priv->mccr0_base + MCSR); | ||
227 | priv->mccr1 = data->mccr1; | ||
228 | priv->mccr0 = data->mccr0 | 0x7f7f; | ||
229 | __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); | ||
230 | __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1); | ||
189 | 231 | ||
190 | /* | 232 | /* |
191 | * Calculate the read/write timeout (us) from the bit clock | 233 | * Calculate the read/write timeout (us) from the bit clock |
@@ -195,36 +237,53 @@ static int mcp_sa11x0_probe(struct platform_device *pdev) | |||
195 | mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / | 237 | mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) / |
196 | mcp->sclk_rate; | 238 | mcp->sclk_rate; |
197 | 239 | ||
198 | ret = mcp_host_register(mcp); | 240 | ret = mcp_host_register(mcp, data->codec_pdata); |
199 | if (ret == 0) | 241 | if (ret == 0) |
200 | goto out; | 242 | goto out; |
201 | 243 | ||
244 | release2: | ||
245 | release_mem_region(res_mem1->start, size1); | ||
202 | release: | 246 | release: |
203 | release_mem_region(0x80060000, 0x60); | 247 | release_mem_region(res_mem0->start, size0); |
204 | platform_set_drvdata(pdev, NULL); | 248 | platform_set_drvdata(pdev, NULL); |
205 | 249 | ||
206 | out: | 250 | out: |
207 | return ret; | 251 | return ret; |
208 | } | 252 | } |
209 | 253 | ||
210 | static int mcp_sa11x0_remove(struct platform_device *dev) | 254 | static int mcp_sa11x0_remove(struct platform_device *pdev) |
211 | { | 255 | { |
212 | struct mcp *mcp = platform_get_drvdata(dev); | 256 | struct mcp *mcp = platform_get_drvdata(pdev); |
257 | struct mcp_sa11x0 *priv = priv(mcp); | ||
258 | struct resource *res_mem; | ||
259 | u32 size; | ||
213 | 260 | ||
214 | platform_set_drvdata(dev, NULL); | 261 | platform_set_drvdata(pdev, NULL); |
215 | mcp_host_unregister(mcp); | 262 | mcp_host_unregister(mcp); |
216 | release_mem_region(0x80060000, 0x60); | ||
217 | 263 | ||
264 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
265 | if (res_mem) { | ||
266 | size = res_mem->end - res_mem->start + 1; | ||
267 | release_mem_region(res_mem->start, size); | ||
268 | } | ||
269 | res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
270 | if (res_mem) { | ||
271 | size = res_mem->end - res_mem->start + 1; | ||
272 | release_mem_region(res_mem->start, size); | ||
273 | } | ||
274 | iounmap(priv->mccr0_base); | ||
275 | iounmap(priv->mccr1_base); | ||
218 | return 0; | 276 | return 0; |
219 | } | 277 | } |
220 | 278 | ||
221 | static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) | 279 | static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) |
222 | { | 280 | { |
223 | struct mcp *mcp = platform_get_drvdata(dev); | 281 | struct mcp *mcp = platform_get_drvdata(dev); |
282 | struct mcp_sa11x0 *priv = priv(mcp); | ||
283 | u32 mccr0; | ||
224 | 284 | ||
225 | priv(mcp)->mccr0 = Ser4MCCR0; | 285 | mccr0 = priv->mccr0 & ~MCCR0_MCE; |
226 | priv(mcp)->mccr1 = Ser4MCCR1; | 286 | __raw_writel(mccr0, priv->mccr0_base + MCCR0); |
227 | Ser4MCCR0 &= ~MCCR0_MCE; | ||
228 | 287 | ||
229 | return 0; | 288 | return 0; |
230 | } | 289 | } |
@@ -232,9 +291,10 @@ static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state) | |||
232 | static int mcp_sa11x0_resume(struct platform_device *dev) | 291 | static int mcp_sa11x0_resume(struct platform_device *dev) |
233 | { | 292 | { |
234 | struct mcp *mcp = platform_get_drvdata(dev); | 293 | struct mcp *mcp = platform_get_drvdata(dev); |
294 | struct mcp_sa11x0 *priv = priv(mcp); | ||
235 | 295 | ||
236 | Ser4MCCR1 = priv(mcp)->mccr1; | 296 | __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0); |
237 | Ser4MCCR0 = priv(mcp)->mccr0; | 297 | __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1); |
238 | 298 | ||
239 | return 0; | 299 | return 0; |
240 | } | 300 | } |
@@ -251,24 +311,14 @@ static struct platform_driver mcp_sa11x0_driver = { | |||
251 | .resume = mcp_sa11x0_resume, | 311 | .resume = mcp_sa11x0_resume, |
252 | .driver = { | 312 | .driver = { |
253 | .name = "sa11x0-mcp", | 313 | .name = "sa11x0-mcp", |
314 | .owner = THIS_MODULE, | ||
254 | }, | 315 | }, |
255 | }; | 316 | }; |
256 | 317 | ||
257 | /* | 318 | /* |
258 | * This needs re-working | 319 | * This needs re-working |
259 | */ | 320 | */ |
260 | static int __init mcp_sa11x0_init(void) | 321 | module_platform_driver(mcp_sa11x0_driver); |
261 | { | ||
262 | return platform_driver_register(&mcp_sa11x0_driver); | ||
263 | } | ||
264 | |||
265 | static void __exit mcp_sa11x0_exit(void) | ||
266 | { | ||
267 | platform_driver_unregister(&mcp_sa11x0_driver); | ||
268 | } | ||
269 | |||
270 | module_init(mcp_sa11x0_init); | ||
271 | module_exit(mcp_sa11x0_exit); | ||
272 | 322 | ||
273 | MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); | 323 | MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>"); |
274 | MODULE_DESCRIPTION("SA11x0 multimedia communications port driver"); | 324 | MODULE_DESCRIPTION("SA11x0 multimedia communications port driver"); |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 3f565ef3e149..68ac2c55d5ae 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -503,19 +503,13 @@ static void omap_usbhs_init(struct device *dev) | |||
503 | spin_lock_irqsave(&omap->lock, flags); | 503 | spin_lock_irqsave(&omap->lock, flags); |
504 | 504 | ||
505 | if (pdata->ehci_data->phy_reset) { | 505 | if (pdata->ehci_data->phy_reset) { |
506 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { | 506 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) |
507 | gpio_request(pdata->ehci_data->reset_gpio_port[0], | 507 | gpio_request_one(pdata->ehci_data->reset_gpio_port[0], |
508 | "USB1 PHY reset"); | 508 | GPIOF_OUT_INIT_LOW, "USB1 PHY reset"); |
509 | gpio_direction_output | ||
510 | (pdata->ehci_data->reset_gpio_port[0], 0); | ||
511 | } | ||
512 | 509 | ||
513 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) { | 510 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) |
514 | gpio_request(pdata->ehci_data->reset_gpio_port[1], | 511 | gpio_request_one(pdata->ehci_data->reset_gpio_port[1], |
515 | "USB2 PHY reset"); | 512 | GPIOF_OUT_INIT_LOW, "USB2 PHY reset"); |
516 | gpio_direction_output | ||
517 | (pdata->ehci_data->reset_gpio_port[1], 0); | ||
518 | } | ||
519 | 513 | ||
520 | /* Hold the PHY in RESET for enough time till DIR is high */ | 514 | /* Hold the PHY in RESET for enough time till DIR is high */ |
521 | udelay(10); | 515 | udelay(10); |
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c index aed0d2a9b032..3927c17e4175 100644 --- a/drivers/mfd/pcf50633-adc.c +++ b/drivers/mfd/pcf50633-adc.c | |||
@@ -249,17 +249,7 @@ static struct platform_driver pcf50633_adc_driver = { | |||
249 | .remove = __devexit_p(pcf50633_adc_remove), | 249 | .remove = __devexit_p(pcf50633_adc_remove), |
250 | }; | 250 | }; |
251 | 251 | ||
252 | static int __init pcf50633_adc_init(void) | 252 | module_platform_driver(pcf50633_adc_driver); |
253 | { | ||
254 | return platform_driver_register(&pcf50633_adc_driver); | ||
255 | } | ||
256 | module_init(pcf50633_adc_init); | ||
257 | |||
258 | static void __exit pcf50633_adc_exit(void) | ||
259 | { | ||
260 | platform_driver_unregister(&pcf50633_adc_driver); | ||
261 | } | ||
262 | module_exit(pcf50633_adc_exit); | ||
263 | 253 | ||
264 | MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); | 254 | MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>"); |
265 | MODULE_DESCRIPTION("PCF50633 adc driver"); | 255 | MODULE_DESCRIPTION("PCF50633 adc driver"); |
diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c new file mode 100644 index 000000000000..e075c113eec6 --- /dev/null +++ b/drivers/mfd/s5m-core.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * s5m87xx.c | ||
3 | * | ||
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd | ||
5 | * http://www.samsung.com | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/moduleparam.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/i2c.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | #include <linux/pm_runtime.h> | ||
22 | #include <linux/mutex.h> | ||
23 | #include <linux/mfd/core.h> | ||
24 | #include <linux/mfd/s5m87xx/s5m-core.h> | ||
25 | #include <linux/mfd/s5m87xx/s5m-pmic.h> | ||
26 | #include <linux/mfd/s5m87xx/s5m-rtc.h> | ||
27 | #include <linux/regmap.h> | ||
28 | |||
29 | static struct mfd_cell s5m87xx_devs[] = { | ||
30 | { | ||
31 | .name = "s5m8767-pmic", | ||
32 | }, { | ||
33 | .name = "s5m-rtc", | ||
34 | }, | ||
35 | }; | ||
36 | |||
37 | int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, void *dest) | ||
38 | { | ||
39 | return regmap_read(s5m87xx->regmap, reg, dest); | ||
40 | } | ||
41 | EXPORT_SYMBOL_GPL(s5m_reg_read); | ||
42 | |||
43 | int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf) | ||
44 | { | ||
45 | return regmap_bulk_read(s5m87xx->regmap, reg, buf, count);; | ||
46 | } | ||
47 | EXPORT_SYMBOL_GPL(s5m_bulk_read); | ||
48 | |||
49 | int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value) | ||
50 | { | ||
51 | return regmap_write(s5m87xx->regmap, reg, value); | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(s5m_reg_write); | ||
54 | |||
55 | int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf) | ||
56 | { | ||
57 | return regmap_raw_write(s5m87xx->regmap, reg, buf, count * sizeof(u16)); | ||
58 | } | ||
59 | EXPORT_SYMBOL_GPL(s5m_bulk_write); | ||
60 | |||
61 | int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask) | ||
62 | { | ||
63 | return regmap_update_bits(s5m87xx->regmap, reg, mask, val); | ||
64 | } | ||
65 | EXPORT_SYMBOL_GPL(s5m_reg_update); | ||
66 | |||
67 | static struct regmap_config s5m_regmap_config = { | ||
68 | .reg_bits = 8, | ||
69 | .val_bits = 8, | ||
70 | }; | ||
71 | |||
72 | static int s5m87xx_i2c_probe(struct i2c_client *i2c, | ||
73 | const struct i2c_device_id *id) | ||
74 | { | ||
75 | struct s5m_platform_data *pdata = i2c->dev.platform_data; | ||
76 | struct s5m87xx_dev *s5m87xx; | ||
77 | int ret = 0; | ||
78 | int error; | ||
79 | |||
80 | s5m87xx = kzalloc(sizeof(struct s5m87xx_dev), GFP_KERNEL); | ||
81 | if (s5m87xx == NULL) | ||
82 | return -ENOMEM; | ||
83 | |||
84 | i2c_set_clientdata(i2c, s5m87xx); | ||
85 | s5m87xx->dev = &i2c->dev; | ||
86 | s5m87xx->i2c = i2c; | ||
87 | s5m87xx->irq = i2c->irq; | ||
88 | s5m87xx->type = id->driver_data; | ||
89 | |||
90 | if (pdata) { | ||
91 | s5m87xx->device_type = pdata->device_type; | ||
92 | s5m87xx->ono = pdata->ono; | ||
93 | s5m87xx->irq_base = pdata->irq_base; | ||
94 | s5m87xx->wakeup = pdata->wakeup; | ||
95 | } | ||
96 | |||
97 | s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config); | ||
98 | if (IS_ERR(s5m87xx->regmap)) { | ||
99 | error = PTR_ERR(s5m87xx->regmap); | ||
100 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
101 | error); | ||
102 | goto err; | ||
103 | } | ||
104 | |||
105 | s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); | ||
106 | i2c_set_clientdata(s5m87xx->rtc, s5m87xx); | ||
107 | |||
108 | if (pdata->cfg_pmic_irq) | ||
109 | pdata->cfg_pmic_irq(); | ||
110 | |||
111 | s5m_irq_init(s5m87xx); | ||
112 | |||
113 | pm_runtime_set_active(s5m87xx->dev); | ||
114 | |||
115 | ret = mfd_add_devices(s5m87xx->dev, -1, | ||
116 | s5m87xx_devs, ARRAY_SIZE(s5m87xx_devs), | ||
117 | NULL, 0); | ||
118 | |||
119 | if (ret < 0) | ||
120 | goto err; | ||
121 | |||
122 | return ret; | ||
123 | |||
124 | err: | ||
125 | mfd_remove_devices(s5m87xx->dev); | ||
126 | s5m_irq_exit(s5m87xx); | ||
127 | i2c_unregister_device(s5m87xx->rtc); | ||
128 | regmap_exit(s5m87xx->regmap); | ||
129 | kfree(s5m87xx); | ||
130 | return ret; | ||
131 | } | ||
132 | |||
133 | static int s5m87xx_i2c_remove(struct i2c_client *i2c) | ||
134 | { | ||
135 | struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c); | ||
136 | |||
137 | mfd_remove_devices(s5m87xx->dev); | ||
138 | s5m_irq_exit(s5m87xx); | ||
139 | i2c_unregister_device(s5m87xx->rtc); | ||
140 | regmap_exit(s5m87xx->regmap); | ||
141 | kfree(s5m87xx); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static const struct i2c_device_id s5m87xx_i2c_id[] = { | ||
146 | { "s5m87xx", 0 }, | ||
147 | { } | ||
148 | }; | ||
149 | MODULE_DEVICE_TABLE(i2c, s5m87xx_i2c_id); | ||
150 | |||
151 | static struct i2c_driver s5m87xx_i2c_driver = { | ||
152 | .driver = { | ||
153 | .name = "s5m87xx", | ||
154 | .owner = THIS_MODULE, | ||
155 | }, | ||
156 | .probe = s5m87xx_i2c_probe, | ||
157 | .remove = s5m87xx_i2c_remove, | ||
158 | .id_table = s5m87xx_i2c_id, | ||
159 | }; | ||
160 | |||
161 | static int __init s5m87xx_i2c_init(void) | ||
162 | { | ||
163 | return i2c_add_driver(&s5m87xx_i2c_driver); | ||
164 | } | ||
165 | |||
166 | subsys_initcall(s5m87xx_i2c_init); | ||
167 | |||
168 | static void __exit s5m87xx_i2c_exit(void) | ||
169 | { | ||
170 | i2c_del_driver(&s5m87xx_i2c_driver); | ||
171 | } | ||
172 | module_exit(s5m87xx_i2c_exit); | ||
173 | |||
174 | MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>"); | ||
175 | MODULE_DESCRIPTION("Core support for the S5M MFD"); | ||
176 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/s5m-irq.c b/drivers/mfd/s5m-irq.c new file mode 100644 index 000000000000..de76dfb6f0ad --- /dev/null +++ b/drivers/mfd/s5m-irq.c | |||
@@ -0,0 +1,487 @@ | |||
1 | /* | ||
2 | * s5m-irq.c | ||
3 | * | ||
4 | * Copyright (c) 2011 Samsung Electronics Co., Ltd | ||
5 | * http://www.samsung.com | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/device.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/mfd/s5m87xx/s5m-core.h> | ||
18 | |||
19 | struct s5m_irq_data { | ||
20 | int reg; | ||
21 | int mask; | ||
22 | }; | ||
23 | |||
24 | static struct s5m_irq_data s5m8767_irqs[] = { | ||
25 | [S5M8767_IRQ_PWRR] = { | ||
26 | .reg = 1, | ||
27 | .mask = S5M8767_IRQ_PWRR_MASK, | ||
28 | }, | ||
29 | [S5M8767_IRQ_PWRF] = { | ||
30 | .reg = 1, | ||
31 | .mask = S5M8767_IRQ_PWRF_MASK, | ||
32 | }, | ||
33 | [S5M8767_IRQ_PWR1S] = { | ||
34 | .reg = 1, | ||
35 | .mask = S5M8767_IRQ_PWR1S_MASK, | ||
36 | }, | ||
37 | [S5M8767_IRQ_JIGR] = { | ||
38 | .reg = 1, | ||
39 | .mask = S5M8767_IRQ_JIGR_MASK, | ||
40 | }, | ||
41 | [S5M8767_IRQ_JIGF] = { | ||
42 | .reg = 1, | ||
43 | .mask = S5M8767_IRQ_JIGF_MASK, | ||
44 | }, | ||
45 | [S5M8767_IRQ_LOWBAT2] = { | ||
46 | .reg = 1, | ||
47 | .mask = S5M8767_IRQ_LOWBAT2_MASK, | ||
48 | }, | ||
49 | [S5M8767_IRQ_LOWBAT1] = { | ||
50 | .reg = 1, | ||
51 | .mask = S5M8767_IRQ_LOWBAT1_MASK, | ||
52 | }, | ||
53 | [S5M8767_IRQ_MRB] = { | ||
54 | .reg = 2, | ||
55 | .mask = S5M8767_IRQ_MRB_MASK, | ||
56 | }, | ||
57 | [S5M8767_IRQ_DVSOK2] = { | ||
58 | .reg = 2, | ||
59 | .mask = S5M8767_IRQ_DVSOK2_MASK, | ||
60 | }, | ||
61 | [S5M8767_IRQ_DVSOK3] = { | ||
62 | .reg = 2, | ||
63 | .mask = S5M8767_IRQ_DVSOK3_MASK, | ||
64 | }, | ||
65 | [S5M8767_IRQ_DVSOK4] = { | ||
66 | .reg = 2, | ||
67 | .mask = S5M8767_IRQ_DVSOK4_MASK, | ||
68 | }, | ||
69 | [S5M8767_IRQ_RTC60S] = { | ||
70 | .reg = 3, | ||
71 | .mask = S5M8767_IRQ_RTC60S_MASK, | ||
72 | }, | ||
73 | [S5M8767_IRQ_RTCA1] = { | ||
74 | .reg = 3, | ||
75 | .mask = S5M8767_IRQ_RTCA1_MASK, | ||
76 | }, | ||
77 | [S5M8767_IRQ_RTCA2] = { | ||
78 | .reg = 3, | ||
79 | .mask = S5M8767_IRQ_RTCA2_MASK, | ||
80 | }, | ||
81 | [S5M8767_IRQ_SMPL] = { | ||
82 | .reg = 3, | ||
83 | .mask = S5M8767_IRQ_SMPL_MASK, | ||
84 | }, | ||
85 | [S5M8767_IRQ_RTC1S] = { | ||
86 | .reg = 3, | ||
87 | .mask = S5M8767_IRQ_RTC1S_MASK, | ||
88 | }, | ||
89 | [S5M8767_IRQ_WTSR] = { | ||
90 | .reg = 3, | ||
91 | .mask = S5M8767_IRQ_WTSR_MASK, | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | static struct s5m_irq_data s5m8763_irqs[] = { | ||
96 | [S5M8763_IRQ_DCINF] = { | ||
97 | .reg = 1, | ||
98 | .mask = S5M8763_IRQ_DCINF_MASK, | ||
99 | }, | ||
100 | [S5M8763_IRQ_DCINR] = { | ||
101 | .reg = 1, | ||
102 | .mask = S5M8763_IRQ_DCINR_MASK, | ||
103 | }, | ||
104 | [S5M8763_IRQ_JIGF] = { | ||
105 | .reg = 1, | ||
106 | .mask = S5M8763_IRQ_JIGF_MASK, | ||
107 | }, | ||
108 | [S5M8763_IRQ_JIGR] = { | ||
109 | .reg = 1, | ||
110 | .mask = S5M8763_IRQ_JIGR_MASK, | ||
111 | }, | ||
112 | [S5M8763_IRQ_PWRONF] = { | ||
113 | .reg = 1, | ||
114 | .mask = S5M8763_IRQ_PWRONF_MASK, | ||
115 | }, | ||
116 | [S5M8763_IRQ_PWRONR] = { | ||
117 | .reg = 1, | ||
118 | .mask = S5M8763_IRQ_PWRONR_MASK, | ||
119 | }, | ||
120 | [S5M8763_IRQ_WTSREVNT] = { | ||
121 | .reg = 2, | ||
122 | .mask = S5M8763_IRQ_WTSREVNT_MASK, | ||
123 | }, | ||
124 | [S5M8763_IRQ_SMPLEVNT] = { | ||
125 | .reg = 2, | ||
126 | .mask = S5M8763_IRQ_SMPLEVNT_MASK, | ||
127 | }, | ||
128 | [S5M8763_IRQ_ALARM1] = { | ||
129 | .reg = 2, | ||
130 | .mask = S5M8763_IRQ_ALARM1_MASK, | ||
131 | }, | ||
132 | [S5M8763_IRQ_ALARM0] = { | ||
133 | .reg = 2, | ||
134 | .mask = S5M8763_IRQ_ALARM0_MASK, | ||
135 | }, | ||
136 | [S5M8763_IRQ_ONKEY1S] = { | ||
137 | .reg = 3, | ||
138 | .mask = S5M8763_IRQ_ONKEY1S_MASK, | ||
139 | }, | ||
140 | [S5M8763_IRQ_TOPOFFR] = { | ||
141 | .reg = 3, | ||
142 | .mask = S5M8763_IRQ_TOPOFFR_MASK, | ||
143 | }, | ||
144 | [S5M8763_IRQ_DCINOVPR] = { | ||
145 | .reg = 3, | ||
146 | .mask = S5M8763_IRQ_DCINOVPR_MASK, | ||
147 | }, | ||
148 | [S5M8763_IRQ_CHGRSTF] = { | ||
149 | .reg = 3, | ||
150 | .mask = S5M8763_IRQ_CHGRSTF_MASK, | ||
151 | }, | ||
152 | [S5M8763_IRQ_DONER] = { | ||
153 | .reg = 3, | ||
154 | .mask = S5M8763_IRQ_DONER_MASK, | ||
155 | }, | ||
156 | [S5M8763_IRQ_CHGFAULT] = { | ||
157 | .reg = 3, | ||
158 | .mask = S5M8763_IRQ_CHGFAULT_MASK, | ||
159 | }, | ||
160 | [S5M8763_IRQ_LOBAT1] = { | ||
161 | .reg = 4, | ||
162 | .mask = S5M8763_IRQ_LOBAT1_MASK, | ||
163 | }, | ||
164 | [S5M8763_IRQ_LOBAT2] = { | ||
165 | .reg = 4, | ||
166 | .mask = S5M8763_IRQ_LOBAT2_MASK, | ||
167 | }, | ||
168 | }; | ||
169 | |||
170 | static inline struct s5m_irq_data * | ||
171 | irq_to_s5m8767_irq(struct s5m87xx_dev *s5m87xx, int irq) | ||
172 | { | ||
173 | return &s5m8767_irqs[irq - s5m87xx->irq_base]; | ||
174 | } | ||
175 | |||
176 | static void s5m8767_irq_lock(struct irq_data *data) | ||
177 | { | ||
178 | struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); | ||
179 | |||
180 | mutex_lock(&s5m87xx->irqlock); | ||
181 | } | ||
182 | |||
183 | static void s5m8767_irq_sync_unlock(struct irq_data *data) | ||
184 | { | ||
185 | struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); | ||
186 | int i; | ||
187 | |||
188 | for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) { | ||
189 | if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) { | ||
190 | s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i]; | ||
191 | s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i, | ||
192 | s5m87xx->irq_masks_cur[i]); | ||
193 | } | ||
194 | } | ||
195 | |||
196 | mutex_unlock(&s5m87xx->irqlock); | ||
197 | } | ||
198 | |||
199 | static void s5m8767_irq_unmask(struct irq_data *data) | ||
200 | { | ||
201 | struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); | ||
202 | struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx, | ||
203 | data->irq); | ||
204 | |||
205 | s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | ||
206 | } | ||
207 | |||
208 | static void s5m8767_irq_mask(struct irq_data *data) | ||
209 | { | ||
210 | struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); | ||
211 | struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx, | ||
212 | data->irq); | ||
213 | |||
214 | s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | ||
215 | } | ||
216 | |||
217 | static struct irq_chip s5m8767_irq_chip = { | ||
218 | .name = "s5m8767", | ||
219 | .irq_bus_lock = s5m8767_irq_lock, | ||
220 | .irq_bus_sync_unlock = s5m8767_irq_sync_unlock, | ||
221 | .irq_mask = s5m8767_irq_mask, | ||
222 | .irq_unmask = s5m8767_irq_unmask, | ||
223 | }; | ||
224 | |||
225 | static inline struct s5m_irq_data * | ||
226 | irq_to_s5m8763_irq(struct s5m87xx_dev *s5m87xx, int irq) | ||
227 | { | ||
228 | return &s5m8763_irqs[irq - s5m87xx->irq_base]; | ||
229 | } | ||
230 | |||
231 | static void s5m8763_irq_lock(struct irq_data *data) | ||
232 | { | ||
233 | struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); | ||
234 | |||
235 | mutex_lock(&s5m87xx->irqlock); | ||
236 | } | ||
237 | |||
238 | static void s5m8763_irq_sync_unlock(struct irq_data *data) | ||
239 | { | ||
240 | struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); | ||
241 | int i; | ||
242 | |||
243 | for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) { | ||
244 | if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) { | ||
245 | s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i]; | ||
246 | s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i, | ||
247 | s5m87xx->irq_masks_cur[i]); | ||
248 | } | ||
249 | } | ||
250 | |||
251 | mutex_unlock(&s5m87xx->irqlock); | ||
252 | } | ||
253 | |||
254 | static void s5m8763_irq_unmask(struct irq_data *data) | ||
255 | { | ||
256 | struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); | ||
257 | struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx, | ||
258 | data->irq); | ||
259 | |||
260 | s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask; | ||
261 | } | ||
262 | |||
263 | static void s5m8763_irq_mask(struct irq_data *data) | ||
264 | { | ||
265 | struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data); | ||
266 | struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx, | ||
267 | data->irq); | ||
268 | |||
269 | s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask; | ||
270 | } | ||
271 | |||
272 | static struct irq_chip s5m8763_irq_chip = { | ||
273 | .name = "s5m8763", | ||
274 | .irq_bus_lock = s5m8763_irq_lock, | ||
275 | .irq_bus_sync_unlock = s5m8763_irq_sync_unlock, | ||
276 | .irq_mask = s5m8763_irq_mask, | ||
277 | .irq_unmask = s5m8763_irq_unmask, | ||
278 | }; | ||
279 | |||
280 | |||
281 | static irqreturn_t s5m8767_irq_thread(int irq, void *data) | ||
282 | { | ||
283 | struct s5m87xx_dev *s5m87xx = data; | ||
284 | u8 irq_reg[NUM_IRQ_REGS-1]; | ||
285 | int ret; | ||
286 | int i; | ||
287 | |||
288 | |||
289 | ret = s5m_bulk_read(s5m87xx, S5M8767_REG_INT1, | ||
290 | NUM_IRQ_REGS - 1, irq_reg); | ||
291 | if (ret < 0) { | ||
292 | dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n", | ||
293 | ret); | ||
294 | return IRQ_NONE; | ||
295 | } | ||
296 | |||
297 | for (i = 0; i < NUM_IRQ_REGS - 1; i++) | ||
298 | irq_reg[i] &= ~s5m87xx->irq_masks_cur[i]; | ||
299 | |||
300 | for (i = 0; i < S5M8767_IRQ_NR; i++) { | ||
301 | if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask) | ||
302 | handle_nested_irq(s5m87xx->irq_base + i); | ||
303 | } | ||
304 | |||
305 | return IRQ_HANDLED; | ||
306 | } | ||
307 | |||
308 | static irqreturn_t s5m8763_irq_thread(int irq, void *data) | ||
309 | { | ||
310 | struct s5m87xx_dev *s5m87xx = data; | ||
311 | u8 irq_reg[NUM_IRQ_REGS]; | ||
312 | int ret; | ||
313 | int i; | ||
314 | |||
315 | ret = s5m_bulk_read(s5m87xx, S5M8763_REG_IRQ1, | ||
316 | NUM_IRQ_REGS, irq_reg); | ||
317 | if (ret < 0) { | ||
318 | dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n", | ||
319 | ret); | ||
320 | return IRQ_NONE; | ||
321 | } | ||
322 | |||
323 | for (i = 0; i < NUM_IRQ_REGS; i++) | ||
324 | irq_reg[i] &= ~s5m87xx->irq_masks_cur[i]; | ||
325 | |||
326 | for (i = 0; i < S5M8763_IRQ_NR; i++) { | ||
327 | if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask) | ||
328 | handle_nested_irq(s5m87xx->irq_base + i); | ||
329 | } | ||
330 | |||
331 | return IRQ_HANDLED; | ||
332 | } | ||
333 | |||
334 | int s5m_irq_resume(struct s5m87xx_dev *s5m87xx) | ||
335 | { | ||
336 | if (s5m87xx->irq && s5m87xx->irq_base){ | ||
337 | switch (s5m87xx->device_type) { | ||
338 | case S5M8763X: | ||
339 | s5m8763_irq_thread(s5m87xx->irq_base, s5m87xx); | ||
340 | break; | ||
341 | case S5M8767X: | ||
342 | s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx); | ||
343 | break; | ||
344 | default: | ||
345 | break; | ||
346 | |||
347 | } | ||
348 | } | ||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | int s5m_irq_init(struct s5m87xx_dev *s5m87xx) | ||
353 | { | ||
354 | int i; | ||
355 | int cur_irq; | ||
356 | int ret = 0; | ||
357 | int type = s5m87xx->device_type; | ||
358 | |||
359 | if (!s5m87xx->irq) { | ||
360 | dev_warn(s5m87xx->dev, | ||
361 | "No interrupt specified, no interrupts\n"); | ||
362 | s5m87xx->irq_base = 0; | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | if (!s5m87xx->irq_base) { | ||
367 | dev_err(s5m87xx->dev, | ||
368 | "No interrupt base specified, no interrupts\n"); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | mutex_init(&s5m87xx->irqlock); | ||
373 | |||
374 | switch (type) { | ||
375 | case S5M8763X: | ||
376 | for (i = 0; i < NUM_IRQ_REGS; i++) { | ||
377 | s5m87xx->irq_masks_cur[i] = 0xff; | ||
378 | s5m87xx->irq_masks_cache[i] = 0xff; | ||
379 | s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i, | ||
380 | 0xff); | ||
381 | } | ||
382 | |||
383 | s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM1, 0xff); | ||
384 | s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM2, 0xff); | ||
385 | |||
386 | for (i = 0; i < S5M8763_IRQ_NR; i++) { | ||
387 | cur_irq = i + s5m87xx->irq_base; | ||
388 | irq_set_chip_data(cur_irq, s5m87xx); | ||
389 | irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip, | ||
390 | handle_edge_irq); | ||
391 | irq_set_nested_thread(cur_irq, 1); | ||
392 | #ifdef CONFIG_ARM | ||
393 | set_irq_flags(cur_irq, IRQF_VALID); | ||
394 | #else | ||
395 | irq_set_noprobe(cur_irq); | ||
396 | #endif | ||
397 | } | ||
398 | |||
399 | ret = request_threaded_irq(s5m87xx->irq, NULL, | ||
400 | s5m8763_irq_thread, | ||
401 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
402 | "s5m87xx-irq", s5m87xx); | ||
403 | if (ret) { | ||
404 | dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n", | ||
405 | s5m87xx->irq, ret); | ||
406 | return ret; | ||
407 | } | ||
408 | break; | ||
409 | case S5M8767X: | ||
410 | for (i = 0; i < NUM_IRQ_REGS - 1; i++) { | ||
411 | s5m87xx->irq_masks_cur[i] = 0xff; | ||
412 | s5m87xx->irq_masks_cache[i] = 0xff; | ||
413 | s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i, | ||
414 | 0xff); | ||
415 | } | ||
416 | for (i = 0; i < S5M8767_IRQ_NR; i++) { | ||
417 | cur_irq = i + s5m87xx->irq_base; | ||
418 | irq_set_chip_data(cur_irq, s5m87xx); | ||
419 | if (ret) { | ||
420 | dev_err(s5m87xx->dev, | ||
421 | "Failed to irq_set_chip_data %d: %d\n", | ||
422 | s5m87xx->irq, ret); | ||
423 | return ret; | ||
424 | } | ||
425 | |||
426 | irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip, | ||
427 | handle_edge_irq); | ||
428 | irq_set_nested_thread(cur_irq, 1); | ||
429 | #ifdef CONFIG_ARM | ||
430 | set_irq_flags(cur_irq, IRQF_VALID); | ||
431 | #else | ||
432 | irq_set_noprobe(cur_irq); | ||
433 | #endif | ||
434 | } | ||
435 | |||
436 | ret = request_threaded_irq(s5m87xx->irq, NULL, | ||
437 | s5m8767_irq_thread, | ||
438 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
439 | "s5m87xx-irq", s5m87xx); | ||
440 | if (ret) { | ||
441 | dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n", | ||
442 | s5m87xx->irq, ret); | ||
443 | return ret; | ||
444 | } | ||
445 | break; | ||
446 | default: | ||
447 | break; | ||
448 | } | ||
449 | |||
450 | if (!s5m87xx->ono) | ||
451 | return 0; | ||
452 | |||
453 | switch (type) { | ||
454 | case S5M8763X: | ||
455 | ret = request_threaded_irq(s5m87xx->ono, NULL, | ||
456 | s5m8763_irq_thread, | ||
457 | IRQF_TRIGGER_FALLING | | ||
458 | IRQF_TRIGGER_RISING | | ||
459 | IRQF_ONESHOT, "s5m87xx-ono", | ||
460 | s5m87xx); | ||
461 | break; | ||
462 | case S5M8767X: | ||
463 | ret = request_threaded_irq(s5m87xx->ono, NULL, | ||
464 | s5m8767_irq_thread, | ||
465 | IRQF_TRIGGER_FALLING | | ||
466 | IRQF_TRIGGER_RISING | | ||
467 | IRQF_ONESHOT, "s5m87xx-ono", s5m87xx); | ||
468 | break; | ||
469 | default: | ||
470 | break; | ||
471 | } | ||
472 | |||
473 | if (ret) | ||
474 | dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n", | ||
475 | s5m87xx->ono, ret); | ||
476 | |||
477 | return 0; | ||
478 | } | ||
479 | |||
480 | void s5m_irq_exit(struct s5m87xx_dev *s5m87xx) | ||
481 | { | ||
482 | if (s5m87xx->ono) | ||
483 | free_irq(s5m87xx->ono, s5m87xx); | ||
484 | |||
485 | if (s5m87xx->irq) | ||
486 | free_irq(s5m87xx->irq, s5m87xx); | ||
487 | } | ||
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index df3702c1756d..f4d86117f44a 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -1720,7 +1720,7 @@ static int sm501_plat_remove(struct platform_device *dev) | |||
1720 | return 0; | 1720 | return 0; |
1721 | } | 1721 | } |
1722 | 1722 | ||
1723 | static struct pci_device_id sm501_pci_tbl[] = { | 1723 | static DEFINE_PCI_DEVICE_TABLE(sm501_pci_tbl) = { |
1724 | { 0x126f, 0x0501, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 1724 | { 0x126f, 0x0501, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
1725 | { 0, }, | 1725 | { 0, }, |
1726 | }; | 1726 | }; |
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c new file mode 100644 index 000000000000..373f423b1181 --- /dev/null +++ b/drivers/mfd/stmpe-i2c.c | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * ST Microelectronics MFD: stmpe's i2c client specific driver | ||
3 | * | ||
4 | * Copyright (C) ST-Ericsson SA 2010 | ||
5 | * Copyright (C) ST Microelectronics SA 2011 | ||
6 | * | ||
7 | * License Terms: GNU General Public License, version 2 | ||
8 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | ||
9 | * Author: Viresh Kumar <viresh.kumar@st.com> for ST Microelectronics | ||
10 | */ | ||
11 | |||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/types.h> | ||
17 | #include "stmpe.h" | ||
18 | |||
19 | static int i2c_reg_read(struct stmpe *stmpe, u8 reg) | ||
20 | { | ||
21 | struct i2c_client *i2c = stmpe->client; | ||
22 | |||
23 | return i2c_smbus_read_byte_data(i2c, reg); | ||
24 | } | ||
25 | |||
26 | static int i2c_reg_write(struct stmpe *stmpe, u8 reg, u8 val) | ||
27 | { | ||
28 | struct i2c_client *i2c = stmpe->client; | ||
29 | |||
30 | return i2c_smbus_write_byte_data(i2c, reg, val); | ||
31 | } | ||
32 | |||
33 | static int i2c_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) | ||
34 | { | ||
35 | struct i2c_client *i2c = stmpe->client; | ||
36 | |||
37 | return i2c_smbus_read_i2c_block_data(i2c, reg, length, values); | ||
38 | } | ||
39 | |||
40 | static int i2c_block_write(struct stmpe *stmpe, u8 reg, u8 length, | ||
41 | const u8 *values) | ||
42 | { | ||
43 | struct i2c_client *i2c = stmpe->client; | ||
44 | |||
45 | return i2c_smbus_write_i2c_block_data(i2c, reg, length, values); | ||
46 | } | ||
47 | |||
48 | static struct stmpe_client_info i2c_ci = { | ||
49 | .read_byte = i2c_reg_read, | ||
50 | .write_byte = i2c_reg_write, | ||
51 | .read_block = i2c_block_read, | ||
52 | .write_block = i2c_block_write, | ||
53 | }; | ||
54 | |||
55 | static int __devinit | ||
56 | stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) | ||
57 | { | ||
58 | i2c_ci.data = (void *)id; | ||
59 | i2c_ci.irq = i2c->irq; | ||
60 | i2c_ci.client = i2c; | ||
61 | i2c_ci.dev = &i2c->dev; | ||
62 | |||
63 | return stmpe_probe(&i2c_ci, id->driver_data); | ||
64 | } | ||
65 | |||
66 | static int __devexit stmpe_i2c_remove(struct i2c_client *i2c) | ||
67 | { | ||
68 | struct stmpe *stmpe = dev_get_drvdata(&i2c->dev); | ||
69 | |||
70 | return stmpe_remove(stmpe); | ||
71 | } | ||
72 | |||
73 | static const struct i2c_device_id stmpe_i2c_id[] = { | ||
74 | { "stmpe610", STMPE610 }, | ||
75 | { "stmpe801", STMPE801 }, | ||
76 | { "stmpe811", STMPE811 }, | ||
77 | { "stmpe1601", STMPE1601 }, | ||
78 | { "stmpe2401", STMPE2401 }, | ||
79 | { "stmpe2403", STMPE2403 }, | ||
80 | { } | ||
81 | }; | ||
82 | MODULE_DEVICE_TABLE(i2c, stmpe_id); | ||
83 | |||
84 | static struct i2c_driver stmpe_i2c_driver = { | ||
85 | .driver.name = "stmpe-i2c", | ||
86 | .driver.owner = THIS_MODULE, | ||
87 | #ifdef CONFIG_PM | ||
88 | .driver.pm = &stmpe_dev_pm_ops, | ||
89 | #endif | ||
90 | .probe = stmpe_i2c_probe, | ||
91 | .remove = __devexit_p(stmpe_i2c_remove), | ||
92 | .id_table = stmpe_i2c_id, | ||
93 | }; | ||
94 | |||
95 | static int __init stmpe_init(void) | ||
96 | { | ||
97 | return i2c_add_driver(&stmpe_i2c_driver); | ||
98 | } | ||
99 | subsys_initcall(stmpe_init); | ||
100 | |||
101 | static void __exit stmpe_exit(void) | ||
102 | { | ||
103 | i2c_del_driver(&stmpe_i2c_driver); | ||
104 | } | ||
105 | module_exit(stmpe_exit); | ||
106 | |||
107 | MODULE_LICENSE("GPL v2"); | ||
108 | MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver"); | ||
109 | MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); | ||
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c new file mode 100644 index 000000000000..b58c43c7ea93 --- /dev/null +++ b/drivers/mfd/stmpe-spi.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * ST Microelectronics MFD: stmpe's spi client specific driver | ||
3 | * | ||
4 | * Copyright (C) ST Microelectronics SA 2011 | ||
5 | * | ||
6 | * License Terms: GNU General Public License, version 2 | ||
7 | * Author: Viresh Kumar <viresh.kumar@st.com> for ST Microelectronics | ||
8 | */ | ||
9 | |||
10 | #include <linux/spi/spi.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include "stmpe.h" | ||
16 | |||
17 | #define READ_CMD (1 << 7) | ||
18 | |||
19 | static int spi_reg_read(struct stmpe *stmpe, u8 reg) | ||
20 | { | ||
21 | struct spi_device *spi = stmpe->client; | ||
22 | int status = spi_w8r16(spi, reg | READ_CMD); | ||
23 | |||
24 | return (status < 0) ? status : status >> 8; | ||
25 | } | ||
26 | |||
27 | static int spi_reg_write(struct stmpe *stmpe, u8 reg, u8 val) | ||
28 | { | ||
29 | struct spi_device *spi = stmpe->client; | ||
30 | u16 cmd = (val << 8) | reg; | ||
31 | |||
32 | return spi_write(spi, (const u8 *)&cmd, 2); | ||
33 | } | ||
34 | |||
35 | static int spi_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) | ||
36 | { | ||
37 | int ret, i; | ||
38 | |||
39 | for (i = 0; i < length; i++) { | ||
40 | ret = spi_reg_read(stmpe, reg + i); | ||
41 | if (ret < 0) | ||
42 | return ret; | ||
43 | *(values + i) = ret; | ||
44 | } | ||
45 | |||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int spi_block_write(struct stmpe *stmpe, u8 reg, u8 length, | ||
50 | const u8 *values) | ||
51 | { | ||
52 | int ret = 0, i; | ||
53 | |||
54 | for (i = length; i > 0; i--, reg++) { | ||
55 | ret = spi_reg_write(stmpe, reg, *(values + i - 1)); | ||
56 | if (ret < 0) | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | static void spi_init(struct stmpe *stmpe) | ||
64 | { | ||
65 | struct spi_device *spi = stmpe->client; | ||
66 | |||
67 | spi->bits_per_word = 8; | ||
68 | |||
69 | /* This register is only present for stmpe811 */ | ||
70 | if (stmpe->variant->id_val == 0x0811) | ||
71 | spi_reg_write(stmpe, STMPE811_REG_SPI_CFG, spi->mode); | ||
72 | |||
73 | if (spi_setup(spi) < 0) | ||
74 | dev_dbg(&spi->dev, "spi_setup failed\n"); | ||
75 | } | ||
76 | |||
77 | static struct stmpe_client_info spi_ci = { | ||
78 | .read_byte = spi_reg_read, | ||
79 | .write_byte = spi_reg_write, | ||
80 | .read_block = spi_block_read, | ||
81 | .write_block = spi_block_write, | ||
82 | .init = spi_init, | ||
83 | }; | ||
84 | |||
85 | static int __devinit | ||
86 | stmpe_spi_probe(struct spi_device *spi) | ||
87 | { | ||
88 | const struct spi_device_id *id = spi_get_device_id(spi); | ||
89 | |||
90 | /* don't exceed max specified rate - 1MHz - Limitation of STMPE */ | ||
91 | if (spi->max_speed_hz > 1000000) { | ||
92 | dev_dbg(&spi->dev, "f(sample) %d KHz?\n", | ||
93 | (spi->max_speed_hz/1000)); | ||
94 | return -EINVAL; | ||
95 | } | ||
96 | |||
97 | spi_ci.irq = spi->irq; | ||
98 | spi_ci.client = spi; | ||
99 | spi_ci.dev = &spi->dev; | ||
100 | |||
101 | return stmpe_probe(&spi_ci, id->driver_data); | ||
102 | } | ||
103 | |||
104 | static int __devexit stmpe_spi_remove(struct spi_device *spi) | ||
105 | { | ||
106 | struct stmpe *stmpe = dev_get_drvdata(&spi->dev); | ||
107 | |||
108 | return stmpe_remove(stmpe); | ||
109 | } | ||
110 | |||
111 | static const struct spi_device_id stmpe_spi_id[] = { | ||
112 | { "stmpe610", STMPE610 }, | ||
113 | { "stmpe801", STMPE801 }, | ||
114 | { "stmpe811", STMPE811 }, | ||
115 | { "stmpe1601", STMPE1601 }, | ||
116 | { "stmpe2401", STMPE2401 }, | ||
117 | { "stmpe2403", STMPE2403 }, | ||
118 | { } | ||
119 | }; | ||
120 | MODULE_DEVICE_TABLE(spi, stmpe_id); | ||
121 | |||
122 | static struct spi_driver stmpe_spi_driver = { | ||
123 | .driver = { | ||
124 | .name = "stmpe-spi", | ||
125 | .bus = &spi_bus_type, | ||
126 | .owner = THIS_MODULE, | ||
127 | #ifdef CONFIG_PM | ||
128 | .pm = &stmpe_dev_pm_ops, | ||
129 | #endif | ||
130 | }, | ||
131 | .probe = stmpe_spi_probe, | ||
132 | .remove = __devexit_p(stmpe_spi_remove), | ||
133 | .id_table = stmpe_spi_id, | ||
134 | }; | ||
135 | |||
136 | static int __init stmpe_init(void) | ||
137 | { | ||
138 | return spi_register_driver(&stmpe_spi_driver); | ||
139 | } | ||
140 | subsys_initcall(stmpe_init); | ||
141 | |||
142 | static void __exit stmpe_exit(void) | ||
143 | { | ||
144 | spi_unregister_driver(&stmpe_spi_driver); | ||
145 | } | ||
146 | module_exit(stmpe_exit); | ||
147 | |||
148 | MODULE_LICENSE("GPL v2"); | ||
149 | MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver"); | ||
150 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); | ||
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 2963689cf45c..e07947e56b2a 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -1,18 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * ST Microelectronics MFD: stmpe's driver | ||
3 | * | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | 4 | * Copyright (C) ST-Ericsson SA 2010 |
3 | * | 5 | * |
4 | * License Terms: GNU General Public License, version 2 | 6 | * License Terms: GNU General Public License, version 2 |
5 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson | 7 | * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson |
6 | */ | 8 | */ |
7 | 9 | ||
10 | #include <linux/gpio.h> | ||
11 | #include <linux/export.h> | ||
8 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
9 | #include <linux/module.h> | ||
10 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
11 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/pm.h> | ||
12 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
13 | #include <linux/i2c.h> | ||
14 | #include <linux/mfd/core.h> | 17 | #include <linux/mfd/core.h> |
15 | #include <linux/mfd/stmpe.h> | ||
16 | #include "stmpe.h" | 18 | #include "stmpe.h" |
17 | 19 | ||
18 | static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) | 20 | static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) |
@@ -29,10 +31,9 @@ static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg) | |||
29 | { | 31 | { |
30 | int ret; | 32 | int ret; |
31 | 33 | ||
32 | ret = i2c_smbus_read_byte_data(stmpe->i2c, reg); | 34 | ret = stmpe->ci->read_byte(stmpe, reg); |
33 | if (ret < 0) | 35 | if (ret < 0) |
34 | dev_err(stmpe->dev, "failed to read reg %#x: %d\n", | 36 | dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret); |
35 | reg, ret); | ||
36 | 37 | ||
37 | dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret); | 38 | dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret); |
38 | 39 | ||
@@ -45,10 +46,9 @@ static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val) | |||
45 | 46 | ||
46 | dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val); | 47 | dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val); |
47 | 48 | ||
48 | ret = i2c_smbus_write_byte_data(stmpe->i2c, reg, val); | 49 | ret = stmpe->ci->write_byte(stmpe, reg, val); |
49 | if (ret < 0) | 50 | if (ret < 0) |
50 | dev_err(stmpe->dev, "failed to write reg %#x: %d\n", | 51 | dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret); |
51 | reg, ret); | ||
52 | 52 | ||
53 | return ret; | 53 | return ret; |
54 | } | 54 | } |
@@ -72,10 +72,9 @@ static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length, | |||
72 | { | 72 | { |
73 | int ret; | 73 | int ret; |
74 | 74 | ||
75 | ret = i2c_smbus_read_i2c_block_data(stmpe->i2c, reg, length, values); | 75 | ret = stmpe->ci->read_block(stmpe, reg, length, values); |
76 | if (ret < 0) | 76 | if (ret < 0) |
77 | dev_err(stmpe->dev, "failed to read regs %#x: %d\n", | 77 | dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret); |
78 | reg, ret); | ||
79 | 78 | ||
80 | dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret); | 79 | dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret); |
81 | stmpe_dump_bytes("stmpe rd: ", values, length); | 80 | stmpe_dump_bytes("stmpe rd: ", values, length); |
@@ -91,11 +90,9 @@ static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length, | |||
91 | dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length); | 90 | dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length); |
92 | stmpe_dump_bytes("stmpe wr: ", values, length); | 91 | stmpe_dump_bytes("stmpe wr: ", values, length); |
93 | 92 | ||
94 | ret = i2c_smbus_write_i2c_block_data(stmpe->i2c, reg, length, | 93 | ret = stmpe->ci->write_block(stmpe, reg, length, values); |
95 | values); | ||
96 | if (ret < 0) | 94 | if (ret < 0) |
97 | dev_err(stmpe->dev, "failed to write regs %#x: %d\n", | 95 | dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret); |
98 | reg, ret); | ||
99 | 96 | ||
100 | return ret; | 97 | return ret; |
101 | } | 98 | } |
@@ -245,12 +242,14 @@ int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block) | |||
245 | u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB]; | 242 | u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB]; |
246 | int af_bits = variant->af_bits; | 243 | int af_bits = variant->af_bits; |
247 | int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8); | 244 | int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8); |
248 | int afperreg = 8 / af_bits; | ||
249 | int mask = (1 << af_bits) - 1; | 245 | int mask = (1 << af_bits) - 1; |
250 | u8 regs[numregs]; | 246 | u8 regs[numregs]; |
251 | int af; | 247 | int af, afperreg, ret; |
252 | int ret; | 248 | |
249 | if (!variant->get_altfunc) | ||
250 | return 0; | ||
253 | 251 | ||
252 | afperreg = 8 / af_bits; | ||
254 | mutex_lock(&stmpe->lock); | 253 | mutex_lock(&stmpe->lock); |
255 | 254 | ||
256 | ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO); | 255 | ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO); |
@@ -325,7 +324,51 @@ static struct mfd_cell stmpe_keypad_cell = { | |||
325 | }; | 324 | }; |
326 | 325 | ||
327 | /* | 326 | /* |
328 | * Touchscreen (STMPE811) | 327 | * STMPE801 |
328 | */ | ||
329 | static const u8 stmpe801_regs[] = { | ||
330 | [STMPE_IDX_CHIP_ID] = STMPE801_REG_CHIP_ID, | ||
331 | [STMPE_IDX_ICR_LSB] = STMPE801_REG_SYS_CTRL, | ||
332 | [STMPE_IDX_GPMR_LSB] = STMPE801_REG_GPIO_MP_STA, | ||
333 | [STMPE_IDX_GPSR_LSB] = STMPE801_REG_GPIO_SET_PIN, | ||
334 | [STMPE_IDX_GPCR_LSB] = STMPE801_REG_GPIO_SET_PIN, | ||
335 | [STMPE_IDX_GPDR_LSB] = STMPE801_REG_GPIO_DIR, | ||
336 | [STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN, | ||
337 | [STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA, | ||
338 | |||
339 | }; | ||
340 | |||
341 | static struct stmpe_variant_block stmpe801_blocks[] = { | ||
342 | { | ||
343 | .cell = &stmpe_gpio_cell, | ||
344 | .irq = 0, | ||
345 | .block = STMPE_BLOCK_GPIO, | ||
346 | }, | ||
347 | }; | ||
348 | |||
349 | static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks, | ||
350 | bool enable) | ||
351 | { | ||
352 | if (blocks & STMPE_BLOCK_GPIO) | ||
353 | return 0; | ||
354 | else | ||
355 | return -EINVAL; | ||
356 | } | ||
357 | |||
358 | static struct stmpe_variant_info stmpe801 = { | ||
359 | .name = "stmpe801", | ||
360 | .id_val = STMPE801_ID, | ||
361 | .id_mask = 0xffff, | ||
362 | .num_gpios = 8, | ||
363 | .regs = stmpe801_regs, | ||
364 | .blocks = stmpe801_blocks, | ||
365 | .num_blocks = ARRAY_SIZE(stmpe801_blocks), | ||
366 | .num_irqs = STMPE801_NR_INTERNAL_IRQS, | ||
367 | .enable = stmpe801_enable, | ||
368 | }; | ||
369 | |||
370 | /* | ||
371 | * Touchscreen (STMPE811 or STMPE610) | ||
329 | */ | 372 | */ |
330 | 373 | ||
331 | static struct resource stmpe_ts_resources[] = { | 374 | static struct resource stmpe_ts_resources[] = { |
@@ -350,7 +393,7 @@ static struct mfd_cell stmpe_ts_cell = { | |||
350 | }; | 393 | }; |
351 | 394 | ||
352 | /* | 395 | /* |
353 | * STMPE811 | 396 | * STMPE811 or STMPE610 |
354 | */ | 397 | */ |
355 | 398 | ||
356 | static const u8 stmpe811_regs[] = { | 399 | static const u8 stmpe811_regs[] = { |
@@ -421,6 +464,21 @@ static struct stmpe_variant_info stmpe811 = { | |||
421 | .get_altfunc = stmpe811_get_altfunc, | 464 | .get_altfunc = stmpe811_get_altfunc, |
422 | }; | 465 | }; |
423 | 466 | ||
467 | /* Similar to 811, except number of gpios */ | ||
468 | static struct stmpe_variant_info stmpe610 = { | ||
469 | .name = "stmpe610", | ||
470 | .id_val = 0x0811, | ||
471 | .id_mask = 0xffff, | ||
472 | .num_gpios = 6, | ||
473 | .af_bits = 1, | ||
474 | .regs = stmpe811_regs, | ||
475 | .blocks = stmpe811_blocks, | ||
476 | .num_blocks = ARRAY_SIZE(stmpe811_blocks), | ||
477 | .num_irqs = STMPE811_NR_INTERNAL_IRQS, | ||
478 | .enable = stmpe811_enable, | ||
479 | .get_altfunc = stmpe811_get_altfunc, | ||
480 | }; | ||
481 | |||
424 | /* | 482 | /* |
425 | * STMPE1601 | 483 | * STMPE1601 |
426 | */ | 484 | */ |
@@ -655,6 +713,8 @@ static struct stmpe_variant_info stmpe2403 = { | |||
655 | }; | 713 | }; |
656 | 714 | ||
657 | static struct stmpe_variant_info *stmpe_variant_info[] = { | 715 | static struct stmpe_variant_info *stmpe_variant_info[] = { |
716 | [STMPE610] = &stmpe610, | ||
717 | [STMPE801] = &stmpe801, | ||
658 | [STMPE811] = &stmpe811, | 718 | [STMPE811] = &stmpe811, |
659 | [STMPE1601] = &stmpe1601, | 719 | [STMPE1601] = &stmpe1601, |
660 | [STMPE2401] = &stmpe2401, | 720 | [STMPE2401] = &stmpe2401, |
@@ -671,6 +731,11 @@ static irqreturn_t stmpe_irq(int irq, void *data) | |||
671 | int ret; | 731 | int ret; |
672 | int i; | 732 | int i; |
673 | 733 | ||
734 | if (variant->id_val == STMPE801_ID) { | ||
735 | handle_nested_irq(stmpe->irq_base); | ||
736 | return IRQ_HANDLED; | ||
737 | } | ||
738 | |||
674 | ret = stmpe_block_read(stmpe, israddr, num, isr); | 739 | ret = stmpe_block_read(stmpe, israddr, num, isr); |
675 | if (ret < 0) | 740 | if (ret < 0) |
676 | return IRQ_NONE; | 741 | return IRQ_NONE; |
@@ -757,14 +822,17 @@ static struct irq_chip stmpe_irq_chip = { | |||
757 | 822 | ||
758 | static int __devinit stmpe_irq_init(struct stmpe *stmpe) | 823 | static int __devinit stmpe_irq_init(struct stmpe *stmpe) |
759 | { | 824 | { |
825 | struct irq_chip *chip = NULL; | ||
760 | int num_irqs = stmpe->variant->num_irqs; | 826 | int num_irqs = stmpe->variant->num_irqs; |
761 | int base = stmpe->irq_base; | 827 | int base = stmpe->irq_base; |
762 | int irq; | 828 | int irq; |
763 | 829 | ||
830 | if (stmpe->variant->id_val != STMPE801_ID) | ||
831 | chip = &stmpe_irq_chip; | ||
832 | |||
764 | for (irq = base; irq < base + num_irqs; irq++) { | 833 | for (irq = base; irq < base + num_irqs; irq++) { |
765 | irq_set_chip_data(irq, stmpe); | 834 | irq_set_chip_data(irq, stmpe); |
766 | irq_set_chip_and_handler(irq, &stmpe_irq_chip, | 835 | irq_set_chip_and_handler(irq, chip, handle_edge_irq); |
767 | handle_edge_irq); | ||
768 | irq_set_nested_thread(irq, 1); | 836 | irq_set_nested_thread(irq, 1); |
769 | #ifdef CONFIG_ARM | 837 | #ifdef CONFIG_ARM |
770 | set_irq_flags(irq, IRQF_VALID); | 838 | set_irq_flags(irq, IRQF_VALID); |
@@ -796,7 +864,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe) | |||
796 | unsigned int irq_trigger = stmpe->pdata->irq_trigger; | 864 | unsigned int irq_trigger = stmpe->pdata->irq_trigger; |
797 | int autosleep_timeout = stmpe->pdata->autosleep_timeout; | 865 | int autosleep_timeout = stmpe->pdata->autosleep_timeout; |
798 | struct stmpe_variant_info *variant = stmpe->variant; | 866 | struct stmpe_variant_info *variant = stmpe->variant; |
799 | u8 icr = STMPE_ICR_LSB_GIM; | 867 | u8 icr; |
800 | unsigned int id; | 868 | unsigned int id; |
801 | u8 data[2]; | 869 | u8 data[2]; |
802 | int ret; | 870 | int ret; |
@@ -819,16 +887,32 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe) | |||
819 | if (ret) | 887 | if (ret) |
820 | return ret; | 888 | return ret; |
821 | 889 | ||
822 | if (irq_trigger == IRQF_TRIGGER_FALLING || | 890 | if (id == STMPE801_ID) |
823 | irq_trigger == IRQF_TRIGGER_RISING) | 891 | icr = STMPE801_REG_SYS_CTRL_INT_EN; |
824 | icr |= STMPE_ICR_LSB_EDGE; | 892 | else |
893 | icr = STMPE_ICR_LSB_GIM; | ||
894 | |||
895 | /* STMPE801 doesn't support Edge interrupts */ | ||
896 | if (id != STMPE801_ID) { | ||
897 | if (irq_trigger == IRQF_TRIGGER_FALLING || | ||
898 | irq_trigger == IRQF_TRIGGER_RISING) | ||
899 | icr |= STMPE_ICR_LSB_EDGE; | ||
900 | } | ||
825 | 901 | ||
826 | if (irq_trigger == IRQF_TRIGGER_RISING || | 902 | if (irq_trigger == IRQF_TRIGGER_RISING || |
827 | irq_trigger == IRQF_TRIGGER_HIGH) | 903 | irq_trigger == IRQF_TRIGGER_HIGH) { |
828 | icr |= STMPE_ICR_LSB_HIGH; | 904 | if (id == STMPE801_ID) |
905 | icr |= STMPE801_REG_SYS_CTRL_INT_HI; | ||
906 | else | ||
907 | icr |= STMPE_ICR_LSB_HIGH; | ||
908 | } | ||
829 | 909 | ||
830 | if (stmpe->pdata->irq_invert_polarity) | 910 | if (stmpe->pdata->irq_invert_polarity) { |
831 | icr ^= STMPE_ICR_LSB_HIGH; | 911 | if (id == STMPE801_ID) |
912 | icr ^= STMPE801_REG_SYS_CTRL_INT_HI; | ||
913 | else | ||
914 | icr ^= STMPE_ICR_LSB_HIGH; | ||
915 | } | ||
832 | 916 | ||
833 | if (stmpe->pdata->autosleep) { | 917 | if (stmpe->pdata->autosleep) { |
834 | ret = stmpe_autosleep(stmpe, autosleep_timeout); | 918 | ret = stmpe_autosleep(stmpe, autosleep_timeout); |
@@ -873,32 +957,10 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe) | |||
873 | return ret; | 957 | return ret; |
874 | } | 958 | } |
875 | 959 | ||
876 | #ifdef CONFIG_PM | 960 | /* Called from client specific probe routines */ |
877 | static int stmpe_suspend(struct device *dev) | 961 | int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum) |
878 | { | ||
879 | struct i2c_client *i2c = to_i2c_client(dev); | ||
880 | |||
881 | if (device_may_wakeup(&i2c->dev)) | ||
882 | enable_irq_wake(i2c->irq); | ||
883 | |||
884 | return 0; | ||
885 | } | ||
886 | |||
887 | static int stmpe_resume(struct device *dev) | ||
888 | { | ||
889 | struct i2c_client *i2c = to_i2c_client(dev); | ||
890 | |||
891 | if (device_may_wakeup(&i2c->dev)) | ||
892 | disable_irq_wake(i2c->irq); | ||
893 | |||
894 | return 0; | ||
895 | } | ||
896 | #endif | ||
897 | |||
898 | static int __devinit stmpe_probe(struct i2c_client *i2c, | ||
899 | const struct i2c_device_id *id) | ||
900 | { | 962 | { |
901 | struct stmpe_platform_data *pdata = i2c->dev.platform_data; | 963 | struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev); |
902 | struct stmpe *stmpe; | 964 | struct stmpe *stmpe; |
903 | int ret; | 965 | int ret; |
904 | 966 | ||
@@ -912,30 +974,43 @@ static int __devinit stmpe_probe(struct i2c_client *i2c, | |||
912 | mutex_init(&stmpe->irq_lock); | 974 | mutex_init(&stmpe->irq_lock); |
913 | mutex_init(&stmpe->lock); | 975 | mutex_init(&stmpe->lock); |
914 | 976 | ||
915 | stmpe->dev = &i2c->dev; | 977 | stmpe->dev = ci->dev; |
916 | stmpe->i2c = i2c; | 978 | stmpe->client = ci->client; |
917 | |||
918 | stmpe->pdata = pdata; | 979 | stmpe->pdata = pdata; |
919 | stmpe->irq_base = pdata->irq_base; | 980 | stmpe->irq_base = pdata->irq_base; |
920 | 981 | stmpe->ci = ci; | |
921 | stmpe->partnum = id->driver_data; | 982 | stmpe->partnum = partnum; |
922 | stmpe->variant = stmpe_variant_info[stmpe->partnum]; | 983 | stmpe->variant = stmpe_variant_info[partnum]; |
923 | stmpe->regs = stmpe->variant->regs; | 984 | stmpe->regs = stmpe->variant->regs; |
924 | stmpe->num_gpios = stmpe->variant->num_gpios; | 985 | stmpe->num_gpios = stmpe->variant->num_gpios; |
986 | dev_set_drvdata(stmpe->dev, stmpe); | ||
925 | 987 | ||
926 | i2c_set_clientdata(i2c, stmpe); | 988 | if (ci->init) |
989 | ci->init(stmpe); | ||
990 | |||
991 | if (pdata->irq_over_gpio) { | ||
992 | ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe"); | ||
993 | if (ret) { | ||
994 | dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n", | ||
995 | ret); | ||
996 | goto out_free; | ||
997 | } | ||
998 | |||
999 | stmpe->irq = gpio_to_irq(pdata->irq_gpio); | ||
1000 | } else { | ||
1001 | stmpe->irq = ci->irq; | ||
1002 | } | ||
927 | 1003 | ||
928 | ret = stmpe_chip_init(stmpe); | 1004 | ret = stmpe_chip_init(stmpe); |
929 | if (ret) | 1005 | if (ret) |
930 | goto out_free; | 1006 | goto free_gpio; |
931 | 1007 | ||
932 | ret = stmpe_irq_init(stmpe); | 1008 | ret = stmpe_irq_init(stmpe); |
933 | if (ret) | 1009 | if (ret) |
934 | goto out_free; | 1010 | goto free_gpio; |
935 | 1011 | ||
936 | ret = request_threaded_irq(stmpe->i2c->irq, NULL, stmpe_irq, | 1012 | ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq, |
937 | pdata->irq_trigger | IRQF_ONESHOT, | 1013 | pdata->irq_trigger | IRQF_ONESHOT, "stmpe", stmpe); |
938 | "stmpe", stmpe); | ||
939 | if (ret) { | 1014 | if (ret) { |
940 | dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret); | 1015 | dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret); |
941 | goto out_removeirq; | 1016 | goto out_removeirq; |
@@ -951,67 +1026,55 @@ static int __devinit stmpe_probe(struct i2c_client *i2c, | |||
951 | 1026 | ||
952 | out_removedevs: | 1027 | out_removedevs: |
953 | mfd_remove_devices(stmpe->dev); | 1028 | mfd_remove_devices(stmpe->dev); |
954 | free_irq(stmpe->i2c->irq, stmpe); | 1029 | free_irq(stmpe->irq, stmpe); |
955 | out_removeirq: | 1030 | out_removeirq: |
956 | stmpe_irq_remove(stmpe); | 1031 | stmpe_irq_remove(stmpe); |
1032 | free_gpio: | ||
1033 | if (pdata->irq_over_gpio) | ||
1034 | gpio_free(pdata->irq_gpio); | ||
957 | out_free: | 1035 | out_free: |
958 | kfree(stmpe); | 1036 | kfree(stmpe); |
959 | return ret; | 1037 | return ret; |
960 | } | 1038 | } |
961 | 1039 | ||
962 | static int __devexit stmpe_remove(struct i2c_client *client) | 1040 | int stmpe_remove(struct stmpe *stmpe) |
963 | { | 1041 | { |
964 | struct stmpe *stmpe = i2c_get_clientdata(client); | ||
965 | |||
966 | mfd_remove_devices(stmpe->dev); | 1042 | mfd_remove_devices(stmpe->dev); |
967 | 1043 | ||
968 | free_irq(stmpe->i2c->irq, stmpe); | 1044 | free_irq(stmpe->irq, stmpe); |
969 | stmpe_irq_remove(stmpe); | 1045 | stmpe_irq_remove(stmpe); |
970 | 1046 | ||
1047 | if (stmpe->pdata->irq_over_gpio) | ||
1048 | gpio_free(stmpe->pdata->irq_gpio); | ||
1049 | |||
971 | kfree(stmpe); | 1050 | kfree(stmpe); |
972 | 1051 | ||
973 | return 0; | 1052 | return 0; |
974 | } | 1053 | } |
975 | 1054 | ||
976 | static const struct i2c_device_id stmpe_id[] = { | ||
977 | { "stmpe811", STMPE811 }, | ||
978 | { "stmpe1601", STMPE1601 }, | ||
979 | { "stmpe2401", STMPE2401 }, | ||
980 | { "stmpe2403", STMPE2403 }, | ||
981 | { } | ||
982 | }; | ||
983 | MODULE_DEVICE_TABLE(i2c, stmpe_id); | ||
984 | |||
985 | #ifdef CONFIG_PM | 1055 | #ifdef CONFIG_PM |
986 | static const struct dev_pm_ops stmpe_dev_pm_ops = { | 1056 | static int stmpe_suspend(struct device *dev) |
987 | .suspend = stmpe_suspend, | 1057 | { |
988 | .resume = stmpe_resume, | 1058 | struct stmpe *stmpe = dev_get_drvdata(dev); |
989 | }; | ||
990 | #endif | ||
991 | 1059 | ||
992 | static struct i2c_driver stmpe_driver = { | 1060 | if (device_may_wakeup(dev)) |
993 | .driver.name = "stmpe", | 1061 | enable_irq_wake(stmpe->irq); |
994 | .driver.owner = THIS_MODULE, | ||
995 | #ifdef CONFIG_PM | ||
996 | .driver.pm = &stmpe_dev_pm_ops, | ||
997 | #endif | ||
998 | .probe = stmpe_probe, | ||
999 | .remove = __devexit_p(stmpe_remove), | ||
1000 | .id_table = stmpe_id, | ||
1001 | }; | ||
1002 | 1062 | ||
1003 | static int __init stmpe_init(void) | 1063 | return 0; |
1004 | { | ||
1005 | return i2c_add_driver(&stmpe_driver); | ||
1006 | } | 1064 | } |
1007 | subsys_initcall(stmpe_init); | ||
1008 | 1065 | ||
1009 | static void __exit stmpe_exit(void) | 1066 | static int stmpe_resume(struct device *dev) |
1010 | { | 1067 | { |
1011 | i2c_del_driver(&stmpe_driver); | 1068 | struct stmpe *stmpe = dev_get_drvdata(dev); |
1069 | |||
1070 | if (device_may_wakeup(dev)) | ||
1071 | disable_irq_wake(stmpe->irq); | ||
1072 | |||
1073 | return 0; | ||
1012 | } | 1074 | } |
1013 | module_exit(stmpe_exit); | ||
1014 | 1075 | ||
1015 | MODULE_LICENSE("GPL v2"); | 1076 | const struct dev_pm_ops stmpe_dev_pm_ops = { |
1016 | MODULE_DESCRIPTION("STMPE MFD core driver"); | 1077 | .suspend = stmpe_suspend, |
1017 | MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); | 1078 | .resume = stmpe_resume, |
1079 | }; | ||
1080 | #endif | ||
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h index e4ee38956583..7b8e13f5b764 100644 --- a/drivers/mfd/stmpe.h +++ b/drivers/mfd/stmpe.h | |||
@@ -8,6 +8,14 @@ | |||
8 | #ifndef __STMPE_H | 8 | #ifndef __STMPE_H |
9 | #define __STMPE_H | 9 | #define __STMPE_H |
10 | 10 | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/mfd/core.h> | ||
13 | #include <linux/mfd/stmpe.h> | ||
14 | #include <linux/printk.h> | ||
15 | #include <linux/types.h> | ||
16 | |||
17 | extern const struct dev_pm_ops stmpe_dev_pm_ops; | ||
18 | |||
11 | #ifdef STMPE_DUMP_BYTES | 19 | #ifdef STMPE_DUMP_BYTES |
12 | static inline void stmpe_dump_bytes(const char *str, const void *buf, | 20 | static inline void stmpe_dump_bytes(const char *str, const void *buf, |
13 | size_t len) | 21 | size_t len) |
@@ -67,11 +75,55 @@ struct stmpe_variant_info { | |||
67 | int (*enable_autosleep)(struct stmpe *stmpe, int autosleep_timeout); | 75 | int (*enable_autosleep)(struct stmpe *stmpe, int autosleep_timeout); |
68 | }; | 76 | }; |
69 | 77 | ||
78 | /** | ||
79 | * struct stmpe_client_info - i2c or spi specific routines/info | ||
80 | * @data: client specific data | ||
81 | * @read_byte: read single byte | ||
82 | * @write_byte: write single byte | ||
83 | * @read_block: read block or multiple bytes | ||
84 | * @write_block: write block or multiple bytes | ||
85 | * @init: client init routine, called during probe | ||
86 | */ | ||
87 | struct stmpe_client_info { | ||
88 | void *data; | ||
89 | int irq; | ||
90 | void *client; | ||
91 | struct device *dev; | ||
92 | int (*read_byte)(struct stmpe *stmpe, u8 reg); | ||
93 | int (*write_byte)(struct stmpe *stmpe, u8 reg, u8 val); | ||
94 | int (*read_block)(struct stmpe *stmpe, u8 reg, u8 len, u8 *values); | ||
95 | int (*write_block)(struct stmpe *stmpe, u8 reg, u8 len, | ||
96 | const u8 *values); | ||
97 | void (*init)(struct stmpe *stmpe); | ||
98 | }; | ||
99 | |||
100 | int stmpe_probe(struct stmpe_client_info *ci, int partnum); | ||
101 | int stmpe_remove(struct stmpe *stmpe); | ||
102 | |||
70 | #define STMPE_ICR_LSB_HIGH (1 << 2) | 103 | #define STMPE_ICR_LSB_HIGH (1 << 2) |
71 | #define STMPE_ICR_LSB_EDGE (1 << 1) | 104 | #define STMPE_ICR_LSB_EDGE (1 << 1) |
72 | #define STMPE_ICR_LSB_GIM (1 << 0) | 105 | #define STMPE_ICR_LSB_GIM (1 << 0) |
73 | 106 | ||
74 | /* | 107 | /* |
108 | * STMPE801 | ||
109 | */ | ||
110 | #define STMPE801_ID 0x0108 | ||
111 | #define STMPE801_NR_INTERNAL_IRQS 1 | ||
112 | |||
113 | #define STMPE801_REG_CHIP_ID 0x00 | ||
114 | #define STMPE801_REG_VERSION_ID 0x02 | ||
115 | #define STMPE801_REG_SYS_CTRL 0x04 | ||
116 | #define STMPE801_REG_GPIO_INT_EN 0x08 | ||
117 | #define STMPE801_REG_GPIO_INT_STA 0x09 | ||
118 | #define STMPE801_REG_GPIO_MP_STA 0x10 | ||
119 | #define STMPE801_REG_GPIO_SET_PIN 0x11 | ||
120 | #define STMPE801_REG_GPIO_DIR 0x12 | ||
121 | |||
122 | #define STMPE801_REG_SYS_CTRL_RESET (1 << 7) | ||
123 | #define STMPE801_REG_SYS_CTRL_INT_EN (1 << 2) | ||
124 | #define STMPE801_REG_SYS_CTRL_INT_HI (1 << 0) | ||
125 | |||
126 | /* | ||
75 | * STMPE811 | 127 | * STMPE811 |
76 | */ | 128 | */ |
77 | 129 | ||
@@ -87,6 +139,7 @@ struct stmpe_variant_info { | |||
87 | 139 | ||
88 | #define STMPE811_REG_CHIP_ID 0x00 | 140 | #define STMPE811_REG_CHIP_ID 0x00 |
89 | #define STMPE811_REG_SYS_CTRL2 0x04 | 141 | #define STMPE811_REG_SYS_CTRL2 0x04 |
142 | #define STMPE811_REG_SPI_CFG 0x08 | ||
90 | #define STMPE811_REG_INT_CTRL 0x09 | 143 | #define STMPE811_REG_INT_CTRL 0x09 |
91 | #define STMPE811_REG_INT_EN 0x0A | 144 | #define STMPE811_REG_INT_EN 0x0A |
92 | #define STMPE811_REG_INT_STA 0x0B | 145 | #define STMPE811_REG_INT_STA 0x0B |
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c index 91ad21ef7721..2d9e8799e733 100644 --- a/drivers/mfd/t7l66xb.c +++ b/drivers/mfd/t7l66xb.c | |||
@@ -442,21 +442,7 @@ static struct platform_driver t7l66xb_platform_driver = { | |||
442 | 442 | ||
443 | /*--------------------------------------------------------------------------*/ | 443 | /*--------------------------------------------------------------------------*/ |
444 | 444 | ||
445 | static int __init t7l66xb_init(void) | 445 | module_platform_driver(t7l66xb_platform_driver); |
446 | { | ||
447 | int retval = 0; | ||
448 | |||
449 | retval = platform_driver_register(&t7l66xb_platform_driver); | ||
450 | return retval; | ||
451 | } | ||
452 | |||
453 | static void __exit t7l66xb_exit(void) | ||
454 | { | ||
455 | platform_driver_unregister(&t7l66xb_platform_driver); | ||
456 | } | ||
457 | |||
458 | module_init(t7l66xb_init); | ||
459 | module_exit(t7l66xb_exit); | ||
460 | 446 | ||
461 | MODULE_DESCRIPTION("Toshiba T7L66XB core driver"); | 447 | MODULE_DESCRIPTION("Toshiba T7L66XB core driver"); |
462 | MODULE_LICENSE("GPL v2"); | 448 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c index 71bc835324d8..d20a284ad4ba 100644 --- a/drivers/mfd/tc6387xb.c +++ b/drivers/mfd/tc6387xb.c | |||
@@ -234,19 +234,7 @@ static struct platform_driver tc6387xb_platform_driver = { | |||
234 | .resume = tc6387xb_resume, | 234 | .resume = tc6387xb_resume, |
235 | }; | 235 | }; |
236 | 236 | ||
237 | 237 | module_platform_driver(tc6387xb_platform_driver); | |
238 | static int __init tc6387xb_init(void) | ||
239 | { | ||
240 | return platform_driver_register(&tc6387xb_platform_driver); | ||
241 | } | ||
242 | |||
243 | static void __exit tc6387xb_exit(void) | ||
244 | { | ||
245 | platform_driver_unregister(&tc6387xb_platform_driver); | ||
246 | } | ||
247 | |||
248 | module_init(tc6387xb_init); | ||
249 | module_exit(tc6387xb_exit); | ||
250 | 238 | ||
251 | MODULE_DESCRIPTION("Toshiba TC6387XB core driver"); | 239 | MODULE_DESCRIPTION("Toshiba TC6387XB core driver"); |
252 | MODULE_LICENSE("GPL v2"); | 240 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c index af9ab0e5ca64..4fb0e6c8e8fe 100644 --- a/drivers/mfd/ti-ssp.c +++ b/drivers/mfd/ti-ssp.c | |||
@@ -458,17 +458,7 @@ static struct platform_driver ti_ssp_driver = { | |||
458 | } | 458 | } |
459 | }; | 459 | }; |
460 | 460 | ||
461 | static int __init ti_ssp_init(void) | 461 | module_platform_driver(ti_ssp_driver); |
462 | { | ||
463 | return platform_driver_register(&ti_ssp_driver); | ||
464 | } | ||
465 | module_init(ti_ssp_init); | ||
466 | |||
467 | static void __exit ti_ssp_exit(void) | ||
468 | { | ||
469 | platform_driver_unregister(&ti_ssp_driver); | ||
470 | } | ||
471 | module_exit(ti_ssp_exit); | ||
472 | 462 | ||
473 | MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); | 463 | MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver"); |
474 | MODULE_AUTHOR("Cyril Chemparathy"); | 464 | MODULE_AUTHOR("Cyril Chemparathy"); |
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c index 02d65692ceb4..0ba26fb12cf5 100644 --- a/drivers/mfd/timberdale.c +++ b/drivers/mfd/timberdale.c | |||
@@ -857,7 +857,7 @@ static void __devexit timb_remove(struct pci_dev *dev) | |||
857 | kfree(priv); | 857 | kfree(priv); |
858 | } | 858 | } |
859 | 859 | ||
860 | static struct pci_device_id timberdale_pci_tbl[] = { | 860 | static DEFINE_PCI_DEVICE_TABLE(timberdale_pci_tbl) = { |
861 | { PCI_DEVICE(PCI_VENDOR_ID_TIMB, PCI_DEVICE_ID_TIMB) }, | 861 | { PCI_DEVICE(PCI_VENDOR_ID_TIMB, PCI_DEVICE_ID_TIMB) }, |
862 | { 0 } | 862 | { 0 } |
863 | }; | 863 | }; |
diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c index a56be931551c..95c0d7978bec 100644 --- a/drivers/mfd/tps65910-irq.c +++ b/drivers/mfd/tps65910-irq.c | |||
@@ -215,6 +215,7 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq, | |||
215 | 215 | ||
216 | int tps65910_irq_exit(struct tps65910 *tps65910) | 216 | int tps65910_irq_exit(struct tps65910 *tps65910) |
217 | { | 217 | { |
218 | free_irq(tps65910->chip_irq, tps65910); | 218 | if (tps65910->chip_irq) |
219 | free_irq(tps65910->chip_irq, tps65910); | ||
219 | return 0; | 220 | return 0; |
220 | } | 221 | } |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index c1da84bc1573..01cf5012a08f 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -172,15 +172,12 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, | |||
172 | 172 | ||
173 | tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); | 173 | tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base); |
174 | 174 | ||
175 | ret = tps65910_irq_init(tps65910, init_data->irq, init_data); | 175 | tps65910_irq_init(tps65910, init_data->irq, init_data); |
176 | if (ret < 0) | ||
177 | goto err; | ||
178 | 176 | ||
179 | kfree(init_data); | 177 | kfree(init_data); |
180 | return ret; | 178 | return ret; |
181 | 179 | ||
182 | err: | 180 | err: |
183 | mfd_remove_devices(tps65910->dev); | ||
184 | kfree(tps65910); | 181 | kfree(tps65910); |
185 | kfree(init_data); | 182 | kfree(init_data); |
186 | return ret; | 183 | return ret; |
@@ -190,8 +187,8 @@ static int tps65910_i2c_remove(struct i2c_client *i2c) | |||
190 | { | 187 | { |
191 | struct tps65910 *tps65910 = i2c_get_clientdata(i2c); | 188 | struct tps65910 *tps65910 = i2c_get_clientdata(i2c); |
192 | 189 | ||
193 | mfd_remove_devices(tps65910->dev); | ||
194 | tps65910_irq_exit(tps65910); | 190 | tps65910_irq_exit(tps65910); |
191 | mfd_remove_devices(tps65910->dev); | ||
195 | kfree(tps65910); | 192 | kfree(tps65910); |
196 | 193 | ||
197 | return 0; | 194 | return 0; |
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c index 6d71e0d25744..27d3302d56b8 100644 --- a/drivers/mfd/tps65912-spi.c +++ b/drivers/mfd/tps65912-spi.c | |||
@@ -111,7 +111,6 @@ static int __devexit tps65912_spi_remove(struct spi_device *spi) | |||
111 | static struct spi_driver tps65912_spi_driver = { | 111 | static struct spi_driver tps65912_spi_driver = { |
112 | .driver = { | 112 | .driver = { |
113 | .name = "tps65912", | 113 | .name = "tps65912", |
114 | .bus = &spi_bus_type, | ||
115 | .owner = THIS_MODULE, | 114 | .owner = THIS_MODULE, |
116 | }, | 115 | }, |
117 | .probe = tps65912_spi_probe, | 116 | .probe = tps65912_spi_probe, |
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index 61e70cfaa774..e04e04ddc15e 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c | |||
@@ -34,6 +34,11 @@ | |||
34 | #include <linux/platform_device.h> | 34 | #include <linux/platform_device.h> |
35 | #include <linux/clk.h> | 35 | #include <linux/clk.h> |
36 | #include <linux/err.h> | 36 | #include <linux/err.h> |
37 | #include <linux/device.h> | ||
38 | #include <linux/of.h> | ||
39 | #include <linux/of_irq.h> | ||
40 | #include <linux/of_platform.h> | ||
41 | #include <linux/irqdomain.h> | ||
37 | 42 | ||
38 | #include <linux/regulator/machine.h> | 43 | #include <linux/regulator/machine.h> |
39 | 44 | ||
@@ -144,6 +149,9 @@ | |||
144 | 149 | ||
145 | #define TWL_MODULE_LAST TWL4030_MODULE_LAST | 150 | #define TWL_MODULE_LAST TWL4030_MODULE_LAST |
146 | 151 | ||
152 | #define TWL4030_NR_IRQS 8 | ||
153 | #define TWL6030_NR_IRQS 20 | ||
154 | |||
147 | /* Base Address defns for twl4030_map[] */ | 155 | /* Base Address defns for twl4030_map[] */ |
148 | 156 | ||
149 | /* subchip/slave 0 - USB ID */ | 157 | /* subchip/slave 0 - USB ID */ |
@@ -255,6 +263,7 @@ struct twl_client { | |||
255 | 263 | ||
256 | static struct twl_client twl_modules[TWL_NUM_SLAVES]; | 264 | static struct twl_client twl_modules[TWL_NUM_SLAVES]; |
257 | 265 | ||
266 | static struct irq_domain domain; | ||
258 | 267 | ||
259 | /* mapping the module id to slave id and base address */ | 268 | /* mapping the module id to slave id and base address */ |
260 | struct twl_mapping { | 269 | struct twl_mapping { |
@@ -1183,14 +1192,48 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1183 | int status; | 1192 | int status; |
1184 | unsigned i; | 1193 | unsigned i; |
1185 | struct twl4030_platform_data *pdata = client->dev.platform_data; | 1194 | struct twl4030_platform_data *pdata = client->dev.platform_data; |
1195 | struct device_node *node = client->dev.of_node; | ||
1186 | u8 temp; | 1196 | u8 temp; |
1187 | int ret = 0; | 1197 | int ret = 0; |
1198 | int nr_irqs = TWL4030_NR_IRQS; | ||
1199 | |||
1200 | if ((id->driver_data) & TWL6030_CLASS) | ||
1201 | nr_irqs = TWL6030_NR_IRQS; | ||
1202 | |||
1203 | if (node && !pdata) { | ||
1204 | /* | ||
1205 | * XXX: Temporary pdata until the information is correctly | ||
1206 | * retrieved by every TWL modules from DT. | ||
1207 | */ | ||
1208 | pdata = devm_kzalloc(&client->dev, | ||
1209 | sizeof(struct twl4030_platform_data), | ||
1210 | GFP_KERNEL); | ||
1211 | if (!pdata) | ||
1212 | return -ENOMEM; | ||
1213 | } | ||
1188 | 1214 | ||
1189 | if (!pdata) { | 1215 | if (!pdata) { |
1190 | dev_dbg(&client->dev, "no platform data?\n"); | 1216 | dev_dbg(&client->dev, "no platform data?\n"); |
1191 | return -EINVAL; | 1217 | return -EINVAL; |
1192 | } | 1218 | } |
1193 | 1219 | ||
1220 | status = irq_alloc_descs(-1, pdata->irq_base, nr_irqs, 0); | ||
1221 | if (IS_ERR_VALUE(status)) { | ||
1222 | dev_err(&client->dev, "Fail to allocate IRQ descs\n"); | ||
1223 | return status; | ||
1224 | } | ||
1225 | |||
1226 | pdata->irq_base = status; | ||
1227 | pdata->irq_end = pdata->irq_base + nr_irqs; | ||
1228 | |||
1229 | domain.irq_base = pdata->irq_base; | ||
1230 | domain.nr_irq = nr_irqs; | ||
1231 | #ifdef CONFIG_OF_IRQ | ||
1232 | domain.of_node = of_node_get(node); | ||
1233 | domain.ops = &irq_domain_simple_ops; | ||
1234 | #endif | ||
1235 | irq_domain_add(&domain); | ||
1236 | |||
1194 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { | 1237 | if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { |
1195 | dev_dbg(&client->dev, "can't talk I2C?\n"); | 1238 | dev_dbg(&client->dev, "can't talk I2C?\n"); |
1196 | return -EIO; | 1239 | return -EIO; |
@@ -1270,7 +1313,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
1270 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); | 1313 | twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); |
1271 | } | 1314 | } |
1272 | 1315 | ||
1273 | status = add_children(pdata, id->driver_data); | 1316 | #ifdef CONFIG_OF_DEVICE |
1317 | if (node) | ||
1318 | status = of_platform_populate(node, NULL, NULL, &client->dev); | ||
1319 | else | ||
1320 | #endif | ||
1321 | status = add_children(pdata, id->driver_data); | ||
1322 | |||
1274 | fail: | 1323 | fail: |
1275 | if (status < 0) | 1324 | if (status < 0) |
1276 | twl_remove(client); | 1325 | twl_remove(client); |
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index ae51ab5d0e5d..838ce4eb444e 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c | |||
@@ -261,17 +261,7 @@ static struct platform_driver twl4030_audio_driver = { | |||
261 | }, | 261 | }, |
262 | }; | 262 | }; |
263 | 263 | ||
264 | static int __devinit twl4030_audio_init(void) | 264 | module_platform_driver(twl4030_audio_driver); |
265 | { | ||
266 | return platform_driver_register(&twl4030_audio_driver); | ||
267 | } | ||
268 | module_init(twl4030_audio_init); | ||
269 | |||
270 | static void __devexit twl4030_audio_exit(void) | ||
271 | { | ||
272 | platform_driver_unregister(&twl4030_audio_driver); | ||
273 | } | ||
274 | module_exit(twl4030_audio_exit); | ||
275 | 265 | ||
276 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); | 266 | MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>"); |
277 | MODULE_LICENSE("GPL"); | 267 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c index 29f11e0765fe..b69bb517b102 100644 --- a/drivers/mfd/twl4030-irq.c +++ b/drivers/mfd/twl4030-irq.c | |||
@@ -492,7 +492,7 @@ static void twl4030_sih_bus_sync_unlock(struct irq_data *data) | |||
492 | u8 bytes[4]; | 492 | u8 bytes[4]; |
493 | } imr; | 493 | } imr; |
494 | 494 | ||
495 | /* byte[0] gets overwriten as we write ... */ | 495 | /* byte[0] gets overwritten as we write ... */ |
496 | imr.word = cpu_to_le32(agent->imr << 8); | 496 | imr.word = cpu_to_le32(agent->imr << 8); |
497 | agent->imr_change_pending = false; | 497 | agent->imr_change_pending = false; |
498 | 498 | ||
@@ -667,6 +667,7 @@ int twl4030_sih_setup(int module) | |||
667 | irq_set_chip_data(irq, agent); | 667 | irq_set_chip_data(irq, agent); |
668 | irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip, | 668 | irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip, |
669 | handle_edge_irq); | 669 | handle_edge_irq); |
670 | irq_set_nested_thread(irq, 1); | ||
670 | activate_irq(irq); | 671 | activate_irq(irq); |
671 | } | 672 | } |
672 | 673 | ||
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c index 834f824d3c11..456ecb5ac4fe 100644 --- a/drivers/mfd/twl4030-madc.c +++ b/drivers/mfd/twl4030-madc.c | |||
@@ -807,19 +807,7 @@ static struct platform_driver twl4030_madc_driver = { | |||
807 | }, | 807 | }, |
808 | }; | 808 | }; |
809 | 809 | ||
810 | static int __init twl4030_madc_init(void) | 810 | module_platform_driver(twl4030_madc_driver); |
811 | { | ||
812 | return platform_driver_register(&twl4030_madc_driver); | ||
813 | } | ||
814 | |||
815 | module_init(twl4030_madc_init); | ||
816 | |||
817 | static void __exit twl4030_madc_exit(void) | ||
818 | { | ||
819 | platform_driver_unregister(&twl4030_madc_driver); | ||
820 | } | ||
821 | |||
822 | module_exit(twl4030_madc_exit); | ||
823 | 811 | ||
824 | MODULE_DESCRIPTION("TWL4030 ADC driver"); | 812 | MODULE_DESCRIPTION("TWL4030 ADC driver"); |
825 | MODULE_LICENSE("GPL"); | 813 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index a764676f0922..d905f5171153 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c | |||
@@ -34,7 +34,8 @@ | |||
34 | static u8 twl4030_start_script_address = 0x2b; | 34 | static u8 twl4030_start_script_address = 0x2b; |
35 | 35 | ||
36 | #define PWR_P1_SW_EVENTS 0x10 | 36 | #define PWR_P1_SW_EVENTS 0x10 |
37 | #define PWR_DEVOFF (1<<0) | 37 | #define PWR_DEVOFF (1 << 0) |
38 | #define SEQ_OFFSYNC (1 << 0) | ||
38 | 39 | ||
39 | #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) | 40 | #define PHY_TO_OFF_PM_MASTER(p) (p - 0x36) |
40 | #define PHY_TO_OFF_PM_RECEIVER(p) (p - 0x5b) | 41 | #define PHY_TO_OFF_PM_RECEIVER(p) (p - 0x5b) |
@@ -511,12 +512,27 @@ int twl4030_remove_script(u8 flags) | |||
511 | return err; | 512 | return err; |
512 | } | 513 | } |
513 | 514 | ||
515 | /* | ||
516 | * In master mode, start the power off sequence. | ||
517 | * After a successful execution, TWL shuts down the power to the SoC | ||
518 | * and all peripherals connected to it. | ||
519 | */ | ||
520 | void twl4030_power_off(void) | ||
521 | { | ||
522 | int err; | ||
523 | |||
524 | err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, PWR_DEVOFF, | ||
525 | TWL4030_PM_MASTER_P1_SW_EVENTS); | ||
526 | if (err) | ||
527 | pr_err("TWL4030 Unable to power off\n"); | ||
528 | } | ||
529 | |||
514 | void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) | 530 | void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) |
515 | { | 531 | { |
516 | int err = 0; | 532 | int err = 0; |
517 | int i; | 533 | int i; |
518 | struct twl4030_resconfig *resconfig; | 534 | struct twl4030_resconfig *resconfig; |
519 | u8 address = twl4030_start_script_address; | 535 | u8 val, address = twl4030_start_script_address; |
520 | 536 | ||
521 | err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, | 537 | err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, |
522 | TWL4030_PM_MASTER_KEY_CFG1, | 538 | TWL4030_PM_MASTER_KEY_CFG1, |
@@ -548,6 +564,28 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) | |||
548 | } | 564 | } |
549 | } | 565 | } |
550 | 566 | ||
567 | /* Board has to be wired properly to use this feature */ | ||
568 | if (twl4030_scripts->use_poweroff && !pm_power_off) { | ||
569 | /* Default for SEQ_OFFSYNC is set, lets ensure this */ | ||
570 | err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &val, | ||
571 | TWL4030_PM_MASTER_CFG_P123_TRANSITION); | ||
572 | if (err) { | ||
573 | pr_warning("TWL4030 Unable to read registers\n"); | ||
574 | |||
575 | } else if (!(val & SEQ_OFFSYNC)) { | ||
576 | val |= SEQ_OFFSYNC; | ||
577 | err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, val, | ||
578 | TWL4030_PM_MASTER_CFG_P123_TRANSITION); | ||
579 | if (err) { | ||
580 | pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n"); | ||
581 | goto relock; | ||
582 | } | ||
583 | } | ||
584 | |||
585 | pm_power_off = twl4030_power_off; | ||
586 | } | ||
587 | |||
588 | relock: | ||
551 | err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, | 589 | err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, |
552 | TWL4030_PM_MASTER_PROTECT_KEY); | 590 | TWL4030_PM_MASTER_PROTECT_KEY); |
553 | if (err) | 591 | if (err) |
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index 268f80fd0439..dda86293dc9f 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c | |||
@@ -509,13 +509,10 @@ static int __devinit twl6040_probe(struct platform_device *pdev) | |||
509 | twl6040->audpwron = -EINVAL; | 509 | twl6040->audpwron = -EINVAL; |
510 | 510 | ||
511 | if (gpio_is_valid(twl6040->audpwron)) { | 511 | if (gpio_is_valid(twl6040->audpwron)) { |
512 | ret = gpio_request(twl6040->audpwron, "audpwron"); | 512 | ret = gpio_request_one(twl6040->audpwron, GPIOF_OUT_INIT_LOW, |
513 | "audpwron"); | ||
513 | if (ret) | 514 | if (ret) |
514 | goto gpio1_err; | 515 | goto gpio1_err; |
515 | |||
516 | ret = gpio_direction_output(twl6040->audpwron, 0); | ||
517 | if (ret) | ||
518 | goto gpio2_err; | ||
519 | } | 516 | } |
520 | 517 | ||
521 | /* codec interrupt */ | 518 | /* codec interrupt */ |
@@ -619,18 +616,7 @@ static struct platform_driver twl6040_driver = { | |||
619 | }, | 616 | }, |
620 | }; | 617 | }; |
621 | 618 | ||
622 | static int __devinit twl6040_init(void) | 619 | module_platform_driver(twl6040_driver); |
623 | { | ||
624 | return platform_driver_register(&twl6040_driver); | ||
625 | } | ||
626 | module_init(twl6040_init); | ||
627 | |||
628 | static void __devexit twl6040_exit(void) | ||
629 | { | ||
630 | platform_driver_unregister(&twl6040_driver); | ||
631 | } | ||
632 | |||
633 | module_exit(twl6040_exit); | ||
634 | 620 | ||
635 | MODULE_DESCRIPTION("TWL6040 MFD"); | 621 | MODULE_DESCRIPTION("TWL6040 MFD"); |
636 | MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); | 622 | MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); |
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c index b281217334eb..91c4f25e0e55 100644 --- a/drivers/mfd/ucb1x00-core.c +++ b/drivers/mfd/ucb1x00-core.c | |||
@@ -36,6 +36,15 @@ static DEFINE_MUTEX(ucb1x00_mutex); | |||
36 | static LIST_HEAD(ucb1x00_drivers); | 36 | static LIST_HEAD(ucb1x00_drivers); |
37 | static LIST_HEAD(ucb1x00_devices); | 37 | static LIST_HEAD(ucb1x00_devices); |
38 | 38 | ||
39 | static struct mcp_device_id ucb1x00_id[] = { | ||
40 | { "ucb1x00", 0 }, /* auto-detection */ | ||
41 | { "ucb1200", UCB_ID_1200 }, | ||
42 | { "ucb1300", UCB_ID_1300 }, | ||
43 | { "tc35143", UCB_ID_TC35143 }, | ||
44 | { } | ||
45 | }; | ||
46 | MODULE_DEVICE_TABLE(mcp, ucb1x00_id); | ||
47 | |||
39 | /** | 48 | /** |
40 | * ucb1x00_io_set_dir - set IO direction | 49 | * ucb1x00_io_set_dir - set IO direction |
41 | * @ucb: UCB1x00 structure describing chip | 50 | * @ucb: UCB1x00 structure describing chip |
@@ -527,17 +536,33 @@ static struct class ucb1x00_class = { | |||
527 | 536 | ||
528 | static int ucb1x00_probe(struct mcp *mcp) | 537 | static int ucb1x00_probe(struct mcp *mcp) |
529 | { | 538 | { |
539 | const struct mcp_device_id *mid; | ||
530 | struct ucb1x00 *ucb; | 540 | struct ucb1x00 *ucb; |
531 | struct ucb1x00_driver *drv; | 541 | struct ucb1x00_driver *drv; |
542 | struct ucb1x00_plat_data *pdata; | ||
532 | unsigned int id; | 543 | unsigned int id; |
533 | int ret = -ENODEV; | 544 | int ret = -ENODEV; |
534 | int temp; | 545 | int temp; |
535 | 546 | ||
536 | mcp_enable(mcp); | 547 | mcp_enable(mcp); |
537 | id = mcp_reg_read(mcp, UCB_ID); | 548 | id = mcp_reg_read(mcp, UCB_ID); |
549 | mid = mcp_get_device_id(mcp); | ||
538 | 550 | ||
539 | if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) { | 551 | if (mid && mid->driver_data) { |
540 | printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id); | 552 | if (id != mid->driver_data) { |
553 | printk(KERN_WARNING "%s wrong ID %04x found: %04x\n", | ||
554 | mid->name, (unsigned int) mid->driver_data, id); | ||
555 | goto err_disable; | ||
556 | } | ||
557 | } else { | ||
558 | mid = &ucb1x00_id[1]; | ||
559 | while (mid->driver_data) { | ||
560 | if (id == mid->driver_data) | ||
561 | break; | ||
562 | mid++; | ||
563 | } | ||
564 | printk(KERN_WARNING "%s ID not found: %04x\n", | ||
565 | ucb1x00_id[0].name, id); | ||
541 | goto err_disable; | 566 | goto err_disable; |
542 | } | 567 | } |
543 | 568 | ||
@@ -546,28 +571,28 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
546 | if (!ucb) | 571 | if (!ucb) |
547 | goto err_disable; | 572 | goto err_disable; |
548 | 573 | ||
549 | 574 | pdata = mcp->attached_device.platform_data; | |
550 | ucb->dev.class = &ucb1x00_class; | 575 | ucb->dev.class = &ucb1x00_class; |
551 | ucb->dev.parent = &mcp->attached_device; | 576 | ucb->dev.parent = &mcp->attached_device; |
552 | dev_set_name(&ucb->dev, "ucb1x00"); | 577 | dev_set_name(&ucb->dev, mid->name); |
553 | 578 | ||
554 | spin_lock_init(&ucb->lock); | 579 | spin_lock_init(&ucb->lock); |
555 | spin_lock_init(&ucb->io_lock); | 580 | spin_lock_init(&ucb->io_lock); |
556 | sema_init(&ucb->adc_sem, 1); | 581 | sema_init(&ucb->adc_sem, 1); |
557 | 582 | ||
558 | ucb->id = id; | 583 | ucb->id = mid; |
559 | ucb->mcp = mcp; | 584 | ucb->mcp = mcp; |
560 | ucb->irq = ucb1x00_detect_irq(ucb); | 585 | ucb->irq = ucb1x00_detect_irq(ucb); |
561 | if (ucb->irq == NO_IRQ) { | 586 | if (ucb->irq == NO_IRQ) { |
562 | printk(KERN_ERR "UCB1x00: IRQ probe failed\n"); | 587 | printk(KERN_ERR "%s: IRQ probe failed\n", mid->name); |
563 | ret = -ENODEV; | 588 | ret = -ENODEV; |
564 | goto err_free; | 589 | goto err_free; |
565 | } | 590 | } |
566 | 591 | ||
567 | ucb->gpio.base = -1; | 592 | ucb->gpio.base = -1; |
568 | if (mcp->gpio_base != 0) { | 593 | if (pdata && (pdata->gpio_base >= 0)) { |
569 | ucb->gpio.label = dev_name(&ucb->dev); | 594 | ucb->gpio.label = dev_name(&ucb->dev); |
570 | ucb->gpio.base = mcp->gpio_base; | 595 | ucb->gpio.base = pdata->gpio_base; |
571 | ucb->gpio.ngpio = 10; | 596 | ucb->gpio.ngpio = 10; |
572 | ucb->gpio.set = ucb1x00_gpio_set; | 597 | ucb->gpio.set = ucb1x00_gpio_set; |
573 | ucb->gpio.get = ucb1x00_gpio_get; | 598 | ucb->gpio.get = ucb1x00_gpio_get; |
@@ -580,10 +605,10 @@ static int ucb1x00_probe(struct mcp *mcp) | |||
580 | dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); | 605 | dev_info(&ucb->dev, "gpio_base not set so no gpiolib support"); |
581 | 606 | ||
582 | ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, | 607 | ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING, |
583 | "UCB1x00", ucb); | 608 | mid->name, ucb); |
584 | if (ret) { | 609 | if (ret) { |
585 | printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n", | 610 | printk(KERN_ERR "%s: unable to grab irq%d: %d\n", |
586 | ucb->irq, ret); | 611 | mid->name, ucb->irq, ret); |
587 | goto err_gpio; | 612 | goto err_gpio; |
588 | } | 613 | } |
589 | 614 | ||
@@ -705,6 +730,7 @@ static struct mcp_driver ucb1x00_driver = { | |||
705 | .remove = ucb1x00_remove, | 730 | .remove = ucb1x00_remove, |
706 | .suspend = ucb1x00_suspend, | 731 | .suspend = ucb1x00_suspend, |
707 | .resume = ucb1x00_resume, | 732 | .resume = ucb1x00_resume, |
733 | .id_table = ucb1x00_id, | ||
708 | }; | 734 | }; |
709 | 735 | ||
710 | static int __init ucb1x00_init(void) | 736 | static int __init ucb1x00_init(void) |
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c index 38ffbd50a0d2..40ec3c118868 100644 --- a/drivers/mfd/ucb1x00-ts.c +++ b/drivers/mfd/ucb1x00-ts.c | |||
@@ -382,7 +382,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev) | |||
382 | ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; | 382 | ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC; |
383 | 383 | ||
384 | idev->name = "Touchscreen panel"; | 384 | idev->name = "Touchscreen panel"; |
385 | idev->id.product = ts->ucb->id; | 385 | idev->id.product = ts->ucb->id->driver_data; |
386 | idev->open = ucb1x00_ts_open; | 386 | idev->open = ucb1x00_ts_open; |
387 | idev->close = ucb1x00_ts_close; | 387 | idev->close = ucb1x00_ts_close; |
388 | 388 | ||
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c index d698703dbd46..b73cc15e0081 100644 --- a/drivers/mfd/vx855.c +++ b/drivers/mfd/vx855.c | |||
@@ -118,7 +118,7 @@ static void __devexit vx855_remove(struct pci_dev *pdev) | |||
118 | pci_disable_device(pdev); | 118 | pci_disable_device(pdev); |
119 | } | 119 | } |
120 | 120 | ||
121 | static struct pci_device_id vx855_pci_tbl[] = { | 121 | static DEFINE_PCI_DEVICE_TABLE(vx855_pci_tbl) = { |
122 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, | 122 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) }, |
123 | { 0, } | 123 | { 0, } |
124 | }; | 124 | }; |
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 0a2b8d41a702..f5e54fae8ada 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
@@ -559,6 +559,8 @@ static int wm831x_write(struct wm831x *wm831x, unsigned short reg, | |||
559 | dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n", | 559 | dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n", |
560 | buf[i], reg + i, reg + i); | 560 | buf[i], reg + i, reg + i); |
561 | ret = regmap_write(wm831x->regmap, reg + i, buf[i]); | 561 | ret = regmap_write(wm831x->regmap, reg + i, buf[i]); |
562 | if (ret != 0) | ||
563 | return ret; | ||
562 | } | 564 | } |
563 | 565 | ||
564 | return 0; | 566 | return 0; |
@@ -1875,7 +1877,6 @@ err_irq: | |||
1875 | err_regmap: | 1877 | err_regmap: |
1876 | mfd_remove_devices(wm831x->dev); | 1878 | mfd_remove_devices(wm831x->dev); |
1877 | regmap_exit(wm831x->regmap); | 1879 | regmap_exit(wm831x->regmap); |
1878 | kfree(wm831x); | ||
1879 | return ret; | 1880 | return ret; |
1880 | } | 1881 | } |
1881 | 1882 | ||
@@ -1887,7 +1888,6 @@ void wm831x_device_exit(struct wm831x *wm831x) | |||
1887 | free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x); | 1888 | free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x); |
1888 | wm831x_irq_exit(wm831x); | 1889 | wm831x_irq_exit(wm831x); |
1889 | regmap_exit(wm831x->regmap); | 1890 | regmap_exit(wm831x->regmap); |
1890 | kfree(wm831x); | ||
1891 | } | 1891 | } |
1892 | 1892 | ||
1893 | int wm831x_device_suspend(struct wm831x *wm831x) | 1893 | int wm831x_device_suspend(struct wm831x *wm831x) |
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c index ac8da1d439da..cb15609b0a48 100644 --- a/drivers/mfd/wm831x-i2c.c +++ b/drivers/mfd/wm831x-i2c.c | |||
@@ -30,7 +30,7 @@ static int wm831x_i2c_probe(struct i2c_client *i2c, | |||
30 | struct wm831x *wm831x; | 30 | struct wm831x *wm831x; |
31 | int ret; | 31 | int ret; |
32 | 32 | ||
33 | wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL); | 33 | wm831x = devm_kzalloc(&i2c->dev, sizeof(struct wm831x), GFP_KERNEL); |
34 | if (wm831x == NULL) | 34 | if (wm831x == NULL) |
35 | return -ENOMEM; | 35 | return -ENOMEM; |
36 | 36 | ||
@@ -42,7 +42,6 @@ static int wm831x_i2c_probe(struct i2c_client *i2c, | |||
42 | ret = PTR_ERR(wm831x->regmap); | 42 | ret = PTR_ERR(wm831x->regmap); |
43 | dev_err(wm831x->dev, "Failed to allocate register map: %d\n", | 43 | dev_err(wm831x->dev, "Failed to allocate register map: %d\n", |
44 | ret); | 44 | ret); |
45 | kfree(wm831x); | ||
46 | return ret; | 45 | return ret; |
47 | } | 46 | } |
48 | 47 | ||
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c index f4747a4a9a93..bec4d0539160 100644 --- a/drivers/mfd/wm831x-irq.c +++ b/drivers/mfd/wm831x-irq.c | |||
@@ -325,11 +325,6 @@ static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data) | |||
325 | return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg; | 325 | return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg; |
326 | } | 326 | } |
327 | 327 | ||
328 | static inline int irq_data_to_mask_reg(struct wm831x_irq_data *irq_data) | ||
329 | { | ||
330 | return WM831X_INTERRUPT_STATUS_1_MASK - 1 + irq_data->reg; | ||
331 | } | ||
332 | |||
333 | static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, | 328 | static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x, |
334 | int irq) | 329 | int irq) |
335 | { | 330 | { |
@@ -477,8 +472,7 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data) | |||
477 | handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD); | 472 | handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD); |
478 | if (primary & WM831X_TCHDATA_INT) | 473 | if (primary & WM831X_TCHDATA_INT) |
479 | handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA); | 474 | handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA); |
480 | if (primary & (WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT)) | 475 | primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT); |
481 | goto out; | ||
482 | 476 | ||
483 | for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { | 477 | for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) { |
484 | int offset = wm831x_irqs[i].reg - 1; | 478 | int offset = wm831x_irqs[i].reg - 1; |
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c index 8d6a9a969dbc..62ef3254105f 100644 --- a/drivers/mfd/wm831x-spi.c +++ b/drivers/mfd/wm831x-spi.c | |||
@@ -30,7 +30,7 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi) | |||
30 | 30 | ||
31 | type = (enum wm831x_parent)id->driver_data; | 31 | type = (enum wm831x_parent)id->driver_data; |
32 | 32 | ||
33 | wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL); | 33 | wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL); |
34 | if (wm831x == NULL) | 34 | if (wm831x == NULL) |
35 | return -ENOMEM; | 35 | return -ENOMEM; |
36 | 36 | ||
@@ -45,7 +45,6 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi) | |||
45 | ret = PTR_ERR(wm831x->regmap); | 45 | ret = PTR_ERR(wm831x->regmap); |
46 | dev_err(wm831x->dev, "Failed to allocate register map: %d\n", | 46 | dev_err(wm831x->dev, "Failed to allocate register map: %d\n", |
47 | ret); | 47 | ret); |
48 | kfree(wm831x); | ||
49 | return ret; | 48 | return ret; |
50 | } | 49 | } |
51 | 50 | ||
@@ -95,7 +94,6 @@ MODULE_DEVICE_TABLE(spi, wm831x_spi_id); | |||
95 | static struct spi_driver wm831x_spi_driver = { | 94 | static struct spi_driver wm831x_spi_driver = { |
96 | .driver = { | 95 | .driver = { |
97 | .name = "wm831x", | 96 | .name = "wm831x", |
98 | .bus = &spi_bus_type, | ||
99 | .owner = THIS_MODULE, | 97 | .owner = THIS_MODULE, |
100 | .pm = &wm831x_spi_pm, | 98 | .pm = &wm831x_spi_pm, |
101 | }, | 99 | }, |
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index e81cc31e4202..dd1caaac55e4 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -573,6 +573,8 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq, | |||
573 | u16 id1, id2, mask_rev; | 573 | u16 id1, id2, mask_rev; |
574 | u16 cust_id, mode, chip_rev; | 574 | u16 cust_id, mode, chip_rev; |
575 | 575 | ||
576 | dev_set_drvdata(wm8350->dev, wm8350); | ||
577 | |||
576 | /* get WM8350 revision and config mode */ | 578 | /* get WM8350 revision and config mode */ |
577 | ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); | 579 | ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1); |
578 | if (ret != 0) { | 580 | if (ret != 0) { |
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index 5fe5de166adb..d955faaf27c4 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c | |||
@@ -63,7 +63,7 @@ static int wm8350_i2c_probe(struct i2c_client *i2c, | |||
63 | struct wm8350 *wm8350; | 63 | struct wm8350 *wm8350; |
64 | int ret = 0; | 64 | int ret = 0; |
65 | 65 | ||
66 | wm8350 = kzalloc(sizeof(struct wm8350), GFP_KERNEL); | 66 | wm8350 = devm_kzalloc(&i2c->dev, sizeof(struct wm8350), GFP_KERNEL); |
67 | if (wm8350 == NULL) | 67 | if (wm8350 == NULL) |
68 | return -ENOMEM; | 68 | return -ENOMEM; |
69 | 69 | ||
@@ -80,7 +80,6 @@ static int wm8350_i2c_probe(struct i2c_client *i2c, | |||
80 | return ret; | 80 | return ret; |
81 | 81 | ||
82 | err: | 82 | err: |
83 | kfree(wm8350); | ||
84 | return ret; | 83 | return ret; |
85 | } | 84 | } |
86 | 85 | ||
@@ -89,7 +88,6 @@ static int wm8350_i2c_remove(struct i2c_client *i2c) | |||
89 | struct wm8350 *wm8350 = i2c_get_clientdata(i2c); | 88 | struct wm8350 *wm8350 = i2c_get_clientdata(i2c); |
90 | 89 | ||
91 | wm8350_device_exit(wm8350); | 90 | wm8350_device_exit(wm8350); |
92 | kfree(wm8350); | ||
93 | 91 | ||
94 | return 0; | 92 | return 0; |
95 | } | 93 | } |
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 62b4626f4561..2204893444a6 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c | |||
@@ -344,7 +344,7 @@ static int wm8400_i2c_probe(struct i2c_client *i2c, | |||
344 | struct wm8400 *wm8400; | 344 | struct wm8400 *wm8400; |
345 | int ret; | 345 | int ret; |
346 | 346 | ||
347 | wm8400 = kzalloc(sizeof(struct wm8400), GFP_KERNEL); | 347 | wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL); |
348 | if (wm8400 == NULL) { | 348 | if (wm8400 == NULL) { |
349 | ret = -ENOMEM; | 349 | ret = -ENOMEM; |
350 | goto err; | 350 | goto err; |
@@ -353,7 +353,7 @@ static int wm8400_i2c_probe(struct i2c_client *i2c, | |||
353 | wm8400->regmap = regmap_init_i2c(i2c, &wm8400_regmap_config); | 353 | wm8400->regmap = regmap_init_i2c(i2c, &wm8400_regmap_config); |
354 | if (IS_ERR(wm8400->regmap)) { | 354 | if (IS_ERR(wm8400->regmap)) { |
355 | ret = PTR_ERR(wm8400->regmap); | 355 | ret = PTR_ERR(wm8400->regmap); |
356 | goto struct_err; | 356 | goto err; |
357 | } | 357 | } |
358 | 358 | ||
359 | wm8400->dev = &i2c->dev; | 359 | wm8400->dev = &i2c->dev; |
@@ -367,8 +367,6 @@ static int wm8400_i2c_probe(struct i2c_client *i2c, | |||
367 | 367 | ||
368 | map_err: | 368 | map_err: |
369 | regmap_exit(wm8400->regmap); | 369 | regmap_exit(wm8400->regmap); |
370 | struct_err: | ||
371 | kfree(wm8400); | ||
372 | err: | 370 | err: |
373 | return ret; | 371 | return ret; |
374 | } | 372 | } |
@@ -379,7 +377,6 @@ static int wm8400_i2c_remove(struct i2c_client *i2c) | |||
379 | 377 | ||
380 | wm8400_release(wm8400); | 378 | wm8400_release(wm8400); |
381 | regmap_exit(wm8400->regmap); | 379 | regmap_exit(wm8400->regmap); |
382 | kfree(wm8400); | ||
383 | 380 | ||
384 | return 0; | 381 | return 0; |
385 | } | 382 | } |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 5664696f2d3a..6a1a092db146 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -500,6 +500,14 @@ config USB_SWITCH_FSA9480 | |||
500 | stereo and mono audio, video, microphone and UART data to use | 500 | stereo and mono audio, video, microphone and UART data to use |
501 | a common connector port. | 501 | a common connector port. |
502 | 502 | ||
503 | config MAX8997_MUIC | ||
504 | tristate "MAX8997 MUIC Support" | ||
505 | depends on MFD_MAX8997 | ||
506 | help | ||
507 | If you say yes here you get support for the MUIC device of | ||
508 | Maxim MAX8997 PMIC. | ||
509 | The MAX8997 MUIC is a USB port accessory detector and switch. | ||
510 | |||
503 | source "drivers/misc/c2port/Kconfig" | 511 | source "drivers/misc/c2port/Kconfig" |
504 | source "drivers/misc/eeprom/Kconfig" | 512 | source "drivers/misc/eeprom/Kconfig" |
505 | source "drivers/misc/cb710/Kconfig" | 513 | source "drivers/misc/cb710/Kconfig" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b26495a02554..3e1d80106f04 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -48,3 +48,4 @@ obj-y += lis3lv02d/ | |||
48 | obj-y += carma/ | 48 | obj-y += carma/ |
49 | obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o | 49 | obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o |
50 | obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ | 50 | obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ |
51 | obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o | ||
diff --git a/drivers/misc/ab8500-pwm.c b/drivers/misc/ab8500-pwm.c index 2208a9d52622..d7a9aa14e5d5 100644 --- a/drivers/misc/ab8500-pwm.c +++ b/drivers/misc/ab8500-pwm.c | |||
@@ -8,8 +8,8 @@ | |||
8 | #include <linux/platform_device.h> | 8 | #include <linux/platform_device.h> |
9 | #include <linux/slab.h> | 9 | #include <linux/slab.h> |
10 | #include <linux/pwm.h> | 10 | #include <linux/pwm.h> |
11 | #include <linux/mfd/ab8500.h> | ||
12 | #include <linux/mfd/abx500.h> | 11 | #include <linux/mfd/abx500.h> |
12 | #include <linux/mfd/abx500/ab8500.h> | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | 14 | ||
15 | /* | 15 | /* |
diff --git a/drivers/misc/max8997-muic.c b/drivers/misc/max8997-muic.c new file mode 100644 index 000000000000..d74ef41aabd5 --- /dev/null +++ b/drivers/misc/max8997-muic.c | |||
@@ -0,0 +1,505 @@ | |||
1 | /* | ||
2 | * max8997-muic.c - MAX8997 muic driver for the Maxim 8997 | ||
3 | * | ||
4 | * Copyright (C) 2011 Samsung Electrnoics | ||
5 | * Donggeun Kim <dg77.kim@samsung.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/err.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/kobject.h> | ||
31 | #include <linux/mfd/max8997.h> | ||
32 | #include <linux/mfd/max8997-private.h> | ||
33 | |||
34 | /* MAX8997-MUIC STATUS1 register */ | ||
35 | #define STATUS1_ADC_SHIFT 0 | ||
36 | #define STATUS1_ADCLOW_SHIFT 5 | ||
37 | #define STATUS1_ADCERR_SHIFT 6 | ||
38 | #define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT) | ||
39 | #define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT) | ||
40 | #define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT) | ||
41 | |||
42 | /* MAX8997-MUIC STATUS2 register */ | ||
43 | #define STATUS2_CHGTYP_SHIFT 0 | ||
44 | #define STATUS2_CHGDETRUN_SHIFT 3 | ||
45 | #define STATUS2_DCDTMR_SHIFT 4 | ||
46 | #define STATUS2_DBCHG_SHIFT 5 | ||
47 | #define STATUS2_VBVOLT_SHIFT 6 | ||
48 | #define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT) | ||
49 | #define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT) | ||
50 | #define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT) | ||
51 | #define STATUS2_DBCHG_MASK (0x1 << STATUS2_DBCHG_SHIFT) | ||
52 | #define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT) | ||
53 | |||
54 | /* MAX8997-MUIC STATUS3 register */ | ||
55 | #define STATUS3_OVP_SHIFT 2 | ||
56 | #define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT) | ||
57 | |||
58 | /* MAX8997-MUIC CONTROL1 register */ | ||
59 | #define COMN1SW_SHIFT 0 | ||
60 | #define COMP2SW_SHIFT 3 | ||
61 | #define COMN1SW_MASK (0x7 << COMN1SW_SHIFT) | ||
62 | #define COMP2SW_MASK (0x7 << COMP2SW_SHIFT) | ||
63 | #define SW_MASK (COMP2SW_MASK | COMN1SW_MASK) | ||
64 | |||
65 | #define MAX8997_SW_USB ((1 << COMP2SW_SHIFT) | (1 << COMN1SW_SHIFT)) | ||
66 | #define MAX8997_SW_AUDIO ((2 << COMP2SW_SHIFT) | (2 << COMN1SW_SHIFT)) | ||
67 | #define MAX8997_SW_UART ((3 << COMP2SW_SHIFT) | (3 << COMN1SW_SHIFT)) | ||
68 | #define MAX8997_SW_OPEN ((0 << COMP2SW_SHIFT) | (0 << COMN1SW_SHIFT)) | ||
69 | |||
70 | #define MAX8997_ADC_GROUND 0x00 | ||
71 | #define MAX8997_ADC_MHL 0x01 | ||
72 | #define MAX8997_ADC_JIG_USB_1 0x18 | ||
73 | #define MAX8997_ADC_JIG_USB_2 0x19 | ||
74 | #define MAX8997_ADC_DESKDOCK 0x1a | ||
75 | #define MAX8997_ADC_JIG_UART 0x1c | ||
76 | #define MAX8997_ADC_CARDOCK 0x1d | ||
77 | #define MAX8997_ADC_OPEN 0x1f | ||
78 | |||
79 | struct max8997_muic_irq { | ||
80 | unsigned int irq; | ||
81 | const char *name; | ||
82 | }; | ||
83 | |||
84 | static struct max8997_muic_irq muic_irqs[] = { | ||
85 | { MAX8997_MUICIRQ_ADCError, "muic-ADC_error" }, | ||
86 | { MAX8997_MUICIRQ_ADCLow, "muic-ADC_low" }, | ||
87 | { MAX8997_MUICIRQ_ADC, "muic-ADC" }, | ||
88 | { MAX8997_MUICIRQ_VBVolt, "muic-VB_voltage" }, | ||
89 | { MAX8997_MUICIRQ_DBChg, "muic-DB_charger" }, | ||
90 | { MAX8997_MUICIRQ_DCDTmr, "muic-DCD_timer" }, | ||
91 | { MAX8997_MUICIRQ_ChgDetRun, "muic-CDR_status" }, | ||
92 | { MAX8997_MUICIRQ_ChgTyp, "muic-charger_type" }, | ||
93 | { MAX8997_MUICIRQ_OVP, "muic-over_voltage" }, | ||
94 | }; | ||
95 | |||
96 | struct max8997_muic_info { | ||
97 | struct device *dev; | ||
98 | struct max8997_dev *iodev; | ||
99 | struct i2c_client *muic; | ||
100 | struct max8997_muic_platform_data *muic_pdata; | ||
101 | |||
102 | int irq; | ||
103 | struct work_struct irq_work; | ||
104 | |||
105 | enum max8997_muic_charger_type pre_charger_type; | ||
106 | int pre_adc; | ||
107 | |||
108 | struct mutex mutex; | ||
109 | }; | ||
110 | |||
111 | static int max8997_muic_handle_usb(struct max8997_muic_info *info, | ||
112 | enum max8997_muic_usb_type usb_type, bool attached) | ||
113 | { | ||
114 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
115 | int ret = 0; | ||
116 | |||
117 | if (usb_type == MAX8997_USB_HOST) { | ||
118 | /* switch to USB */ | ||
119 | ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, | ||
120 | attached ? MAX8997_SW_USB : MAX8997_SW_OPEN, | ||
121 | SW_MASK); | ||
122 | if (ret) { | ||
123 | dev_err(info->dev, "failed to update muic register\n"); | ||
124 | goto out; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | if (mdata->usb_callback) | ||
129 | mdata->usb_callback(usb_type, attached); | ||
130 | out: | ||
131 | return ret; | ||
132 | } | ||
133 | |||
134 | static void max8997_muic_handle_mhl(struct max8997_muic_info *info, | ||
135 | bool attached) | ||
136 | { | ||
137 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
138 | |||
139 | if (mdata->mhl_callback) | ||
140 | mdata->mhl_callback(attached); | ||
141 | } | ||
142 | |||
143 | static int max8997_muic_handle_dock(struct max8997_muic_info *info, | ||
144 | int adc, bool attached) | ||
145 | { | ||
146 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
147 | int ret = 0; | ||
148 | |||
149 | /* switch to AUDIO */ | ||
150 | ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, | ||
151 | attached ? MAX8997_SW_AUDIO : MAX8997_SW_OPEN, | ||
152 | SW_MASK); | ||
153 | if (ret) { | ||
154 | dev_err(info->dev, "failed to update muic register\n"); | ||
155 | goto out; | ||
156 | } | ||
157 | |||
158 | switch (adc) { | ||
159 | case MAX8997_ADC_DESKDOCK: | ||
160 | if (mdata->deskdock_callback) | ||
161 | mdata->deskdock_callback(attached); | ||
162 | break; | ||
163 | case MAX8997_ADC_CARDOCK: | ||
164 | if (mdata->cardock_callback) | ||
165 | mdata->cardock_callback(attached); | ||
166 | break; | ||
167 | default: | ||
168 | break; | ||
169 | } | ||
170 | out: | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info, | ||
175 | bool attached) | ||
176 | { | ||
177 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
178 | int ret = 0; | ||
179 | |||
180 | /* switch to UART */ | ||
181 | ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1, | ||
182 | attached ? MAX8997_SW_UART : MAX8997_SW_OPEN, | ||
183 | SW_MASK); | ||
184 | if (ret) { | ||
185 | dev_err(info->dev, "failed to update muic register\n"); | ||
186 | goto out; | ||
187 | } | ||
188 | |||
189 | if (mdata->uart_callback) | ||
190 | mdata->uart_callback(attached); | ||
191 | out: | ||
192 | return ret; | ||
193 | } | ||
194 | |||
195 | static int max8997_muic_handle_adc_detach(struct max8997_muic_info *info) | ||
196 | { | ||
197 | int ret = 0; | ||
198 | |||
199 | switch (info->pre_adc) { | ||
200 | case MAX8997_ADC_GROUND: | ||
201 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false); | ||
202 | break; | ||
203 | case MAX8997_ADC_MHL: | ||
204 | max8997_muic_handle_mhl(info, false); | ||
205 | break; | ||
206 | case MAX8997_ADC_JIG_USB_1: | ||
207 | case MAX8997_ADC_JIG_USB_2: | ||
208 | ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, false); | ||
209 | break; | ||
210 | case MAX8997_ADC_DESKDOCK: | ||
211 | case MAX8997_ADC_CARDOCK: | ||
212 | ret = max8997_muic_handle_dock(info, info->pre_adc, false); | ||
213 | break; | ||
214 | case MAX8997_ADC_JIG_UART: | ||
215 | ret = max8997_muic_handle_jig_uart(info, false); | ||
216 | break; | ||
217 | default: | ||
218 | break; | ||
219 | } | ||
220 | |||
221 | return ret; | ||
222 | } | ||
223 | |||
224 | static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc) | ||
225 | { | ||
226 | int ret = 0; | ||
227 | |||
228 | switch (adc) { | ||
229 | case MAX8997_ADC_GROUND: | ||
230 | ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true); | ||
231 | break; | ||
232 | case MAX8997_ADC_MHL: | ||
233 | max8997_muic_handle_mhl(info, true); | ||
234 | break; | ||
235 | case MAX8997_ADC_JIG_USB_1: | ||
236 | case MAX8997_ADC_JIG_USB_2: | ||
237 | ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, true); | ||
238 | break; | ||
239 | case MAX8997_ADC_DESKDOCK: | ||
240 | case MAX8997_ADC_CARDOCK: | ||
241 | ret = max8997_muic_handle_dock(info, adc, true); | ||
242 | break; | ||
243 | case MAX8997_ADC_JIG_UART: | ||
244 | ret = max8997_muic_handle_jig_uart(info, true); | ||
245 | break; | ||
246 | case MAX8997_ADC_OPEN: | ||
247 | ret = max8997_muic_handle_adc_detach(info); | ||
248 | break; | ||
249 | default: | ||
250 | break; | ||
251 | } | ||
252 | |||
253 | info->pre_adc = adc; | ||
254 | |||
255 | return ret; | ||
256 | } | ||
257 | |||
258 | static int max8997_muic_handle_charger_type(struct max8997_muic_info *info, | ||
259 | enum max8997_muic_charger_type charger_type) | ||
260 | { | ||
261 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
262 | u8 adc; | ||
263 | int ret; | ||
264 | |||
265 | ret = max8997_read_reg(info->muic, MAX8997_MUIC_REG_STATUS1, &adc); | ||
266 | if (ret) { | ||
267 | dev_err(info->dev, "failed to read muic register\n"); | ||
268 | goto out; | ||
269 | } | ||
270 | |||
271 | switch (charger_type) { | ||
272 | case MAX8997_CHARGER_TYPE_NONE: | ||
273 | if (mdata->charger_callback) | ||
274 | mdata->charger_callback(false, charger_type); | ||
275 | if (info->pre_charger_type == MAX8997_CHARGER_TYPE_USB) { | ||
276 | max8997_muic_handle_usb(info, | ||
277 | MAX8997_USB_DEVICE, false); | ||
278 | } | ||
279 | break; | ||
280 | case MAX8997_CHARGER_TYPE_USB: | ||
281 | if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) { | ||
282 | max8997_muic_handle_usb(info, | ||
283 | MAX8997_USB_DEVICE, true); | ||
284 | } | ||
285 | if (mdata->charger_callback) | ||
286 | mdata->charger_callback(true, charger_type); | ||
287 | break; | ||
288 | case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT: | ||
289 | case MAX8997_CHARGER_TYPE_DEDICATED_CHG: | ||
290 | case MAX8997_CHARGER_TYPE_500MA: | ||
291 | case MAX8997_CHARGER_TYPE_1A: | ||
292 | if (mdata->charger_callback) | ||
293 | mdata->charger_callback(true, charger_type); | ||
294 | break; | ||
295 | default: | ||
296 | break; | ||
297 | } | ||
298 | |||
299 | info->pre_charger_type = charger_type; | ||
300 | out: | ||
301 | return ret; | ||
302 | } | ||
303 | |||
304 | static void max8997_muic_irq_work(struct work_struct *work) | ||
305 | { | ||
306 | struct max8997_muic_info *info = container_of(work, | ||
307 | struct max8997_muic_info, irq_work); | ||
308 | struct max8997_platform_data *pdata = | ||
309 | dev_get_platdata(info->iodev->dev); | ||
310 | u8 status[3]; | ||
311 | u8 adc, chg_type; | ||
312 | |||
313 | int irq_type = info->irq - pdata->irq_base; | ||
314 | int ret; | ||
315 | |||
316 | mutex_lock(&info->mutex); | ||
317 | |||
318 | ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, | ||
319 | 3, status); | ||
320 | if (ret) { | ||
321 | dev_err(info->dev, "failed to read muic register\n"); | ||
322 | mutex_unlock(&info->mutex); | ||
323 | return; | ||
324 | } | ||
325 | |||
326 | dev_dbg(info->dev, "%s: STATUS1:0x%x, 2:0x%x\n", __func__, | ||
327 | status[0], status[1]); | ||
328 | |||
329 | switch (irq_type) { | ||
330 | case MAX8997_MUICIRQ_ADC: | ||
331 | adc = status[0] & STATUS1_ADC_MASK; | ||
332 | adc >>= STATUS1_ADC_SHIFT; | ||
333 | |||
334 | max8997_muic_handle_adc(info, adc); | ||
335 | break; | ||
336 | case MAX8997_MUICIRQ_ChgTyp: | ||
337 | chg_type = status[1] & STATUS2_CHGTYP_MASK; | ||
338 | chg_type >>= STATUS2_CHGTYP_SHIFT; | ||
339 | |||
340 | max8997_muic_handle_charger_type(info, chg_type); | ||
341 | break; | ||
342 | default: | ||
343 | dev_info(info->dev, "misc interrupt: %s occurred\n", | ||
344 | muic_irqs[irq_type].name); | ||
345 | break; | ||
346 | } | ||
347 | |||
348 | mutex_unlock(&info->mutex); | ||
349 | |||
350 | return; | ||
351 | } | ||
352 | |||
353 | static irqreturn_t max8997_muic_irq_handler(int irq, void *data) | ||
354 | { | ||
355 | struct max8997_muic_info *info = data; | ||
356 | |||
357 | dev_dbg(info->dev, "irq:%d\n", irq); | ||
358 | info->irq = irq; | ||
359 | |||
360 | schedule_work(&info->irq_work); | ||
361 | |||
362 | return IRQ_HANDLED; | ||
363 | } | ||
364 | |||
365 | static void max8997_muic_detect_dev(struct max8997_muic_info *info) | ||
366 | { | ||
367 | int ret; | ||
368 | u8 status[2], adc, chg_type; | ||
369 | |||
370 | ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1, | ||
371 | 2, status); | ||
372 | if (ret) { | ||
373 | dev_err(info->dev, "failed to read muic register\n"); | ||
374 | return; | ||
375 | } | ||
376 | |||
377 | dev_info(info->dev, "STATUS1:0x%x, STATUS2:0x%x\n", | ||
378 | status[0], status[1]); | ||
379 | |||
380 | adc = status[0] & STATUS1_ADC_MASK; | ||
381 | adc >>= STATUS1_ADC_SHIFT; | ||
382 | |||
383 | chg_type = status[1] & STATUS2_CHGTYP_MASK; | ||
384 | chg_type >>= STATUS2_CHGTYP_SHIFT; | ||
385 | |||
386 | max8997_muic_handle_adc(info, adc); | ||
387 | max8997_muic_handle_charger_type(info, chg_type); | ||
388 | } | ||
389 | |||
390 | static void max8997_initialize_device(struct max8997_muic_info *info) | ||
391 | { | ||
392 | struct max8997_muic_platform_data *mdata = info->muic_pdata; | ||
393 | int i; | ||
394 | |||
395 | for (i = 0; i < mdata->num_init_data; i++) { | ||
396 | max8997_write_reg(info->muic, mdata->init_data[i].addr, | ||
397 | mdata->init_data[i].data); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | static int __devinit max8997_muic_probe(struct platform_device *pdev) | ||
402 | { | ||
403 | struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
404 | struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
405 | struct max8997_muic_info *info; | ||
406 | int ret, i; | ||
407 | |||
408 | info = kzalloc(sizeof(struct max8997_muic_info), GFP_KERNEL); | ||
409 | if (!info) { | ||
410 | dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
411 | ret = -ENOMEM; | ||
412 | goto err_kfree; | ||
413 | } | ||
414 | |||
415 | if (!pdata->muic_pdata) { | ||
416 | dev_err(&pdev->dev, "failed to get platform_data\n"); | ||
417 | ret = -EINVAL; | ||
418 | goto err_pdata; | ||
419 | } | ||
420 | info->muic_pdata = pdata->muic_pdata; | ||
421 | |||
422 | info->dev = &pdev->dev; | ||
423 | info->iodev = iodev; | ||
424 | info->muic = iodev->muic; | ||
425 | |||
426 | platform_set_drvdata(pdev, info); | ||
427 | mutex_init(&info->mutex); | ||
428 | |||
429 | INIT_WORK(&info->irq_work, max8997_muic_irq_work); | ||
430 | |||
431 | for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) { | ||
432 | struct max8997_muic_irq *muic_irq = &muic_irqs[i]; | ||
433 | |||
434 | ret = request_threaded_irq(pdata->irq_base + muic_irq->irq, | ||
435 | NULL, max8997_muic_irq_handler, | ||
436 | 0, muic_irq->name, | ||
437 | info); | ||
438 | if (ret) { | ||
439 | dev_err(&pdev->dev, | ||
440 | "failed: irq request (IRQ: %d," | ||
441 | " error :%d)\n", | ||
442 | muic_irq->irq, ret); | ||
443 | |||
444 | for (i = i - 1; i >= 0; i--) | ||
445 | free_irq(muic_irq->irq, info); | ||
446 | |||
447 | goto err_irq; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | /* Initialize registers according to platform data */ | ||
452 | max8997_initialize_device(info); | ||
453 | |||
454 | /* Initial device detection */ | ||
455 | max8997_muic_detect_dev(info); | ||
456 | |||
457 | return ret; | ||
458 | |||
459 | err_irq: | ||
460 | err_pdata: | ||
461 | kfree(info); | ||
462 | err_kfree: | ||
463 | return ret; | ||
464 | } | ||
465 | |||
466 | static int __devexit max8997_muic_remove(struct platform_device *pdev) | ||
467 | { | ||
468 | struct max8997_muic_info *info = platform_get_drvdata(pdev); | ||
469 | struct max8997_platform_data *pdata = | ||
470 | dev_get_platdata(info->iodev->dev); | ||
471 | int i; | ||
472 | |||
473 | for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) | ||
474 | free_irq(pdata->irq_base + muic_irqs[i].irq, info); | ||
475 | cancel_work_sync(&info->irq_work); | ||
476 | |||
477 | kfree(info); | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static struct platform_driver max8997_muic_driver = { | ||
483 | .driver = { | ||
484 | .name = "max8997-muic", | ||
485 | .owner = THIS_MODULE, | ||
486 | }, | ||
487 | .probe = max8997_muic_probe, | ||
488 | .remove = __devexit_p(max8997_muic_remove), | ||
489 | }; | ||
490 | |||
491 | static int __init max8997_muic_init(void) | ||
492 | { | ||
493 | return platform_driver_register(&max8997_muic_driver); | ||
494 | } | ||
495 | module_init(max8997_muic_init); | ||
496 | |||
497 | static void __exit max8997_muic_exit(void) | ||
498 | { | ||
499 | platform_driver_unregister(&max8997_muic_driver); | ||
500 | } | ||
501 | module_exit(max8997_muic_exit); | ||
502 | |||
503 | MODULE_DESCRIPTION("Maxim MAX8997 MUIC driver"); | ||
504 | MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>"); | ||
505 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 12eef393e216..400756ec7c49 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile | |||
@@ -6,5 +6,4 @@ subdir-ccflags-$(CONFIG_MMC_DEBUG) := -DDEBUG | |||
6 | 6 | ||
7 | obj-$(CONFIG_MMC) += core/ | 7 | obj-$(CONFIG_MMC) += core/ |
8 | obj-$(CONFIG_MMC) += card/ | 8 | obj-$(CONFIG_MMC) += card/ |
9 | obj-$(CONFIG_MMC) += host/ | 9 | obj-$(subst m,y,$(CONFIG_MMC)) += host/ |
10 | |||
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 1e0e27cbe987..0cad48a284a8 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c | |||
@@ -107,6 +107,8 @@ struct mmc_blk_data { | |||
107 | */ | 107 | */ |
108 | unsigned int part_curr; | 108 | unsigned int part_curr; |
109 | struct device_attribute force_ro; | 109 | struct device_attribute force_ro; |
110 | struct device_attribute power_ro_lock; | ||
111 | int area_type; | ||
110 | }; | 112 | }; |
111 | 113 | ||
112 | static DEFINE_MUTEX(open_lock); | 114 | static DEFINE_MUTEX(open_lock); |
@@ -119,6 +121,7 @@ enum mmc_blk_status { | |||
119 | MMC_BLK_ABORT, | 121 | MMC_BLK_ABORT, |
120 | MMC_BLK_DATA_ERR, | 122 | MMC_BLK_DATA_ERR, |
121 | MMC_BLK_ECC_ERR, | 123 | MMC_BLK_ECC_ERR, |
124 | MMC_BLK_NOMEDIUM, | ||
122 | }; | 125 | }; |
123 | 126 | ||
124 | module_param(perdev_minors, int, 0444); | 127 | module_param(perdev_minors, int, 0444); |
@@ -165,6 +168,70 @@ static void mmc_blk_put(struct mmc_blk_data *md) | |||
165 | mutex_unlock(&open_lock); | 168 | mutex_unlock(&open_lock); |
166 | } | 169 | } |
167 | 170 | ||
171 | static ssize_t power_ro_lock_show(struct device *dev, | ||
172 | struct device_attribute *attr, char *buf) | ||
173 | { | ||
174 | int ret; | ||
175 | struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev)); | ||
176 | struct mmc_card *card = md->queue.card; | ||
177 | int locked = 0; | ||
178 | |||
179 | if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PERM_WP_EN) | ||
180 | locked = 2; | ||
181 | else if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_EN) | ||
182 | locked = 1; | ||
183 | |||
184 | ret = snprintf(buf, PAGE_SIZE, "%d\n", locked); | ||
185 | |||
186 | return ret; | ||
187 | } | ||
188 | |||
189 | static ssize_t power_ro_lock_store(struct device *dev, | ||
190 | struct device_attribute *attr, const char *buf, size_t count) | ||
191 | { | ||
192 | int ret; | ||
193 | struct mmc_blk_data *md, *part_md; | ||
194 | struct mmc_card *card; | ||
195 | unsigned long set; | ||
196 | |||
197 | if (kstrtoul(buf, 0, &set)) | ||
198 | return -EINVAL; | ||
199 | |||
200 | if (set != 1) | ||
201 | return count; | ||
202 | |||
203 | md = mmc_blk_get(dev_to_disk(dev)); | ||
204 | card = md->queue.card; | ||
205 | |||
206 | mmc_claim_host(card->host); | ||
207 | |||
208 | ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, | ||
209 | card->ext_csd.boot_ro_lock | | ||
210 | EXT_CSD_BOOT_WP_B_PWR_WP_EN, | ||
211 | card->ext_csd.part_time); | ||
212 | if (ret) | ||
213 | pr_err("%s: Locking boot partition ro until next power on failed: %d\n", md->disk->disk_name, ret); | ||
214 | else | ||
215 | card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN; | ||
216 | |||
217 | mmc_release_host(card->host); | ||
218 | |||
219 | if (!ret) { | ||
220 | pr_info("%s: Locking boot partition ro until next power on\n", | ||
221 | md->disk->disk_name); | ||
222 | set_disk_ro(md->disk, 1); | ||
223 | |||
224 | list_for_each_entry(part_md, &md->part, part) | ||
225 | if (part_md->area_type == MMC_BLK_DATA_AREA_BOOT) { | ||
226 | pr_info("%s: Locking boot partition ro until next power on\n", part_md->disk->disk_name); | ||
227 | set_disk_ro(part_md->disk, 1); | ||
228 | } | ||
229 | } | ||
230 | |||
231 | mmc_blk_put(md); | ||
232 | return count; | ||
233 | } | ||
234 | |||
168 | static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, | 235 | static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr, |
169 | char *buf) | 236 | char *buf) |
170 | { | 237 | { |
@@ -266,6 +333,9 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user( | |||
266 | goto idata_err; | 333 | goto idata_err; |
267 | } | 334 | } |
268 | 335 | ||
336 | if (!idata->buf_bytes) | ||
337 | return idata; | ||
338 | |||
269 | idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); | 339 | idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL); |
270 | if (!idata->buf) { | 340 | if (!idata->buf) { |
271 | err = -ENOMEM; | 341 | err = -ENOMEM; |
@@ -312,25 +382,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
312 | if (IS_ERR(idata)) | 382 | if (IS_ERR(idata)) |
313 | return PTR_ERR(idata); | 383 | return PTR_ERR(idata); |
314 | 384 | ||
315 | cmd.opcode = idata->ic.opcode; | ||
316 | cmd.arg = idata->ic.arg; | ||
317 | cmd.flags = idata->ic.flags; | ||
318 | |||
319 | data.sg = &sg; | ||
320 | data.sg_len = 1; | ||
321 | data.blksz = idata->ic.blksz; | ||
322 | data.blocks = idata->ic.blocks; | ||
323 | |||
324 | sg_init_one(data.sg, idata->buf, idata->buf_bytes); | ||
325 | |||
326 | if (idata->ic.write_flag) | ||
327 | data.flags = MMC_DATA_WRITE; | ||
328 | else | ||
329 | data.flags = MMC_DATA_READ; | ||
330 | |||
331 | mrq.cmd = &cmd; | ||
332 | mrq.data = &data; | ||
333 | |||
334 | md = mmc_blk_get(bdev->bd_disk); | 385 | md = mmc_blk_get(bdev->bd_disk); |
335 | if (!md) { | 386 | if (!md) { |
336 | err = -EINVAL; | 387 | err = -EINVAL; |
@@ -343,6 +394,48 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
343 | goto cmd_done; | 394 | goto cmd_done; |
344 | } | 395 | } |
345 | 396 | ||
397 | cmd.opcode = idata->ic.opcode; | ||
398 | cmd.arg = idata->ic.arg; | ||
399 | cmd.flags = idata->ic.flags; | ||
400 | |||
401 | if (idata->buf_bytes) { | ||
402 | data.sg = &sg; | ||
403 | data.sg_len = 1; | ||
404 | data.blksz = idata->ic.blksz; | ||
405 | data.blocks = idata->ic.blocks; | ||
406 | |||
407 | sg_init_one(data.sg, idata->buf, idata->buf_bytes); | ||
408 | |||
409 | if (idata->ic.write_flag) | ||
410 | data.flags = MMC_DATA_WRITE; | ||
411 | else | ||
412 | data.flags = MMC_DATA_READ; | ||
413 | |||
414 | /* data.flags must already be set before doing this. */ | ||
415 | mmc_set_data_timeout(&data, card); | ||
416 | |||
417 | /* Allow overriding the timeout_ns for empirical tuning. */ | ||
418 | if (idata->ic.data_timeout_ns) | ||
419 | data.timeout_ns = idata->ic.data_timeout_ns; | ||
420 | |||
421 | if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { | ||
422 | /* | ||
423 | * Pretend this is a data transfer and rely on the | ||
424 | * host driver to compute timeout. When all host | ||
425 | * drivers support cmd.cmd_timeout for R1B, this | ||
426 | * can be changed to: | ||
427 | * | ||
428 | * mrq.data = NULL; | ||
429 | * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; | ||
430 | */ | ||
431 | data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; | ||
432 | } | ||
433 | |||
434 | mrq.data = &data; | ||
435 | } | ||
436 | |||
437 | mrq.cmd = &cmd; | ||
438 | |||
346 | mmc_claim_host(card->host); | 439 | mmc_claim_host(card->host); |
347 | 440 | ||
348 | if (idata->ic.is_acmd) { | 441 | if (idata->ic.is_acmd) { |
@@ -351,24 +444,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev, | |||
351 | goto cmd_rel_host; | 444 | goto cmd_rel_host; |
352 | } | 445 | } |
353 | 446 | ||
354 | /* data.flags must already be set before doing this. */ | ||
355 | mmc_set_data_timeout(&data, card); | ||
356 | /* Allow overriding the timeout_ns for empirical tuning. */ | ||
357 | if (idata->ic.data_timeout_ns) | ||
358 | data.timeout_ns = idata->ic.data_timeout_ns; | ||
359 | |||
360 | if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) { | ||
361 | /* | ||
362 | * Pretend this is a data transfer and rely on the host driver | ||
363 | * to compute timeout. When all host drivers support | ||
364 | * cmd.cmd_timeout for R1B, this can be changed to: | ||
365 | * | ||
366 | * mrq.data = NULL; | ||
367 | * cmd.cmd_timeout = idata->ic.cmd_timeout_ms; | ||
368 | */ | ||
369 | data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000; | ||
370 | } | ||
371 | |||
372 | mmc_wait_for_req(card->host, &mrq); | 447 | mmc_wait_for_req(card->host, &mrq); |
373 | 448 | ||
374 | if (cmd.error) { | 449 | if (cmd.error) { |
@@ -565,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries) | |||
565 | return err; | 640 | return err; |
566 | } | 641 | } |
567 | 642 | ||
643 | #define ERR_NOMEDIUM 3 | ||
568 | #define ERR_RETRY 2 | 644 | #define ERR_RETRY 2 |
569 | #define ERR_ABORT 1 | 645 | #define ERR_ABORT 1 |
570 | #define ERR_CONTINUE 0 | 646 | #define ERR_CONTINUE 0 |
@@ -632,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, | |||
632 | u32 status, stop_status = 0; | 708 | u32 status, stop_status = 0; |
633 | int err, retry; | 709 | int err, retry; |
634 | 710 | ||
711 | if (mmc_card_removed(card)) | ||
712 | return ERR_NOMEDIUM; | ||
713 | |||
635 | /* | 714 | /* |
636 | * Try to get card status which indicates both the card state | 715 | * Try to get card status which indicates both the card state |
637 | * and why there was no response. If the first attempt fails, | 716 | * and why there was no response. If the first attempt fails, |
@@ -648,8 +727,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req, | |||
648 | } | 727 | } |
649 | 728 | ||
650 | /* We couldn't get a response from the card. Give up. */ | 729 | /* We couldn't get a response from the card. Give up. */ |
651 | if (err) | 730 | if (err) { |
731 | /* Check if the card is removed */ | ||
732 | if (mmc_detect_card_removed(card->host)) | ||
733 | return ERR_NOMEDIUM; | ||
652 | return ERR_ABORT; | 734 | return ERR_ABORT; |
735 | } | ||
653 | 736 | ||
654 | /* Flag ECC errors */ | 737 | /* Flag ECC errors */ |
655 | if ((status & R1_CARD_ECC_FAILED) || | 738 | if ((status & R1_CARD_ECC_FAILED) || |
@@ -922,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card, | |||
922 | return MMC_BLK_RETRY; | 1005 | return MMC_BLK_RETRY; |
923 | case ERR_ABORT: | 1006 | case ERR_ABORT: |
924 | return MMC_BLK_ABORT; | 1007 | return MMC_BLK_ABORT; |
1008 | case ERR_NOMEDIUM: | ||
1009 | return MMC_BLK_NOMEDIUM; | ||
925 | case ERR_CONTINUE: | 1010 | case ERR_CONTINUE: |
926 | break; | 1011 | break; |
927 | } | 1012 | } |
@@ -1255,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1255 | if (!ret) | 1340 | if (!ret) |
1256 | goto start_new_req; | 1341 | goto start_new_req; |
1257 | break; | 1342 | break; |
1343 | case MMC_BLK_NOMEDIUM: | ||
1344 | goto cmd_abort; | ||
1258 | } | 1345 | } |
1259 | 1346 | ||
1260 | if (ret) { | 1347 | if (ret) { |
@@ -1271,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc) | |||
1271 | 1358 | ||
1272 | cmd_abort: | 1359 | cmd_abort: |
1273 | spin_lock_irq(&md->lock); | 1360 | spin_lock_irq(&md->lock); |
1361 | if (mmc_card_removed(card)) | ||
1362 | req->cmd_flags |= REQ_QUIET; | ||
1274 | while (ret) | 1363 | while (ret) |
1275 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); | 1364 | ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req)); |
1276 | spin_unlock_irq(&md->lock); | 1365 | spin_unlock_irq(&md->lock); |
@@ -1339,7 +1428,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
1339 | struct device *parent, | 1428 | struct device *parent, |
1340 | sector_t size, | 1429 | sector_t size, |
1341 | bool default_ro, | 1430 | bool default_ro, |
1342 | const char *subname) | 1431 | const char *subname, |
1432 | int area_type) | ||
1343 | { | 1433 | { |
1344 | struct mmc_blk_data *md; | 1434 | struct mmc_blk_data *md; |
1345 | int devidx, ret; | 1435 | int devidx, ret; |
@@ -1364,11 +1454,12 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card, | |||
1364 | if (!subname) { | 1454 | if (!subname) { |
1365 | md->name_idx = find_first_zero_bit(name_use, max_devices); | 1455 | md->name_idx = find_first_zero_bit(name_use, max_devices); |
1366 | __set_bit(md->name_idx, name_use); | 1456 | __set_bit(md->name_idx, name_use); |
1367 | } | 1457 | } else |
1368 | else | ||
1369 | md->name_idx = ((struct mmc_blk_data *) | 1458 | md->name_idx = ((struct mmc_blk_data *) |
1370 | dev_to_disk(parent)->private_data)->name_idx; | 1459 | dev_to_disk(parent)->private_data)->name_idx; |
1371 | 1460 | ||
1461 | md->area_type = area_type; | ||
1462 | |||
1372 | /* | 1463 | /* |
1373 | * Set the read-only status based on the supported commands | 1464 | * Set the read-only status based on the supported commands |
1374 | * and the write protect switch. | 1465 | * and the write protect switch. |
@@ -1462,7 +1553,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card) | |||
1462 | size = card->csd.capacity << (card->csd.read_blkbits - 9); | 1553 | size = card->csd.capacity << (card->csd.read_blkbits - 9); |
1463 | } | 1554 | } |
1464 | 1555 | ||
1465 | md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL); | 1556 | md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL, |
1557 | MMC_BLK_DATA_AREA_MAIN); | ||
1466 | return md; | 1558 | return md; |
1467 | } | 1559 | } |
1468 | 1560 | ||
@@ -1471,13 +1563,14 @@ static int mmc_blk_alloc_part(struct mmc_card *card, | |||
1471 | unsigned int part_type, | 1563 | unsigned int part_type, |
1472 | sector_t size, | 1564 | sector_t size, |
1473 | bool default_ro, | 1565 | bool default_ro, |
1474 | const char *subname) | 1566 | const char *subname, |
1567 | int area_type) | ||
1475 | { | 1568 | { |
1476 | char cap_str[10]; | 1569 | char cap_str[10]; |
1477 | struct mmc_blk_data *part_md; | 1570 | struct mmc_blk_data *part_md; |
1478 | 1571 | ||
1479 | part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, | 1572 | part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro, |
1480 | subname); | 1573 | subname, area_type); |
1481 | if (IS_ERR(part_md)) | 1574 | if (IS_ERR(part_md)) |
1482 | return PTR_ERR(part_md); | 1575 | return PTR_ERR(part_md); |
1483 | part_md->part_type = part_type; | 1576 | part_md->part_type = part_type; |
@@ -1510,7 +1603,8 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md) | |||
1510 | card->part[idx].part_cfg, | 1603 | card->part[idx].part_cfg, |
1511 | card->part[idx].size >> 9, | 1604 | card->part[idx].size >> 9, |
1512 | card->part[idx].force_ro, | 1605 | card->part[idx].force_ro, |
1513 | card->part[idx].name); | 1606 | card->part[idx].name, |
1607 | card->part[idx].area_type); | ||
1514 | if (ret) | 1608 | if (ret) |
1515 | return ret; | 1609 | return ret; |
1516 | } | 1610 | } |
@@ -1539,9 +1633,16 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card) | |||
1539 | 1633 | ||
1540 | static void mmc_blk_remove_req(struct mmc_blk_data *md) | 1634 | static void mmc_blk_remove_req(struct mmc_blk_data *md) |
1541 | { | 1635 | { |
1636 | struct mmc_card *card; | ||
1637 | |||
1542 | if (md) { | 1638 | if (md) { |
1639 | card = md->queue.card; | ||
1543 | if (md->disk->flags & GENHD_FL_UP) { | 1640 | if (md->disk->flags & GENHD_FL_UP) { |
1544 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); | 1641 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); |
1642 | if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && | ||
1643 | card->ext_csd.boot_ro_lockable) | ||
1644 | device_remove_file(disk_to_dev(md->disk), | ||
1645 | &md->power_ro_lock); | ||
1545 | 1646 | ||
1546 | /* Stop new requests from getting into the queue */ | 1647 | /* Stop new requests from getting into the queue */ |
1547 | del_gendisk(md->disk); | 1648 | del_gendisk(md->disk); |
@@ -1570,6 +1671,7 @@ static void mmc_blk_remove_parts(struct mmc_card *card, | |||
1570 | static int mmc_add_disk(struct mmc_blk_data *md) | 1671 | static int mmc_add_disk(struct mmc_blk_data *md) |
1571 | { | 1672 | { |
1572 | int ret; | 1673 | int ret; |
1674 | struct mmc_card *card = md->queue.card; | ||
1573 | 1675 | ||
1574 | add_disk(md->disk); | 1676 | add_disk(md->disk); |
1575 | md->force_ro.show = force_ro_show; | 1677 | md->force_ro.show = force_ro_show; |
@@ -1579,18 +1681,53 @@ static int mmc_add_disk(struct mmc_blk_data *md) | |||
1579 | md->force_ro.attr.mode = S_IRUGO | S_IWUSR; | 1681 | md->force_ro.attr.mode = S_IRUGO | S_IWUSR; |
1580 | ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); | 1682 | ret = device_create_file(disk_to_dev(md->disk), &md->force_ro); |
1581 | if (ret) | 1683 | if (ret) |
1582 | del_gendisk(md->disk); | 1684 | goto force_ro_fail; |
1685 | |||
1686 | if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) && | ||
1687 | card->ext_csd.boot_ro_lockable) { | ||
1688 | mode_t mode; | ||
1689 | |||
1690 | if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_DIS) | ||
1691 | mode = S_IRUGO; | ||
1692 | else | ||
1693 | mode = S_IRUGO | S_IWUSR; | ||
1694 | |||
1695 | md->power_ro_lock.show = power_ro_lock_show; | ||
1696 | md->power_ro_lock.store = power_ro_lock_store; | ||
1697 | md->power_ro_lock.attr.mode = mode; | ||
1698 | md->power_ro_lock.attr.name = | ||
1699 | "ro_lock_until_next_power_on"; | ||
1700 | ret = device_create_file(disk_to_dev(md->disk), | ||
1701 | &md->power_ro_lock); | ||
1702 | if (ret) | ||
1703 | goto power_ro_lock_fail; | ||
1704 | } | ||
1705 | return ret; | ||
1706 | |||
1707 | power_ro_lock_fail: | ||
1708 | device_remove_file(disk_to_dev(md->disk), &md->force_ro); | ||
1709 | force_ro_fail: | ||
1710 | del_gendisk(md->disk); | ||
1583 | 1711 | ||
1584 | return ret; | 1712 | return ret; |
1585 | } | 1713 | } |
1586 | 1714 | ||
1715 | #define CID_MANFID_SANDISK 0x2 | ||
1716 | #define CID_MANFID_TOSHIBA 0x11 | ||
1717 | #define CID_MANFID_MICRON 0x13 | ||
1718 | |||
1587 | static const struct mmc_fixup blk_fixups[] = | 1719 | static const struct mmc_fixup blk_fixups[] = |
1588 | { | 1720 | { |
1589 | MMC_FIXUP("SEM02G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1721 | MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk, |
1590 | MMC_FIXUP("SEM04G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1722 | MMC_QUIRK_INAND_CMD38), |
1591 | MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1723 | MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk, |
1592 | MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1724 | MMC_QUIRK_INAND_CMD38), |
1593 | MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38), | 1725 | MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk, |
1726 | MMC_QUIRK_INAND_CMD38), | ||
1727 | MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
1728 | MMC_QUIRK_INAND_CMD38), | ||
1729 | MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk, | ||
1730 | MMC_QUIRK_INAND_CMD38), | ||
1594 | 1731 | ||
1595 | /* | 1732 | /* |
1596 | * Some MMC cards experience performance degradation with CMD23 | 1733 | * Some MMC cards experience performance degradation with CMD23 |
@@ -1600,18 +1737,18 @@ static const struct mmc_fixup blk_fixups[] = | |||
1600 | * | 1737 | * |
1601 | * N.B. This doesn't affect SD cards. | 1738 | * N.B. This doesn't affect SD cards. |
1602 | */ | 1739 | */ |
1603 | MMC_FIXUP("MMC08G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1740 | MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
1604 | MMC_QUIRK_BLK_NO_CMD23), | 1741 | MMC_QUIRK_BLK_NO_CMD23), |
1605 | MMC_FIXUP("MMC16G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1742 | MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
1606 | MMC_QUIRK_BLK_NO_CMD23), | 1743 | MMC_QUIRK_BLK_NO_CMD23), |
1607 | MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc, | 1744 | MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc, |
1608 | MMC_QUIRK_BLK_NO_CMD23), | 1745 | MMC_QUIRK_BLK_NO_CMD23), |
1609 | 1746 | ||
1610 | /* | 1747 | /* |
1611 | * Some Micron MMC cards needs longer data read timeout than | 1748 | * Some Micron MMC cards needs longer data read timeout than |
1612 | * indicated in CSD. | 1749 | * indicated in CSD. |
1613 | */ | 1750 | */ |
1614 | MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc, | 1751 | MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc, |
1615 | MMC_QUIRK_LONG_READ_TIME), | 1752 | MMC_QUIRK_LONG_READ_TIME), |
1616 | 1753 | ||
1617 | END_FIXUP | 1754 | END_FIXUP |
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index e99bdc18002d..759714ed6bee 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c | |||
@@ -1581,6 +1581,7 @@ static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill) | |||
1581 | 1581 | ||
1582 | t->max_segs = test->card->host->max_segs; | 1582 | t->max_segs = test->card->host->max_segs; |
1583 | t->max_seg_sz = test->card->host->max_seg_size; | 1583 | t->max_seg_sz = test->card->host->max_seg_size; |
1584 | t->max_seg_sz -= t->max_seg_sz % 512; | ||
1584 | 1585 | ||
1585 | t->max_tfr = t->max_sz; | 1586 | t->max_tfr = t->max_sz; |
1586 | if (t->max_tfr >> 9 > test->card->host->max_blk_count) | 1587 | if (t->max_tfr >> 9 > test->card->host->max_blk_count) |
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c index dcad59cbfef1..2517547b4366 100644 --- a/drivers/mmc/card/queue.c +++ b/drivers/mmc/card/queue.c | |||
@@ -29,6 +29,8 @@ | |||
29 | */ | 29 | */ |
30 | static int mmc_prep_request(struct request_queue *q, struct request *req) | 30 | static int mmc_prep_request(struct request_queue *q, struct request *req) |
31 | { | 31 | { |
32 | struct mmc_queue *mq = q->queuedata; | ||
33 | |||
32 | /* | 34 | /* |
33 | * We only like normal block requests and discards. | 35 | * We only like normal block requests and discards. |
34 | */ | 36 | */ |
@@ -37,6 +39,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req) | |||
37 | return BLKPREP_KILL; | 39 | return BLKPREP_KILL; |
38 | } | 40 | } |
39 | 41 | ||
42 | if (mq && mmc_card_removed(mq->card)) | ||
43 | return BLKPREP_KILL; | ||
44 | |||
40 | req->cmd_flags |= REQ_DONTPREP; | 45 | req->cmd_flags |= REQ_DONTPREP; |
41 | 46 | ||
42 | return BLKPREP_OK; | 47 | return BLKPREP_OK; |
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile index 639501970b41..dca4428380f1 100644 --- a/drivers/mmc/core/Makefile +++ b/drivers/mmc/core/Makefile | |||
@@ -7,6 +7,6 @@ mmc_core-y := core.o bus.o host.o \ | |||
7 | mmc.o mmc_ops.o sd.o sd_ops.o \ | 7 | mmc.o mmc_ops.o sd.o sd_ops.o \ |
8 | sdio.o sdio_ops.o sdio_bus.o \ | 8 | sdio.o sdio_ops.o sdio_bus.o \ |
9 | sdio_cis.o sdio_io.o sdio_irq.o \ | 9 | sdio_cis.o sdio_io.o sdio_irq.o \ |
10 | quirks.o | 10 | quirks.o cd-gpio.o |
11 | 11 | ||
12 | mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o | 12 | mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o |
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index 6be49249895a..5d011a39dfff 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c | |||
@@ -303,10 +303,11 @@ int mmc_add_card(struct mmc_card *card) | |||
303 | mmc_card_ddr_mode(card) ? "DDR " : "", | 303 | mmc_card_ddr_mode(card) ? "DDR " : "", |
304 | type); | 304 | type); |
305 | } else { | 305 | } else { |
306 | printk(KERN_INFO "%s: new %s%s%s card at address %04x\n", | 306 | pr_info("%s: new %s%s%s%s card at address %04x\n", |
307 | mmc_hostname(card->host), | 307 | mmc_hostname(card->host), |
308 | mmc_sd_card_uhs(card) ? "ultra high speed " : | 308 | mmc_card_uhs(card) ? "ultra high speed " : |
309 | (mmc_card_highspeed(card) ? "high speed " : ""), | 309 | (mmc_card_highspeed(card) ? "high speed " : ""), |
310 | (mmc_card_hs200(card) ? "HS200 " : ""), | ||
310 | mmc_card_ddr_mode(card) ? "DDR " : "", | 311 | mmc_card_ddr_mode(card) ? "DDR " : "", |
311 | type, card->rca); | 312 | type, card->rca); |
312 | } | 313 | } |
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c new file mode 100644 index 000000000000..082202ae4a03 --- /dev/null +++ b/drivers/mmc/core/cd-gpio.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * Generic GPIO card-detect helper | ||
3 | * | ||
4 | * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/err.h> | ||
12 | #include <linux/gpio.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/jiffies.h> | ||
15 | #include <linux/mmc/host.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/slab.h> | ||
18 | |||
19 | struct mmc_cd_gpio { | ||
20 | unsigned int gpio; | ||
21 | char label[0]; | ||
22 | }; | ||
23 | |||
24 | static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id) | ||
25 | { | ||
26 | /* Schedule a card detection after a debounce timeout */ | ||
27 | mmc_detect_change(dev_id, msecs_to_jiffies(100)); | ||
28 | return IRQ_HANDLED; | ||
29 | } | ||
30 | |||
31 | int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio, | ||
32 | unsigned int irq, unsigned long flags) | ||
33 | { | ||
34 | size_t len = strlen(dev_name(host->parent)) + 4; | ||
35 | struct mmc_cd_gpio *cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL); | ||
36 | int ret; | ||
37 | |||
38 | if (!cd) | ||
39 | return -ENOMEM; | ||
40 | |||
41 | snprintf(cd->label, len, "%s cd", dev_name(host->parent)); | ||
42 | |||
43 | ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label); | ||
44 | if (ret < 0) | ||
45 | goto egpioreq; | ||
46 | |||
47 | ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt, | ||
48 | flags, cd->label, host); | ||
49 | if (ret < 0) | ||
50 | goto eirqreq; | ||
51 | |||
52 | cd->gpio = gpio; | ||
53 | host->hotplug.irq = irq; | ||
54 | host->hotplug.handler_priv = cd; | ||
55 | |||
56 | return 0; | ||
57 | |||
58 | eirqreq: | ||
59 | gpio_free(gpio); | ||
60 | egpioreq: | ||
61 | kfree(cd); | ||
62 | return ret; | ||
63 | } | ||
64 | EXPORT_SYMBOL(mmc_cd_gpio_request); | ||
65 | |||
66 | void mmc_cd_gpio_free(struct mmc_host *host) | ||
67 | { | ||
68 | struct mmc_cd_gpio *cd = host->hotplug.handler_priv; | ||
69 | |||
70 | free_irq(host->hotplug.irq, host); | ||
71 | gpio_free(cd->gpio); | ||
72 | kfree(cd); | ||
73 | } | ||
74 | EXPORT_SYMBOL(mmc_cd_gpio_free); | ||
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 75d7d7e17366..f545a3e6eb80 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -140,7 +140,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq) | |||
140 | cmd->retries = 0; | 140 | cmd->retries = 0; |
141 | } | 141 | } |
142 | 142 | ||
143 | if (err && cmd->retries) { | 143 | if (err && cmd->retries && !mmc_card_removed(host->card)) { |
144 | /* | 144 | /* |
145 | * Request starter must handle retries - see | 145 | * Request starter must handle retries - see |
146 | * mmc_wait_for_req_done(). | 146 | * mmc_wait_for_req_done(). |
@@ -247,6 +247,11 @@ static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq) | |||
247 | { | 247 | { |
248 | init_completion(&mrq->completion); | 248 | init_completion(&mrq->completion); |
249 | mrq->done = mmc_wait_done; | 249 | mrq->done = mmc_wait_done; |
250 | if (mmc_card_removed(host->card)) { | ||
251 | mrq->cmd->error = -ENOMEDIUM; | ||
252 | complete(&mrq->completion); | ||
253 | return; | ||
254 | } | ||
250 | mmc_start_request(host, mrq); | 255 | mmc_start_request(host, mrq); |
251 | } | 256 | } |
252 | 257 | ||
@@ -259,7 +264,8 @@ static void mmc_wait_for_req_done(struct mmc_host *host, | |||
259 | wait_for_completion(&mrq->completion); | 264 | wait_for_completion(&mrq->completion); |
260 | 265 | ||
261 | cmd = mrq->cmd; | 266 | cmd = mrq->cmd; |
262 | if (!cmd->error || !cmd->retries) | 267 | if (!cmd->error || !cmd->retries || |
268 | mmc_card_removed(host->card)) | ||
263 | break; | 269 | break; |
264 | 270 | ||
265 | pr_debug("%s: req failed (CMD%u): %d, retrying...\n", | 271 | pr_debug("%s: req failed (CMD%u): %d, retrying...\n", |
@@ -1456,7 +1462,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay) | |||
1456 | WARN_ON(host->removed); | 1462 | WARN_ON(host->removed); |
1457 | spin_unlock_irqrestore(&host->lock, flags); | 1463 | spin_unlock_irqrestore(&host->lock, flags); |
1458 | #endif | 1464 | #endif |
1459 | 1465 | host->detect_change = 1; | |
1460 | mmc_schedule_delayed_work(&host->detect, delay); | 1466 | mmc_schedule_delayed_work(&host->detect, delay); |
1461 | } | 1467 | } |
1462 | 1468 | ||
@@ -2049,6 +2055,43 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq) | |||
2049 | return -EIO; | 2055 | return -EIO; |
2050 | } | 2056 | } |
2051 | 2057 | ||
2058 | int _mmc_detect_card_removed(struct mmc_host *host) | ||
2059 | { | ||
2060 | int ret; | ||
2061 | |||
2062 | if ((host->caps & MMC_CAP_NONREMOVABLE) || !host->bus_ops->alive) | ||
2063 | return 0; | ||
2064 | |||
2065 | if (!host->card || mmc_card_removed(host->card)) | ||
2066 | return 1; | ||
2067 | |||
2068 | ret = host->bus_ops->alive(host); | ||
2069 | if (ret) { | ||
2070 | mmc_card_set_removed(host->card); | ||
2071 | pr_debug("%s: card remove detected\n", mmc_hostname(host)); | ||
2072 | } | ||
2073 | |||
2074 | return ret; | ||
2075 | } | ||
2076 | |||
2077 | int mmc_detect_card_removed(struct mmc_host *host) | ||
2078 | { | ||
2079 | struct mmc_card *card = host->card; | ||
2080 | |||
2081 | WARN_ON(!host->claimed); | ||
2082 | /* | ||
2083 | * The card will be considered unchanged unless we have been asked to | ||
2084 | * detect a change or host requires polling to provide card detection. | ||
2085 | */ | ||
2086 | if (card && !host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL)) | ||
2087 | return mmc_card_removed(card); | ||
2088 | |||
2089 | host->detect_change = 0; | ||
2090 | |||
2091 | return _mmc_detect_card_removed(host); | ||
2092 | } | ||
2093 | EXPORT_SYMBOL(mmc_detect_card_removed); | ||
2094 | |||
2052 | void mmc_rescan(struct work_struct *work) | 2095 | void mmc_rescan(struct work_struct *work) |
2053 | { | 2096 | { |
2054 | static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; | 2097 | static const unsigned freqs[] = { 400000, 300000, 200000, 100000 }; |
@@ -2069,6 +2112,8 @@ void mmc_rescan(struct work_struct *work) | |||
2069 | && !(host->caps & MMC_CAP_NONREMOVABLE)) | 2112 | && !(host->caps & MMC_CAP_NONREMOVABLE)) |
2070 | host->bus_ops->detect(host); | 2113 | host->bus_ops->detect(host); |
2071 | 2114 | ||
2115 | host->detect_change = 0; | ||
2116 | |||
2072 | /* | 2117 | /* |
2073 | * Let mmc_bus_put() free the bus/bus_ops if we've found that | 2118 | * Let mmc_bus_put() free the bus/bus_ops if we've found that |
2074 | * the card is no longer present. | 2119 | * the card is no longer present. |
@@ -2130,6 +2175,7 @@ void mmc_stop_host(struct mmc_host *host) | |||
2130 | 2175 | ||
2131 | mmc_bus_get(host); | 2176 | mmc_bus_get(host); |
2132 | if (host->bus_ops && !host->bus_dead) { | 2177 | if (host->bus_ops && !host->bus_dead) { |
2178 | /* Calling bus_ops->remove() with a claimed host can deadlock */ | ||
2133 | if (host->bus_ops->remove) | 2179 | if (host->bus_ops->remove) |
2134 | host->bus_ops->remove(host); | 2180 | host->bus_ops->remove(host); |
2135 | 2181 | ||
@@ -2201,6 +2247,9 @@ int mmc_card_awake(struct mmc_host *host) | |||
2201 | { | 2247 | { |
2202 | int err = -ENOSYS; | 2248 | int err = -ENOSYS; |
2203 | 2249 | ||
2250 | if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) | ||
2251 | return 0; | ||
2252 | |||
2204 | mmc_bus_get(host); | 2253 | mmc_bus_get(host); |
2205 | 2254 | ||
2206 | if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) | 2255 | if (host->bus_ops && !host->bus_dead && host->bus_ops->awake) |
@@ -2216,6 +2265,9 @@ int mmc_card_sleep(struct mmc_host *host) | |||
2216 | { | 2265 | { |
2217 | int err = -ENOSYS; | 2266 | int err = -ENOSYS; |
2218 | 2267 | ||
2268 | if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD) | ||
2269 | return 0; | ||
2270 | |||
2219 | mmc_bus_get(host); | 2271 | mmc_bus_get(host); |
2220 | 2272 | ||
2221 | if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) | 2273 | if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep) |
@@ -2270,6 +2322,7 @@ EXPORT_SYMBOL(mmc_flush_cache); | |||
2270 | int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | 2322 | int mmc_cache_ctrl(struct mmc_host *host, u8 enable) |
2271 | { | 2323 | { |
2272 | struct mmc_card *card = host->card; | 2324 | struct mmc_card *card = host->card; |
2325 | unsigned int timeout; | ||
2273 | int err = 0; | 2326 | int err = 0; |
2274 | 2327 | ||
2275 | if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) || | 2328 | if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) || |
@@ -2280,16 +2333,18 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable) | |||
2280 | (card->ext_csd.cache_size > 0)) { | 2333 | (card->ext_csd.cache_size > 0)) { |
2281 | enable = !!enable; | 2334 | enable = !!enable; |
2282 | 2335 | ||
2283 | if (card->ext_csd.cache_ctrl ^ enable) | 2336 | if (card->ext_csd.cache_ctrl ^ enable) { |
2337 | timeout = enable ? card->ext_csd.generic_cmd6_time : 0; | ||
2284 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 2338 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
2285 | EXT_CSD_CACHE_CTRL, enable, 0); | 2339 | EXT_CSD_CACHE_CTRL, enable, timeout); |
2286 | if (err) | 2340 | if (err) |
2287 | pr_err("%s: cache %s error %d\n", | 2341 | pr_err("%s: cache %s error %d\n", |
2288 | mmc_hostname(card->host), | 2342 | mmc_hostname(card->host), |
2289 | enable ? "on" : "off", | 2343 | enable ? "on" : "off", |
2290 | err); | 2344 | err); |
2291 | else | 2345 | else |
2292 | card->ext_csd.cache_ctrl = enable; | 2346 | card->ext_csd.cache_ctrl = enable; |
2347 | } | ||
2293 | } | 2348 | } |
2294 | 2349 | ||
2295 | return err; | 2350 | return err; |
@@ -2310,7 +2365,13 @@ int mmc_suspend_host(struct mmc_host *host) | |||
2310 | cancel_delayed_work(&host->disable); | 2365 | cancel_delayed_work(&host->disable); |
2311 | cancel_delayed_work(&host->detect); | 2366 | cancel_delayed_work(&host->detect); |
2312 | mmc_flush_scheduled_work(); | 2367 | mmc_flush_scheduled_work(); |
2313 | err = mmc_cache_ctrl(host, 0); | 2368 | if (mmc_try_claim_host(host)) { |
2369 | err = mmc_cache_ctrl(host, 0); | ||
2370 | mmc_do_release_host(host); | ||
2371 | } else { | ||
2372 | err = -EBUSY; | ||
2373 | } | ||
2374 | |||
2314 | if (err) | 2375 | if (err) |
2315 | goto out; | 2376 | goto out; |
2316 | 2377 | ||
@@ -2338,7 +2399,9 @@ int mmc_suspend_host(struct mmc_host *host) | |||
2338 | if (err == -ENOSYS || !host->bus_ops->resume) { | 2399 | if (err == -ENOSYS || !host->bus_ops->resume) { |
2339 | /* | 2400 | /* |
2340 | * We simply "remove" the card in this case. | 2401 | * We simply "remove" the card in this case. |
2341 | * It will be redetected on resume. | 2402 | * It will be redetected on resume. (Calling |
2403 | * bus_ops->remove() with a claimed host can | ||
2404 | * deadlock.) | ||
2342 | */ | 2405 | */ |
2343 | if (host->bus_ops->remove) | 2406 | if (host->bus_ops->remove) |
2344 | host->bus_ops->remove(host); | 2407 | host->bus_ops->remove(host); |
@@ -2431,11 +2494,11 @@ int mmc_pm_notify(struct notifier_block *notify_block, | |||
2431 | if (!host->bus_ops || host->bus_ops->suspend) | 2494 | if (!host->bus_ops || host->bus_ops->suspend) |
2432 | break; | 2495 | break; |
2433 | 2496 | ||
2434 | mmc_claim_host(host); | 2497 | /* Calling bus_ops->remove() with a claimed host can deadlock */ |
2435 | |||
2436 | if (host->bus_ops->remove) | 2498 | if (host->bus_ops->remove) |
2437 | host->bus_ops->remove(host); | 2499 | host->bus_ops->remove(host); |
2438 | 2500 | ||
2501 | mmc_claim_host(host); | ||
2439 | mmc_detach_bus(host); | 2502 | mmc_detach_bus(host); |
2440 | mmc_power_off(host); | 2503 | mmc_power_off(host); |
2441 | mmc_release_host(host); | 2504 | mmc_release_host(host); |
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index afa6bd2b7b70..3bdafbca354f 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h | |||
@@ -24,6 +24,7 @@ struct mmc_bus_ops { | |||
24 | int (*resume)(struct mmc_host *); | 24 | int (*resume)(struct mmc_host *); |
25 | int (*power_save)(struct mmc_host *); | 25 | int (*power_save)(struct mmc_host *); |
26 | int (*power_restore)(struct mmc_host *); | 26 | int (*power_restore)(struct mmc_host *); |
27 | int (*alive)(struct mmc_host *); | ||
27 | }; | 28 | }; |
28 | 29 | ||
29 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); | 30 | void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops); |
@@ -59,6 +60,8 @@ void mmc_rescan(struct work_struct *work); | |||
59 | void mmc_start_host(struct mmc_host *host); | 60 | void mmc_start_host(struct mmc_host *host); |
60 | void mmc_stop_host(struct mmc_host *host); | 61 | void mmc_stop_host(struct mmc_host *host); |
61 | 62 | ||
63 | int _mmc_detect_card_removed(struct mmc_host *host); | ||
64 | |||
62 | int mmc_attach_mmc(struct mmc_host *host); | 65 | int mmc_attach_mmc(struct mmc_host *host); |
63 | int mmc_attach_sd(struct mmc_host *host); | 66 | int mmc_attach_sd(struct mmc_host *host); |
64 | int mmc_attach_sdio(struct mmc_host *host); | 67 | int mmc_attach_sdio(struct mmc_host *host); |
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c index 3923880118b6..9ab5b17d488a 100644 --- a/drivers/mmc/core/debugfs.c +++ b/drivers/mmc/core/debugfs.c | |||
@@ -57,6 +57,8 @@ static int mmc_ios_show(struct seq_file *s, void *data) | |||
57 | const char *str; | 57 | const char *str; |
58 | 58 | ||
59 | seq_printf(s, "clock:\t\t%u Hz\n", ios->clock); | 59 | seq_printf(s, "clock:\t\t%u Hz\n", ios->clock); |
60 | if (host->actual_clock) | ||
61 | seq_printf(s, "actual clock:\t%u Hz\n", host->actual_clock); | ||
60 | seq_printf(s, "vdd:\t\t%u ", ios->vdd); | 62 | seq_printf(s, "vdd:\t\t%u ", ios->vdd); |
61 | if ((1 << ios->vdd) & MMC_VDD_165_195) | 63 | if ((1 << ios->vdd) & MMC_VDD_165_195) |
62 | seq_printf(s, "(1.65 - 1.95 V)\n"); | 64 | seq_printf(s, "(1.65 - 1.95 V)\n"); |
@@ -133,6 +135,9 @@ static int mmc_ios_show(struct seq_file *s, void *data) | |||
133 | case MMC_TIMING_UHS_DDR50: | 135 | case MMC_TIMING_UHS_DDR50: |
134 | str = "sd uhs DDR50"; | 136 | str = "sd uhs DDR50"; |
135 | break; | 137 | break; |
138 | case MMC_TIMING_MMC_HS200: | ||
139 | str = "mmc high-speed SDR200"; | ||
140 | break; | ||
136 | default: | 141 | default: |
137 | str = "invalid"; | 142 | str = "invalid"; |
138 | break; | 143 | break; |
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index d31c78b72b0f..30055f2b0d44 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c | |||
@@ -54,6 +54,27 @@ static DEFINE_IDR(mmc_host_idr); | |||
54 | static DEFINE_SPINLOCK(mmc_host_lock); | 54 | static DEFINE_SPINLOCK(mmc_host_lock); |
55 | 55 | ||
56 | #ifdef CONFIG_MMC_CLKGATE | 56 | #ifdef CONFIG_MMC_CLKGATE |
57 | static ssize_t clkgate_delay_show(struct device *dev, | ||
58 | struct device_attribute *attr, char *buf) | ||
59 | { | ||
60 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | ||
61 | return snprintf(buf, PAGE_SIZE, "%lu\n", host->clkgate_delay); | ||
62 | } | ||
63 | |||
64 | static ssize_t clkgate_delay_store(struct device *dev, | ||
65 | struct device_attribute *attr, const char *buf, size_t count) | ||
66 | { | ||
67 | struct mmc_host *host = cls_dev_to_mmc_host(dev); | ||
68 | unsigned long flags, value; | ||
69 | |||
70 | if (kstrtoul(buf, 0, &value)) | ||
71 | return -EINVAL; | ||
72 | |||
73 | spin_lock_irqsave(&host->clk_lock, flags); | ||
74 | host->clkgate_delay = value; | ||
75 | spin_unlock_irqrestore(&host->clk_lock, flags); | ||
76 | return count; | ||
77 | } | ||
57 | 78 | ||
58 | /* | 79 | /* |
59 | * Enabling clock gating will make the core call out to the host | 80 | * Enabling clock gating will make the core call out to the host |
@@ -114,7 +135,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host) | |||
114 | static void mmc_host_clk_gate_work(struct work_struct *work) | 135 | static void mmc_host_clk_gate_work(struct work_struct *work) |
115 | { | 136 | { |
116 | struct mmc_host *host = container_of(work, struct mmc_host, | 137 | struct mmc_host *host = container_of(work, struct mmc_host, |
117 | clk_gate_work); | 138 | clk_gate_work.work); |
118 | 139 | ||
119 | mmc_host_clk_gate_delayed(host); | 140 | mmc_host_clk_gate_delayed(host); |
120 | } | 141 | } |
@@ -131,6 +152,8 @@ void mmc_host_clk_hold(struct mmc_host *host) | |||
131 | { | 152 | { |
132 | unsigned long flags; | 153 | unsigned long flags; |
133 | 154 | ||
155 | /* cancel any clock gating work scheduled by mmc_host_clk_release() */ | ||
156 | cancel_delayed_work_sync(&host->clk_gate_work); | ||
134 | mutex_lock(&host->clk_gate_mutex); | 157 | mutex_lock(&host->clk_gate_mutex); |
135 | spin_lock_irqsave(&host->clk_lock, flags); | 158 | spin_lock_irqsave(&host->clk_lock, flags); |
136 | if (host->clk_gated) { | 159 | if (host->clk_gated) { |
@@ -180,7 +203,8 @@ void mmc_host_clk_release(struct mmc_host *host) | |||
180 | host->clk_requests--; | 203 | host->clk_requests--; |
181 | if (mmc_host_may_gate_card(host->card) && | 204 | if (mmc_host_may_gate_card(host->card) && |
182 | !host->clk_requests) | 205 | !host->clk_requests) |
183 | queue_work(system_nrt_wq, &host->clk_gate_work); | 206 | queue_delayed_work(system_nrt_wq, &host->clk_gate_work, |
207 | msecs_to_jiffies(host->clkgate_delay)); | ||
184 | spin_unlock_irqrestore(&host->clk_lock, flags); | 208 | spin_unlock_irqrestore(&host->clk_lock, flags); |
185 | } | 209 | } |
186 | 210 | ||
@@ -213,8 +237,13 @@ static inline void mmc_host_clk_init(struct mmc_host *host) | |||
213 | host->clk_requests = 0; | 237 | host->clk_requests = 0; |
214 | /* Hold MCI clock for 8 cycles by default */ | 238 | /* Hold MCI clock for 8 cycles by default */ |
215 | host->clk_delay = 8; | 239 | host->clk_delay = 8; |
240 | /* | ||
241 | * Default clock gating delay is 200ms. | ||
242 | * This value can be tuned by writing into sysfs entry. | ||
243 | */ | ||
244 | host->clkgate_delay = 200; | ||
216 | host->clk_gated = false; | 245 | host->clk_gated = false; |
217 | INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); | 246 | INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work); |
218 | spin_lock_init(&host->clk_lock); | 247 | spin_lock_init(&host->clk_lock); |
219 | mutex_init(&host->clk_gate_mutex); | 248 | mutex_init(&host->clk_gate_mutex); |
220 | } | 249 | } |
@@ -229,7 +258,7 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) | |||
229 | * Wait for any outstanding gate and then make sure we're | 258 | * Wait for any outstanding gate and then make sure we're |
230 | * ungated before exiting. | 259 | * ungated before exiting. |
231 | */ | 260 | */ |
232 | if (cancel_work_sync(&host->clk_gate_work)) | 261 | if (cancel_delayed_work_sync(&host->clk_gate_work)) |
233 | mmc_host_clk_gate_delayed(host); | 262 | mmc_host_clk_gate_delayed(host); |
234 | if (host->clk_gated) | 263 | if (host->clk_gated) |
235 | mmc_host_clk_hold(host); | 264 | mmc_host_clk_hold(host); |
@@ -237,6 +266,17 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) | |||
237 | WARN_ON(host->clk_requests > 1); | 266 | WARN_ON(host->clk_requests > 1); |
238 | } | 267 | } |
239 | 268 | ||
269 | static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) | ||
270 | { | ||
271 | host->clkgate_delay_attr.show = clkgate_delay_show; | ||
272 | host->clkgate_delay_attr.store = clkgate_delay_store; | ||
273 | sysfs_attr_init(&host->clkgate_delay_attr.attr); | ||
274 | host->clkgate_delay_attr.attr.name = "clkgate_delay"; | ||
275 | host->clkgate_delay_attr.attr.mode = S_IRUGO | S_IWUSR; | ||
276 | if (device_create_file(&host->class_dev, &host->clkgate_delay_attr)) | ||
277 | pr_err("%s: Failed to create clkgate_delay sysfs entry\n", | ||
278 | mmc_hostname(host)); | ||
279 | } | ||
240 | #else | 280 | #else |
241 | 281 | ||
242 | static inline void mmc_host_clk_init(struct mmc_host *host) | 282 | static inline void mmc_host_clk_init(struct mmc_host *host) |
@@ -247,6 +287,10 @@ static inline void mmc_host_clk_exit(struct mmc_host *host) | |||
247 | { | 287 | { |
248 | } | 288 | } |
249 | 289 | ||
290 | static inline void mmc_host_clk_sysfs_init(struct mmc_host *host) | ||
291 | { | ||
292 | } | ||
293 | |||
250 | #endif | 294 | #endif |
251 | 295 | ||
252 | /** | 296 | /** |
@@ -335,6 +379,7 @@ int mmc_add_host(struct mmc_host *host) | |||
335 | #ifdef CONFIG_DEBUG_FS | 379 | #ifdef CONFIG_DEBUG_FS |
336 | mmc_add_host_debugfs(host); | 380 | mmc_add_host_debugfs(host); |
337 | #endif | 381 | #endif |
382 | mmc_host_clk_sysfs_init(host); | ||
338 | 383 | ||
339 | mmc_start_host(host); | 384 | mmc_start_host(host); |
340 | register_pm_notifier(&host->pm_notify); | 385 | register_pm_notifier(&host->pm_notify); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index d240427c1246..59b9ba52e66a 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -286,6 +286,27 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
286 | } | 286 | } |
287 | card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; | 287 | card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; |
288 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { | 288 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { |
289 | case EXT_CSD_CARD_TYPE_SDR_ALL: | ||
290 | case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V: | ||
291 | case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V: | ||
292 | case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52: | ||
293 | card->ext_csd.hs_max_dtr = 200000000; | ||
294 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200; | ||
295 | break; | ||
296 | case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL: | ||
297 | case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V: | ||
298 | case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V: | ||
299 | case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52: | ||
300 | card->ext_csd.hs_max_dtr = 200000000; | ||
301 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V; | ||
302 | break; | ||
303 | case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL: | ||
304 | case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V: | ||
305 | case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V: | ||
306 | case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52: | ||
307 | card->ext_csd.hs_max_dtr = 200000000; | ||
308 | card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V; | ||
309 | break; | ||
289 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | | 310 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | |
290 | EXT_CSD_CARD_TYPE_26: | 311 | EXT_CSD_CARD_TYPE_26: |
291 | card->ext_csd.hs_max_dtr = 52000000; | 312 | card->ext_csd.hs_max_dtr = 52000000; |
@@ -348,7 +369,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
348 | part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; | 369 | part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; |
349 | mmc_part_add(card, part_size, | 370 | mmc_part_add(card, part_size, |
350 | EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, | 371 | EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx, |
351 | "boot%d", idx, true); | 372 | "boot%d", idx, true, |
373 | MMC_BLK_DATA_AREA_BOOT); | ||
352 | } | 374 | } |
353 | } | 375 | } |
354 | } | 376 | } |
@@ -435,7 +457,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
435 | hc_wp_grp_sz); | 457 | hc_wp_grp_sz); |
436 | mmc_part_add(card, part_size << 19, | 458 | mmc_part_add(card, part_size << 19, |
437 | EXT_CSD_PART_CONFIG_ACC_GP0 + idx, | 459 | EXT_CSD_PART_CONFIG_ACC_GP0 + idx, |
438 | "gp%d", idx, false); | 460 | "gp%d", idx, false, |
461 | MMC_BLK_DATA_AREA_GP); | ||
439 | } | 462 | } |
440 | } | 463 | } |
441 | card->ext_csd.sec_trim_mult = | 464 | card->ext_csd.sec_trim_mult = |
@@ -446,6 +469,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
446 | ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; | 469 | ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; |
447 | card->ext_csd.trim_timeout = 300 * | 470 | card->ext_csd.trim_timeout = 300 * |
448 | ext_csd[EXT_CSD_TRIM_MULT]; | 471 | ext_csd[EXT_CSD_TRIM_MULT]; |
472 | |||
473 | /* | ||
474 | * Note that the call to mmc_part_add above defaults to read | ||
475 | * only. If this default assumption is changed, the call must | ||
476 | * take into account the value of boot_locked below. | ||
477 | */ | ||
478 | card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP]; | ||
479 | card->ext_csd.boot_ro_lockable = true; | ||
449 | } | 480 | } |
450 | 481 | ||
451 | if (card->ext_csd.rev >= 5) { | 482 | if (card->ext_csd.rev >= 5) { |
@@ -690,6 +721,79 @@ static int mmc_select_powerclass(struct mmc_card *card, | |||
690 | } | 721 | } |
691 | 722 | ||
692 | /* | 723 | /* |
724 | * Selects the desired buswidth and switch to the HS200 mode | ||
725 | * if bus width set without error | ||
726 | */ | ||
727 | static int mmc_select_hs200(struct mmc_card *card) | ||
728 | { | ||
729 | int idx, err = 0; | ||
730 | struct mmc_host *host; | ||
731 | static unsigned ext_csd_bits[] = { | ||
732 | EXT_CSD_BUS_WIDTH_4, | ||
733 | EXT_CSD_BUS_WIDTH_8, | ||
734 | }; | ||
735 | static unsigned bus_widths[] = { | ||
736 | MMC_BUS_WIDTH_4, | ||
737 | MMC_BUS_WIDTH_8, | ||
738 | }; | ||
739 | |||
740 | BUG_ON(!card); | ||
741 | |||
742 | host = card->host; | ||
743 | |||
744 | if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V && | ||
745 | host->caps2 & MMC_CAP2_HS200_1_2V_SDR) | ||
746 | if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0)) | ||
747 | err = mmc_set_signal_voltage(host, | ||
748 | MMC_SIGNAL_VOLTAGE_180, 0); | ||
749 | |||
750 | /* If fails try again during next card power cycle */ | ||
751 | if (err) | ||
752 | goto err; | ||
753 | |||
754 | idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 1 : 0; | ||
755 | |||
756 | /* | ||
757 | * Unlike SD, MMC cards dont have a configuration register to notify | ||
758 | * supported bus width. So bus test command should be run to identify | ||
759 | * the supported bus width or compare the ext csd values of current | ||
760 | * bus width and ext csd values of 1 bit mode read earlier. | ||
761 | */ | ||
762 | for (; idx >= 0; idx--) { | ||
763 | |||
764 | /* | ||
765 | * Host is capable of 8bit transfer, then switch | ||
766 | * the device to work in 8bit transfer mode. If the | ||
767 | * mmc switch command returns error then switch to | ||
768 | * 4bit transfer mode. On success set the corresponding | ||
769 | * bus width on the host. | ||
770 | */ | ||
771 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
772 | EXT_CSD_BUS_WIDTH, | ||
773 | ext_csd_bits[idx], | ||
774 | card->ext_csd.generic_cmd6_time); | ||
775 | if (err) | ||
776 | continue; | ||
777 | |||
778 | mmc_set_bus_width(card->host, bus_widths[idx]); | ||
779 | |||
780 | if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) | ||
781 | err = mmc_compare_ext_csds(card, bus_widths[idx]); | ||
782 | else | ||
783 | err = mmc_bus_test(card, bus_widths[idx]); | ||
784 | if (!err) | ||
785 | break; | ||
786 | } | ||
787 | |||
788 | /* switch to HS200 mode if bus width set successfully */ | ||
789 | if (!err) | ||
790 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
791 | EXT_CSD_HS_TIMING, 2, 0); | ||
792 | err: | ||
793 | return err; | ||
794 | } | ||
795 | |||
796 | /* | ||
693 | * Handle the detection and initialisation of a card. | 797 | * Handle the detection and initialisation of a card. |
694 | * | 798 | * |
695 | * In the case of a resume, "oldcard" will contain the card | 799 | * In the case of a resume, "oldcard" will contain the card |
@@ -895,11 +999,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
895 | /* | 999 | /* |
896 | * Activate high speed (if supported) | 1000 | * Activate high speed (if supported) |
897 | */ | 1001 | */ |
898 | if ((card->ext_csd.hs_max_dtr != 0) && | 1002 | if (card->ext_csd.hs_max_dtr != 0) { |
899 | (host->caps & MMC_CAP_MMC_HIGHSPEED)) { | 1003 | err = 0; |
900 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1004 | if (card->ext_csd.hs_max_dtr > 52000000 && |
901 | EXT_CSD_HS_TIMING, 1, | 1005 | host->caps2 & MMC_CAP2_HS200) |
902 | card->ext_csd.generic_cmd6_time); | 1006 | err = mmc_select_hs200(card); |
1007 | else if (host->caps & MMC_CAP_MMC_HIGHSPEED) | ||
1008 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | ||
1009 | EXT_CSD_HS_TIMING, 1, 0); | ||
1010 | |||
903 | if (err && err != -EBADMSG) | 1011 | if (err && err != -EBADMSG) |
904 | goto free_card; | 1012 | goto free_card; |
905 | 1013 | ||
@@ -908,8 +1016,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
908 | mmc_hostname(card->host)); | 1016 | mmc_hostname(card->host)); |
909 | err = 0; | 1017 | err = 0; |
910 | } else { | 1018 | } else { |
911 | mmc_card_set_highspeed(card); | 1019 | if (card->ext_csd.hs_max_dtr > 52000000 && |
912 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | 1020 | host->caps2 & MMC_CAP2_HS200) { |
1021 | mmc_card_set_hs200(card); | ||
1022 | mmc_set_timing(card->host, | ||
1023 | MMC_TIMING_MMC_HS200); | ||
1024 | } else { | ||
1025 | mmc_card_set_highspeed(card); | ||
1026 | mmc_set_timing(card->host, MMC_TIMING_MMC_HS); | ||
1027 | } | ||
913 | } | 1028 | } |
914 | } | 1029 | } |
915 | 1030 | ||
@@ -934,7 +1049,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
934 | */ | 1049 | */ |
935 | max_dtr = (unsigned int)-1; | 1050 | max_dtr = (unsigned int)-1; |
936 | 1051 | ||
937 | if (mmc_card_highspeed(card)) { | 1052 | if (mmc_card_highspeed(card) || mmc_card_hs200(card)) { |
938 | if (max_dtr > card->ext_csd.hs_max_dtr) | 1053 | if (max_dtr > card->ext_csd.hs_max_dtr) |
939 | max_dtr = card->ext_csd.hs_max_dtr; | 1054 | max_dtr = card->ext_csd.hs_max_dtr; |
940 | } else if (max_dtr > card->csd.max_dtr) { | 1055 | } else if (max_dtr > card->csd.max_dtr) { |
@@ -960,9 +1075,48 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
960 | } | 1075 | } |
961 | 1076 | ||
962 | /* | 1077 | /* |
1078 | * Indicate HS200 SDR mode (if supported). | ||
1079 | */ | ||
1080 | if (mmc_card_hs200(card)) { | ||
1081 | u32 ext_csd_bits; | ||
1082 | u32 bus_width = card->host->ios.bus_width; | ||
1083 | |||
1084 | /* | ||
1085 | * For devices supporting HS200 mode, the bus width has | ||
1086 | * to be set before executing the tuning function. If | ||
1087 | * set before tuning, then device will respond with CRC | ||
1088 | * errors for responses on CMD line. So for HS200 the | ||
1089 | * sequence will be | ||
1090 | * 1. set bus width 4bit / 8 bit (1 bit not supported) | ||
1091 | * 2. switch to HS200 mode | ||
1092 | * 3. set the clock to > 52Mhz <=200MHz and | ||
1093 | * 4. execute tuning for HS200 | ||
1094 | */ | ||
1095 | if ((host->caps2 & MMC_CAP2_HS200) && | ||
1096 | card->host->ops->execute_tuning) | ||
1097 | err = card->host->ops->execute_tuning(card->host, | ||
1098 | MMC_SEND_TUNING_BLOCK_HS200); | ||
1099 | if (err) { | ||
1100 | pr_warning("%s: tuning execution failed\n", | ||
1101 | mmc_hostname(card->host)); | ||
1102 | goto err; | ||
1103 | } | ||
1104 | |||
1105 | ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ? | ||
1106 | EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4; | ||
1107 | err = mmc_select_powerclass(card, ext_csd_bits, ext_csd); | ||
1108 | if (err) { | ||
1109 | pr_err("%s: power class selection to bus width %d failed\n", | ||
1110 | mmc_hostname(card->host), 1 << bus_width); | ||
1111 | goto err; | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | /* | ||
963 | * Activate wide bus and DDR (if supported). | 1116 | * Activate wide bus and DDR (if supported). |
964 | */ | 1117 | */ |
965 | if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) && | 1118 | if (!mmc_card_hs200(card) && |
1119 | (card->csd.mmca_vsn >= CSD_SPEC_VER_3) && | ||
966 | (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { | 1120 | (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { |
967 | static unsigned ext_csd_bits[][2] = { | 1121 | static unsigned ext_csd_bits[][2] = { |
968 | { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, | 1122 | { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, |
@@ -1048,7 +1202,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1048 | * | 1202 | * |
1049 | * WARNING: eMMC rules are NOT the same as SD DDR | 1203 | * WARNING: eMMC rules are NOT the same as SD DDR |
1050 | */ | 1204 | */ |
1051 | if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) { | 1205 | if (ddr == MMC_1_2V_DDR_MODE) { |
1052 | err = mmc_set_signal_voltage(host, | 1206 | err = mmc_set_signal_voltage(host, |
1053 | MMC_SIGNAL_VOLTAGE_120, 0); | 1207 | MMC_SIGNAL_VOLTAGE_120, 0); |
1054 | if (err) | 1208 | if (err) |
@@ -1067,14 +1221,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
1067 | if ((host->caps2 & MMC_CAP2_CACHE_CTRL) && | 1221 | if ((host->caps2 & MMC_CAP2_CACHE_CTRL) && |
1068 | card->ext_csd.cache_size > 0) { | 1222 | card->ext_csd.cache_size > 0) { |
1069 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, | 1223 | err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, |
1070 | EXT_CSD_CACHE_CTRL, 1, 0); | 1224 | EXT_CSD_CACHE_CTRL, 1, |
1225 | card->ext_csd.generic_cmd6_time); | ||
1071 | if (err && err != -EBADMSG) | 1226 | if (err && err != -EBADMSG) |
1072 | goto free_card; | 1227 | goto free_card; |
1073 | 1228 | ||
1074 | /* | 1229 | /* |
1075 | * Only if no error, cache is turned on successfully. | 1230 | * Only if no error, cache is turned on successfully. |
1076 | */ | 1231 | */ |
1077 | card->ext_csd.cache_ctrl = err ? 0 : 1; | 1232 | if (err) { |
1233 | pr_warning("%s: Cache is supported, " | ||
1234 | "but failed to turn on (%d)\n", | ||
1235 | mmc_hostname(card->host), err); | ||
1236 | card->ext_csd.cache_ctrl = 0; | ||
1237 | err = 0; | ||
1238 | } else { | ||
1239 | card->ext_csd.cache_ctrl = 1; | ||
1240 | } | ||
1078 | } | 1241 | } |
1079 | 1242 | ||
1080 | if (!oldcard) | 1243 | if (!oldcard) |
@@ -1105,6 +1268,14 @@ static void mmc_remove(struct mmc_host *host) | |||
1105 | } | 1268 | } |
1106 | 1269 | ||
1107 | /* | 1270 | /* |
1271 | * Card detection - card is alive. | ||
1272 | */ | ||
1273 | static int mmc_alive(struct mmc_host *host) | ||
1274 | { | ||
1275 | return mmc_send_status(host->card, NULL); | ||
1276 | } | ||
1277 | |||
1278 | /* | ||
1108 | * Card detection callback from host. | 1279 | * Card detection callback from host. |
1109 | */ | 1280 | */ |
1110 | static void mmc_detect(struct mmc_host *host) | 1281 | static void mmc_detect(struct mmc_host *host) |
@@ -1119,7 +1290,7 @@ static void mmc_detect(struct mmc_host *host) | |||
1119 | /* | 1290 | /* |
1120 | * Just check if our card has been removed. | 1291 | * Just check if our card has been removed. |
1121 | */ | 1292 | */ |
1122 | err = mmc_send_status(host->card, NULL); | 1293 | err = _mmc_detect_card_removed(host); |
1123 | 1294 | ||
1124 | mmc_release_host(host); | 1295 | mmc_release_host(host); |
1125 | 1296 | ||
@@ -1224,6 +1395,7 @@ static const struct mmc_bus_ops mmc_ops = { | |||
1224 | .suspend = NULL, | 1395 | .suspend = NULL, |
1225 | .resume = NULL, | 1396 | .resume = NULL, |
1226 | .power_restore = mmc_power_restore, | 1397 | .power_restore = mmc_power_restore, |
1398 | .alive = mmc_alive, | ||
1227 | }; | 1399 | }; |
1228 | 1400 | ||
1229 | static const struct mmc_bus_ops mmc_ops_unsafe = { | 1401 | static const struct mmc_bus_ops mmc_ops_unsafe = { |
@@ -1234,6 +1406,7 @@ static const struct mmc_bus_ops mmc_ops_unsafe = { | |||
1234 | .suspend = mmc_suspend, | 1406 | .suspend = mmc_suspend, |
1235 | .resume = mmc_resume, | 1407 | .resume = mmc_resume, |
1236 | .power_restore = mmc_power_restore, | 1408 | .power_restore = mmc_power_restore, |
1409 | .alive = mmc_alive, | ||
1237 | }; | 1410 | }; |
1238 | 1411 | ||
1239 | static void mmc_attach_bus_ops(struct mmc_host *host) | 1412 | static void mmc_attach_bus_ops(struct mmc_host *host) |
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index f2a05ea40f2a..c63ad03c29c7 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c | |||
@@ -307,8 +307,8 @@ static int mmc_read_switch(struct mmc_card *card) | |||
307 | goto out; | 307 | goto out; |
308 | } | 308 | } |
309 | 309 | ||
310 | if (status[13] & UHS_SDR50_BUS_SPEED) | 310 | if (status[13] & SD_MODE_HIGH_SPEED) |
311 | card->sw_caps.hs_max_dtr = 50000000; | 311 | card->sw_caps.hs_max_dtr = HIGH_SPEED_MAX_DTR; |
312 | 312 | ||
313 | if (card->scr.sda_spec3) { | 313 | if (card->scr.sda_spec3) { |
314 | card->sw_caps.sd3_bus_mode = status[13]; | 314 | card->sw_caps.sd3_bus_mode = status[13]; |
@@ -661,7 +661,8 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) | |||
661 | 661 | ||
662 | /* SPI mode doesn't define CMD19 */ | 662 | /* SPI mode doesn't define CMD19 */ |
663 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) | 663 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) |
664 | err = card->host->ops->execute_tuning(card->host); | 664 | err = card->host->ops->execute_tuning(card->host, |
665 | MMC_SEND_TUNING_BLOCK); | ||
665 | 666 | ||
666 | out: | 667 | out: |
667 | kfree(status); | 668 | kfree(status); |
@@ -960,7 +961,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, | |||
960 | goto free_card; | 961 | goto free_card; |
961 | 962 | ||
962 | /* Card is an ultra-high-speed card */ | 963 | /* Card is an ultra-high-speed card */ |
963 | mmc_sd_card_set_uhs(card); | 964 | mmc_card_set_uhs(card); |
964 | 965 | ||
965 | /* | 966 | /* |
966 | * Since initialization is now complete, enable preset | 967 | * Since initialization is now complete, enable preset |
@@ -1019,6 +1020,14 @@ static void mmc_sd_remove(struct mmc_host *host) | |||
1019 | } | 1020 | } |
1020 | 1021 | ||
1021 | /* | 1022 | /* |
1023 | * Card detection - card is alive. | ||
1024 | */ | ||
1025 | static int mmc_sd_alive(struct mmc_host *host) | ||
1026 | { | ||
1027 | return mmc_send_status(host->card, NULL); | ||
1028 | } | ||
1029 | |||
1030 | /* | ||
1022 | * Card detection callback from host. | 1031 | * Card detection callback from host. |
1023 | */ | 1032 | */ |
1024 | static void mmc_sd_detect(struct mmc_host *host) | 1033 | static void mmc_sd_detect(struct mmc_host *host) |
@@ -1033,7 +1042,7 @@ static void mmc_sd_detect(struct mmc_host *host) | |||
1033 | /* | 1042 | /* |
1034 | * Just check if our card has been removed. | 1043 | * Just check if our card has been removed. |
1035 | */ | 1044 | */ |
1036 | err = mmc_send_status(host->card, NULL); | 1045 | err = _mmc_detect_card_removed(host); |
1037 | 1046 | ||
1038 | mmc_release_host(host); | 1047 | mmc_release_host(host); |
1039 | 1048 | ||
@@ -1102,6 +1111,7 @@ static const struct mmc_bus_ops mmc_sd_ops = { | |||
1102 | .suspend = NULL, | 1111 | .suspend = NULL, |
1103 | .resume = NULL, | 1112 | .resume = NULL, |
1104 | .power_restore = mmc_sd_power_restore, | 1113 | .power_restore = mmc_sd_power_restore, |
1114 | .alive = mmc_sd_alive, | ||
1105 | }; | 1115 | }; |
1106 | 1116 | ||
1107 | static const struct mmc_bus_ops mmc_sd_ops_unsafe = { | 1117 | static const struct mmc_bus_ops mmc_sd_ops_unsafe = { |
@@ -1110,6 +1120,7 @@ static const struct mmc_bus_ops mmc_sd_ops_unsafe = { | |||
1110 | .suspend = mmc_sd_suspend, | 1120 | .suspend = mmc_sd_suspend, |
1111 | .resume = mmc_sd_resume, | 1121 | .resume = mmc_sd_resume, |
1112 | .power_restore = mmc_sd_power_restore, | 1122 | .power_restore = mmc_sd_power_restore, |
1123 | .alive = mmc_sd_alive, | ||
1113 | }; | 1124 | }; |
1114 | 1125 | ||
1115 | static void mmc_sd_attach_bus_ops(struct mmc_host *host) | 1126 | static void mmc_sd_attach_bus_ops(struct mmc_host *host) |
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 3ab565e32a6a..bd7bacc950dc 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/mmc/host.h> | 15 | #include <linux/mmc/host.h> |
16 | #include <linux/mmc/card.h> | 16 | #include <linux/mmc/card.h> |
17 | #include <linux/mmc/mmc.h> | ||
17 | #include <linux/mmc/sdio.h> | 18 | #include <linux/mmc/sdio.h> |
18 | #include <linux/mmc/sdio_func.h> | 19 | #include <linux/mmc/sdio_func.h> |
19 | #include <linux/mmc/sdio_ids.h> | 20 | #include <linux/mmc/sdio_ids.h> |
@@ -102,6 +103,7 @@ static int sdio_read_cccr(struct mmc_card *card) | |||
102 | int ret; | 103 | int ret; |
103 | int cccr_vsn; | 104 | int cccr_vsn; |
104 | unsigned char data; | 105 | unsigned char data; |
106 | unsigned char speed; | ||
105 | 107 | ||
106 | memset(&card->cccr, 0, sizeof(struct sdio_cccr)); | 108 | memset(&card->cccr, 0, sizeof(struct sdio_cccr)); |
107 | 109 | ||
@@ -140,12 +142,60 @@ static int sdio_read_cccr(struct mmc_card *card) | |||
140 | } | 142 | } |
141 | 143 | ||
142 | if (cccr_vsn >= SDIO_CCCR_REV_1_20) { | 144 | if (cccr_vsn >= SDIO_CCCR_REV_1_20) { |
143 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data); | 145 | ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); |
144 | if (ret) | 146 | if (ret) |
145 | goto out; | 147 | goto out; |
146 | 148 | ||
147 | if (data & SDIO_SPEED_SHS) | 149 | card->scr.sda_spec3 = 0; |
148 | card->cccr.high_speed = 1; | 150 | card->sw_caps.sd3_bus_mode = 0; |
151 | card->sw_caps.sd3_drv_type = 0; | ||
152 | if (cccr_vsn >= SDIO_CCCR_REV_3_00) { | ||
153 | card->scr.sda_spec3 = 1; | ||
154 | ret = mmc_io_rw_direct(card, 0, 0, | ||
155 | SDIO_CCCR_UHS, 0, &data); | ||
156 | if (ret) | ||
157 | goto out; | ||
158 | |||
159 | if (card->host->caps & | ||
160 | (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | ||
161 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | | ||
162 | MMC_CAP_UHS_DDR50)) { | ||
163 | if (data & SDIO_UHS_DDR50) | ||
164 | card->sw_caps.sd3_bus_mode | ||
165 | |= SD_MODE_UHS_DDR50; | ||
166 | |||
167 | if (data & SDIO_UHS_SDR50) | ||
168 | card->sw_caps.sd3_bus_mode | ||
169 | |= SD_MODE_UHS_SDR50; | ||
170 | |||
171 | if (data & SDIO_UHS_SDR104) | ||
172 | card->sw_caps.sd3_bus_mode | ||
173 | |= SD_MODE_UHS_SDR104; | ||
174 | } | ||
175 | |||
176 | ret = mmc_io_rw_direct(card, 0, 0, | ||
177 | SDIO_CCCR_DRIVE_STRENGTH, 0, &data); | ||
178 | if (ret) | ||
179 | goto out; | ||
180 | |||
181 | if (data & SDIO_DRIVE_SDTA) | ||
182 | card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_A; | ||
183 | if (data & SDIO_DRIVE_SDTC) | ||
184 | card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C; | ||
185 | if (data & SDIO_DRIVE_SDTD) | ||
186 | card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D; | ||
187 | } | ||
188 | |||
189 | /* if no uhs mode ensure we check for high speed */ | ||
190 | if (!card->sw_caps.sd3_bus_mode) { | ||
191 | if (speed & SDIO_SPEED_SHS) { | ||
192 | card->cccr.high_speed = 1; | ||
193 | card->sw_caps.hs_max_dtr = 50000000; | ||
194 | } else { | ||
195 | card->cccr.high_speed = 0; | ||
196 | card->sw_caps.hs_max_dtr = 25000000; | ||
197 | } | ||
198 | } | ||
149 | } | 199 | } |
150 | 200 | ||
151 | out: | 201 | out: |
@@ -327,6 +377,194 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card) | |||
327 | return max_dtr; | 377 | return max_dtr; |
328 | } | 378 | } |
329 | 379 | ||
380 | static unsigned char host_drive_to_sdio_drive(int host_strength) | ||
381 | { | ||
382 | switch (host_strength) { | ||
383 | case MMC_SET_DRIVER_TYPE_A: | ||
384 | return SDIO_DTSx_SET_TYPE_A; | ||
385 | case MMC_SET_DRIVER_TYPE_B: | ||
386 | return SDIO_DTSx_SET_TYPE_B; | ||
387 | case MMC_SET_DRIVER_TYPE_C: | ||
388 | return SDIO_DTSx_SET_TYPE_C; | ||
389 | case MMC_SET_DRIVER_TYPE_D: | ||
390 | return SDIO_DTSx_SET_TYPE_D; | ||
391 | default: | ||
392 | return SDIO_DTSx_SET_TYPE_B; | ||
393 | } | ||
394 | } | ||
395 | |||
396 | static void sdio_select_driver_type(struct mmc_card *card) | ||
397 | { | ||
398 | int host_drv_type = SD_DRIVER_TYPE_B; | ||
399 | int card_drv_type = SD_DRIVER_TYPE_B; | ||
400 | int drive_strength; | ||
401 | unsigned char card_strength; | ||
402 | int err; | ||
403 | |||
404 | /* | ||
405 | * If the host doesn't support any of the Driver Types A,C or D, | ||
406 | * or there is no board specific handler then default Driver | ||
407 | * Type B is used. | ||
408 | */ | ||
409 | if (!(card->host->caps & | ||
410 | (MMC_CAP_DRIVER_TYPE_A | | ||
411 | MMC_CAP_DRIVER_TYPE_C | | ||
412 | MMC_CAP_DRIVER_TYPE_D))) | ||
413 | return; | ||
414 | |||
415 | if (!card->host->ops->select_drive_strength) | ||
416 | return; | ||
417 | |||
418 | if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) | ||
419 | host_drv_type |= SD_DRIVER_TYPE_A; | ||
420 | |||
421 | if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) | ||
422 | host_drv_type |= SD_DRIVER_TYPE_C; | ||
423 | |||
424 | if (card->host->caps & MMC_CAP_DRIVER_TYPE_D) | ||
425 | host_drv_type |= SD_DRIVER_TYPE_D; | ||
426 | |||
427 | if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A) | ||
428 | card_drv_type |= SD_DRIVER_TYPE_A; | ||
429 | |||
430 | if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C) | ||
431 | card_drv_type |= SD_DRIVER_TYPE_C; | ||
432 | |||
433 | if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_D) | ||
434 | card_drv_type |= SD_DRIVER_TYPE_D; | ||
435 | |||
436 | /* | ||
437 | * The drive strength that the hardware can support | ||
438 | * depends on the board design. Pass the appropriate | ||
439 | * information and let the hardware specific code | ||
440 | * return what is possible given the options | ||
441 | */ | ||
442 | drive_strength = card->host->ops->select_drive_strength( | ||
443 | card->sw_caps.uhs_max_dtr, | ||
444 | host_drv_type, card_drv_type); | ||
445 | |||
446 | /* if error just use default for drive strength B */ | ||
447 | err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0, | ||
448 | &card_strength); | ||
449 | if (err) | ||
450 | return; | ||
451 | |||
452 | card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT); | ||
453 | card_strength |= host_drive_to_sdio_drive(drive_strength); | ||
454 | |||
455 | err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH, | ||
456 | card_strength, NULL); | ||
457 | |||
458 | /* if error default to drive strength B */ | ||
459 | if (!err) | ||
460 | mmc_set_driver_type(card->host, drive_strength); | ||
461 | } | ||
462 | |||
463 | |||
464 | static int sdio_set_bus_speed_mode(struct mmc_card *card) | ||
465 | { | ||
466 | unsigned int bus_speed, timing; | ||
467 | int err; | ||
468 | unsigned char speed; | ||
469 | |||
470 | /* | ||
471 | * If the host doesn't support any of the UHS-I modes, fallback on | ||
472 | * default speed. | ||
473 | */ | ||
474 | if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | ||
475 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))) | ||
476 | return 0; | ||
477 | |||
478 | bus_speed = SDIO_SPEED_SDR12; | ||
479 | timing = MMC_TIMING_UHS_SDR12; | ||
480 | if ((card->host->caps & MMC_CAP_UHS_SDR104) && | ||
481 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) { | ||
482 | bus_speed = SDIO_SPEED_SDR104; | ||
483 | timing = MMC_TIMING_UHS_SDR104; | ||
484 | card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR; | ||
485 | } else if ((card->host->caps & MMC_CAP_UHS_DDR50) && | ||
486 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) { | ||
487 | bus_speed = SDIO_SPEED_DDR50; | ||
488 | timing = MMC_TIMING_UHS_DDR50; | ||
489 | card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR; | ||
490 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | ||
491 | MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode & | ||
492 | SD_MODE_UHS_SDR50)) { | ||
493 | bus_speed = SDIO_SPEED_SDR50; | ||
494 | timing = MMC_TIMING_UHS_SDR50; | ||
495 | card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR; | ||
496 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | ||
497 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) && | ||
498 | (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) { | ||
499 | bus_speed = SDIO_SPEED_SDR25; | ||
500 | timing = MMC_TIMING_UHS_SDR25; | ||
501 | card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR; | ||
502 | } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 | | ||
503 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 | | ||
504 | MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode & | ||
505 | SD_MODE_UHS_SDR12)) { | ||
506 | bus_speed = SDIO_SPEED_SDR12; | ||
507 | timing = MMC_TIMING_UHS_SDR12; | ||
508 | card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR; | ||
509 | } | ||
510 | |||
511 | err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed); | ||
512 | if (err) | ||
513 | return err; | ||
514 | |||
515 | speed &= ~SDIO_SPEED_BSS_MASK; | ||
516 | speed |= bus_speed; | ||
517 | err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL); | ||
518 | if (err) | ||
519 | return err; | ||
520 | |||
521 | if (bus_speed) { | ||
522 | mmc_set_timing(card->host, timing); | ||
523 | mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr); | ||
524 | } | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | /* | ||
530 | * UHS-I specific initialization procedure | ||
531 | */ | ||
532 | static int mmc_sdio_init_uhs_card(struct mmc_card *card) | ||
533 | { | ||
534 | int err; | ||
535 | |||
536 | if (!card->scr.sda_spec3) | ||
537 | return 0; | ||
538 | |||
539 | /* | ||
540 | * Switch to wider bus (if supported). | ||
541 | */ | ||
542 | if (card->host->caps & MMC_CAP_4_BIT_DATA) { | ||
543 | err = sdio_enable_4bit_bus(card); | ||
544 | if (err > 0) { | ||
545 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
546 | err = 0; | ||
547 | } | ||
548 | } | ||
549 | |||
550 | /* Set the driver strength for the card */ | ||
551 | sdio_select_driver_type(card); | ||
552 | |||
553 | /* Set bus speed mode of the card */ | ||
554 | err = sdio_set_bus_speed_mode(card); | ||
555 | if (err) | ||
556 | goto out; | ||
557 | |||
558 | /* Initialize and start re-tuning timer */ | ||
559 | if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) | ||
560 | err = card->host->ops->execute_tuning(card->host, | ||
561 | MMC_SEND_TUNING_BLOCK); | ||
562 | |||
563 | out: | ||
564 | |||
565 | return err; | ||
566 | } | ||
567 | |||
330 | /* | 568 | /* |
331 | * Handle the detection and initialisation of a card. | 569 | * Handle the detection and initialisation of a card. |
332 | * | 570 | * |
@@ -394,6 +632,30 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
394 | host->ops->init_card(host, card); | 632 | host->ops->init_card(host, card); |
395 | 633 | ||
396 | /* | 634 | /* |
635 | * If the host and card support UHS-I mode request the card | ||
636 | * to switch to 1.8V signaling level. No 1.8v signalling if | ||
637 | * UHS mode is not enabled to maintain compatibilty and some | ||
638 | * systems that claim 1.8v signalling in fact do not support | ||
639 | * it. | ||
640 | */ | ||
641 | if ((ocr & R4_18V_PRESENT) && | ||
642 | (host->caps & | ||
643 | (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 | | ||
644 | MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | | ||
645 | MMC_CAP_UHS_DDR50))) { | ||
646 | err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, | ||
647 | true); | ||
648 | if (err) { | ||
649 | ocr &= ~R4_18V_PRESENT; | ||
650 | host->ocr &= ~R4_18V_PRESENT; | ||
651 | } | ||
652 | err = 0; | ||
653 | } else { | ||
654 | ocr &= ~R4_18V_PRESENT; | ||
655 | host->ocr &= ~R4_18V_PRESENT; | ||
656 | } | ||
657 | |||
658 | /* | ||
397 | * For native busses: set card RCA and quit open drain mode. | 659 | * For native busses: set card RCA and quit open drain mode. |
398 | */ | 660 | */ |
399 | if (!powered_resume && !mmc_host_is_spi(host)) { | 661 | if (!powered_resume && !mmc_host_is_spi(host)) { |
@@ -492,29 +754,39 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, | |||
492 | if (err) | 754 | if (err) |
493 | goto remove; | 755 | goto remove; |
494 | 756 | ||
495 | /* | 757 | /* Initialization sequence for UHS-I cards */ |
496 | * Switch to high-speed (if supported). | 758 | /* Only if card supports 1.8v and UHS signaling */ |
497 | */ | 759 | if ((ocr & R4_18V_PRESENT) && card->sw_caps.sd3_bus_mode) { |
498 | err = sdio_enable_hs(card); | 760 | err = mmc_sdio_init_uhs_card(card); |
499 | if (err > 0) | 761 | if (err) |
500 | mmc_sd_go_highspeed(card); | 762 | goto remove; |
501 | else if (err) | ||
502 | goto remove; | ||
503 | 763 | ||
504 | /* | 764 | /* Card is an ultra-high-speed card */ |
505 | * Change to the card's maximum speed. | 765 | mmc_card_set_uhs(card); |
506 | */ | 766 | } else { |
507 | mmc_set_clock(host, mmc_sdio_get_max_clock(card)); | 767 | /* |
768 | * Switch to high-speed (if supported). | ||
769 | */ | ||
770 | err = sdio_enable_hs(card); | ||
771 | if (err > 0) | ||
772 | mmc_sd_go_highspeed(card); | ||
773 | else if (err) | ||
774 | goto remove; | ||
508 | 775 | ||
509 | /* | 776 | /* |
510 | * Switch to wider bus (if supported). | 777 | * Change to the card's maximum speed. |
511 | */ | 778 | */ |
512 | err = sdio_enable_4bit_bus(card); | 779 | mmc_set_clock(host, mmc_sdio_get_max_clock(card)); |
513 | if (err > 0) | ||
514 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
515 | else if (err) | ||
516 | goto remove; | ||
517 | 780 | ||
781 | /* | ||
782 | * Switch to wider bus (if supported). | ||
783 | */ | ||
784 | err = sdio_enable_4bit_bus(card); | ||
785 | if (err > 0) | ||
786 | mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4); | ||
787 | else if (err) | ||
788 | goto remove; | ||
789 | } | ||
518 | finish: | 790 | finish: |
519 | if (!oldcard) | 791 | if (!oldcard) |
520 | host->card = card; | 792 | host->card = card; |
@@ -550,6 +822,14 @@ static void mmc_sdio_remove(struct mmc_host *host) | |||
550 | } | 822 | } |
551 | 823 | ||
552 | /* | 824 | /* |
825 | * Card detection - card is alive. | ||
826 | */ | ||
827 | static int mmc_sdio_alive(struct mmc_host *host) | ||
828 | { | ||
829 | return mmc_select_card(host->card); | ||
830 | } | ||
831 | |||
832 | /* | ||
553 | * Card detection callback from host. | 833 | * Card detection callback from host. |
554 | */ | 834 | */ |
555 | static void mmc_sdio_detect(struct mmc_host *host) | 835 | static void mmc_sdio_detect(struct mmc_host *host) |
@@ -571,7 +851,7 @@ static void mmc_sdio_detect(struct mmc_host *host) | |||
571 | /* | 851 | /* |
572 | * Just check if our card has been removed. | 852 | * Just check if our card has been removed. |
573 | */ | 853 | */ |
574 | err = mmc_select_card(host->card); | 854 | err = _mmc_detect_card_removed(host); |
575 | 855 | ||
576 | mmc_release_host(host); | 856 | mmc_release_host(host); |
577 | 857 | ||
@@ -749,6 +1029,7 @@ static const struct mmc_bus_ops mmc_sdio_ops = { | |||
749 | .suspend = mmc_sdio_suspend, | 1029 | .suspend = mmc_sdio_suspend, |
750 | .resume = mmc_sdio_resume, | 1030 | .resume = mmc_sdio_resume, |
751 | .power_restore = mmc_sdio_power_restore, | 1031 | .power_restore = mmc_sdio_power_restore, |
1032 | .alive = mmc_sdio_alive, | ||
752 | }; | 1033 | }; |
753 | 1034 | ||
754 | 1035 | ||
@@ -797,8 +1078,17 @@ int mmc_attach_sdio(struct mmc_host *host) | |||
797 | * Detect and init the card. | 1078 | * Detect and init the card. |
798 | */ | 1079 | */ |
799 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); | 1080 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); |
800 | if (err) | 1081 | if (err) { |
801 | goto err; | 1082 | if (err == -EAGAIN) { |
1083 | /* | ||
1084 | * Retry initialization with S18R set to 0. | ||
1085 | */ | ||
1086 | host->ocr &= ~R4_18V_PRESENT; | ||
1087 | err = mmc_sdio_init_card(host, host->ocr, NULL, 0); | ||
1088 | } | ||
1089 | if (err) | ||
1090 | goto err; | ||
1091 | } | ||
802 | card = host->card; | 1092 | card = host->card; |
803 | 1093 | ||
804 | /* | 1094 | /* |
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c index b1f3168f791b..8f6f5ac131fc 100644 --- a/drivers/mmc/core/sdio_io.c +++ b/drivers/mmc/core/sdio_io.c | |||
@@ -196,6 +196,9 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func) | |||
196 | else | 196 | else |
197 | mval = min(mval, func->max_blksize); | 197 | mval = min(mval, func->max_blksize); |
198 | 198 | ||
199 | if (mmc_card_broken_byte_mode_512(func->card)) | ||
200 | return min(mval, 511u); | ||
201 | |||
199 | return min(mval, 512u); /* maximum size for byte mode */ | 202 | return min(mval, 512u); /* maximum size for byte mode */ |
200 | } | 203 | } |
201 | 204 | ||
@@ -314,7 +317,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, | |||
314 | func->card->host->max_seg_size / func->cur_blksize); | 317 | func->card->host->max_seg_size / func->cur_blksize); |
315 | max_blocks = min(max_blocks, 511u); | 318 | max_blocks = min(max_blocks, 511u); |
316 | 319 | ||
317 | while (remainder > func->cur_blksize) { | 320 | while (remainder >= func->cur_blksize) { |
318 | unsigned blocks; | 321 | unsigned blocks; |
319 | 322 | ||
320 | blocks = remainder / func->cur_blksize; | 323 | blocks = remainder / func->cur_blksize; |
@@ -339,8 +342,9 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write, | |||
339 | while (remainder > 0) { | 342 | while (remainder > 0) { |
340 | size = min(remainder, sdio_max_byte_size(func)); | 343 | size = min(remainder, sdio_max_byte_size(func)); |
341 | 344 | ||
345 | /* Indicate byte mode by setting "blocks" = 0 */ | ||
342 | ret = mmc_io_rw_extended(func->card, write, func->num, addr, | 346 | ret = mmc_io_rw_extended(func->card, write, func->num, addr, |
343 | incr_addr, buf, 1, size); | 347 | incr_addr, buf, 0, size); |
344 | if (ret) | 348 | if (ret) |
345 | return ret; | 349 | return ret; |
346 | 350 | ||
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c index b0517cc06200..d29e20630eed 100644 --- a/drivers/mmc/core/sdio_ops.c +++ b/drivers/mmc/core/sdio_ops.c | |||
@@ -128,8 +128,6 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | |||
128 | 128 | ||
129 | BUG_ON(!card); | 129 | BUG_ON(!card); |
130 | BUG_ON(fn > 7); | 130 | BUG_ON(fn > 7); |
131 | BUG_ON(blocks == 1 && blksz > 512); | ||
132 | WARN_ON(blocks == 0); | ||
133 | WARN_ON(blksz == 0); | 131 | WARN_ON(blksz == 0); |
134 | 132 | ||
135 | /* sanity check */ | 133 | /* sanity check */ |
@@ -144,22 +142,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn, | |||
144 | cmd.arg |= fn << 28; | 142 | cmd.arg |= fn << 28; |
145 | cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; | 143 | cmd.arg |= incr_addr ? 0x04000000 : 0x00000000; |
146 | cmd.arg |= addr << 9; | 144 | cmd.arg |= addr << 9; |
147 | if (blocks == 1 && blksz < 512) | 145 | if (blocks == 0) |
148 | cmd.arg |= blksz; /* byte mode */ | 146 | cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */ |
149 | else if (blocks == 1 && blksz == 512 && | ||
150 | !(mmc_card_broken_byte_mode_512(card))) | ||
151 | cmd.arg |= 0; /* byte mode, 0==512 */ | ||
152 | else | 147 | else |
153 | cmd.arg |= 0x08000000 | blocks; /* block mode */ | 148 | cmd.arg |= 0x08000000 | blocks; /* block mode */ |
154 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; | 149 | cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; |
155 | 150 | ||
156 | data.blksz = blksz; | 151 | data.blksz = blksz; |
157 | data.blocks = blocks; | 152 | /* Code in host drivers/fwk assumes that "blocks" always is >=1 */ |
153 | data.blocks = blocks ? blocks : 1; | ||
158 | data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; | 154 | data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ; |
159 | data.sg = &sg; | 155 | data.sg = &sg; |
160 | data.sg_len = 1; | 156 | data.sg_len = 1; |
161 | 157 | ||
162 | sg_init_one(&sg, buf, blksz * blocks); | 158 | sg_init_one(&sg, buf, data.blksz * data.blocks); |
163 | 159 | ||
164 | mmc_set_data_timeout(&data, card); | 160 | mmc_set_data_timeout(&data, card); |
165 | 161 | ||
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index b4b83f302e32..745f8fce2519 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o | |||
9 | obj-$(CONFIG_MMC_MXS) += mxs-mmc.o | 9 | obj-$(CONFIG_MMC_MXS) += mxs-mmc.o |
10 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o | 10 | obj-$(CONFIG_MMC_SDHCI) += sdhci.o |
11 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o | 11 | obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o |
12 | obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o | ||
12 | obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o | 13 | obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o |
13 | obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o | 14 | obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o |
14 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o | 15 | obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index f437c3e6f3aa..947faa5d2ce4 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -236,7 +236,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
236 | 236 | ||
237 | sg = &data->sg[i]; | 237 | sg = &data->sg[i]; |
238 | 238 | ||
239 | sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 239 | sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset; |
240 | amount = min(size, sg->length); | 240 | amount = min(size, sg->length); |
241 | size -= amount; | 241 | size -= amount; |
242 | 242 | ||
@@ -252,7 +252,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data | |||
252 | dmabuf = (unsigned *)tmpv; | 252 | dmabuf = (unsigned *)tmpv; |
253 | } | 253 | } |
254 | 254 | ||
255 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 255 | kunmap_atomic(sgbuffer); |
256 | 256 | ||
257 | if (size == 0) | 257 | if (size == 0) |
258 | break; | 258 | break; |
@@ -302,7 +302,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) | |||
302 | 302 | ||
303 | sg = &data->sg[i]; | 303 | sg = &data->sg[i]; |
304 | 304 | ||
305 | sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 305 | sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset; |
306 | amount = min(size, sg->length); | 306 | amount = min(size, sg->length); |
307 | size -= amount; | 307 | size -= amount; |
308 | 308 | ||
@@ -318,7 +318,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host) | |||
318 | } | 318 | } |
319 | 319 | ||
320 | flush_kernel_dcache_page(sg_page(sg)); | 320 | flush_kernel_dcache_page(sg_page(sg)); |
321 | kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ); | 321 | kunmap_atomic(sgbuffer); |
322 | data->bytes_xfered += amount; | 322 | data->bytes_xfered += amount; |
323 | if (size == 0) | 323 | if (size == 0) |
324 | break; | 324 | break; |
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c index 0371bf502249..03666174ca48 100644 --- a/drivers/mmc/host/bfin_sdh.c +++ b/drivers/mmc/host/bfin_sdh.c | |||
@@ -627,17 +627,7 @@ static struct platform_driver sdh_driver = { | |||
627 | }, | 627 | }, |
628 | }; | 628 | }; |
629 | 629 | ||
630 | static int __init sdh_init(void) | 630 | module_platform_driver(sdh_driver); |
631 | { | ||
632 | return platform_driver_register(&sdh_driver); | ||
633 | } | ||
634 | module_init(sdh_init); | ||
635 | |||
636 | static void __exit sdh_exit(void) | ||
637 | { | ||
638 | platform_driver_unregister(&sdh_driver); | ||
639 | } | ||
640 | module_exit(sdh_exit); | ||
641 | 631 | ||
642 | MODULE_DESCRIPTION("Blackfin Secure Digital Host Driver"); | 632 | MODULE_DESCRIPTION("Blackfin Secure Digital Host Driver"); |
643 | MODULE_AUTHOR("Cliff Cai, Roy Huang"); | 633 | MODULE_AUTHOR("Cliff Cai, Roy Huang"); |
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c index ce2a47b71dd6..83693fd7c6b3 100644 --- a/drivers/mmc/host/cb710-mmc.c +++ b/drivers/mmc/host/cb710-mmc.c | |||
@@ -780,18 +780,7 @@ static struct platform_driver cb710_mmc_driver = { | |||
780 | #endif | 780 | #endif |
781 | }; | 781 | }; |
782 | 782 | ||
783 | static int __init cb710_mmc_init_module(void) | 783 | module_platform_driver(cb710_mmc_driver); |
784 | { | ||
785 | return platform_driver_register(&cb710_mmc_driver); | ||
786 | } | ||
787 | |||
788 | static void __exit cb710_mmc_cleanup_module(void) | ||
789 | { | ||
790 | platform_driver_unregister(&cb710_mmc_driver); | ||
791 | } | ||
792 | |||
793 | module_init(cb710_mmc_init_module); | ||
794 | module_exit(cb710_mmc_cleanup_module); | ||
795 | 784 | ||
796 | MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>"); | 785 | MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>"); |
797 | MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part"); | 786 | MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part"); |
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 3aaeb0841914..0e342793ff14 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c | |||
@@ -588,11 +588,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot) | |||
588 | mci_writel(host, CTYPE, (slot->ctype << slot->id)); | 588 | mci_writel(host, CTYPE, (slot->ctype << slot->id)); |
589 | } | 589 | } |
590 | 590 | ||
591 | static void dw_mci_start_request(struct dw_mci *host, | 591 | static void __dw_mci_start_request(struct dw_mci *host, |
592 | struct dw_mci_slot *slot) | 592 | struct dw_mci_slot *slot, |
593 | struct mmc_command *cmd) | ||
593 | { | 594 | { |
594 | struct mmc_request *mrq; | 595 | struct mmc_request *mrq; |
595 | struct mmc_command *cmd; | ||
596 | struct mmc_data *data; | 596 | struct mmc_data *data; |
597 | u32 cmdflags; | 597 | u32 cmdflags; |
598 | 598 | ||
@@ -610,14 +610,13 @@ static void dw_mci_start_request(struct dw_mci *host, | |||
610 | host->completed_events = 0; | 610 | host->completed_events = 0; |
611 | host->data_status = 0; | 611 | host->data_status = 0; |
612 | 612 | ||
613 | data = mrq->data; | 613 | data = cmd->data; |
614 | if (data) { | 614 | if (data) { |
615 | dw_mci_set_timeout(host); | 615 | dw_mci_set_timeout(host); |
616 | mci_writel(host, BYTCNT, data->blksz*data->blocks); | 616 | mci_writel(host, BYTCNT, data->blksz*data->blocks); |
617 | mci_writel(host, BLKSIZ, data->blksz); | 617 | mci_writel(host, BLKSIZ, data->blksz); |
618 | } | 618 | } |
619 | 619 | ||
620 | cmd = mrq->cmd; | ||
621 | cmdflags = dw_mci_prepare_command(slot->mmc, cmd); | 620 | cmdflags = dw_mci_prepare_command(slot->mmc, cmd); |
622 | 621 | ||
623 | /* this is the first command, send the initialization clock */ | 622 | /* this is the first command, send the initialization clock */ |
@@ -635,6 +634,16 @@ static void dw_mci_start_request(struct dw_mci *host, | |||
635 | host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); | 634 | host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop); |
636 | } | 635 | } |
637 | 636 | ||
637 | static void dw_mci_start_request(struct dw_mci *host, | ||
638 | struct dw_mci_slot *slot) | ||
639 | { | ||
640 | struct mmc_request *mrq = slot->mrq; | ||
641 | struct mmc_command *cmd; | ||
642 | |||
643 | cmd = mrq->sbc ? mrq->sbc : mrq->cmd; | ||
644 | __dw_mci_start_request(host, slot, cmd); | ||
645 | } | ||
646 | |||
638 | /* must be called with host->lock held */ | 647 | /* must be called with host->lock held */ |
639 | static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot, | 648 | static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot, |
640 | struct mmc_request *mrq) | 649 | struct mmc_request *mrq) |
@@ -698,12 +707,15 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
698 | break; | 707 | break; |
699 | } | 708 | } |
700 | 709 | ||
710 | regs = mci_readl(slot->host, UHS_REG); | ||
711 | |||
701 | /* DDR mode set */ | 712 | /* DDR mode set */ |
702 | if (ios->timing == MMC_TIMING_UHS_DDR50) { | 713 | if (ios->timing == MMC_TIMING_UHS_DDR50) |
703 | regs = mci_readl(slot->host, UHS_REG); | ||
704 | regs |= (0x1 << slot->id) << 16; | 714 | regs |= (0x1 << slot->id) << 16; |
705 | mci_writel(slot->host, UHS_REG, regs); | 715 | else |
706 | } | 716 | regs &= ~(0x1 << slot->id) << 16; |
717 | |||
718 | mci_writel(slot->host, UHS_REG, regs); | ||
707 | 719 | ||
708 | if (ios->clock) { | 720 | if (ios->clock) { |
709 | /* | 721 | /* |
@@ -889,7 +901,14 @@ static void dw_mci_tasklet_func(unsigned long priv) | |||
889 | cmd = host->cmd; | 901 | cmd = host->cmd; |
890 | host->cmd = NULL; | 902 | host->cmd = NULL; |
891 | set_bit(EVENT_CMD_COMPLETE, &host->completed_events); | 903 | set_bit(EVENT_CMD_COMPLETE, &host->completed_events); |
892 | dw_mci_command_complete(host, host->mrq->cmd); | 904 | dw_mci_command_complete(host, cmd); |
905 | if (cmd == host->mrq->sbc && !cmd->error) { | ||
906 | prev_state = state = STATE_SENDING_CMD; | ||
907 | __dw_mci_start_request(host, host->cur_slot, | ||
908 | host->mrq->cmd); | ||
909 | goto unlock; | ||
910 | } | ||
911 | |||
893 | if (!host->mrq->data || cmd->error) { | 912 | if (!host->mrq->data || cmd->error) { |
894 | dw_mci_request_end(host, host->mrq); | 913 | dw_mci_request_end(host, host->mrq); |
895 | goto unlock; | 914 | goto unlock; |
@@ -967,6 +986,12 @@ static void dw_mci_tasklet_func(unsigned long priv) | |||
967 | goto unlock; | 986 | goto unlock; |
968 | } | 987 | } |
969 | 988 | ||
989 | if (host->mrq->sbc && !data->error) { | ||
990 | data->stop->error = 0; | ||
991 | dw_mci_request_end(host, host->mrq); | ||
992 | goto unlock; | ||
993 | } | ||
994 | |||
970 | prev_state = state = STATE_SENDING_STOP; | 995 | prev_state = state = STATE_SENDING_STOP; |
971 | if (!data->error) | 996 | if (!data->error) |
972 | send_stop_cmd(host, data); | 997 | send_stop_cmd(host, data); |
@@ -1678,8 +1703,9 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id) | |||
1678 | 1703 | ||
1679 | if (host->pdata->caps) | 1704 | if (host->pdata->caps) |
1680 | mmc->caps = host->pdata->caps; | 1705 | mmc->caps = host->pdata->caps; |
1681 | else | 1706 | |
1682 | mmc->caps = 0; | 1707 | if (host->pdata->caps2) |
1708 | mmc->caps2 = host->pdata->caps2; | ||
1683 | 1709 | ||
1684 | if (host->pdata->get_bus_wd) | 1710 | if (host->pdata->get_bus_wd) |
1685 | if (host->pdata->get_bus_wd(slot->id) >= 4) | 1711 | if (host->pdata->get_bus_wd(slot->id) >= 4) |
@@ -1923,7 +1949,7 @@ static int dw_mci_probe(struct platform_device *pdev) | |||
1923 | * should put it in the platform data. | 1949 | * should put it in the platform data. |
1924 | */ | 1950 | */ |
1925 | fifo_size = mci_readl(host, FIFOTH); | 1951 | fifo_size = mci_readl(host, FIFOTH); |
1926 | fifo_size = 1 + ((fifo_size >> 16) & 0x7ff); | 1952 | fifo_size = 1 + ((fifo_size >> 16) & 0xfff); |
1927 | } else { | 1953 | } else { |
1928 | fifo_size = host->pdata->fifo_depth; | 1954 | fifo_size = host->pdata->fifo_depth; |
1929 | } | 1955 | } |
@@ -2062,14 +2088,14 @@ static int __exit dw_mci_remove(struct platform_device *pdev) | |||
2062 | return 0; | 2088 | return 0; |
2063 | } | 2089 | } |
2064 | 2090 | ||
2065 | #ifdef CONFIG_PM | 2091 | #ifdef CONFIG_PM_SLEEP |
2066 | /* | 2092 | /* |
2067 | * TODO: we should probably disable the clock to the card in the suspend path. | 2093 | * TODO: we should probably disable the clock to the card in the suspend path. |
2068 | */ | 2094 | */ |
2069 | static int dw_mci_suspend(struct platform_device *pdev, pm_message_t mesg) | 2095 | static int dw_mci_suspend(struct device *dev) |
2070 | { | 2096 | { |
2071 | int i, ret; | 2097 | int i, ret; |
2072 | struct dw_mci *host = platform_get_drvdata(pdev); | 2098 | struct dw_mci *host = dev_get_drvdata(dev); |
2073 | 2099 | ||
2074 | for (i = 0; i < host->num_slots; i++) { | 2100 | for (i = 0; i < host->num_slots; i++) { |
2075 | struct dw_mci_slot *slot = host->slot[i]; | 2101 | struct dw_mci_slot *slot = host->slot[i]; |
@@ -2092,10 +2118,10 @@ static int dw_mci_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
2092 | return 0; | 2118 | return 0; |
2093 | } | 2119 | } |
2094 | 2120 | ||
2095 | static int dw_mci_resume(struct platform_device *pdev) | 2121 | static int dw_mci_resume(struct device *dev) |
2096 | { | 2122 | { |
2097 | int i, ret; | 2123 | int i, ret; |
2098 | struct dw_mci *host = platform_get_drvdata(pdev); | 2124 | struct dw_mci *host = dev_get_drvdata(dev); |
2099 | 2125 | ||
2100 | if (host->vmmc) | 2126 | if (host->vmmc) |
2101 | regulator_enable(host->vmmc); | 2127 | regulator_enable(host->vmmc); |
@@ -2103,7 +2129,7 @@ static int dw_mci_resume(struct platform_device *pdev) | |||
2103 | if (host->dma_ops->init) | 2129 | if (host->dma_ops->init) |
2104 | host->dma_ops->init(host); | 2130 | host->dma_ops->init(host); |
2105 | 2131 | ||
2106 | if (!mci_wait_reset(&pdev->dev, host)) { | 2132 | if (!mci_wait_reset(dev, host)) { |
2107 | ret = -ENODEV; | 2133 | ret = -ENODEV; |
2108 | return ret; | 2134 | return ret; |
2109 | } | 2135 | } |
@@ -2131,14 +2157,15 @@ static int dw_mci_resume(struct platform_device *pdev) | |||
2131 | #else | 2157 | #else |
2132 | #define dw_mci_suspend NULL | 2158 | #define dw_mci_suspend NULL |
2133 | #define dw_mci_resume NULL | 2159 | #define dw_mci_resume NULL |
2134 | #endif /* CONFIG_PM */ | 2160 | #endif /* CONFIG_PM_SLEEP */ |
2161 | |||
2162 | static SIMPLE_DEV_PM_OPS(dw_mci_pmops, dw_mci_suspend, dw_mci_resume); | ||
2135 | 2163 | ||
2136 | static struct platform_driver dw_mci_driver = { | 2164 | static struct platform_driver dw_mci_driver = { |
2137 | .remove = __exit_p(dw_mci_remove), | 2165 | .remove = __exit_p(dw_mci_remove), |
2138 | .suspend = dw_mci_suspend, | ||
2139 | .resume = dw_mci_resume, | ||
2140 | .driver = { | 2166 | .driver = { |
2141 | .name = "dw_mmc", | 2167 | .name = "dw_mmc", |
2168 | .pm = &dw_mci_pmops, | ||
2142 | }, | 2169 | }, |
2143 | }; | 2170 | }; |
2144 | 2171 | ||
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 72c071f6e001..df392a1143f2 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h | |||
@@ -126,7 +126,7 @@ | |||
126 | #define SDMMC_CMD_RESP_EXP BIT(6) | 126 | #define SDMMC_CMD_RESP_EXP BIT(6) |
127 | #define SDMMC_CMD_INDX(n) ((n) & 0x1F) | 127 | #define SDMMC_CMD_INDX(n) ((n) & 0x1F) |
128 | /* Status register defines */ | 128 | /* Status register defines */ |
129 | #define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FF) | 129 | #define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FFF) |
130 | /* Internal DMAC interrupt defines */ | 130 | /* Internal DMAC interrupt defines */ |
131 | #define SDMMC_IDMAC_INT_AI BIT(9) | 131 | #define SDMMC_IDMAC_INT_AI BIT(9) |
132 | #define SDMMC_IDMAC_INT_NI BIT(8) | 132 | #define SDMMC_IDMAC_INT_NI BIT(8) |
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c index 74218ad677e4..c8852a8128a9 100644 --- a/drivers/mmc/host/jz4740_mmc.c +++ b/drivers/mmc/host/jz4740_mmc.c | |||
@@ -1012,17 +1012,7 @@ static struct platform_driver jz4740_mmc_driver = { | |||
1012 | }, | 1012 | }, |
1013 | }; | 1013 | }; |
1014 | 1014 | ||
1015 | static int __init jz4740_mmc_init(void) | 1015 | module_platform_driver(jz4740_mmc_driver); |
1016 | { | ||
1017 | return platform_driver_register(&jz4740_mmc_driver); | ||
1018 | } | ||
1019 | module_init(jz4740_mmc_init); | ||
1020 | |||
1021 | static void __exit jz4740_mmc_exit(void) | ||
1022 | { | ||
1023 | platform_driver_unregister(&jz4740_mmc_driver); | ||
1024 | } | ||
1025 | module_exit(jz4740_mmc_exit); | ||
1026 | 1016 | ||
1027 | MODULE_DESCRIPTION("JZ4740 SD/MMC controller driver"); | 1017 | MODULE_DESCRIPTION("JZ4740 SD/MMC controller driver"); |
1028 | MODULE_LICENSE("GPL"); | 1018 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c index 92946b84e9fa..273306c68d58 100644 --- a/drivers/mmc/host/mmc_spi.c +++ b/drivers/mmc/host/mmc_spi.c | |||
@@ -1525,7 +1525,6 @@ static struct of_device_id mmc_spi_of_match_table[] __devinitdata = { | |||
1525 | static struct spi_driver mmc_spi_driver = { | 1525 | static struct spi_driver mmc_spi_driver = { |
1526 | .driver = { | 1526 | .driver = { |
1527 | .name = "mmc_spi", | 1527 | .name = "mmc_spi", |
1528 | .bus = &spi_bus_type, | ||
1529 | .owner = THIS_MODULE, | 1528 | .owner = THIS_MODULE, |
1530 | .of_match_table = mmc_spi_of_match_table, | 1529 | .of_match_table = mmc_spi_of_match_table, |
1531 | }, | 1530 | }, |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index fa8dd2fda4b2..ece03b491c7d 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -1245,6 +1245,7 @@ static int __devinit mmci_probe(struct amba_device *dev, | |||
1245 | if (host->vcc == NULL) | 1245 | if (host->vcc == NULL) |
1246 | mmc->ocr_avail = plat->ocr_mask; | 1246 | mmc->ocr_avail = plat->ocr_mask; |
1247 | mmc->caps = plat->capabilities; | 1247 | mmc->caps = plat->capabilities; |
1248 | mmc->caps2 = plat->capabilities2; | ||
1248 | 1249 | ||
1249 | /* | 1250 | /* |
1250 | * We can do SGIO | 1251 | * We can do SGIO |
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c index 80d8eb143b48..1d14cda95e56 100644 --- a/drivers/mmc/host/msm_sdcc.c +++ b/drivers/mmc/host/msm_sdcc.c | |||
@@ -689,8 +689,8 @@ msmsdcc_pio_irq(int irq, void *dev_id) | |||
689 | 689 | ||
690 | /* Map the current scatter buffer */ | 690 | /* Map the current scatter buffer */ |
691 | local_irq_save(flags); | 691 | local_irq_save(flags); |
692 | buffer = kmap_atomic(sg_page(host->pio.sg), | 692 | buffer = kmap_atomic(sg_page(host->pio.sg)) |
693 | KM_BIO_SRC_IRQ) + host->pio.sg->offset; | 693 | + host->pio.sg->offset; |
694 | buffer += host->pio.sg_off; | 694 | buffer += host->pio.sg_off; |
695 | remain = host->pio.sg->length - host->pio.sg_off; | 695 | remain = host->pio.sg->length - host->pio.sg_off; |
696 | len = 0; | 696 | len = 0; |
@@ -700,7 +700,7 @@ msmsdcc_pio_irq(int irq, void *dev_id) | |||
700 | len = msmsdcc_pio_write(host, buffer, remain, status); | 700 | len = msmsdcc_pio_write(host, buffer, remain, status); |
701 | 701 | ||
702 | /* Unmap the buffer */ | 702 | /* Unmap the buffer */ |
703 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); | 703 | kunmap_atomic(buffer); |
704 | local_irq_restore(flags); | 704 | local_irq_restore(flags); |
705 | 705 | ||
706 | host->pio.sg_off += len; | 706 | host->pio.sg_off += len; |
@@ -1480,18 +1480,7 @@ static struct platform_driver msmsdcc_driver = { | |||
1480 | }, | 1480 | }, |
1481 | }; | 1481 | }; |
1482 | 1482 | ||
1483 | static int __init msmsdcc_init(void) | 1483 | module_platform_driver(msmsdcc_driver); |
1484 | { | ||
1485 | return platform_driver_register(&msmsdcc_driver); | ||
1486 | } | ||
1487 | |||
1488 | static void __exit msmsdcc_exit(void) | ||
1489 | { | ||
1490 | platform_driver_unregister(&msmsdcc_driver); | ||
1491 | } | ||
1492 | |||
1493 | module_init(msmsdcc_init); | ||
1494 | module_exit(msmsdcc_exit); | ||
1495 | 1484 | ||
1496 | MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver"); | 1485 | MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver"); |
1497 | MODULE_LICENSE("GPL"); | 1486 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 8e0fbe994047..7088b40f9579 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c | |||
@@ -1047,18 +1047,7 @@ static struct platform_driver mxcmci_driver = { | |||
1047 | } | 1047 | } |
1048 | }; | 1048 | }; |
1049 | 1049 | ||
1050 | static int __init mxcmci_init(void) | 1050 | module_platform_driver(mxcmci_driver); |
1051 | { | ||
1052 | return platform_driver_register(&mxcmci_driver); | ||
1053 | } | ||
1054 | |||
1055 | static void __exit mxcmci_exit(void) | ||
1056 | { | ||
1057 | platform_driver_unregister(&mxcmci_driver); | ||
1058 | } | ||
1059 | |||
1060 | module_init(mxcmci_init); | ||
1061 | module_exit(mxcmci_exit); | ||
1062 | 1051 | ||
1063 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); | 1052 | MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver"); |
1064 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); | 1053 | MODULE_AUTHOR("Sascha Hauer, Pengutronix"); |
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c index 973011f9a298..4e2e019dd5c9 100644 --- a/drivers/mmc/host/mxs-mmc.c +++ b/drivers/mmc/host/mxs-mmc.c | |||
@@ -855,18 +855,7 @@ static struct platform_driver mxs_mmc_driver = { | |||
855 | }, | 855 | }, |
856 | }; | 856 | }; |
857 | 857 | ||
858 | static int __init mxs_mmc_init(void) | 858 | module_platform_driver(mxs_mmc_driver); |
859 | { | ||
860 | return platform_driver_register(&mxs_mmc_driver); | ||
861 | } | ||
862 | |||
863 | static void __exit mxs_mmc_exit(void) | ||
864 | { | ||
865 | platform_driver_unregister(&mxs_mmc_driver); | ||
866 | } | ||
867 | |||
868 | module_init(mxs_mmc_init); | ||
869 | module_exit(mxs_mmc_exit); | ||
870 | 859 | ||
871 | MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral"); | 860 | MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral"); |
872 | MODULE_AUTHOR("Freescale Semiconductor"); | 861 | MODULE_AUTHOR("Freescale Semiconductor"); |
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c index d1fb561e089d..fd0c661bbad3 100644 --- a/drivers/mmc/host/omap_hsmmc.c +++ b/drivers/mmc/host/omap_hsmmc.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
25 | #include <linux/dma-mapping.h> | 25 | #include <linux/dma-mapping.h> |
26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
27 | #include <linux/workqueue.h> | ||
28 | #include <linux/timer.h> | 27 | #include <linux/timer.h> |
29 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
30 | #include <linux/mmc/host.h> | 29 | #include <linux/mmc/host.h> |
@@ -120,7 +119,6 @@ | |||
120 | 119 | ||
121 | #define MMC_AUTOSUSPEND_DELAY 100 | 120 | #define MMC_AUTOSUSPEND_DELAY 100 |
122 | #define MMC_TIMEOUT_MS 20 | 121 | #define MMC_TIMEOUT_MS 20 |
123 | #define OMAP_MMC_MASTER_CLOCK 96000000 | ||
124 | #define OMAP_MMC_MIN_CLOCK 400000 | 122 | #define OMAP_MMC_MIN_CLOCK 400000 |
125 | #define OMAP_MMC_MAX_CLOCK 52000000 | 123 | #define OMAP_MMC_MAX_CLOCK 52000000 |
126 | #define DRIVER_NAME "omap_hsmmc" | 124 | #define DRIVER_NAME "omap_hsmmc" |
@@ -163,7 +161,6 @@ struct omap_hsmmc_host { | |||
163 | */ | 161 | */ |
164 | struct regulator *vcc; | 162 | struct regulator *vcc; |
165 | struct regulator *vcc_aux; | 163 | struct regulator *vcc_aux; |
166 | struct work_struct mmc_carddetect_work; | ||
167 | void __iomem *base; | 164 | void __iomem *base; |
168 | resource_size_t mapbase; | 165 | resource_size_t mapbase; |
169 | spinlock_t irq_lock; /* Prevent races with irq handler */ | 166 | spinlock_t irq_lock; /* Prevent races with irq handler */ |
@@ -598,12 +595,12 @@ static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host) | |||
598 | } | 595 | } |
599 | 596 | ||
600 | /* Calculate divisor for the given clock frequency */ | 597 | /* Calculate divisor for the given clock frequency */ |
601 | static u16 calc_divisor(struct mmc_ios *ios) | 598 | static u16 calc_divisor(struct omap_hsmmc_host *host, struct mmc_ios *ios) |
602 | { | 599 | { |
603 | u16 dsor = 0; | 600 | u16 dsor = 0; |
604 | 601 | ||
605 | if (ios->clock) { | 602 | if (ios->clock) { |
606 | dsor = DIV_ROUND_UP(OMAP_MMC_MASTER_CLOCK, ios->clock); | 603 | dsor = DIV_ROUND_UP(clk_get_rate(host->fclk), ios->clock); |
607 | if (dsor > 250) | 604 | if (dsor > 250) |
608 | dsor = 250; | 605 | dsor = 250; |
609 | } | 606 | } |
@@ -623,7 +620,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host) | |||
623 | 620 | ||
624 | regval = OMAP_HSMMC_READ(host->base, SYSCTL); | 621 | regval = OMAP_HSMMC_READ(host->base, SYSCTL); |
625 | regval = regval & ~(CLKD_MASK | DTO_MASK); | 622 | regval = regval & ~(CLKD_MASK | DTO_MASK); |
626 | regval = regval | (calc_divisor(ios) << 6) | (DTO << 16); | 623 | regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16); |
627 | OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); | 624 | OMAP_HSMMC_WRITE(host->base, SYSCTL, regval); |
628 | OMAP_HSMMC_WRITE(host->base, SYSCTL, | 625 | OMAP_HSMMC_WRITE(host->base, SYSCTL, |
629 | OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); | 626 | OMAP_HSMMC_READ(host->base, SYSCTL) | ICE); |
@@ -1280,17 +1277,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host) | |||
1280 | } | 1277 | } |
1281 | 1278 | ||
1282 | /* | 1279 | /* |
1283 | * Work Item to notify the core about card insertion/removal | 1280 | * irq handler to notify the core about card insertion/removal |
1284 | */ | 1281 | */ |
1285 | static void omap_hsmmc_detect(struct work_struct *work) | 1282 | static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id) |
1286 | { | 1283 | { |
1287 | struct omap_hsmmc_host *host = | 1284 | struct omap_hsmmc_host *host = dev_id; |
1288 | container_of(work, struct omap_hsmmc_host, mmc_carddetect_work); | ||
1289 | struct omap_mmc_slot_data *slot = &mmc_slot(host); | 1285 | struct omap_mmc_slot_data *slot = &mmc_slot(host); |
1290 | int carddetect; | 1286 | int carddetect; |
1291 | 1287 | ||
1292 | if (host->suspended) | 1288 | if (host->suspended) |
1293 | return; | 1289 | return IRQ_HANDLED; |
1294 | 1290 | ||
1295 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); | 1291 | sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch"); |
1296 | 1292 | ||
@@ -1305,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work) | |||
1305 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); | 1301 | mmc_detect_change(host->mmc, (HZ * 200) / 1000); |
1306 | else | 1302 | else |
1307 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); | 1303 | mmc_detect_change(host->mmc, (HZ * 50) / 1000); |
1308 | } | ||
1309 | |||
1310 | /* | ||
1311 | * ISR for handling card insertion and removal | ||
1312 | */ | ||
1313 | static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id) | ||
1314 | { | ||
1315 | struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id; | ||
1316 | |||
1317 | if (host->suspended) | ||
1318 | return IRQ_HANDLED; | ||
1319 | schedule_work(&host->mmc_carddetect_work); | ||
1320 | |||
1321 | return IRQ_HANDLED; | 1304 | return IRQ_HANDLED; |
1322 | } | 1305 | } |
1323 | 1306 | ||
@@ -1919,7 +1902,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
1919 | host->next_data.cookie = 1; | 1902 | host->next_data.cookie = 1; |
1920 | 1903 | ||
1921 | platform_set_drvdata(pdev, host); | 1904 | platform_set_drvdata(pdev, host); |
1922 | INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect); | ||
1923 | 1905 | ||
1924 | mmc->ops = &omap_hsmmc_ops; | 1906 | mmc->ops = &omap_hsmmc_ops; |
1925 | 1907 | ||
@@ -2049,10 +2031,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev) | |||
2049 | 2031 | ||
2050 | /* Request IRQ for card detect */ | 2032 | /* Request IRQ for card detect */ |
2051 | if ((mmc_slot(host).card_detect_irq)) { | 2033 | if ((mmc_slot(host).card_detect_irq)) { |
2052 | ret = request_irq(mmc_slot(host).card_detect_irq, | 2034 | ret = request_threaded_irq(mmc_slot(host).card_detect_irq, |
2053 | omap_hsmmc_cd_handler, | 2035 | NULL, |
2054 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 2036 | omap_hsmmc_detect, |
2055 | mmc_hostname(mmc), host); | 2037 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
2038 | mmc_hostname(mmc), host); | ||
2056 | if (ret) { | 2039 | if (ret) { |
2057 | dev_dbg(mmc_dev(host->mmc), | 2040 | dev_dbg(mmc_dev(host->mmc), |
2058 | "Unable to grab MMC CD IRQ\n"); | 2041 | "Unable to grab MMC CD IRQ\n"); |
@@ -2131,7 +2114,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev) | |||
2131 | free_irq(host->irq, host); | 2114 | free_irq(host->irq, host); |
2132 | if (mmc_slot(host).card_detect_irq) | 2115 | if (mmc_slot(host).card_detect_irq) |
2133 | free_irq(mmc_slot(host).card_detect_irq, host); | 2116 | free_irq(mmc_slot(host).card_detect_irq, host); |
2134 | flush_work_sync(&host->mmc_carddetect_work); | ||
2135 | 2117 | ||
2136 | pm_runtime_put_sync(host->dev); | 2118 | pm_runtime_put_sync(host->dev); |
2137 | pm_runtime_disable(host->dev); | 2119 | pm_runtime_disable(host->dev); |
@@ -2178,7 +2160,6 @@ static int omap_hsmmc_suspend(struct device *dev) | |||
2178 | return ret; | 2160 | return ret; |
2179 | } | 2161 | } |
2180 | } | 2162 | } |
2181 | cancel_work_sync(&host->mmc_carddetect_work); | ||
2182 | ret = mmc_suspend_host(host->mmc); | 2163 | ret = mmc_suspend_host(host->mmc); |
2183 | 2164 | ||
2184 | if (ret) { | 2165 | if (ret) { |
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c index fc4356e00d46..cb2dc0e75ba7 100644 --- a/drivers/mmc/host/pxamci.c +++ b/drivers/mmc/host/pxamci.c | |||
@@ -872,18 +872,7 @@ static struct platform_driver pxamci_driver = { | |||
872 | }, | 872 | }, |
873 | }; | 873 | }; |
874 | 874 | ||
875 | static int __init pxamci_init(void) | 875 | module_platform_driver(pxamci_driver); |
876 | { | ||
877 | return platform_driver_register(&pxamci_driver); | ||
878 | } | ||
879 | |||
880 | static void __exit pxamci_exit(void) | ||
881 | { | ||
882 | platform_driver_unregister(&pxamci_driver); | ||
883 | } | ||
884 | |||
885 | module_init(pxamci_init); | ||
886 | module_exit(pxamci_exit); | ||
887 | 876 | ||
888 | MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver"); | 877 | MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver"); |
889 | MODULE_LICENSE("GPL"); | 878 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c index 720f99334a7f..1bcfd6dbb5cc 100644 --- a/drivers/mmc/host/s3cmci.c +++ b/drivers/mmc/host/s3cmci.c | |||
@@ -1914,18 +1914,7 @@ static struct platform_driver s3cmci_driver = { | |||
1914 | .shutdown = s3cmci_shutdown, | 1914 | .shutdown = s3cmci_shutdown, |
1915 | }; | 1915 | }; |
1916 | 1916 | ||
1917 | static int __init s3cmci_init(void) | 1917 | module_platform_driver(s3cmci_driver); |
1918 | { | ||
1919 | return platform_driver_register(&s3cmci_driver); | ||
1920 | } | ||
1921 | |||
1922 | static void __exit s3cmci_exit(void) | ||
1923 | { | ||
1924 | platform_driver_unregister(&s3cmci_driver); | ||
1925 | } | ||
1926 | |||
1927 | module_init(s3cmci_init); | ||
1928 | module_exit(s3cmci_exit); | ||
1929 | 1918 | ||
1930 | MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); | 1919 | MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver"); |
1931 | MODULE_LICENSE("GPL v2"); | 1920 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c index b4257e700617..28a870804f60 100644 --- a/drivers/mmc/host/sdhci-cns3xxx.c +++ b/drivers/mmc/host/sdhci-cns3xxx.c | |||
@@ -115,17 +115,7 @@ static struct platform_driver sdhci_cns3xxx_driver = { | |||
115 | .remove = __devexit_p(sdhci_cns3xxx_remove), | 115 | .remove = __devexit_p(sdhci_cns3xxx_remove), |
116 | }; | 116 | }; |
117 | 117 | ||
118 | static int __init sdhci_cns3xxx_init(void) | 118 | module_platform_driver(sdhci_cns3xxx_driver); |
119 | { | ||
120 | return platform_driver_register(&sdhci_cns3xxx_driver); | ||
121 | } | ||
122 | module_init(sdhci_cns3xxx_init); | ||
123 | |||
124 | static void __exit sdhci_cns3xxx_exit(void) | ||
125 | { | ||
126 | platform_driver_unregister(&sdhci_cns3xxx_driver); | ||
127 | } | ||
128 | module_exit(sdhci_cns3xxx_exit); | ||
129 | 119 | ||
130 | MODULE_DESCRIPTION("SDHCI driver for CNS3xxx"); | 120 | MODULE_DESCRIPTION("SDHCI driver for CNS3xxx"); |
131 | MODULE_AUTHOR("Scott Shu, " | 121 | MODULE_AUTHOR("Scott Shu, " |
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c index a81312c91f70..46fd1fd1b605 100644 --- a/drivers/mmc/host/sdhci-dove.c +++ b/drivers/mmc/host/sdhci-dove.c | |||
@@ -88,17 +88,7 @@ static struct platform_driver sdhci_dove_driver = { | |||
88 | .remove = __devexit_p(sdhci_dove_remove), | 88 | .remove = __devexit_p(sdhci_dove_remove), |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static int __init sdhci_dove_init(void) | 91 | module_platform_driver(sdhci_dove_driver); |
92 | { | ||
93 | return platform_driver_register(&sdhci_dove_driver); | ||
94 | } | ||
95 | module_init(sdhci_dove_init); | ||
96 | |||
97 | static void __exit sdhci_dove_exit(void) | ||
98 | { | ||
99 | platform_driver_unregister(&sdhci_dove_driver); | ||
100 | } | ||
101 | module_exit(sdhci_dove_exit); | ||
102 | 92 | ||
103 | MODULE_DESCRIPTION("SDHCI driver for Dove"); | 93 | MODULE_DESCRIPTION("SDHCI driver for Dove"); |
104 | MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>, " | 94 | MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>, " |
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index 38ebc4ea259f..d601e41af282 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c | |||
@@ -606,17 +606,7 @@ static struct platform_driver sdhci_esdhc_imx_driver = { | |||
606 | .remove = __devexit_p(sdhci_esdhc_imx_remove), | 606 | .remove = __devexit_p(sdhci_esdhc_imx_remove), |
607 | }; | 607 | }; |
608 | 608 | ||
609 | static int __init sdhci_esdhc_imx_init(void) | 609 | module_platform_driver(sdhci_esdhc_imx_driver); |
610 | { | ||
611 | return platform_driver_register(&sdhci_esdhc_imx_driver); | ||
612 | } | ||
613 | module_init(sdhci_esdhc_imx_init); | ||
614 | |||
615 | static void __exit sdhci_esdhc_imx_exit(void) | ||
616 | { | ||
617 | platform_driver_unregister(&sdhci_esdhc_imx_driver); | ||
618 | } | ||
619 | module_exit(sdhci_esdhc_imx_exit); | ||
620 | 610 | ||
621 | MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC"); | 611 | MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC"); |
622 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); | 612 | MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>"); |
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h index c3b08f111942..b97b2f5dafdb 100644 --- a/drivers/mmc/host/sdhci-esdhc.h +++ b/drivers/mmc/host/sdhci-esdhc.h | |||
@@ -73,7 +73,7 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock) | |||
73 | | (div << ESDHC_DIVIDER_SHIFT) | 73 | | (div << ESDHC_DIVIDER_SHIFT) |
74 | | (pre_div << ESDHC_PREDIV_SHIFT)); | 74 | | (pre_div << ESDHC_PREDIV_SHIFT)); |
75 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); | 75 | sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL); |
76 | mdelay(100); | 76 | mdelay(1); |
77 | out: | 77 | out: |
78 | host->clock = clock; | 78 | host->clock = clock; |
79 | } | 79 | } |
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 01e5f627e0f0..ff4adc018041 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c | |||
@@ -131,17 +131,7 @@ static struct platform_driver sdhci_esdhc_driver = { | |||
131 | .remove = __devexit_p(sdhci_esdhc_remove), | 131 | .remove = __devexit_p(sdhci_esdhc_remove), |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static int __init sdhci_esdhc_init(void) | 134 | module_platform_driver(sdhci_esdhc_driver); |
135 | { | ||
136 | return platform_driver_register(&sdhci_esdhc_driver); | ||
137 | } | ||
138 | module_init(sdhci_esdhc_init); | ||
139 | |||
140 | static void __exit sdhci_esdhc_exit(void) | ||
141 | { | ||
142 | platform_driver_unregister(&sdhci_esdhc_driver); | ||
143 | } | ||
144 | module_exit(sdhci_esdhc_exit); | ||
145 | 135 | ||
146 | MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC"); | 136 | MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC"); |
147 | MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, " | 137 | MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, " |
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c index 3619adc7d9fc..0ce088ae0228 100644 --- a/drivers/mmc/host/sdhci-of-hlwd.c +++ b/drivers/mmc/host/sdhci-of-hlwd.c | |||
@@ -93,17 +93,7 @@ static struct platform_driver sdhci_hlwd_driver = { | |||
93 | .remove = __devexit_p(sdhci_hlwd_remove), | 93 | .remove = __devexit_p(sdhci_hlwd_remove), |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static int __init sdhci_hlwd_init(void) | 96 | module_platform_driver(sdhci_hlwd_driver); |
97 | { | ||
98 | return platform_driver_register(&sdhci_hlwd_driver); | ||
99 | } | ||
100 | module_init(sdhci_hlwd_init); | ||
101 | |||
102 | static void __exit sdhci_hlwd_exit(void) | ||
103 | { | ||
104 | platform_driver_unregister(&sdhci_hlwd_driver); | ||
105 | } | ||
106 | module_exit(sdhci_hlwd_exit); | ||
107 | 97 | ||
108 | MODULE_DESCRIPTION("Nintendo Wii SDHCI OF driver"); | 98 | MODULE_DESCRIPTION("Nintendo Wii SDHCI OF driver"); |
109 | MODULE_AUTHOR("The GameCube Linux Team, Albert Herranz"); | 99 | MODULE_AUTHOR("The GameCube Linux Team, Albert Herranz"); |
diff --git a/drivers/mmc/host/sdhci-pci-data.c b/drivers/mmc/host/sdhci-pci-data.c new file mode 100644 index 000000000000..a611217769f5 --- /dev/null +++ b/drivers/mmc/host/sdhci-pci-data.c | |||
@@ -0,0 +1,5 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/mmc/sdhci-pci-data.h> | ||
3 | |||
4 | struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, int slotno); | ||
5 | EXPORT_SYMBOL_GPL(sdhci_pci_get_data); | ||
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 6878a94626bc..7165e6a09274 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c | |||
@@ -23,8 +23,8 @@ | |||
23 | #include <linux/scatterlist.h> | 23 | #include <linux/scatterlist.h> |
24 | #include <linux/io.h> | 24 | #include <linux/io.h> |
25 | #include <linux/gpio.h> | 25 | #include <linux/gpio.h> |
26 | #include <linux/sfi.h> | ||
27 | #include <linux/pm_runtime.h> | 26 | #include <linux/pm_runtime.h> |
27 | #include <linux/mmc/sdhci-pci-data.h> | ||
28 | 28 | ||
29 | #include "sdhci.h" | 29 | #include "sdhci.h" |
30 | 30 | ||
@@ -61,6 +61,7 @@ struct sdhci_pci_fixes { | |||
61 | struct sdhci_pci_slot { | 61 | struct sdhci_pci_slot { |
62 | struct sdhci_pci_chip *chip; | 62 | struct sdhci_pci_chip *chip; |
63 | struct sdhci_host *host; | 63 | struct sdhci_host *host; |
64 | struct sdhci_pci_data *data; | ||
64 | 65 | ||
65 | int pci_bar; | 66 | int pci_bar; |
66 | int rst_n_gpio; | 67 | int rst_n_gpio; |
@@ -171,32 +172,9 @@ static int mrst_hc_probe(struct sdhci_pci_chip *chip) | |||
171 | return 0; | 172 | return 0; |
172 | } | 173 | } |
173 | 174 | ||
174 | /* Medfield eMMC hardware reset GPIOs */ | ||
175 | static int mfd_emmc0_rst_gpio = -EINVAL; | ||
176 | static int mfd_emmc1_rst_gpio = -EINVAL; | ||
177 | |||
178 | static int mfd_emmc_gpio_parse(struct sfi_table_header *table) | ||
179 | { | ||
180 | struct sfi_table_simple *sb = (struct sfi_table_simple *)table; | ||
181 | struct sfi_gpio_table_entry *entry; | ||
182 | int i, num; | ||
183 | |||
184 | num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry); | ||
185 | entry = (struct sfi_gpio_table_entry *)sb->pentry; | ||
186 | |||
187 | for (i = 0; i < num; i++, entry++) { | ||
188 | if (!strncmp(entry->pin_name, "emmc0_rst", SFI_NAME_LEN)) | ||
189 | mfd_emmc0_rst_gpio = entry->pin_no; | ||
190 | else if (!strncmp(entry->pin_name, "emmc1_rst", SFI_NAME_LEN)) | ||
191 | mfd_emmc1_rst_gpio = entry->pin_no; | ||
192 | } | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | #ifdef CONFIG_PM_RUNTIME | 175 | #ifdef CONFIG_PM_RUNTIME |
198 | 176 | ||
199 | static irqreturn_t mfd_sd_cd(int irq, void *dev_id) | 177 | static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id) |
200 | { | 178 | { |
201 | struct sdhci_pci_slot *slot = dev_id; | 179 | struct sdhci_pci_slot *slot = dev_id; |
202 | struct sdhci_host *host = slot->host; | 180 | struct sdhci_host *host = slot->host; |
@@ -205,15 +183,16 @@ static irqreturn_t mfd_sd_cd(int irq, void *dev_id) | |||
205 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
206 | } | 184 | } |
207 | 185 | ||
208 | #define MFLD_SD_CD_PIN 69 | 186 | static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot) |
209 | |||
210 | static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot) | ||
211 | { | 187 | { |
212 | int err, irq, gpio = MFLD_SD_CD_PIN; | 188 | int err, irq, gpio = slot->cd_gpio; |
213 | 189 | ||
214 | slot->cd_gpio = -EINVAL; | 190 | slot->cd_gpio = -EINVAL; |
215 | slot->cd_irq = -EINVAL; | 191 | slot->cd_irq = -EINVAL; |
216 | 192 | ||
193 | if (!gpio_is_valid(gpio)) | ||
194 | return; | ||
195 | |||
217 | err = gpio_request(gpio, "sd_cd"); | 196 | err = gpio_request(gpio, "sd_cd"); |
218 | if (err < 0) | 197 | if (err < 0) |
219 | goto out; | 198 | goto out; |
@@ -226,72 +205,53 @@ static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot) | |||
226 | if (irq < 0) | 205 | if (irq < 0) |
227 | goto out_free; | 206 | goto out_free; |
228 | 207 | ||
229 | err = request_irq(irq, mfd_sd_cd, IRQF_TRIGGER_RISING | | 208 | err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING | |
230 | IRQF_TRIGGER_FALLING, "sd_cd", slot); | 209 | IRQF_TRIGGER_FALLING, "sd_cd", slot); |
231 | if (err) | 210 | if (err) |
232 | goto out_free; | 211 | goto out_free; |
233 | 212 | ||
234 | slot->cd_gpio = gpio; | 213 | slot->cd_gpio = gpio; |
235 | slot->cd_irq = irq; | 214 | slot->cd_irq = irq; |
236 | slot->host->quirks2 |= SDHCI_QUIRK2_OWN_CARD_DETECTION; | ||
237 | 215 | ||
238 | return 0; | 216 | return; |
239 | 217 | ||
240 | out_free: | 218 | out_free: |
241 | gpio_free(gpio); | 219 | gpio_free(gpio); |
242 | out: | 220 | out: |
243 | dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n"); | 221 | dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n"); |
244 | return 0; | ||
245 | } | 222 | } |
246 | 223 | ||
247 | static void mfd_sd_remove_slot(struct sdhci_pci_slot *slot, int dead) | 224 | static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot) |
248 | { | 225 | { |
249 | if (slot->cd_irq >= 0) | 226 | if (slot->cd_irq >= 0) |
250 | free_irq(slot->cd_irq, slot); | 227 | free_irq(slot->cd_irq, slot); |
251 | gpio_free(slot->cd_gpio); | 228 | if (gpio_is_valid(slot->cd_gpio)) |
229 | gpio_free(slot->cd_gpio); | ||
252 | } | 230 | } |
253 | 231 | ||
254 | #else | 232 | #else |
255 | 233 | ||
256 | #define mfd_sd_probe_slot NULL | 234 | static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot) |
257 | #define mfd_sd_remove_slot NULL | 235 | { |
236 | } | ||
237 | |||
238 | static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot) | ||
239 | { | ||
240 | } | ||
258 | 241 | ||
259 | #endif | 242 | #endif |
260 | 243 | ||
261 | static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot) | 244 | static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot) |
262 | { | 245 | { |
263 | const char *name = NULL; | ||
264 | int gpio = -EINVAL; | ||
265 | |||
266 | sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, mfd_emmc_gpio_parse); | ||
267 | |||
268 | switch (slot->chip->pdev->device) { | ||
269 | case PCI_DEVICE_ID_INTEL_MFD_EMMC0: | ||
270 | gpio = mfd_emmc0_rst_gpio; | ||
271 | name = "eMMC0_reset"; | ||
272 | break; | ||
273 | case PCI_DEVICE_ID_INTEL_MFD_EMMC1: | ||
274 | gpio = mfd_emmc1_rst_gpio; | ||
275 | name = "eMMC1_reset"; | ||
276 | break; | ||
277 | } | ||
278 | |||
279 | if (!gpio_request(gpio, name)) { | ||
280 | gpio_direction_output(gpio, 1); | ||
281 | slot->rst_n_gpio = gpio; | ||
282 | slot->host->mmc->caps |= MMC_CAP_HW_RESET; | ||
283 | } | ||
284 | |||
285 | slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE; | 246 | slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE; |
286 | |||
287 | slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC; | 247 | slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC; |
288 | |||
289 | return 0; | 248 | return 0; |
290 | } | 249 | } |
291 | 250 | ||
292 | static void mfd_emmc_remove_slot(struct sdhci_pci_slot *slot, int dead) | 251 | static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot) |
293 | { | 252 | { |
294 | gpio_free(slot->rst_n_gpio); | 253 | slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD; |
254 | return 0; | ||
295 | } | 255 | } |
296 | 256 | ||
297 | static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = { | 257 | static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = { |
@@ -307,20 +267,18 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = { | |||
307 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { | 267 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = { |
308 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 268 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
309 | .allow_runtime_pm = true, | 269 | .allow_runtime_pm = true, |
310 | .probe_slot = mfd_sd_probe_slot, | ||
311 | .remove_slot = mfd_sd_remove_slot, | ||
312 | }; | 270 | }; |
313 | 271 | ||
314 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = { | 272 | static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = { |
315 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 273 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
316 | .allow_runtime_pm = true, | 274 | .allow_runtime_pm = true, |
275 | .probe_slot = mfd_sdio_probe_slot, | ||
317 | }; | 276 | }; |
318 | 277 | ||
319 | static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = { | 278 | static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = { |
320 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, | 279 | .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC, |
321 | .allow_runtime_pm = true, | 280 | .allow_runtime_pm = true, |
322 | .probe_slot = mfd_emmc_probe_slot, | 281 | .probe_slot = mfd_emmc_probe_slot, |
323 | .remove_slot = mfd_emmc_remove_slot, | ||
324 | }; | 282 | }; |
325 | 283 | ||
326 | /* O2Micro extra registers */ | 284 | /* O2Micro extra registers */ |
@@ -1012,11 +970,8 @@ static int sdhci_pci_suspend(struct device *dev) | |||
1012 | 970 | ||
1013 | ret = sdhci_suspend_host(slot->host); | 971 | ret = sdhci_suspend_host(slot->host); |
1014 | 972 | ||
1015 | if (ret) { | 973 | if (ret) |
1016 | for (i--; i >= 0; i--) | 974 | goto err_pci_suspend; |
1017 | sdhci_resume_host(chip->slots[i]->host); | ||
1018 | return ret; | ||
1019 | } | ||
1020 | 975 | ||
1021 | slot_pm_flags = slot->host->mmc->pm_flags; | 976 | slot_pm_flags = slot->host->mmc->pm_flags; |
1022 | if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ) | 977 | if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ) |
@@ -1027,11 +982,8 @@ static int sdhci_pci_suspend(struct device *dev) | |||
1027 | 982 | ||
1028 | if (chip->fixes && chip->fixes->suspend) { | 983 | if (chip->fixes && chip->fixes->suspend) { |
1029 | ret = chip->fixes->suspend(chip); | 984 | ret = chip->fixes->suspend(chip); |
1030 | if (ret) { | 985 | if (ret) |
1031 | for (i = chip->num_slots - 1; i >= 0; i--) | 986 | goto err_pci_suspend; |
1032 | sdhci_resume_host(chip->slots[i]->host); | ||
1033 | return ret; | ||
1034 | } | ||
1035 | } | 987 | } |
1036 | 988 | ||
1037 | pci_save_state(pdev); | 989 | pci_save_state(pdev); |
@@ -1048,6 +1000,11 @@ static int sdhci_pci_suspend(struct device *dev) | |||
1048 | } | 1000 | } |
1049 | 1001 | ||
1050 | return 0; | 1002 | return 0; |
1003 | |||
1004 | err_pci_suspend: | ||
1005 | while (--i >= 0) | ||
1006 | sdhci_resume_host(chip->slots[i]->host); | ||
1007 | return ret; | ||
1051 | } | 1008 | } |
1052 | 1009 | ||
1053 | static int sdhci_pci_resume(struct device *dev) | 1010 | static int sdhci_pci_resume(struct device *dev) |
@@ -1113,23 +1070,22 @@ static int sdhci_pci_runtime_suspend(struct device *dev) | |||
1113 | 1070 | ||
1114 | ret = sdhci_runtime_suspend_host(slot->host); | 1071 | ret = sdhci_runtime_suspend_host(slot->host); |
1115 | 1072 | ||
1116 | if (ret) { | 1073 | if (ret) |
1117 | for (i--; i >= 0; i--) | 1074 | goto err_pci_runtime_suspend; |
1118 | sdhci_runtime_resume_host(chip->slots[i]->host); | ||
1119 | return ret; | ||
1120 | } | ||
1121 | } | 1075 | } |
1122 | 1076 | ||
1123 | if (chip->fixes && chip->fixes->suspend) { | 1077 | if (chip->fixes && chip->fixes->suspend) { |
1124 | ret = chip->fixes->suspend(chip); | 1078 | ret = chip->fixes->suspend(chip); |
1125 | if (ret) { | 1079 | if (ret) |
1126 | for (i = chip->num_slots - 1; i >= 0; i--) | 1080 | goto err_pci_runtime_suspend; |
1127 | sdhci_runtime_resume_host(chip->slots[i]->host); | ||
1128 | return ret; | ||
1129 | } | ||
1130 | } | 1081 | } |
1131 | 1082 | ||
1132 | return 0; | 1083 | return 0; |
1084 | |||
1085 | err_pci_runtime_suspend: | ||
1086 | while (--i >= 0) | ||
1087 | sdhci_runtime_resume_host(chip->slots[i]->host); | ||
1088 | return ret; | ||
1133 | } | 1089 | } |
1134 | 1090 | ||
1135 | static int sdhci_pci_runtime_resume(struct device *dev) | 1091 | static int sdhci_pci_runtime_resume(struct device *dev) |
@@ -1190,11 +1146,12 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = { | |||
1190 | \*****************************************************************************/ | 1146 | \*****************************************************************************/ |
1191 | 1147 | ||
1192 | static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | 1148 | static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( |
1193 | struct pci_dev *pdev, struct sdhci_pci_chip *chip, int bar) | 1149 | struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar, |
1150 | int slotno) | ||
1194 | { | 1151 | { |
1195 | struct sdhci_pci_slot *slot; | 1152 | struct sdhci_pci_slot *slot; |
1196 | struct sdhci_host *host; | 1153 | struct sdhci_host *host; |
1197 | int ret; | 1154 | int ret, bar = first_bar + slotno; |
1198 | 1155 | ||
1199 | if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { | 1156 | if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { |
1200 | dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar); | 1157 | dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar); |
@@ -1228,6 +1185,23 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
1228 | slot->host = host; | 1185 | slot->host = host; |
1229 | slot->pci_bar = bar; | 1186 | slot->pci_bar = bar; |
1230 | slot->rst_n_gpio = -EINVAL; | 1187 | slot->rst_n_gpio = -EINVAL; |
1188 | slot->cd_gpio = -EINVAL; | ||
1189 | |||
1190 | /* Retrieve platform data if there is any */ | ||
1191 | if (*sdhci_pci_get_data) | ||
1192 | slot->data = sdhci_pci_get_data(pdev, slotno); | ||
1193 | |||
1194 | if (slot->data) { | ||
1195 | if (slot->data->setup) { | ||
1196 | ret = slot->data->setup(slot->data); | ||
1197 | if (ret) { | ||
1198 | dev_err(&pdev->dev, "platform setup failed\n"); | ||
1199 | goto free; | ||
1200 | } | ||
1201 | } | ||
1202 | slot->rst_n_gpio = slot->data->rst_n_gpio; | ||
1203 | slot->cd_gpio = slot->data->cd_gpio; | ||
1204 | } | ||
1231 | 1205 | ||
1232 | host->hw_name = "PCI"; | 1206 | host->hw_name = "PCI"; |
1233 | host->ops = &sdhci_pci_ops; | 1207 | host->ops = &sdhci_pci_ops; |
@@ -1238,7 +1212,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
1238 | ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc)); | 1212 | ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc)); |
1239 | if (ret) { | 1213 | if (ret) { |
1240 | dev_err(&pdev->dev, "cannot request region\n"); | 1214 | dev_err(&pdev->dev, "cannot request region\n"); |
1241 | goto free; | 1215 | goto cleanup; |
1242 | } | 1216 | } |
1243 | 1217 | ||
1244 | host->ioaddr = pci_ioremap_bar(pdev, bar); | 1218 | host->ioaddr = pci_ioremap_bar(pdev, bar); |
@@ -1254,15 +1228,30 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot( | |||
1254 | goto unmap; | 1228 | goto unmap; |
1255 | } | 1229 | } |
1256 | 1230 | ||
1231 | if (gpio_is_valid(slot->rst_n_gpio)) { | ||
1232 | if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) { | ||
1233 | gpio_direction_output(slot->rst_n_gpio, 1); | ||
1234 | slot->host->mmc->caps |= MMC_CAP_HW_RESET; | ||
1235 | } else { | ||
1236 | dev_warn(&pdev->dev, "failed to request rst_n_gpio\n"); | ||
1237 | slot->rst_n_gpio = -EINVAL; | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1257 | host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; | 1241 | host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ; |
1258 | 1242 | ||
1259 | ret = sdhci_add_host(host); | 1243 | ret = sdhci_add_host(host); |
1260 | if (ret) | 1244 | if (ret) |
1261 | goto remove; | 1245 | goto remove; |
1262 | 1246 | ||
1247 | sdhci_pci_add_own_cd(slot); | ||
1248 | |||
1263 | return slot; | 1249 | return slot; |
1264 | 1250 | ||
1265 | remove: | 1251 | remove: |
1252 | if (gpio_is_valid(slot->rst_n_gpio)) | ||
1253 | gpio_free(slot->rst_n_gpio); | ||
1254 | |||
1266 | if (chip->fixes && chip->fixes->remove_slot) | 1255 | if (chip->fixes && chip->fixes->remove_slot) |
1267 | chip->fixes->remove_slot(slot, 0); | 1256 | chip->fixes->remove_slot(slot, 0); |
1268 | 1257 | ||
@@ -1272,6 +1261,10 @@ unmap: | |||
1272 | release: | 1261 | release: |
1273 | pci_release_region(pdev, bar); | 1262 | pci_release_region(pdev, bar); |
1274 | 1263 | ||
1264 | cleanup: | ||
1265 | if (slot->data && slot->data->cleanup) | ||
1266 | slot->data->cleanup(slot->data); | ||
1267 | |||
1275 | free: | 1268 | free: |
1276 | sdhci_free_host(host); | 1269 | sdhci_free_host(host); |
1277 | 1270 | ||
@@ -1283,6 +1276,8 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) | |||
1283 | int dead; | 1276 | int dead; |
1284 | u32 scratch; | 1277 | u32 scratch; |
1285 | 1278 | ||
1279 | sdhci_pci_remove_own_cd(slot); | ||
1280 | |||
1286 | dead = 0; | 1281 | dead = 0; |
1287 | scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); | 1282 | scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS); |
1288 | if (scratch == (u32)-1) | 1283 | if (scratch == (u32)-1) |
@@ -1290,9 +1285,15 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot) | |||
1290 | 1285 | ||
1291 | sdhci_remove_host(slot->host, dead); | 1286 | sdhci_remove_host(slot->host, dead); |
1292 | 1287 | ||
1288 | if (gpio_is_valid(slot->rst_n_gpio)) | ||
1289 | gpio_free(slot->rst_n_gpio); | ||
1290 | |||
1293 | if (slot->chip->fixes && slot->chip->fixes->remove_slot) | 1291 | if (slot->chip->fixes && slot->chip->fixes->remove_slot) |
1294 | slot->chip->fixes->remove_slot(slot, dead); | 1292 | slot->chip->fixes->remove_slot(slot, dead); |
1295 | 1293 | ||
1294 | if (slot->data && slot->data->cleanup) | ||
1295 | slot->data->cleanup(slot->data); | ||
1296 | |||
1296 | pci_release_region(slot->chip->pdev, slot->pci_bar); | 1297 | pci_release_region(slot->chip->pdev, slot->pci_bar); |
1297 | 1298 | ||
1298 | sdhci_free_host(slot->host); | 1299 | sdhci_free_host(slot->host); |
@@ -1379,7 +1380,7 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev, | |||
1379 | slots = chip->num_slots; /* Quirk may have changed this */ | 1380 | slots = chip->num_slots; /* Quirk may have changed this */ |
1380 | 1381 | ||
1381 | for (i = 0; i < slots; i++) { | 1382 | for (i = 0; i < slots; i++) { |
1382 | slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i); | 1383 | slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i); |
1383 | if (IS_ERR(slot)) { | 1384 | if (IS_ERR(slot)) { |
1384 | for (i--; i >= 0; i--) | 1385 | for (i--; i >= 0; i--) |
1385 | sdhci_pci_remove_slot(chip->slots[i]); | 1386 | sdhci_pci_remove_slot(chip->slots[i]); |
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c index 7a039c3cb1f1..dbb75bfbcffb 100644 --- a/drivers/mmc/host/sdhci-pxav2.c +++ b/drivers/mmc/host/sdhci-pxav2.c | |||
@@ -223,18 +223,8 @@ static struct platform_driver sdhci_pxav2_driver = { | |||
223 | .probe = sdhci_pxav2_probe, | 223 | .probe = sdhci_pxav2_probe, |
224 | .remove = __devexit_p(sdhci_pxav2_remove), | 224 | .remove = __devexit_p(sdhci_pxav2_remove), |
225 | }; | 225 | }; |
226 | static int __init sdhci_pxav2_init(void) | ||
227 | { | ||
228 | return platform_driver_register(&sdhci_pxav2_driver); | ||
229 | } | ||
230 | |||
231 | static void __exit sdhci_pxav2_exit(void) | ||
232 | { | ||
233 | platform_driver_unregister(&sdhci_pxav2_driver); | ||
234 | } | ||
235 | 226 | ||
236 | module_init(sdhci_pxav2_init); | 227 | module_platform_driver(sdhci_pxav2_driver); |
237 | module_exit(sdhci_pxav2_exit); | ||
238 | 228 | ||
239 | MODULE_DESCRIPTION("SDHCI driver for pxav2"); | 229 | MODULE_DESCRIPTION("SDHCI driver for pxav2"); |
240 | MODULE_AUTHOR("Marvell International Ltd."); | 230 | MODULE_AUTHOR("Marvell International Ltd."); |
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index 15673a7ee6a5..f29695683556 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c | |||
@@ -269,18 +269,8 @@ static struct platform_driver sdhci_pxav3_driver = { | |||
269 | .probe = sdhci_pxav3_probe, | 269 | .probe = sdhci_pxav3_probe, |
270 | .remove = __devexit_p(sdhci_pxav3_remove), | 270 | .remove = __devexit_p(sdhci_pxav3_remove), |
271 | }; | 271 | }; |
272 | static int __init sdhci_pxav3_init(void) | ||
273 | { | ||
274 | return platform_driver_register(&sdhci_pxav3_driver); | ||
275 | } | ||
276 | |||
277 | static void __exit sdhci_pxav3_exit(void) | ||
278 | { | ||
279 | platform_driver_unregister(&sdhci_pxav3_driver); | ||
280 | } | ||
281 | 272 | ||
282 | module_init(sdhci_pxav3_init); | 273 | module_platform_driver(sdhci_pxav3_driver); |
283 | module_exit(sdhci_pxav3_exit); | ||
284 | 274 | ||
285 | MODULE_DESCRIPTION("SDHCI driver for pxav3"); | 275 | MODULE_DESCRIPTION("SDHCI driver for pxav3"); |
286 | MODULE_AUTHOR("Marvell International Ltd."); | 276 | MODULE_AUTHOR("Marvell International Ltd."); |
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c index 9a20d1f55bb7..1af756ee0f9a 100644 --- a/drivers/mmc/host/sdhci-s3c.c +++ b/drivers/mmc/host/sdhci-s3c.c | |||
@@ -80,7 +80,7 @@ static void sdhci_s3c_check_sclk(struct sdhci_host *host) | |||
80 | 80 | ||
81 | tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; | 81 | tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK; |
82 | tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; | 82 | tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT; |
83 | writel(tmp, host->ioaddr + 0x80); | 83 | writel(tmp, host->ioaddr + S3C_SDHCI_CONTROL2); |
84 | } | 84 | } |
85 | } | 85 | } |
86 | 86 | ||
@@ -521,6 +521,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev) | |||
521 | if (pdata->host_caps) | 521 | if (pdata->host_caps) |
522 | host->mmc->caps |= pdata->host_caps; | 522 | host->mmc->caps |= pdata->host_caps; |
523 | 523 | ||
524 | if (pdata->pm_caps) | ||
525 | host->mmc->pm_caps |= pdata->pm_caps; | ||
526 | |||
524 | host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR | | 527 | host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR | |
525 | SDHCI_QUIRK_32BIT_DMA_SIZE); | 528 | SDHCI_QUIRK_32BIT_DMA_SIZE); |
526 | 529 | ||
@@ -654,18 +657,7 @@ static struct platform_driver sdhci_s3c_driver = { | |||
654 | }, | 657 | }, |
655 | }; | 658 | }; |
656 | 659 | ||
657 | static int __init sdhci_s3c_init(void) | 660 | module_platform_driver(sdhci_s3c_driver); |
658 | { | ||
659 | return platform_driver_register(&sdhci_s3c_driver); | ||
660 | } | ||
661 | |||
662 | static void __exit sdhci_s3c_exit(void) | ||
663 | { | ||
664 | platform_driver_unregister(&sdhci_s3c_driver); | ||
665 | } | ||
666 | |||
667 | module_init(sdhci_s3c_init); | ||
668 | module_exit(sdhci_s3c_exit); | ||
669 | 661 | ||
670 | MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue"); | 662 | MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue"); |
671 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | 663 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); |
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c index 63cc8b6a1c9e..b7f8b33c5f19 100644 --- a/drivers/mmc/host/sdhci-spear.c +++ b/drivers/mmc/host/sdhci-spear.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
23 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
24 | #include <linux/pm.h> | ||
24 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
25 | #include <linux/mmc/host.h> | 26 | #include <linux/mmc/host.h> |
26 | #include <linux/mmc/sdhci-spear.h> | 27 | #include <linux/mmc/sdhci-spear.h> |
@@ -271,26 +272,54 @@ static int __devexit sdhci_remove(struct platform_device *pdev) | |||
271 | return 0; | 272 | return 0; |
272 | } | 273 | } |
273 | 274 | ||
275 | #ifdef CONFIG_PM | ||
276 | static int sdhci_suspend(struct device *dev) | ||
277 | { | ||
278 | struct sdhci_host *host = dev_get_drvdata(dev); | ||
279 | struct spear_sdhci *sdhci = dev_get_platdata(dev); | ||
280 | int ret; | ||
281 | |||
282 | ret = sdhci_suspend_host(host); | ||
283 | if (!ret) | ||
284 | clk_disable(sdhci->clk); | ||
285 | |||
286 | return ret; | ||
287 | } | ||
288 | |||
289 | static int sdhci_resume(struct device *dev) | ||
290 | { | ||
291 | struct sdhci_host *host = dev_get_drvdata(dev); | ||
292 | struct spear_sdhci *sdhci = dev_get_platdata(dev); | ||
293 | int ret; | ||
294 | |||
295 | ret = clk_enable(sdhci->clk); | ||
296 | if (ret) { | ||
297 | dev_dbg(dev, "Resume: Error enabling clock\n"); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
301 | return sdhci_resume_host(host); | ||
302 | } | ||
303 | |||
304 | const struct dev_pm_ops sdhci_pm_ops = { | ||
305 | .suspend = sdhci_suspend, | ||
306 | .resume = sdhci_resume, | ||
307 | }; | ||
308 | #endif | ||
309 | |||
274 | static struct platform_driver sdhci_driver = { | 310 | static struct platform_driver sdhci_driver = { |
275 | .driver = { | 311 | .driver = { |
276 | .name = "sdhci", | 312 | .name = "sdhci", |
277 | .owner = THIS_MODULE, | 313 | .owner = THIS_MODULE, |
314 | #ifdef CONFIG_PM | ||
315 | .pm = &sdhci_pm_ops, | ||
316 | #endif | ||
278 | }, | 317 | }, |
279 | .probe = sdhci_probe, | 318 | .probe = sdhci_probe, |
280 | .remove = __devexit_p(sdhci_remove), | 319 | .remove = __devexit_p(sdhci_remove), |
281 | }; | 320 | }; |
282 | 321 | ||
283 | static int __init sdhci_init(void) | 322 | module_platform_driver(sdhci_driver); |
284 | { | ||
285 | return platform_driver_register(&sdhci_driver); | ||
286 | } | ||
287 | module_init(sdhci_init); | ||
288 | |||
289 | static void __exit sdhci_exit(void) | ||
290 | { | ||
291 | platform_driver_unregister(&sdhci_driver); | ||
292 | } | ||
293 | module_exit(sdhci_exit); | ||
294 | 323 | ||
295 | MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); | 324 | MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver"); |
296 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); | 325 | MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>"); |
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index e2e18d3f949c..78a36eba4df0 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c | |||
@@ -324,17 +324,7 @@ static struct platform_driver sdhci_tegra_driver = { | |||
324 | .remove = __devexit_p(sdhci_tegra_remove), | 324 | .remove = __devexit_p(sdhci_tegra_remove), |
325 | }; | 325 | }; |
326 | 326 | ||
327 | static int __init sdhci_tegra_init(void) | 327 | module_platform_driver(sdhci_tegra_driver); |
328 | { | ||
329 | return platform_driver_register(&sdhci_tegra_driver); | ||
330 | } | ||
331 | module_init(sdhci_tegra_init); | ||
332 | |||
333 | static void __exit sdhci_tegra_exit(void) | ||
334 | { | ||
335 | platform_driver_unregister(&sdhci_tegra_driver); | ||
336 | } | ||
337 | module_exit(sdhci_tegra_exit); | ||
338 | 328 | ||
339 | MODULE_DESCRIPTION("SDHCI driver for Tegra"); | 329 | MODULE_DESCRIPTION("SDHCI driver for Tegra"); |
340 | MODULE_AUTHOR(" Google, Inc."); | 330 | MODULE_AUTHOR(" Google, Inc."); |
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 19ed580f2cab..8d66706824a6 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c | |||
@@ -49,7 +49,7 @@ static void sdhci_finish_data(struct sdhci_host *); | |||
49 | 49 | ||
50 | static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); | 50 | static void sdhci_send_command(struct sdhci_host *, struct mmc_command *); |
51 | static void sdhci_finish_command(struct sdhci_host *); | 51 | static void sdhci_finish_command(struct sdhci_host *); |
52 | static int sdhci_execute_tuning(struct mmc_host *mmc); | 52 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode); |
53 | static void sdhci_tuning_timer(unsigned long data); | 53 | static void sdhci_tuning_timer(unsigned long data); |
54 | 54 | ||
55 | #ifdef CONFIG_PM_RUNTIME | 55 | #ifdef CONFIG_PM_RUNTIME |
@@ -146,10 +146,8 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable) | |||
146 | { | 146 | { |
147 | u32 present, irqs; | 147 | u32 present, irqs; |
148 | 148 | ||
149 | if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) | 149 | if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) || |
150 | return; | 150 | !mmc_card_is_removable(host->mmc)) |
151 | |||
152 | if (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION) | ||
153 | return; | 151 | return; |
154 | 152 | ||
155 | present = sdhci_readl(host, SDHCI_PRESENT_STATE) & | 153 | present = sdhci_readl(host, SDHCI_PRESENT_STATE) & |
@@ -214,6 +212,11 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask) | |||
214 | 212 | ||
215 | if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) | 213 | if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET) |
216 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); | 214 | sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier); |
215 | |||
216 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { | ||
217 | if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL)) | ||
218 | host->ops->enable_dma(host); | ||
219 | } | ||
217 | } | 220 | } |
218 | 221 | ||
219 | static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); | 222 | static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios); |
@@ -423,12 +426,12 @@ static void sdhci_transfer_pio(struct sdhci_host *host) | |||
423 | static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) | 426 | static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags) |
424 | { | 427 | { |
425 | local_irq_save(*flags); | 428 | local_irq_save(*flags); |
426 | return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 429 | return kmap_atomic(sg_page(sg)) + sg->offset; |
427 | } | 430 | } |
428 | 431 | ||
429 | static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) | 432 | static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags) |
430 | { | 433 | { |
431 | kunmap_atomic(buffer, KM_BIO_SRC_IRQ); | 434 | kunmap_atomic(buffer); |
432 | local_irq_restore(*flags); | 435 | local_irq_restore(*flags); |
433 | } | 436 | } |
434 | 437 | ||
@@ -1016,7 +1019,8 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd) | |||
1016 | flags |= SDHCI_CMD_INDEX; | 1019 | flags |= SDHCI_CMD_INDEX; |
1017 | 1020 | ||
1018 | /* CMD19 is special in that the Data Present Select should be set */ | 1021 | /* CMD19 is special in that the Data Present Select should be set */ |
1019 | if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK)) | 1022 | if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK || |
1023 | cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) | ||
1020 | flags |= SDHCI_CMD_DATA; | 1024 | flags |= SDHCI_CMD_DATA; |
1021 | 1025 | ||
1022 | sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); | 1026 | sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND); |
@@ -1066,12 +1070,15 @@ static void sdhci_finish_command(struct sdhci_host *host) | |||
1066 | static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | 1070 | static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) |
1067 | { | 1071 | { |
1068 | int div = 0; /* Initialized for compiler warning */ | 1072 | int div = 0; /* Initialized for compiler warning */ |
1073 | int real_div = div, clk_mul = 1; | ||
1069 | u16 clk = 0; | 1074 | u16 clk = 0; |
1070 | unsigned long timeout; | 1075 | unsigned long timeout; |
1071 | 1076 | ||
1072 | if (clock == host->clock) | 1077 | if (clock && clock == host->clock) |
1073 | return; | 1078 | return; |
1074 | 1079 | ||
1080 | host->mmc->actual_clock = 0; | ||
1081 | |||
1075 | if (host->ops->set_clock) { | 1082 | if (host->ops->set_clock) { |
1076 | host->ops->set_clock(host, clock); | 1083 | host->ops->set_clock(host, clock); |
1077 | if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) | 1084 | if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) |
@@ -1109,6 +1116,8 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
1109 | * Control register. | 1116 | * Control register. |
1110 | */ | 1117 | */ |
1111 | clk = SDHCI_PROG_CLOCK_MODE; | 1118 | clk = SDHCI_PROG_CLOCK_MODE; |
1119 | real_div = div; | ||
1120 | clk_mul = host->clk_mul; | ||
1112 | div--; | 1121 | div--; |
1113 | } | 1122 | } |
1114 | } else { | 1123 | } else { |
@@ -1122,6 +1131,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
1122 | break; | 1131 | break; |
1123 | } | 1132 | } |
1124 | } | 1133 | } |
1134 | real_div = div; | ||
1125 | div >>= 1; | 1135 | div >>= 1; |
1126 | } | 1136 | } |
1127 | } else { | 1137 | } else { |
@@ -1130,9 +1140,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) | |||
1130 | if ((host->max_clk / div) <= clock) | 1140 | if ((host->max_clk / div) <= clock) |
1131 | break; | 1141 | break; |
1132 | } | 1142 | } |
1143 | real_div = div; | ||
1133 | div >>= 1; | 1144 | div >>= 1; |
1134 | } | 1145 | } |
1135 | 1146 | ||
1147 | if (real_div) | ||
1148 | host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div; | ||
1149 | |||
1136 | clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; | 1150 | clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; |
1137 | clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) | 1151 | clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) |
1138 | << SDHCI_DIVIDER_HI_SHIFT; | 1152 | << SDHCI_DIVIDER_HI_SHIFT; |
@@ -1160,7 +1174,7 @@ out: | |||
1160 | host->clock = clock; | 1174 | host->clock = clock; |
1161 | } | 1175 | } |
1162 | 1176 | ||
1163 | static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | 1177 | static int sdhci_set_power(struct sdhci_host *host, unsigned short power) |
1164 | { | 1178 | { |
1165 | u8 pwr = 0; | 1179 | u8 pwr = 0; |
1166 | 1180 | ||
@@ -1183,13 +1197,13 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
1183 | } | 1197 | } |
1184 | 1198 | ||
1185 | if (host->pwr == pwr) | 1199 | if (host->pwr == pwr) |
1186 | return; | 1200 | return -1; |
1187 | 1201 | ||
1188 | host->pwr = pwr; | 1202 | host->pwr = pwr; |
1189 | 1203 | ||
1190 | if (pwr == 0) { | 1204 | if (pwr == 0) { |
1191 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); | 1205 | sdhci_writeb(host, 0, SDHCI_POWER_CONTROL); |
1192 | return; | 1206 | return 0; |
1193 | } | 1207 | } |
1194 | 1208 | ||
1195 | /* | 1209 | /* |
@@ -1216,6 +1230,8 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) | |||
1216 | */ | 1230 | */ |
1217 | if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) | 1231 | if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER) |
1218 | mdelay(10); | 1232 | mdelay(10); |
1233 | |||
1234 | return power; | ||
1219 | } | 1235 | } |
1220 | 1236 | ||
1221 | /*****************************************************************************\ | 1237 | /*****************************************************************************\ |
@@ -1277,7 +1293,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1277 | if ((host->flags & SDHCI_NEEDS_RETUNING) && | 1293 | if ((host->flags & SDHCI_NEEDS_RETUNING) && |
1278 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { | 1294 | !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) { |
1279 | spin_unlock_irqrestore(&host->lock, flags); | 1295 | spin_unlock_irqrestore(&host->lock, flags); |
1280 | sdhci_execute_tuning(mmc); | 1296 | sdhci_execute_tuning(mmc, mrq->cmd->opcode); |
1281 | spin_lock_irqsave(&host->lock, flags); | 1297 | spin_lock_irqsave(&host->lock, flags); |
1282 | 1298 | ||
1283 | /* Restore original mmc_request structure */ | 1299 | /* Restore original mmc_request structure */ |
@@ -1297,12 +1313,17 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
1297 | static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | 1313 | static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) |
1298 | { | 1314 | { |
1299 | unsigned long flags; | 1315 | unsigned long flags; |
1316 | int vdd_bit = -1; | ||
1300 | u8 ctrl; | 1317 | u8 ctrl; |
1301 | 1318 | ||
1302 | spin_lock_irqsave(&host->lock, flags); | 1319 | spin_lock_irqsave(&host->lock, flags); |
1303 | 1320 | ||
1304 | if (host->flags & SDHCI_DEVICE_DEAD) | 1321 | if (host->flags & SDHCI_DEVICE_DEAD) { |
1305 | goto out; | 1322 | spin_unlock_irqrestore(&host->lock, flags); |
1323 | if (host->vmmc && ios->power_mode == MMC_POWER_OFF) | ||
1324 | mmc_regulator_set_ocr(host->mmc, host->vmmc, 0); | ||
1325 | return; | ||
1326 | } | ||
1306 | 1327 | ||
1307 | /* | 1328 | /* |
1308 | * Reset the chip on each power off. | 1329 | * Reset the chip on each power off. |
@@ -1316,9 +1337,15 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
1316 | sdhci_set_clock(host, ios->clock); | 1337 | sdhci_set_clock(host, ios->clock); |
1317 | 1338 | ||
1318 | if (ios->power_mode == MMC_POWER_OFF) | 1339 | if (ios->power_mode == MMC_POWER_OFF) |
1319 | sdhci_set_power(host, -1); | 1340 | vdd_bit = sdhci_set_power(host, -1); |
1320 | else | 1341 | else |
1321 | sdhci_set_power(host, ios->vdd); | 1342 | vdd_bit = sdhci_set_power(host, ios->vdd); |
1343 | |||
1344 | if (host->vmmc && vdd_bit != -1) { | ||
1345 | spin_unlock_irqrestore(&host->lock, flags); | ||
1346 | mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit); | ||
1347 | spin_lock_irqsave(&host->lock, flags); | ||
1348 | } | ||
1322 | 1349 | ||
1323 | if (host->ops->platform_send_init_74_clocks) | 1350 | if (host->ops->platform_send_init_74_clocks) |
1324 | host->ops->platform_send_init_74_clocks(host, ios->power_mode); | 1351 | host->ops->platform_send_init_74_clocks(host, ios->power_mode); |
@@ -1361,11 +1388,11 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
1361 | unsigned int clock; | 1388 | unsigned int clock; |
1362 | 1389 | ||
1363 | /* In case of UHS-I modes, set High Speed Enable */ | 1390 | /* In case of UHS-I modes, set High Speed Enable */ |
1364 | if ((ios->timing == MMC_TIMING_UHS_SDR50) || | 1391 | if ((ios->timing == MMC_TIMING_MMC_HS200) || |
1392 | (ios->timing == MMC_TIMING_UHS_SDR50) || | ||
1365 | (ios->timing == MMC_TIMING_UHS_SDR104) || | 1393 | (ios->timing == MMC_TIMING_UHS_SDR104) || |
1366 | (ios->timing == MMC_TIMING_UHS_DDR50) || | 1394 | (ios->timing == MMC_TIMING_UHS_DDR50) || |
1367 | (ios->timing == MMC_TIMING_UHS_SDR25) || | 1395 | (ios->timing == MMC_TIMING_UHS_SDR25)) |
1368 | (ios->timing == MMC_TIMING_UHS_SDR12)) | ||
1369 | ctrl |= SDHCI_CTRL_HISPD; | 1396 | ctrl |= SDHCI_CTRL_HISPD; |
1370 | 1397 | ||
1371 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1398 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
@@ -1415,7 +1442,9 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
1415 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1442 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
1416 | /* Select Bus Speed Mode for host */ | 1443 | /* Select Bus Speed Mode for host */ |
1417 | ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; | 1444 | ctrl_2 &= ~SDHCI_CTRL_UHS_MASK; |
1418 | if (ios->timing == MMC_TIMING_UHS_SDR12) | 1445 | if (ios->timing == MMC_TIMING_MMC_HS200) |
1446 | ctrl_2 |= SDHCI_CTRL_HS_SDR200; | ||
1447 | else if (ios->timing == MMC_TIMING_UHS_SDR12) | ||
1419 | ctrl_2 |= SDHCI_CTRL_UHS_SDR12; | 1448 | ctrl_2 |= SDHCI_CTRL_UHS_SDR12; |
1420 | else if (ios->timing == MMC_TIMING_UHS_SDR25) | 1449 | else if (ios->timing == MMC_TIMING_UHS_SDR25) |
1421 | ctrl_2 |= SDHCI_CTRL_UHS_SDR25; | 1450 | ctrl_2 |= SDHCI_CTRL_UHS_SDR25; |
@@ -1443,7 +1472,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios) | |||
1443 | if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) | 1472 | if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS) |
1444 | sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); | 1473 | sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA); |
1445 | 1474 | ||
1446 | out: | ||
1447 | mmiowb(); | 1475 | mmiowb(); |
1448 | spin_unlock_irqrestore(&host->lock, flags); | 1476 | spin_unlock_irqrestore(&host->lock, flags); |
1449 | } | 1477 | } |
@@ -1663,7 +1691,7 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc, | |||
1663 | return err; | 1691 | return err; |
1664 | } | 1692 | } |
1665 | 1693 | ||
1666 | static int sdhci_execute_tuning(struct mmc_host *mmc) | 1694 | static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode) |
1667 | { | 1695 | { |
1668 | struct sdhci_host *host; | 1696 | struct sdhci_host *host; |
1669 | u16 ctrl; | 1697 | u16 ctrl; |
@@ -1671,6 +1699,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) | |||
1671 | int tuning_loop_counter = MAX_TUNING_LOOP; | 1699 | int tuning_loop_counter = MAX_TUNING_LOOP; |
1672 | unsigned long timeout; | 1700 | unsigned long timeout; |
1673 | int err = 0; | 1701 | int err = 0; |
1702 | bool requires_tuning_nonuhs = false; | ||
1674 | 1703 | ||
1675 | host = mmc_priv(mmc); | 1704 | host = mmc_priv(mmc); |
1676 | 1705 | ||
@@ -1681,13 +1710,19 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) | |||
1681 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 1710 | ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
1682 | 1711 | ||
1683 | /* | 1712 | /* |
1684 | * Host Controller needs tuning only in case of SDR104 mode | 1713 | * The Host Controller needs tuning only in case of SDR104 mode |
1685 | * and for SDR50 mode when Use Tuning for SDR50 is set in | 1714 | * and for SDR50 mode when Use Tuning for SDR50 is set in the |
1686 | * Capabilities register. | 1715 | * Capabilities register. |
1716 | * If the Host Controller supports the HS200 mode then the | ||
1717 | * tuning function has to be executed. | ||
1687 | */ | 1718 | */ |
1719 | if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) && | ||
1720 | (host->flags & SDHCI_SDR50_NEEDS_TUNING || | ||
1721 | host->flags & SDHCI_HS200_NEEDS_TUNING)) | ||
1722 | requires_tuning_nonuhs = true; | ||
1723 | |||
1688 | if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) || | 1724 | if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) || |
1689 | (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) && | 1725 | requires_tuning_nonuhs) |
1690 | (host->flags & SDHCI_SDR50_NEEDS_TUNING))) | ||
1691 | ctrl |= SDHCI_CTRL_EXEC_TUNING; | 1726 | ctrl |= SDHCI_CTRL_EXEC_TUNING; |
1692 | else { | 1727 | else { |
1693 | spin_unlock(&host->lock); | 1728 | spin_unlock(&host->lock); |
@@ -1723,7 +1758,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) | |||
1723 | if (!tuning_loop_counter && !timeout) | 1758 | if (!tuning_loop_counter && !timeout) |
1724 | break; | 1759 | break; |
1725 | 1760 | ||
1726 | cmd.opcode = MMC_SEND_TUNING_BLOCK; | 1761 | cmd.opcode = opcode; |
1727 | cmd.arg = 0; | 1762 | cmd.arg = 0; |
1728 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; | 1763 | cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC; |
1729 | cmd.retries = 0; | 1764 | cmd.retries = 0; |
@@ -1738,7 +1773,17 @@ static int sdhci_execute_tuning(struct mmc_host *mmc) | |||
1738 | * block to the Host Controller. So we set the block size | 1773 | * block to the Host Controller. So we set the block size |
1739 | * to 64 here. | 1774 | * to 64 here. |
1740 | */ | 1775 | */ |
1741 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE); | 1776 | if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200) { |
1777 | if (mmc->ios.bus_width == MMC_BUS_WIDTH_8) | ||
1778 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128), | ||
1779 | SDHCI_BLOCK_SIZE); | ||
1780 | else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4) | ||
1781 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), | ||
1782 | SDHCI_BLOCK_SIZE); | ||
1783 | } else { | ||
1784 | sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), | ||
1785 | SDHCI_BLOCK_SIZE); | ||
1786 | } | ||
1742 | 1787 | ||
1743 | /* | 1788 | /* |
1744 | * The tuning block is sent by the card to the host controller. | 1789 | * The tuning block is sent by the card to the host controller. |
@@ -2121,12 +2166,14 @@ static void sdhci_show_adma_error(struct sdhci_host *host) { } | |||
2121 | 2166 | ||
2122 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) | 2167 | static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) |
2123 | { | 2168 | { |
2169 | u32 command; | ||
2124 | BUG_ON(intmask == 0); | 2170 | BUG_ON(intmask == 0); |
2125 | 2171 | ||
2126 | /* CMD19 generates _only_ Buffer Read Ready interrupt */ | 2172 | /* CMD19 generates _only_ Buffer Read Ready interrupt */ |
2127 | if (intmask & SDHCI_INT_DATA_AVAIL) { | 2173 | if (intmask & SDHCI_INT_DATA_AVAIL) { |
2128 | if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) == | 2174 | command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)); |
2129 | MMC_SEND_TUNING_BLOCK) { | 2175 | if (command == MMC_SEND_TUNING_BLOCK || |
2176 | command == MMC_SEND_TUNING_BLOCK_HS200) { | ||
2130 | host->tuning_done = 1; | 2177 | host->tuning_done = 1; |
2131 | wake_up(&host->buf_ready_int); | 2178 | wake_up(&host->buf_ready_int); |
2132 | return; | 2179 | return; |
@@ -2330,26 +2377,33 @@ out: | |||
2330 | int sdhci_suspend_host(struct sdhci_host *host) | 2377 | int sdhci_suspend_host(struct sdhci_host *host) |
2331 | { | 2378 | { |
2332 | int ret; | 2379 | int ret; |
2380 | bool has_tuning_timer; | ||
2333 | 2381 | ||
2334 | sdhci_disable_card_detection(host); | 2382 | sdhci_disable_card_detection(host); |
2335 | 2383 | ||
2336 | /* Disable tuning since we are suspending */ | 2384 | /* Disable tuning since we are suspending */ |
2337 | if (host->version >= SDHCI_SPEC_300 && host->tuning_count && | 2385 | has_tuning_timer = host->version >= SDHCI_SPEC_300 && |
2338 | host->tuning_mode == SDHCI_TUNING_MODE_1) { | 2386 | host->tuning_count && host->tuning_mode == SDHCI_TUNING_MODE_1; |
2387 | if (has_tuning_timer) { | ||
2388 | del_timer_sync(&host->tuning_timer); | ||
2339 | host->flags &= ~SDHCI_NEEDS_RETUNING; | 2389 | host->flags &= ~SDHCI_NEEDS_RETUNING; |
2340 | mod_timer(&host->tuning_timer, jiffies + | ||
2341 | host->tuning_count * HZ); | ||
2342 | } | 2390 | } |
2343 | 2391 | ||
2344 | ret = mmc_suspend_host(host->mmc); | 2392 | ret = mmc_suspend_host(host->mmc); |
2345 | if (ret) | 2393 | if (ret) { |
2394 | if (has_tuning_timer) { | ||
2395 | host->flags |= SDHCI_NEEDS_RETUNING; | ||
2396 | mod_timer(&host->tuning_timer, jiffies + | ||
2397 | host->tuning_count * HZ); | ||
2398 | } | ||
2399 | |||
2400 | sdhci_enable_card_detection(host); | ||
2401 | |||
2346 | return ret; | 2402 | return ret; |
2403 | } | ||
2347 | 2404 | ||
2348 | free_irq(host->irq, host); | 2405 | free_irq(host->irq, host); |
2349 | 2406 | ||
2350 | if (host->vmmc) | ||
2351 | ret = regulator_disable(host->vmmc); | ||
2352 | |||
2353 | return ret; | 2407 | return ret; |
2354 | } | 2408 | } |
2355 | 2409 | ||
@@ -2359,12 +2413,6 @@ int sdhci_resume_host(struct sdhci_host *host) | |||
2359 | { | 2413 | { |
2360 | int ret; | 2414 | int ret; |
2361 | 2415 | ||
2362 | if (host->vmmc) { | ||
2363 | int ret = regulator_enable(host->vmmc); | ||
2364 | if (ret) | ||
2365 | return ret; | ||
2366 | } | ||
2367 | |||
2368 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { | 2416 | if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) { |
2369 | if (host->ops->enable_dma) | 2417 | if (host->ops->enable_dma) |
2370 | host->ops->enable_dma(host); | 2418 | host->ops->enable_dma(host); |
@@ -2727,10 +2775,14 @@ int sdhci_add_host(struct sdhci_host *host) | |||
2727 | if (caps[1] & SDHCI_SUPPORT_DDR50) | 2775 | if (caps[1] & SDHCI_SUPPORT_DDR50) |
2728 | mmc->caps |= MMC_CAP_UHS_DDR50; | 2776 | mmc->caps |= MMC_CAP_UHS_DDR50; |
2729 | 2777 | ||
2730 | /* Does the host needs tuning for SDR50? */ | 2778 | /* Does the host need tuning for SDR50? */ |
2731 | if (caps[1] & SDHCI_USE_SDR50_TUNING) | 2779 | if (caps[1] & SDHCI_USE_SDR50_TUNING) |
2732 | host->flags |= SDHCI_SDR50_NEEDS_TUNING; | 2780 | host->flags |= SDHCI_SDR50_NEEDS_TUNING; |
2733 | 2781 | ||
2782 | /* Does the host need tuning for HS200? */ | ||
2783 | if (mmc->caps2 & MMC_CAP2_HS200) | ||
2784 | host->flags |= SDHCI_HS200_NEEDS_TUNING; | ||
2785 | |||
2734 | /* Driver Type(s) (A, C, D) supported by the host */ | 2786 | /* Driver Type(s) (A, C, D) supported by the host */ |
2735 | if (caps[1] & SDHCI_DRIVER_TYPE_A) | 2787 | if (caps[1] & SDHCI_DRIVER_TYPE_A) |
2736 | mmc->caps |= MMC_CAP_DRIVER_TYPE_A; | 2788 | mmc->caps |= MMC_CAP_DRIVER_TYPE_A; |
@@ -2926,8 +2978,6 @@ int sdhci_add_host(struct sdhci_host *host) | |||
2926 | if (IS_ERR(host->vmmc)) { | 2978 | if (IS_ERR(host->vmmc)) { |
2927 | pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); | 2979 | pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc)); |
2928 | host->vmmc = NULL; | 2980 | host->vmmc = NULL; |
2929 | } else { | ||
2930 | regulator_enable(host->vmmc); | ||
2931 | } | 2981 | } |
2932 | 2982 | ||
2933 | sdhci_init(host, 0); | 2983 | sdhci_init(host, 0); |
@@ -3016,10 +3066,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead) | |||
3016 | tasklet_kill(&host->card_tasklet); | 3066 | tasklet_kill(&host->card_tasklet); |
3017 | tasklet_kill(&host->finish_tasklet); | 3067 | tasklet_kill(&host->finish_tasklet); |
3018 | 3068 | ||
3019 | if (host->vmmc) { | 3069 | if (host->vmmc) |
3020 | regulator_disable(host->vmmc); | ||
3021 | regulator_put(host->vmmc); | 3070 | regulator_put(host->vmmc); |
3022 | } | ||
3023 | 3071 | ||
3024 | kfree(host->adma_desc); | 3072 | kfree(host->adma_desc); |
3025 | kfree(host->align_buffer); | 3073 | kfree(host->align_buffer); |
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index a04d4d0c6fd2..ad265b96b75b 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h | |||
@@ -158,6 +158,7 @@ | |||
158 | #define SDHCI_CTRL_UHS_SDR50 0x0002 | 158 | #define SDHCI_CTRL_UHS_SDR50 0x0002 |
159 | #define SDHCI_CTRL_UHS_SDR104 0x0003 | 159 | #define SDHCI_CTRL_UHS_SDR104 0x0003 |
160 | #define SDHCI_CTRL_UHS_DDR50 0x0004 | 160 | #define SDHCI_CTRL_UHS_DDR50 0x0004 |
161 | #define SDHCI_CTRL_HS_SDR200 0x0005 /* reserved value in SDIO spec */ | ||
161 | #define SDHCI_CTRL_VDD_180 0x0008 | 162 | #define SDHCI_CTRL_VDD_180 0x0008 |
162 | #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 | 163 | #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030 |
163 | #define SDHCI_CTRL_DRV_TYPE_B 0x0000 | 164 | #define SDHCI_CTRL_DRV_TYPE_B 0x0000 |
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index d5505f3fe2a1..4a2c5b2355f2 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c | |||
@@ -16,6 +16,33 @@ | |||
16 | * | 16 | * |
17 | */ | 17 | */ |
18 | 18 | ||
19 | /* | ||
20 | * The MMCIF driver is now processing MMC requests asynchronously, according | ||
21 | * to the Linux MMC API requirement. | ||
22 | * | ||
23 | * The MMCIF driver processes MMC requests in up to 3 stages: command, optional | ||
24 | * data, and optional stop. To achieve asynchronous processing each of these | ||
25 | * stages is split into two halves: a top and a bottom half. The top half | ||
26 | * initialises the hardware, installs a timeout handler to handle completion | ||
27 | * timeouts, and returns. In case of the command stage this immediately returns | ||
28 | * control to the caller, leaving all further processing to run asynchronously. | ||
29 | * All further request processing is performed by the bottom halves. | ||
30 | * | ||
31 | * The bottom half further consists of a "hard" IRQ handler, an IRQ handler | ||
32 | * thread, a DMA completion callback, if DMA is used, a timeout work, and | ||
33 | * request- and stage-specific handler methods. | ||
34 | * | ||
35 | * Each bottom half run begins with either a hardware interrupt, a DMA callback | ||
36 | * invocation, or a timeout work run. In case of an error or a successful | ||
37 | * processing completion, the MMC core is informed and the request processing is | ||
38 | * finished. In case processing has to continue, i.e., if data has to be read | ||
39 | * from or written to the card, or if a stop command has to be sent, the next | ||
40 | * top half is called, which performs the necessary hardware handling and | ||
41 | * reschedules the timeout work. This returns the driver state machine into the | ||
42 | * bottom half waiting state. | ||
43 | */ | ||
44 | |||
45 | #include <linux/bitops.h> | ||
19 | #include <linux/clk.h> | 46 | #include <linux/clk.h> |
20 | #include <linux/completion.h> | 47 | #include <linux/completion.h> |
21 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
@@ -123,6 +150,11 @@ | |||
123 | #define MASK_MRBSYTO (1 << 1) | 150 | #define MASK_MRBSYTO (1 << 1) |
124 | #define MASK_MRSPTO (1 << 0) | 151 | #define MASK_MRSPTO (1 << 0) |
125 | 152 | ||
153 | #define MASK_START_CMD (MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | \ | ||
154 | MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | \ | ||
155 | MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \ | ||
156 | MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO) | ||
157 | |||
126 | /* CE_HOST_STS1 */ | 158 | /* CE_HOST_STS1 */ |
127 | #define STS1_CMDSEQ (1 << 31) | 159 | #define STS1_CMDSEQ (1 << 31) |
128 | 160 | ||
@@ -162,9 +194,21 @@ enum mmcif_state { | |||
162 | STATE_IOS, | 194 | STATE_IOS, |
163 | }; | 195 | }; |
164 | 196 | ||
197 | enum mmcif_wait_for { | ||
198 | MMCIF_WAIT_FOR_REQUEST, | ||
199 | MMCIF_WAIT_FOR_CMD, | ||
200 | MMCIF_WAIT_FOR_MREAD, | ||
201 | MMCIF_WAIT_FOR_MWRITE, | ||
202 | MMCIF_WAIT_FOR_READ, | ||
203 | MMCIF_WAIT_FOR_WRITE, | ||
204 | MMCIF_WAIT_FOR_READ_END, | ||
205 | MMCIF_WAIT_FOR_WRITE_END, | ||
206 | MMCIF_WAIT_FOR_STOP, | ||
207 | }; | ||
208 | |||
165 | struct sh_mmcif_host { | 209 | struct sh_mmcif_host { |
166 | struct mmc_host *mmc; | 210 | struct mmc_host *mmc; |
167 | struct mmc_data *data; | 211 | struct mmc_request *mrq; |
168 | struct platform_device *pd; | 212 | struct platform_device *pd; |
169 | struct sh_dmae_slave dma_slave_tx; | 213 | struct sh_dmae_slave dma_slave_tx; |
170 | struct sh_dmae_slave dma_slave_rx; | 214 | struct sh_dmae_slave dma_slave_rx; |
@@ -172,11 +216,17 @@ struct sh_mmcif_host { | |||
172 | unsigned int clk; | 216 | unsigned int clk; |
173 | int bus_width; | 217 | int bus_width; |
174 | bool sd_error; | 218 | bool sd_error; |
219 | bool dying; | ||
175 | long timeout; | 220 | long timeout; |
176 | void __iomem *addr; | 221 | void __iomem *addr; |
177 | struct completion intr_wait; | 222 | u32 *pio_ptr; |
223 | spinlock_t lock; /* protect sh_mmcif_host::state */ | ||
178 | enum mmcif_state state; | 224 | enum mmcif_state state; |
179 | spinlock_t lock; | 225 | enum mmcif_wait_for wait_for; |
226 | struct delayed_work timeout_work; | ||
227 | size_t blocksize; | ||
228 | int sg_idx; | ||
229 | int sg_blkidx; | ||
180 | bool power; | 230 | bool power; |
181 | bool card_present; | 231 | bool card_present; |
182 | 232 | ||
@@ -202,19 +252,21 @@ static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host, | |||
202 | static void mmcif_dma_complete(void *arg) | 252 | static void mmcif_dma_complete(void *arg) |
203 | { | 253 | { |
204 | struct sh_mmcif_host *host = arg; | 254 | struct sh_mmcif_host *host = arg; |
255 | struct mmc_data *data = host->mrq->data; | ||
256 | |||
205 | dev_dbg(&host->pd->dev, "Command completed\n"); | 257 | dev_dbg(&host->pd->dev, "Command completed\n"); |
206 | 258 | ||
207 | if (WARN(!host->data, "%s: NULL data in DMA completion!\n", | 259 | if (WARN(!data, "%s: NULL data in DMA completion!\n", |
208 | dev_name(&host->pd->dev))) | 260 | dev_name(&host->pd->dev))) |
209 | return; | 261 | return; |
210 | 262 | ||
211 | if (host->data->flags & MMC_DATA_READ) | 263 | if (data->flags & MMC_DATA_READ) |
212 | dma_unmap_sg(host->chan_rx->device->dev, | 264 | dma_unmap_sg(host->chan_rx->device->dev, |
213 | host->data->sg, host->data->sg_len, | 265 | data->sg, data->sg_len, |
214 | DMA_FROM_DEVICE); | 266 | DMA_FROM_DEVICE); |
215 | else | 267 | else |
216 | dma_unmap_sg(host->chan_tx->device->dev, | 268 | dma_unmap_sg(host->chan_tx->device->dev, |
217 | host->data->sg, host->data->sg_len, | 269 | data->sg, data->sg_len, |
218 | DMA_TO_DEVICE); | 270 | DMA_TO_DEVICE); |
219 | 271 | ||
220 | complete(&host->dma_complete); | 272 | complete(&host->dma_complete); |
@@ -222,13 +274,14 @@ static void mmcif_dma_complete(void *arg) | |||
222 | 274 | ||
223 | static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) | 275 | static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) |
224 | { | 276 | { |
225 | struct scatterlist *sg = host->data->sg; | 277 | struct mmc_data *data = host->mrq->data; |
278 | struct scatterlist *sg = data->sg; | ||
226 | struct dma_async_tx_descriptor *desc = NULL; | 279 | struct dma_async_tx_descriptor *desc = NULL; |
227 | struct dma_chan *chan = host->chan_rx; | 280 | struct dma_chan *chan = host->chan_rx; |
228 | dma_cookie_t cookie = -EINVAL; | 281 | dma_cookie_t cookie = -EINVAL; |
229 | int ret; | 282 | int ret; |
230 | 283 | ||
231 | ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len, | 284 | ret = dma_map_sg(chan->device->dev, sg, data->sg_len, |
232 | DMA_FROM_DEVICE); | 285 | DMA_FROM_DEVICE); |
233 | if (ret > 0) { | 286 | if (ret > 0) { |
234 | host->dma_active = true; | 287 | host->dma_active = true; |
@@ -244,7 +297,7 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) | |||
244 | dma_async_issue_pending(chan); | 297 | dma_async_issue_pending(chan); |
245 | } | 298 | } |
246 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", | 299 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", |
247 | __func__, host->data->sg_len, ret, cookie); | 300 | __func__, data->sg_len, ret, cookie); |
248 | 301 | ||
249 | if (!desc) { | 302 | if (!desc) { |
250 | /* DMA failed, fall back to PIO */ | 303 | /* DMA failed, fall back to PIO */ |
@@ -265,18 +318,19 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host) | |||
265 | } | 318 | } |
266 | 319 | ||
267 | dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, | 320 | dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__, |
268 | desc, cookie, host->data->sg_len); | 321 | desc, cookie, data->sg_len); |
269 | } | 322 | } |
270 | 323 | ||
271 | static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host) | 324 | static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host) |
272 | { | 325 | { |
273 | struct scatterlist *sg = host->data->sg; | 326 | struct mmc_data *data = host->mrq->data; |
327 | struct scatterlist *sg = data->sg; | ||
274 | struct dma_async_tx_descriptor *desc = NULL; | 328 | struct dma_async_tx_descriptor *desc = NULL; |
275 | struct dma_chan *chan = host->chan_tx; | 329 | struct dma_chan *chan = host->chan_tx; |
276 | dma_cookie_t cookie = -EINVAL; | 330 | dma_cookie_t cookie = -EINVAL; |
277 | int ret; | 331 | int ret; |
278 | 332 | ||
279 | ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len, | 333 | ret = dma_map_sg(chan->device->dev, sg, data->sg_len, |
280 | DMA_TO_DEVICE); | 334 | DMA_TO_DEVICE); |
281 | if (ret > 0) { | 335 | if (ret > 0) { |
282 | host->dma_active = true; | 336 | host->dma_active = true; |
@@ -292,7 +346,7 @@ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host) | |||
292 | dma_async_issue_pending(chan); | 346 | dma_async_issue_pending(chan); |
293 | } | 347 | } |
294 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", | 348 | dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n", |
295 | __func__, host->data->sg_len, ret, cookie); | 349 | __func__, data->sg_len, ret, cookie); |
296 | 350 | ||
297 | if (!desc) { | 351 | if (!desc) { |
298 | /* DMA failed, fall back to PIO */ | 352 | /* DMA failed, fall back to PIO */ |
@@ -399,7 +453,7 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk) | |||
399 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); | 453 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK); |
400 | else | 454 | else |
401 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & | 455 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR & |
402 | (ilog2(__rounddown_pow_of_two(host->clk / clk)) << 16)); | 456 | ((fls(host->clk / clk) - 1) << 16)); |
403 | 457 | ||
404 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); | 458 | sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE); |
405 | } | 459 | } |
@@ -421,7 +475,7 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host) | |||
421 | static int sh_mmcif_error_manage(struct sh_mmcif_host *host) | 475 | static int sh_mmcif_error_manage(struct sh_mmcif_host *host) |
422 | { | 476 | { |
423 | u32 state1, state2; | 477 | u32 state1, state2; |
424 | int ret, timeout = 10000000; | 478 | int ret, timeout; |
425 | 479 | ||
426 | host->sd_error = false; | 480 | host->sd_error = false; |
427 | 481 | ||
@@ -433,155 +487,212 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host) | |||
433 | if (state1 & STS1_CMDSEQ) { | 487 | if (state1 & STS1_CMDSEQ) { |
434 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); | 488 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK); |
435 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK); | 489 | sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK); |
436 | while (1) { | 490 | for (timeout = 10000000; timeout; timeout--) { |
437 | timeout--; | ||
438 | if (timeout < 0) { | ||
439 | dev_err(&host->pd->dev, | ||
440 | "Forceed end of command sequence timeout err\n"); | ||
441 | return -EIO; | ||
442 | } | ||
443 | if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) | 491 | if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1) |
444 | & STS1_CMDSEQ)) | 492 | & STS1_CMDSEQ)) |
445 | break; | 493 | break; |
446 | mdelay(1); | 494 | mdelay(1); |
447 | } | 495 | } |
496 | if (!timeout) { | ||
497 | dev_err(&host->pd->dev, | ||
498 | "Forced end of command sequence timeout err\n"); | ||
499 | return -EIO; | ||
500 | } | ||
448 | sh_mmcif_sync_reset(host); | 501 | sh_mmcif_sync_reset(host); |
449 | dev_dbg(&host->pd->dev, "Forced end of command sequence\n"); | 502 | dev_dbg(&host->pd->dev, "Forced end of command sequence\n"); |
450 | return -EIO; | 503 | return -EIO; |
451 | } | 504 | } |
452 | 505 | ||
453 | if (state2 & STS2_CRC_ERR) { | 506 | if (state2 & STS2_CRC_ERR) { |
454 | dev_dbg(&host->pd->dev, ": Happened CRC error\n"); | 507 | dev_dbg(&host->pd->dev, ": CRC error\n"); |
455 | ret = -EIO; | 508 | ret = -EIO; |
456 | } else if (state2 & STS2_TIMEOUT_ERR) { | 509 | } else if (state2 & STS2_TIMEOUT_ERR) { |
457 | dev_dbg(&host->pd->dev, ": Happened Timeout error\n"); | 510 | dev_dbg(&host->pd->dev, ": Timeout\n"); |
458 | ret = -ETIMEDOUT; | 511 | ret = -ETIMEDOUT; |
459 | } else { | 512 | } else { |
460 | dev_dbg(&host->pd->dev, ": Happened End/Index error\n"); | 513 | dev_dbg(&host->pd->dev, ": End/Index error\n"); |
461 | ret = -EIO; | 514 | ret = -EIO; |
462 | } | 515 | } |
463 | return ret; | 516 | return ret; |
464 | } | 517 | } |
465 | 518 | ||
466 | static int sh_mmcif_single_read(struct sh_mmcif_host *host, | 519 | static bool sh_mmcif_next_block(struct sh_mmcif_host *host, u32 *p) |
467 | struct mmc_request *mrq) | ||
468 | { | 520 | { |
469 | struct mmc_data *data = mrq->data; | 521 | struct mmc_data *data = host->mrq->data; |
470 | long time; | 522 | |
471 | u32 blocksize, i, *p = sg_virt(data->sg); | 523 | host->sg_blkidx += host->blocksize; |
524 | |||
525 | /* data->sg->length must be a multiple of host->blocksize? */ | ||
526 | BUG_ON(host->sg_blkidx > data->sg->length); | ||
527 | |||
528 | if (host->sg_blkidx == data->sg->length) { | ||
529 | host->sg_blkidx = 0; | ||
530 | if (++host->sg_idx < data->sg_len) | ||
531 | host->pio_ptr = sg_virt(++data->sg); | ||
532 | } else { | ||
533 | host->pio_ptr = p; | ||
534 | } | ||
535 | |||
536 | if (host->sg_idx == data->sg_len) | ||
537 | return false; | ||
538 | |||
539 | return true; | ||
540 | } | ||
541 | |||
542 | static void sh_mmcif_single_read(struct sh_mmcif_host *host, | ||
543 | struct mmc_request *mrq) | ||
544 | { | ||
545 | host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) & | ||
546 | BLOCK_SIZE_MASK) + 3; | ||
547 | |||
548 | host->wait_for = MMCIF_WAIT_FOR_READ; | ||
549 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
472 | 550 | ||
473 | /* buf read enable */ | 551 | /* buf read enable */ |
474 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | 552 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); |
475 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 553 | } |
476 | host->timeout); | 554 | |
477 | if (time <= 0 || host->sd_error) | 555 | static bool sh_mmcif_read_block(struct sh_mmcif_host *host) |
478 | return sh_mmcif_error_manage(host); | 556 | { |
479 | 557 | struct mmc_data *data = host->mrq->data; | |
480 | blocksize = (BLOCK_SIZE_MASK & | 558 | u32 *p = sg_virt(data->sg); |
481 | sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; | 559 | int i; |
482 | for (i = 0; i < blocksize / 4; i++) | 560 | |
561 | if (host->sd_error) { | ||
562 | data->error = sh_mmcif_error_manage(host); | ||
563 | return false; | ||
564 | } | ||
565 | |||
566 | for (i = 0; i < host->blocksize / 4; i++) | ||
483 | *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA); | 567 | *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA); |
484 | 568 | ||
485 | /* buffer read end */ | 569 | /* buffer read end */ |
486 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); | 570 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE); |
487 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 571 | host->wait_for = MMCIF_WAIT_FOR_READ_END; |
488 | host->timeout); | ||
489 | if (time <= 0 || host->sd_error) | ||
490 | return sh_mmcif_error_manage(host); | ||
491 | 572 | ||
492 | return 0; | 573 | return true; |
493 | } | 574 | } |
494 | 575 | ||
495 | static int sh_mmcif_multi_read(struct sh_mmcif_host *host, | 576 | static void sh_mmcif_multi_read(struct sh_mmcif_host *host, |
496 | struct mmc_request *mrq) | 577 | struct mmc_request *mrq) |
497 | { | 578 | { |
498 | struct mmc_data *data = mrq->data; | 579 | struct mmc_data *data = mrq->data; |
499 | long time; | 580 | |
500 | u32 blocksize, i, j, sec, *p; | 581 | if (!data->sg_len || !data->sg->length) |
501 | 582 | return; | |
502 | blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr, | 583 | |
503 | MMCIF_CE_BLOCK_SET); | 584 | host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) & |
504 | for (j = 0; j < data->sg_len; j++) { | 585 | BLOCK_SIZE_MASK; |
505 | p = sg_virt(data->sg); | 586 | |
506 | for (sec = 0; sec < data->sg->length / blocksize; sec++) { | 587 | host->wait_for = MMCIF_WAIT_FOR_MREAD; |
507 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | 588 | host->sg_idx = 0; |
508 | /* buf read enable */ | 589 | host->sg_blkidx = 0; |
509 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 590 | host->pio_ptr = sg_virt(data->sg); |
510 | host->timeout); | 591 | schedule_delayed_work(&host->timeout_work, host->timeout); |
511 | 592 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | |
512 | if (time <= 0 || host->sd_error) | 593 | } |
513 | return sh_mmcif_error_manage(host); | 594 | |
514 | 595 | static bool sh_mmcif_mread_block(struct sh_mmcif_host *host) | |
515 | for (i = 0; i < blocksize / 4; i++) | 596 | { |
516 | *p++ = sh_mmcif_readl(host->addr, | 597 | struct mmc_data *data = host->mrq->data; |
517 | MMCIF_CE_DATA); | 598 | u32 *p = host->pio_ptr; |
518 | } | 599 | int i; |
519 | if (j < data->sg_len - 1) | 600 | |
520 | data->sg++; | 601 | if (host->sd_error) { |
602 | data->error = sh_mmcif_error_manage(host); | ||
603 | return false; | ||
521 | } | 604 | } |
522 | return 0; | 605 | |
606 | BUG_ON(!data->sg->length); | ||
607 | |||
608 | for (i = 0; i < host->blocksize / 4; i++) | ||
609 | *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA); | ||
610 | |||
611 | if (!sh_mmcif_next_block(host, p)) | ||
612 | return false; | ||
613 | |||
614 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
615 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN); | ||
616 | |||
617 | return true; | ||
523 | } | 618 | } |
524 | 619 | ||
525 | static int sh_mmcif_single_write(struct sh_mmcif_host *host, | 620 | static void sh_mmcif_single_write(struct sh_mmcif_host *host, |
526 | struct mmc_request *mrq) | 621 | struct mmc_request *mrq) |
527 | { | 622 | { |
528 | struct mmc_data *data = mrq->data; | 623 | host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) & |
529 | long time; | 624 | BLOCK_SIZE_MASK) + 3; |
530 | u32 blocksize, i, *p = sg_virt(data->sg); | ||
531 | 625 | ||
532 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | 626 | host->wait_for = MMCIF_WAIT_FOR_WRITE; |
627 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
533 | 628 | ||
534 | /* buf write enable */ | 629 | /* buf write enable */ |
535 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 630 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); |
536 | host->timeout); | 631 | } |
537 | if (time <= 0 || host->sd_error) | 632 | |
538 | return sh_mmcif_error_manage(host); | 633 | static bool sh_mmcif_write_block(struct sh_mmcif_host *host) |
539 | 634 | { | |
540 | blocksize = (BLOCK_SIZE_MASK & | 635 | struct mmc_data *data = host->mrq->data; |
541 | sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3; | 636 | u32 *p = sg_virt(data->sg); |
542 | for (i = 0; i < blocksize / 4; i++) | 637 | int i; |
638 | |||
639 | if (host->sd_error) { | ||
640 | data->error = sh_mmcif_error_manage(host); | ||
641 | return false; | ||
642 | } | ||
643 | |||
644 | for (i = 0; i < host->blocksize / 4; i++) | ||
543 | sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++); | 645 | sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++); |
544 | 646 | ||
545 | /* buffer write end */ | 647 | /* buffer write end */ |
546 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); | 648 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE); |
649 | host->wait_for = MMCIF_WAIT_FOR_WRITE_END; | ||
547 | 650 | ||
548 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 651 | return true; |
549 | host->timeout); | ||
550 | if (time <= 0 || host->sd_error) | ||
551 | return sh_mmcif_error_manage(host); | ||
552 | |||
553 | return 0; | ||
554 | } | 652 | } |
555 | 653 | ||
556 | static int sh_mmcif_multi_write(struct sh_mmcif_host *host, | 654 | static void sh_mmcif_multi_write(struct sh_mmcif_host *host, |
557 | struct mmc_request *mrq) | 655 | struct mmc_request *mrq) |
558 | { | 656 | { |
559 | struct mmc_data *data = mrq->data; | 657 | struct mmc_data *data = mrq->data; |
560 | long time; | ||
561 | u32 i, sec, j, blocksize, *p; | ||
562 | 658 | ||
563 | blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr, | 659 | if (!data->sg_len || !data->sg->length) |
564 | MMCIF_CE_BLOCK_SET); | 660 | return; |
565 | 661 | ||
566 | for (j = 0; j < data->sg_len; j++) { | 662 | host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) & |
567 | p = sg_virt(data->sg); | 663 | BLOCK_SIZE_MASK; |
568 | for (sec = 0; sec < data->sg->length / blocksize; sec++) { | ||
569 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | ||
570 | /* buf write enable*/ | ||
571 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | ||
572 | host->timeout); | ||
573 | 664 | ||
574 | if (time <= 0 || host->sd_error) | 665 | host->wait_for = MMCIF_WAIT_FOR_MWRITE; |
575 | return sh_mmcif_error_manage(host); | 666 | host->sg_idx = 0; |
667 | host->sg_blkidx = 0; | ||
668 | host->pio_ptr = sg_virt(data->sg); | ||
669 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
670 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | ||
671 | } | ||
576 | 672 | ||
577 | for (i = 0; i < blocksize / 4; i++) | 673 | static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host) |
578 | sh_mmcif_writel(host->addr, | 674 | { |
579 | MMCIF_CE_DATA, *p++); | 675 | struct mmc_data *data = host->mrq->data; |
580 | } | 676 | u32 *p = host->pio_ptr; |
581 | if (j < data->sg_len - 1) | 677 | int i; |
582 | data->sg++; | 678 | |
679 | if (host->sd_error) { | ||
680 | data->error = sh_mmcif_error_manage(host); | ||
681 | return false; | ||
583 | } | 682 | } |
584 | return 0; | 683 | |
684 | BUG_ON(!data->sg->length); | ||
685 | |||
686 | for (i = 0; i < host->blocksize / 4; i++) | ||
687 | sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++); | ||
688 | |||
689 | if (!sh_mmcif_next_block(host, p)) | ||
690 | return false; | ||
691 | |||
692 | schedule_delayed_work(&host->timeout_work, host->timeout); | ||
693 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN); | ||
694 | |||
695 | return true; | ||
585 | } | 696 | } |
586 | 697 | ||
587 | static void sh_mmcif_get_response(struct sh_mmcif_host *host, | 698 | static void sh_mmcif_get_response(struct sh_mmcif_host *host, |
@@ -603,8 +714,11 @@ static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host, | |||
603 | } | 714 | } |
604 | 715 | ||
605 | static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | 716 | static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, |
606 | struct mmc_request *mrq, struct mmc_command *cmd, u32 opc) | 717 | struct mmc_request *mrq) |
607 | { | 718 | { |
719 | struct mmc_data *data = mrq->data; | ||
720 | struct mmc_command *cmd = mrq->cmd; | ||
721 | u32 opc = cmd->opcode; | ||
608 | u32 tmp = 0; | 722 | u32 tmp = 0; |
609 | 723 | ||
610 | /* Response Type check */ | 724 | /* Response Type check */ |
@@ -636,7 +750,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
636 | break; | 750 | break; |
637 | } | 751 | } |
638 | /* WDAT / DATW */ | 752 | /* WDAT / DATW */ |
639 | if (host->data) { | 753 | if (data) { |
640 | tmp |= CMD_SET_WDAT; | 754 | tmp |= CMD_SET_WDAT; |
641 | switch (host->bus_width) { | 755 | switch (host->bus_width) { |
642 | case MMC_BUS_WIDTH_1: | 756 | case MMC_BUS_WIDTH_1: |
@@ -660,7 +774,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
660 | if (opc == MMC_READ_MULTIPLE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK) { | 774 | if (opc == MMC_READ_MULTIPLE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK) { |
661 | tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN; | 775 | tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN; |
662 | sh_mmcif_bitset(host, MMCIF_CE_BLOCK_SET, | 776 | sh_mmcif_bitset(host, MMCIF_CE_BLOCK_SET, |
663 | mrq->data->blocks << 16); | 777 | data->blocks << 16); |
664 | } | 778 | } |
665 | /* RIDXC[1:0] check bits */ | 779 | /* RIDXC[1:0] check bits */ |
666 | if (opc == MMC_SEND_OP_COND || opc == MMC_ALL_SEND_CID || | 780 | if (opc == MMC_SEND_OP_COND || opc == MMC_ALL_SEND_CID || |
@@ -674,68 +788,60 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host, | |||
674 | opc == MMC_SEND_CSD || opc == MMC_SEND_CID) | 788 | opc == MMC_SEND_CSD || opc == MMC_SEND_CID) |
675 | tmp |= CMD_SET_CRC7C_INTERNAL; | 789 | tmp |= CMD_SET_CRC7C_INTERNAL; |
676 | 790 | ||
677 | return opc = ((opc << 24) | tmp); | 791 | return (opc << 24) | tmp; |
678 | } | 792 | } |
679 | 793 | ||
680 | static int sh_mmcif_data_trans(struct sh_mmcif_host *host, | 794 | static int sh_mmcif_data_trans(struct sh_mmcif_host *host, |
681 | struct mmc_request *mrq, u32 opc) | 795 | struct mmc_request *mrq, u32 opc) |
682 | { | 796 | { |
683 | int ret; | ||
684 | |||
685 | switch (opc) { | 797 | switch (opc) { |
686 | case MMC_READ_MULTIPLE_BLOCK: | 798 | case MMC_READ_MULTIPLE_BLOCK: |
687 | ret = sh_mmcif_multi_read(host, mrq); | 799 | sh_mmcif_multi_read(host, mrq); |
688 | break; | 800 | return 0; |
689 | case MMC_WRITE_MULTIPLE_BLOCK: | 801 | case MMC_WRITE_MULTIPLE_BLOCK: |
690 | ret = sh_mmcif_multi_write(host, mrq); | 802 | sh_mmcif_multi_write(host, mrq); |
691 | break; | 803 | return 0; |
692 | case MMC_WRITE_BLOCK: | 804 | case MMC_WRITE_BLOCK: |
693 | ret = sh_mmcif_single_write(host, mrq); | 805 | sh_mmcif_single_write(host, mrq); |
694 | break; | 806 | return 0; |
695 | case MMC_READ_SINGLE_BLOCK: | 807 | case MMC_READ_SINGLE_BLOCK: |
696 | case MMC_SEND_EXT_CSD: | 808 | case MMC_SEND_EXT_CSD: |
697 | ret = sh_mmcif_single_read(host, mrq); | 809 | sh_mmcif_single_read(host, mrq); |
698 | break; | 810 | return 0; |
699 | default: | 811 | default: |
700 | dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc); | 812 | dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc); |
701 | ret = -EINVAL; | 813 | return -EINVAL; |
702 | break; | ||
703 | } | 814 | } |
704 | return ret; | ||
705 | } | 815 | } |
706 | 816 | ||
707 | static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, | 817 | static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, |
708 | struct mmc_request *mrq, struct mmc_command *cmd) | 818 | struct mmc_request *mrq) |
709 | { | 819 | { |
710 | long time; | 820 | struct mmc_command *cmd = mrq->cmd; |
711 | int ret = 0, mask = 0; | ||
712 | u32 opc = cmd->opcode; | 821 | u32 opc = cmd->opcode; |
822 | u32 mask; | ||
713 | 823 | ||
714 | switch (opc) { | 824 | switch (opc) { |
715 | /* respons busy check */ | 825 | /* response busy check */ |
716 | case MMC_SWITCH: | 826 | case MMC_SWITCH: |
717 | case MMC_STOP_TRANSMISSION: | 827 | case MMC_STOP_TRANSMISSION: |
718 | case MMC_SET_WRITE_PROT: | 828 | case MMC_SET_WRITE_PROT: |
719 | case MMC_CLR_WRITE_PROT: | 829 | case MMC_CLR_WRITE_PROT: |
720 | case MMC_ERASE: | 830 | case MMC_ERASE: |
721 | case MMC_GEN_CMD: | 831 | case MMC_GEN_CMD: |
722 | mask = MASK_MRBSYE; | 832 | mask = MASK_START_CMD | MASK_MRBSYE; |
723 | break; | 833 | break; |
724 | default: | 834 | default: |
725 | mask = MASK_MCRSPE; | 835 | mask = MASK_START_CMD | MASK_MCRSPE; |
726 | break; | 836 | break; |
727 | } | 837 | } |
728 | mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | | ||
729 | MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | | ||
730 | MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | | ||
731 | MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO; | ||
732 | 838 | ||
733 | if (host->data) { | 839 | if (mrq->data) { |
734 | sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0); | 840 | sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0); |
735 | sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, | 841 | sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, |
736 | mrq->data->blksz); | 842 | mrq->data->blksz); |
737 | } | 843 | } |
738 | opc = sh_mmcif_set_cmd(host, mrq, cmd, opc); | 844 | opc = sh_mmcif_set_cmd(host, mrq); |
739 | 845 | ||
740 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0); | 846 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0); |
741 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); | 847 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask); |
@@ -744,80 +850,28 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host, | |||
744 | /* set cmd */ | 850 | /* set cmd */ |
745 | sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); | 851 | sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc); |
746 | 852 | ||
747 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 853 | host->wait_for = MMCIF_WAIT_FOR_CMD; |
748 | host->timeout); | 854 | schedule_delayed_work(&host->timeout_work, host->timeout); |
749 | if (time <= 0) { | ||
750 | cmd->error = sh_mmcif_error_manage(host); | ||
751 | return; | ||
752 | } | ||
753 | if (host->sd_error) { | ||
754 | switch (cmd->opcode) { | ||
755 | case MMC_ALL_SEND_CID: | ||
756 | case MMC_SELECT_CARD: | ||
757 | case MMC_APP_CMD: | ||
758 | cmd->error = -ETIMEDOUT; | ||
759 | break; | ||
760 | default: | ||
761 | dev_dbg(&host->pd->dev, "Cmd(d'%d) err\n", | ||
762 | cmd->opcode); | ||
763 | cmd->error = sh_mmcif_error_manage(host); | ||
764 | break; | ||
765 | } | ||
766 | host->sd_error = false; | ||
767 | return; | ||
768 | } | ||
769 | if (!(cmd->flags & MMC_RSP_PRESENT)) { | ||
770 | cmd->error = 0; | ||
771 | return; | ||
772 | } | ||
773 | sh_mmcif_get_response(host, cmd); | ||
774 | if (host->data) { | ||
775 | if (!host->dma_active) { | ||
776 | ret = sh_mmcif_data_trans(host, mrq, cmd->opcode); | ||
777 | } else { | ||
778 | long time = | ||
779 | wait_for_completion_interruptible_timeout(&host->dma_complete, | ||
780 | host->timeout); | ||
781 | if (!time) | ||
782 | ret = -ETIMEDOUT; | ||
783 | else if (time < 0) | ||
784 | ret = time; | ||
785 | sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, | ||
786 | BUF_ACC_DMAREN | BUF_ACC_DMAWEN); | ||
787 | host->dma_active = false; | ||
788 | } | ||
789 | if (ret < 0) | ||
790 | mrq->data->bytes_xfered = 0; | ||
791 | else | ||
792 | mrq->data->bytes_xfered = | ||
793 | mrq->data->blocks * mrq->data->blksz; | ||
794 | } | ||
795 | cmd->error = ret; | ||
796 | } | 855 | } |
797 | 856 | ||
798 | static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, | 857 | static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host, |
799 | struct mmc_request *mrq, struct mmc_command *cmd) | 858 | struct mmc_request *mrq) |
800 | { | 859 | { |
801 | long time; | 860 | switch (mrq->cmd->opcode) { |
802 | 861 | case MMC_READ_MULTIPLE_BLOCK: | |
803 | if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK) | ||
804 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE); | 862 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE); |
805 | else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK) | 863 | break; |
864 | case MMC_WRITE_MULTIPLE_BLOCK: | ||
806 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); | 865 | sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); |
807 | else { | 866 | break; |
867 | default: | ||
808 | dev_err(&host->pd->dev, "unsupported stop cmd\n"); | 868 | dev_err(&host->pd->dev, "unsupported stop cmd\n"); |
809 | cmd->error = sh_mmcif_error_manage(host); | 869 | mrq->stop->error = sh_mmcif_error_manage(host); |
810 | return; | 870 | return; |
811 | } | 871 | } |
812 | 872 | ||
813 | time = wait_for_completion_interruptible_timeout(&host->intr_wait, | 873 | host->wait_for = MMCIF_WAIT_FOR_STOP; |
814 | host->timeout); | 874 | schedule_delayed_work(&host->timeout_work, host->timeout); |
815 | if (time <= 0 || host->sd_error) { | ||
816 | cmd->error = sh_mmcif_error_manage(host); | ||
817 | return; | ||
818 | } | ||
819 | sh_mmcif_get_cmd12response(host, cmd); | ||
820 | cmd->error = 0; | ||
821 | } | 875 | } |
822 | 876 | ||
823 | static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) | 877 | static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) |
@@ -856,23 +910,10 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
856 | default: | 910 | default: |
857 | break; | 911 | break; |
858 | } | 912 | } |
859 | host->data = mrq->data; | ||
860 | if (mrq->data) { | ||
861 | if (mrq->data->flags & MMC_DATA_READ) { | ||
862 | if (host->chan_rx) | ||
863 | sh_mmcif_start_dma_rx(host); | ||
864 | } else { | ||
865 | if (host->chan_tx) | ||
866 | sh_mmcif_start_dma_tx(host); | ||
867 | } | ||
868 | } | ||
869 | sh_mmcif_start_cmd(host, mrq, mrq->cmd); | ||
870 | host->data = NULL; | ||
871 | 913 | ||
872 | if (!mrq->cmd->error && mrq->stop) | 914 | host->mrq = mrq; |
873 | sh_mmcif_stop_cmd(host, mrq, mrq->stop); | 915 | |
874 | host->state = STATE_IDLE; | 916 | sh_mmcif_start_cmd(host, mrq); |
875 | mmc_request_done(mmc, mrq); | ||
876 | } | 917 | } |
877 | 918 | ||
878 | static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | 919 | static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
@@ -947,9 +988,156 @@ static struct mmc_host_ops sh_mmcif_ops = { | |||
947 | .get_cd = sh_mmcif_get_cd, | 988 | .get_cd = sh_mmcif_get_cd, |
948 | }; | 989 | }; |
949 | 990 | ||
950 | static void sh_mmcif_detect(struct mmc_host *mmc) | 991 | static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host) |
951 | { | 992 | { |
952 | mmc_detect_change(mmc, 0); | 993 | struct mmc_command *cmd = host->mrq->cmd; |
994 | struct mmc_data *data = host->mrq->data; | ||
995 | long time; | ||
996 | |||
997 | if (host->sd_error) { | ||
998 | switch (cmd->opcode) { | ||
999 | case MMC_ALL_SEND_CID: | ||
1000 | case MMC_SELECT_CARD: | ||
1001 | case MMC_APP_CMD: | ||
1002 | cmd->error = -ETIMEDOUT; | ||
1003 | host->sd_error = false; | ||
1004 | break; | ||
1005 | default: | ||
1006 | cmd->error = sh_mmcif_error_manage(host); | ||
1007 | dev_dbg(&host->pd->dev, "Cmd(d'%d) error %d\n", | ||
1008 | cmd->opcode, cmd->error); | ||
1009 | break; | ||
1010 | } | ||
1011 | return false; | ||
1012 | } | ||
1013 | if (!(cmd->flags & MMC_RSP_PRESENT)) { | ||
1014 | cmd->error = 0; | ||
1015 | return false; | ||
1016 | } | ||
1017 | |||
1018 | sh_mmcif_get_response(host, cmd); | ||
1019 | |||
1020 | if (!data) | ||
1021 | return false; | ||
1022 | |||
1023 | if (data->flags & MMC_DATA_READ) { | ||
1024 | if (host->chan_rx) | ||
1025 | sh_mmcif_start_dma_rx(host); | ||
1026 | } else { | ||
1027 | if (host->chan_tx) | ||
1028 | sh_mmcif_start_dma_tx(host); | ||
1029 | } | ||
1030 | |||
1031 | if (!host->dma_active) { | ||
1032 | data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode); | ||
1033 | if (!data->error) | ||
1034 | return true; | ||
1035 | return false; | ||
1036 | } | ||
1037 | |||
1038 | /* Running in the IRQ thread, can sleep */ | ||
1039 | time = wait_for_completion_interruptible_timeout(&host->dma_complete, | ||
1040 | host->timeout); | ||
1041 | if (host->sd_error) { | ||
1042 | dev_err(host->mmc->parent, | ||
1043 | "Error IRQ while waiting for DMA completion!\n"); | ||
1044 | /* Woken up by an error IRQ: abort DMA */ | ||
1045 | if (data->flags & MMC_DATA_READ) | ||
1046 | dmaengine_terminate_all(host->chan_rx); | ||
1047 | else | ||
1048 | dmaengine_terminate_all(host->chan_tx); | ||
1049 | data->error = sh_mmcif_error_manage(host); | ||
1050 | } else if (!time) { | ||
1051 | data->error = -ETIMEDOUT; | ||
1052 | } else if (time < 0) { | ||
1053 | data->error = time; | ||
1054 | } | ||
1055 | sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC, | ||
1056 | BUF_ACC_DMAREN | BUF_ACC_DMAWEN); | ||
1057 | host->dma_active = false; | ||
1058 | |||
1059 | if (data->error) | ||
1060 | data->bytes_xfered = 0; | ||
1061 | |||
1062 | return false; | ||
1063 | } | ||
1064 | |||
1065 | static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id) | ||
1066 | { | ||
1067 | struct sh_mmcif_host *host = dev_id; | ||
1068 | struct mmc_request *mrq = host->mrq; | ||
1069 | struct mmc_data *data = mrq->data; | ||
1070 | |||
1071 | cancel_delayed_work_sync(&host->timeout_work); | ||
1072 | |||
1073 | /* | ||
1074 | * All handlers return true, if processing continues, and false, if the | ||
1075 | * request has to be completed - successfully or not | ||
1076 | */ | ||
1077 | switch (host->wait_for) { | ||
1078 | case MMCIF_WAIT_FOR_REQUEST: | ||
1079 | /* We're too late, the timeout has already kicked in */ | ||
1080 | return IRQ_HANDLED; | ||
1081 | case MMCIF_WAIT_FOR_CMD: | ||
1082 | if (sh_mmcif_end_cmd(host)) | ||
1083 | /* Wait for data */ | ||
1084 | return IRQ_HANDLED; | ||
1085 | break; | ||
1086 | case MMCIF_WAIT_FOR_MREAD: | ||
1087 | if (sh_mmcif_mread_block(host)) | ||
1088 | /* Wait for more data */ | ||
1089 | return IRQ_HANDLED; | ||
1090 | break; | ||
1091 | case MMCIF_WAIT_FOR_READ: | ||
1092 | if (sh_mmcif_read_block(host)) | ||
1093 | /* Wait for data end */ | ||
1094 | return IRQ_HANDLED; | ||
1095 | break; | ||
1096 | case MMCIF_WAIT_FOR_MWRITE: | ||
1097 | if (sh_mmcif_mwrite_block(host)) | ||
1098 | /* Wait data to write */ | ||
1099 | return IRQ_HANDLED; | ||
1100 | break; | ||
1101 | case MMCIF_WAIT_FOR_WRITE: | ||
1102 | if (sh_mmcif_write_block(host)) | ||
1103 | /* Wait for data end */ | ||
1104 | return IRQ_HANDLED; | ||
1105 | break; | ||
1106 | case MMCIF_WAIT_FOR_STOP: | ||
1107 | if (host->sd_error) { | ||
1108 | mrq->stop->error = sh_mmcif_error_manage(host); | ||
1109 | break; | ||
1110 | } | ||
1111 | sh_mmcif_get_cmd12response(host, mrq->stop); | ||
1112 | mrq->stop->error = 0; | ||
1113 | break; | ||
1114 | case MMCIF_WAIT_FOR_READ_END: | ||
1115 | case MMCIF_WAIT_FOR_WRITE_END: | ||
1116 | if (host->sd_error) | ||
1117 | data->error = sh_mmcif_error_manage(host); | ||
1118 | break; | ||
1119 | default: | ||
1120 | BUG(); | ||
1121 | } | ||
1122 | |||
1123 | if (host->wait_for != MMCIF_WAIT_FOR_STOP) { | ||
1124 | if (!mrq->cmd->error && data && !data->error) | ||
1125 | data->bytes_xfered = | ||
1126 | data->blocks * data->blksz; | ||
1127 | |||
1128 | if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) { | ||
1129 | sh_mmcif_stop_cmd(host, mrq); | ||
1130 | if (!mrq->stop->error) | ||
1131 | return IRQ_HANDLED; | ||
1132 | } | ||
1133 | } | ||
1134 | |||
1135 | host->wait_for = MMCIF_WAIT_FOR_REQUEST; | ||
1136 | host->state = STATE_IDLE; | ||
1137 | host->mrq = NULL; | ||
1138 | mmc_request_done(host->mmc, mrq); | ||
1139 | |||
1140 | return IRQ_HANDLED; | ||
953 | } | 1141 | } |
954 | 1142 | ||
955 | static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | 1143 | static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) |
@@ -960,7 +1148,12 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | |||
960 | 1148 | ||
961 | state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); | 1149 | state = sh_mmcif_readl(host->addr, MMCIF_CE_INT); |
962 | 1150 | ||
963 | if (state & INT_RBSYE) { | 1151 | if (state & INT_ERR_STS) { |
1152 | /* error interrupts - process first */ | ||
1153 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); | ||
1154 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); | ||
1155 | err = 1; | ||
1156 | } else if (state & INT_RBSYE) { | ||
964 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, | 1157 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, |
965 | ~(INT_RBSYE | INT_CRSPE)); | 1158 | ~(INT_RBSYE | INT_CRSPE)); |
966 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE); | 1159 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE); |
@@ -988,11 +1181,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | |||
988 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, | 1181 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, |
989 | ~(INT_CMD12RBE | INT_CMD12CRE)); | 1182 | ~(INT_CMD12RBE | INT_CMD12CRE)); |
990 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); | 1183 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE); |
991 | } else if (state & INT_ERR_STS) { | ||
992 | /* err interrupts */ | ||
993 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); | ||
994 | sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state); | ||
995 | err = 1; | ||
996 | } else { | 1184 | } else { |
997 | dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state); | 1185 | dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state); |
998 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); | 1186 | sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state); |
@@ -1003,14 +1191,57 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id) | |||
1003 | host->sd_error = true; | 1191 | host->sd_error = true; |
1004 | dev_dbg(&host->pd->dev, "int err state = %08x\n", state); | 1192 | dev_dbg(&host->pd->dev, "int err state = %08x\n", state); |
1005 | } | 1193 | } |
1006 | if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) | 1194 | if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) { |
1007 | complete(&host->intr_wait); | 1195 | if (!host->dma_active) |
1008 | else | 1196 | return IRQ_WAKE_THREAD; |
1197 | else if (host->sd_error) | ||
1198 | mmcif_dma_complete(host); | ||
1199 | } else { | ||
1009 | dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state); | 1200 | dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state); |
1201 | } | ||
1010 | 1202 | ||
1011 | return IRQ_HANDLED; | 1203 | return IRQ_HANDLED; |
1012 | } | 1204 | } |
1013 | 1205 | ||
1206 | static void mmcif_timeout_work(struct work_struct *work) | ||
1207 | { | ||
1208 | struct delayed_work *d = container_of(work, struct delayed_work, work); | ||
1209 | struct sh_mmcif_host *host = container_of(d, struct sh_mmcif_host, timeout_work); | ||
1210 | struct mmc_request *mrq = host->mrq; | ||
1211 | |||
1212 | if (host->dying) | ||
1213 | /* Don't run after mmc_remove_host() */ | ||
1214 | return; | ||
1215 | |||
1216 | /* | ||
1217 | * Handle races with cancel_delayed_work(), unless | ||
1218 | * cancel_delayed_work_sync() is used | ||
1219 | */ | ||
1220 | switch (host->wait_for) { | ||
1221 | case MMCIF_WAIT_FOR_CMD: | ||
1222 | mrq->cmd->error = sh_mmcif_error_manage(host); | ||
1223 | break; | ||
1224 | case MMCIF_WAIT_FOR_STOP: | ||
1225 | mrq->stop->error = sh_mmcif_error_manage(host); | ||
1226 | break; | ||
1227 | case MMCIF_WAIT_FOR_MREAD: | ||
1228 | case MMCIF_WAIT_FOR_MWRITE: | ||
1229 | case MMCIF_WAIT_FOR_READ: | ||
1230 | case MMCIF_WAIT_FOR_WRITE: | ||
1231 | case MMCIF_WAIT_FOR_READ_END: | ||
1232 | case MMCIF_WAIT_FOR_WRITE_END: | ||
1233 | mrq->data->error = sh_mmcif_error_manage(host); | ||
1234 | break; | ||
1235 | default: | ||
1236 | BUG(); | ||
1237 | } | ||
1238 | |||
1239 | host->state = STATE_IDLE; | ||
1240 | host->wait_for = MMCIF_WAIT_FOR_REQUEST; | ||
1241 | host->mrq = NULL; | ||
1242 | mmc_request_done(host->mmc, mrq); | ||
1243 | } | ||
1244 | |||
1014 | static int __devinit sh_mmcif_probe(struct platform_device *pdev) | 1245 | static int __devinit sh_mmcif_probe(struct platform_device *pdev) |
1015 | { | 1246 | { |
1016 | int ret = 0, irq[2]; | 1247 | int ret = 0, irq[2]; |
@@ -1064,7 +1295,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
1064 | host->clk = clk_get_rate(host->hclk); | 1295 | host->clk = clk_get_rate(host->hclk); |
1065 | host->pd = pdev; | 1296 | host->pd = pdev; |
1066 | 1297 | ||
1067 | init_completion(&host->intr_wait); | ||
1068 | spin_lock_init(&host->lock); | 1298 | spin_lock_init(&host->lock); |
1069 | 1299 | ||
1070 | mmc->ops = &sh_mmcif_ops; | 1300 | mmc->ops = &sh_mmcif_ops; |
@@ -1101,19 +1331,21 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) | |||
1101 | 1331 | ||
1102 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1332 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
1103 | 1333 | ||
1104 | ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host); | 1334 | ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host); |
1105 | if (ret) { | 1335 | if (ret) { |
1106 | dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n"); | 1336 | dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n"); |
1107 | goto clean_up3; | 1337 | goto clean_up3; |
1108 | } | 1338 | } |
1109 | ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host); | 1339 | ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host); |
1110 | if (ret) { | 1340 | if (ret) { |
1111 | free_irq(irq[0], host); | 1341 | free_irq(irq[0], host); |
1112 | dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); | 1342 | dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); |
1113 | goto clean_up3; | 1343 | goto clean_up3; |
1114 | } | 1344 | } |
1115 | 1345 | ||
1116 | sh_mmcif_detect(host->mmc); | 1346 | INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work); |
1347 | |||
1348 | mmc_detect_change(host->mmc, 0); | ||
1117 | 1349 | ||
1118 | dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION); | 1350 | dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION); |
1119 | dev_dbg(&pdev->dev, "chip ver H'%04x\n", | 1351 | dev_dbg(&pdev->dev, "chip ver H'%04x\n", |
@@ -1139,11 +1371,19 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev) | |||
1139 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); | 1371 | struct sh_mmcif_host *host = platform_get_drvdata(pdev); |
1140 | int irq[2]; | 1372 | int irq[2]; |
1141 | 1373 | ||
1374 | host->dying = true; | ||
1142 | pm_runtime_get_sync(&pdev->dev); | 1375 | pm_runtime_get_sync(&pdev->dev); |
1143 | 1376 | ||
1144 | mmc_remove_host(host->mmc); | 1377 | mmc_remove_host(host->mmc); |
1145 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); | 1378 | sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); |
1146 | 1379 | ||
1380 | /* | ||
1381 | * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the | ||
1382 | * mmc_remove_host() call above. But swapping order doesn't help either | ||
1383 | * (a query on the linux-mmc mailing list didn't bring any replies). | ||
1384 | */ | ||
1385 | cancel_delayed_work_sync(&host->timeout_work); | ||
1386 | |||
1147 | if (host->addr) | 1387 | if (host->addr) |
1148 | iounmap(host->addr); | 1388 | iounmap(host->addr); |
1149 | 1389 | ||
@@ -1206,19 +1446,7 @@ static struct platform_driver sh_mmcif_driver = { | |||
1206 | }, | 1446 | }, |
1207 | }; | 1447 | }; |
1208 | 1448 | ||
1209 | static int __init sh_mmcif_init(void) | 1449 | module_platform_driver(sh_mmcif_driver); |
1210 | { | ||
1211 | return platform_driver_register(&sh_mmcif_driver); | ||
1212 | } | ||
1213 | |||
1214 | static void __exit sh_mmcif_exit(void) | ||
1215 | { | ||
1216 | platform_driver_unregister(&sh_mmcif_driver); | ||
1217 | } | ||
1218 | |||
1219 | module_init(sh_mmcif_init); | ||
1220 | module_exit(sh_mmcif_exit); | ||
1221 | |||
1222 | 1450 | ||
1223 | MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver"); | 1451 | MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver"); |
1224 | MODULE_LICENSE("GPL"); | 1452 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 41ae6466bd83..58da3c44acc5 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c | |||
@@ -282,18 +282,7 @@ static struct platform_driver sh_mobile_sdhi_driver = { | |||
282 | .remove = __devexit_p(sh_mobile_sdhi_remove), | 282 | .remove = __devexit_p(sh_mobile_sdhi_remove), |
283 | }; | 283 | }; |
284 | 284 | ||
285 | static int __init sh_mobile_sdhi_init(void) | 285 | module_platform_driver(sh_mobile_sdhi_driver); |
286 | { | ||
287 | return platform_driver_register(&sh_mobile_sdhi_driver); | ||
288 | } | ||
289 | |||
290 | static void __exit sh_mobile_sdhi_exit(void) | ||
291 | { | ||
292 | platform_driver_unregister(&sh_mobile_sdhi_driver); | ||
293 | } | ||
294 | |||
295 | module_init(sh_mobile_sdhi_init); | ||
296 | module_exit(sh_mobile_sdhi_exit); | ||
297 | 286 | ||
298 | MODULE_DESCRIPTION("SuperH Mobile SDHI driver"); | 287 | MODULE_DESCRIPTION("SuperH Mobile SDHI driver"); |
299 | MODULE_AUTHOR("Magnus Damm"); | 288 | MODULE_AUTHOR("Magnus Damm"); |
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c index 69d249f51d6a..43d962829f8e 100644 --- a/drivers/mmc/host/tifm_sd.c +++ b/drivers/mmc/host/tifm_sd.c | |||
@@ -118,7 +118,7 @@ static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, | |||
118 | unsigned char *buf; | 118 | unsigned char *buf; |
119 | unsigned int pos = 0, val; | 119 | unsigned int pos = 0, val; |
120 | 120 | ||
121 | buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + off; | 121 | buf = kmap_atomic(pg) + off; |
122 | if (host->cmd_flags & DATA_CARRY) { | 122 | if (host->cmd_flags & DATA_CARRY) { |
123 | buf[pos++] = host->bounce_buf_data[0]; | 123 | buf[pos++] = host->bounce_buf_data[0]; |
124 | host->cmd_flags &= ~DATA_CARRY; | 124 | host->cmd_flags &= ~DATA_CARRY; |
@@ -134,7 +134,7 @@ static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg, | |||
134 | } | 134 | } |
135 | buf[pos++] = (val >> 8) & 0xff; | 135 | buf[pos++] = (val >> 8) & 0xff; |
136 | } | 136 | } |
137 | kunmap_atomic(buf - off, KM_BIO_DST_IRQ); | 137 | kunmap_atomic(buf - off); |
138 | } | 138 | } |
139 | 139 | ||
140 | static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, | 140 | static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, |
@@ -144,7 +144,7 @@ static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, | |||
144 | unsigned char *buf; | 144 | unsigned char *buf; |
145 | unsigned int pos = 0, val; | 145 | unsigned int pos = 0, val; |
146 | 146 | ||
147 | buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + off; | 147 | buf = kmap_atomic(pg) + off; |
148 | if (host->cmd_flags & DATA_CARRY) { | 148 | if (host->cmd_flags & DATA_CARRY) { |
149 | val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00); | 149 | val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00); |
150 | writel(val, sock->addr + SOCK_MMCSD_DATA); | 150 | writel(val, sock->addr + SOCK_MMCSD_DATA); |
@@ -161,7 +161,7 @@ static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg, | |||
161 | val |= (buf[pos++] << 8) & 0xff00; | 161 | val |= (buf[pos++] << 8) & 0xff00; |
162 | writel(val, sock->addr + SOCK_MMCSD_DATA); | 162 | writel(val, sock->addr + SOCK_MMCSD_DATA); |
163 | } | 163 | } |
164 | kunmap_atomic(buf - off, KM_BIO_SRC_IRQ); | 164 | kunmap_atomic(buf - off); |
165 | } | 165 | } |
166 | 166 | ||
167 | static void tifm_sd_transfer_data(struct tifm_sd *host) | 167 | static void tifm_sd_transfer_data(struct tifm_sd *host) |
@@ -212,13 +212,13 @@ static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off, | |||
212 | struct page *src, unsigned int src_off, | 212 | struct page *src, unsigned int src_off, |
213 | unsigned int count) | 213 | unsigned int count) |
214 | { | 214 | { |
215 | unsigned char *src_buf = kmap_atomic(src, KM_BIO_SRC_IRQ) + src_off; | 215 | unsigned char *src_buf = kmap_atomic(src) + src_off; |
216 | unsigned char *dst_buf = kmap_atomic(dst, KM_BIO_DST_IRQ) + dst_off; | 216 | unsigned char *dst_buf = kmap_atomic(dst) + dst_off; |
217 | 217 | ||
218 | memcpy(dst_buf, src_buf, count); | 218 | memcpy(dst_buf, src_buf, count); |
219 | 219 | ||
220 | kunmap_atomic(dst_buf - dst_off, KM_BIO_DST_IRQ); | 220 | kunmap_atomic(dst_buf - dst_off); |
221 | kunmap_atomic(src_buf - src_off, KM_BIO_SRC_IRQ); | 221 | kunmap_atomic(src_buf - src_off); |
222 | } | 222 | } |
223 | 223 | ||
224 | static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data) | 224 | static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data) |
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c index a4ea10242787..113ce6c9cf32 100644 --- a/drivers/mmc/host/tmio_mmc.c +++ b/drivers/mmc/host/tmio_mmc.c | |||
@@ -138,19 +138,7 @@ static struct platform_driver tmio_mmc_driver = { | |||
138 | .resume = tmio_mmc_resume, | 138 | .resume = tmio_mmc_resume, |
139 | }; | 139 | }; |
140 | 140 | ||
141 | 141 | module_platform_driver(tmio_mmc_driver); | |
142 | static int __init tmio_mmc_init(void) | ||
143 | { | ||
144 | return platform_driver_register(&tmio_mmc_driver); | ||
145 | } | ||
146 | |||
147 | static void __exit tmio_mmc_exit(void) | ||
148 | { | ||
149 | platform_driver_unregister(&tmio_mmc_driver); | ||
150 | } | ||
151 | |||
152 | module_init(tmio_mmc_init); | ||
153 | module_exit(tmio_mmc_exit); | ||
154 | 142 | ||
155 | MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver"); | 143 | MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver"); |
156 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); | 144 | MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); |
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 3020f98218f0..a95e6d901726 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h | |||
@@ -105,13 +105,13 @@ static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg, | |||
105 | unsigned long *flags) | 105 | unsigned long *flags) |
106 | { | 106 | { |
107 | local_irq_save(*flags); | 107 | local_irq_save(*flags); |
108 | return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset; | 108 | return kmap_atomic(sg_page(sg)) + sg->offset; |
109 | } | 109 | } |
110 | 110 | ||
111 | static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg, | 111 | static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg, |
112 | unsigned long *flags, void *virt) | 112 | unsigned long *flags, void *virt) |
113 | { | 113 | { |
114 | kunmap_atomic(virt - sg->offset, KM_BIO_SRC_IRQ); | 114 | kunmap_atomic(virt - sg->offset); |
115 | local_irq_restore(*flags); | 115 | local_irq_restore(*flags); |
116 | } | 116 | } |
117 | 117 | ||
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index 4208b3958069..abad01b37cfb 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c | |||
@@ -800,8 +800,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) | |||
800 | } else if (ios->power_mode != MMC_POWER_UP) { | 800 | } else if (ios->power_mode != MMC_POWER_UP) { |
801 | if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) | 801 | if (host->set_pwr && ios->power_mode == MMC_POWER_OFF) |
802 | host->set_pwr(host->pdev, 0); | 802 | host->set_pwr(host->pdev, 0); |
803 | if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && | 803 | if (pdata->power) { |
804 | pdata->power) { | ||
805 | pdata->power = false; | 804 | pdata->power = false; |
806 | pm_runtime_put(&host->pdev->dev); | 805 | pm_runtime_put(&host->pdev->dev); |
807 | } | 806 | } |
@@ -915,6 +914,23 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
915 | if (ret < 0) | 914 | if (ret < 0) |
916 | goto pm_disable; | 915 | goto pm_disable; |
917 | 916 | ||
917 | /* | ||
918 | * There are 4 different scenarios for the card detection: | ||
919 | * 1) an external gpio irq handles the cd (best for power savings) | ||
920 | * 2) internal sdhi irq handles the cd | ||
921 | * 3) a worker thread polls the sdhi - indicated by MMC_CAP_NEEDS_POLL | ||
922 | * 4) the medium is non-removable - indicated by MMC_CAP_NONREMOVABLE | ||
923 | * | ||
924 | * While we increment the rtpm counter for all scenarios when the mmc | ||
925 | * core activates us by calling an appropriate set_ios(), we must | ||
926 | * additionally ensure that in case 2) the tmio mmc hardware stays | ||
927 | * powered on during runtime for the card detection to work. | ||
928 | */ | ||
929 | if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD | ||
930 | || mmc->caps & MMC_CAP_NEEDS_POLL | ||
931 | || mmc->caps & MMC_CAP_NONREMOVABLE)) | ||
932 | pm_runtime_get_noresume(&pdev->dev); | ||
933 | |||
918 | tmio_mmc_clk_stop(_host); | 934 | tmio_mmc_clk_stop(_host); |
919 | tmio_mmc_reset(_host); | 935 | tmio_mmc_reset(_host); |
920 | 936 | ||
@@ -933,12 +949,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host, | |||
933 | /* See if we also get DMA */ | 949 | /* See if we also get DMA */ |
934 | tmio_mmc_request_dma(_host, pdata); | 950 | tmio_mmc_request_dma(_host, pdata); |
935 | 951 | ||
936 | /* We have to keep the device powered for its card detection to work */ | ||
937 | if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD)) { | ||
938 | pdata->power = true; | ||
939 | pm_runtime_get_noresume(&pdev->dev); | ||
940 | } | ||
941 | |||
942 | mmc_add_host(mmc); | 952 | mmc_add_host(mmc); |
943 | 953 | ||
944 | /* Unmask the IRQs we want to know about */ | 954 | /* Unmask the IRQs we want to know about */ |
@@ -974,7 +984,9 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host) | |||
974 | * the controller, the runtime PM is suspended and pdata->power == false, | 984 | * the controller, the runtime PM is suspended and pdata->power == false, |
975 | * so, our .runtime_resume() will not try to detect a card in the slot. | 985 | * so, our .runtime_resume() will not try to detect a card in the slot. |
976 | */ | 986 | */ |
977 | if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD) | 987 | if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD |
988 | || host->mmc->caps & MMC_CAP_NEEDS_POLL | ||
989 | || host->mmc->caps & MMC_CAP_NONREMOVABLE) | ||
978 | pm_runtime_get_sync(&pdev->dev); | 990 | pm_runtime_get_sync(&pdev->dev); |
979 | 991 | ||
980 | mmc_remove_host(host->mmc); | 992 | mmc_remove_host(host->mmc); |
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index db8e8272d69b..3ce99e00a49e 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c | |||
@@ -315,8 +315,7 @@ static void mtdoops_do_dump(struct kmsg_dumper *dumper, | |||
315 | char *dst; | 315 | char *dst; |
316 | 316 | ||
317 | if (reason != KMSG_DUMP_OOPS && | 317 | if (reason != KMSG_DUMP_OOPS && |
318 | reason != KMSG_DUMP_PANIC && | 318 | reason != KMSG_DUMP_PANIC) |
319 | reason != KMSG_DUMP_KEXEC) | ||
320 | return; | 319 | return; |
321 | 320 | ||
322 | /* Only dump oopses if dump_oops is set */ | 321 | /* Only dump oopses if dump_oops is set */ |
diff --git a/drivers/mtd/ubi/debug.h b/drivers/mtd/ubi/debug.h index 64fbb0021825..ead2cd16ba75 100644 --- a/drivers/mtd/ubi/debug.h +++ b/drivers/mtd/ubi/debug.h | |||
@@ -43,7 +43,10 @@ | |||
43 | pr_debug("UBI DBG " type ": " fmt "\n", ##__VA_ARGS__) | 43 | pr_debug("UBI DBG " type ": " fmt "\n", ##__VA_ARGS__) |
44 | 44 | ||
45 | /* Just a debugging messages not related to any specific UBI subsystem */ | 45 | /* Just a debugging messages not related to any specific UBI subsystem */ |
46 | #define dbg_msg(fmt, ...) ubi_dbg_msg("msg", fmt, ##__VA_ARGS__) | 46 | #define dbg_msg(fmt, ...) \ |
47 | printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \ | ||
48 | current->pid, __func__, ##__VA_ARGS__) | ||
49 | |||
47 | /* General debugging messages */ | 50 | /* General debugging messages */ |
48 | #define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__) | 51 | #define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__) |
49 | /* Messages from the eraseblock association sub-system */ | 52 | /* Messages from the eraseblock association sub-system */ |
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index 9ad18da1891d..890754c9f327 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -306,7 +306,7 @@ static int create_vtbl(struct ubi_device *ubi, struct ubi_scan_info *si, | |||
306 | int copy, void *vtbl) | 306 | int copy, void *vtbl) |
307 | { | 307 | { |
308 | int err, tries = 0; | 308 | int err, tries = 0; |
309 | static struct ubi_vid_hdr *vid_hdr; | 309 | struct ubi_vid_hdr *vid_hdr; |
310 | struct ubi_scan_leb *new_seb; | 310 | struct ubi_scan_leb *new_seb; |
311 | 311 | ||
312 | ubi_msg("create volume table (copy #%d)", copy + 1); | 312 | ubi_msg("create volume table (copy #%d)", copy + 1); |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 106b88a04738..342626f4bc46 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -99,16 +99,26 @@ static inline u8 _simple_hash(const u8 *hash_start, int hash_size) | |||
99 | 99 | ||
100 | /*********************** tlb specific functions ***************************/ | 100 | /*********************** tlb specific functions ***************************/ |
101 | 101 | ||
102 | static inline void _lock_tx_hashtbl(struct bonding *bond) | 102 | static inline void _lock_tx_hashtbl_bh(struct bonding *bond) |
103 | { | 103 | { |
104 | spin_lock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); | 104 | spin_lock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); |
105 | } | 105 | } |
106 | 106 | ||
107 | static inline void _unlock_tx_hashtbl(struct bonding *bond) | 107 | static inline void _unlock_tx_hashtbl_bh(struct bonding *bond) |
108 | { | 108 | { |
109 | spin_unlock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); | 109 | spin_unlock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); |
110 | } | 110 | } |
111 | 111 | ||
112 | static inline void _lock_tx_hashtbl(struct bonding *bond) | ||
113 | { | ||
114 | spin_lock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); | ||
115 | } | ||
116 | |||
117 | static inline void _unlock_tx_hashtbl(struct bonding *bond) | ||
118 | { | ||
119 | spin_unlock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock)); | ||
120 | } | ||
121 | |||
112 | /* Caller must hold tx_hashtbl lock */ | 122 | /* Caller must hold tx_hashtbl lock */ |
113 | static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load) | 123 | static inline void tlb_init_table_entry(struct tlb_client_info *entry, int save_load) |
114 | { | 124 | { |
@@ -129,14 +139,13 @@ static inline void tlb_init_slave(struct slave *slave) | |||
129 | SLAVE_TLB_INFO(slave).head = TLB_NULL_INDEX; | 139 | SLAVE_TLB_INFO(slave).head = TLB_NULL_INDEX; |
130 | } | 140 | } |
131 | 141 | ||
132 | /* Caller must hold bond lock for read */ | 142 | /* Caller must hold bond lock for read, BH disabled */ |
133 | static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_load) | 143 | static void __tlb_clear_slave(struct bonding *bond, struct slave *slave, |
144 | int save_load) | ||
134 | { | 145 | { |
135 | struct tlb_client_info *tx_hash_table; | 146 | struct tlb_client_info *tx_hash_table; |
136 | u32 index; | 147 | u32 index; |
137 | 148 | ||
138 | _lock_tx_hashtbl(bond); | ||
139 | |||
140 | /* clear slave from tx_hashtbl */ | 149 | /* clear slave from tx_hashtbl */ |
141 | tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; | 150 | tx_hash_table = BOND_ALB_INFO(bond).tx_hashtbl; |
142 | 151 | ||
@@ -151,8 +160,15 @@ static void tlb_clear_slave(struct bonding *bond, struct slave *slave, int save_ | |||
151 | } | 160 | } |
152 | 161 | ||
153 | tlb_init_slave(slave); | 162 | tlb_init_slave(slave); |
163 | } | ||
154 | 164 | ||
155 | _unlock_tx_hashtbl(bond); | 165 | /* Caller must hold bond lock for read */ |
166 | static void tlb_clear_slave(struct bonding *bond, struct slave *slave, | ||
167 | int save_load) | ||
168 | { | ||
169 | _lock_tx_hashtbl_bh(bond); | ||
170 | __tlb_clear_slave(bond, slave, save_load); | ||
171 | _unlock_tx_hashtbl_bh(bond); | ||
156 | } | 172 | } |
157 | 173 | ||
158 | /* Must be called before starting the monitor timer */ | 174 | /* Must be called before starting the monitor timer */ |
@@ -169,7 +185,7 @@ static int tlb_initialize(struct bonding *bond) | |||
169 | bond->dev->name); | 185 | bond->dev->name); |
170 | return -1; | 186 | return -1; |
171 | } | 187 | } |
172 | _lock_tx_hashtbl(bond); | 188 | _lock_tx_hashtbl_bh(bond); |
173 | 189 | ||
174 | bond_info->tx_hashtbl = new_hashtbl; | 190 | bond_info->tx_hashtbl = new_hashtbl; |
175 | 191 | ||
@@ -177,7 +193,7 @@ static int tlb_initialize(struct bonding *bond) | |||
177 | tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0); | 193 | tlb_init_table_entry(&bond_info->tx_hashtbl[i], 0); |
178 | } | 194 | } |
179 | 195 | ||
180 | _unlock_tx_hashtbl(bond); | 196 | _unlock_tx_hashtbl_bh(bond); |
181 | 197 | ||
182 | return 0; | 198 | return 0; |
183 | } | 199 | } |
@@ -187,12 +203,12 @@ static void tlb_deinitialize(struct bonding *bond) | |||
187 | { | 203 | { |
188 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); | 204 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); |
189 | 205 | ||
190 | _lock_tx_hashtbl(bond); | 206 | _lock_tx_hashtbl_bh(bond); |
191 | 207 | ||
192 | kfree(bond_info->tx_hashtbl); | 208 | kfree(bond_info->tx_hashtbl); |
193 | bond_info->tx_hashtbl = NULL; | 209 | bond_info->tx_hashtbl = NULL; |
194 | 210 | ||
195 | _unlock_tx_hashtbl(bond); | 211 | _unlock_tx_hashtbl_bh(bond); |
196 | } | 212 | } |
197 | 213 | ||
198 | static long long compute_gap(struct slave *slave) | 214 | static long long compute_gap(struct slave *slave) |
@@ -226,15 +242,13 @@ static struct slave *tlb_get_least_loaded_slave(struct bonding *bond) | |||
226 | return least_loaded; | 242 | return least_loaded; |
227 | } | 243 | } |
228 | 244 | ||
229 | /* Caller must hold bond lock for read */ | 245 | static struct slave *__tlb_choose_channel(struct bonding *bond, u32 hash_index, |
230 | static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u32 skb_len) | 246 | u32 skb_len) |
231 | { | 247 | { |
232 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); | 248 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); |
233 | struct tlb_client_info *hash_table; | 249 | struct tlb_client_info *hash_table; |
234 | struct slave *assigned_slave; | 250 | struct slave *assigned_slave; |
235 | 251 | ||
236 | _lock_tx_hashtbl(bond); | ||
237 | |||
238 | hash_table = bond_info->tx_hashtbl; | 252 | hash_table = bond_info->tx_hashtbl; |
239 | assigned_slave = hash_table[hash_index].tx_slave; | 253 | assigned_slave = hash_table[hash_index].tx_slave; |
240 | if (!assigned_slave) { | 254 | if (!assigned_slave) { |
@@ -263,22 +277,46 @@ static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u3 | |||
263 | hash_table[hash_index].tx_bytes += skb_len; | 277 | hash_table[hash_index].tx_bytes += skb_len; |
264 | } | 278 | } |
265 | 279 | ||
266 | _unlock_tx_hashtbl(bond); | ||
267 | |||
268 | return assigned_slave; | 280 | return assigned_slave; |
269 | } | 281 | } |
270 | 282 | ||
283 | /* Caller must hold bond lock for read */ | ||
284 | static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, | ||
285 | u32 skb_len) | ||
286 | { | ||
287 | struct slave *tx_slave; | ||
288 | /* | ||
289 | * We don't need to disable softirq here, becase | ||
290 | * tlb_choose_channel() is only called by bond_alb_xmit() | ||
291 | * which already has softirq disabled. | ||
292 | */ | ||
293 | _lock_tx_hashtbl(bond); | ||
294 | tx_slave = __tlb_choose_channel(bond, hash_index, skb_len); | ||
295 | _unlock_tx_hashtbl(bond); | ||
296 | return tx_slave; | ||
297 | } | ||
298 | |||
271 | /*********************** rlb specific functions ***************************/ | 299 | /*********************** rlb specific functions ***************************/ |
272 | static inline void _lock_rx_hashtbl(struct bonding *bond) | 300 | static inline void _lock_rx_hashtbl_bh(struct bonding *bond) |
273 | { | 301 | { |
274 | spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); | 302 | spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); |
275 | } | 303 | } |
276 | 304 | ||
277 | static inline void _unlock_rx_hashtbl(struct bonding *bond) | 305 | static inline void _unlock_rx_hashtbl_bh(struct bonding *bond) |
278 | { | 306 | { |
279 | spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); | 307 | spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); |
280 | } | 308 | } |
281 | 309 | ||
310 | static inline void _lock_rx_hashtbl(struct bonding *bond) | ||
311 | { | ||
312 | spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); | ||
313 | } | ||
314 | |||
315 | static inline void _unlock_rx_hashtbl(struct bonding *bond) | ||
316 | { | ||
317 | spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock)); | ||
318 | } | ||
319 | |||
282 | /* when an ARP REPLY is received from a client update its info | 320 | /* when an ARP REPLY is received from a client update its info |
283 | * in the rx_hashtbl | 321 | * in the rx_hashtbl |
284 | */ | 322 | */ |
@@ -288,7 +326,7 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) | |||
288 | struct rlb_client_info *client_info; | 326 | struct rlb_client_info *client_info; |
289 | u32 hash_index; | 327 | u32 hash_index; |
290 | 328 | ||
291 | _lock_rx_hashtbl(bond); | 329 | _lock_rx_hashtbl_bh(bond); |
292 | 330 | ||
293 | hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src)); | 331 | hash_index = _simple_hash((u8*)&(arp->ip_src), sizeof(arp->ip_src)); |
294 | client_info = &(bond_info->rx_hashtbl[hash_index]); | 332 | client_info = &(bond_info->rx_hashtbl[hash_index]); |
@@ -303,7 +341,7 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) | |||
303 | bond_info->rx_ntt = 1; | 341 | bond_info->rx_ntt = 1; |
304 | } | 342 | } |
305 | 343 | ||
306 | _unlock_rx_hashtbl(bond); | 344 | _unlock_rx_hashtbl_bh(bond); |
307 | } | 345 | } |
308 | 346 | ||
309 | static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, | 347 | static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond, |
@@ -401,7 +439,7 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave) | |||
401 | u32 index, next_index; | 439 | u32 index, next_index; |
402 | 440 | ||
403 | /* clear slave from rx_hashtbl */ | 441 | /* clear slave from rx_hashtbl */ |
404 | _lock_rx_hashtbl(bond); | 442 | _lock_rx_hashtbl_bh(bond); |
405 | 443 | ||
406 | rx_hash_table = bond_info->rx_hashtbl; | 444 | rx_hash_table = bond_info->rx_hashtbl; |
407 | index = bond_info->rx_hashtbl_head; | 445 | index = bond_info->rx_hashtbl_head; |
@@ -432,7 +470,7 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave) | |||
432 | } | 470 | } |
433 | } | 471 | } |
434 | 472 | ||
435 | _unlock_rx_hashtbl(bond); | 473 | _unlock_rx_hashtbl_bh(bond); |
436 | 474 | ||
437 | write_lock_bh(&bond->curr_slave_lock); | 475 | write_lock_bh(&bond->curr_slave_lock); |
438 | 476 | ||
@@ -489,7 +527,7 @@ static void rlb_update_rx_clients(struct bonding *bond) | |||
489 | struct rlb_client_info *client_info; | 527 | struct rlb_client_info *client_info; |
490 | u32 hash_index; | 528 | u32 hash_index; |
491 | 529 | ||
492 | _lock_rx_hashtbl(bond); | 530 | _lock_rx_hashtbl_bh(bond); |
493 | 531 | ||
494 | hash_index = bond_info->rx_hashtbl_head; | 532 | hash_index = bond_info->rx_hashtbl_head; |
495 | for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { | 533 | for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { |
@@ -507,7 +545,7 @@ static void rlb_update_rx_clients(struct bonding *bond) | |||
507 | */ | 545 | */ |
508 | bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY; | 546 | bond_info->rlb_update_delay_counter = RLB_UPDATE_DELAY; |
509 | 547 | ||
510 | _unlock_rx_hashtbl(bond); | 548 | _unlock_rx_hashtbl_bh(bond); |
511 | } | 549 | } |
512 | 550 | ||
513 | /* The slave was assigned a new mac address - update the clients */ | 551 | /* The slave was assigned a new mac address - update the clients */ |
@@ -518,7 +556,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla | |||
518 | int ntt = 0; | 556 | int ntt = 0; |
519 | u32 hash_index; | 557 | u32 hash_index; |
520 | 558 | ||
521 | _lock_rx_hashtbl(bond); | 559 | _lock_rx_hashtbl_bh(bond); |
522 | 560 | ||
523 | hash_index = bond_info->rx_hashtbl_head; | 561 | hash_index = bond_info->rx_hashtbl_head; |
524 | for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { | 562 | for (; hash_index != RLB_NULL_INDEX; hash_index = client_info->next) { |
@@ -538,7 +576,7 @@ static void rlb_req_update_slave_clients(struct bonding *bond, struct slave *sla | |||
538 | bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY; | 576 | bond_info->rlb_update_retry_counter = RLB_UPDATE_RETRY; |
539 | } | 577 | } |
540 | 578 | ||
541 | _unlock_rx_hashtbl(bond); | 579 | _unlock_rx_hashtbl_bh(bond); |
542 | } | 580 | } |
543 | 581 | ||
544 | /* mark all clients using src_ip to be updated */ | 582 | /* mark all clients using src_ip to be updated */ |
@@ -709,7 +747,7 @@ static void rlb_rebalance(struct bonding *bond) | |||
709 | int ntt; | 747 | int ntt; |
710 | u32 hash_index; | 748 | u32 hash_index; |
711 | 749 | ||
712 | _lock_rx_hashtbl(bond); | 750 | _lock_rx_hashtbl_bh(bond); |
713 | 751 | ||
714 | ntt = 0; | 752 | ntt = 0; |
715 | hash_index = bond_info->rx_hashtbl_head; | 753 | hash_index = bond_info->rx_hashtbl_head; |
@@ -727,7 +765,7 @@ static void rlb_rebalance(struct bonding *bond) | |||
727 | if (ntt) { | 765 | if (ntt) { |
728 | bond_info->rx_ntt = 1; | 766 | bond_info->rx_ntt = 1; |
729 | } | 767 | } |
730 | _unlock_rx_hashtbl(bond); | 768 | _unlock_rx_hashtbl_bh(bond); |
731 | } | 769 | } |
732 | 770 | ||
733 | /* Caller must hold rx_hashtbl lock */ | 771 | /* Caller must hold rx_hashtbl lock */ |
@@ -751,7 +789,7 @@ static int rlb_initialize(struct bonding *bond) | |||
751 | bond->dev->name); | 789 | bond->dev->name); |
752 | return -1; | 790 | return -1; |
753 | } | 791 | } |
754 | _lock_rx_hashtbl(bond); | 792 | _lock_rx_hashtbl_bh(bond); |
755 | 793 | ||
756 | bond_info->rx_hashtbl = new_hashtbl; | 794 | bond_info->rx_hashtbl = new_hashtbl; |
757 | 795 | ||
@@ -761,7 +799,7 @@ static int rlb_initialize(struct bonding *bond) | |||
761 | rlb_init_table_entry(bond_info->rx_hashtbl + i); | 799 | rlb_init_table_entry(bond_info->rx_hashtbl + i); |
762 | } | 800 | } |
763 | 801 | ||
764 | _unlock_rx_hashtbl(bond); | 802 | _unlock_rx_hashtbl_bh(bond); |
765 | 803 | ||
766 | /* register to receive ARPs */ | 804 | /* register to receive ARPs */ |
767 | bond->recv_probe = rlb_arp_recv; | 805 | bond->recv_probe = rlb_arp_recv; |
@@ -773,13 +811,13 @@ static void rlb_deinitialize(struct bonding *bond) | |||
773 | { | 811 | { |
774 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); | 812 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); |
775 | 813 | ||
776 | _lock_rx_hashtbl(bond); | 814 | _lock_rx_hashtbl_bh(bond); |
777 | 815 | ||
778 | kfree(bond_info->rx_hashtbl); | 816 | kfree(bond_info->rx_hashtbl); |
779 | bond_info->rx_hashtbl = NULL; | 817 | bond_info->rx_hashtbl = NULL; |
780 | bond_info->rx_hashtbl_head = RLB_NULL_INDEX; | 818 | bond_info->rx_hashtbl_head = RLB_NULL_INDEX; |
781 | 819 | ||
782 | _unlock_rx_hashtbl(bond); | 820 | _unlock_rx_hashtbl_bh(bond); |
783 | } | 821 | } |
784 | 822 | ||
785 | static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id) | 823 | static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id) |
@@ -787,7 +825,7 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id) | |||
787 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); | 825 | struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond)); |
788 | u32 curr_index; | 826 | u32 curr_index; |
789 | 827 | ||
790 | _lock_rx_hashtbl(bond); | 828 | _lock_rx_hashtbl_bh(bond); |
791 | 829 | ||
792 | curr_index = bond_info->rx_hashtbl_head; | 830 | curr_index = bond_info->rx_hashtbl_head; |
793 | while (curr_index != RLB_NULL_INDEX) { | 831 | while (curr_index != RLB_NULL_INDEX) { |
@@ -812,7 +850,7 @@ static void rlb_clear_vlan(struct bonding *bond, unsigned short vlan_id) | |||
812 | curr_index = next_index; | 850 | curr_index = next_index; |
813 | } | 851 | } |
814 | 852 | ||
815 | _unlock_rx_hashtbl(bond); | 853 | _unlock_rx_hashtbl_bh(bond); |
816 | } | 854 | } |
817 | 855 | ||
818 | /*********************** tlb/rlb shared functions *********************/ | 856 | /*********************** tlb/rlb shared functions *********************/ |
@@ -1320,7 +1358,9 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) | |||
1320 | res = bond_dev_queue_xmit(bond, skb, tx_slave->dev); | 1358 | res = bond_dev_queue_xmit(bond, skb, tx_slave->dev); |
1321 | } else { | 1359 | } else { |
1322 | if (tx_slave) { | 1360 | if (tx_slave) { |
1323 | tlb_clear_slave(bond, tx_slave, 0); | 1361 | _lock_tx_hashtbl(bond); |
1362 | __tlb_clear_slave(bond, tx_slave, 0); | ||
1363 | _unlock_tx_hashtbl(bond); | ||
1324 | } | 1364 | } |
1325 | } | 1365 | } |
1326 | 1366 | ||
diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index 9e8ba4f5636b..0f92e3567f68 100644 --- a/drivers/net/ethernet/8390/ax88796.c +++ b/drivers/net/ethernet/8390/ax88796.c | |||
@@ -623,7 +623,8 @@ static int ax_mii_init(struct net_device *dev) | |||
623 | 623 | ||
624 | ax->mii_bus->name = "ax88796_mii_bus"; | 624 | ax->mii_bus->name = "ax88796_mii_bus"; |
625 | ax->mii_bus->parent = dev->dev.parent; | 625 | ax->mii_bus->parent = dev->dev.parent; |
626 | snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); | 626 | snprintf(ax->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
627 | pdev->name, pdev->id); | ||
627 | 628 | ||
628 | ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | 629 | ax->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); |
629 | if (!ax->mii_bus->irq) { | 630 | if (!ax->mii_bus->irq) { |
diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index b6d69c91db96..d812a103e032 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c | |||
@@ -1670,7 +1670,8 @@ static int __devinit bfin_mii_bus_probe(struct platform_device *pdev) | |||
1670 | miibus->name = "bfin_mii_bus"; | 1670 | miibus->name = "bfin_mii_bus"; |
1671 | miibus->phy_mask = mii_bus_pd->phy_mask; | 1671 | miibus->phy_mask = mii_bus_pd->phy_mask; |
1672 | 1672 | ||
1673 | snprintf(miibus->id, MII_BUS_ID_SIZE, "0"); | 1673 | snprintf(miibus->id, MII_BUS_ID_SIZE, "%s-%x", |
1674 | pdev->name, pdev->id); | ||
1674 | miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | 1675 | miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); |
1675 | if (!miibus->irq) | 1676 | if (!miibus->irq) |
1676 | goto out_err_irq_alloc; | 1677 | goto out_err_irq_alloc; |
diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index cc9262be69c8..8b95dd314253 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c | |||
@@ -1171,7 +1171,8 @@ static int __devinit au1000_probe(struct platform_device *pdev) | |||
1171 | aup->mii_bus->write = au1000_mdiobus_write; | 1171 | aup->mii_bus->write = au1000_mdiobus_write; |
1172 | aup->mii_bus->reset = au1000_mdiobus_reset; | 1172 | aup->mii_bus->reset = au1000_mdiobus_reset; |
1173 | aup->mii_bus->name = "au1000_eth_mii"; | 1173 | aup->mii_bus->name = "au1000_eth_mii"; |
1174 | snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%x", aup->mac_id); | 1174 | snprintf(aup->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
1175 | pdev->name, aup->mac_id); | ||
1175 | aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | 1176 | aup->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); |
1176 | if (aup->mii_bus->irq == NULL) | 1177 | if (aup->mii_bus->irq == NULL) |
1177 | goto err_out; | 1178 | goto err_out; |
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index d44331eb07fe..986019b2c849 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c | |||
@@ -1727,7 +1727,7 @@ static int __devinit bcm_enet_probe(struct platform_device *pdev) | |||
1727 | bus->priv = priv; | 1727 | bus->priv = priv; |
1728 | bus->read = bcm_enet_mdio_read_phylib; | 1728 | bus->read = bcm_enet_mdio_read_phylib; |
1729 | bus->write = bcm_enet_mdio_write_phylib; | 1729 | bus->write = bcm_enet_mdio_write_phylib; |
1730 | sprintf(bus->id, "%d", priv->mac_id); | 1730 | sprintf(bus->id, "%s-%d", pdev->name, priv->mac_id); |
1731 | 1731 | ||
1732 | /* only probe bus where we think the PHY is, because | 1732 | /* only probe bus where we think the PHY is, because |
1733 | * the mdio read operation return 0 instead of 0xffff | 1733 | * the mdio read operation return 0 instead of 0xffff |
diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index 8fa7abc53ec6..084904ceaa30 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c | |||
@@ -2259,7 +2259,8 @@ static int sbmac_init(struct platform_device *pldev, long long base) | |||
2259 | } | 2259 | } |
2260 | 2260 | ||
2261 | sc->mii_bus->name = sbmac_mdio_string; | 2261 | sc->mii_bus->name = sbmac_mdio_string; |
2262 | snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx); | 2262 | snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
2263 | pldev->name, idx); | ||
2263 | sc->mii_bus->priv = sc; | 2264 | sc->mii_bus->priv = sc; |
2264 | sc->mii_bus->read = sbmac_mii_read; | 2265 | sc->mii_bus->read = sbmac_mii_read; |
2265 | sc->mii_bus->write = sbmac_mii_write; | 2266 | sc->mii_bus->write = sbmac_mii_write; |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index f3d5c65d99cf..23200680d4c1 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -243,7 +243,8 @@ static int macb_mii_init(struct macb *bp) | |||
243 | bp->mii_bus->read = &macb_mdio_read; | 243 | bp->mii_bus->read = &macb_mdio_read; |
244 | bp->mii_bus->write = &macb_mdio_write; | 244 | bp->mii_bus->write = &macb_mdio_write; |
245 | bp->mii_bus->reset = &macb_mdio_reset; | 245 | bp->mii_bus->reset = &macb_mdio_reset; |
246 | snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", bp->pdev->id); | 246 | snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
247 | bp->pdev->name, bp->pdev->id); | ||
247 | bp->mii_bus->priv = bp; | 248 | bp->mii_bus->priv = bp; |
248 | bp->mii_bus->parent = &bp->dev->dev; | 249 | bp->mii_bus->parent = &bp->dev->dev; |
249 | pdata = bp->pdev->dev.platform_data; | 250 | pdata = bp->pdev->dev.platform_data; |
diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c index ce88c0f399f6..925c9bafc9b9 100644 --- a/drivers/net/ethernet/dnet.c +++ b/drivers/net/ethernet/dnet.c | |||
@@ -325,7 +325,8 @@ static int dnet_mii_init(struct dnet *bp) | |||
325 | bp->mii_bus->write = &dnet_mdio_write; | 325 | bp->mii_bus->write = &dnet_mdio_write; |
326 | bp->mii_bus->reset = &dnet_mdio_reset; | 326 | bp->mii_bus->reset = &dnet_mdio_reset; |
327 | 327 | ||
328 | snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); | 328 | snprintf(bp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
329 | bp->pdev->name, bp->pdev->id); | ||
329 | 330 | ||
330 | bp->mii_bus->priv = bp; | 331 | bp->mii_bus->priv = bp; |
331 | 332 | ||
diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index ddcbbb34d1b9..7b25e9cf13f6 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c | |||
@@ -476,6 +476,7 @@ fec_restart(struct net_device *ndev, int duplex) | |||
476 | } else { | 476 | } else { |
477 | #ifdef FEC_MIIGSK_ENR | 477 | #ifdef FEC_MIIGSK_ENR |
478 | if (id_entry->driver_data & FEC_QUIRK_USE_GASKET) { | 478 | if (id_entry->driver_data & FEC_QUIRK_USE_GASKET) { |
479 | u32 cfgr; | ||
479 | /* disable the gasket and wait */ | 480 | /* disable the gasket and wait */ |
480 | writel(0, fep->hwp + FEC_MIIGSK_ENR); | 481 | writel(0, fep->hwp + FEC_MIIGSK_ENR); |
481 | while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4) | 482 | while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4) |
@@ -486,9 +487,11 @@ fec_restart(struct net_device *ndev, int duplex) | |||
486 | * RMII, 50 MHz, no loopback, no echo | 487 | * RMII, 50 MHz, no loopback, no echo |
487 | * MII, 25 MHz, no loopback, no echo | 488 | * MII, 25 MHz, no loopback, no echo |
488 | */ | 489 | */ |
489 | writel((fep->phy_interface == PHY_INTERFACE_MODE_RMII) ? | 490 | cfgr = (fep->phy_interface == PHY_INTERFACE_MODE_RMII) |
490 | 1 : 0, fep->hwp + FEC_MIIGSK_CFGR); | 491 | ? BM_MIIGSK_CFGR_RMII : BM_MIIGSK_CFGR_MII; |
491 | 492 | if (fep->phy_dev && fep->phy_dev->speed == SPEED_10) | |
493 | cfgr |= BM_MIIGSK_CFGR_FRCONT_10M; | ||
494 | writel(cfgr, fep->hwp + FEC_MIIGSK_CFGR); | ||
492 | 495 | ||
493 | /* re-enable the gasket */ | 496 | /* re-enable the gasket */ |
494 | writel(2, fep->hwp + FEC_MIIGSK_ENR); | 497 | writel(2, fep->hwp + FEC_MIIGSK_ENR); |
@@ -1077,7 +1080,8 @@ static int fec_enet_mii_init(struct platform_device *pdev) | |||
1077 | fep->mii_bus->read = fec_enet_mdio_read; | 1080 | fep->mii_bus->read = fec_enet_mdio_read; |
1078 | fep->mii_bus->write = fec_enet_mdio_write; | 1081 | fep->mii_bus->write = fec_enet_mdio_write; |
1079 | fep->mii_bus->reset = fec_enet_mdio_reset; | 1082 | fep->mii_bus->reset = fec_enet_mdio_reset; |
1080 | snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%x", fep->dev_id + 1); | 1083 | snprintf(fep->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
1084 | pdev->name, fep->dev_id + 1); | ||
1081 | fep->mii_bus->priv = fep; | 1085 | fep->mii_bus->priv = fep; |
1082 | fep->mii_bus->parent = &pdev->dev; | 1086 | fep->mii_bus->parent = &pdev->dev; |
1083 | 1087 | ||
diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 8b2c6d797e6d..8408c627b195 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h | |||
@@ -47,6 +47,10 @@ | |||
47 | #define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */ | 47 | #define FEC_MIIGSK_CFGR 0x300 /* MIIGSK Configuration reg */ |
48 | #define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */ | 48 | #define FEC_MIIGSK_ENR 0x308 /* MIIGSK Enable reg */ |
49 | 49 | ||
50 | #define BM_MIIGSK_CFGR_MII 0x00 | ||
51 | #define BM_MIIGSK_CFGR_RMII 0x01 | ||
52 | #define BM_MIIGSK_CFGR_FRCONT_10M 0x40 | ||
53 | |||
50 | #else | 54 | #else |
51 | 55 | ||
52 | #define FEC_ECNTRL 0x000 /* Ethernet control reg */ | 56 | #define FEC_ECNTRL 0x000 /* Ethernet control reg */ |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index e01cdaa722a9..39d160d353a4 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -1984,7 +1984,8 @@ static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb) | |||
1984 | return fcb; | 1984 | return fcb; |
1985 | } | 1985 | } |
1986 | 1986 | ||
1987 | static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb) | 1987 | static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb, |
1988 | int fcb_length) | ||
1988 | { | 1989 | { |
1989 | u8 flags = 0; | 1990 | u8 flags = 0; |
1990 | 1991 | ||
@@ -2006,7 +2007,7 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb) | |||
2006 | * frame (skb->data) and the start of the IP hdr. | 2007 | * frame (skb->data) and the start of the IP hdr. |
2007 | * l4os is the distance between the start of the | 2008 | * l4os is the distance between the start of the |
2008 | * l3 hdr and the l4 hdr */ | 2009 | * l3 hdr and the l4 hdr */ |
2009 | fcb->l3os = (u16)(skb_network_offset(skb) - GMAC_FCB_LEN); | 2010 | fcb->l3os = (u16)(skb_network_offset(skb) - fcb_length); |
2010 | fcb->l4os = skb_network_header_len(skb); | 2011 | fcb->l4os = skb_network_header_len(skb); |
2011 | 2012 | ||
2012 | fcb->flags = flags; | 2013 | fcb->flags = flags; |
@@ -2046,7 +2047,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2046 | int i, rq = 0, do_tstamp = 0; | 2047 | int i, rq = 0, do_tstamp = 0; |
2047 | u32 bufaddr; | 2048 | u32 bufaddr; |
2048 | unsigned long flags; | 2049 | unsigned long flags; |
2049 | unsigned int nr_frags, nr_txbds, length; | 2050 | unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN; |
2050 | 2051 | ||
2051 | /* | 2052 | /* |
2052 | * TOE=1 frames larger than 2500 bytes may see excess delays | 2053 | * TOE=1 frames larger than 2500 bytes may see excess delays |
@@ -2070,22 +2071,28 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2070 | 2071 | ||
2071 | /* check if time stamp should be generated */ | 2072 | /* check if time stamp should be generated */ |
2072 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && | 2073 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP && |
2073 | priv->hwts_tx_en)) | 2074 | priv->hwts_tx_en)) { |
2074 | do_tstamp = 1; | 2075 | do_tstamp = 1; |
2076 | fcb_length = GMAC_FCB_LEN + GMAC_TXPAL_LEN; | ||
2077 | } | ||
2075 | 2078 | ||
2076 | /* make space for additional header when fcb is needed */ | 2079 | /* make space for additional header when fcb is needed */ |
2077 | if (((skb->ip_summed == CHECKSUM_PARTIAL) || | 2080 | if (((skb->ip_summed == CHECKSUM_PARTIAL) || |
2078 | vlan_tx_tag_present(skb) || | 2081 | vlan_tx_tag_present(skb) || |
2079 | unlikely(do_tstamp)) && | 2082 | unlikely(do_tstamp)) && |
2080 | (skb_headroom(skb) < GMAC_FCB_LEN)) { | 2083 | (skb_headroom(skb) < fcb_length)) { |
2081 | struct sk_buff *skb_new; | 2084 | struct sk_buff *skb_new; |
2082 | 2085 | ||
2083 | skb_new = skb_realloc_headroom(skb, GMAC_FCB_LEN); | 2086 | skb_new = skb_realloc_headroom(skb, fcb_length); |
2084 | if (!skb_new) { | 2087 | if (!skb_new) { |
2085 | dev->stats.tx_errors++; | 2088 | dev->stats.tx_errors++; |
2086 | kfree_skb(skb); | 2089 | kfree_skb(skb); |
2087 | return NETDEV_TX_OK; | 2090 | return NETDEV_TX_OK; |
2088 | } | 2091 | } |
2092 | |||
2093 | /* Steal sock reference for processing TX time stamps */ | ||
2094 | swap(skb_new->sk, skb->sk); | ||
2095 | swap(skb_new->destructor, skb->destructor); | ||
2089 | kfree_skb(skb); | 2096 | kfree_skb(skb); |
2090 | skb = skb_new; | 2097 | skb = skb_new; |
2091 | } | 2098 | } |
@@ -2154,6 +2161,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2154 | lstatus = txbdp_start->lstatus; | 2161 | lstatus = txbdp_start->lstatus; |
2155 | } | 2162 | } |
2156 | 2163 | ||
2164 | /* Add TxPAL between FCB and frame if required */ | ||
2165 | if (unlikely(do_tstamp)) { | ||
2166 | skb_push(skb, GMAC_TXPAL_LEN); | ||
2167 | memset(skb->data, 0, GMAC_TXPAL_LEN); | ||
2168 | } | ||
2169 | |||
2157 | /* Set up checksumming */ | 2170 | /* Set up checksumming */ |
2158 | if (CHECKSUM_PARTIAL == skb->ip_summed) { | 2171 | if (CHECKSUM_PARTIAL == skb->ip_summed) { |
2159 | fcb = gfar_add_fcb(skb); | 2172 | fcb = gfar_add_fcb(skb); |
@@ -2164,7 +2177,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2164 | skb_checksum_help(skb); | 2177 | skb_checksum_help(skb); |
2165 | } else { | 2178 | } else { |
2166 | lstatus |= BD_LFLAG(TXBD_TOE); | 2179 | lstatus |= BD_LFLAG(TXBD_TOE); |
2167 | gfar_tx_checksum(skb, fcb); | 2180 | gfar_tx_checksum(skb, fcb, fcb_length); |
2168 | } | 2181 | } |
2169 | } | 2182 | } |
2170 | 2183 | ||
@@ -2196,9 +2209,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2196 | * the full frame length. | 2209 | * the full frame length. |
2197 | */ | 2210 | */ |
2198 | if (unlikely(do_tstamp)) { | 2211 | if (unlikely(do_tstamp)) { |
2199 | txbdp_tstamp->bufPtr = txbdp_start->bufPtr + GMAC_FCB_LEN; | 2212 | txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_length; |
2200 | txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) | | 2213 | txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) | |
2201 | (skb_headlen(skb) - GMAC_FCB_LEN); | 2214 | (skb_headlen(skb) - fcb_length); |
2202 | lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN; | 2215 | lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN; |
2203 | } else { | 2216 | } else { |
2204 | lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); | 2217 | lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); |
@@ -2490,7 +2503,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2490 | 2503 | ||
2491 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { | 2504 | if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) { |
2492 | next = next_txbd(bdp, base, tx_ring_size); | 2505 | next = next_txbd(bdp, base, tx_ring_size); |
2493 | buflen = next->length + GMAC_FCB_LEN; | 2506 | buflen = next->length + GMAC_FCB_LEN + GMAC_TXPAL_LEN; |
2494 | } else | 2507 | } else |
2495 | buflen = bdp->length; | 2508 | buflen = bdp->length; |
2496 | 2509 | ||
@@ -2502,6 +2515,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2502 | u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7); | 2515 | u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7); |
2503 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); | 2516 | memset(&shhwtstamps, 0, sizeof(shhwtstamps)); |
2504 | shhwtstamps.hwtstamp = ns_to_ktime(*ns); | 2517 | shhwtstamps.hwtstamp = ns_to_ktime(*ns); |
2518 | skb_pull(skb, GMAC_FCB_LEN + GMAC_TXPAL_LEN); | ||
2505 | skb_tstamp_tx(skb, &shhwtstamps); | 2519 | skb_tstamp_tx(skb, &shhwtstamps); |
2506 | bdp->lstatus &= BD_LFLAG(TXBD_WRAP); | 2520 | bdp->lstatus &= BD_LFLAG(TXBD_WRAP); |
2507 | bdp = next; | 2521 | bdp = next; |
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index fe7ac3a83194..40c33a7554c0 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h | |||
@@ -63,6 +63,9 @@ struct ethtool_rx_list { | |||
63 | /* Length for FCB */ | 63 | /* Length for FCB */ |
64 | #define GMAC_FCB_LEN 8 | 64 | #define GMAC_FCB_LEN 8 |
65 | 65 | ||
66 | /* Length for TxPAL */ | ||
67 | #define GMAC_TXPAL_LEN 16 | ||
68 | |||
66 | /* Default padding amount */ | 69 | /* Default padding amount */ |
67 | #define DEFAULT_PADDING 2 | 70 | #define DEFAULT_PADDING 2 |
68 | 71 | ||
diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 0b3567ab8121..85e2c6cd9708 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c | |||
@@ -98,6 +98,7 @@ struct ltq_etop_chan { | |||
98 | 98 | ||
99 | struct ltq_etop_priv { | 99 | struct ltq_etop_priv { |
100 | struct net_device *netdev; | 100 | struct net_device *netdev; |
101 | struct platform_device *pdev; | ||
101 | struct ltq_eth_data *pldata; | 102 | struct ltq_eth_data *pldata; |
102 | struct resource *res; | 103 | struct resource *res; |
103 | 104 | ||
@@ -436,7 +437,8 @@ ltq_etop_mdio_init(struct net_device *dev) | |||
436 | priv->mii_bus->read = ltq_etop_mdio_rd; | 437 | priv->mii_bus->read = ltq_etop_mdio_rd; |
437 | priv->mii_bus->write = ltq_etop_mdio_wr; | 438 | priv->mii_bus->write = ltq_etop_mdio_wr; |
438 | priv->mii_bus->name = "ltq_mii"; | 439 | priv->mii_bus->name = "ltq_mii"; |
439 | snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0); | 440 | snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
441 | priv->pdev->name, priv->pdev->id); | ||
440 | priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | 442 | priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); |
441 | if (!priv->mii_bus->irq) { | 443 | if (!priv->mii_bus->irq) { |
442 | err = -ENOMEM; | 444 | err = -ENOMEM; |
@@ -734,6 +736,7 @@ ltq_etop_probe(struct platform_device *pdev) | |||
734 | dev->ethtool_ops = <q_etop_ethtool_ops; | 736 | dev->ethtool_ops = <q_etop_ethtool_ops; |
735 | priv = netdev_priv(dev); | 737 | priv = netdev_priv(dev); |
736 | priv->res = res; | 738 | priv->res = res; |
739 | priv->pdev = pdev; | ||
737 | priv->pldata = dev_get_platdata(&pdev->dev); | 740 | priv->pldata = dev_get_platdata(&pdev->dev); |
738 | priv->netdev = dev; | 741 | priv->netdev = dev; |
739 | spin_lock_init(&priv->lock); | 742 | spin_lock_init(&priv->lock); |
diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 80aab4e5d695..9c049d2cb97d 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c | |||
@@ -2613,7 +2613,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) | |||
2613 | msp->smi_bus->name = "mv643xx_eth smi"; | 2613 | msp->smi_bus->name = "mv643xx_eth smi"; |
2614 | msp->smi_bus->read = smi_bus_read; | 2614 | msp->smi_bus->read = smi_bus_read; |
2615 | msp->smi_bus->write = smi_bus_write, | 2615 | msp->smi_bus->write = smi_bus_write, |
2616 | snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id); | 2616 | snprintf(msp->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d", |
2617 | pdev->name, pdev->id); | ||
2617 | msp->smi_bus->parent = &pdev->dev; | 2618 | msp->smi_bus->parent = &pdev->dev; |
2618 | msp->smi_bus->phy_mask = 0xffffffff; | 2619 | msp->smi_bus->phy_mask = 0xffffffff; |
2619 | if (mdiobus_register(msp->smi_bus) < 0) | 2620 | if (mdiobus_register(msp->smi_bus) < 0) |
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 5ec409e3da09..953ba5851f7b 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c | |||
@@ -1552,7 +1552,8 @@ static int pxa168_eth_probe(struct platform_device *pdev) | |||
1552 | pep->smi_bus->name = "pxa168_eth smi"; | 1552 | pep->smi_bus->name = "pxa168_eth smi"; |
1553 | pep->smi_bus->read = pxa168_smi_read; | 1553 | pep->smi_bus->read = pxa168_smi_read; |
1554 | pep->smi_bus->write = pxa168_smi_write; | 1554 | pep->smi_bus->write = pxa168_smi_write; |
1555 | snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id); | 1555 | snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d", |
1556 | pdev->name, pdev->id); | ||
1556 | pep->smi_bus->parent = &pdev->dev; | 1557 | pep->smi_bus->parent = &pdev->dev; |
1557 | pep->smi_bus->phy_mask = 0xffffffff; | 1558 | pep->smi_bus->phy_mask = 0xffffffff; |
1558 | err = mdiobus_register(pep->smi_bus); | 1559 | err = mdiobus_register(pep->smi_bus); |
diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index 6ed09a85f035..e52cd310ae76 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c | |||
@@ -746,7 +746,7 @@ | |||
746 | #define MAC_ADDR_ORDER(i) (ETH_ALEN - 1 - (i)) | 746 | #define MAC_ADDR_ORDER(i) (ETH_ALEN - 1 - (i)) |
747 | 747 | ||
748 | #define MAX_ETHERNET_BODY_SIZE 1500 | 748 | #define MAX_ETHERNET_BODY_SIZE 1500 |
749 | #define ETHERNET_HEADER_SIZE 14 | 749 | #define ETHERNET_HEADER_SIZE (14 + VLAN_HLEN) |
750 | 750 | ||
751 | #define MAX_ETHERNET_PACKET_SIZE \ | 751 | #define MAX_ETHERNET_PACKET_SIZE \ |
752 | (MAX_ETHERNET_BODY_SIZE + ETHERNET_HEADER_SIZE) | 752 | (MAX_ETHERNET_BODY_SIZE + ETHERNET_HEADER_SIZE) |
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index fc9bda9bc36c..6ece4295d78f 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -1702,7 +1702,8 @@ static int sh_mdio_init(struct net_device *ndev, int id, | |||
1702 | /* Hook up MII support for ethtool */ | 1702 | /* Hook up MII support for ethtool */ |
1703 | mdp->mii_bus->name = "sh_mii"; | 1703 | mdp->mii_bus->name = "sh_mii"; |
1704 | mdp->mii_bus->parent = &ndev->dev; | 1704 | mdp->mii_bus->parent = &ndev->dev; |
1705 | snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%x", id); | 1705 | snprintf(mdp->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
1706 | mdp->pdev->name, pdid); | ||
1706 | 1707 | ||
1707 | /* PHY IRQ */ | 1708 | /* PHY IRQ */ |
1708 | mdp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); | 1709 | mdp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); |
diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c index a7ff8ea342b4..22e9c0181ce8 100644 --- a/drivers/net/ethernet/s6gmac.c +++ b/drivers/net/ethernet/s6gmac.c | |||
@@ -1004,7 +1004,7 @@ static int __devinit s6gmac_probe(struct platform_device *pdev) | |||
1004 | mb->write = s6mii_write; | 1004 | mb->write = s6mii_write; |
1005 | mb->reset = s6mii_reset; | 1005 | mb->reset = s6mii_reset; |
1006 | mb->priv = pd; | 1006 | mb->priv = pd; |
1007 | snprintf(mb->id, MII_BUS_ID_SIZE, "0"); | 1007 | snprintf(mb->id, MII_BUS_ID_SIZE, "%s-%x", pdev->name, pdev->id); |
1008 | mb->phy_mask = ~(1 << 0); | 1008 | mb->phy_mask = ~(1 << 0); |
1009 | mb->irq = &pd->mii.irq[0]; | 1009 | mb->irq = &pd->mii.irq[0]; |
1010 | for (i = 0; i < PHY_MAX_ADDR; i++) { | 1010 | for (i = 0; i < PHY_MAX_ADDR; i++) { |
diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 9d0b8ced0234..24d2df068d71 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c | |||
@@ -1044,7 +1044,8 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev, | |||
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | pdata->mii_bus->name = SMSC_MDIONAME; | 1046 | pdata->mii_bus->name = SMSC_MDIONAME; |
1047 | snprintf(pdata->mii_bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); | 1047 | snprintf(pdata->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
1048 | pdev->name, pdev->id); | ||
1048 | pdata->mii_bus->priv = pdata; | 1049 | pdata->mii_bus->priv = pdata; |
1049 | pdata->mii_bus->read = smsc911x_mii_read; | 1050 | pdata->mii_bus->read = smsc911x_mii_read; |
1050 | pdata->mii_bus->write = smsc911x_mii_write; | 1051 | pdata->mii_bus->write = smsc911x_mii_write; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c index 41e6b33e1b08..c07cfe989f6e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/mmc_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/mmc_core.c | |||
@@ -22,6 +22,7 @@ | |||
22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> | 22 | Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
23 | *******************************************************************************/ | 23 | *******************************************************************************/ |
24 | 24 | ||
25 | #include <linux/kernel.h> | ||
25 | #include <linux/io.h> | 26 | #include <linux/io.h> |
26 | #include "mmc.h" | 27 | #include "mmc.h" |
27 | 28 | ||
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 3738b4700548..96fa2da30763 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -307,7 +307,7 @@ static int stmmac_init_phy(struct net_device *dev) | |||
307 | priv->speed = 0; | 307 | priv->speed = 0; |
308 | priv->oldduplex = -1; | 308 | priv->oldduplex = -1; |
309 | 309 | ||
310 | snprintf(bus_id, MII_BUS_ID_SIZE, "%x", priv->plat->bus_id); | 310 | snprintf(bus_id, MII_BUS_ID_SIZE, "stmmac-%x", priv->plat->bus_id); |
311 | snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, | 311 | snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, bus_id, |
312 | priv->plat->phy_addr); | 312 | priv->plat->phy_addr); |
313 | pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); | 313 | pr_debug("stmmac_init_phy: trying to attach to %s\n", phy_id); |
@@ -772,7 +772,7 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv) | |||
772 | dwmac_mmc_ctrl(priv->ioaddr, mode); | 772 | dwmac_mmc_ctrl(priv->ioaddr, mode); |
773 | memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); | 773 | memset(&priv->mmc, 0, sizeof(struct stmmac_counters)); |
774 | } else | 774 | } else |
775 | pr_info(" No MAC Management Counters available"); | 775 | pr_info(" No MAC Management Counters available\n"); |
776 | } | 776 | } |
777 | 777 | ||
778 | static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) | 778 | static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index 51f441233962..da4a1042523a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | |||
@@ -158,7 +158,8 @@ int stmmac_mdio_register(struct net_device *ndev) | |||
158 | new_bus->read = &stmmac_mdio_read; | 158 | new_bus->read = &stmmac_mdio_read; |
159 | new_bus->write = &stmmac_mdio_write; | 159 | new_bus->write = &stmmac_mdio_write; |
160 | new_bus->reset = &stmmac_mdio_reset; | 160 | new_bus->reset = &stmmac_mdio_reset; |
161 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", mdio_bus_data->bus_id); | 161 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
162 | new_bus->name, mdio_bus_data->bus_id); | ||
162 | new_bus->priv = ndev; | 163 | new_bus->priv = ndev; |
163 | new_bus->irq = irqlist; | 164 | new_bus->irq = irqlist; |
164 | new_bus->phy_mask = mdio_bus_data->phy_mask; | 165 | new_bus->phy_mask = mdio_bus_data->phy_mask; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 7b1594f4944e..1ac83243649a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -62,7 +62,7 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) | |||
62 | priv = stmmac_dvr_probe(&(pdev->dev), plat_dat); | 62 | priv = stmmac_dvr_probe(&(pdev->dev), plat_dat); |
63 | if (!priv) { | 63 | if (!priv) { |
64 | pr_err("%s: main drivr probe failed", __func__); | 64 | pr_err("%s: main drivr probe failed", __func__); |
65 | goto out_release_region; | 65 | goto out_unmap; |
66 | } | 66 | } |
67 | 67 | ||
68 | priv->ioaddr = addr; | 68 | priv->ioaddr = addr; |
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c index aaac0c7ad111..4d9a28ffd3c3 100644 --- a/drivers/net/ethernet/ti/cpmac.c +++ b/drivers/net/ethernet/ti/cpmac.c | |||
@@ -1269,7 +1269,7 @@ int __devinit cpmac_init(void) | |||
1269 | } | 1269 | } |
1270 | 1270 | ||
1271 | cpmac_mii->phy_mask = ~(mask | 0x80000000); | 1271 | cpmac_mii->phy_mask = ~(mask | 0x80000000); |
1272 | snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "1"); | 1272 | snprintf(cpmac_mii->id, MII_BUS_ID_SIZE, "cpmac-1"); |
1273 | 1273 | ||
1274 | res = mdiobus_register(cpmac_mii); | 1274 | res = mdiobus_register(cpmac_mii); |
1275 | if (res) | 1275 | if (res) |
diff --git a/drivers/net/ethernet/ti/davinci_mdio.c b/drivers/net/ethernet/ti/davinci_mdio.c index 7615040df756..ef7c9c17bfff 100644 --- a/drivers/net/ethernet/ti/davinci_mdio.c +++ b/drivers/net/ethernet/ti/davinci_mdio.c | |||
@@ -313,7 +313,8 @@ static int __devinit davinci_mdio_probe(struct platform_device *pdev) | |||
313 | data->bus->reset = davinci_mdio_reset, | 313 | data->bus->reset = davinci_mdio_reset, |
314 | data->bus->parent = dev; | 314 | data->bus->parent = dev; |
315 | data->bus->priv = data; | 315 | data->bus->priv = data; |
316 | snprintf(data->bus->id, MII_BUS_ID_SIZE, "%x", pdev->id); | 316 | snprintf(data->bus->id, MII_BUS_ID_SIZE, "%s-%x", |
317 | pdev->name, pdev->id); | ||
317 | 318 | ||
318 | data->clk = clk_get(dev, NULL); | 319 | data->clk = clk_get(dev, NULL); |
319 | if (IS_ERR(data->clk)) { | 320 | if (IS_ERR(data->clk)) { |
diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c index a9ce01bafd20..164fb775d7b3 100644 --- a/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/drivers/net/ethernet/tundra/tsi108_eth.c | |||
@@ -1604,7 +1604,7 @@ tsi108_init_one(struct platform_device *pdev) | |||
1604 | data->phyregs = ioremap(einfo->phyregs, 0x400); | 1604 | data->phyregs = ioremap(einfo->phyregs, 0x400); |
1605 | if (NULL == data->phyregs) { | 1605 | if (NULL == data->phyregs) { |
1606 | err = -ENOMEM; | 1606 | err = -ENOMEM; |
1607 | goto regs_fail; | 1607 | goto phyregs_fail; |
1608 | } | 1608 | } |
1609 | /* MII setup */ | 1609 | /* MII setup */ |
1610 | data->mii_if.dev = dev; | 1610 | data->mii_if.dev = dev; |
@@ -1663,9 +1663,11 @@ tsi108_init_one(struct platform_device *pdev) | |||
1663 | return 0; | 1663 | return 0; |
1664 | 1664 | ||
1665 | register_fail: | 1665 | register_fail: |
1666 | iounmap(data->regs); | ||
1667 | iounmap(data->phyregs); | 1666 | iounmap(data->phyregs); |
1668 | 1667 | ||
1668 | phyregs_fail: | ||
1669 | iounmap(data->regs); | ||
1670 | |||
1669 | regs_fail: | 1671 | regs_fail: |
1670 | free_netdev(dev); | 1672 | free_netdev(dev); |
1671 | return err; | 1673 | return err; |
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index 5c4983b2870a..10b18eb63d25 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c | |||
@@ -39,10 +39,9 @@ | |||
39 | 39 | ||
40 | /* A few user-configurable values. | 40 | /* A few user-configurable values. |
41 | These may be modified when a driver module is loaded. */ | 41 | These may be modified when a driver module is loaded. */ |
42 | 42 | static int debug = 0; | |
43 | #define DEBUG | 43 | #define RHINE_MSG_DEFAULT \ |
44 | static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ | 44 | (0x0000) |
45 | static int max_interrupt_work = 20; | ||
46 | 45 | ||
47 | /* Set the copy breakpoint for the copy-only-tiny-frames scheme. | 46 | /* Set the copy breakpoint for the copy-only-tiny-frames scheme. |
48 | Setting to > 1518 effectively disables this feature. */ | 47 | Setting to > 1518 effectively disables this feature. */ |
@@ -128,12 +127,10 @@ MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); | |||
128 | MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver"); | 127 | MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver"); |
129 | MODULE_LICENSE("GPL"); | 128 | MODULE_LICENSE("GPL"); |
130 | 129 | ||
131 | module_param(max_interrupt_work, int, 0); | ||
132 | module_param(debug, int, 0); | 130 | module_param(debug, int, 0); |
133 | module_param(rx_copybreak, int, 0); | 131 | module_param(rx_copybreak, int, 0); |
134 | module_param(avoid_D3, bool, 0); | 132 | module_param(avoid_D3, bool, 0); |
135 | MODULE_PARM_DESC(max_interrupt_work, "VIA Rhine maximum events handled per interrupt"); | 133 | MODULE_PARM_DESC(debug, "VIA Rhine debug message flags"); |
136 | MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)"); | ||
137 | MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames"); | 134 | MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames"); |
138 | MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)"); | 135 | MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)"); |
139 | 136 | ||
@@ -351,16 +348,25 @@ static const int mmio_verify_registers[] = { | |||
351 | 348 | ||
352 | /* Bits in the interrupt status/mask registers. */ | 349 | /* Bits in the interrupt status/mask registers. */ |
353 | enum intr_status_bits { | 350 | enum intr_status_bits { |
354 | IntrRxDone=0x0001, IntrRxErr=0x0004, IntrRxEmpty=0x0020, | 351 | IntrRxDone = 0x0001, |
355 | IntrTxDone=0x0002, IntrTxError=0x0008, IntrTxUnderrun=0x0210, | 352 | IntrTxDone = 0x0002, |
356 | IntrPCIErr=0x0040, | 353 | IntrRxErr = 0x0004, |
357 | IntrStatsMax=0x0080, IntrRxEarly=0x0100, | 354 | IntrTxError = 0x0008, |
358 | IntrRxOverflow=0x0400, IntrRxDropped=0x0800, IntrRxNoBuf=0x1000, | 355 | IntrRxEmpty = 0x0020, |
359 | IntrTxAborted=0x2000, IntrLinkChange=0x4000, | 356 | IntrPCIErr = 0x0040, |
360 | IntrRxWakeUp=0x8000, | 357 | IntrStatsMax = 0x0080, |
361 | IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260, | 358 | IntrRxEarly = 0x0100, |
362 | IntrTxDescRace=0x080000, /* mapped from IntrStatus2 */ | 359 | IntrTxUnderrun = 0x0210, |
363 | IntrTxErrSummary=0x082218, | 360 | IntrRxOverflow = 0x0400, |
361 | IntrRxDropped = 0x0800, | ||
362 | IntrRxNoBuf = 0x1000, | ||
363 | IntrTxAborted = 0x2000, | ||
364 | IntrLinkChange = 0x4000, | ||
365 | IntrRxWakeUp = 0x8000, | ||
366 | IntrTxDescRace = 0x080000, /* mapped from IntrStatus2 */ | ||
367 | IntrNormalSummary = IntrRxDone | IntrTxDone, | ||
368 | IntrTxErrSummary = IntrTxDescRace | IntrTxAborted | IntrTxError | | ||
369 | IntrTxUnderrun, | ||
364 | }; | 370 | }; |
365 | 371 | ||
366 | /* Bits in WOLcrSet/WOLcrClr and PwrcsrSet/PwrcsrClr */ | 372 | /* Bits in WOLcrSet/WOLcrClr and PwrcsrSet/PwrcsrClr */ |
@@ -439,8 +445,13 @@ struct rhine_private { | |||
439 | struct net_device *dev; | 445 | struct net_device *dev; |
440 | struct napi_struct napi; | 446 | struct napi_struct napi; |
441 | spinlock_t lock; | 447 | spinlock_t lock; |
448 | struct mutex task_lock; | ||
449 | bool task_enable; | ||
450 | struct work_struct slow_event_task; | ||
442 | struct work_struct reset_task; | 451 | struct work_struct reset_task; |
443 | 452 | ||
453 | u32 msg_enable; | ||
454 | |||
444 | /* Frequently used values: keep some adjacent for cache effect. */ | 455 | /* Frequently used values: keep some adjacent for cache effect. */ |
445 | u32 quirks; | 456 | u32 quirks; |
446 | struct rx_desc *rx_head_desc; | 457 | struct rx_desc *rx_head_desc; |
@@ -476,41 +487,50 @@ static int mdio_read(struct net_device *dev, int phy_id, int location); | |||
476 | static void mdio_write(struct net_device *dev, int phy_id, int location, int value); | 487 | static void mdio_write(struct net_device *dev, int phy_id, int location, int value); |
477 | static int rhine_open(struct net_device *dev); | 488 | static int rhine_open(struct net_device *dev); |
478 | static void rhine_reset_task(struct work_struct *work); | 489 | static void rhine_reset_task(struct work_struct *work); |
490 | static void rhine_slow_event_task(struct work_struct *work); | ||
479 | static void rhine_tx_timeout(struct net_device *dev); | 491 | static void rhine_tx_timeout(struct net_device *dev); |
480 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, | 492 | static netdev_tx_t rhine_start_tx(struct sk_buff *skb, |
481 | struct net_device *dev); | 493 | struct net_device *dev); |
482 | static irqreturn_t rhine_interrupt(int irq, void *dev_instance); | 494 | static irqreturn_t rhine_interrupt(int irq, void *dev_instance); |
483 | static void rhine_tx(struct net_device *dev); | 495 | static void rhine_tx(struct net_device *dev); |
484 | static int rhine_rx(struct net_device *dev, int limit); | 496 | static int rhine_rx(struct net_device *dev, int limit); |
485 | static void rhine_error(struct net_device *dev, int intr_status); | ||
486 | static void rhine_set_rx_mode(struct net_device *dev); | 497 | static void rhine_set_rx_mode(struct net_device *dev); |
487 | static struct net_device_stats *rhine_get_stats(struct net_device *dev); | 498 | static struct net_device_stats *rhine_get_stats(struct net_device *dev); |
488 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 499 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
489 | static const struct ethtool_ops netdev_ethtool_ops; | 500 | static const struct ethtool_ops netdev_ethtool_ops; |
490 | static int rhine_close(struct net_device *dev); | 501 | static int rhine_close(struct net_device *dev); |
491 | static void rhine_shutdown (struct pci_dev *pdev); | ||
492 | static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid); | 502 | static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid); |
493 | static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid); | 503 | static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid); |
494 | static void rhine_set_cam(void __iomem *ioaddr, int idx, u8 *addr); | 504 | static void rhine_restart_tx(struct net_device *dev); |
495 | static void rhine_set_vlan_cam(void __iomem *ioaddr, int idx, u8 *addr); | 505 | |
496 | static void rhine_set_cam_mask(void __iomem *ioaddr, u32 mask); | 506 | static void rhine_wait_bit(struct rhine_private *rp, u8 reg, u8 mask, bool high) |
497 | static void rhine_set_vlan_cam_mask(void __iomem *ioaddr, u32 mask); | 507 | { |
498 | static void rhine_init_cam_filter(struct net_device *dev); | 508 | void __iomem *ioaddr = rp->base; |
499 | static void rhine_update_vcam(struct net_device *dev); | 509 | int i; |
500 | 510 | ||
501 | #define RHINE_WAIT_FOR(condition) \ | 511 | for (i = 0; i < 1024; i++) { |
502 | do { \ | 512 | if (high ^ !!(ioread8(ioaddr + reg) & mask)) |
503 | int i = 1024; \ | 513 | break; |
504 | while (!(condition) && --i) \ | 514 | udelay(10); |
505 | ; \ | 515 | } |
506 | if (debug > 1 && i < 512) \ | 516 | if (i > 64) { |
507 | pr_info("%4d cycles used @ %s:%d\n", \ | 517 | netif_dbg(rp, hw, rp->dev, "%s bit wait (%02x/%02x) cycle " |
508 | 1024 - i, __func__, __LINE__); \ | 518 | "count: %04d\n", high ? "high" : "low", reg, mask, i); |
509 | } while (0) | 519 | } |
510 | 520 | } | |
511 | static inline u32 get_intr_status(struct net_device *dev) | 521 | |
522 | static void rhine_wait_bit_high(struct rhine_private *rp, u8 reg, u8 mask) | ||
523 | { | ||
524 | rhine_wait_bit(rp, reg, mask, true); | ||
525 | } | ||
526 | |||
527 | static void rhine_wait_bit_low(struct rhine_private *rp, u8 reg, u8 mask) | ||
528 | { | ||
529 | rhine_wait_bit(rp, reg, mask, false); | ||
530 | } | ||
531 | |||
532 | static u32 rhine_get_events(struct rhine_private *rp) | ||
512 | { | 533 | { |
513 | struct rhine_private *rp = netdev_priv(dev); | ||
514 | void __iomem *ioaddr = rp->base; | 534 | void __iomem *ioaddr = rp->base; |
515 | u32 intr_status; | 535 | u32 intr_status; |
516 | 536 | ||
@@ -521,6 +541,16 @@ static inline u32 get_intr_status(struct net_device *dev) | |||
521 | return intr_status; | 541 | return intr_status; |
522 | } | 542 | } |
523 | 543 | ||
544 | static void rhine_ack_events(struct rhine_private *rp, u32 mask) | ||
545 | { | ||
546 | void __iomem *ioaddr = rp->base; | ||
547 | |||
548 | if (rp->quirks & rqStatusWBRace) | ||
549 | iowrite8(mask >> 16, ioaddr + IntrStatus2); | ||
550 | iowrite16(mask, ioaddr + IntrStatus); | ||
551 | mmiowb(); | ||
552 | } | ||
553 | |||
524 | /* | 554 | /* |
525 | * Get power related registers into sane state. | 555 | * Get power related registers into sane state. |
526 | * Notify user about past WOL event. | 556 | * Notify user about past WOL event. |
@@ -585,6 +615,7 @@ static void rhine_chip_reset(struct net_device *dev) | |||
585 | { | 615 | { |
586 | struct rhine_private *rp = netdev_priv(dev); | 616 | struct rhine_private *rp = netdev_priv(dev); |
587 | void __iomem *ioaddr = rp->base; | 617 | void __iomem *ioaddr = rp->base; |
618 | u8 cmd1; | ||
588 | 619 | ||
589 | iowrite8(Cmd1Reset, ioaddr + ChipCmd1); | 620 | iowrite8(Cmd1Reset, ioaddr + ChipCmd1); |
590 | IOSYNC; | 621 | IOSYNC; |
@@ -597,13 +628,12 @@ static void rhine_chip_reset(struct net_device *dev) | |||
597 | iowrite8(0x40, ioaddr + MiscCmd); | 628 | iowrite8(0x40, ioaddr + MiscCmd); |
598 | 629 | ||
599 | /* Reset can take somewhat longer (rare) */ | 630 | /* Reset can take somewhat longer (rare) */ |
600 | RHINE_WAIT_FOR(!(ioread8(ioaddr + ChipCmd1) & Cmd1Reset)); | 631 | rhine_wait_bit_low(rp, ChipCmd1, Cmd1Reset); |
601 | } | 632 | } |
602 | 633 | ||
603 | if (debug > 1) | 634 | cmd1 = ioread8(ioaddr + ChipCmd1); |
604 | netdev_info(dev, "Reset %s\n", | 635 | netif_info(rp, hw, dev, "Reset %s\n", (cmd1 & Cmd1Reset) ? |
605 | (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) ? | 636 | "failed" : "succeeded"); |
606 | "failed" : "succeeded"); | ||
607 | } | 637 | } |
608 | 638 | ||
609 | #ifdef USE_MMIO | 639 | #ifdef USE_MMIO |
@@ -629,9 +659,15 @@ static void __devinit rhine_reload_eeprom(long pioaddr, struct net_device *dev) | |||
629 | { | 659 | { |
630 | struct rhine_private *rp = netdev_priv(dev); | 660 | struct rhine_private *rp = netdev_priv(dev); |
631 | void __iomem *ioaddr = rp->base; | 661 | void __iomem *ioaddr = rp->base; |
662 | int i; | ||
632 | 663 | ||
633 | outb(0x20, pioaddr + MACRegEEcsr); | 664 | outb(0x20, pioaddr + MACRegEEcsr); |
634 | RHINE_WAIT_FOR(!(inb(pioaddr + MACRegEEcsr) & 0x20)); | 665 | for (i = 0; i < 1024; i++) { |
666 | if (!(inb(pioaddr + MACRegEEcsr) & 0x20)) | ||
667 | break; | ||
668 | } | ||
669 | if (i > 512) | ||
670 | pr_info("%4d cycles used @ %s:%d\n", i, __func__, __LINE__); | ||
635 | 671 | ||
636 | #ifdef USE_MMIO | 672 | #ifdef USE_MMIO |
637 | /* | 673 | /* |
@@ -657,23 +693,127 @@ static void rhine_poll(struct net_device *dev) | |||
657 | } | 693 | } |
658 | #endif | 694 | #endif |
659 | 695 | ||
696 | static void rhine_kick_tx_threshold(struct rhine_private *rp) | ||
697 | { | ||
698 | if (rp->tx_thresh < 0xe0) { | ||
699 | void __iomem *ioaddr = rp->base; | ||
700 | |||
701 | rp->tx_thresh += 0x20; | ||
702 | BYTE_REG_BITS_SET(rp->tx_thresh, 0x80, ioaddr + TxConfig); | ||
703 | } | ||
704 | } | ||
705 | |||
706 | static void rhine_tx_err(struct rhine_private *rp, u32 status) | ||
707 | { | ||
708 | struct net_device *dev = rp->dev; | ||
709 | |||
710 | if (status & IntrTxAborted) { | ||
711 | netif_info(rp, tx_err, dev, | ||
712 | "Abort %08x, frame dropped\n", status); | ||
713 | } | ||
714 | |||
715 | if (status & IntrTxUnderrun) { | ||
716 | rhine_kick_tx_threshold(rp); | ||
717 | netif_info(rp, tx_err ,dev, "Transmitter underrun, " | ||
718 | "Tx threshold now %02x\n", rp->tx_thresh); | ||
719 | } | ||
720 | |||
721 | if (status & IntrTxDescRace) | ||
722 | netif_info(rp, tx_err, dev, "Tx descriptor write-back race\n"); | ||
723 | |||
724 | if ((status & IntrTxError) && | ||
725 | (status & (IntrTxAborted | IntrTxUnderrun | IntrTxDescRace)) == 0) { | ||
726 | rhine_kick_tx_threshold(rp); | ||
727 | netif_info(rp, tx_err, dev, "Unspecified error. " | ||
728 | "Tx threshold now %02x\n", rp->tx_thresh); | ||
729 | } | ||
730 | |||
731 | rhine_restart_tx(dev); | ||
732 | } | ||
733 | |||
734 | static void rhine_update_rx_crc_and_missed_errord(struct rhine_private *rp) | ||
735 | { | ||
736 | void __iomem *ioaddr = rp->base; | ||
737 | struct net_device_stats *stats = &rp->dev->stats; | ||
738 | |||
739 | stats->rx_crc_errors += ioread16(ioaddr + RxCRCErrs); | ||
740 | stats->rx_missed_errors += ioread16(ioaddr + RxMissed); | ||
741 | |||
742 | /* | ||
743 | * Clears the "tally counters" for CRC errors and missed frames(?). | ||
744 | * It has been reported that some chips need a write of 0 to clear | ||
745 | * these, for others the counters are set to 1 when written to and | ||
746 | * instead cleared when read. So we clear them both ways ... | ||
747 | */ | ||
748 | iowrite32(0, ioaddr + RxMissed); | ||
749 | ioread16(ioaddr + RxCRCErrs); | ||
750 | ioread16(ioaddr + RxMissed); | ||
751 | } | ||
752 | |||
753 | #define RHINE_EVENT_NAPI_RX (IntrRxDone | \ | ||
754 | IntrRxErr | \ | ||
755 | IntrRxEmpty | \ | ||
756 | IntrRxOverflow | \ | ||
757 | IntrRxDropped | \ | ||
758 | IntrRxNoBuf | \ | ||
759 | IntrRxWakeUp) | ||
760 | |||
761 | #define RHINE_EVENT_NAPI_TX_ERR (IntrTxError | \ | ||
762 | IntrTxAborted | \ | ||
763 | IntrTxUnderrun | \ | ||
764 | IntrTxDescRace) | ||
765 | #define RHINE_EVENT_NAPI_TX (IntrTxDone | RHINE_EVENT_NAPI_TX_ERR) | ||
766 | |||
767 | #define RHINE_EVENT_NAPI (RHINE_EVENT_NAPI_RX | \ | ||
768 | RHINE_EVENT_NAPI_TX | \ | ||
769 | IntrStatsMax) | ||
770 | #define RHINE_EVENT_SLOW (IntrPCIErr | IntrLinkChange) | ||
771 | #define RHINE_EVENT (RHINE_EVENT_NAPI | RHINE_EVENT_SLOW) | ||
772 | |||
660 | static int rhine_napipoll(struct napi_struct *napi, int budget) | 773 | static int rhine_napipoll(struct napi_struct *napi, int budget) |
661 | { | 774 | { |
662 | struct rhine_private *rp = container_of(napi, struct rhine_private, napi); | 775 | struct rhine_private *rp = container_of(napi, struct rhine_private, napi); |
663 | struct net_device *dev = rp->dev; | 776 | struct net_device *dev = rp->dev; |
664 | void __iomem *ioaddr = rp->base; | 777 | void __iomem *ioaddr = rp->base; |
665 | int work_done; | 778 | u16 enable_mask = RHINE_EVENT & 0xffff; |
779 | int work_done = 0; | ||
780 | u32 status; | ||
781 | |||
782 | status = rhine_get_events(rp); | ||
783 | rhine_ack_events(rp, status & ~RHINE_EVENT_SLOW); | ||
784 | |||
785 | if (status & RHINE_EVENT_NAPI_RX) | ||
786 | work_done += rhine_rx(dev, budget); | ||
787 | |||
788 | if (status & RHINE_EVENT_NAPI_TX) { | ||
789 | if (status & RHINE_EVENT_NAPI_TX_ERR) { | ||
790 | /* Avoid scavenging before Tx engine turned off */ | ||
791 | rhine_wait_bit_low(rp, ChipCmd, CmdTxOn); | ||
792 | if (ioread8(ioaddr + ChipCmd) & CmdTxOn) | ||
793 | netif_warn(rp, tx_err, dev, "Tx still on\n"); | ||
794 | } | ||
666 | 795 | ||
667 | work_done = rhine_rx(dev, budget); | 796 | rhine_tx(dev); |
797 | |||
798 | if (status & RHINE_EVENT_NAPI_TX_ERR) | ||
799 | rhine_tx_err(rp, status); | ||
800 | } | ||
801 | |||
802 | if (status & IntrStatsMax) { | ||
803 | spin_lock(&rp->lock); | ||
804 | rhine_update_rx_crc_and_missed_errord(rp); | ||
805 | spin_unlock(&rp->lock); | ||
806 | } | ||
807 | |||
808 | if (status & RHINE_EVENT_SLOW) { | ||
809 | enable_mask &= ~RHINE_EVENT_SLOW; | ||
810 | schedule_work(&rp->slow_event_task); | ||
811 | } | ||
668 | 812 | ||
669 | if (work_done < budget) { | 813 | if (work_done < budget) { |
670 | napi_complete(napi); | 814 | napi_complete(napi); |
671 | 815 | iowrite16(enable_mask, ioaddr + IntrEnable); | |
672 | iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | | 816 | mmiowb(); |
673 | IntrRxDropped | IntrRxNoBuf | IntrTxAborted | | ||
674 | IntrTxDone | IntrTxError | IntrTxUnderrun | | ||
675 | IntrPCIErr | IntrStatsMax | IntrLinkChange, | ||
676 | ioaddr + IntrEnable); | ||
677 | } | 817 | } |
678 | return work_done; | 818 | return work_done; |
679 | } | 819 | } |
@@ -797,6 +937,7 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, | |||
797 | rp->quirks = quirks; | 937 | rp->quirks = quirks; |
798 | rp->pioaddr = pioaddr; | 938 | rp->pioaddr = pioaddr; |
799 | rp->pdev = pdev; | 939 | rp->pdev = pdev; |
940 | rp->msg_enable = netif_msg_init(debug, RHINE_MSG_DEFAULT); | ||
800 | 941 | ||
801 | rc = pci_request_regions(pdev, DRV_NAME); | 942 | rc = pci_request_regions(pdev, DRV_NAME); |
802 | if (rc) | 943 | if (rc) |
@@ -856,7 +997,9 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, | |||
856 | dev->irq = pdev->irq; | 997 | dev->irq = pdev->irq; |
857 | 998 | ||
858 | spin_lock_init(&rp->lock); | 999 | spin_lock_init(&rp->lock); |
1000 | mutex_init(&rp->task_lock); | ||
859 | INIT_WORK(&rp->reset_task, rhine_reset_task); | 1001 | INIT_WORK(&rp->reset_task, rhine_reset_task); |
1002 | INIT_WORK(&rp->slow_event_task, rhine_slow_event_task); | ||
860 | 1003 | ||
861 | rp->mii_if.dev = dev; | 1004 | rp->mii_if.dev = dev; |
862 | rp->mii_if.mdio_read = mdio_read; | 1005 | rp->mii_if.mdio_read = mdio_read; |
@@ -916,8 +1059,8 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, | |||
916 | } | 1059 | } |
917 | } | 1060 | } |
918 | rp->mii_if.phy_id = phy_id; | 1061 | rp->mii_if.phy_id = phy_id; |
919 | if (debug > 1 && avoid_D3) | 1062 | if (avoid_D3) |
920 | netdev_info(dev, "No D3 power state at shutdown\n"); | 1063 | netif_info(rp, probe, dev, "No D3 power state at shutdown\n"); |
921 | 1064 | ||
922 | return 0; | 1065 | return 0; |
923 | 1066 | ||
@@ -1093,7 +1236,7 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media) | |||
1093 | struct rhine_private *rp = netdev_priv(dev); | 1236 | struct rhine_private *rp = netdev_priv(dev); |
1094 | void __iomem *ioaddr = rp->base; | 1237 | void __iomem *ioaddr = rp->base; |
1095 | 1238 | ||
1096 | mii_check_media(&rp->mii_if, debug, init_media); | 1239 | mii_check_media(&rp->mii_if, netif_msg_link(rp), init_media); |
1097 | 1240 | ||
1098 | if (rp->mii_if.full_duplex) | 1241 | if (rp->mii_if.full_duplex) |
1099 | iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1FDuplex, | 1242 | iowrite8(ioread8(ioaddr + ChipCmd1) | Cmd1FDuplex, |
@@ -1101,24 +1244,26 @@ static void rhine_check_media(struct net_device *dev, unsigned int init_media) | |||
1101 | else | 1244 | else |
1102 | iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex, | 1245 | iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex, |
1103 | ioaddr + ChipCmd1); | 1246 | ioaddr + ChipCmd1); |
1104 | if (debug > 1) | 1247 | |
1105 | netdev_info(dev, "force_media %d, carrier %d\n", | 1248 | netif_info(rp, link, dev, "force_media %d, carrier %d\n", |
1106 | rp->mii_if.force_media, netif_carrier_ok(dev)); | 1249 | rp->mii_if.force_media, netif_carrier_ok(dev)); |
1107 | } | 1250 | } |
1108 | 1251 | ||
1109 | /* Called after status of force_media possibly changed */ | 1252 | /* Called after status of force_media possibly changed */ |
1110 | static void rhine_set_carrier(struct mii_if_info *mii) | 1253 | static void rhine_set_carrier(struct mii_if_info *mii) |
1111 | { | 1254 | { |
1255 | struct net_device *dev = mii->dev; | ||
1256 | struct rhine_private *rp = netdev_priv(dev); | ||
1257 | |||
1112 | if (mii->force_media) { | 1258 | if (mii->force_media) { |
1113 | /* autoneg is off: Link is always assumed to be up */ | 1259 | /* autoneg is off: Link is always assumed to be up */ |
1114 | if (!netif_carrier_ok(mii->dev)) | 1260 | if (!netif_carrier_ok(dev)) |
1115 | netif_carrier_on(mii->dev); | 1261 | netif_carrier_on(dev); |
1116 | } | 1262 | } else /* Let MMI library update carrier status */ |
1117 | else /* Let MMI library update carrier status */ | 1263 | rhine_check_media(dev, 0); |
1118 | rhine_check_media(mii->dev, 0); | 1264 | |
1119 | if (debug > 1) | 1265 | netif_info(rp, link, dev, "force_media %d, carrier %d\n", |
1120 | netdev_info(mii->dev, "force_media %d, carrier %d\n", | 1266 | mii->force_media, netif_carrier_ok(dev)); |
1121 | mii->force_media, netif_carrier_ok(mii->dev)); | ||
1122 | } | 1267 | } |
1123 | 1268 | ||
1124 | /** | 1269 | /** |
@@ -1266,10 +1411,10 @@ static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid) | |||
1266 | { | 1411 | { |
1267 | struct rhine_private *rp = netdev_priv(dev); | 1412 | struct rhine_private *rp = netdev_priv(dev); |
1268 | 1413 | ||
1269 | spin_lock_irq(&rp->lock); | 1414 | spin_lock_bh(&rp->lock); |
1270 | set_bit(vid, rp->active_vlans); | 1415 | set_bit(vid, rp->active_vlans); |
1271 | rhine_update_vcam(dev); | 1416 | rhine_update_vcam(dev); |
1272 | spin_unlock_irq(&rp->lock); | 1417 | spin_unlock_bh(&rp->lock); |
1273 | return 0; | 1418 | return 0; |
1274 | } | 1419 | } |
1275 | 1420 | ||
@@ -1277,10 +1422,10 @@ static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
1277 | { | 1422 | { |
1278 | struct rhine_private *rp = netdev_priv(dev); | 1423 | struct rhine_private *rp = netdev_priv(dev); |
1279 | 1424 | ||
1280 | spin_lock_irq(&rp->lock); | 1425 | spin_lock_bh(&rp->lock); |
1281 | clear_bit(vid, rp->active_vlans); | 1426 | clear_bit(vid, rp->active_vlans); |
1282 | rhine_update_vcam(dev); | 1427 | rhine_update_vcam(dev); |
1283 | spin_unlock_irq(&rp->lock); | 1428 | spin_unlock_bh(&rp->lock); |
1284 | return 0; | 1429 | return 0; |
1285 | } | 1430 | } |
1286 | 1431 | ||
@@ -1310,12 +1455,7 @@ static void init_registers(struct net_device *dev) | |||
1310 | 1455 | ||
1311 | napi_enable(&rp->napi); | 1456 | napi_enable(&rp->napi); |
1312 | 1457 | ||
1313 | /* Enable interrupts by setting the interrupt mask. */ | 1458 | iowrite16(RHINE_EVENT & 0xffff, ioaddr + IntrEnable); |
1314 | iowrite16(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow | | ||
1315 | IntrRxDropped | IntrRxNoBuf | IntrTxAborted | | ||
1316 | IntrTxDone | IntrTxError | IntrTxUnderrun | | ||
1317 | IntrPCIErr | IntrStatsMax | IntrLinkChange, | ||
1318 | ioaddr + IntrEnable); | ||
1319 | 1459 | ||
1320 | iowrite16(CmdStart | CmdTxOn | CmdRxOn | (Cmd1NoTxPoll << 8), | 1460 | iowrite16(CmdStart | CmdTxOn | CmdRxOn | (Cmd1NoTxPoll << 8), |
1321 | ioaddr + ChipCmd); | 1461 | ioaddr + ChipCmd); |
@@ -1323,23 +1463,27 @@ static void init_registers(struct net_device *dev) | |||
1323 | } | 1463 | } |
1324 | 1464 | ||
1325 | /* Enable MII link status auto-polling (required for IntrLinkChange) */ | 1465 | /* Enable MII link status auto-polling (required for IntrLinkChange) */ |
1326 | static void rhine_enable_linkmon(void __iomem *ioaddr) | 1466 | static void rhine_enable_linkmon(struct rhine_private *rp) |
1327 | { | 1467 | { |
1468 | void __iomem *ioaddr = rp->base; | ||
1469 | |||
1328 | iowrite8(0, ioaddr + MIICmd); | 1470 | iowrite8(0, ioaddr + MIICmd); |
1329 | iowrite8(MII_BMSR, ioaddr + MIIRegAddr); | 1471 | iowrite8(MII_BMSR, ioaddr + MIIRegAddr); |
1330 | iowrite8(0x80, ioaddr + MIICmd); | 1472 | iowrite8(0x80, ioaddr + MIICmd); |
1331 | 1473 | ||
1332 | RHINE_WAIT_FOR((ioread8(ioaddr + MIIRegAddr) & 0x20)); | 1474 | rhine_wait_bit_high(rp, MIIRegAddr, 0x20); |
1333 | 1475 | ||
1334 | iowrite8(MII_BMSR | 0x40, ioaddr + MIIRegAddr); | 1476 | iowrite8(MII_BMSR | 0x40, ioaddr + MIIRegAddr); |
1335 | } | 1477 | } |
1336 | 1478 | ||
1337 | /* Disable MII link status auto-polling (required for MDIO access) */ | 1479 | /* Disable MII link status auto-polling (required for MDIO access) */ |
1338 | static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks) | 1480 | static void rhine_disable_linkmon(struct rhine_private *rp) |
1339 | { | 1481 | { |
1482 | void __iomem *ioaddr = rp->base; | ||
1483 | |||
1340 | iowrite8(0, ioaddr + MIICmd); | 1484 | iowrite8(0, ioaddr + MIICmd); |
1341 | 1485 | ||
1342 | if (quirks & rqRhineI) { | 1486 | if (rp->quirks & rqRhineI) { |
1343 | iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR | 1487 | iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR |
1344 | 1488 | ||
1345 | /* Can be called from ISR. Evil. */ | 1489 | /* Can be called from ISR. Evil. */ |
@@ -1348,13 +1492,13 @@ static void rhine_disable_linkmon(void __iomem *ioaddr, u32 quirks) | |||
1348 | /* 0x80 must be set immediately before turning it off */ | 1492 | /* 0x80 must be set immediately before turning it off */ |
1349 | iowrite8(0x80, ioaddr + MIICmd); | 1493 | iowrite8(0x80, ioaddr + MIICmd); |
1350 | 1494 | ||
1351 | RHINE_WAIT_FOR(ioread8(ioaddr + MIIRegAddr) & 0x20); | 1495 | rhine_wait_bit_high(rp, MIIRegAddr, 0x20); |
1352 | 1496 | ||
1353 | /* Heh. Now clear 0x80 again. */ | 1497 | /* Heh. Now clear 0x80 again. */ |
1354 | iowrite8(0, ioaddr + MIICmd); | 1498 | iowrite8(0, ioaddr + MIICmd); |
1355 | } | 1499 | } |
1356 | else | 1500 | else |
1357 | RHINE_WAIT_FOR(ioread8(ioaddr + MIIRegAddr) & 0x80); | 1501 | rhine_wait_bit_high(rp, MIIRegAddr, 0x80); |
1358 | } | 1502 | } |
1359 | 1503 | ||
1360 | /* Read and write over the MII Management Data I/O (MDIO) interface. */ | 1504 | /* Read and write over the MII Management Data I/O (MDIO) interface. */ |
@@ -1365,16 +1509,16 @@ static int mdio_read(struct net_device *dev, int phy_id, int regnum) | |||
1365 | void __iomem *ioaddr = rp->base; | 1509 | void __iomem *ioaddr = rp->base; |
1366 | int result; | 1510 | int result; |
1367 | 1511 | ||
1368 | rhine_disable_linkmon(ioaddr, rp->quirks); | 1512 | rhine_disable_linkmon(rp); |
1369 | 1513 | ||
1370 | /* rhine_disable_linkmon already cleared MIICmd */ | 1514 | /* rhine_disable_linkmon already cleared MIICmd */ |
1371 | iowrite8(phy_id, ioaddr + MIIPhyAddr); | 1515 | iowrite8(phy_id, ioaddr + MIIPhyAddr); |
1372 | iowrite8(regnum, ioaddr + MIIRegAddr); | 1516 | iowrite8(regnum, ioaddr + MIIRegAddr); |
1373 | iowrite8(0x40, ioaddr + MIICmd); /* Trigger read */ | 1517 | iowrite8(0x40, ioaddr + MIICmd); /* Trigger read */ |
1374 | RHINE_WAIT_FOR(!(ioread8(ioaddr + MIICmd) & 0x40)); | 1518 | rhine_wait_bit_low(rp, MIICmd, 0x40); |
1375 | result = ioread16(ioaddr + MIIData); | 1519 | result = ioread16(ioaddr + MIIData); |
1376 | 1520 | ||
1377 | rhine_enable_linkmon(ioaddr); | 1521 | rhine_enable_linkmon(rp); |
1378 | return result; | 1522 | return result; |
1379 | } | 1523 | } |
1380 | 1524 | ||
@@ -1383,16 +1527,33 @@ static void mdio_write(struct net_device *dev, int phy_id, int regnum, int value | |||
1383 | struct rhine_private *rp = netdev_priv(dev); | 1527 | struct rhine_private *rp = netdev_priv(dev); |
1384 | void __iomem *ioaddr = rp->base; | 1528 | void __iomem *ioaddr = rp->base; |
1385 | 1529 | ||
1386 | rhine_disable_linkmon(ioaddr, rp->quirks); | 1530 | rhine_disable_linkmon(rp); |
1387 | 1531 | ||
1388 | /* rhine_disable_linkmon already cleared MIICmd */ | 1532 | /* rhine_disable_linkmon already cleared MIICmd */ |
1389 | iowrite8(phy_id, ioaddr + MIIPhyAddr); | 1533 | iowrite8(phy_id, ioaddr + MIIPhyAddr); |
1390 | iowrite8(regnum, ioaddr + MIIRegAddr); | 1534 | iowrite8(regnum, ioaddr + MIIRegAddr); |
1391 | iowrite16(value, ioaddr + MIIData); | 1535 | iowrite16(value, ioaddr + MIIData); |
1392 | iowrite8(0x20, ioaddr + MIICmd); /* Trigger write */ | 1536 | iowrite8(0x20, ioaddr + MIICmd); /* Trigger write */ |
1393 | RHINE_WAIT_FOR(!(ioread8(ioaddr + MIICmd) & 0x20)); | 1537 | rhine_wait_bit_low(rp, MIICmd, 0x20); |
1394 | 1538 | ||
1395 | rhine_enable_linkmon(ioaddr); | 1539 | rhine_enable_linkmon(rp); |
1540 | } | ||
1541 | |||
1542 | static void rhine_task_disable(struct rhine_private *rp) | ||
1543 | { | ||
1544 | mutex_lock(&rp->task_lock); | ||
1545 | rp->task_enable = false; | ||
1546 | mutex_unlock(&rp->task_lock); | ||
1547 | |||
1548 | cancel_work_sync(&rp->slow_event_task); | ||
1549 | cancel_work_sync(&rp->reset_task); | ||
1550 | } | ||
1551 | |||
1552 | static void rhine_task_enable(struct rhine_private *rp) | ||
1553 | { | ||
1554 | mutex_lock(&rp->task_lock); | ||
1555 | rp->task_enable = true; | ||
1556 | mutex_unlock(&rp->task_lock); | ||
1396 | } | 1557 | } |
1397 | 1558 | ||
1398 | static int rhine_open(struct net_device *dev) | 1559 | static int rhine_open(struct net_device *dev) |
@@ -1406,8 +1567,7 @@ static int rhine_open(struct net_device *dev) | |||
1406 | if (rc) | 1567 | if (rc) |
1407 | return rc; | 1568 | return rc; |
1408 | 1569 | ||
1409 | if (debug > 1) | 1570 | netif_dbg(rp, ifup, dev, "%s() irq %d\n", __func__, rp->pdev->irq); |
1410 | netdev_dbg(dev, "%s() irq %d\n", __func__, rp->pdev->irq); | ||
1411 | 1571 | ||
1412 | rc = alloc_ring(dev); | 1572 | rc = alloc_ring(dev); |
1413 | if (rc) { | 1573 | if (rc) { |
@@ -1417,11 +1577,12 @@ static int rhine_open(struct net_device *dev) | |||
1417 | alloc_rbufs(dev); | 1577 | alloc_rbufs(dev); |
1418 | alloc_tbufs(dev); | 1578 | alloc_tbufs(dev); |
1419 | rhine_chip_reset(dev); | 1579 | rhine_chip_reset(dev); |
1580 | rhine_task_enable(rp); | ||
1420 | init_registers(dev); | 1581 | init_registers(dev); |
1421 | if (debug > 2) | 1582 | |
1422 | netdev_dbg(dev, "%s() Done - status %04x MII status: %04x\n", | 1583 | netif_dbg(rp, ifup, dev, "%s() Done - status %04x MII status: %04x\n", |
1423 | __func__, ioread16(ioaddr + ChipCmd), | 1584 | __func__, ioread16(ioaddr + ChipCmd), |
1424 | mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); | 1585 | mdio_read(dev, rp->mii_if.phy_id, MII_BMSR)); |
1425 | 1586 | ||
1426 | netif_start_queue(dev); | 1587 | netif_start_queue(dev); |
1427 | 1588 | ||
@@ -1434,11 +1595,12 @@ static void rhine_reset_task(struct work_struct *work) | |||
1434 | reset_task); | 1595 | reset_task); |
1435 | struct net_device *dev = rp->dev; | 1596 | struct net_device *dev = rp->dev; |
1436 | 1597 | ||
1437 | /* protect against concurrent rx interrupts */ | 1598 | mutex_lock(&rp->task_lock); |
1438 | disable_irq(rp->pdev->irq); | ||
1439 | 1599 | ||
1440 | napi_disable(&rp->napi); | 1600 | if (!rp->task_enable) |
1601 | goto out_unlock; | ||
1441 | 1602 | ||
1603 | napi_disable(&rp->napi); | ||
1442 | spin_lock_bh(&rp->lock); | 1604 | spin_lock_bh(&rp->lock); |
1443 | 1605 | ||
1444 | /* clear all descriptors */ | 1606 | /* clear all descriptors */ |
@@ -1452,11 +1614,13 @@ static void rhine_reset_task(struct work_struct *work) | |||
1452 | init_registers(dev); | 1614 | init_registers(dev); |
1453 | 1615 | ||
1454 | spin_unlock_bh(&rp->lock); | 1616 | spin_unlock_bh(&rp->lock); |
1455 | enable_irq(rp->pdev->irq); | ||
1456 | 1617 | ||
1457 | dev->trans_start = jiffies; /* prevent tx timeout */ | 1618 | dev->trans_start = jiffies; /* prevent tx timeout */ |
1458 | dev->stats.tx_errors++; | 1619 | dev->stats.tx_errors++; |
1459 | netif_wake_queue(dev); | 1620 | netif_wake_queue(dev); |
1621 | |||
1622 | out_unlock: | ||
1623 | mutex_unlock(&rp->task_lock); | ||
1460 | } | 1624 | } |
1461 | 1625 | ||
1462 | static void rhine_tx_timeout(struct net_device *dev) | 1626 | static void rhine_tx_timeout(struct net_device *dev) |
@@ -1477,7 +1641,6 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, | |||
1477 | struct rhine_private *rp = netdev_priv(dev); | 1641 | struct rhine_private *rp = netdev_priv(dev); |
1478 | void __iomem *ioaddr = rp->base; | 1642 | void __iomem *ioaddr = rp->base; |
1479 | unsigned entry; | 1643 | unsigned entry; |
1480 | unsigned long flags; | ||
1481 | 1644 | ||
1482 | /* Caution: the write order is important here, set the field | 1645 | /* Caution: the write order is important here, set the field |
1483 | with the "ownership" bits last. */ | 1646 | with the "ownership" bits last. */ |
@@ -1529,7 +1692,6 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, | |||
1529 | rp->tx_ring[entry].tx_status = 0; | 1692 | rp->tx_ring[entry].tx_status = 0; |
1530 | 1693 | ||
1531 | /* lock eth irq */ | 1694 | /* lock eth irq */ |
1532 | spin_lock_irqsave(&rp->lock, flags); | ||
1533 | wmb(); | 1695 | wmb(); |
1534 | rp->tx_ring[entry].tx_status |= cpu_to_le32(DescOwn); | 1696 | rp->tx_ring[entry].tx_status |= cpu_to_le32(DescOwn); |
1535 | wmb(); | 1697 | wmb(); |
@@ -1550,78 +1712,43 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb, | |||
1550 | if (rp->cur_tx == rp->dirty_tx + TX_QUEUE_LEN) | 1712 | if (rp->cur_tx == rp->dirty_tx + TX_QUEUE_LEN) |
1551 | netif_stop_queue(dev); | 1713 | netif_stop_queue(dev); |
1552 | 1714 | ||
1553 | spin_unlock_irqrestore(&rp->lock, flags); | 1715 | netif_dbg(rp, tx_queued, dev, "Transmit frame #%d queued in slot %d\n", |
1716 | rp->cur_tx - 1, entry); | ||
1554 | 1717 | ||
1555 | if (debug > 4) { | ||
1556 | netdev_dbg(dev, "Transmit frame #%d queued in slot %d\n", | ||
1557 | rp->cur_tx-1, entry); | ||
1558 | } | ||
1559 | return NETDEV_TX_OK; | 1718 | return NETDEV_TX_OK; |
1560 | } | 1719 | } |
1561 | 1720 | ||
1721 | static void rhine_irq_disable(struct rhine_private *rp) | ||
1722 | { | ||
1723 | iowrite16(0x0000, rp->base + IntrEnable); | ||
1724 | mmiowb(); | ||
1725 | } | ||
1726 | |||
1562 | /* The interrupt handler does all of the Rx thread work and cleans up | 1727 | /* The interrupt handler does all of the Rx thread work and cleans up |
1563 | after the Tx thread. */ | 1728 | after the Tx thread. */ |
1564 | static irqreturn_t rhine_interrupt(int irq, void *dev_instance) | 1729 | static irqreturn_t rhine_interrupt(int irq, void *dev_instance) |
1565 | { | 1730 | { |
1566 | struct net_device *dev = dev_instance; | 1731 | struct net_device *dev = dev_instance; |
1567 | struct rhine_private *rp = netdev_priv(dev); | 1732 | struct rhine_private *rp = netdev_priv(dev); |
1568 | void __iomem *ioaddr = rp->base; | 1733 | u32 status; |
1569 | u32 intr_status; | ||
1570 | int boguscnt = max_interrupt_work; | ||
1571 | int handled = 0; | 1734 | int handled = 0; |
1572 | 1735 | ||
1573 | while ((intr_status = get_intr_status(dev))) { | 1736 | status = rhine_get_events(rp); |
1574 | handled = 1; | ||
1575 | |||
1576 | /* Acknowledge all of the current interrupt sources ASAP. */ | ||
1577 | if (intr_status & IntrTxDescRace) | ||
1578 | iowrite8(0x08, ioaddr + IntrStatus2); | ||
1579 | iowrite16(intr_status & 0xffff, ioaddr + IntrStatus); | ||
1580 | IOSYNC; | ||
1581 | 1737 | ||
1582 | if (debug > 4) | 1738 | netif_dbg(rp, intr, dev, "Interrupt, status %08x\n", status); |
1583 | netdev_dbg(dev, "Interrupt, status %08x\n", | ||
1584 | intr_status); | ||
1585 | |||
1586 | if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped | | ||
1587 | IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) { | ||
1588 | iowrite16(IntrTxAborted | | ||
1589 | IntrTxDone | IntrTxError | IntrTxUnderrun | | ||
1590 | IntrPCIErr | IntrStatsMax | IntrLinkChange, | ||
1591 | ioaddr + IntrEnable); | ||
1592 | |||
1593 | napi_schedule(&rp->napi); | ||
1594 | } | ||
1595 | 1739 | ||
1596 | if (intr_status & (IntrTxErrSummary | IntrTxDone)) { | 1740 | if (status & RHINE_EVENT) { |
1597 | if (intr_status & IntrTxErrSummary) { | 1741 | handled = 1; |
1598 | /* Avoid scavenging before Tx engine turned off */ | ||
1599 | RHINE_WAIT_FOR(!(ioread8(ioaddr+ChipCmd) & CmdTxOn)); | ||
1600 | if (debug > 2 && | ||
1601 | ioread8(ioaddr+ChipCmd) & CmdTxOn) | ||
1602 | netdev_warn(dev, | ||
1603 | "%s: Tx engine still on\n", | ||
1604 | __func__); | ||
1605 | } | ||
1606 | rhine_tx(dev); | ||
1607 | } | ||
1608 | 1742 | ||
1609 | /* Abnormal error summary/uncommon events handlers. */ | 1743 | rhine_irq_disable(rp); |
1610 | if (intr_status & (IntrPCIErr | IntrLinkChange | | 1744 | napi_schedule(&rp->napi); |
1611 | IntrStatsMax | IntrTxError | IntrTxAborted | | 1745 | } |
1612 | IntrTxUnderrun | IntrTxDescRace)) | ||
1613 | rhine_error(dev, intr_status); | ||
1614 | 1746 | ||
1615 | if (--boguscnt < 0) { | 1747 | if (status & ~(IntrLinkChange | IntrStatsMax | RHINE_EVENT_NAPI)) { |
1616 | netdev_warn(dev, "Too much work at interrupt, status=%#08x\n", | 1748 | netif_err(rp, intr, dev, "Something Wicked happened! %08x\n", |
1617 | intr_status); | 1749 | status); |
1618 | break; | ||
1619 | } | ||
1620 | } | 1750 | } |
1621 | 1751 | ||
1622 | if (debug > 3) | ||
1623 | netdev_dbg(dev, "exiting interrupt, status=%08x\n", | ||
1624 | ioread16(ioaddr + IntrStatus)); | ||
1625 | return IRQ_RETVAL(handled); | 1752 | return IRQ_RETVAL(handled); |
1626 | } | 1753 | } |
1627 | 1754 | ||
@@ -1632,20 +1759,16 @@ static void rhine_tx(struct net_device *dev) | |||
1632 | struct rhine_private *rp = netdev_priv(dev); | 1759 | struct rhine_private *rp = netdev_priv(dev); |
1633 | int txstatus = 0, entry = rp->dirty_tx % TX_RING_SIZE; | 1760 | int txstatus = 0, entry = rp->dirty_tx % TX_RING_SIZE; |
1634 | 1761 | ||
1635 | spin_lock(&rp->lock); | ||
1636 | |||
1637 | /* find and cleanup dirty tx descriptors */ | 1762 | /* find and cleanup dirty tx descriptors */ |
1638 | while (rp->dirty_tx != rp->cur_tx) { | 1763 | while (rp->dirty_tx != rp->cur_tx) { |
1639 | txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status); | 1764 | txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status); |
1640 | if (debug > 6) | 1765 | netif_dbg(rp, tx_done, dev, "Tx scavenge %d status %08x\n", |
1641 | netdev_dbg(dev, "Tx scavenge %d status %08x\n", | 1766 | entry, txstatus); |
1642 | entry, txstatus); | ||
1643 | if (txstatus & DescOwn) | 1767 | if (txstatus & DescOwn) |
1644 | break; | 1768 | break; |
1645 | if (txstatus & 0x8000) { | 1769 | if (txstatus & 0x8000) { |
1646 | if (debug > 1) | 1770 | netif_dbg(rp, tx_done, dev, |
1647 | netdev_dbg(dev, "Transmit error, Tx status %08x\n", | 1771 | "Transmit error, Tx status %08x\n", txstatus); |
1648 | txstatus); | ||
1649 | dev->stats.tx_errors++; | 1772 | dev->stats.tx_errors++; |
1650 | if (txstatus & 0x0400) | 1773 | if (txstatus & 0x0400) |
1651 | dev->stats.tx_carrier_errors++; | 1774 | dev->stats.tx_carrier_errors++; |
@@ -1667,10 +1790,8 @@ static void rhine_tx(struct net_device *dev) | |||
1667 | dev->stats.collisions += (txstatus >> 3) & 0x0F; | 1790 | dev->stats.collisions += (txstatus >> 3) & 0x0F; |
1668 | else | 1791 | else |
1669 | dev->stats.collisions += txstatus & 0x0F; | 1792 | dev->stats.collisions += txstatus & 0x0F; |
1670 | if (debug > 6) | 1793 | netif_dbg(rp, tx_done, dev, "collisions: %1.1x:%1.1x\n", |
1671 | netdev_dbg(dev, "collisions: %1.1x:%1.1x\n", | 1794 | (txstatus >> 3) & 0xF, txstatus & 0xF); |
1672 | (txstatus >> 3) & 0xF, | ||
1673 | txstatus & 0xF); | ||
1674 | dev->stats.tx_bytes += rp->tx_skbuff[entry]->len; | 1795 | dev->stats.tx_bytes += rp->tx_skbuff[entry]->len; |
1675 | dev->stats.tx_packets++; | 1796 | dev->stats.tx_packets++; |
1676 | } | 1797 | } |
@@ -1687,8 +1808,6 @@ static void rhine_tx(struct net_device *dev) | |||
1687 | } | 1808 | } |
1688 | if ((rp->cur_tx - rp->dirty_tx) < TX_QUEUE_LEN - 4) | 1809 | if ((rp->cur_tx - rp->dirty_tx) < TX_QUEUE_LEN - 4) |
1689 | netif_wake_queue(dev); | 1810 | netif_wake_queue(dev); |
1690 | |||
1691 | spin_unlock(&rp->lock); | ||
1692 | } | 1811 | } |
1693 | 1812 | ||
1694 | /** | 1813 | /** |
@@ -1713,11 +1832,8 @@ static int rhine_rx(struct net_device *dev, int limit) | |||
1713 | int count; | 1832 | int count; |
1714 | int entry = rp->cur_rx % RX_RING_SIZE; | 1833 | int entry = rp->cur_rx % RX_RING_SIZE; |
1715 | 1834 | ||
1716 | if (debug > 4) { | 1835 | netif_dbg(rp, rx_status, dev, "%s(), entry %d status %08x\n", __func__, |
1717 | netdev_dbg(dev, "%s(), entry %d status %08x\n", | 1836 | entry, le32_to_cpu(rp->rx_head_desc->rx_status)); |
1718 | __func__, entry, | ||
1719 | le32_to_cpu(rp->rx_head_desc->rx_status)); | ||
1720 | } | ||
1721 | 1837 | ||
1722 | /* If EOP is set on the next entry, it's a new packet. Send it up. */ | 1838 | /* If EOP is set on the next entry, it's a new packet. Send it up. */ |
1723 | for (count = 0; count < limit; ++count) { | 1839 | for (count = 0; count < limit; ++count) { |
@@ -1729,9 +1845,8 @@ static int rhine_rx(struct net_device *dev, int limit) | |||
1729 | if (desc_status & DescOwn) | 1845 | if (desc_status & DescOwn) |
1730 | break; | 1846 | break; |
1731 | 1847 | ||
1732 | if (debug > 4) | 1848 | netif_dbg(rp, rx_status, dev, "%s() status %08x\n", __func__, |
1733 | netdev_dbg(dev, "%s() status is %08x\n", | 1849 | desc_status); |
1734 | __func__, desc_status); | ||
1735 | 1850 | ||
1736 | if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) { | 1851 | if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) { |
1737 | if ((desc_status & RxWholePkt) != RxWholePkt) { | 1852 | if ((desc_status & RxWholePkt) != RxWholePkt) { |
@@ -1747,9 +1862,9 @@ static int rhine_rx(struct net_device *dev, int limit) | |||
1747 | dev->stats.rx_length_errors++; | 1862 | dev->stats.rx_length_errors++; |
1748 | } else if (desc_status & RxErr) { | 1863 | } else if (desc_status & RxErr) { |
1749 | /* There was a error. */ | 1864 | /* There was a error. */ |
1750 | if (debug > 2) | 1865 | netif_dbg(rp, rx_err, dev, |
1751 | netdev_dbg(dev, "%s() Rx error was %08x\n", | 1866 | "%s() Rx error %08x\n", __func__, |
1752 | __func__, desc_status); | 1867 | desc_status); |
1753 | dev->stats.rx_errors++; | 1868 | dev->stats.rx_errors++; |
1754 | if (desc_status & 0x0030) | 1869 | if (desc_status & 0x0030) |
1755 | dev->stats.rx_length_errors++; | 1870 | dev->stats.rx_length_errors++; |
@@ -1839,19 +1954,6 @@ static int rhine_rx(struct net_device *dev, int limit) | |||
1839 | return count; | 1954 | return count; |
1840 | } | 1955 | } |
1841 | 1956 | ||
1842 | /* | ||
1843 | * Clears the "tally counters" for CRC errors and missed frames(?). | ||
1844 | * It has been reported that some chips need a write of 0 to clear | ||
1845 | * these, for others the counters are set to 1 when written to and | ||
1846 | * instead cleared when read. So we clear them both ways ... | ||
1847 | */ | ||
1848 | static inline void clear_tally_counters(void __iomem *ioaddr) | ||
1849 | { | ||
1850 | iowrite32(0, ioaddr + RxMissed); | ||
1851 | ioread16(ioaddr + RxCRCErrs); | ||
1852 | ioread16(ioaddr + RxMissed); | ||
1853 | } | ||
1854 | |||
1855 | static void rhine_restart_tx(struct net_device *dev) { | 1957 | static void rhine_restart_tx(struct net_device *dev) { |
1856 | struct rhine_private *rp = netdev_priv(dev); | 1958 | struct rhine_private *rp = netdev_priv(dev); |
1857 | void __iomem *ioaddr = rp->base; | 1959 | void __iomem *ioaddr = rp->base; |
@@ -1862,7 +1964,7 @@ static void rhine_restart_tx(struct net_device *dev) { | |||
1862 | * If new errors occurred, we need to sort them out before doing Tx. | 1964 | * If new errors occurred, we need to sort them out before doing Tx. |
1863 | * In that case the ISR will be back here RSN anyway. | 1965 | * In that case the ISR will be back here RSN anyway. |
1864 | */ | 1966 | */ |
1865 | intr_status = get_intr_status(dev); | 1967 | intr_status = rhine_get_events(rp); |
1866 | 1968 | ||
1867 | if ((intr_status & IntrTxErrSummary) == 0) { | 1969 | if ((intr_status & IntrTxErrSummary) == 0) { |
1868 | 1970 | ||
@@ -1883,79 +1985,50 @@ static void rhine_restart_tx(struct net_device *dev) { | |||
1883 | } | 1985 | } |
1884 | else { | 1986 | else { |
1885 | /* This should never happen */ | 1987 | /* This should never happen */ |
1886 | if (debug > 1) | 1988 | netif_warn(rp, tx_err, dev, "another error occurred %08x\n", |
1887 | netdev_warn(dev, "%s() Another error occurred %08x\n", | 1989 | intr_status); |
1888 | __func__, intr_status); | ||
1889 | } | 1990 | } |
1890 | 1991 | ||
1891 | } | 1992 | } |
1892 | 1993 | ||
1893 | static void rhine_error(struct net_device *dev, int intr_status) | 1994 | static void rhine_slow_event_task(struct work_struct *work) |
1894 | { | 1995 | { |
1895 | struct rhine_private *rp = netdev_priv(dev); | 1996 | struct rhine_private *rp = |
1896 | void __iomem *ioaddr = rp->base; | 1997 | container_of(work, struct rhine_private, slow_event_task); |
1998 | struct net_device *dev = rp->dev; | ||
1999 | u32 intr_status; | ||
1897 | 2000 | ||
1898 | spin_lock(&rp->lock); | 2001 | mutex_lock(&rp->task_lock); |
2002 | |||
2003 | if (!rp->task_enable) | ||
2004 | goto out_unlock; | ||
2005 | |||
2006 | intr_status = rhine_get_events(rp); | ||
2007 | rhine_ack_events(rp, intr_status & RHINE_EVENT_SLOW); | ||
1899 | 2008 | ||
1900 | if (intr_status & IntrLinkChange) | 2009 | if (intr_status & IntrLinkChange) |
1901 | rhine_check_media(dev, 0); | 2010 | rhine_check_media(dev, 0); |
1902 | if (intr_status & IntrStatsMax) { | ||
1903 | dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs); | ||
1904 | dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed); | ||
1905 | clear_tally_counters(ioaddr); | ||
1906 | } | ||
1907 | if (intr_status & IntrTxAborted) { | ||
1908 | if (debug > 1) | ||
1909 | netdev_info(dev, "Abort %08x, frame dropped\n", | ||
1910 | intr_status); | ||
1911 | } | ||
1912 | if (intr_status & IntrTxUnderrun) { | ||
1913 | if (rp->tx_thresh < 0xE0) | ||
1914 | BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig); | ||
1915 | if (debug > 1) | ||
1916 | netdev_info(dev, "Transmitter underrun, Tx threshold now %02x\n", | ||
1917 | rp->tx_thresh); | ||
1918 | } | ||
1919 | if (intr_status & IntrTxDescRace) { | ||
1920 | if (debug > 2) | ||
1921 | netdev_info(dev, "Tx descriptor write-back race\n"); | ||
1922 | } | ||
1923 | if ((intr_status & IntrTxError) && | ||
1924 | (intr_status & (IntrTxAborted | | ||
1925 | IntrTxUnderrun | IntrTxDescRace)) == 0) { | ||
1926 | if (rp->tx_thresh < 0xE0) { | ||
1927 | BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig); | ||
1928 | } | ||
1929 | if (debug > 1) | ||
1930 | netdev_info(dev, "Unspecified error. Tx threshold now %02x\n", | ||
1931 | rp->tx_thresh); | ||
1932 | } | ||
1933 | if (intr_status & (IntrTxAborted | IntrTxUnderrun | IntrTxDescRace | | ||
1934 | IntrTxError)) | ||
1935 | rhine_restart_tx(dev); | ||
1936 | |||
1937 | if (intr_status & ~(IntrLinkChange | IntrStatsMax | IntrTxUnderrun | | ||
1938 | IntrTxError | IntrTxAborted | IntrNormalSummary | | ||
1939 | IntrTxDescRace)) { | ||
1940 | if (debug > 1) | ||
1941 | netdev_err(dev, "Something Wicked happened! %08x\n", | ||
1942 | intr_status); | ||
1943 | } | ||
1944 | 2011 | ||
1945 | spin_unlock(&rp->lock); | 2012 | if (intr_status & IntrPCIErr) |
2013 | netif_warn(rp, hw, dev, "PCI error\n"); | ||
2014 | |||
2015 | napi_disable(&rp->napi); | ||
2016 | rhine_irq_disable(rp); | ||
2017 | /* Slow and safe. Consider __napi_schedule as a replacement ? */ | ||
2018 | napi_enable(&rp->napi); | ||
2019 | napi_schedule(&rp->napi); | ||
2020 | |||
2021 | out_unlock: | ||
2022 | mutex_unlock(&rp->task_lock); | ||
1946 | } | 2023 | } |
1947 | 2024 | ||
1948 | static struct net_device_stats *rhine_get_stats(struct net_device *dev) | 2025 | static struct net_device_stats *rhine_get_stats(struct net_device *dev) |
1949 | { | 2026 | { |
1950 | struct rhine_private *rp = netdev_priv(dev); | 2027 | struct rhine_private *rp = netdev_priv(dev); |
1951 | void __iomem *ioaddr = rp->base; | ||
1952 | unsigned long flags; | ||
1953 | 2028 | ||
1954 | spin_lock_irqsave(&rp->lock, flags); | 2029 | spin_lock_bh(&rp->lock); |
1955 | dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs); | 2030 | rhine_update_rx_crc_and_missed_errord(rp); |
1956 | dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed); | 2031 | spin_unlock_bh(&rp->lock); |
1957 | clear_tally_counters(ioaddr); | ||
1958 | spin_unlock_irqrestore(&rp->lock, flags); | ||
1959 | 2032 | ||
1960 | return &dev->stats; | 2033 | return &dev->stats; |
1961 | } | 2034 | } |
@@ -2022,9 +2095,9 @@ static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
2022 | struct rhine_private *rp = netdev_priv(dev); | 2095 | struct rhine_private *rp = netdev_priv(dev); |
2023 | int rc; | 2096 | int rc; |
2024 | 2097 | ||
2025 | spin_lock_irq(&rp->lock); | 2098 | mutex_lock(&rp->task_lock); |
2026 | rc = mii_ethtool_gset(&rp->mii_if, cmd); | 2099 | rc = mii_ethtool_gset(&rp->mii_if, cmd); |
2027 | spin_unlock_irq(&rp->lock); | 2100 | mutex_unlock(&rp->task_lock); |
2028 | 2101 | ||
2029 | return rc; | 2102 | return rc; |
2030 | } | 2103 | } |
@@ -2034,10 +2107,10 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
2034 | struct rhine_private *rp = netdev_priv(dev); | 2107 | struct rhine_private *rp = netdev_priv(dev); |
2035 | int rc; | 2108 | int rc; |
2036 | 2109 | ||
2037 | spin_lock_irq(&rp->lock); | 2110 | mutex_lock(&rp->task_lock); |
2038 | rc = mii_ethtool_sset(&rp->mii_if, cmd); | 2111 | rc = mii_ethtool_sset(&rp->mii_if, cmd); |
2039 | spin_unlock_irq(&rp->lock); | ||
2040 | rhine_set_carrier(&rp->mii_if); | 2112 | rhine_set_carrier(&rp->mii_if); |
2113 | mutex_unlock(&rp->task_lock); | ||
2041 | 2114 | ||
2042 | return rc; | 2115 | return rc; |
2043 | } | 2116 | } |
@@ -2058,12 +2131,16 @@ static u32 netdev_get_link(struct net_device *dev) | |||
2058 | 2131 | ||
2059 | static u32 netdev_get_msglevel(struct net_device *dev) | 2132 | static u32 netdev_get_msglevel(struct net_device *dev) |
2060 | { | 2133 | { |
2061 | return debug; | 2134 | struct rhine_private *rp = netdev_priv(dev); |
2135 | |||
2136 | return rp->msg_enable; | ||
2062 | } | 2137 | } |
2063 | 2138 | ||
2064 | static void netdev_set_msglevel(struct net_device *dev, u32 value) | 2139 | static void netdev_set_msglevel(struct net_device *dev, u32 value) |
2065 | { | 2140 | { |
2066 | debug = value; | 2141 | struct rhine_private *rp = netdev_priv(dev); |
2142 | |||
2143 | rp->msg_enable = value; | ||
2067 | } | 2144 | } |
2068 | 2145 | ||
2069 | static void rhine_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) | 2146 | static void rhine_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) |
@@ -2119,10 +2196,10 @@ static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
2119 | if (!netif_running(dev)) | 2196 | if (!netif_running(dev)) |
2120 | return -EINVAL; | 2197 | return -EINVAL; |
2121 | 2198 | ||
2122 | spin_lock_irq(&rp->lock); | 2199 | mutex_lock(&rp->task_lock); |
2123 | rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL); | 2200 | rc = generic_mii_ioctl(&rp->mii_if, if_mii(rq), cmd, NULL); |
2124 | spin_unlock_irq(&rp->lock); | ||
2125 | rhine_set_carrier(&rp->mii_if); | 2201 | rhine_set_carrier(&rp->mii_if); |
2202 | mutex_unlock(&rp->task_lock); | ||
2126 | 2203 | ||
2127 | return rc; | 2204 | return rc; |
2128 | } | 2205 | } |
@@ -2132,27 +2209,21 @@ static int rhine_close(struct net_device *dev) | |||
2132 | struct rhine_private *rp = netdev_priv(dev); | 2209 | struct rhine_private *rp = netdev_priv(dev); |
2133 | void __iomem *ioaddr = rp->base; | 2210 | void __iomem *ioaddr = rp->base; |
2134 | 2211 | ||
2212 | rhine_task_disable(rp); | ||
2135 | napi_disable(&rp->napi); | 2213 | napi_disable(&rp->napi); |
2136 | cancel_work_sync(&rp->reset_task); | ||
2137 | netif_stop_queue(dev); | 2214 | netif_stop_queue(dev); |
2138 | 2215 | ||
2139 | spin_lock_irq(&rp->lock); | 2216 | netif_dbg(rp, ifdown, dev, "Shutting down ethercard, status was %04x\n", |
2140 | 2217 | ioread16(ioaddr + ChipCmd)); | |
2141 | if (debug > 1) | ||
2142 | netdev_dbg(dev, "Shutting down ethercard, status was %04x\n", | ||
2143 | ioread16(ioaddr + ChipCmd)); | ||
2144 | 2218 | ||
2145 | /* Switch to loopback mode to avoid hardware races. */ | 2219 | /* Switch to loopback mode to avoid hardware races. */ |
2146 | iowrite8(rp->tx_thresh | 0x02, ioaddr + TxConfig); | 2220 | iowrite8(rp->tx_thresh | 0x02, ioaddr + TxConfig); |
2147 | 2221 | ||
2148 | /* Disable interrupts by clearing the interrupt mask. */ | 2222 | rhine_irq_disable(rp); |
2149 | iowrite16(0x0000, ioaddr + IntrEnable); | ||
2150 | 2223 | ||
2151 | /* Stop the chip's Tx and Rx processes. */ | 2224 | /* Stop the chip's Tx and Rx processes. */ |
2152 | iowrite16(CmdStop, ioaddr + ChipCmd); | 2225 | iowrite16(CmdStop, ioaddr + ChipCmd); |
2153 | 2226 | ||
2154 | spin_unlock_irq(&rp->lock); | ||
2155 | |||
2156 | free_irq(rp->pdev->irq, dev); | 2227 | free_irq(rp->pdev->irq, dev); |
2157 | free_rbufs(dev); | 2228 | free_rbufs(dev); |
2158 | free_tbufs(dev); | 2229 | free_tbufs(dev); |
@@ -2192,6 +2263,8 @@ static void rhine_shutdown (struct pci_dev *pdev) | |||
2192 | if (rp->quirks & rq6patterns) | 2263 | if (rp->quirks & rq6patterns) |
2193 | iowrite8(0x04, ioaddr + WOLcgClr); | 2264 | iowrite8(0x04, ioaddr + WOLcgClr); |
2194 | 2265 | ||
2266 | spin_lock(&rp->lock); | ||
2267 | |||
2195 | if (rp->wolopts & WAKE_MAGIC) { | 2268 | if (rp->wolopts & WAKE_MAGIC) { |
2196 | iowrite8(WOLmagic, ioaddr + WOLcrSet); | 2269 | iowrite8(WOLmagic, ioaddr + WOLcrSet); |
2197 | /* | 2270 | /* |
@@ -2216,58 +2289,46 @@ static void rhine_shutdown (struct pci_dev *pdev) | |||
2216 | iowrite8(ioread8(ioaddr + StickyHW) | 0x04, ioaddr + StickyHW); | 2289 | iowrite8(ioread8(ioaddr + StickyHW) | 0x04, ioaddr + StickyHW); |
2217 | } | 2290 | } |
2218 | 2291 | ||
2219 | /* Hit power state D3 (sleep) */ | 2292 | spin_unlock(&rp->lock); |
2220 | if (!avoid_D3) | ||
2221 | iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW); | ||
2222 | 2293 | ||
2223 | /* TODO: Check use of pci_enable_wake() */ | 2294 | if (system_state == SYSTEM_POWER_OFF && !avoid_D3) { |
2295 | iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW); | ||
2224 | 2296 | ||
2297 | pci_wake_from_d3(pdev, true); | ||
2298 | pci_set_power_state(pdev, PCI_D3hot); | ||
2299 | } | ||
2225 | } | 2300 | } |
2226 | 2301 | ||
2227 | #ifdef CONFIG_PM | 2302 | #ifdef CONFIG_PM_SLEEP |
2228 | static int rhine_suspend(struct pci_dev *pdev, pm_message_t state) | 2303 | static int rhine_suspend(struct device *device) |
2229 | { | 2304 | { |
2305 | struct pci_dev *pdev = to_pci_dev(device); | ||
2230 | struct net_device *dev = pci_get_drvdata(pdev); | 2306 | struct net_device *dev = pci_get_drvdata(pdev); |
2231 | struct rhine_private *rp = netdev_priv(dev); | 2307 | struct rhine_private *rp = netdev_priv(dev); |
2232 | unsigned long flags; | ||
2233 | 2308 | ||
2234 | if (!netif_running(dev)) | 2309 | if (!netif_running(dev)) |
2235 | return 0; | 2310 | return 0; |
2236 | 2311 | ||
2312 | rhine_task_disable(rp); | ||
2313 | rhine_irq_disable(rp); | ||
2237 | napi_disable(&rp->napi); | 2314 | napi_disable(&rp->napi); |
2238 | 2315 | ||
2239 | netif_device_detach(dev); | 2316 | netif_device_detach(dev); |
2240 | pci_save_state(pdev); | ||
2241 | 2317 | ||
2242 | spin_lock_irqsave(&rp->lock, flags); | ||
2243 | rhine_shutdown(pdev); | 2318 | rhine_shutdown(pdev); |
2244 | spin_unlock_irqrestore(&rp->lock, flags); | ||
2245 | 2319 | ||
2246 | free_irq(dev->irq, dev); | ||
2247 | return 0; | 2320 | return 0; |
2248 | } | 2321 | } |
2249 | 2322 | ||
2250 | static int rhine_resume(struct pci_dev *pdev) | 2323 | static int rhine_resume(struct device *device) |
2251 | { | 2324 | { |
2325 | struct pci_dev *pdev = to_pci_dev(device); | ||
2252 | struct net_device *dev = pci_get_drvdata(pdev); | 2326 | struct net_device *dev = pci_get_drvdata(pdev); |
2253 | struct rhine_private *rp = netdev_priv(dev); | 2327 | struct rhine_private *rp = netdev_priv(dev); |
2254 | unsigned long flags; | ||
2255 | int ret; | ||
2256 | 2328 | ||
2257 | if (!netif_running(dev)) | 2329 | if (!netif_running(dev)) |
2258 | return 0; | 2330 | return 0; |
2259 | 2331 | ||
2260 | if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev)) | ||
2261 | netdev_err(dev, "request_irq failed\n"); | ||
2262 | |||
2263 | ret = pci_set_power_state(pdev, PCI_D0); | ||
2264 | if (debug > 1) | ||
2265 | netdev_info(dev, "Entering power state D0 %s (%d)\n", | ||
2266 | ret ? "failed" : "succeeded", ret); | ||
2267 | |||
2268 | pci_restore_state(pdev); | ||
2269 | |||
2270 | spin_lock_irqsave(&rp->lock, flags); | ||
2271 | #ifdef USE_MMIO | 2332 | #ifdef USE_MMIO |
2272 | enable_mmio(rp->pioaddr, rp->quirks); | 2333 | enable_mmio(rp->pioaddr, rp->quirks); |
2273 | #endif | 2334 | #endif |
@@ -2276,25 +2337,32 @@ static int rhine_resume(struct pci_dev *pdev) | |||
2276 | free_rbufs(dev); | 2337 | free_rbufs(dev); |
2277 | alloc_tbufs(dev); | 2338 | alloc_tbufs(dev); |
2278 | alloc_rbufs(dev); | 2339 | alloc_rbufs(dev); |
2340 | rhine_task_enable(rp); | ||
2341 | spin_lock_bh(&rp->lock); | ||
2279 | init_registers(dev); | 2342 | init_registers(dev); |
2280 | spin_unlock_irqrestore(&rp->lock, flags); | 2343 | spin_unlock_bh(&rp->lock); |
2281 | 2344 | ||
2282 | netif_device_attach(dev); | 2345 | netif_device_attach(dev); |
2283 | 2346 | ||
2284 | return 0; | 2347 | return 0; |
2285 | } | 2348 | } |
2286 | #endif /* CONFIG_PM */ | 2349 | |
2350 | static SIMPLE_DEV_PM_OPS(rhine_pm_ops, rhine_suspend, rhine_resume); | ||
2351 | #define RHINE_PM_OPS (&rhine_pm_ops) | ||
2352 | |||
2353 | #else | ||
2354 | |||
2355 | #define RHINE_PM_OPS NULL | ||
2356 | |||
2357 | #endif /* !CONFIG_PM_SLEEP */ | ||
2287 | 2358 | ||
2288 | static struct pci_driver rhine_driver = { | 2359 | static struct pci_driver rhine_driver = { |
2289 | .name = DRV_NAME, | 2360 | .name = DRV_NAME, |
2290 | .id_table = rhine_pci_tbl, | 2361 | .id_table = rhine_pci_tbl, |
2291 | .probe = rhine_init_one, | 2362 | .probe = rhine_init_one, |
2292 | .remove = __devexit_p(rhine_remove_one), | 2363 | .remove = __devexit_p(rhine_remove_one), |
2293 | #ifdef CONFIG_PM | 2364 | .shutdown = rhine_shutdown, |
2294 | .suspend = rhine_suspend, | 2365 | .driver.pm = RHINE_PM_OPS, |
2295 | .resume = rhine_resume, | ||
2296 | #endif /* CONFIG_PM */ | ||
2297 | .shutdown = rhine_shutdown, | ||
2298 | }; | 2366 | }; |
2299 | 2367 | ||
2300 | static struct dmi_system_id __initdata rhine_dmi_table[] = { | 2368 | static struct dmi_system_id __initdata rhine_dmi_table[] = { |
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index f45c85a84261..72a854f05bb8 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c | |||
@@ -529,7 +529,7 @@ static int ixp4xx_mdio_register(void) | |||
529 | mdio_bus->name = "IXP4xx MII Bus"; | 529 | mdio_bus->name = "IXP4xx MII Bus"; |
530 | mdio_bus->read = &ixp4xx_mdio_read; | 530 | mdio_bus->read = &ixp4xx_mdio_read; |
531 | mdio_bus->write = &ixp4xx_mdio_write; | 531 | mdio_bus->write = &ixp4xx_mdio_write; |
532 | strcpy(mdio_bus->id, "0"); | 532 | snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "ixp4xx-eth-0"); |
533 | 533 | ||
534 | if ((err = mdiobus_register(mdio_bus))) | 534 | if ((err = mdiobus_register(mdio_bus))) |
535 | mdiobus_free(mdio_bus); | 535 | mdiobus_free(mdio_bus); |
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c index 9663e0ba6003..ba3c59147aa7 100644 --- a/drivers/net/phy/dp83640.c +++ b/drivers/net/phy/dp83640.c | |||
@@ -1159,7 +1159,7 @@ static void rx_timestamp_work(struct work_struct *work) | |||
1159 | } | 1159 | } |
1160 | } | 1160 | } |
1161 | spin_unlock_irqrestore(&dp83640->rx_lock, flags); | 1161 | spin_unlock_irqrestore(&dp83640->rx_lock, flags); |
1162 | netif_rx(skb); | 1162 | netif_rx_ni(skb); |
1163 | } | 1163 | } |
1164 | 1164 | ||
1165 | /* Clear out expired time stamps. */ | 1165 | /* Clear out expired time stamps. */ |
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index 1fa4d73c3cca..633680d0828e 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c | |||
@@ -220,7 +220,7 @@ static int __init fixed_mdio_bus_init(void) | |||
220 | goto err_mdiobus_reg; | 220 | goto err_mdiobus_reg; |
221 | } | 221 | } |
222 | 222 | ||
223 | snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "0"); | 223 | snprintf(fmb->mii_bus->id, MII_BUS_ID_SIZE, "fixed-0"); |
224 | fmb->mii_bus->name = "Fixed MDIO Bus"; | 224 | fmb->mii_bus->name = "Fixed MDIO Bus"; |
225 | fmb->mii_bus->priv = fmb; | 225 | fmb->mii_bus->priv = fmb; |
226 | fmb->mii_bus->parent = &pdev->dev; | 226 | fmb->mii_bus->parent = &pdev->dev; |
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c index 89c5a3eccc12..50e8e5e74465 100644 --- a/drivers/net/phy/mdio-gpio.c +++ b/drivers/net/phy/mdio-gpio.c | |||
@@ -116,7 +116,7 @@ static struct mii_bus * __devinit mdio_gpio_bus_init(struct device *dev, | |||
116 | if (!new_bus->irq[i]) | 116 | if (!new_bus->irq[i]) |
117 | new_bus->irq[i] = PHY_POLL; | 117 | new_bus->irq[i] = PHY_POLL; |
118 | 118 | ||
119 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", bus_id); | 119 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "gpio-%x", bus_id); |
120 | 120 | ||
121 | if (gpio_request(bitbang->mdc, "mdc")) | 121 | if (gpio_request(bitbang->mdc, "mdc")) |
122 | goto out_free_bus; | 122 | goto out_free_bus; |
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c index bd12ba941be5..826d961f39f7 100644 --- a/drivers/net/phy/mdio-octeon.c +++ b/drivers/net/phy/mdio-octeon.c | |||
@@ -118,7 +118,8 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev) | |||
118 | bus->mii_bus->priv = bus; | 118 | bus->mii_bus->priv = bus; |
119 | bus->mii_bus->irq = bus->phy_irq; | 119 | bus->mii_bus->irq = bus->phy_irq; |
120 | bus->mii_bus->name = "mdio-octeon"; | 120 | bus->mii_bus->name = "mdio-octeon"; |
121 | snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%x", bus->unit); | 121 | snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
122 | bus->mii_bus->name, bus->unit); | ||
122 | bus->mii_bus->parent = &pdev->dev; | 123 | bus->mii_bus->parent = &pdev->dev; |
123 | 124 | ||
124 | bus->mii_bus->read = octeon_mdiobus_read; | 125 | bus->mii_bus->read = octeon_mdiobus_read; |
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 6c58da2b882c..88cc5db9affd 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c | |||
@@ -37,22 +37,36 @@ | |||
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
38 | 38 | ||
39 | /** | 39 | /** |
40 | * mdiobus_alloc - allocate a mii_bus structure | 40 | * mdiobus_alloc_size - allocate a mii_bus structure |
41 | * | 41 | * |
42 | * Description: called by a bus driver to allocate an mii_bus | 42 | * Description: called by a bus driver to allocate an mii_bus |
43 | * structure to fill in. | 43 | * structure to fill in. |
44 | * | ||
45 | * 'size' is an an extra amount of memory to allocate for private storage. | ||
46 | * If non-zero, then bus->priv is points to that memory. | ||
44 | */ | 47 | */ |
45 | struct mii_bus *mdiobus_alloc(void) | 48 | struct mii_bus *mdiobus_alloc_size(size_t size) |
46 | { | 49 | { |
47 | struct mii_bus *bus; | 50 | struct mii_bus *bus; |
51 | size_t aligned_size = ALIGN(sizeof(*bus), NETDEV_ALIGN); | ||
52 | size_t alloc_size; | ||
53 | |||
54 | /* If we alloc extra space, it should be aligned */ | ||
55 | if (size) | ||
56 | alloc_size = aligned_size + size; | ||
57 | else | ||
58 | alloc_size = sizeof(*bus); | ||
48 | 59 | ||
49 | bus = kzalloc(sizeof(*bus), GFP_KERNEL); | 60 | bus = kzalloc(alloc_size, GFP_KERNEL); |
50 | if (bus != NULL) | 61 | if (bus) { |
51 | bus->state = MDIOBUS_ALLOCATED; | 62 | bus->state = MDIOBUS_ALLOCATED; |
63 | if (size) | ||
64 | bus->priv = (void *)bus + aligned_size; | ||
65 | } | ||
52 | 66 | ||
53 | return bus; | 67 | return bus; |
54 | } | 68 | } |
55 | EXPORT_SYMBOL(mdiobus_alloc); | 69 | EXPORT_SYMBOL(mdiobus_alloc_size); |
56 | 70 | ||
57 | /** | 71 | /** |
58 | * mdiobus_release - mii_bus device release callback | 72 | * mdiobus_release - mii_bus device release callback |
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index c1c9293c2bbf..df884dde2a51 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c | |||
@@ -585,8 +585,8 @@ static int pptp_create(struct net *net, struct socket *sock) | |||
585 | po = pppox_sk(sk); | 585 | po = pppox_sk(sk); |
586 | opt = &po->proto.pptp; | 586 | opt = &po->proto.pptp; |
587 | 587 | ||
588 | opt->seq_sent = 0; opt->seq_recv = 0; | 588 | opt->seq_sent = 0; opt->seq_recv = 0xffffffff; |
589 | opt->ack_recv = 0; opt->ack_sent = 0; | 589 | opt->ack_recv = 0; opt->ack_sent = 0xffffffff; |
590 | 590 | ||
591 | error = 0; | 591 | error = 0; |
592 | out: | 592 | out: |
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index d0937c4634c9..8e84f5bdd6ca 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -978,6 +978,7 @@ static int ax88772_link_reset(struct usbnet *dev) | |||
978 | 978 | ||
979 | static int ax88772_reset(struct usbnet *dev) | 979 | static int ax88772_reset(struct usbnet *dev) |
980 | { | 980 | { |
981 | struct asix_data *data = (struct asix_data *)&dev->data; | ||
981 | int ret, embd_phy; | 982 | int ret, embd_phy; |
982 | u16 rx_ctl; | 983 | u16 rx_ctl; |
983 | 984 | ||
@@ -1055,6 +1056,13 @@ static int ax88772_reset(struct usbnet *dev) | |||
1055 | goto out; | 1056 | goto out; |
1056 | } | 1057 | } |
1057 | 1058 | ||
1059 | /* Rewrite MAC address */ | ||
1060 | memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); | ||
1061 | ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
1062 | data->mac_addr); | ||
1063 | if (ret < 0) | ||
1064 | goto out; | ||
1065 | |||
1058 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ | 1066 | /* Set RX_CTL to default values with 2k buffer, and enable cactus */ |
1059 | ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); | 1067 | ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); |
1060 | if (ret < 0) | 1068 | if (ret < 0) |
@@ -1320,6 +1328,13 @@ static int ax88178_reset(struct usbnet *dev) | |||
1320 | if (ret < 0) | 1328 | if (ret < 0) |
1321 | return ret; | 1329 | return ret; |
1322 | 1330 | ||
1331 | /* Rewrite MAC address */ | ||
1332 | memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); | ||
1333 | ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, | ||
1334 | data->mac_addr); | ||
1335 | if (ret < 0) | ||
1336 | return ret; | ||
1337 | |||
1323 | ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); | 1338 | ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); |
1324 | if (ret < 0) | 1339 | if (ret < 0) |
1325 | return ret; | 1340 | return ret; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 2589b38b689a..2b0bfb8cca02 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -46,7 +46,7 @@ static const int m2ThreshExt_off = 127; | |||
46 | * @chan: | 46 | * @chan: |
47 | * | 47 | * |
48 | * This is the function to change channel on single-chip devices, that is | 48 | * This is the function to change channel on single-chip devices, that is |
49 | * all devices after ar9280. | 49 | * for AR9300 family of chipsets. |
50 | * | 50 | * |
51 | * This function takes the channel value in MHz and sets | 51 | * This function takes the channel value in MHz and sets |
52 | * hardware channel value. Assumes writes have been enabled to analog bus. | 52 | * hardware channel value. Assumes writes have been enabled to analog bus. |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index b30e9fc6433f..171ccf7c972f 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -679,7 +679,6 @@ void ath9k_deinit_device(struct ath_softc *sc); | |||
679 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | 679 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); |
680 | void ath9k_reload_chainmask_settings(struct ath_softc *sc); | 680 | void ath9k_reload_chainmask_settings(struct ath_softc *sc); |
681 | 681 | ||
682 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); | ||
683 | bool ath9k_uses_beacons(int type); | 682 | bool ath9k_uses_beacons(int type); |
684 | 683 | ||
685 | #ifdef CONFIG_ATH9K_PCI | 684 | #ifdef CONFIG_ATH9K_PCI |
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 172e33db7f4c..2f4b48e6fb03 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -400,6 +400,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
400 | ah->noise = ath9k_hw_getchan_noise(ah, chan); | 400 | ah->noise = ath9k_hw_getchan_noise(ah, chan); |
401 | return true; | 401 | return true; |
402 | } | 402 | } |
403 | EXPORT_SYMBOL(ath9k_hw_getnf); | ||
403 | 404 | ||
404 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, | 405 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, |
405 | struct ath9k_channel *chan) | 406 | struct ath9k_channel *chan) |
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 05b9dbf81850..3b33996d97df 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | #include "hw.h" | 20 | #include "hw.h" |
21 | 21 | ||
22 | #define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3 | ||
23 | #define AR_PHY_CCA_FILTERWINDOW_LENGTH 5 | 22 | #define AR_PHY_CCA_FILTERWINDOW_LENGTH 5 |
24 | 23 | ||
25 | #define NUM_NF_READINGS 6 | 24 | #define NUM_NF_READINGS 6 |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e267c92dbfb8..4a00806e2852 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1629,7 +1629,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1629 | 1629 | ||
1630 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1630 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
1631 | struct ieee80211_channel *curchan = hw->conf.channel; | 1631 | struct ieee80211_channel *curchan = hw->conf.channel; |
1632 | struct ath9k_channel old_chan; | ||
1633 | int pos = curchan->hw_value; | 1632 | int pos = curchan->hw_value; |
1634 | int old_pos = -1; | 1633 | int old_pos = -1; |
1635 | unsigned long flags; | 1634 | unsigned long flags; |
@@ -1654,11 +1653,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1654 | * Preserve the current channel values, before updating | 1653 | * Preserve the current channel values, before updating |
1655 | * the same channel | 1654 | * the same channel |
1656 | */ | 1655 | */ |
1657 | if (old_pos == pos) { | 1656 | if (ah->curchan && (old_pos == pos)) |
1658 | memcpy(&old_chan, &sc->sc_ah->channels[pos], | 1657 | ath9k_hw_getnf(ah, ah->curchan); |
1659 | sizeof(struct ath9k_channel)); | ||
1660 | ah->curchan = &old_chan; | ||
1661 | } | ||
1662 | 1658 | ||
1663 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], | 1659 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], |
1664 | curchan, conf->channel_type); | 1660 | curchan, conf->channel_type); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 5a002a21f108..f7eeee1dcdb6 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -3119,8 +3119,10 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) | |||
3119 | /* Verify NVRAM bytes */ | 3119 | /* Verify NVRAM bytes */ |
3120 | brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize); | 3120 | brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize); |
3121 | nvram_ularray = kmalloc(varsize, GFP_ATOMIC); | 3121 | nvram_ularray = kmalloc(varsize, GFP_ATOMIC); |
3122 | if (!nvram_ularray) | 3122 | if (!nvram_ularray) { |
3123 | kfree(vbuffer); | ||
3123 | return -ENOMEM; | 3124 | return -ENOMEM; |
3125 | } | ||
3124 | 3126 | ||
3125 | /* Upload image to verify downloaded contents. */ | 3127 | /* Upload image to verify downloaded contents. */ |
3126 | memset(nvram_ularray, 0xaa, varsize); | 3128 | memset(nvram_ularray, 0xaa, varsize); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 6f91a148c222..3fda6b1dcf46 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c | |||
@@ -196,6 +196,8 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, | |||
196 | /* Allocate skb buffer to contain firmware */ | 196 | /* Allocate skb buffer to contain firmware */ |
197 | /* info and tx descriptor info. */ | 197 | /* info and tx descriptor info. */ |
198 | skb = dev_alloc_skb(frag_length); | 198 | skb = dev_alloc_skb(frag_length); |
199 | if (!skb) | ||
200 | return false; | ||
199 | skb_reserve(skb, extra_descoffset); | 201 | skb_reserve(skb, extra_descoffset); |
200 | seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length - | 202 | seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length - |
201 | extra_descoffset)); | 203 | extra_descoffset)); |
@@ -573,6 +575,8 @@ static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd, | |||
573 | 575 | ||
574 | len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len); | 576 | len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len); |
575 | skb = dev_alloc_skb(len); | 577 | skb = dev_alloc_skb(len); |
578 | if (!skb) | ||
579 | return false; | ||
576 | cb_desc = (struct rtl_tcb_desc *)(skb->cb); | 580 | cb_desc = (struct rtl_tcb_desc *)(skb->cb); |
577 | cb_desc->queue_index = TXCMD_QUEUE; | 581 | cb_desc->queue_index = TXCMD_QUEUE; |
578 | cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL; | 582 | cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL; |
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index d0b597b50398..0cb64f50cecd 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -3404,8 +3404,8 @@ static int __init parport_init_mode_setup(char *str) | |||
3404 | #endif | 3404 | #endif |
3405 | 3405 | ||
3406 | #ifdef MODULE | 3406 | #ifdef MODULE |
3407 | static const char *irq[PARPORT_PC_MAX_PORTS]; | 3407 | static char *irq[PARPORT_PC_MAX_PORTS]; |
3408 | static const char *dma[PARPORT_PC_MAX_PORTS]; | 3408 | static char *dma[PARPORT_PC_MAX_PORTS]; |
3409 | 3409 | ||
3410 | MODULE_PARM_DESC(io, "Base I/O address (SPP regs)"); | 3410 | MODULE_PARM_DESC(io, "Base I/O address (SPP regs)"); |
3411 | module_param_array(io, int, NULL, 0); | 3411 | module_param_array(io, int, NULL, 0); |
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index e91b8ddc2793..c9b92531ae60 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
@@ -16,8 +16,8 @@ | |||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/mfd/ab8500.h> | ||
20 | #include <linux/mfd/abx500.h> | 19 | #include <linux/mfd/abx500.h> |
20 | #include <linux/mfd/abx500/ab8500.h> | ||
21 | #include <linux/regulator/driver.h> | 21 | #include <linux/regulator/driver.h> |
22 | #include <linux/regulator/machine.h> | 22 | #include <linux/regulator/machine.h> |
23 | #include <linux/regulator/ab8500.h> | 23 | #include <linux/regulator/ab8500.h> |
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c index a0a9810adf0b..4bcf9ca2818a 100644 --- a/drivers/rtc/rtc-ab8500.c +++ b/drivers/rtc/rtc-ab8500.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | #include <linux/rtc.h> | 16 | #include <linux/rtc.h> |
17 | #include <linux/mfd/abx500.h> | 17 | #include <linux/mfd/abx500.h> |
18 | #include <linux/mfd/ab8500.h> | 18 | #include <linux/mfd/abx500/ab8500.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | 20 | ||
21 | #define AB8500_RTC_SOFF_STAT_REG 0x00 | 21 | #define AB8500_RTC_SOFF_STAT_REG 0x00 |
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c index 4a5529346b47..2d71943bc436 100644 --- a/drivers/rtc/rtc-max8925.c +++ b/drivers/rtc/rtc-max8925.c | |||
@@ -261,6 +261,8 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev) | |||
261 | /* XXX - isn't this redundant? */ | 261 | /* XXX - isn't this redundant? */ |
262 | platform_set_drvdata(pdev, info); | 262 | platform_set_drvdata(pdev, info); |
263 | 263 | ||
264 | device_init_wakeup(&pdev->dev, 1); | ||
265 | |||
264 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, | 266 | info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev, |
265 | &max8925_rtc_ops, THIS_MODULE); | 267 | &max8925_rtc_ops, THIS_MODULE); |
266 | ret = PTR_ERR(info->rtc_dev); | 268 | ret = PTR_ERR(info->rtc_dev); |
@@ -290,10 +292,34 @@ static int __devexit max8925_rtc_remove(struct platform_device *pdev) | |||
290 | return 0; | 292 | return 0; |
291 | } | 293 | } |
292 | 294 | ||
295 | #ifdef CONFIG_PM_SLEEP | ||
296 | static int max8925_rtc_suspend(struct device *dev) | ||
297 | { | ||
298 | struct platform_device *pdev = to_platform_device(dev); | ||
299 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
300 | |||
301 | if (device_may_wakeup(dev)) | ||
302 | chip->wakeup_flag |= 1 << MAX8925_IRQ_RTC_ALARM0; | ||
303 | return 0; | ||
304 | } | ||
305 | static int max8925_rtc_resume(struct device *dev) | ||
306 | { | ||
307 | struct platform_device *pdev = to_platform_device(dev); | ||
308 | struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent); | ||
309 | |||
310 | if (device_may_wakeup(dev)) | ||
311 | chip->wakeup_flag &= ~(1 << MAX8925_IRQ_RTC_ALARM0); | ||
312 | return 0; | ||
313 | } | ||
314 | #endif | ||
315 | |||
316 | static SIMPLE_DEV_PM_OPS(max8925_rtc_pm_ops, max8925_rtc_suspend, max8925_rtc_resume); | ||
317 | |||
293 | static struct platform_driver max8925_rtc_driver = { | 318 | static struct platform_driver max8925_rtc_driver = { |
294 | .driver = { | 319 | .driver = { |
295 | .name = "max8925-rtc", | 320 | .name = "max8925-rtc", |
296 | .owner = THIS_MODULE, | 321 | .owner = THIS_MODULE, |
322 | .pm = &max8925_rtc_pm_ops, | ||
297 | }, | 323 | }, |
298 | .probe = max8925_rtc_probe, | 324 | .probe = max8925_rtc_probe, |
299 | .remove = __devexit_p(max8925_rtc_remove), | 325 | .remove = __devexit_p(max8925_rtc_remove), |
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c index 07ccea9ada40..74fe6e62e0f7 100644 --- a/drivers/usb/otg/ab8500-usb.c +++ b/drivers/usb/otg/ab8500-usb.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/mfd/abx500.h> | 32 | #include <linux/mfd/abx500.h> |
33 | #include <linux/mfd/ab8500.h> | 33 | #include <linux/mfd/abx500/ab8500.h> |
34 | 34 | ||
35 | #define AB8500_MAIN_WD_CTRL_REG 0x01 | 35 | #define AB8500_MAIN_WD_CTRL_REG 0x01 |
36 | #define AB8500_USB_LINE_STAT_REG 0x80 | 36 | #define AB8500_USB_LINE_STAT_REG 0x80 |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 081dc4745274..fe13ac567d54 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -81,7 +81,7 @@ static int vram __devinitdata = 0; | |||
81 | static int bpp __devinitdata = 8; | 81 | static int bpp __devinitdata = 8; |
82 | static int reverse_i2c __devinitdata; | 82 | static int reverse_i2c __devinitdata; |
83 | #ifdef CONFIG_MTRR | 83 | #ifdef CONFIG_MTRR |
84 | static int nomtrr __devinitdata = 0; | 84 | static bool nomtrr __devinitdata = false; |
85 | #endif | 85 | #endif |
86 | #ifdef CONFIG_PMAC_BACKLIGHT | 86 | #ifdef CONFIG_PMAC_BACKLIGHT |
87 | static int backlight __devinitdata = 1; | 87 | static int backlight __devinitdata = 1; |
@@ -1509,7 +1509,7 @@ static int __devinit nvidiafb_setup(char *options) | |||
1509 | backlight = simple_strtoul(this_opt+10, NULL, 0); | 1509 | backlight = simple_strtoul(this_opt+10, NULL, 0); |
1510 | #ifdef CONFIG_MTRR | 1510 | #ifdef CONFIG_MTRR |
1511 | } else if (!strncmp(this_opt, "nomtrr", 6)) { | 1511 | } else if (!strncmp(this_opt, "nomtrr", 6)) { |
1512 | nomtrr = 1; | 1512 | nomtrr = true; |
1513 | #endif | 1513 | #endif |
1514 | } else if (!strncmp(this_opt, "fpdither:", 9)) { | 1514 | } else if (!strncmp(this_opt, "fpdither:", 9)) { |
1515 | fpdither = simple_strtol(this_opt+9, NULL, 0); | 1515 | fpdither = simple_strtol(this_opt+9, NULL, 0); |
@@ -1599,7 +1599,7 @@ MODULE_PARM_DESC(bpp, "pixel width in bits" | |||
1599 | module_param(reverse_i2c, int, 0); | 1599 | module_param(reverse_i2c, int, 0); |
1600 | MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus"); | 1600 | MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus"); |
1601 | #ifdef CONFIG_MTRR | 1601 | #ifdef CONFIG_MTRR |
1602 | module_param(nomtrr, bool, 0); | 1602 | module_param(nomtrr, bool, false); |
1603 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " | 1603 | MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " |
1604 | "(default=0)"); | 1604 | "(default=0)"); |
1605 | #endif | 1605 | #endif |