260 NULL) {
261 cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
262 "can't get state", instance);
263 ddi_soft_state_free(cpudrv_state, instance);
264 cpudrv_enabled = B_FALSE;
265 return (DDI_FAILURE);
266 }
267 cpudsp->dip = dip;
268
269 /*
270 * Find CPU number for this dev_info node.
271 */
272 if (!cpudrv_get_cpu_id(dip, &(cpudsp->cpu_id))) {
273 cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
274 "can't convert dip to cpu_id", instance);
275 ddi_soft_state_free(cpudrv_state, instance);
276 cpudrv_enabled = B_FALSE;
277 return (DDI_FAILURE);
278 }
279
280 mutex_init(&cpudsp->lock, NULL, MUTEX_DRIVER, NULL);
281 if (cpudrv_is_enabled(cpudsp)) {
282 if (cpudrv_init(cpudsp) != DDI_SUCCESS) {
283 cpudrv_enabled = B_FALSE;
284 cpudrv_free(cpudsp);
285 ddi_soft_state_free(cpudrv_state, instance);
286 return (DDI_FAILURE);
287 }
288 if (cpudrv_comp_create(cpudsp) != DDI_SUCCESS) {
289 cpudrv_enabled = B_FALSE;
290 cpudrv_free(cpudsp);
291 ddi_soft_state_free(cpudrv_state, instance);
292 return (DDI_FAILURE);
293 }
294 if (ddi_prop_update_string(DDI_DEV_T_NONE,
295 dip, "pm-class", "CPU") != DDI_PROP_SUCCESS) {
296 cpudrv_enabled = B_FALSE;
297 cpudrv_free(cpudsp);
298 ddi_soft_state_free(cpudrv_state, instance);
299 return (DDI_FAILURE);
300 }
301
302 /*
303 * Taskq is used to dispatch routine to monitor CPU
304 * activities.
305 */
306 cpudsp->cpudrv_pm.tq = ddi_taskq_create(dip,
307 "cpudrv_monitor", CPUDRV_TASKQ_THREADS,
308 TASKQ_DEFAULTPRI, 0);
309
310 mutex_init(&cpudsp->cpudrv_pm.timeout_lock, NULL,
311 MUTEX_DRIVER, NULL);
312 cv_init(&cpudsp->cpudrv_pm.timeout_cv, NULL,
313 CV_DEFAULT, NULL);
314
315 /*
316 * Driver needs to assume that CPU is running at
317 * unknown speed at DDI_ATTACH and switch it to the
318 * needed speed. We assume that initial needed speed
319 * is full speed for us.
320 */
321 /*
322 * We need to take the lock because cpudrv_monitor()
323 * will start running in parallel with attach().
324 */
325 mutex_enter(&cpudsp->lock);
326 cpudsp->cpudrv_pm.cur_spd = NULL;
327 cpudsp->cpudrv_pm.pm_started = B_FALSE;
328 /*
329 * We don't call pm_raise_power() directly from attach
330 * because driver attach for a slave CPU node can
331 * happen before the CPU is even initialized. We just
332 * start the monitoring system which understands
333 * unknown speed and moves CPU to top speed when it
334 * has been initialized.
335 */
336 CPUDRV_MONITOR_INIT(cpudsp);
337 mutex_exit(&cpudsp->lock);
338
339 }
340
341 if (!cpudrv_mach_init(cpudsp)) {
342 cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
343 "cpudrv_mach_init failed", instance);
344 cpudrv_enabled = B_FALSE;
345 cpudrv_free(cpudsp);
346 ddi_soft_state_free(cpudrv_state, instance);
347 return (DDI_FAILURE);
348 }
349
350 CPUDRV_INSTALL_MAX_CHANGE_HANDLER(cpudsp);
351
352 (void) ddi_prop_update_int(DDI_DEV_T_NONE, dip,
353 DDI_NO_AUTODETACH, 1);
354 ddi_report_dev(dip);
355 return (DDI_SUCCESS);
356
357 case DDI_RESUME:
358 DPRINTF(D_ATTACH, ("cpudrv_attach: instance %d: "
359 "DDI_RESUME called\n", instance));
360
361 cpudsp = ddi_get_soft_state(cpudrv_state, instance);
362 ASSERT(cpudsp != NULL);
363
364 /*
|
260 NULL) {
261 cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
262 "can't get state", instance);
263 ddi_soft_state_free(cpudrv_state, instance);
264 cpudrv_enabled = B_FALSE;
265 return (DDI_FAILURE);
266 }
267 cpudsp->dip = dip;
268
269 /*
270 * Find CPU number for this dev_info node.
271 */
272 if (!cpudrv_get_cpu_id(dip, &(cpudsp->cpu_id))) {
273 cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
274 "can't convert dip to cpu_id", instance);
275 ddi_soft_state_free(cpudrv_state, instance);
276 cpudrv_enabled = B_FALSE;
277 return (DDI_FAILURE);
278 }
279
280 if (!cpudrv_is_enabled(cpudsp)) {
281 cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
282 "not supported or it got disabled on us",
283 instance);
284 cpudrv_enabled = B_FALSE;
285 ddi_soft_state_free(cpudrv_state, instance);
286 return (DDI_FAILURE);
287 }
288
289 mutex_init(&cpudsp->lock, NULL, MUTEX_DRIVER, NULL);
290 if (cpudrv_init(cpudsp) != DDI_SUCCESS) {
291 cpudrv_enabled = B_FALSE;
292 cpudrv_free(cpudsp);
293 ddi_soft_state_free(cpudrv_state, instance);
294 return (DDI_FAILURE);
295 }
296 if (cpudrv_comp_create(cpudsp) != DDI_SUCCESS) {
297 cpudrv_enabled = B_FALSE;
298 cpudrv_free(cpudsp);
299 ddi_soft_state_free(cpudrv_state, instance);
300 return (DDI_FAILURE);
301 }
302 if (ddi_prop_update_string(DDI_DEV_T_NONE,
303 dip, "pm-class", "CPU") != DDI_PROP_SUCCESS) {
304 cpudrv_enabled = B_FALSE;
305 cpudrv_free(cpudsp);
306 ddi_soft_state_free(cpudrv_state, instance);
307 return (DDI_FAILURE);
308 }
309
310 /*
311 * Taskq is used to dispatch routine to monitor CPU
312 * activities.
313 */
314 cpudsp->cpudrv_pm.tq = ddi_taskq_create(dip,
315 "cpudrv_monitor", CPUDRV_TASKQ_THREADS,
316 TASKQ_DEFAULTPRI, 0);
317 if (cpudsp->cpudrv_pm.tq == NULL) {
318 cpudrv_enabled = B_FALSE;
319 cpudrv_free(cpudsp);
320 ddi_soft_state_free(cpudrv_state, instance);
321 return (DDI_FAILURE);
322 }
323
324 mutex_init(&cpudsp->cpudrv_pm.timeout_lock, NULL,
325 MUTEX_DRIVER, NULL);
326 cv_init(&cpudsp->cpudrv_pm.timeout_cv, NULL,
327 CV_DEFAULT, NULL);
328
329 /*
330 * Driver needs to assume that CPU is running at
331 * unknown speed at DDI_ATTACH and switch it to the
332 * needed speed. We assume that initial needed speed
333 * is full speed for us.
334 */
335 /*
336 * We need to take the lock because cpudrv_monitor()
337 * will start running in parallel with attach().
338 */
339 mutex_enter(&cpudsp->lock);
340 cpudsp->cpudrv_pm.cur_spd = NULL;
341 cpudsp->cpudrv_pm.pm_started = B_FALSE;
342 /*
343 * We don't call pm_raise_power() directly from attach
344 * because driver attach for a slave CPU node can
345 * happen before the CPU is even initialized. We just
346 * start the monitoring system which understands
347 * unknown speed and moves CPU to top speed when it
348 * has been initialized.
349 */
350 CPUDRV_MONITOR_INIT(cpudsp);
351 mutex_exit(&cpudsp->lock);
352
353 if (!cpudrv_mach_init(cpudsp)) {
354 cmn_err(CE_WARN, "cpudrv_attach: instance %d: "
355 "cpudrv_mach_init failed", instance);
356 cpudrv_enabled = B_FALSE;
357 ddi_taskq_destroy(cpudsp->cpudrv_pm.tq);
358 cpudrv_free(cpudsp);
359 ddi_soft_state_free(cpudrv_state, instance);
360 return (DDI_FAILURE);
361 }
362
363 CPUDRV_INSTALL_MAX_CHANGE_HANDLER(cpudsp);
364
365 (void) ddi_prop_update_int(DDI_DEV_T_NONE, dip,
366 DDI_NO_AUTODETACH, 1);
367 ddi_report_dev(dip);
368 return (DDI_SUCCESS);
369
370 case DDI_RESUME:
371 DPRINTF(D_ATTACH, ("cpudrv_attach: instance %d: "
372 "DDI_RESUME called\n", instance));
373
374 cpudsp = ddi_get_soft_state(cpudrv_state, instance);
375 ASSERT(cpudsp != NULL);
376
377 /*
|