LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] adb: create class devices for each adb device
From: Aristeu Rozanski @ 2007-07-17  1:30 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <1184628153.25235.111.camel@localhost.localdomain>

Hi Benjamin,
> I don't think class device is the right approach. Classes are supposed
> to be a functional binding, ie, in this case, input devices. ADB is a
> bus, and as such, you should create an adb bus type and and adb_device
> that is an extension of struct device, not struct class device.
ok, I'll work on that.

> There's also the question of what to do on ADB resets (such as when
> doing a sleep/wakeup cycle). Should we wipe out all devices and
> re-created them, thus loosing any settings ? Or should we have some way
> to attempt at re-matching existing ones ?
or maybe generate disconnect/connect events so udev rules can reconfigure
each keyboard?

-- 
Aristeu

^ permalink raw reply

* Re: [PATCH 3/3] 82xx: SBCPQ2 board platform support
From: Arnd Bergmann @ 2007-07-17  1:27 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <469B3401.9030602@windriver.com>

On Monday 16 July 2007, Mark Zhan wrote:
> This patch addes the powerpc support to Wind River SBC PowerQUICCII 82xx board.

Hi Mark!

I've got lots of small comments about your code, but mostly it comes
down to one problem: your new platform code is not able to coexist
with other platforms because you hardcode information.

> +static struct resource m48t59_resources[] = {
> +	{
> +		.start	= SBCPQ2_RTC_BASE,
> +		.end	= SBCPQ2_RTC_BASE + SBCPQ2_RTC_SIZE - 1,
> +		.flags	= IORESOURCE_MEM,
> +	}, {
> +		.start	= SBCPQ2_M48T59_IRQ,
> +		.end	= SBCPQ2_M48T59_IRQ,
> +		.flags	= IORESOURCE_IRQ,
> +	},
> +	{ },
> +};

This is the kind of information that belongs into the device tree,
not hardcoded into the board code.

> +/**
> + * sbcpq2_pdev_init - Register the platform device for sbcpq2 board
> + */
> +static int __init sbcpq2_platdev_init(void)
> +{
> +	struct irq_desc *desc = irq_desc + SBCPQ2_M48T59_IRQ;

same for the interrupt number. Worse, this looks broken
because the descriptor array describes virtual interrupt
numbers, while SBCPQ2_M48T59_IRQ must be a physical number.
These are often the same, but there is no guarantee.

In order to get a virtual interrupt number for a given device,
you need to call irq_of_parse_and_map().

> +	/* Install a dummy irq chip for M48T59 RTC irq */
> +	if (desc->chip == &no_irq_chip)
> +		set_irq_handler(SBCPQ2_M48T59_IRQ, desc->handle_irq);
> +
> +	/* Register all platform devices for sbcpq2 */
> +	platform_add_devices(sbcpq2_devices, ARRAY_SIZE(sbcpq2_devices));
> +	return 0;
> +}
> +arch_initcall(sbcpq2_platdev_init);


> +/*
> + * For SBCPQ2 board, the interrupt of M48T59 RTC chip
> + * will generate a machine check exception. We use a
> + * fake irq to give the platform machine_check_exception() hook
> + * a chance to call the driver ISR. If IRQ_HANDLED is returned,
> + * then we will survive from the machine check exception.
> + */
> +static int sbcpq2_mach_check(struct pt_regs *regs)
> +{
> +	int recover = 0;
> +	struct irq_desc *desc = irq_desc + SBCPQ2_M48T59_IRQ;
> +
> +	struct irqaction *action = desc->action;
> +
> +	while (action && (action->dev_id != &m48t59_rtc))
> +		action = action->next;
> +
> +	/* Try to call m48t59 RTC driver ISR */
> +	if (action && action->handler)
> +		recover = action->handler(SBCPQ2_M48T59_IRQ, &m48t59_rtc);
> +
> +	return recover;
> +}

What you do here looks really scary, but maybe I'm just misunderstanding
it completely. Why don't you just register your rtc handler function
as the machine check handler instead of going through various indirections?

> +static void __init sbcpq2_init_IRQ(void)
> +{
> +	struct device_node *np;
> +	struct resource res;
> +
> +	np = of_find_compatible_node(NULL, "cpm-pic", "CPM2");
> +	if (np == NULL) {
> +		printk(KERN_ERR "PIC init: can not find cpm-pic node\n");
> +		return;
> +	}

This looks like your device tree is wrong. Shouldn't the interrupt
controller have device_type="interrupt-controller" and a specific
compatible property instead of having the name in the device_type?

> +static void __init sbcpq2_setup_arch(void)
> +{
> +	struct device_node *np;
> +	volatile memctl_cpm2_t *mc;

not volatile, but __iomem!

> +	unsigned char * eeprom_base;
> +	int i = 0;
> +
> +#ifdef CONFIG_CPM2
> +	cpm2_reset();
> +#endif
> +
> +	/*
> +	 * Make sure that we have the right CS# setting
> +	 */
> +	mc = &cpm2_immr->im_memctl;
> +
> +	/* Boot Flash is the on-board flash */
> +	mc->memc_br0 = (SBCPQ2_BOOT_FLASH_BASE & 0xFFFF8000) | 0x0801;
> +	mc->memc_or0 = 0xFFE00896;

consequently, this needs to use out_be32 or similar.
Where does SBCPQ2_BOOT_FLASH_BASE come from? Shouldn't that be set
up by the boot loader to match the device tree?

> +		model = (char *)of_get_property(np, "model", NULL);
> +		if (!model)
> +			continue;

The cast is not needed here.
> +
> +		id = of_get_property(np, "device-id", NULL);
> +		if (!id)
> +			continue;
> +
> +		macaddr = (unsigned char *)of_get_mac_address(np);
> +		if (!macaddr)
> +			continue;

or here.

> +		if (strstr(model, "FCC"))
> +			eeprom_ofs = SBCPQ2_FCC1_MACADDR_OFS;
> +		else if (strstr(model, "SCC"))
> +			eeprom_ofs = SBCPQ2_SCC1_MACADDR_OFS;
> +		eeprom_ofs += ((*id) - 1) * 6;

of_device_is_compatible()


> +		for (j = 0; j < 6; j++)
> +			*(macaddr + j) = *(eeprom_base + eeprom_ofs + j);

in_8().

> +	}
> +	iounmap(eeprom_base);
> +}
> +
> +/*
> + * Called very early, device-tree isn't unflattened
> + */
> +static int __init sbcpq2_probe(void)
> +{
> +	/* We always match for now, eventually we should look at
> +	 * the flat dev tree to ensure this is the board we are
> +	 * supposed to run on
> +	 */
> +	return 1;
> +}

Don't write why the code is wrong -- just fix it.

> +/* For our show_cpuinfo hooks. */
> +#define CPUINFO_VENDOR		"Wind River"
> +#define CPUINFO_MACHINE		"SBC PowerQUICCII 82xx"

Not in a header file please.

> +/*
> + * Wind River SBC PowerQUICCII 82xx Physical Memory Map (CS0 for OnBoard Flash)
> + *
> + *   0x00000000 - 0x07FFFFFF	CS2, 128 MB DIMM SDRAM
> + *   0x08000000 - 0x0FFFFFFF	CS3, 128 MB DIMM SDRAM
> + *   0x12000000 - 0x12100000	CS8, ATM
> + *   0x20000000 - 0x20FFFFFF	CS4, 16 MB Local Bus SDRAM
> + *   0x21000000 - 0x21001FFF	CS7, Control EPLD
> + *   0x22000000 - 0x22001FFF	CS5, 8KB EEPROM
> + *   0x22002000 - 0x22003FFF	CS5, visionPORT
> + *   0x22004000 - 0x22005FFF	CS5, User Switches
> + *   0x22006000 - 0x22007FFF	CS5, STATUS
> + *   0x22008000 - 0x22009FFF	CS5, i8259 interrupt controller
> + *   0x2200A000 - 0x2200BFFF	CS5, LED (Seven Segment Display)
> + *   0x80000000 - 0x80001FFF	CS11, RTC
> + *   0xE0000000 - 0xE3FFFFFF	CS6, 64 MB DIMM Flash
> + *   0xE4000000 - 0xE7FFFFFF	CS1, 64 MB DIMM Flash
> + *   0xFE000000 - 0xFFFFFFFF	CS0, 2 MB Boot Flash
> + *   0xF0000000 - 0xF0020000	MPC82xx Internal Registers Space
> + */
> +#define SBCPQ2_SDRAM_BASE		0x00000000
> +#define SBCPQ2_SDRAM_SIZE		0x10000000
> +
> +#define SBCPQ2_LOCAL_SDRAM_BASE		0x20000000
> +#define SBCPQ2_LOCAL_SDRAM_SIZE		0x1000000
> +
> +#define SBCPQ2_EPLD_BASE		0x21000000
> +#define SBCPQ2_EPLD_SIZE		0x2000
> +
> +#define SBCPQ2_EEPROM_BASE		0x22000000
> +#define SBCPQ2_EEPROM_SIZE		0x2000
> +
> +/* User Switches SW5 */
> +#define SBCPQ2_USER_SW_BASE		0x22004000
> +#define SBCPQ2_USER_SW_SIZE		0x2000
> +
> +#define SBCPQ2_STATUS_BASE		0x22006000
> +#define SBCPQ2_STATUS_SIZE		0x2000
> +
> +#define SBCPQ2_I8259_BASE		0x22008000
> +#define SBCPQ2_I8259_SIZE		0x2000
> +
> +/* Seven Segment Display LED D46 */
> +#define SBCPQ2_LED_BASE			0x2200A000
> +#define SBCPQ2_LED_SIZE			0x2000
> +
> +#define SBCPQ2_RTC_BASE			0x80000000
> +#define SBCPQ2_RTC_SIZE			0x2000
> +
> +#define SBCPQ2_BOOT_FLASH_BASE		0xFE000000
> +#define SBCPQ2_BOOT_FLASH_SIZE		0x00200000
> +
> +#define SBCPQ2_DIMM_FLASH_BASE		0xE0000000
> +#define SBCPQ2_DIMM_FLASH_SIZE		0x04000000
> +
> +#define CPM_MAP_ADDR			0xF0000000
> +#define CPM_IRQ_OFFSET			0

