summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorFinn Thain <fthain@linux-m68k.org>2026-09-04 19:26:36 +1000
committerJens Axboe <axboe@kernel.dk>2026-09-23 05:14:06 -0600
commit52981bb358d1b5c38040b00f81e2cf973f9148ad (patch)
treec03e1302fb509c52bbbfa8ccc394864f5ed7986d /drivers/block
parent05a7c4b197279cfb3ec3df26146ce085a2438aec (diff)
downloadlinux-next-52981bb358d1b5c38040b00f81e2cf973f9148ad.tar.gz
linux-next-52981bb358d1b5c38040b00f81e2cf973f9148ad.zip
swim: Perform ISM/IWM mode switching according to specs
The SWIM spec says, "MOTOREN must be low to switch modes" and "after switching from ISM to IWM, the very first command must be a clear L7". The ISM spec says, MOTOREN "must not be cleared until after the Action bit is cleared". Perform those operations in the correct sequence. When switching to ISM mode, the Mode register has to be selected with a particular sequence of bit flips. Set q7 low then q6 low then mtrOff. Reviewed-by: Laurent Vivier <laurent@vivier.eu> Fixes: 8852ecd97488 ("m68k: mac - Add SWIM floppy support") Signed-off-by: Finn Thain <fthain@linux-m68k.org> Tested-by: Stan Johnson <userm57@yahoo.com> Link: https://patch.msgid.link/75714ecc9a12d59511967dc9e24163dc8f3bbdd8.1788513996.git.fthain@linux-m68k.org Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/swim.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/block/swim.c b/drivers/block/swim.c
index 3f92677ad127..190b2e1b5b0e 100644
--- a/drivers/block/swim.c
+++ b/drivers/block/swim.c
@@ -149,6 +149,7 @@ struct iwm {
#define ACTION 0x08
#define WRITE_MODE 0x10
#define HEDSEL 0x20
+#define ISM_SELECT 0x40
#define MOTON 0x80
/*----------------------------------------------------------------------------*/
@@ -223,18 +224,21 @@ extern int swim_read_sector_data(struct swim __iomem *base,
static DEFINE_MUTEX(swim_mutex);
static inline void set_swim_mode(struct swim __iomem *base, int enable)
{
- struct iwm __iomem *iwm_base;
+ struct iwm __iomem *iwm_base = (struct iwm __iomem *)base;
unsigned long flags;
if (!enable) {
- swim_write(base, mode0, 0xf8);
+ swim_write(base, mode0, ACTION);
+ swim_write(base, mode0, ENBL1 | ENBL2 | MOTON);
+ swim_write(base, mode0, ISM_SELECT);
+ iwm_read(iwm_base, q7L);
return;
}
- iwm_base = (struct iwm __iomem *)base;
local_irq_save(flags);
iwm_read(iwm_base, q7L);
+ iwm_read(iwm_base, q6L);
iwm_read(iwm_base, mtrOff);
iwm_read(iwm_base, q6H);