Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "Support power resources defined in acpi on ata"

Markus Probst <markus.probst@posteo.de> says:

This series adds support for power resources defined in acpi on ata
ports/devices. A device can define a power resource in an ata port/device,
which then gets powered on right before the port is probed. This can be
useful for devices, which have sata power connectors that are:
a: powered down by default
b: can be individually powered on
like in some synology nas devices. If thats the case it will be assumed,
that the power resource won't survive reboots and therefore the disk will
be stopped.

Link: https://patch.msgid.link/20251104142413.322347-1-markus.probst@posteo.de
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

+113 -1
+67
drivers/ata/libata-acpi.c
··· 246 246 } 247 247 248 248 /** 249 + * ata_acpi_dev_manage_restart - if the disk should be stopped (spun down) on 250 + * system restart. 251 + * @dev: target ATA device 252 + * 253 + * RETURNS: 254 + * true if the disk should be stopped, otherwise false. 255 + */ 256 + bool ata_acpi_dev_manage_restart(struct ata_device *dev) 257 + { 258 + struct device *tdev; 259 + 260 + /* 261 + * If ATA_FLAG_ACPI_SATA is set, the acpi fwnode is attached to the 262 + * ata_device instead of the ata_port. 263 + */ 264 + if (dev->link->ap->flags & ATA_FLAG_ACPI_SATA) 265 + tdev = &dev->tdev; 266 + else 267 + tdev = &dev->link->ap->tdev; 268 + 269 + if (!is_acpi_device_node(tdev->fwnode)) 270 + return false; 271 + return acpi_bus_power_manageable(ACPI_HANDLE(tdev)); 272 + } 273 + 274 + /** 275 + * ata_acpi_port_power_on - set the power state of the ata port to D0 276 + * @ap: target ATA port 277 + * 278 + * This function is called at the beginning of ata_port_probe(). 279 + */ 280 + void ata_acpi_port_power_on(struct ata_port *ap) 281 + { 282 + acpi_handle handle; 283 + int i; 284 + 285 + /* 286 + * If ATA_FLAG_ACPI_SATA is set, the acpi fwnode is attached to the 287 + * ata_device instead of the ata_port. 288 + */ 289 + if (ap->flags & ATA_FLAG_ACPI_SATA) { 290 + for (i = 0; i < ATA_MAX_DEVICES; i++) { 291 + struct ata_device *dev = &ap->link.device[i]; 292 + 293 + if (!is_acpi_device_node(dev->tdev.fwnode)) 294 + continue; 295 + handle = ACPI_HANDLE(&dev->tdev); 296 + if (!acpi_bus_power_manageable(handle)) 297 + continue; 298 + if (acpi_bus_set_power(handle, ACPI_STATE_D0)) 299 + ata_dev_err(dev, 300 + "acpi: failed to set power state to D0\n"); 301 + } 302 + return; 303 + } 304 + 305 + if (!is_acpi_device_node(ap->tdev.fwnode)) 306 + return; 307 + handle = ACPI_HANDLE(&ap->tdev); 308 + if (!acpi_bus_power_manageable(handle)) 309 + return; 310 + 311 + if (acpi_bus_set_power(handle, ACPI_STATE_D0)) 312 + ata_port_err(ap, "acpi: failed to set power state to D0\n"); 313 + } 314 + 315 + /** 249 316 * ata_acpi_dissociate - dissociate ATA host from ACPI objects 250 317 * @host: target ATA host 251 318 *
+2
drivers/ata/libata-core.c
··· 5904 5904 struct ata_eh_info *ehi = &ap->link.eh_info; 5905 5905 unsigned long flags; 5906 5906 5907 + ata_acpi_port_power_on(ap); 5908 + 5907 5909 /* kick EH for boot probing */ 5908 5910 spin_lock_irqsave(ap->lock, flags); 5909 5911
+1
drivers/ata/libata-scsi.c
··· 1095 1095 */ 1096 1096 sdev->manage_runtime_start_stop = 1; 1097 1097 sdev->manage_shutdown = 1; 1098 + sdev->manage_restart = ata_acpi_dev_manage_restart(dev); 1098 1099 sdev->force_runtime_start_on_system_start = 1; 1099 1100 } 1100 1101
+4
drivers/ata/libata.h
··· 130 130 extern void ata_acpi_set_state(struct ata_port *ap, pm_message_t state); 131 131 extern void ata_acpi_bind_port(struct ata_port *ap); 132 132 extern void ata_acpi_bind_dev(struct ata_device *dev); 133 + extern void ata_acpi_port_power_on(struct ata_port *ap); 134 + extern bool ata_acpi_dev_manage_restart(struct ata_device *dev); 133 135 extern acpi_handle ata_dev_acpi_handle(struct ata_device *dev); 134 136 #else 135 137 static inline void ata_acpi_dissociate(struct ata_host *host) { } ··· 142 140 pm_message_t state) { } 143 141 static inline void ata_acpi_bind_port(struct ata_port *ap) {} 144 142 static inline void ata_acpi_bind_dev(struct ata_device *dev) {} 143 + static inline void ata_acpi_port_power_on(struct ata_port *ap) {} 144 + static inline bool ata_acpi_dev_manage_restart(struct ata_device *dev) { return 0; } 145 145 #endif 146 146 147 147 /* libata-scsi.c */
+33 -1
drivers/scsi/sd.c
··· 318 318 } 319 319 static DEVICE_ATTR_RW(manage_shutdown); 320 320 321 + static ssize_t manage_restart_show(struct device *dev, 322 + struct device_attribute *attr, char *buf) 323 + { 324 + struct scsi_disk *sdkp = to_scsi_disk(dev); 325 + struct scsi_device *sdp = sdkp->device; 326 + 327 + return sysfs_emit(buf, "%u\n", sdp->manage_restart); 328 + } 329 + 330 + static ssize_t manage_restart_store(struct device *dev, 331 + struct device_attribute *attr, 332 + const char *buf, size_t count) 333 + { 334 + struct scsi_disk *sdkp = to_scsi_disk(dev); 335 + struct scsi_device *sdp = sdkp->device; 336 + bool v; 337 + 338 + if (!capable(CAP_SYS_ADMIN)) 339 + return -EACCES; 340 + 341 + if (kstrtobool(buf, &v)) 342 + return -EINVAL; 343 + 344 + sdp->manage_restart = v; 345 + 346 + return count; 347 + } 348 + static DEVICE_ATTR_RW(manage_restart); 349 + 321 350 static ssize_t 322 351 allow_restart_show(struct device *dev, struct device_attribute *attr, char *buf) 323 352 { ··· 683 654 &dev_attr_manage_system_start_stop.attr, 684 655 &dev_attr_manage_runtime_start_stop.attr, 685 656 &dev_attr_manage_shutdown.attr, 657 + &dev_attr_manage_restart.attr, 686 658 &dev_attr_protection_type.attr, 687 659 &dev_attr_protection_mode.attr, 688 660 &dev_attr_app_tag_own.attr, ··· 4207 4177 (system_state == SYSTEM_POWER_OFF && 4208 4178 sdkp->device->manage_shutdown) || 4209 4179 (system_state == SYSTEM_RUNNING && 4210 - sdkp->device->manage_runtime_start_stop)) { 4180 + sdkp->device->manage_runtime_start_stop) || 4181 + (system_state == SYSTEM_RESTART && 4182 + sdkp->device->manage_restart)) { 4211 4183 sd_printk(KERN_NOTICE, sdkp, "Stopping disk\n"); 4212 4184 sd_start_stop_device(sdkp, 0); 4213 4185 }
+6
include/scsi/scsi_device.h
··· 179 179 unsigned manage_shutdown:1; 180 180 181 181 /* 182 + * If true, let the high-level device driver (sd) manage the device 183 + * power state for system restart (reboot) operations. 184 + */ 185 + unsigned manage_restart:1; 186 + 187 + /* 182 188 * If set and if the device is runtime suspended, ask the high-level 183 189 * device driver (sd) to force a runtime resume of the device. 184 190 */