All this is in the device tree already, so don't duplicate it here.

> +/*
> + * The offset of ethernet MAC addr within EEPROM
> + */
> +#define SBCPQ2_FCC1_MACADDR_OFS		0x60
> +#define SBCPQ2_FCC2_MACADDR_OFS		0x66
> +#define SBCPQ2_FCC3_MACADDR_OFS		0x72
> +#define SBCPQ2_SCC1_MACADDR_OFS		0x78

Likewise, the mac address is in the device tree, so no need
to tell the kernel how to read it.

> +/*
> + * The following IRQs are routed to i8259 PIC.
> + *
> + * NOTE: i8259 PIC is cascaded to SIU_INT_IRQ6 of CPM2 interrupt controller
> + */
> +#define SBCPQ2_PC_IRQA		(NR_SIU_INTS+0)
> +#define SBCPQ2_PC_IRQB		(NR_SIU_INTS+1)
> +#define SBCPQ2_MPC185_IRQ	(NR_SIU_INTS+2)
> +#define SBCPQ2_ATM_IRQ		(NR_SIU_INTS+3)
> +#define SBCPQ2_PIRQA		(NR_SIU_INTS+4)
> +#define SBCPQ2_PIRQB		(NR_SIU_INTS+5)
> +#define SBCPQ2_PIRQC		(NR_SIU_INTS+6)
> +#define SBCPQ2_PIRQD		(NR_SIU_INTS+7)

Again, these are in the device tree, so don't put them here.

> +/* cpm serial driver works with constants below */
> +#define SIU_INT_SMC1		((uint)0x04+CPM_IRQ_OFFSET)
> +#define SIU_INT_SMC2		((uint)0x05+CPM_IRQ_OFFSET)
> +#define SIU_INT_SCC1		((uint)0x28+CPM_IRQ_OFFSET)
> +#define SIU_INT_SCC2		((uint)0x29+CPM_IRQ_OFFSET)
> +#define SIU_INT_SCC3		((uint)0x2a+CPM_IRQ_OFFSET)
> +#define SIU_INT_SCC4		((uint)0x2b+CPM_IRQ_OFFSET)

What are these for? If you need them in the device driver, just put
them in there, not in a header file. Also, you should make
sure not to pollute the global name space, so they should
be named SBCPQ2_SIU_INT_* to make it clear that they are board
specific.

> +#ifdef CONFIG_SBCPQ2
> +#include <platforms/82xx/sbcpq2.h>
> +#endif

Never put #ifdef around an #include.

> +
>   #ifdef CONFIG_PCI_8260
>   #include <platforms/82xx/m82xx_pci.h>
>   #endif

Kill this #ifdef as well while you're there. If you get name space
conflicts, just rename the symbols to make them unique.

> +/ {
> +	model = "SBCPQ2";
> +	compatible = "mpc82xx";
> +	#address-cells = <1>;
> +	#size-cells = <1>;
> +	linux,phandle = <100>;

Don't put explicit phandles here. If you need a reference, do it
symbolically.

	Arnd <><

^ permalink raw reply

* [PATCH 3/4] phy: Fix Vitesse RGMII-ID support
From: Andy Fleming @ 2007-07-17  1:27 UTC (permalink / raw)
  To: jgarzik, paulus, galak; +Cc: netdev, linuxppc-dev
In-Reply-To: <11846356233423-git-send-email-afleming@freescale.com>

The Vitesse PHY on the 8641D needs to be set up with internal delay to
work in RGMII mode.  So we add skew when it is set to RGMII_ID mode.

Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Haruki Dai <Dai.Haruki@freescale.com>
Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
---
 drivers/net/phy/vitesse.c |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index f39ab76..6a53856 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -21,6 +21,10 @@
 /* Vitesse Extended Control Register 1 */
 #define MII_VSC8244_EXT_CON1           0x17
 #define MII_VSC8244_EXTCON1_INIT       0x0000
+#define MII_VSC8244_EXTCON1_TX_SKEW_MASK	0x0c00
+#define MII_VSC8244_EXTCON1_RX_SKEW_MASK	0x0300
+#define MII_VSC8244_EXTCON1_TX_SKEW	0x0800
+#define MII_VSC8244_EXTCON1_RX_SKEW	0x0200
 
 /* Vitesse Interrupt Mask Register */
 #define MII_VSC8244_IMASK		0x19
@@ -39,7 +43,7 @@
 
 /* Vitesse Auxiliary Control/Status Register */
 #define MII_VSC8244_AUX_CONSTAT        	0x1c
-#define MII_VSC8244_AUXCONSTAT_INIT    	0x0004
+#define MII_VSC8244_AUXCONSTAT_INIT    	0x0000
 #define MII_VSC8244_AUXCONSTAT_DUPLEX  	0x0020
 #define MII_VSC8244_AUXCONSTAT_SPEED   	0x0018
 #define MII_VSC8244_AUXCONSTAT_GBIT    	0x0010
@@ -51,6 +55,7 @@ MODULE_LICENSE("GPL");
 
 static int vsc824x_config_init(struct phy_device *phydev)
 {
+	int extcon;
 	int err;
 
 	err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT,
@@ -58,8 +63,20 @@ static int vsc824x_config_init(struct phy_device *phydev)
 	if (err < 0)
 		return err;
 
-	err = phy_write(phydev, MII_VSC8244_EXT_CON1,
-			MII_VSC8244_EXTCON1_INIT);
+	extcon = phy_read(phydev, MII_VSC8244_EXT_CON1);
+
+	if (extcon < 0)
+		return err;
+
+	extcon &= ~(MII_VSC8244_EXTCON1_TX_SKEW_MASK |
+			MII_VSC8244_EXTCON1_RX_SKEW_MASK);
+
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+		extcon |= (MII_VSC8244_EXTCON1_TX_SKEW |
+				MII_VSC8244_EXTCON1_RX_SKEW);
+
+	err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon);
+
 	return err;
 }
 
-- 
1.5.0.2.230.gfbe3d-dirty

^ permalink raw reply related

* [PATCH 2/4] gianfar: Add phy-connection-type to gianfar nodes
From: Andy Fleming @ 2007-07-17  1:26 UTC (permalink / raw)
  To: jgarzik, paulus, galak; +Cc: netdev, linuxppc-dev
In-Reply-To: <1184635622653-git-send-email-afleming@freescale.com>

The TSEC/eTSEC automatically detect their PHY interface type, unless
the type is RGMII-ID (RGMII with internal delay).  In that situation,
it just detects RGMII.  In order to fix this, we need to pass in rgmii-id
if that is the connection type.

Signed-off-by: Andy Fleming <afleming@freescale.com>
---
 Documentation/powerpc/booting-without-of.txt |    6 ++++++
 arch/powerpc/boot/dts/mpc8641_hpcn.dts       |    4 ++++
 2 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index d42d981..a41b6b1 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1241,6 +1241,12 @@ platforms are moved over to use the flattened-device-tree model.
       network device.  This is used by the bootwrapper to interpret
       MAC addresses passed by the firmware when no information other
       than indices is available to associate an address with a device.
+    - phy-connection-type : a string naming the controller/PHY interface type,
+      i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii",
+      "tbi", or "rtbi".  This property is only really needed if the connection
+      is of type "rgmii-id", as all other connection types are detected by
+      hardware.
+
 
   Example:
 
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index 260b264..9849073 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -121,6 +121,7 @@
 			interrupts = <1d 2 1e 2 22 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
