cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mediabay.c (19149B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Driver for the media bay on the PowerBook 3400 and 2400.
      4 *
      5 * Copyright (C) 1998 Paul Mackerras.
      6 *
      7 * Various evolutions by Benjamin Herrenschmidt & Henry Worth
      8 */
      9#include <linux/types.h>
     10#include <linux/errno.h>
     11#include <linux/kernel.h>
     12#include <linux/delay.h>
     13#include <linux/sched.h>
     14#include <linux/timer.h>
     15#include <linux/stddef.h>
     16#include <linux/init.h>
     17#include <linux/kthread.h>
     18#include <linux/mutex.h>
     19#include <linux/pgtable.h>
     20
     21#include <asm/io.h>
     22#include <asm/machdep.h>
     23#include <asm/pmac_feature.h>
     24#include <asm/mediabay.h>
     25#include <asm/sections.h>
     26#include <asm/ohare.h>
     27#include <asm/heathrow.h>
     28#include <asm/keylargo.h>
     29#include <linux/adb.h>
     30#include <linux/pmu.h>
     31
     32#define MB_FCR32(bay, r)	((bay)->base + ((r) >> 2))
     33#define MB_FCR8(bay, r)		(((volatile u8 __iomem *)((bay)->base)) + (r))
     34
     35#define MB_IN32(bay,r)		(in_le32(MB_FCR32(bay,r)))
     36#define MB_OUT32(bay,r,v)	(out_le32(MB_FCR32(bay,r), (v)))
     37#define MB_BIS(bay,r,v)		(MB_OUT32((bay), (r), MB_IN32((bay), r) | (v)))
     38#define MB_BIC(bay,r,v)		(MB_OUT32((bay), (r), MB_IN32((bay), r) & ~(v)))
     39#define MB_IN8(bay,r)		(in_8(MB_FCR8(bay,r)))
     40#define MB_OUT8(bay,r,v)	(out_8(MB_FCR8(bay,r), (v)))
     41
     42struct media_bay_info;
     43
     44struct mb_ops {
     45	char*	name;
     46	void	(*init)(struct media_bay_info *bay);
     47	u8	(*content)(struct media_bay_info *bay);
     48	void	(*power)(struct media_bay_info *bay, int on_off);
     49	int	(*setup_bus)(struct media_bay_info *bay, u8 device_id);
     50	void	(*un_reset)(struct media_bay_info *bay);
     51	void	(*un_reset_ide)(struct media_bay_info *bay);
     52};
     53
     54struct media_bay_info {
     55	u32 __iomem			*base;
     56	int				content_id;
     57	int				state;
     58	int				last_value;
     59	int				value_count;
     60	int				timer;
     61	struct macio_dev		*mdev;
     62	const struct mb_ops*		ops;
     63	int				index;
     64	int				cached_gpio;
     65	int				sleeping;
     66	int				user_lock;
     67	struct mutex			lock;
     68};
     69
     70#define MAX_BAYS	2
     71
     72static struct media_bay_info media_bays[MAX_BAYS];
     73static int media_bay_count = 0;
     74
     75/*
     76 * Wait that number of ms between each step in normal polling mode
     77 */
     78#define MB_POLL_DELAY	25
     79
     80/*
     81 * Consider the media-bay ID value stable if it is the same for
     82 * this number of milliseconds
     83 */
     84#define MB_STABLE_DELAY	100
     85
     86/* Wait after powering up the media bay this delay in ms
     87 * timeout bumped for some powerbooks
     88 */
     89#define MB_POWER_DELAY	200
     90
     91/*
     92 * Hold the media-bay reset signal true for this many ticks
     93 * after a device is inserted before releasing it.
     94 */
     95#define MB_RESET_DELAY	50
     96
     97/*
     98 * Wait this long after the reset signal is released and before doing
     99 * further operations. After this delay, the IDE reset signal is released
    100 * too for an IDE device
    101 */
    102#define MB_SETUP_DELAY	100
    103
    104/*
    105 * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted
    106 * (or until the device is ready) before calling into the driver
    107 */
    108#define MB_IDE_WAIT	1000
    109
    110/*
    111 * States of a media bay
    112 */
    113enum {
    114	mb_empty = 0,		/* Idle */
    115	mb_powering_up,		/* power bit set, waiting MB_POWER_DELAY */
    116	mb_enabling_bay,	/* enable bits set, waiting MB_RESET_DELAY */
    117	mb_resetting,		/* reset bit unset, waiting MB_SETUP_DELAY */
    118	mb_ide_resetting,	/* IDE reset bit unser, waiting MB_IDE_WAIT */
    119	mb_up,			/* Media bay full */
    120	mb_powering_down	/* Powering down (avoid too fast down/up) */
    121};
    122
    123#define MB_POWER_SOUND		0x08
    124#define MB_POWER_FLOPPY		0x04
    125#define MB_POWER_ATA		0x02
    126#define MB_POWER_PCI		0x01
    127#define MB_POWER_OFF		0x00
    128
    129/*
    130 * Functions for polling content of media bay
    131 */
    132 
    133static u8
    134ohare_mb_content(struct media_bay_info *bay)
    135{
    136	return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7;
    137}
    138
    139static u8
    140heathrow_mb_content(struct media_bay_info *bay)
    141{
    142	return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7;
    143}
    144
    145static u8
    146keylargo_mb_content(struct media_bay_info *bay)
    147{
    148	int new_gpio;
    149
    150	new_gpio = MB_IN8(bay, KL_GPIO_MEDIABAY_IRQ) & KEYLARGO_GPIO_INPUT_DATA;
    151	if (new_gpio) {
    152		bay->cached_gpio = new_gpio;
    153		return MB_NO;
    154	} else if (bay->cached_gpio != new_gpio) {
    155		MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
    156		(void)MB_IN32(bay, KEYLARGO_MBCR);
    157		udelay(5);
    158		MB_BIC(bay, KEYLARGO_MBCR, 0x0000000F);
    159		(void)MB_IN32(bay, KEYLARGO_MBCR);
    160		udelay(5);
    161		bay->cached_gpio = new_gpio;
    162	}
    163	return (MB_IN32(bay, KEYLARGO_MBCR) >> 4) & 7;
    164}
    165
    166/*
    167 * Functions for powering up/down the bay, puts the bay device
    168 * into reset state as well
    169 */
    170
    171static void
    172ohare_mb_power(struct media_bay_info* bay, int on_off)
    173{
    174	if (on_off) {
    175		/* Power up device, assert it's reset line */
    176		MB_BIC(bay, OHARE_FCR, OH_BAY_RESET_N);
    177		MB_BIC(bay, OHARE_FCR, OH_BAY_POWER_N);
    178	} else {
    179		/* Disable all devices */
    180		MB_BIC(bay, OHARE_FCR, OH_BAY_DEV_MASK);
    181		MB_BIC(bay, OHARE_FCR, OH_FLOPPY_ENABLE);
    182		/* Cut power from bay, release reset line */
    183		MB_BIS(bay, OHARE_FCR, OH_BAY_POWER_N);
    184		MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
    185		MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
    186	}
    187	MB_BIC(bay, OHARE_MBCR, 0x00000F00);
    188}
    189
    190static void
    191heathrow_mb_power(struct media_bay_info* bay, int on_off)
    192{
    193	if (on_off) {
    194		/* Power up device, assert it's reset line */
    195		MB_BIC(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
    196		MB_BIC(bay, HEATHROW_FCR, HRW_BAY_POWER_N);
    197	} else {
    198		/* Disable all devices */
    199		MB_BIC(bay, HEATHROW_FCR, HRW_BAY_DEV_MASK);
    200		MB_BIC(bay, HEATHROW_FCR, HRW_SWIM_ENABLE);
    201		/* Cut power from bay, release reset line */
    202		MB_BIS(bay, HEATHROW_FCR, HRW_BAY_POWER_N);
    203		MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
    204		MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
    205	}
    206	MB_BIC(bay, HEATHROW_MBCR, 0x00000F00);
    207}
    208
    209static void
    210keylargo_mb_power(struct media_bay_info* bay, int on_off)
    211{
    212	if (on_off) {
    213		/* Power up device, assert it's reset line */
    214            	MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
    215            	MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_POWER);
    216	} else {
    217		/* Disable all devices */
    218		MB_BIC(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
    219		MB_BIC(bay, KEYLARGO_FCR1, KL1_EIDE0_ENABLE);
    220		/* Cut power from bay, release reset line */
    221		MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_POWER);
    222		MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
    223		MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
    224	}
    225	MB_BIC(bay, KEYLARGO_MBCR, 0x0000000F);
    226}
    227
    228/*
    229 * Functions for configuring the media bay for a given type of device,
    230 * enable the related busses
    231 */
    232
    233static int
    234ohare_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
    235{
    236	switch(device_id) {
    237		case MB_FD:
    238		case MB_FD1:
    239			MB_BIS(bay, OHARE_FCR, OH_BAY_FLOPPY_ENABLE);
    240			MB_BIS(bay, OHARE_FCR, OH_FLOPPY_ENABLE);
    241			return 0;
    242		case MB_CD:
    243			MB_BIC(bay, OHARE_FCR, OH_IDE1_RESET_N);
    244			MB_BIS(bay, OHARE_FCR, OH_BAY_IDE_ENABLE);
    245			return 0;
    246		case MB_PCI:
    247			MB_BIS(bay, OHARE_FCR, OH_BAY_PCI_ENABLE);
    248			return 0;
    249	}
    250	return -ENODEV;
    251}
    252
    253static int
    254heathrow_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
    255{
    256	switch(device_id) {
    257		case MB_FD:
    258		case MB_FD1:
    259			MB_BIS(bay, HEATHROW_FCR, HRW_BAY_FLOPPY_ENABLE);
    260			MB_BIS(bay, HEATHROW_FCR, HRW_SWIM_ENABLE);
    261			return 0;
    262		case MB_CD:
    263			MB_BIC(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
    264			MB_BIS(bay, HEATHROW_FCR, HRW_BAY_IDE_ENABLE);
    265			return 0;
    266		case MB_PCI:
    267			MB_BIS(bay, HEATHROW_FCR, HRW_BAY_PCI_ENABLE);
    268			return 0;
    269	}
    270	return -ENODEV;
    271}
    272
    273static int
    274keylargo_mb_setup_bus(struct media_bay_info* bay, u8 device_id)
    275{
    276	switch(device_id) {
    277		case MB_CD:
    278			MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
    279			MB_BIC(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
    280			MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_ENABLE);
    281			return 0;
    282		case MB_PCI:
    283			MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_PCI_ENABLE);
    284			return 0;
    285		case MB_SOUND:
    286			MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_SOUND_ENABLE);
    287			return 0;
    288	}
    289	return -ENODEV;
    290}
    291
    292/*
    293 * Functions for tweaking resets
    294 */
    295
    296static void
    297ohare_mb_un_reset(struct media_bay_info* bay)
    298{
    299	MB_BIS(bay, OHARE_FCR, OH_BAY_RESET_N);
    300}
    301
    302static void keylargo_mb_init(struct media_bay_info *bay)
    303{
    304	MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_ENABLE);
    305}
    306
    307static void heathrow_mb_un_reset(struct media_bay_info* bay)
    308{
    309	MB_BIS(bay, HEATHROW_FCR, HRW_BAY_RESET_N);
    310}
    311
    312static void keylargo_mb_un_reset(struct media_bay_info* bay)
    313{
    314	MB_BIS(bay, KEYLARGO_MBCR, KL_MBCR_MB0_DEV_RESET);
    315}
    316
    317static void ohare_mb_un_reset_ide(struct media_bay_info* bay)
    318{
    319	MB_BIS(bay, OHARE_FCR, OH_IDE1_RESET_N);
    320}
    321
    322static void heathrow_mb_un_reset_ide(struct media_bay_info* bay)
    323{
    324	MB_BIS(bay, HEATHROW_FCR, HRW_IDE1_RESET_N);
    325}
    326
    327static void keylargo_mb_un_reset_ide(struct media_bay_info* bay)
    328{
    329	MB_BIS(bay, KEYLARGO_FCR1, KL1_EIDE0_RESET_N);
    330}
    331
    332static inline void set_mb_power(struct media_bay_info* bay, int onoff)
    333{
    334	/* Power up up and assert the bay reset line */
    335	if (onoff) {
    336		bay->ops->power(bay, 1);
    337		bay->state = mb_powering_up;
    338		pr_debug("mediabay%d: powering up\n", bay->index);
    339	} else { 
    340		/* Make sure everything is powered down & disabled */
    341		bay->ops->power(bay, 0);
    342		bay->state = mb_powering_down;
    343		pr_debug("mediabay%d: powering down\n", bay->index);
    344	}
    345	bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
    346}
    347
    348static void poll_media_bay(struct media_bay_info* bay)
    349{
    350	int id = bay->ops->content(bay);
    351
    352	static char *mb_content_types[] = {
    353		"a floppy drive",
    354		"a floppy drive",
    355		"an unsupported audio device",
    356		"an ATA device",
    357		"an unsupported PCI device",
    358		"an unknown device",
    359	};
    360
    361	if (id != bay->last_value) {
    362		bay->last_value = id;
    363		bay->value_count = 0;
    364		return;
    365	}
    366	if (id == bay->content_id)
    367		return;
    368
    369	bay->value_count += msecs_to_jiffies(MB_POLL_DELAY);
    370	if (bay->value_count >= msecs_to_jiffies(MB_STABLE_DELAY)) {
    371		/* If the device type changes without going thru
    372		 * "MB_NO", we force a pass by "MB_NO" to make sure
    373		 * things are properly reset
    374		 */
    375		if ((id != MB_NO) && (bay->content_id != MB_NO)) {
    376			id = MB_NO;
    377			pr_debug("mediabay%d: forcing MB_NO\n", bay->index);
    378		}
    379		pr_debug("mediabay%d: switching to %d\n", bay->index, id);
    380		set_mb_power(bay, id != MB_NO);
    381		bay->content_id = id;
    382		if (id >= MB_NO || id < 0)
    383			printk(KERN_INFO "mediabay%d: Bay is now empty\n", bay->index);
    384		else
    385			printk(KERN_INFO "mediabay%d: Bay contains %s\n",
    386			       bay->index, mb_content_types[id]);
    387	}
    388}
    389
    390int check_media_bay(struct macio_dev *baydev)
    391{
    392	struct media_bay_info* bay;
    393	int id;
    394
    395	if (baydev == NULL)
    396		return MB_NO;
    397
    398	/* This returns an instant snapshot, not locking, sine
    399	 * we may be called with the bay lock held. The resulting
    400	 * fuzzyness of the result if called at the wrong time is
    401	 * not actually a huge deal
    402	 */
    403	bay = macio_get_drvdata(baydev);
    404	if (bay == NULL)
    405		return MB_NO;
    406	id = bay->content_id;
    407	if (bay->state != mb_up)
    408		return MB_NO;
    409	if (id == MB_FD1)
    410		return MB_FD;
    411	return id;
    412}
    413EXPORT_SYMBOL_GPL(check_media_bay);
    414
    415void lock_media_bay(struct macio_dev *baydev)
    416{
    417	struct media_bay_info* bay;
    418
    419	if (baydev == NULL)
    420		return;
    421	bay = macio_get_drvdata(baydev);
    422	if (bay == NULL)
    423		return;
    424	mutex_lock(&bay->lock);
    425	bay->user_lock = 1;
    426}
    427EXPORT_SYMBOL_GPL(lock_media_bay);
    428
    429void unlock_media_bay(struct macio_dev *baydev)
    430{
    431	struct media_bay_info* bay;
    432
    433	if (baydev == NULL)
    434		return;
    435	bay = macio_get_drvdata(baydev);
    436	if (bay == NULL)
    437		return;
    438	if (bay->user_lock) {
    439		bay->user_lock = 0;
    440		mutex_unlock(&bay->lock);
    441	}
    442}
    443EXPORT_SYMBOL_GPL(unlock_media_bay);
    444
    445static int mb_broadcast_hotplug(struct device *dev, void *data)
    446{
    447	struct media_bay_info* bay = data;
    448	struct macio_dev *mdev;
    449	struct macio_driver *drv;
    450	int state;
    451
    452	if (dev->bus != &macio_bus_type)
    453		return 0;
    454
    455	state = bay->state == mb_up ? bay->content_id : MB_NO;
    456	if (state == MB_FD1)
    457		state = MB_FD;
    458	mdev = to_macio_device(dev);
    459	drv = to_macio_driver(dev->driver);
    460	if (dev->driver && drv->mediabay_event)
    461		drv->mediabay_event(mdev, state);
    462	return 0;
    463}
    464
    465static void media_bay_step(int i)
    466{
    467	struct media_bay_info* bay = &media_bays[i];
    468
    469	/* We don't poll when powering down */
    470	if (bay->state != mb_powering_down)
    471	    poll_media_bay(bay);
    472
    473	/* If timer expired run state machine */
    474	if (bay->timer != 0) {
    475		bay->timer -= msecs_to_jiffies(MB_POLL_DELAY);
    476		if (bay->timer > 0)
    477			return;
    478		bay->timer = 0;
    479	}
    480
    481	switch(bay->state) {
    482	case mb_powering_up:
    483	    	if (bay->ops->setup_bus(bay, bay->last_value) < 0) {
    484			pr_debug("mediabay%d: device not supported (kind:%d)\n",
    485				 i, bay->content_id);
    486	    		set_mb_power(bay, 0);
    487	    		break;
    488	    	}
    489	    	bay->timer = msecs_to_jiffies(MB_RESET_DELAY);
    490	    	bay->state = mb_enabling_bay;
    491		pr_debug("mediabay%d: enabling (kind:%d)\n", i, bay->content_id);
    492		break;
    493	case mb_enabling_bay:
    494		bay->ops->un_reset(bay);
    495	    	bay->timer = msecs_to_jiffies(MB_SETUP_DELAY);
    496	    	bay->state = mb_resetting;
    497		pr_debug("mediabay%d: releasing bay reset (kind:%d)\n",
    498			 i, bay->content_id);
    499	    	break;
    500	case mb_resetting:
    501		if (bay->content_id != MB_CD) {
    502			pr_debug("mediabay%d: bay is up (kind:%d)\n", i,
    503				 bay->content_id);
    504			bay->state = mb_up;
    505			device_for_each_child(&bay->mdev->ofdev.dev,
    506					      bay, mb_broadcast_hotplug);
    507			break;
    508	    	}
    509		pr_debug("mediabay%d: releasing ATA reset (kind:%d)\n",
    510			 i, bay->content_id);
    511		bay->ops->un_reset_ide(bay);
    512	    	bay->timer = msecs_to_jiffies(MB_IDE_WAIT);
    513	    	bay->state = mb_ide_resetting;
    514	    	break;
    515
    516	case mb_ide_resetting:
    517		pr_debug("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
    518		bay->state = mb_up;
    519		device_for_each_child(&bay->mdev->ofdev.dev,
    520				      bay, mb_broadcast_hotplug);
    521	    	break;
    522
    523	case mb_powering_down:
    524	    	bay->state = mb_empty;
    525		device_for_each_child(&bay->mdev->ofdev.dev,
    526				      bay, mb_broadcast_hotplug);
    527		pr_debug("mediabay%d: end of power down\n", i);
    528	    	break;
    529	}
    530}
    531
    532/*
    533 * This procedure runs as a kernel thread to poll the media bay
    534 * once each tick and register and unregister the IDE interface
    535 * with the IDE driver.  It needs to be a thread because
    536 * ide_register can't be called from interrupt context.
    537 */
    538static int media_bay_task(void *x)
    539{
    540	int	i;
    541
    542	while (!kthread_should_stop()) {
    543		for (i = 0; i < media_bay_count; ++i) {
    544			mutex_lock(&media_bays[i].lock);
    545			if (!media_bays[i].sleeping)
    546				media_bay_step(i);
    547			mutex_unlock(&media_bays[i].lock);
    548		}
    549
    550		msleep_interruptible(MB_POLL_DELAY);
    551	}
    552	return 0;
    553}
    554
    555static int media_bay_attach(struct macio_dev *mdev,
    556			    const struct of_device_id *match)
    557{
    558	struct media_bay_info* bay;
    559	u32 __iomem *regbase;
    560	struct device_node *ofnode;
    561	unsigned long base;
    562	int i;
    563
    564	ofnode = mdev->ofdev.dev.of_node;
    565
    566	if (macio_resource_count(mdev) < 1)
    567		return -ENODEV;
    568	if (macio_request_resources(mdev, "media-bay"))
    569		return -EBUSY;
    570	/* Media bay registers are located at the beginning of the
    571         * mac-io chip, for now, we trick and align down the first
    572	 * resource passed in
    573         */
    574	base = macio_resource_start(mdev, 0) & 0xffff0000u;
    575	regbase = (u32 __iomem *)ioremap(base, 0x100);
    576	if (regbase == NULL) {
    577		macio_release_resources(mdev);
    578		return -ENOMEM;
    579	}
    580	
    581	i = media_bay_count++;
    582	bay = &media_bays[i];
    583	bay->mdev = mdev;
    584	bay->base = regbase;
    585	bay->index = i;
    586	bay->ops = match->data;
    587	bay->sleeping = 0;
    588	mutex_init(&bay->lock);
    589
    590	/* Init HW probing */
    591	if (bay->ops->init)
    592		bay->ops->init(bay);
    593
    594	printk(KERN_INFO "mediabay%d: Registered %s media-bay\n", i, bay->ops->name);
    595
    596	/* Force an immediate detect */
    597	set_mb_power(bay, 0);
    598	msleep(MB_POWER_DELAY);
    599	bay->content_id = MB_NO;
    600	bay->last_value = bay->ops->content(bay);
    601	bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
    602	bay->state = mb_empty;
    603
    604	/* Mark us ready by filling our mdev data */
    605	macio_set_drvdata(mdev, bay);
    606
    607	/* Startup kernel thread */
    608	if (i == 0)
    609		kthread_run(media_bay_task, NULL, "media-bay");
    610
    611	return 0;
    612
    613}
    614
    615static int media_bay_suspend(struct macio_dev *mdev, pm_message_t state)
    616{
    617	struct media_bay_info	*bay = macio_get_drvdata(mdev);
    618
    619	if (state.event != mdev->ofdev.dev.power.power_state.event
    620	    && (state.event & PM_EVENT_SLEEP)) {
    621		mutex_lock(&bay->lock);
    622		bay->sleeping = 1;
    623		set_mb_power(bay, 0);
    624		mutex_unlock(&bay->lock);
    625		msleep(MB_POLL_DELAY);
    626		mdev->ofdev.dev.power.power_state = state;
    627	}
    628	return 0;
    629}
    630
    631static int media_bay_resume(struct macio_dev *mdev)
    632{
    633	struct media_bay_info	*bay = macio_get_drvdata(mdev);
    634
    635	if (mdev->ofdev.dev.power.power_state.event != PM_EVENT_ON) {
    636		mdev->ofdev.dev.power.power_state = PMSG_ON;
    637
    638	       	/* We re-enable the bay using it's previous content
    639	       	   only if it did not change. Note those bozo timings,
    640	       	   they seem to help the 3400 get it right.
    641	       	 */
    642	       	/* Force MB power to 0 */
    643		mutex_lock(&bay->lock);
    644	       	set_mb_power(bay, 0);
    645		msleep(MB_POWER_DELAY);
    646	       	if (bay->ops->content(bay) != bay->content_id) {
    647			printk("mediabay%d: Content changed during sleep...\n", bay->index);
    648			mutex_unlock(&bay->lock);
    649	       		return 0;
    650		}
    651	       	set_mb_power(bay, 1);
    652	       	bay->last_value = bay->content_id;
    653	       	bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY);
    654	       	bay->timer = msecs_to_jiffies(MB_POWER_DELAY);
    655	       	do {
    656			msleep(MB_POLL_DELAY);
    657	       		media_bay_step(bay->index);
    658	       	} while((bay->state != mb_empty) &&
    659	       		(bay->state != mb_up));
    660		bay->sleeping = 0;
    661		mutex_unlock(&bay->lock);
    662	}
    663	return 0;
    664}
    665
    666
    667/* Definitions of "ops" structures.
    668 */
    669static const struct mb_ops ohare_mb_ops = {
    670	.name		= "Ohare",
    671	.content	= ohare_mb_content,
    672	.power		= ohare_mb_power,
    673	.setup_bus	= ohare_mb_setup_bus,
    674	.un_reset	= ohare_mb_un_reset,
    675	.un_reset_ide	= ohare_mb_un_reset_ide,
    676};
    677
    678static const struct mb_ops heathrow_mb_ops = {
    679	.name		= "Heathrow",
    680	.content	= heathrow_mb_content,
    681	.power		= heathrow_mb_power,
    682	.setup_bus	= heathrow_mb_setup_bus,
    683	.un_reset	= heathrow_mb_un_reset,
    684	.un_reset_ide	= heathrow_mb_un_reset_ide,
    685};
    686
    687static const struct mb_ops keylargo_mb_ops = {
    688	.name		= "KeyLargo",
    689	.init		= keylargo_mb_init,
    690	.content	= keylargo_mb_content,
    691	.power		= keylargo_mb_power,
    692	.setup_bus	= keylargo_mb_setup_bus,
    693	.un_reset	= keylargo_mb_un_reset,
    694	.un_reset_ide	= keylargo_mb_un_reset_ide,
    695};
    696
    697/*
    698 * It seems that the bit for the media-bay interrupt in the IRQ_LEVEL
    699 * register is always set when there is something in the media bay.
    700 * This causes problems for the interrupt code if we attach an interrupt
    701 * handler to the media-bay interrupt, because it tends to go into
    702 * an infinite loop calling the media bay interrupt handler.
    703 * Therefore we do it all by polling the media bay once each tick.
    704 */
    705
    706static const struct of_device_id media_bay_match[] =
    707{
    708	{
    709	.name		= "media-bay",
    710	.compatible	= "keylargo-media-bay",
    711	.data		= &keylargo_mb_ops,
    712	},
    713	{
    714	.name		= "media-bay",
    715	.compatible	= "heathrow-media-bay",
    716	.data		= &heathrow_mb_ops,
    717	},
    718	{
    719	.name		= "media-bay",
    720	.compatible	= "ohare-media-bay",
    721	.data		= &ohare_mb_ops,
    722	},
    723	{},
    724};
    725
    726static struct macio_driver media_bay_driver =
    727{
    728	.driver = {
    729		.name		= "media-bay",
    730		.of_match_table	= media_bay_match,
    731	},
    732	.probe		= media_bay_attach,
    733	.suspend	= media_bay_suspend,
    734	.resume		= media_bay_resume
    735};
    736
    737static int __init media_bay_init(void)
    738{
    739	int i;
    740
    741	for (i=0; i<MAX_BAYS; i++) {
    742		memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
    743		media_bays[i].content_id	= -1;
    744	}
    745	if (!machine_is(powermac))
    746		return 0;
    747
    748	macio_register_driver(&media_bay_driver);	
    749
    750	return 0;
    751}
    752
    753device_initcall(media_bay_init);