brintos

brintos / linux-shallow public Read only

0
0
Text · 18.7 KiB · 36070c6 Raw
754 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*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 Worth8 */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	271 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 mode77 */78#define MB_POLL_DELAY	2579 80/*81 * Consider the media-bay ID value stable if it is the same for82 * this number of milliseconds83 */84#define MB_STABLE_DELAY	10085 86/* Wait after powering up the media bay this delay in ms87 * timeout bumped for some powerbooks88 */89#define MB_POWER_DELAY	20090 91/*92 * Hold the media-bay reset signal true for this many ticks93 * after a device is inserted before releasing it.94 */95#define MB_RESET_DELAY	5096 97/*98 * Wait this long after the reset signal is released and before doing99 * further operations. After this delay, the IDE reset signal is released100 * too for an IDE device101 */102#define MB_SETUP_DELAY	100103 104/*105 * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted106 * (or until the device is ready) before calling into the driver107 */108#define MB_IDE_WAIT	1000109 110/*111 * States of a media bay112 */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		0x08124#define MB_POWER_FLOPPY		0x04125#define MB_POWER_ATA		0x02126#define MB_POWER_PCI		0x01127#define MB_POWER_OFF		0x00128 129/*130 * Functions for polling content of media bay131 */132 133static u8134ohare_mb_content(struct media_bay_info *bay)135{136	return (MB_IN32(bay, OHARE_MBCR) >> 12) & 7;137}138 139static u8140heathrow_mb_content(struct media_bay_info *bay)141{142	return (MB_IN32(bay, HEATHROW_MBCR) >> 12) & 7;143}144 145static u8146keylargo_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 device168 * into reset state as well169 */170 171static void172ohare_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 void191heathrow_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 void210keylargo_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 busses231 */232 233static int234ohare_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 int254heathrow_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 int274keylargo_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 resets294 */295 296static void297ohare_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 thru372		 * "MB_NO", we force a pass by "MB_NO" to make sure373		 * things are properly reset374		 */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		else385			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, sine399	 * we may be called with the bay lock held. The resulting400	 * fuzzyness of the result if called at the wrong time is401	 * not actually a huge deal402	 */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 bay534 * once each tick and register and unregister the IDE interface535 * with the IDE driver.  It needs to be a thread because536 * 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 the571         * mac-io chip, for now, we trick and align down the first572	 * resource passed in573         */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.event620	    && (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 content639	       	   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_LEVEL699 * register is always set when there is something in the media bay.700 * This causes problems for the interrupt code if we attach an interrupt701 * handler to the media-bay interrupt, because it tends to go into702 * 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_resume735};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);754