+			phy-connection-type = "rgmii-id";
 		};
 
 		ethernet@25000 {
@@ -134,6 +135,7 @@
 			interrupts = <23 2 24 2 28 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
 		};
 		
 		ethernet@26000 {
@@ -147,6 +149,7 @@
 			interrupts = <1F 2 20 2 21 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy2>;
+			phy-connection-type = "rgmii-id";
 		};
 
 		ethernet@27000 {
@@ -160,6 +163,7 @@
 			interrupts = <25 2 26 2 27 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy3>;
+			phy-connection-type = "rgmii-id";
 		};
 		serial@4500 {
 			device_type = "serial";
-- 
1.5.0.2.230.gfbe3d-dirty

^ permalink raw reply related

* [PATCH 4/4] gianfar: Fix RGMII-ID handling in gianfar
From: Andy Fleming @ 2007-07-17  1:27 UTC (permalink / raw)
  To: jgarzik, paulus, galak; +Cc: netdev, linuxppc-dev
In-Reply-To: <11846356241295-git-send-email-afleming@freescale.com>

The TSEC/eTSEC can detect the interface to the PHY automatically,
but it isn't able to detect whether the RGMII connection needs internal
delay.  So we need to detect that change in the device tree, propagate
it to the platform data, and then check it if we're in RGMII.  This fixes
a bug on the 8641D HPCN board where the Vitesse PHY doesn't use the delay
for RGMII.

Signed-off-by: Andy Fleming <afleming@freescale.com>
---
 arch/powerpc/sysdev/fsl_soc.c |    9 +++++++++
 drivers/net/gianfar.c         |   12 +++++++++++-
 include/linux/fsl_devices.h   |    1 +
 3 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index cad1757..64efee6 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -197,6 +197,7 @@ static int __init gfar_of_init(void)
 		struct gianfar_platform_data gfar_data;
 		const unsigned int *id;
 		const char *model;
+		const char *ctype;
 		const void *mac_addr;
 		const phandle *ph;
 		int n_res = 2;
@@ -254,6 +255,14 @@ static int __init gfar_of_init(void)
 			    FSL_GIANFAR_DEV_HAS_VLAN |
 			    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
 
+		ctype = of_get_property(np, "phy-connection-type", NULL);
+
+		/* We only care about rgmii-id.  The rest are autodetected */
+		if (ctype && !strcmp(ctype, "rgmii-id"))
+			gfar_data.interface = PHY_INTERFACE_MODE_RGMII_ID;
+		else
+			gfar_data.interface = PHY_INTERFACE_MODE_MII;
+
 		ph = of_get_property(np, "phy-handle", NULL);
 		phy = of_find_node_by_phandle(*ph);
 
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index d7a1a58..f926905 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -420,8 +420,18 @@ static phy_interface_t gfar_get_interface(struct net_device *dev)
 	if (ecntrl & ECNTRL_REDUCED_MODE) {
 		if (ecntrl & ECNTRL_REDUCED_MII_MODE)
 			return PHY_INTERFACE_MODE_RMII;
-		else
+		else {
+			phy_interface_t interface = priv->einfo->interface;
+
+			/*
+			 * This isn't autodetected right now, so it must
+			 * be set by the device tree or platform code.
+			 */
+			if (interface == PHY_INTERFACE_MODE_RGMII_ID)
+				return PHY_INTERFACE_MODE_RGMII_ID;
+
 			return PHY_INTERFACE_MODE_RGMII;
+		}
 	}
 
 	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT)
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 73710d6..2de358f 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -53,6 +53,7 @@ struct gianfar_platform_data {
 	u32	bus_id;
 	u32	phy_id;
 	u8	mac_addr[6];
+	phy_interface_t interface;
 };
 
 struct gianfar_mdio_data {
-- 
1.5.0.2.230.gfbe3d-dirty

^ permalink raw reply related

* [PATCH 1/4] phy: Fix Vitesse 824x PHY interrupt acking
From: Andy Fleming @ 2007-07-17  1:26 UTC (permalink / raw)
  To: jgarzik, paulus, galak; +Cc: netdev, linuxppc-dev
In-Reply-To: <1184635621688-git-send-email-afleming@freescale.com>

The Vitesse 824x PHY doesn't allow an interrupt to be cleared if
the mask bit for that interrupt isn't set.  This means that the PHY
Lib's order of handling interrupts (disable, then clear) breaks on this
PHY.  However, clearing then disabling the interrupt opens up the code
for a silly race condition.  So rather than change the PHY Lib, we change
the Vitesse driver so it always clears interrupts before disabling them.
Further, the ack function only clears the interrupt if interrupts are
enabled.

Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: York Sun <yorksun@freescale.com>
Acked-by: Haiying Wang <Haiying.Wang@freescale.com>
---
 drivers/net/phy/vitesse.c |   23 +++++++++++++++++++++--
 1 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 596222b..f39ab76 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -65,7 +65,15 @@ static int vsc824x_config_init(struct phy_device *phydev)
 
 static int vsc824x_ack_interrupt(struct phy_device *phydev)
 {
-	int err = phy_read(phydev, MII_VSC8244_ISTAT);
+	int err = 0;
+	
+	/*
+	 * Don't bother to ACK the interrupts if interrupts
+	 * are disabled.  The 824x cannot clear the interrupts
+	 * if they are disabled.
+	 */
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+		err = phy_read(phydev, MII_VSC8244_ISTAT);
 
 	return (err < 0) ? err : 0;
 }
@@ -77,8 +85,19 @@ static int vsc824x_config_intr(struct phy_device *phydev)
 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 		err = phy_write(phydev, MII_VSC8244_IMASK,
 				MII_VSC8244_IMASK_MASK);
-	else
+	else {
+		/*
+		 * The Vitesse PHY cannot clear the interrupt
+		 * once it has disabled them, so we clear them first
+		 */
+		err = phy_read(phydev, MII_VSC8244_ISTAT);
+
+		if (err)
+			return err;
+
 		err = phy_write(phydev, MII_VSC8244_IMASK, 0);
+	}
+
 	return err;
 }
 
-- 
1.5.0.2.230.gfbe3d-dirty

^ permalink raw reply related

* [PATCH 2.6.22-rc7 0/4] phy/gianfar: Fixes for gianfar and vitesse RGMII-ID support
From: Andy Fleming @ 2007-07-17  1:26 UTC (permalink / raw)
  To: jgarzik, paulus, galak; +Cc: netdev, linuxppc-dev

A few bugs in the Vitesse PHY driver were found on the 8641D HPCN board.
Originally, they were masked by a bug in the PHY Lib which was fixed by patch 
5f708dd91d15876e26d7a57f97a255cedffca463 (Fix phy_id for Vitesse 824x PHY).
That patch allowed the Vitesse PHY to bind on the 8641D HPCN board, thereby
exposing a bug in the interrupt handling and a bug in the configuration of
the PHY.  This sequence of patches fixes the irq handling bug, then fixes 
the configuration bug in 3 places:

1) The Vitesse PHY driver
2) The gianfar driver (needs to pass in the mode correctly for internal delay)
3) The OF device tree for arch/powerpc boards

You can apply the following patches, or pull them directly:

The following changes since commit c5e3ae8823693b260ce1f217adca8add1bc0b3de:
  Ayaz Abdulla (1):
        forcedeth bug fix: realtek phy

are found in the git repository at:

  http://opensource.freescale.com/pub/scm/linux-2.6-85xx.git netdev

Andy Fleming (4):
      Fix Vitesse 824x PHY interrupt acking
      Add phy-connection-type to gianfar nodes
      Fix Vitesse RGMII-ID support
      Fix RGMII-ID handling in gianfar

 Documentation/powerpc/booting-without-of.txt |    6 +++
 arch/powerpc/boot/dts/mpc8641_hpcn.dts       |    4 ++
 arch/powerpc/sysdev/fsl_soc.c                |    9 +++++
 drivers/net/gianfar.c                        |   12 ++++++-
 drivers/net/phy/vitesse.c                    |   46 +++++++++++++++++++++++---
 include/linux/fsl_devices.h                  |    1 +
 6 files changed, 72 insertions(+), 6 deletions(-)

^ permalink raw reply

* [PATCH] POWERPC 8xx: bump up initial memory limit for 8xx
From: Vitaly Bordug @ 2007-07-17  1:17 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev


From: John Traill <john.traill@freescale.com>

The 8xx can only support a max of 8M during early boot ( it seems a lot of
8xx boards only have 8M so the bug was never triggered ). The following
change makes it able to run with 128M.

Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>

---

 arch/powerpc/mm/init_32.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index e1f5ded..7cee86d 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -133,6 +133,9 @@ void __init MMU_init(void)
 	/* 601 can only access 16MB at the moment */
 	if (PVR_VER(mfspr(SPRN_PVR)) == 1)
 		__initial_memory_limit = 0x01000000;
+	/* 852 can only access 8MB at the moment */
+	if (PVR_VER(mfspr(SPRN_PVR)) == 0x50)
+		__initial_memory_limit = 0x00800000;
 
 	/* parse args from command line */
 	MMU_setup();

^ permalink raw reply related

* Re: [PATCH 2/3] 82xx: Parse SMC serial device node in DTS
From: Arnd Bergmann @ 2007-07-17  1:02 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <469B33F9.2080604@windriver.com>

T24gTW9uZGF5IDE2IEp1bHkgMjAwNywgTWFyayBaaGFuIHdyb3RlOgo+IC2goKCgoKCgoKCgoKCg
oKBjcG1fdWFydF9kYXRhLnVhcnRfY2xrID0gcHBjX3Byb2NfZnJlcTsKPiAroKCgoKCgoKCgoKCg
oKCgaWYgKHN0cnN0cihtb2RlbCwgIlNNQyIpKSB7Cj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
Y3BtX3VhcnRfZGV2ID0gcGxhdGZvcm1fZGV2aWNlX3JlZ2lzdGVyX3NpbXBsZSgiZnNsLWNwbS1z
bWM6dWFydCIsCj4gK6CgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
oKCgoKCgoKCgoKBpLCAmclswXSwgMyk7Cj4gK6CgoKCgoKCgoKCgoKCgoH0gZWxzZSBpZiAoc3Ry
c3RyKG1vZGVsLCAiU0NDIikpIHsKPiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKBjcG1fdWFydF9k
ZXYgPSBwbGF0Zm9ybV9kZXZpY2VfcmVnaXN0ZXJfc2ltcGxlKCJmc2wtY3BtLXNjYzp1YXJ0IiwK
PiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
oGksICZyWzBdLCAzKTsKPiAroKCgoKCgoKCgoKCgoKCgfQo+IAoKWW91IHNob3VsZCBwcm9iYWJs
eSB1c2Ugb2ZfZGV2aWNlX2lzX2NvbXBhdGlibGUoKSB0byBjaGVjawppZiBhIGdpdmVuIGRldmlj
ZSBjYW4gYmUgdXNlZCBieSBhIHBhcnRpY3VsYXIgZHJpdmVyLgoKCUFybmQgPD48Cg==

^ permalink raw reply

* Re: [PATCH 1/3] 82xx: some 82xx platform hook functions can be shared by different boards
From: Arnd Bergmann @ 2007-07-17  0:59 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: paulus
In-Reply-To: <469B33F2.9040306@windriver.com>

On Monday 16 July 2007, Mark Zhan wrote:

> @@ -96,7 +94,7 @@
>   	pvid = mfspr(SPRN_PVR);
>   	svid = mfspr(SPRN_SVR);
> 
> -	seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n");
> +	seq_printf(m, "Vendor\t\t: %s\n", CPUINFO_VENDOR);
>   	seq_printf(m, "Machine\t\t: %s\n", CPUINFO_MACHINE);
>   	seq_printf(m, "PVR\t\t: 0x%x\n", pvid);
>   	seq_printf(m, "SVR\t\t: 0x%x\n", svid);

This is a step in the wrong direction. CPUINFO_{VENDOR,MACHINE}
comes from a platform specific header file, so you can not
use these definitions in platform independent code without
breaking multiplatform kernels.

One possible solution would be a platform specific show_cpuinfo()
function that calls a generic 82xx version and passes in the
two values. Even better would be to just dump whatever string
you find in the /model property in the device tree.

> +
> +#define RMR_CSRE 0x00000001
> +
> +void mpc82xx_restart(char *cmd)
> +{
> +	__volatile__ unsigned char dummy;
> +
> +	local_irq_disable();
> +	((cpm2_map_t *) cpm2_immr)->im_clkrst.car_rmr |= RMR_CSRE;
> +
> +	/* Clear the ME,EE,IR & DR bits in MSR to cause checkstop */
> +	mtmsr(mfmsr() & ~(MSR_ME | MSR_EE | MSR_IR | MSR_DR));
> +	dummy = ((cpm2_map_t *) cpm2_immr)->im_clkrst.res[0];
> +	printk("Restart failed\n");
> +	while (1) ;
> +}

I know you're just moving that code, but it looks horribly wrong
nonetheless. cpm2_immr is an __iomem variable, so you must not
dereference it but instead should use the in_8() macro to
access it.

Once you get that right, you don't need the volatile variable
any more.

> +void mpc82xx_halt(void)
> +{
> +	local_irq_disable();
> +	while (1) ;
> +}

Here, as in the function above, there should at least be a cpu_relax()
in the final loop. If the CPU has a nap functionality or something
similar, that would be even better.

	Arnd <><

^ permalink raw reply

* [PATCH] USB_DR device support for FSL MPC831x
From: Vitaly Bordug @ 2007-07-17  0:58 UTC (permalink / raw)
  To: Greg KH; +Cc: linuxppc-dev


This adds support for USB device mode on mpc831x series. 
Devicetree node modification is required to make it work - 

dr_mode ="peripheral";

which should be commented out if host mode is desired onboot.

Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>

---

 arch/powerpc/sysdev/fsl_soc.c |    1 +
 include/linux/fsl_devices.h   |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index c0ddc80..27a1510 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -514,6 +514,7 @@ static int __init fsl_usb_of_init(void)
 			}
 		} else if (prop && !strcmp(prop, "peripheral")) {
 			usb_data.operating_mode = FSL_USB2_DR_DEVICE;
+			usb_data.max_ep_nr = *(unsigned int*)of_get_property(np, "max_ep_nr",NULL);
 			usb_dev_dr_client = platform_device_register_simple(
 					"fsl-usb2-udc", i, r, 2);
 			if (IS_ERR(usb_dev_dr_client)) {
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 12e631f..a3feb34 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -103,6 +103,7 @@ struct fsl_usb2_platform_data {
 	enum fsl_usb2_operating_modes	operating_mode;
 	enum fsl_usb2_phy_modes		phy_mode;
 	unsigned int			port_enables;
+	unsigned int			max_ep_nr;
 };
 
 /* Flags in fsl_usb2_mph_platform_data */

^ permalink raw reply related

* [PATCH] USB_DR host support for FSL MPC831x
From: Vitaly Bordug @ 2007-07-17  0:58 UTC (permalink / raw)
  To: Greg KH; +Cc: linuxppc-dev


Modifies fsl_ehci code so that to get USB host working on
mpc831x platform. Verified with MPC8313RDB reference board.

Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>

---

 arch/powerpc/boot/dts/mpc8313erdb.dts |    1 +
 drivers/usb/host/ehci-fsl.c           |    4 +++-
 drivers/usb/host/ehci-hcd.c           |    2 +-
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index 1b351dc..c330e79 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -90,6 +90,7 @@
 			interrupt-parent = < &ipic >;
 			interrupts = <26 8>;
 			phy_type = "utmi_wide";
+			control_init  = <00000280>; // UTMI ext 48 MHz clk
 		};
 
 		mdio@24520 {
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index c7a7c59..3e3187b 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -185,12 +185,14 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd)
 	struct ehci_hcd *ehci = hcd_to_ehci(hcd);
 	struct fsl_usb2_platform_data *pdata;
 	void __iomem *non_ehci = hcd->regs;
+	u32 temp;
 
 	pdata =
 	    (struct fsl_usb2_platform_data *)hcd->self.controller->
 	    platform_data;
 	/* Enable PHY interface in the control reg. */
-	out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004);
+	temp = in_be32(non_ehci + FSL_SOC_USB_CTRL);
+	out_be32(non_ehci + FSL_SOC_USB_CTRL, temp | 0x00000004);
 	out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
 
 #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 099aff6..994a127 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -925,7 +925,7 @@ MODULE_LICENSE ("GPL");
 #define	PCI_DRIVER		ehci_pci_driver
 #endif
 
-#ifdef CONFIG_MPC834x
+#if defined(CONFIG_MPC834x) || defined(CONFIG_PPC_MPC831x)
 #include "ehci-fsl.c"
 #define	PLATFORM_DRIVER		ehci_fsl_driver
 #endif

^ permalink raw reply related

* [PATCH] POWERPC: add support of the GiGE switch for mpc8313RDB via fixed PHY
From: Vitaly Bordug @ 2007-07-17  0:49 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev


This utilises pretend phy, making access to it via device tree. GiGE switch
is connected to TSEC1 with fixed gigE link, so we need to emulate it
via artificial PHY to make it work.

Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>

---

 arch/powerpc/boot/dts/mpc8313erdb.dts     |    1 +
 arch/powerpc/platforms/83xx/mpc8313_rdb.c |   43 +++++++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index a1533cc..1b351dc 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -100,6 +100,7 @@
 			#size-cells = <0>;
 			phy1: ethernet-phy@1 {
 				interrupt-parent = < &ipic >;
+				compatible = "fixed";
 				interrupts = <13 8>;
 				reg = <1>;
 				device_type = "ethernet-phy";
diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
index b410e67..5ee08fc 100644
--- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
@@ -115,6 +115,49 @@ static int __init rtc_hookup(void)
 late_initcall(rtc_hookup);
 #endif
 
+#if defined(CONFIG_FIXED_MII_1000_FDX)
+
+static int fixed_set_link (void)
+{
+	struct fixed_info *phyinfo = fixed_mdio_get_phydev(0);	/* only one fixed phy on this platform */
+	struct phy_device *phydev;
+	struct device_node *np;
+	struct device_node *child;
+	unsigned int i;
+	struct resource res;
+	int ret;
+	u32 *id = NULL;
+
+	if (!phyinfo)
+		return -ENXIO;
+	phydev = phyinfo->phydev;
+	if (!phydev)
+		return -ENXIO;
+	for (np = NULL, i = 0;
+	     (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL;
+	     i++) {
+
+		memset(&res, 0, sizeof(res));
+
+		ret = of_address_to_resource(np, 0, &res);
+		if (ret)
+			return ret;
+		child = of_find_compatible_node(np, "ethernet-phy","fixed");
+		if (!child)
+			return -ENXIO;
+		id = (u32*)of_get_property(child, "reg", NULL);
+		if (!id)
+			return -ENXIO;
+		break;
+	}
+	snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT,  res.start, *id);
+	memset(phyinfo->regs,0xff,sizeof(phyinfo->regs[0])*phyinfo->regs_num);
+
+	return 0;
+}
+late_initcall(fixed_set_link);
+#endif
+
 /*
  * Called very early, MMU is off, device-tree isn't unflattened
  */

^ permalink raw reply related

* [PATCH] POWERPC: Added RTC support for mpc8313RDB and utilize "clock-frequency"
From: Vitaly Bordug @ 2007-07-17  0:49 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev


This enables DS1337 embedded RTC and uses "clock-frequency"
property to configure loops_per_jiffy. Fixed spaces vs tabs issue
in couple of places.

Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>

---

 arch/powerpc/platforms/83xx/mpc8313_rdb.c |   52 ++++++++++++++++++++++++++++-
 1 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
index 3edfe17..b410e67 100644
--- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
@@ -14,6 +14,8 @@
  */
 
 #include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/rtc.h>
 
 #include <asm/time.h>
 #include <asm/ipic.h>
@@ -42,6 +44,17 @@ static void __init mpc8313_rdb_setup_arch(void)
 	if (ppc_md.progress)
 		ppc_md.progress("mpc8313_rdb_setup_arch()", 0);
 
+	np = of_find_node_by_type(NULL, "cpu");
+	if (np != 0) {
+		const unsigned int *fp =
+			get_property(np, "clock-frequency", NULL);
+		if (fp != 0)
+			loops_per_jiffy = *fp / HZ;
+		else
+			loops_per_jiffy = 50000000 / HZ;
+		of_node_put(np);
+	}
+
 #ifdef CONFIG_PCI
 	for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
 		mpc83xx_add_bridge(np);
@@ -67,14 +80,49 @@ void __init mpc8313_rdb_init_IRQ(void)
 	ipic_set_default_priority();
 }
 
+#if defined (CONFIG_SENSORS_DS1337) && defined (CONFIG_I2C)
+
+extern int ds1337_do_command(int id, int cmd, void *arg);
+extern spinlock_t rtc_lock;
+#define DS1337_GET_DATE		0
+#define DS1337_SET_DATE		1
+
+static void mpc8313rdb_get_rtc_time(struct rtc_time *tm)
+{
+	int result;
+
+	result = ds1337_do_command(0, DS1337_GET_DATE, tm);
+
+	if (result == 0)
+		result = mktime(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
+}
+
+static int mpc8313rdb_set_rtc_time(struct rtc_time *tm)
+{
+	int result;
+
+	result = ds1337_do_command(0, DS1337_SET_DATE, tm);
+
+	return result;
+}
+
+static int __init rtc_hookup(void)
+{
+	ppc_md.get_rtc_time = mpc8313rdb_get_rtc_time;
+	ppc_md.set_rtc_time = mpc8313rdb_set_rtc_time;
+	return 0;
+}
+late_initcall(rtc_hookup);
+#endif
+
 /*
  * Called very early, MMU is off, device-tree isn't unflattened
  */
 static int __init mpc8313_rdb_probe(void)
 {
-        unsigned long root = of_get_flat_dt_root();
+	unsigned long root = of_get_flat_dt_root();
 
-        return of_flat_dt_is_compatible(root, "MPC8313ERDB");
+	return of_flat_dt_is_compatible(root, "MPC8313ERDB");
 }
 
 define_machine(mpc8313_rdb) {

^ permalink raw reply related

* Re: [PATCH 0/3] 82xx: Add the support for Wind River SBC PowerQUICCII
From: Vitaly Bordug @ 2007-07-17  0:44 UTC (permalink / raw)
  To: Mark Zhan; +Cc: linuxppc-dev, paulus
In-Reply-To: <469B33E8.8010105@windriver.com>

On Mon, 16 Jul 2007 17:01:28 +0800
Mark Zhan wrote:

> These 3 patches add the powerpc support of Wind River SBC
> PowerQUICCII.
> 
I am sorry, but this would intercept with big 8xx/82xx series from 
Scott Wood I am reviewing now. it makes the initial merged code
more maintainable and powerpc-friendly, but would have some rework
required in upcoming patches for new BSPs.

OTOH, it would make all the changes below very short and apparent.
Of course, if something would block those series this one can be considered to merge.


> 1) Currently, some mpc82xx platform hooks in mpc82xx_ads.c are
> actually not specific to ads board. So the 1st patch makes them be
> shared by different 82xx boards.
> 
> 2) The 2nd patch make 'cpm_uart_of_init' be able to parse SMC uart in
> DTS
> 
> 3) The 3rd patch is the platform codes, defconfig and dts for Wind
> River SBC PowerQUICCII 82xx board.
> 
> Any comment is welcome.
> 
> Thanks
> Mark Zhan
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev


-- 
Sincerely, Vitaly

^ permalink raw reply

* [PATCH] PHY fixed driver: rework release path and update phy_id notation
From: Vitaly Bordug @ 2007-07-17  0:07 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linuxppc-dev, linux-kernel, netdev


device_bind_driver() error code returning has been fixed.  
release() function has been written, so that to free resources 
in correct way; the release path is now clean. 
 
Before the rework, it used to cause 
 Device 'fixed@100:1' does not have a release() function, it is broken 
 and must be fixed. 
 BUG: at drivers/base/core.c:104 device_release() 
  
 Call Trace:   
  [<ffffffff802ec380>] kobject_cleanup+0x53/0x7e 
  [<ffffffff802ec3ab>] kobject_release+0x0/0x9 
  [<ffffffff802ecf3f>] kref_put+0x74/0x81 
  [<ffffffff8035493b>] fixed_mdio_register_device+0x230/0x265 
  [<ffffffff80564d31>] fixed_init+0x1f/0x35 
  [<ffffffff802071a4>] init+0x147/0x2fb 
  [<ffffffff80223b6e>] schedule_tail+0x36/0x92 
  [<ffffffff8020a678>] child_rip+0xa/0x12 
  [<ffffffff80311714>] acpi_ds_init_one_object+0x0/0x83 
  [<ffffffff8020705d>] init+0x0/0x2fb 
  [<ffffffff8020a66e>] child_rip+0x0/0x12   
 
 
Also changed the notation of the fixed phy definition on 
mdio bus to the form of <speed>+<duplex> to make it able to be used by 
gianfar and ucc_geth that define phy_id strictly as "%d:%d" and cleaned up 
the whitespace issues.
 
Signed-off-by: Vitaly Bordug <vitb@kernel.crashing.org>

---

 drivers/net/phy/Kconfig |   14 ++
 drivers/net/phy/fixed.c |  310 ++++++++++++++++++++++++-----------------------
 2 files changed, 169 insertions(+), 155 deletions(-)

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index dd09011..432c210 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -76,4 +76,18 @@ config FIXED_MII_100_FDX
 	bool "Emulation for 100M Fdx fixed PHY behavior"
 	depends on FIXED_PHY
 
+config FIXED_MII_1000_FDX
+	bool "Emulation for 1000M Fdx fixed PHY behavior"
+	depends on FIXED_PHY
+
+config FIXED_MII_AMNT
+        int "Number of emulated PHYs to allocate "
+        depends on FIXED_PHY
+        default "1"
+        ---help---
+        Sometimes it is required to have several independent emulated
+        PHYs on the bus (in case of multi-eth but phy-less HW for instance).
+        This control will have specified number allocated for each fixed
+        PHY type enabled.
+
 endif # PHYLIB
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index bb96691..5619182 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -30,53 +30,31 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
+#include <linux/phy_fixed.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-#define MII_REGS_NUM	7
-
-/*
-    The idea is to emulate normal phy behavior by responding with
-    pre-defined values to mii BMCR read, so that read_status hook could
-    take all the needed info.
-*/
-
-struct fixed_phy_status {
-	u8 	link;
-	u16	speed;
-	u8 	duplex;
-};
-
-/*-----------------------------------------------------------------------------
- *  Private information hoder for mii_bus
- *-----------------------------------------------------------------------------*/
-struct fixed_info {
-	u16 *regs;
-	u8 regs_num;
-	struct fixed_phy_status phy_status;
-	struct phy_device *phydev; /* pointer to the container */
-	/* link & speed cb */
-	int(*link_update)(struct net_device*, struct fixed_phy_status*);
-
-};
+/* we need to track the allocated pointers in order to free them on exit */
+static struct fixed_info *fixed_phy_ptrs[CONFIG_FIXED_MII_AMNT*MAX_PHY_AMNT];
 
 /*-----------------------------------------------------------------------------
  *  If something weird is required to be done with link/speed,
  * network driver is able to assign a function to implement this.
  * May be useful for PHY's that need to be software-driven.
  *-----------------------------------------------------------------------------*/
-int fixed_mdio_set_link_update(struct phy_device* phydev,
-		int(*link_update)(struct net_device*, struct fixed_phy_status*))
+int fixed_mdio_set_link_update(struct phy_device *phydev,
+			       int (*link_update) (struct net_device *,
+						   struct fixed_phy_status *))
 {
 	struct fixed_info *fixed;
 
-	if(link_update == NULL)
+	if (link_update == NULL)
 		return -EINVAL;
 
-	if(phydev) {
-		if(phydev->bus)	{
+	if (phydev) {
+		if (phydev->bus) {
 			fixed = phydev->bus->priv;
 			fixed->link_update = link_update;
 			return 0;
@@ -84,54 +62,64 @@ int fixed_mdio_set_link_update(struct phy_device* phydev,
 	}
 	return -EINVAL;
 }
+
 EXPORT_SYMBOL(fixed_mdio_set_link_update);
 
+struct fixed_info *fixed_mdio_get_phydev (int phydev_ind)
+{
+	if (phydev_ind >= MAX_PHY_AMNT)
+		return NULL;
+	return fixed_phy_ptrs[phydev_ind];
+}
+
+EXPORT_SYMBOL(fixed_mdio_get_phydev);
+
 /*-----------------------------------------------------------------------------
  *  This is used for updating internal mii regs from the status
  *-----------------------------------------------------------------------------*/
-#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX)
 static int fixed_mdio_update_regs(struct fixed_info *fixed)
 {
 	u16 *regs = fixed->regs;
 	u16 bmsr = 0;
 	u16 bmcr = 0;
 
-	if(!regs) {
+	if (!regs) {
 		printk(KERN_ERR "%s: regs not set up", __FUNCTION__);
 		return -EINVAL;
 	}
 
-	if(fixed->phy_status.link)
+	if (fixed->phy_status.link)
 		bmsr |= BMSR_LSTATUS;
 
-	if(fixed->phy_status.duplex) {
+	if (fixed->phy_status.duplex) {
 		bmcr |= BMCR_FULLDPLX;
 
-		switch ( fixed->phy_status.speed ) {
+		switch (fixed->phy_status.speed) {
 		case 100:
 			bmsr |= BMSR_100FULL;
 			bmcr |= BMCR_SPEED100;
-		break;
+			break;
 
 		case 10:
 			bmsr |= BMSR_10FULL;
-		break;
+			break;
 		}
 	} else {
-		switch ( fixed->phy_status.speed ) {
+		switch (fixed->phy_status.speed) {
 		case 100:
 			bmsr |= BMSR_100HALF;
 			bmcr |= BMCR_SPEED100;
-		break;
+			break;
 
 		case 10:
 			bmsr |= BMSR_100HALF;
-		break;
+			break;
 		}
 	}
 
-	regs[MII_BMCR] =  bmcr;
-	regs[MII_BMSR] =  bmsr | 0x800; /*we are always capable of 10 hdx*/
+	regs[MII_BMCR] = bmcr;
+	regs[MII_BMSR] = bmsr | 0x800;	/*we are always capable of 10 hdx */
 
 	return 0;
 }
@@ -141,29 +129,30 @@ static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location)
 	struct fixed_info *fixed = bus->priv;
 
 	/* if user has registered link update callback, use it */
-	if(fixed->phydev)
-		if(fixed->phydev->attached_dev) {
-			if(fixed->link_update) {
+	if (fixed->phydev)
+		if (fixed->phydev->attached_dev) {
+			if (fixed->link_update) {
 				fixed->link_update(fixed->phydev->attached_dev,
-						&fixed->phy_status);
+						   &fixed->phy_status);
 				fixed_mdio_update_regs(fixed);
 			}
-	}
+		}
 
 	if ((unsigned int)location >= fixed->regs_num)
 		return -1;
 	return fixed->regs[location];
 }
 
-static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
+static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location,
+			   u16 val)
 {
-	/* do nothing for now*/
+	/* do nothing for now */
 	return 0;
 }
 
 static int fixed_mii_reset(struct mii_bus *bus)
 {
-	/*nothing here - no way/need to reset it*/
+	/*nothing here - no way/need to reset it */
 	return 0;
 }
 #endif
@@ -171,8 +160,8 @@ static int fixed_mii_reset(struct mii_bus *bus)
 static int fixed_config_aneg(struct phy_device *phydev)
 {
 	/* :TODO:03/13/2006 09:45:37 PM::
-	 The full autoneg funcionality can be emulated,
-	 but no need to have anything here for now
+	   The full autoneg funcionality can be emulated,
+	   but no need to have anything here for now
 	 */
 	return 0;
 }
@@ -182,59 +171,79 @@ static int fixed_config_aneg(struct phy_device *phydev)
  * match will never return true...
  *-----------------------------------------------------------------------------*/
 static struct phy_driver fixed_mdio_driver = {
-	.name		= "Fixed PHY",
-	.features	= PHY_BASIC_FEATURES,
-	.config_aneg	= fixed_config_aneg,
-	.read_status	= genphy_read_status,
-	.driver 	= { .owner = THIS_MODULE,},
+	.name = "Fixed PHY",
+#ifdef CONFIG_FIXED_MII_1000_FDX
+	.features = PHY_GBIT_FEATURES,
+#else
+	.features = PHY_BASIC_FEATURES,
+#endif
+	.config_aneg = fixed_config_aneg,
+	.read_status = genphy_read_status,
+	.driver = { .owner = THIS_MODULE, },
 };
 
+static void fixed_mdio_release(struct device *dev)
+{
+	struct phy_device *phydev = container_of(dev, struct phy_device, dev);
+	struct mii_bus *bus = phydev->bus;
+	struct fixed_info *fixed = bus->priv;
+
+	kfree(phydev);
+	kfree(bus->dev);
+	kfree(bus);
+	kfree(fixed->regs);
+	kfree(fixed);
+}
+
 /*-----------------------------------------------------------------------------
  *  This func is used to create all the necessary stuff, bind
  * the fixed phy driver and register all it on the mdio_bus_type.
- * speed is either 10 or 100, duplex is boolean.
+ * speed is either 10 or 100 or 1000, duplex is boolean.
  * number is used to create multiple fixed PHYs, so that several devices can
  * utilize them simultaneously.
+ *
+ * The device on mdio bus will look like [bus_id]:[phy_id],
+ * bus_id = number
+ * phy_id = speed+duplex.
  *-----------------------------------------------------------------------------*/
-#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
-static int fixed_mdio_register_device(int number, int speed, int duplex)
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX)
+struct fixed_info *fixed_mdio_register_device(
+	int bus_id, int speed, int duplex, u8 phy_id)
 {
 	struct mii_bus *new_bus;
 	struct fixed_info *fixed;
 	struct phy_device *phydev;
-	int err = 0;
+	int err;
 
-	struct device* dev = kzalloc(sizeof(struct device), GFP_KERNEL);
+	struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL);
 
-	if (NULL == dev)
-		return -ENOMEM;
+	if (dev == NULL)
+		goto err_dev_alloc;
 
 	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
 
-	if (NULL == new_bus) {
-		kfree(dev);
-		return -ENOMEM;
-	}
+	if (new_bus == NULL)
+		goto err_bus_alloc;
+
 	fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL);
 
-	if (NULL == fixed) {
-		kfree(dev);
-		kfree(new_bus);
-		return -ENOMEM;
-	}
+	if (fixed == NULL)
+		goto err_fixed_alloc;
+
+	fixed->regs = kzalloc(MII_REGS_NUM * sizeof(int), GFP_KERNEL);
+	if (NULL == fixed->regs)
+		goto err_fixed_regs_alloc;
 
-	fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL);
 	fixed->regs_num = MII_REGS_NUM;
 	fixed->phy_status.speed = speed;
 	fixed->phy_status.duplex = duplex;
 	fixed->phy_status.link = 1;
 
-	new_bus->name = "Fixed MII Bus",
-	new_bus->read = &fixed_mii_read,
-	new_bus->write = &fixed_mii_write,
-	new_bus->reset = &fixed_mii_reset,
-
-	/*set up workspace*/
+	new_bus->name = "Fixed MII Bus";
+	new_bus->read = &fixed_mii_read;
+	new_bus->write = &fixed_mii_write;
+	new_bus->reset = &fixed_mii_reset;
+	/*set up workspace */
 	fixed_mdio_update_regs(fixed);
 	new_bus->priv = fixed;
 
@@ -243,119 +252,110 @@ static int fixed_mdio_register_device(int number, int speed, int duplex)
 
 	/* create phy_device and register it on the mdio bus */
 	phydev = phy_device_create(new_bus, 0, 0);
+	if (phydev == NULL)
+		goto err_phy_dev_create;
 
 	/*
-	 Put the phydev pointer into the fixed pack so that bus read/write code could
-	 be able to access for instance attached netdev. Well it doesn't have to do
-	 so, only in case of utilizing user-specified link-update...
+	 * Put the phydev pointer into the fixed pack so that bus read/write
+	 * code could be able to access for instance attached netdev. Well it
+	 * doesn't have to do so, only in case of utilizing user-specified
+	 * link-update...
 	 */
-	fixed->phydev = phydev;
 
-	if(NULL == phydev) {
-		err = -ENOMEM;
-		goto device_create_fail;
-	}
+	fixed->phydev = phydev;
+	phydev->speed = speed;
+	phydev->duplex = duplex;
 
 	phydev->irq = PHY_IGNORE_INTERRUPT;
 	phydev->dev.bus = &mdio_bus_type;
 
-	if(number)
-		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
-				"fixed_%d@%d:%d", number, speed, duplex);
-	else
-		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
-				"fixed@%d:%d", speed, duplex);
-	phydev->bus = new_bus;
+	snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
+		 PHY_ID_FMT, bus_id, phy_id);
 
-	err = device_register(&phydev->dev);
-	if(err) {
-		printk(KERN_ERR "Phy %s failed to register\n",
-				phydev->dev.bus_id);
-		goto bus_register_fail;
-	}
+	phydev->bus = new_bus;
 
-	/*
-	   the mdio bus has phy_id match... In order not to do it
-	   artificially, we are binding the driver here by hand;
-	   it will be the same for all the fixed phys anyway.
-	 */
 	phydev->dev.driver = &fixed_mdio_driver.driver;
-
+	phydev->dev.release = fixed_mdio_release;
 	err = phydev->dev.driver->probe(&phydev->dev);
-	if(err < 0) {
-		printk(KERN_ERR "Phy %s: problems with fixed driver\n",phydev->dev.bus_id);
-		goto probe_fail;
+	if (err < 0) {
+		printk(KERN_ERR "Phy %s: problems with fixed driver\n",
+		       phydev->dev.bus_id);
+		goto err_out;
 	}
+	err = device_register(&phydev->dev);
+	if (err) {
+		printk(KERN_ERR "Phy %s failed to register\n",
+		       phydev->dev.bus_id);
+		goto err_out;
+	}
+	//phydev->state = PHY_RUNNING; /* make phy go up quick, but in 10Mbit/HDX
+	return fixed;
 
-	err = device_bind_driver(&phydev->dev);
-	if (err)
-		goto probe_fail;
-
-	return 0;
-
-probe_fail:
-	device_unregister(&phydev->dev);
-bus_register_fail:
+err_out:
 	kfree(phydev);
-device_create_fail:
-	kfree(dev);
-	kfree(new_bus);
+err_phy_dev_create:
+	kfree(fixed->regs);
+err_fixed_regs_alloc:
 	kfree(fixed);
+err_fixed_alloc:
+	kfree(new_bus);
+err_bus_alloc:
+	kfree(dev);
+err_dev_alloc:
+
+	return NULL;
 
-	return err;
 }
 #endif
 
-
 MODULE_DESCRIPTION("Fixed PHY device & driver for PAL");
 MODULE_AUTHOR("Vitaly Bordug");
 MODULE_LICENSE("GPL");
 
 static int __init fixed_init(void)
 {
-#if 0
-	int ret;
-	int duplex = 0;
-#endif
-
-	/* register on the bus... Not expected to be matched with anything there... */
+	int cnt = 0;
+	int i;
+/* register on the bus... Not expected to be matched
+ * with anything there...
+ *
+ */
 	phy_driver_register(&fixed_mdio_driver);
 
-	/* So let the fun begin...
-	   We will create several mdio devices here, and will bound the upper
-	   driver to them.
-
-	   Then the external software can lookup the phy bus by searching
-	   fixed@speed:duplex, e.g. fixed@100:1, to be connected to the
-	   virtual 100M Fdx phy.
-
-	   In case several virtual PHYs required, the bus_id will be in form
-	   fixed_<num>@<speed>:<duplex>, which make it able even to define
-	   driver-specific link control callback, if for instance PHY is completely
-	   SW-driven.
-
-	*/
-
-#ifdef CONFIG_FIXED_MII_DUPLEX
-#if 0
-	duplex = 1;
-#endif
+/* We will create several mdio devices here, and will bound the upper
+ * driver to them.
+ *
+ * Then the external software can lookup the phy bus by searching
+ * for 0:101, to be connected to the virtual 100M Fdx phy.
+ *
+ * In case several virtual PHYs required, the bus_id will be in form
+ * [num]:[duplex]+[speed], which make it able even to define
+ * driver-specific link control callback, if for instance PHY is
+ * completely SW-driven.
+ */
+	for (i=1; i <= CONFIG_FIXED_MII_AMNT; i++) {
+#ifdef CONFIG_FIXED_MII_1000_FDX
+		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(0, 1000, 1, i);
 #endif
-
 #ifdef CONFIG_FIXED_MII_100_FDX
-	fixed_mdio_register_device(0, 100, 1);
+		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(1, 100, 1, i);
 #endif
-
 #ifdef CONFIG_FIXED_MII_10_FDX
-	fixed_mdio_register_device(0, 10, 1);
+		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(2, 10, 1, i);
 #endif
+	}
+
 	return 0;
 }
 
 static void __exit fixed_exit(void)
 {
+	int i;
+
 	phy_driver_unregister(&fixed_mdio_driver);
-	/* :WARNING:02/18/2006 04:32:40 AM:: Cleanup all the created stuff */
+	for (i=0; i < MAX_PHY_AMNT; i++)
+		if ( fixed_phy_ptrs[i] )
+			device_unregister(&fixed_phy_ptrs[i]->phydev->dev);
 }
 
 module_init(fixed_init);

^ permalink raw reply related

* Re: [PATCH 1/2] adb: create class devices for each adb device
From: Benjamin Herrenschmidt @ 2007-07-16 23:22 UTC (permalink / raw)
  To: Aristeu Rozanski; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070716205319.GC30232@cathedrallabs.org>

On Mon, 2007-07-16 at 16:53 -0400, Aristeu Rozanski wrote:
> This patch adds a class device for each adb device that has a handler.
> The class device contents will be accessible by /sys/class/adb/<handler>N
> directory. This patch is needed in order to add an class device
> attribute to all keyboards that will determine the sysrq key for each
> keyboard.

I don't think class device is the right approach. Classes are supposed
to be a functional binding, ie, in this case, input devices. ADB is a
bus, and as such, you should create an adb bus type and and adb_device
that is an extension of struct device, not struct class device.

There's also the question of what to do on ADB resets (such as when
doing a sleep/wakeup cycle). Should we wipe out all devices and
re-created them, thus loosing any settings ? Or should we have some way
to attempt at re-matching existing ones ?

Cheers,
Ben.

> Signed-of-by: Aristeu Rozanski <aris@ruivo.org>
> 
> --- linus-2.6.orig/drivers/macintosh/adb.c	2007-05-11 10:09:13.000000000 -0400
> +++ linus-2.6/drivers/macintosh/adb.c	2007-05-11 10:09:36.000000000 -0400
> @@ -102,11 +102,21 @@
>  static void adbdev_init(void);
>  static int try_handler_change(int, int);
>  
> +static char *adb_device_id_string[] = {
> +	[ADB_DONGLE] = "dongle",
> +	[ADB_KEYBOARD] = "keyboard",
> +	[ADB_MOUSE] = "mouse",
> +	[ADB_TABLET] = "tablet",
> +	[ADB_MODEM] = "modem",
> +	[ADB_MISC] = "misc",
> +};
> +
>  static struct adb_handler {
>  	void (*handler)(unsigned char *, int, int);
>  	int original_address;
>  	int handler_id;
>  	int busy;
> +	char name[16];
>  } adb_handler[16];
>  
>  /*
> @@ -508,6 +518,9 @@
>  		if ((adb_handler[i].original_address == default_id) &&
>  		    (!handler_id || (handler_id == adb_handler[i].handler_id) || 
>  		    try_handler_change(i, handler_id))) {
> +		    	int rc;
> +			struct class_device *cdev;
> +
>  			if (adb_handler[i].handler != 0) {
>  				printk(KERN_ERR
>  				       "Two handlers for ADB device %d\n",
> @@ -517,7 +530,26 @@
>  			write_lock_irq(&adb_handler_lock);
>  			adb_handler[i].handler = handler;
>  			write_unlock_irq(&adb_handler_lock);
> -			ids->id[ids->nids++] = i;
> +
> +			snprintf(adb_handler[i].name,
> +				sizeof(adb_handler[i].name), "%s%i",
> +				adb_device_id_string[default_id], ids->nids);
> +
> +			cdev = &ids->id[ids->nids].cdev;
> +			cdev->class = adb_dev_class;
> +			class_device_initialize(cdev);
> +			snprintf(cdev->class_id, sizeof(cdev->class_id), "%s",
> +				 adb_handler[i].name);
> +			rc = class_device_add(cdev);
> +			if (rc) {
> +				printk(KERN_WARNING "adb: unable to add class "
> +				       "device\n");
> +				for (i = ids->nids - 1; i >= 0; i--)
> +					class_device_del(&ids->id[i].cdev);
> +				ids->nids = 0;
> +				return 0;
> +			}
> +			ids->id[ids->nids++].id = i;
>  		}
>  	}
>  	up(&adb_handler_sem);
> @@ -525,9 +557,9 @@
>  }
>  
>  int
> -adb_unregister(int index)
> +adb_unregister(int index, struct adb_ids *ids)
>  {
> -	int ret = -ENODEV;
> +	int i, ret = -ENODEV;
>  
>  	down(&adb_handler_sem);
>  	write_lock_irq(&adb_handler_lock);
> @@ -539,6 +571,8 @@
>  		}
>  		ret = 0;
>  		adb_handler[index].handler = NULL;
> +		for (i = 0; i < ids->nids; i++)
> +			class_device_del(&ids->id[i].cdev);
>  	}
>  	write_unlock_irq(&adb_handler_lock);
>  	up(&adb_handler_sem);
> --- linus-2.6.orig/include/linux/adb.h	2007-05-11 10:09:13.000000000 -0400
> +++ linus-2.6/include/linux/adb.h	2007-05-11 10:09:36.000000000 -0400
> @@ -3,6 +3,7 @@
>   */
>  #ifndef __ADB_H
>  #define __ADB_H
> +#include <linux/device.h>
>  
>  /* ADB commands */
>  #define ADB_BUSRESET		0
> @@ -57,7 +58,11 @@
>  
>  struct adb_ids {
>  	int nids;
> -	unsigned char id[16];
> +	struct adb_id {
> +		unsigned char id;
> +		struct class_device cdev;
> +		void *priv;
> +	} id[16];
>  };
>  
>  /* Structure which encapsulates a low-level ADB driver */
> @@ -91,7 +96,7 @@
>  		int flags, int nbytes, ...);
>  int adb_register(int default_id,int handler_id,struct adb_ids *ids,
>  		 void (*handler)(unsigned char *, int, int));
> -int adb_unregister(int index);
> +int adb_unregister(int index, struct adb_ids *ids);
>  void adb_poll(void);
>  void adb_input(unsigned char *, int, int);
>  int adb_reset_bus(void);
> --- linus-2.6.orig/drivers/macintosh/adbhid.c	2007-05-11 10:09:19.000000000 -0400
> +++ linus-2.6/drivers/macintosh/adbhid.c	2007-05-11 10:10:15.000000000 -0400
> @@ -875,7 +875,7 @@
>  	adb_register(ADB_MISC, 0, &buttons_ids, adbhid_buttons_input);
>  
>  	for (i = 0; i < keyboard_ids.nids; i++) {
> -		int id = keyboard_ids.id[i];
> +		int id = keyboard_ids.id[i].id;
>  
>  		adb_get_infos(id, &default_id, &org_handler_id);
>  
> @@ -902,7 +902,7 @@
>  	}
>  
>  	for (i = 0; i < buttons_ids.nids; i++) {
> -		int id = buttons_ids.id[i];
> +		int id = buttons_ids.id[i].id;
>  
>  		adb_get_infos(id, &default_id, &org_handler_id);
>  		reg |= adbhid_input_reregister(id, default_id, org_handler_id,
> @@ -912,7 +912,7 @@
>  	/* Try to switch all mice to handler 4, or 2 for three-button
>  	   mode and full resolution. */
>  	for (i = 0; i < mouse_ids.nids; i++) {
> -		int id = mouse_ids.id[i];
> +		int id = mouse_ids.id[i].id;
>  		int mouse_kind;
>  
>  		adb_get_infos(id, &default_id, &org_handler_id);
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [PATCH] adbhid: enable KEY_FN key reporting
From: Benjamin Herrenschmidt @ 2007-07-16 23:20 UTC (permalink / raw)
  To: Aristeu Rozanski; +Cc: linuxppc-dev, Paul Mackerras
In-Reply-To: <20070716205309.GA30232@cathedrallabs.org>

On Mon, 2007-07-16 at 16:53 -0400, Aristeu Rozanski wrote:
> When a Fn key is used in combination with another key in ADB keyboards
> it will generate a Fn event and then a second event that can be a
> different key than pressed (Fn + F1 for instance can generate Fn +
> brightness down if it's configured like that). This patch enables the
> reporting of the Fn key to the input system.
> 
> As Fn is a dead key for most purposes, it's useful to report it so
> applications can make use of it. One example is apple_mouse
> (https://jake.ruivo.org/uinputd/trunk/apple_mouse/) that emulates the
> second and third keys using a combination of keyboard keys and the mouse
> button. Other applications may use the KEY_FN as a modifier aswell.
> I've been updating and using this patch for months without problems.
> 
> Signed-off-by: Aristeu Rozanski <aris@ruivo.org>

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

> --- linus-2.6.orig/drivers/macintosh/adbhid.c	2007-05-11 10:09:13.000000000 -0400
> +++ linus-2.6/drivers/macintosh/adbhid.c	2007-05-11 10:09:19.000000000 -0400
> @@ -70,7 +70,7 @@
>  #define ADB_KEY_POWER_OLD	0x7e
>  #define ADB_KEY_POWER		0x7f
>  
> -u8 adb_to_linux_keycodes[128] = {
> +u16 adb_to_linux_keycodes[128] = {
>  	/* 0x00 */ KEY_A, 		/*  30 */
>  	/* 0x01 */ KEY_S, 		/*  31 */
>  	/* 0x02 */ KEY_D,		/*  32 */
> @@ -134,7 +134,7 @@
>  	/* 0x3c */ KEY_RIGHT,		/* 106 */
>  	/* 0x3d */ KEY_DOWN,		/* 108 */
>  	/* 0x3e */ KEY_UP,		/* 103 */
> -	/* 0x3f */ 0,
> +	/* 0x3f */ KEY_FN,		/* 0x1d0 */
>  	/* 0x40 */ 0,
>  	/* 0x41 */ KEY_KPDOT,		/*  83 */
>  	/* 0x42 */ 0,
> @@ -208,7 +208,7 @@
>  	int original_handler_id;
>  	int current_handler_id;
>  	int mouse_kind;
> -	unsigned char *keycode;
> +	u16 *keycode;
>  	char name[64];
>  	char phys[32];
>  	int flags;
> @@ -275,7 +275,7 @@
>  adbhid_input_keycode(int id, int keycode, int repeat)
>  {
>  	struct adbhid *ahid = adbhid[id];
> -	int up_flag;
> +	int up_flag, key;
>  
>  	up_flag = (keycode & 0x80);
>  	keycode &= 0x7f;
> @@ -321,8 +321,7 @@
>  			}
>  		} else
>  			ahid->flags |= FLAG_FN_KEY_PRESSED;
> -		/* Swallow the key press */
> -		return;
> +		break;
>  	case ADB_KEY_DEL:
>  		/* Emulate Fn+delete = forward delete */
>  		if (ahid->flags & FLAG_FN_KEY_PRESSED) {
> @@ -336,9 +335,9 @@
>  #endif /* CONFIG_PPC_PMAC */
>  	}
>  
> -	if (adbhid[id]->keycode[keycode]) {
> -		input_report_key(adbhid[id]->input,
> -				 adbhid[id]->keycode[keycode], !up_flag);
> + 	key = adbhid[id]->keycode[keycode];
> + 	if (key) {
> + 		input_report_key(adbhid[id]->input, key, !up_flag);
>  		input_sync(adbhid[id]->input);
>  	} else
>  		printk(KERN_INFO "Unhandled ADB key (scancode %#02x) %s.\n", keycode,
> @@ -757,8 +756,8 @@
>  		input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
>  		input_dev->ledbit[0] = BIT(LED_SCROLLL) | BIT(LED_CAPSL) | BIT(LED_NUML);
>  		input_dev->event = adbhid_kbd_event;
> -		input_dev->keycodemax = 127;
> -		input_dev->keycodesize = 1;
> +		input_dev->keycodemax = KEY_FN;
> +		input_dev->keycodesize = sizeof(hid->keycode[0]);
>  		break;
>  
>  	case ADB_MOUSE:
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [RFC][PATCH 6/8] Walnut DTS
From: Benjamin Herrenschmidt @ 2007-07-16 22:34 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Yoder Stuart-B08248
In-Reply-To: <469BEECC.6070404@freescale.com>

On Mon, 2007-07-16 at 17:18 -0500, Scott Wood wrote:
> 
> OK...  but if you're doing a pure IRQ number conversion, the only useful 
> #address-cells would be zero, which makes it a reasonable default IMHO 
> (unlike the arbitrary 2 for regular traversal).

It does make a reasonable default. The thing, as I exlained, is I
dislike the whole idea of "default" values in the first place.

Cheers,
Ben.

^ permalink raw reply

* Re: [PATCH] Fix Tsi108 ethernet driver performance
From: Jeff Garzik @ 2007-07-16 22:27 UTC (permalink / raw)
  To: Alexandre Bounine; +Cc: netdev, linuxppc-dev
In-Reply-To: <1B5F013528140F45B5C671039279CA5701F834BB@NANUK.pc.tundra.com>

Alexandre Bounine wrote:
> From: Alexandre Bounine <alexandreb@tundra.com>
> 
> This patch improves performance of the Tsi108 Ethernet driver by
> changing interrupt handling for frame receive path. It reduces number of
> interrupts generated for received frames and therefore lowers CPU
> utilization by the device driver.
>    
> Signed-off-by: Alexandre Bounine <alexandreb@tundra.com>

Look into NAPI...

^ permalink raw reply

* Re: [RFC][PATCH 6/8] Walnut DTS
From: Scott Wood @ 2007-07-16 22:18 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, Yoder Stuart-B08248
In-Reply-To: <1184623898.25235.96.camel@localhost.localdomain>

Benjamin Herrenschmidt wrote:
> No, interrupt maps are useful in devices with no children in some corner
> cases. Remember that a map doesnt need to use the address part of the
> source specifier, thus it can be used to do a pure domain->domain
> conversion of the irq numbers, what sort of thing. The map has the added
> advantage that today, it's the only mechanism that allows you to specify
> different interrupt-parents through the same nexus, which is useful for
> 4xx.

OK...  but if you're doing a pure IRQ number conversion, the only useful 
#address-cells would be zero, which makes it a reasonable default IMHO 
(unlike the arbitrary 2 for regular traversal).

-Scott

^ permalink raw reply

* Re: [patch 5/6] ps3: BD/DVD/CD-ROM Storage Driver
From: Benjamin Herrenschmidt @ 2007-07-16 22:12 UTC (permalink / raw)
  To: James Bottomley
  Cc: Arnd Bergmann, linux-scsi, Linux Kernel Development,
	Alessandro Rubini, Linux/PPC Development, Paul Mackerras,
	Jens Axboe, Geert Uytterhoeven
In-Reply-To: <1184623415.3447.48.camel@localhost.localdomain>

On Mon, 2007-07-16 at 17:03 -0500, James Bottomley wrote:
> On Tue, 2007-07-17 at 07:49 +1000, Benjamin Herrenschmidt wrote:
> > > No ... that was the point of flush_kernel_dcache_page().  The page in
> > > question is page cache backed and contains user mappings.  However, the
> > > block layer has already done a flush_dcache_page() in get_user_pages()
> > > and the user shouldn't be touching memory under I/O (unless they want
> > > self induced aliasing problems) so we're free to assume all the user
> > > cachelines are purged, hence all we have to do is flush the kernel alias
> > > to bring the page up to date and make the users see it correctly.
> > 
> > The block layer will have done that even in the swap-out path ? (Just
> > asking... I'm not very familiar with the block layer)
> 
> Er ... not really, this is the I/O path for user initiated I/O.  The
> page out path, by definition, can't have any extant user mappings.  For
> page out, the relevant page is flushed before its mapping is detached,
> and then it can be paged to the backing store (or for anonymous pages to
> the swap device) when no mappings remain.

Ok, thanks.

Ben.

^ permalink raw reply

* RE: [RFC][PATCH 6/8] Walnut DTS
From: Benjamin Herrenschmidt @ 2007-07-16 22:12 UTC (permalink / raw)
  To: Yoder Stuart-B08248; +Cc: linuxppc-dev
In-Reply-To: <9696D7A991D0824DBA8DFAC74A9C5FA303067256@az33exm25.fsl.freescale.net>


> > I would personally be inclined to define that whatever spec we come up
> > with always require #address-cells/#size-cells for any node that can
> > have either device children or interrupt children, and ban default
> > values alltogether.
> 
> Did you really mean #size-cells here?  Shouldn't it be #interrupt-cells?

Yup, as I said, my fingers got a bit too fast on the keyboard. I means
#interrupt-cells.

Ben.

^ permalink raw reply

* Re: [RFC][PATCH 6/8] Walnut DTS
From: Benjamin Herrenschmidt @ 2007-07-16 22:11 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev, Yoder Stuart-B08248
In-Reply-To: <469BE93E.1070702@freescale.com>

On Mon, 2007-07-16 at 16:55 -0500, Scott Wood wrote:
> Benjamin Herrenschmidt wrote:
> > I would personally be inclined to define that whatever spec we come up
> > with always require #address-cells/#size-cells for any node that can
> > have either device children or interrupt children, and ban default
> > values alltogether.
> 
> When is #size-cells used in the interrupt tree at all?

It's not, sorry, my fingers typed a bit too fast :-)

> And given the odd behavior of using an interrupt map in an interrupt 
> parent that is not the device parent (you're potentially using keys from 
> different domains that could clash, be a different sizes, etc), if we 
> make any changes in that regard, I'd forbid interrupt maps in interrupt 
> controllers with no device children, and thus #address-cells has no 
> meaning there.

No, interrupt maps are useful in devices with no children in some corner
cases. Remember that a map doesnt need to use the address part of the
source specifier, thus it can be used to do a pure domain->domain
conversion of the irq numbers, what sort of thing. The map has the added
advantage that today, it's the only mechanism that allows you to specify
different interrupt-parents through the same nexus, which is useful for
4xx.

Ben.

^ permalink raw reply

* Re: [patch 5/6] ps3: BD/DVD/CD-ROM Storage Driver
From: James Bottomley @ 2007-07-16 22:03 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Arnd Bergmann, linux-scsi, Linux Kernel Development,
	Alessandro Rubini, Linux/PPC Development, Paul Mackerras,
	Jens Axboe, Geert Uytterhoeven
In-Reply-To: <1184622555.25235.91.camel@localhost.localdomain>

On Tue, 2007-07-17 at 07:49 +1000, Benjamin Herrenschmidt wrote:
> > No ... that was the point of flush_kernel_dcache_page().  The page in
> > question is page cache backed and contains user mappings.  However, the
> > block layer has already done a flush_dcache_page() in get_user_pages()
> > and the user shouldn't be touching memory under I/O (unless they want
> > self induced aliasing problems) so we're free to assume all the user
> > cachelines are purged, hence all we have to do is flush the kernel alias
> > to bring the page up to date and make the users see it correctly.
> 
> The block layer will have done that even in the swap-out path ? (Just
> asking... I'm not very familiar with the block layer)

Er ... not really, this is the I/O path for user initiated I/O.  The
page out path, by definition, can't have any extant user mappings.  For
page out, the relevant page is flushed before its mapping is detached,
and then it can be paged to the backing store (or for anonymous pages to
the swap device) when no mappings remain.

James

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox